mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-29 12:03:03 +00:00
195 lines
7.1 KiB
Plaintext
195 lines
7.1 KiB
Plaintext
$Id$
|
|
|
|
This document describes some of the machine dependent parts in ld(1) and rtld(?)
|
|
Most of the machine dependencies are a result of different ways in which
|
|
relocation information is conveyed in an architecture's object files.
|
|
Especially RISC architectures are likely candidates to have deviated from the
|
|
traditional relocation record structure due a tendency to use odd sized
|
|
"bitfields" to denote immediate operands within their fixed size instructions.
|
|
|
|
Also, there may be slight differences in the model used for Position
|
|
Independent Code generation by the compiler.
|
|
|
|
Lastly, both ld and rtld must fiddle with actual machine instructions to setup
|
|
a transfer vector to accommodate PIC code and dynamic linking.
|
|
|
|
|
|
Machine dependent macros and data structures.
|
|
|
|
typedef struct jmpslot { ... } jmpslot_t;
|
|
|
|
The Procedure Linkage Table (PLT) is an array of these structures.
|
|
The structure contains room for a control transfer instruction
|
|
and a relocation index. md_make_jmpslot() and md_fix_jmpslot()
|
|
are responsible for filling these in.
|
|
|
|
JMPSLOT_NEEDS_RELOC()
|
|
|
|
Macro indicating whether or not a jmpslot entry needs a run-time
|
|
relocation when ld has already resolved the symbolic reference
|
|
(eg. when `-Bsymbolic' was given). Usually the case if the control
|
|
transfer instruction is PC relative or something.
|
|
|
|
RELOC_STATICS_THROUGH_GOT_P(r)
|
|
|
|
Predicate taking a `struct relocation_info *' as an argument. It
|
|
decides whether variables with file scope are addressed relative to
|
|
the start Global Offset Table (1) or an entry in GOT must be
|
|
allocated (0). The compiler has a say in this.
|
|
|
|
|
|
Some other random macros:
|
|
|
|
BAD_MID(ex)
|
|
|
|
Tells whether the machine ID in an input file header is acceptable.
|
|
|
|
N_SET_FLAG(ex,f)
|
|
|
|
Set flags F in a.out header. Must account for possible non-NetBSD
|
|
headers; QMAGIC is still a documented ld output format.
|
|
|
|
N_IS_DYNAMIC(ex)
|
|
|
|
Return true if this appears to be a dynamically linked object.
|
|
|
|
#define relocation_info reloc_info_<machine>
|
|
|
|
Define (possibly machine dependent) relocation record format.
|
|
Should convert to a typedef someday for greater opacity.
|
|
|
|
md_got_reloc(r)
|
|
|
|
Adjustment to be applied to the relocation value of references
|
|
to "_GLOBAL_OFFSET_TABLE". It's here because of Sun's sparc as(1),
|
|
(it's is a *bug*), and could have been `#ifdef SUN_COMPAT' if I
|
|
had not let it slip into NetBSD's gas for compatibility.
|
|
|
|
md_get_rt_segment_addend(r,a)
|
|
|
|
Another SunOS bug workaround.
|
|
|
|
|
|
The macros below have defaults defined in ld.h for the traditional relocation
|
|
structure format; each takes a `struct relocation_info *' argument (see
|
|
ld.h for more detailed comments):
|
|
|
|
RELOC_ADDRESS(r) - the address at which to relocate
|
|
RELOC_EXTERN_P(r) - relocation for external symbol
|
|
RELOC_TYPE(r) - segment (text/data/bss), non-external relocs
|
|
RELOC_SYMBOL(r) - symbol index, external relocs
|
|
RELOC_MEMORY_SUB_P(r) - relocation involves something to subtract
|
|
RELOC_MEMORY_ADD_P(r) - relocation involves something to add
|
|
RELOC_ADD_EXTRA(r) - <disused> (moved into MD files)
|
|
RELOC_PCREL_P(r) - relocation is PC relative
|
|
RELOC_VALUE_RIGHTSHIFT(r) - <disused>
|
|
RELOC_TARGET_SIZE(r) - size (in bytes) of relocated value
|
|
RELOC_TARGET_BITPOS(r) - <disused> (moved into MD files)
|
|
RELOC_TARGET_BITSIZE(r) - <disused> (moved into MD files)
|
|
RELOC_JMPTAB_P(r) - relocation is for a PLT entry
|
|
RELOC_BASEREL_P(r) - relocation is for a GOT entry
|
|
RELOC_RELATIVE_P(r) - relocation is load address relative
|
|
RELOC_COPY_P(r) - relocation involves an initialization
|
|
RELOC_INIT_SEGMENT_RELOC(r) - initialize a relocation record pertaining to
|
|
a segment; traditional archs can use bzero().
|
|
RELOC_LAZY_P(r) - (run-time) resolution can be lazy.
|
|
CHECK_GOT_RELOC(r) - consistency check on relocations involving
|
|
the "_GLOBAL_OFFSET_TABLE" symbol
|
|
|
|
|
|
|
|
Things which are currently defined as routines in <machine>/md.c:
|
|
|
|
|
|
md_init_header(struct exec *hp, int magic, int flags)
|
|
|
|
Initializes the output file header. Straightforward, unless
|
|
multiple OS'es are supported.
|
|
|
|
|
|
md_swap*_exec_hdr(struct exec *)
|
|
|
|
Input/output a.out header in target byte-order.
|
|
|
|
|
|
md_swap*_reloc(struct relocation_info *, n)
|
|
|
|
Input/output N relocation records in target byte-order.
|
|
|
|
|
|
md_get_addend(struct relocation_info *rp, char *addr)
|
|
|
|
Return a relocation addend. Traditionally found in the object file
|
|
at address ADDR. The relocation record determines the data width
|
|
in bytes (using RELOC_TARGET_SIZE()).
|
|
|
|
md_relocate(struct relocation_info *rp, long reloc, char *addr,
|
|
int relocatable_output)
|
|
|
|
Perform a relocation at the given address, usually by entering
|
|
the specified value RELOC into the object file. Some architectures
|
|
may store the relocation in RP when RELOCATABLE_OUTPUT is set.
|
|
Again, the byte size of the relocation value is determined from
|
|
RP through RELOC_TARGET_SIZE().
|
|
|
|
md_make_reloc(struct relocation_info *rp, int type)
|
|
|
|
Construct the machine dependent part of a relocation record used
|
|
for run-time relocation. Sets RP's type field or one or more
|
|
bitfields according to TYPE which is ld's internal relocation
|
|
representation of the type of (run-time) relocation. TYPE is a
|
|
combination of the following bits:
|
|
|
|
RELTYPE_EXTERN - relocation is for unresolved symbol
|
|
RELTYPE_JMPSLOT - relocation is for a PLT entry
|
|
RELTYPE_BASEREL - <not used>
|
|
RELTYPE_RELATIVE - relocation is load address relative
|
|
RELTYPE_COPY - relocation is an initalization
|
|
|
|
md_make_jmpreloc(struct relocation_info *rp, *r, int type)
|
|
|
|
Set up a run-time relocation record pertaining to a jmpslot.
|
|
This usually sets a bit or a relocation type dedicated to jmpslot
|
|
relocations. R is the relocation record to be updated (ie. the
|
|
run-time relocation record), while RP points at the relocation
|
|
record from the object file on behalf of which we allocated a
|
|
PLT entry. RP may not be needed.
|
|
|
|
md_make_gotreloc(struct relocation_info *rp, *r, int type)
|
|
|
|
Set up a run-time relocation record pertaining to a GOT entry.
|
|
This usually sets a bit or a relocation type dedicated to GOT
|
|
relocations. R is the relocation record to be updated (ie. the
|
|
run-time relocation record), while RP points at the relocation
|
|
record from the object file on behalf of which we allocated a
|
|
GOT entry.
|
|
|
|
md_make_cpyreloc(struct relocation_info *rp, *r)
|
|
|
|
Mark the relocation record as pertaining to a location that needs
|
|
run-time initializing from some shared object source.
|
|
R and RP same as above.
|
|
|
|
md_make_jmpslot(jmpslot_t *sp, long offset, long index)
|
|
|
|
Construct a jmpslot, ie. fill in the machine opcodes that comprise
|
|
a transfer to slot 0 of the PLT. OFFSET is the location of SP
|
|
relative to the start of the PLT (ie. (int)sp - (int)&PLT[0] ).
|
|
INDEX is the entry in the run-time relocation record table which
|
|
determines what symbol this jmpslot is supposed to resolve.
|
|
|
|
md_fix_jmpslot(jmpslot_t *sp, long offset, long addr)
|
|
|
|
Fix up a jmpslot so that it will transfer directly to ADDR
|
|
in stead of to PLT[0]. OFFSET has the same meaning as in
|
|
md_make_jmpslot(). This function is called by binder() after
|
|
it has resolved a symbol into a (run-time) address.
|
|
|
|
md_set_breakpoint(long where, long *savep)
|
|
|
|
Set a breakpoint. Used when run under a debugger. The breakpoint
|
|
instruction is to be set at location WHERE. The original contents
|
|
of *WHERE is to be saved in *SAVEP.
|
|
|
|
|