mirror of
https://github.com/bebbo/amigaos-binutils-2.14.git
synced 2025-12-08 22:38:24 +00:00
430 lines
16 KiB
Plaintext
430 lines
16 KiB
Plaintext
This is bfd.info, produced by makeinfo version 4.3 from bfd.texinfo.
|
|
|
|
START-INFO-DIR-ENTRY
|
|
* Bfd: (bfd). The Binary File Descriptor library.
|
|
END-INFO-DIR-ENTRY
|
|
|
|
This file documents the BFD library.
|
|
|
|
Copyright (C) 1991, 2000, 2001, 2003 Free Software Foundation, Inc.
|
|
|
|
Permission is granted to copy, distribute and/or modify this document
|
|
under the terms of the GNU Free Documentation License, Version 1.1
|
|
or any later version published by the Free Software Foundation;
|
|
with no Invariant Sections, with no Front-Cover Texts, and with no
|
|
Back-Cover Texts. A copy of the license is included in the
|
|
section entitled "GNU Free Documentation License".
|
|
|
|
|
|
File: bfd.info, Node: typedef arelent, Next: howto manager, Prev: Relocations, Up: Relocations
|
|
|
|
typedef arelent
|
|
---------------
|
|
|
|
This is the structure of a relocation entry:
|
|
|
|
|
|
typedef enum bfd_reloc_status
|
|
{
|
|
/* No errors detected. */
|
|
bfd_reloc_ok,
|
|
|
|
/* The relocation was performed, but there was an overflow. */
|
|
bfd_reloc_overflow,
|
|
|
|
/* The address to relocate was not within the section supplied. */
|
|
bfd_reloc_outofrange,
|
|
|
|
/* Used by special functions. */
|
|
bfd_reloc_continue,
|
|
|
|
/* Unsupported relocation size requested. */
|
|
bfd_reloc_notsupported,
|
|
|
|
/* Unused. */
|
|
bfd_reloc_other,
|
|
|
|
/* The symbol to relocate against was undefined. */
|
|
bfd_reloc_undefined,
|
|
|
|
/* The relocation was performed, but may not be ok - presently
|
|
generated only when linking i960 coff files with i960 b.out
|
|
symbols. If this type is returned, the error_message argument
|
|
to bfd_perform_relocation will be set. */
|
|
bfd_reloc_dangerous
|
|
}
|
|
bfd_reloc_status_type;
|
|
|
|
|
|
typedef struct reloc_cache_entry
|
|
{
|
|
/* A pointer into the canonical table of pointers. */
|
|
struct symbol_cache_entry **sym_ptr_ptr;
|
|
|
|
/* offset in section. */
|
|
bfd_size_type address;
|
|
|
|
/* addend for relocation value. */
|
|
bfd_vma addend;
|
|
|
|
/* Pointer to how to perform the required relocation. */
|
|
reloc_howto_type *howto;
|
|
|
|
}
|
|
arelent;
|
|
*Description*
|
|
Here is a description of each of the fields within an `arelent':
|
|
|
|
* `sym_ptr_ptr'
|
|
The symbol table pointer points to a pointer to the symbol
|
|
associated with the relocation request. It is the pointer into the
|
|
table returned by the back end's `get_symtab' action. *Note Symbols::.
|
|
The symbol is referenced through a pointer to a pointer so that tools
|
|
like the linker can fix up all the symbols of the same name by
|
|
modifying only one pointer. The relocation routine looks in the symbol
|
|
and uses the base of the section the symbol is attached to and the
|
|
value of the symbol as the initial relocation offset. If the symbol
|
|
pointer is zero, then the section provided is looked up.
|
|
|
|
* `address'
|
|
The `address' field gives the offset in bytes from the base of the
|
|
section data which owns the relocation record to the first byte of
|
|
relocatable information. The actual data relocated will be relative to
|
|
this point; for example, a relocation type which modifies the bottom
|
|
two bytes of a four byte word would not touch the first byte pointed to
|
|
in a big endian world.
|
|
|
|
* `addend'
|
|
The `addend' is a value provided by the back end to be added (!) to
|
|
the relocation offset. Its interpretation is dependent upon the howto.
|
|
For example, on the 68k the code:
|
|
|
|
char foo[];
|
|
main()
|
|
{
|
|
return foo[0x12345678];
|
|
}
|
|
|
|
Could be compiled into:
|
|
|
|
linkw fp,#-4
|
|
moveb @#12345678,d0
|
|
extbl d0
|
|
unlk fp
|
|
rts
|
|
|
|
This could create a reloc pointing to `foo', but leave the offset in
|
|
the data, something like:
|
|
|
|
RELOCATION RECORDS FOR [.text]:
|
|
offset type value
|
|
00000006 32 _foo
|
|
|
|
00000000 4e56 fffc ; linkw fp,#-4
|
|
00000004 1039 1234 5678 ; moveb @#12345678,d0
|
|
0000000a 49c0 ; extbl d0
|
|
0000000c 4e5e ; unlk fp
|
|
0000000e 4e75 ; rts
|
|
|
|
Using coff and an 88k, some instructions don't have enough space in
|
|
them to represent the full address range, and pointers have to be
|
|
loaded in two parts. So you'd get something like:
|
|
|
|
or.u r13,r0,hi16(_foo+0x12345678)
|
|
ld.b r2,r13,lo16(_foo+0x12345678)
|
|
jmp r1
|
|
|
|
This should create two relocs, both pointing to `_foo', and with
|
|
0x12340000 in their addend field. The data would consist of:
|
|
|
|
RELOCATION RECORDS FOR [.text]:
|
|
offset type value
|
|
00000002 HVRT16 _foo+0x12340000
|
|
00000006 LVRT16 _foo+0x12340000
|
|
|
|
00000000 5da05678 ; or.u r13,r0,0x5678
|
|
00000004 1c4d5678 ; ld.b r2,r13,0x5678
|
|
00000008 f400c001 ; jmp r1
|
|
|
|
The relocation routine digs out the value from the data, adds it to
|
|
the addend to get the original offset, and then adds the value of
|
|
`_foo'. Note that all 32 bits have to be kept around somewhere, to cope
|
|
with carry from bit 15 to bit 16.
|
|
|
|
One further example is the sparc and the a.out format. The sparc has
|
|
a similar problem to the 88k, in that some instructions don't have room
|
|
for an entire offset, but on the sparc the parts are created in odd
|
|
sized lumps. The designers of the a.out format chose to not use the
|
|
data within the section for storing part of the offset; all the offset
|
|
is kept within the reloc. Anything in the data should be ignored.
|
|
|
|
save %sp,-112,%sp
|
|
sethi %hi(_foo+0x12345678),%g2
|
|
ldsb [%g2+%lo(_foo+0x12345678)],%i0
|
|
ret
|
|
restore
|
|
|
|
Both relocs contain a pointer to `foo', and the offsets contain junk.
|
|
|
|
RELOCATION RECORDS FOR [.text]:
|
|
offset type value
|
|
00000004 HI22 _foo+0x12345678
|
|
00000008 LO10 _foo+0x12345678
|
|
|
|
00000000 9de3bf90 ; save %sp,-112,%sp
|
|
00000004 05000000 ; sethi %hi(_foo+0),%g2
|
|
00000008 f048a000 ; ldsb [%g2+%lo(_foo+0)],%i0
|
|
0000000c 81c7e008 ; ret
|
|
00000010 81e80000 ; restore
|
|
|
|
* `howto'
|
|
The `howto' field can be imagined as a relocation instruction. It is
|
|
a pointer to a structure which contains information on what to do with
|
|
all of the other information in the reloc record and data section. A
|
|
back end would normally have a relocation instruction set and turn
|
|
relocations into pointers to the correct structure on input - but it
|
|
would be possible to create each howto field on demand.
|
|
|
|
`enum complain_overflow'
|
|
........................
|
|
|
|
Indicates what sort of overflow checking should be done when
|
|
performing a relocation.
|
|
|
|
|
|
enum complain_overflow
|
|
{
|
|
/* Do not complain on overflow. */
|
|
complain_overflow_dont,
|
|
|
|
/* Complain if the bitfield overflows, whether it is considered
|
|
as signed or unsigned. */
|
|
complain_overflow_bitfield,
|
|
|
|
/* Complain if the value overflows when considered as signed
|
|
number. */
|
|
complain_overflow_signed,
|
|
|
|
/* Complain if the value overflows when considered as an
|
|
unsigned number. */
|
|
complain_overflow_unsigned
|
|
};
|
|
|
|
`reloc_howto_type'
|
|
..................
|
|
|
|
The `reloc_howto_type' is a structure which contains all the
|
|
information that libbfd needs to know to tie up a back end's data.
|
|
|
|
struct symbol_cache_entry; /* Forward declaration. */
|
|
|
|
struct reloc_howto_struct
|
|
{
|
|
/* The type field has mainly a documentary use - the back end can
|
|
do what it wants with it, though normally the back end's
|
|
external idea of what a reloc number is stored
|
|
in this field. For example, a PC relative word relocation
|
|
in a coff environment has the type 023 - because that's
|
|
what the outside world calls a R_PCRWORD reloc. */
|
|
unsigned int type;
|
|
|
|
/* The value the final relocation is shifted right by. This drops
|
|
unwanted data from the relocation. */
|
|
unsigned int rightshift;
|
|
|
|
/* The size of the item to be relocated. This is *not* a
|
|
power-of-two measure. To get the number of bytes operated
|
|
on by a type of relocation, use bfd_get_reloc_size. */
|
|
int size;
|
|
|
|
/* The number of bits in the item to be relocated. This is used
|
|
when doing overflow checking. */
|
|
unsigned int bitsize;
|
|
|
|
/* Notes that the relocation is relative to the location in the
|
|
data section of the addend. The relocation function will
|
|
subtract from the relocation value the address of the location
|
|
being relocated. */
|
|
bfd_boolean pc_relative;
|
|
|
|
/* The bit position of the reloc value in the destination.
|
|
The relocated value is left shifted by this amount. */
|
|
unsigned int bitpos;
|
|
|
|
/* What type of overflow error should be checked for when
|
|
relocating. */
|
|
enum complain_overflow complain_on_overflow;
|
|
|
|
/* If this field is non null, then the supplied function is
|
|
called rather than the normal function. This allows really
|
|
strange relocation methods to be accomodated (e.g., i960 callj
|
|
instructions). */
|
|
bfd_reloc_status_type (*special_function)
|
|
PARAMS ((bfd *, arelent *, struct symbol_cache_entry *, PTR, asection *,
|
|
bfd *, char **));
|
|
|
|
/* The textual name of the relocation type. */
|
|
char *name;
|
|
|
|
/* Some formats record a relocation addend in the section contents
|
|
rather than with the relocation. For ELF formats this is the
|
|
distinction between USE_REL and USE_RELA (though the code checks
|
|
for USE_REL == 1/0). The value of this field is TRUE if the
|
|
addend is recorded with the section contents; when performing a
|
|
partial link (ld -r) the section contents (the data) will be
|
|
modified. The value of this field is FALSE if addends are
|
|
recorded with the relocation (in arelent.addend); when performing
|
|
a partial link the relocation will be modified.
|
|
All relocations for all ELF USE_RELA targets should set this field
|
|
to FALSE (values of TRUE should be looked on with suspicion).
|
|
However, the converse is not true: not all relocations of all ELF
|
|
USE_REL targets set this field to TRUE. Why this is so is peculiar
|
|
to each particular target. For relocs that aren't used in partial
|
|
links (e.g. GOT stuff) it doesn't matter what this is set to. */
|
|
bfd_boolean partial_inplace;
|
|
|
|
/* src_mask selects the part of the instruction (or data) to be used
|
|
in the relocation sum. If the target relocations don't have an
|
|
addend in the reloc, eg. ELF USE_REL, src_mask will normally equal
|
|
dst_mask to extract the addend from the section contents. If
|
|
relocations do have an addend in the reloc, eg. ELF USE_RELA, this
|
|
field should be zero. Non-zero values for ELF USE_RELA targets are
|
|
bogus as in those cases the value in the dst_mask part of the
|
|
section contents should be treated as garbage. */
|
|
bfd_vma src_mask;
|
|
|
|
/* dst_mask selects which parts of the instruction (or data) are
|
|
replaced with a relocated value. */
|
|
bfd_vma dst_mask;
|
|
|
|
/* When some formats create PC relative instructions, they leave
|
|
the value of the pc of the place being relocated in the offset
|
|
slot of the instruction, so that a PC relative relocation can
|
|
be made just by adding in an ordinary offset (e.g., sun3 a.out).
|
|
Some formats leave the displacement part of an instruction
|
|
empty (e.g., m88k bcs); this flag signals the fact. */
|
|
bfd_boolean pcrel_offset;
|
|
};
|
|
|
|
`The HOWTO Macro'
|
|
.................
|
|
|
|
*Description*
|
|
The HOWTO define is horrible and will go away.
|
|
#define HOWTO(C, R, S, B, P, BI, O, SF, NAME, INPLACE, MASKSRC, MASKDST, PC) \
|
|
{ (unsigned) C, R, S, B, P, BI, O, SF, NAME, INPLACE, MASKSRC, MASKDST, PC }
|
|
|
|
*Description*
|
|
And will be replaced with the totally magic way. But for the moment, we
|
|
are compatible, so do it this way.
|
|
#define NEWHOWTO(FUNCTION, NAME, SIZE, REL, IN) \
|
|
HOWTO (0, 0, SIZE, 0, REL, 0, complain_overflow_dont, FUNCTION, \
|
|
NAME, FALSE, 0, 0, IN)
|
|
|
|
*Description*
|
|
This is used to fill in an empty howto entry in an array.
|
|
#define EMPTY_HOWTO(C) \
|
|
HOWTO ((C), 0, 0, 0, FALSE, 0, complain_overflow_dont, NULL, \
|
|
NULL, FALSE, 0, 0, FALSE)
|
|
|
|
*Description*
|
|
Helper routine to turn a symbol into a relocation value.
|
|
#define HOWTO_PREPARE(relocation, symbol) \
|
|
{ \
|
|
if (symbol != (asymbol *) NULL) \
|
|
{ \
|
|
if (bfd_is_com_section (symbol->section)) \
|
|
{ \
|
|
relocation = 0; \
|
|
} \
|
|
else \
|
|
{ \
|
|
relocation = symbol->value; \
|
|
} \
|
|
} \
|
|
}
|
|
|
|
`bfd_get_reloc_size'
|
|
....................
|
|
|
|
*Synopsis*
|
|
unsigned int bfd_get_reloc_size (reloc_howto_type *);
|
|
*Description*
|
|
For a reloc_howto_type that operates on a fixed number of bytes, this
|
|
returns the number of bytes operated on.
|
|
|
|
`arelent_chain'
|
|
...............
|
|
|
|
*Description*
|
|
How relocs are tied together in an `asection':
|
|
typedef struct relent_chain
|
|
{
|
|
arelent relent;
|
|
struct relent_chain *next;
|
|
}
|
|
arelent_chain;
|
|
|
|
`bfd_check_overflow'
|
|
....................
|
|
|
|
*Synopsis*
|
|
bfd_reloc_status_type
|
|
bfd_check_overflow
|
|
(enum complain_overflow how,
|
|
unsigned int bitsize,
|
|
unsigned int rightshift,
|
|
unsigned int addrsize,
|
|
bfd_vma relocation);
|
|
*Description*
|
|
Perform overflow checking on RELOCATION which has BITSIZE significant
|
|
bits and will be shifted right by RIGHTSHIFT bits, on a machine with
|
|
addresses containing ADDRSIZE significant bits. The result is either of
|
|
`bfd_reloc_ok' or `bfd_reloc_overflow'.
|
|
|
|
`bfd_perform_relocation'
|
|
........................
|
|
|
|
*Synopsis*
|
|
bfd_reloc_status_type
|
|
bfd_perform_relocation
|
|
(bfd *abfd,
|
|
arelent *reloc_entry,
|
|
PTR data,
|
|
asection *input_section,
|
|
bfd *output_bfd,
|
|
char **error_message);
|
|
*Description*
|
|
If OUTPUT_BFD is supplied to this function, the generated image will be
|
|
relocatable; the relocations are copied to the output file after they
|
|
have been changed to reflect the new state of the world. There are two
|
|
ways of reflecting the results of partial linkage in an output file: by
|
|
modifying the output data in place, and by modifying the relocation
|
|
record. Some native formats (e.g., basic a.out and basic coff) have no
|
|
way of specifying an addend in the relocation type, so the addend has
|
|
to go in the output data. This is no big deal since in these formats
|
|
the output data slot will always be big enough for the addend. Complex
|
|
reloc types with addends were invented to solve just this problem. The
|
|
ERROR_MESSAGE argument is set to an error message if this return
|
|
`bfd_reloc_dangerous'.
|
|
|
|
`bfd_install_relocation'
|
|
........................
|
|
|
|
*Synopsis*
|
|
bfd_reloc_status_type
|
|
bfd_install_relocation
|
|
(bfd *abfd,
|
|
arelent *reloc_entry,
|
|
PTR data, bfd_vma data_start,
|
|
asection *input_section,
|
|
char **error_message);
|
|
*Description*
|
|
This looks remarkably like `bfd_perform_relocation', except it does not
|
|
expect that the section contents have been filled in. I.e., it's
|
|
suitable for use when creating, rather than applying a relocation.
|
|
|
|
For now, this function should be considered reserved for the
|
|
assembler.
|
|
|