Compiler system executable object modules with all external references defined have the same format as relocatable modules and are executable without re-link editing.
Local relocation entries must be used for symbols that are defined. Therefore, external relocations are used only for undefined symbols. Figure 9-3 gives an overview of the Relocation Table entry for an undefined external symbol.
Table 9-11: Relocation Types
Symbol Value Description
R_ABS 0x0 Relocation already performed.
R_REFHALF 0x1 16-bit reference to the symbol’s virtual address.
R_REFWORD 0x2 32-bit reference to the symbol’s virtual address.
R_JMPADDR 0x3 26-bit jump reference to the symbol’s virtual address.
R_REFHI 0x4 Reference to the high 16-bits of symbol’s virtual address.
R_REFLO 0x5 Reference to the low 16-bits of symbol’s virtual address.
R_GPREL 0x6 Reference to the offset from the global pointer to the symbol’s virtual address.
R_LITERAL 0x7 Reference to a literal in a literal pool as an offset from the global pointer.
R_REL32 0x8 Reference to the distance from the offset to the global pointer.
0x9-0x15 Reserved 0x1D-0x1F Reserved
Chapter 9 Figure 9-3: Relocation Table Entry for Undefined External Symbols
The assembler creates this entry as follows:
Sets r_vaddr to point to the item to be relocated.
Places a constant to be added to the value for relocation at the address for the item to be relocated (r_vaddr).
Sets r_symndx to the index of the External Symbols entry that contains the symbol value.
Sets r_type to the constant for the type of relocation types. Table 9-11 shows the valid constants for the relocation type.
Sets r_extern to 1.
NOTE: The assembler always sets the value of the undefined entry in External Symbols to 0. It may assign a constant value to be added to the relocated value at the address where the location is to be done. If the width of the constant is less than a full word, and an overflow occurs after relocation, the link editor flags this as an error.
When the link editor determines that an external symbol is defined, it changes the Relocation Table entry for the symbol to a local relocation entry. Figure 9-4 gives an overview of the new entry.
r_vaddr r_symndx
Relocation Table Entry
r_extern=1
External Symbols
value=0
Section Data
constant
Sign-extended to 32 bits.
Chapter 9
Figure 9-4: Relocation Table Entry for a Local Relocation Entry
To change this entry from an external relocation entry to a local relocation entry, the link editor:
• Picks up the constant from the address to be relocated (r_vaddr).
• If the width of the constant is less than 32 bits, sign-extends the constant to 32 bits.
• Adds the value for relocation (the value of the symbol) to the constant and places it back in the address to be relocated.
• Sets r_symndx to the section number that contains the external symbol.
• Sets r_extern to 0.
s_vaddr r_vaddr
r_symndx Relocation Table Entry
Section n Data r_extern=0
Section n Optional
Section Data
constant r_type
r_type
Header
symbol location
Sign-extended to 32 bits.
Chapter 9 Examples
The examples that follow use external relocation entries.
Example 1: 32-Bit Reference – R_REFWORD. This example shows assembly statements that set the value at location b to the global data value y.
.globl y .data
b: .word y #R_REFWORD relocation type at address b for symbol y
In processing this statement, the assembler generates a relocation entry of type R_REFWORD for the address b and the symbol y. After determining the address for the symbol y, the loader adds the 32-bit address of y to the 32-bit value at location b, and places the sum in location b. The loader handles 16-bit addresses (R_REFHALF) in the same manner, except it checks for overflow after determining the relocation value.
Example 2: 26-Bit Jump – R_JMPADDR. This example shows assembly statements that call routine x from location c.
.text
x: #routine x ...
c: jal x #R_JMPADDR relocation type at address c for symbol x
In processing these statements, the assembler generates a relocation entry of type R_JMPADDR for the address and the symbol x. After determining the address for the routine, the loader shifts the address right two bits, adds the low 26 bits of the result to the low 26 bits of the instruction at address c (after sign-extending it), and places the results back into the low 26 bits at address c.
R_JMPADDR relocation entries are produced for the assembler’s j (Jump) and jal (Jump and Link) instructions. These instructions take the high four bits of the target address from the address of the delay slot of their instruction.
The link editor makes sure that the same four bits are in the target address after relocation; if not, it generates an error message.
If the entry is a local relocation type, the target of the Jump instruction is assembled in the instruction at the address to be relocated. The high four bits of the jump target are taken from the high 4 bits of the address of the delay slot of the instruction to be relocated.
Example 3: High/Low Reference - R_REFHI/R_REFLO. This example shows an assembler macro that loads the absolute address y, plus a constant, into Register 6:
Chapter 9
In processing this statement, the assembler generates a 0 as the value y, and the following machine language statements:
f: lui $at,constant>>16 #R_REFHI relocation type at address f for symbol y
g: addiu $r6,constant&0xffff($at) #R_REFLO relocation type at address for symbol y
In this example, the assembler produces two relocation entries.
NOTE: When a R_REFHI relocation entry appears, the next relocation entry must always be the corresponding R_REFLO entry. This is required in order to reconstruct the constant that is to be added to the value for relocation.
In determining the final constant values for the two instructions, the link editor must take into account that the addiu instruction of the R_REFLO relocation entry sign-extends the immediate value of the constant.
In determining the sum of the address for the symbol y and the constant, the link editor does the following:
• It uses the low 16 bits of this sum for the immediate value of the R_REFLO relocation address.
• Because all instructions that are marked with a R_REFLO perform a signed operation, the assembler adjusts the high portion of the sum if Bit 15 is set. Then it uses the high 16 bits of the sum for the immediate value of the R_REFHI instruction at the relocation address. For example:
Example 4: Offset Reference – R_GPREL. This example shows an assembly macro that loads a global pointer relative value y into Register 6:
lw $r6,y
In processing this statement, the assembler generates a 0 as the value y and the following machine language statement:
h: lw $r6,0($gp) #R_GPREL relocation type at lw $r6,0x10008000
lui lw
$at,0x1001
$r6,0x8000($at)
at = 0x10010000 + 0xFFFF8000 0x10008000
Chapter 9
address h for symbol y
and a R_GPREL relocation entry would be produced. The assembler then uses the difference between the address for the symbol y and the address of the global pointer, as the immediate value for the instruction. The link editor gets the value of the global pointer used by the assembler from gp_value in the Optional Header (Table 9-4).
Example 4: Example of the R_LITERAL. This example shows of an R_LITERAL uses a floating-point literal. The assembler macro:
li.s $f0,1.234
is translated into the following machine instruction:
h: lwc1 $f0,–32752(gp)# R_LITERAL relocation type at address h for the
literal 1.234
and a R_LITERAL relocation entry is produced; the value of the literal is put into the .lit4 section. The link editor places only one of all like literal constants in the literal pool. The difference between the virtual address of the literal and the address of the global pointer is used as the immediate value for the instruction. The link editor handles 8-byte literal constants similarly, except it places each unique constant in the .lit8 section. The value of the –G num option used when compiling determines if the literal pools are used.