A short description of the machine dependent parts of ld/rtld.
This commit is contained in:
parent
c02010b599
commit
e04b1df8e3
192
gnu/usr.bin/ld/PORTING
Normal file
192
gnu/usr.bin/ld/PORTING
Normal file
@ -0,0 +1,192 @@
|
||||
$Id: PORTING,v 1.1 1994/11/28 10:37:10 pk Exp $
|
||||
|
||||
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_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.
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user