forked from Imagelibrary/binutils-gdb
New documentation style
This commit is contained in:
735
bfd/reloc.c
735
bfd/reloc.c
@@ -18,162 +18,165 @@ You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/*doc*
|
||||
@section Relocations
|
||||
/*
|
||||
SECTION
|
||||
Relocations
|
||||
|
||||
BFD maintains relocations in much the same was as it maintains
|
||||
symbols; they are left alone until required, then read in en-mass and
|
||||
traslated into an internal form. There is a common routine
|
||||
@code{bfd_perform_relocation} which acts upon the canonical form to to
|
||||
the actual fixup.
|
||||
DESCRIPTION
|
||||
BFD maintains relocations in much the same was as it maintains
|
||||
symbols; they are left alone until required, then read in
|
||||
en-mass and traslated into an internal form. There is a common
|
||||
routine <<bfd_perform_relocation>> which acts upon the
|
||||
canonical form to to the actual fixup.
|
||||
|
||||
Note that relocations are maintained on a per section basis, whilst
|
||||
symbols are maintained on a per BFD basis.
|
||||
Note that relocations are maintained on a per section basis,
|
||||
whilst symbols are maintained on a per BFD basis.
|
||||
|
||||
All a back end has to do to fit the BFD interface is to create as many
|
||||
@code{struct reloc_cache_entry} as there are relocations in a
|
||||
particuar section, and fill in the right bits:
|
||||
All a back end has to do to fit the BFD interface is to create
|
||||
as many <<struct reloc_cache_entry>> as there are relocations
|
||||
in a particuar section, and fill in the right bits:
|
||||
|
||||
@menu
|
||||
* typedef arelent::
|
||||
* reloc handling functions::
|
||||
* howto manager::
|
||||
@end menu
|
||||
|
||||
*/
|
||||
#include "sysdep.h"
|
||||
#include "bfd.h"
|
||||
#include "sysdep.h"
|
||||
#include "libbfd.h"
|
||||
/*doc
|
||||
@node typedef arelent, Relocations, reloc handling functions, Relocations
|
||||
@section typedef arelent
|
||||
|
||||
|
||||
*/
|
||||
|
||||
/*proto* bfd_perform_relocation
|
||||
The relocation routine returns as a status an enumerated type:
|
||||
|
||||
*+++
|
||||
|
||||
$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,
|
||||
|
||||
Unused
|
||||
|
||||
$ bfd_reloc_notsupported,
|
||||
|
||||
Unsupported relocation size requested.
|
||||
|
||||
$ 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.
|
||||
|
||||
$ bfd_reloc_dangerous
|
||||
$ }
|
||||
$ bfd_reloc_status_enum_type;
|
||||
|
||||
*---
|
||||
|
||||
*/
|
||||
|
||||
/*proto*
|
||||
|
||||
*+++
|
||||
|
||||
$typedef struct reloc_cache_entry
|
||||
${
|
||||
|
||||
A pointer into the canonical table of pointers
|
||||
|
||||
$ struct symbol_cache_entry **sym_ptr_ptr;
|
||||
|
||||
offset in section
|
||||
|
||||
$ rawdata_offset address;
|
||||
|
||||
addend for relocation value
|
||||
|
||||
$ bfd_vma addend;
|
||||
|
||||
if sym is null this is the section
|
||||
|
||||
$ struct sec *section;
|
||||
|
||||
Pointer to how to perform the required relocation
|
||||
|
||||
$ CONST struct reloc_howto_struct *howto;
|
||||
$} arelent;
|
||||
|
||||
*---
|
||||
|
||||
*/
|
||||
|
||||
/*doc*
|
||||
@table @code
|
||||
@item sym_ptr_ptr
|
||||
The symbol table pointer points to a pointer to the symbol associated with the
|
||||
relocation request. This would naturally be the pointer into the table
|
||||
returned by the back end's get_symtab action. @xref{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.
|
||||
@item 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.
|
||||
@item 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:
|
||||
@node typedef arelent, howto manager, Relocations, Relocations
|
||||
|
||||
SUBSECTION
|
||||
typedef arelent
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
bfd_perform_relocation
|
||||
|
||||
DESCRIPTION
|
||||
The relocation routine returns as a status an enumerated type:
|
||||
|
||||
.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,
|
||||
|
||||
Unused
|
||||
|
||||
. bfd_reloc_notsupported,
|
||||
|
||||
Unsupported relocation size requested.
|
||||
|
||||
. 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.
|
||||
|
||||
. 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
|
||||
|
||||
. rawdata_offset address;
|
||||
|
||||
addend for relocation value
|
||||
|
||||
. bfd_vma addend;
|
||||
|
||||
if sym is null this is the section
|
||||
|
||||
. struct sec *section;
|
||||
|
||||
Pointer to how to perform the required relocation
|
||||
|
||||
. CONST struct reloc_howto_struct *howto;
|
||||
.} arelent;
|
||||
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
DESCRIPTION
|
||||
|
||||
o sym_ptr_ptr
|
||||
The symbol table pointer points to a pointer to the symbol
|
||||
associated with the relocation request. This would naturally
|
||||
be the pointer into the table returned by the back end's
|
||||
get_symtab action. @xref{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.
|
||||
|
||||
o 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. @item 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:
|
||||
|
||||
EXAMPLE
|
||||
|
||||
*+
|
||||
char foo[];
|
||||
main()
|
||||
{
|
||||
return foo[0x12345678];
|
||||
}
|
||||
*-
|
||||
Could be compiled into:
|
||||
|
||||
*+
|
||||
DESCRIPTION
|
||||
Could be compiled into:
|
||||
|
||||
EXAMPLE
|
||||
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)
|
||||
DESCRIPTION
|
||||
|
||||
*+
|
||||
This could create a reloc pointing to foo, but leave the
|
||||
offset in the data (something like)
|
||||
|
||||
EXAMPLE
|
||||
RELOCATION RECORDS FOR [.text]:
|
||||
OFFSET TYPE VALUE
|
||||
offset type value
|
||||
00000006 32 _foo
|
||||
|
||||
00000000 4e56 fffc ; linkw fp,#-4
|
||||
@@ -181,54 +184,59 @@ OFFSET TYPE VALUE
|
||||
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:
|
||||
DESCRIPTION
|
||||
|
||||
*+
|
||||
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:
|
||||
|
||||
EXAMPLE
|
||||
or.u r13,r0,hi16(_foo+0x12345678)
|
||||
ld.b r2,r13,lo16(_foo+0x12345678)
|
||||
jmp r1
|
||||
*-
|
||||
This whould create two relocs, both pointing to _foo, and with 0x12340000
|
||||
in their addend field. The data would consist of:
|
||||
|
||||
*+
|
||||
DESCRIPTION
|
||||
This whould create two relocs, both pointing to _foo, and with
|
||||
0x12340000 in their addend field. The data would consist of:
|
||||
|
||||
EXAMPLE
|
||||
RELOCATION RECORDS FOR [.text]:
|
||||
OFFSET TYPE VALUE
|
||||
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.
|
||||
|
||||
On 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 odd
|
||||
sized lumps. The designers of the a.out format chose not to use the
|
||||
data within the section for storing part of the offset; all the offset
|
||||
is kept within the reloc. Any thing in the data should be ignored.
|
||||
DESCRIPTION
|
||||
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.
|
||||
|
||||
*+
|
||||
On 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 odd sized lumps. The designers of
|
||||
the a.out format chose not to use the data within the section
|
||||
for storing part of the offset; all the offset is kept within
|
||||
the reloc. Any thing in the data should be ignored.
|
||||
EXAMPLE
|
||||
save %sp,-112,%sp
|
||||
sethi %hi(_foo+0x12345678),%g2
|
||||
ldsb [%g2+%lo(_foo+0x12345678)],%i0
|
||||
ret
|
||||
restore
|
||||
*-
|
||||
Both relocs contains a pointer to foo, and the offsets would contain junk.
|
||||
|
||||
*+
|
||||
DESCRIPTION
|
||||
Both relocs contains a pointer to foo, and the offsets would
|
||||
contain junk.
|
||||
|
||||
EXAMPLE
|
||||
|
||||
RELOCATION RECORDS FOR [.text]:
|
||||
OFFSET TYPE VALUE
|
||||
offset type value
|
||||
00000004 HI22 _foo+0x12345678
|
||||
00000008 LO10 _foo+0x12345678
|
||||
|
||||
@@ -237,198 +245,214 @@ OFFSET TYPE VALUE
|
||||
00000008 f048a000 ; ldsb [%g2+%lo(_foo+0)],%i0
|
||||
0000000c 81c7e008 ; ret
|
||||
00000010 81e80000 ; restore
|
||||
*-
|
||||
@item section
|
||||
The section field is only used when the symbol pointer field is null.
|
||||
It supplies the section into which the data should be relocated. The
|
||||
field's main use comes from assemblers which do most of the symbol fixups
|
||||
themselves; an assembler may take an internal reference to a label,
|
||||
but since it knows where the label is, it can turn the relocation
|
||||
request from a symbol lookup into a section relative relocation - the
|
||||
relocation emitted has no symbol, just a section to relocate against.
|
||||
|
||||
I'm not sure what it means when both a symbol pointer an a section
|
||||
pointer are present. Some formats use this sort of mechanism to
|
||||
describe PIC relocations, but BFD can't to that sort of thing yet.
|
||||
@item howto
|
||||
The howto field can be imagined as a relocation instruction. It is a
|
||||
pointer to a struct which contains information on what to do with all
|
||||
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.
|
||||
@end table
|
||||
DESCRIPTION
|
||||
|
||||
o section
|
||||
The section field is only used when the symbol pointer field
|
||||
is null. It supplies the section into which the data should be
|
||||
relocated. The field's main use comes from assemblers which do
|
||||
most of the symbol fixups themselves; an assembler may take an
|
||||
internal reference to a label, but since it knows where the
|
||||
label is, it can turn the relocation request from a symbol
|
||||
lookup into a section relative relocation - the relocation
|
||||
emitted has no symbol, just a section to relocate against. I'm
|
||||
not sure what it means when both a symbol pointer an a section
|
||||
pointer are present. Some formats use this sort of mechanism
|
||||
to describe PIC relocations, but BFD can't to that sort of
|
||||
thing yet. @item howto The howto field can be imagined as a
|
||||
relocation instruction. It is a pointer to a struct which
|
||||
contains information on what to do with all 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.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/*proto* reloc_howto_type
|
||||
The @code{reloc_howto_type} is a structure which contains all the
|
||||
information that BFD needs to know to tie up a back end's data.
|
||||
/*
|
||||
SUBSUBSECTION
|
||||
<<reloc_howto_type>>
|
||||
|
||||
*+++
|
||||
DESCRIPTION
|
||||
The <<reloc_howto_type>> is a structure which contains all the
|
||||
information that BFD needs to know to tie up a back end's data.
|
||||
|
||||
$typedef CONST struct reloc_howto_struct
|
||||
${
|
||||
The type field has mainly a documetary use - the back end can to what
|
||||
it wants with it, though the normally the back end's external idea of
|
||||
what a reloc number would be would be stored in this field. For
|
||||
example, the a PC relative word relocation in a coff environment would
|
||||
have the type 023 - because that's what the outside world calls a
|
||||
R_PCRWORD reloc.
|
||||
.typedef CONST struct reloc_howto_struct
|
||||
.{
|
||||
The type field has mainly a documetary use - the back end can
|
||||
to what it wants with it, though the normally the back end's
|
||||
external idea of what a reloc number would be would be stored
|
||||
in this field. For example, the a PC relative word relocation
|
||||
in a coff environment would have the type 023 - because that's
|
||||
what the outside world calls a R_PCRWORD reloc.
|
||||
|
||||
$ unsigned int type;
|
||||
. unsigned int type;
|
||||
|
||||
The value the final relocation is shifted right by. This drops
|
||||
unwanted data from the relocation.
|
||||
The value the final relocation is shifted right by. This drops
|
||||
unwanted data from the relocation.
|
||||
|
||||
$ unsigned int rightshift;
|
||||
. unsigned int rightshift;
|
||||
|
||||
The size of the item to be relocated - 0, is one byte, 1 is 2 bytes, 3
|
||||
is four bytes.
|
||||
The size of the item to be relocated - 0, is one byte, 1 is 2
|
||||
bytes, 3 is four bytes.
|
||||
|
||||
$ unsigned int size;
|
||||
. unsigned int size;
|
||||
|
||||
Now obsolete
|
||||
Now obsolete
|
||||
|
||||
$ unsigned int bitsize;
|
||||
. 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.
|
||||
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.
|
||||
|
||||
$ boolean pc_relative;
|
||||
. boolean pc_relative;
|
||||
|
||||
Now obsolete
|
||||
Now obsolete
|
||||
|
||||
$ unsigned int bitpos;
|
||||
. unsigned int bitpos;
|
||||
|
||||
Now obsolete
|
||||
Now obsolete
|
||||
|
||||
$ boolean absolute;
|
||||
. boolean absolute;
|
||||
|
||||
Causes the relocation routine to return an error if overflow is
|
||||
detected when relocating.
|
||||
Causes the relocation routine to return an error if overflow
|
||||
is detected when relocating.
|
||||
|
||||
$ boolean complain_on_overflow;
|
||||
. boolean 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 (eg, i960 callj instructions).
|
||||
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 (eg, i960 callj
|
||||
instructions).
|
||||
|
||||
$ bfd_reloc_status_enum_type (*special_function)();
|
||||
. bfd_reloc_status_type (*special_function)();
|
||||
|
||||
The textual name of the relocation type.
|
||||
The textual name of the relocation type.
|
||||
|
||||
$ char *name;
|
||||
. char *name;
|
||||
|
||||
When performing a partial link, some formats must modify the
|
||||
relocations rather than the data - this flag signals this.
|
||||
When performing a partial link, some formats must modify the
|
||||
relocations rather than the data - this flag signals this.
|
||||
|
||||
$ boolean partial_inplace;
|
||||
. boolean partial_inplace;
|
||||
|
||||
The src_mask is used to select what parts of the read in data are to
|
||||
be used in the relocation sum. Eg, if this was an 8 bit bit of data
|
||||
which we read and relocated, this would be 0x000000ff. When we have
|
||||
relocs which have an addend, such as sun4 extended relocs, the value
|
||||
in the offset part of a relocating field is garbage so we never use
|
||||
it. In this case the mask would be 0x00000000.
|
||||
The src_mask is used to select what parts of the read in data
|
||||
are to be used in the relocation sum. Eg, if this was an 8 bit
|
||||
bit of data which we read and relocated, this would be
|
||||
0x000000ff. When we have relocs which have an addend, such as
|
||||
sun4 extended relocs, the value in the offset part of a
|
||||
relocating field is garbage so we never use it. In this case
|
||||
the mask would be 0x00000000.
|
||||
. bfd_word src_mask;
|
||||
|
||||
$ bfd_word src_mask;
|
||||
The dst_mask is what parts of the instruction are replaced into the
|
||||
instruction. In most cases src_mask == dst_mask, except in the above
|
||||
special case, where dst_mask would be 0x000000ff, and src_mask would
|
||||
be 0x00000000.
|
||||
The dst_mask is what parts of the instruction are replaced
|
||||
into the instruction. In most cases src_mask == dst_mask,
|
||||
except in the above special case, where dst_mask would be
|
||||
0x000000ff, and src_mask would be 0x00000000.
|
||||
. bfd_word dst_mask;
|
||||
|
||||
$ bfd_word 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 (eg sun3 a.out). Some formats leave the
|
||||
displacement part of an instruction empty (eg m88k bcs), this flag
|
||||
signals the fact.
|
||||
|
||||
$ boolean pcrel_offset;
|
||||
$} reloc_howto_type;
|
||||
*---
|
||||
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 (eg sun3 a.out).
|
||||
Some formats leave the displacement part of an instruction
|
||||
empty (eg m88k bcs), this flag signals the fact.
|
||||
. boolean pcrel_offset;
|
||||
.} reloc_howto_type;
|
||||
|
||||
*/
|
||||
|
||||
/*proto* HOWTO
|
||||
The HOWTO define is horrible and will go away.
|
||||
*+
|
||||
#define HOWTO(C, R,S,B, P, BI, ABS, O, SF, NAME, INPLACE, MASKSRC, MASKDST, PC) \
|
||||
{(unsigned)C,R,S,B, P, BI, ABS,O,SF,NAME,INPLACE,MASKSRC,MASKDST,PC}
|
||||
*-
|
||||
|
||||
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,false,false,FUNCTION, NAME,false,0,0,IN)
|
||||
*-
|
||||
|
||||
Helper routine to turn a symbol into a relocation value.
|
||||
|
||||
*+
|
||||
/*
|
||||
FUNCTION
|
||||
HOWTO
|
||||
DESCRIPTION
|
||||
The HOWTO define is horrible and will go away.
|
||||
|
||||
|
||||
#define HOWTO_PREPARE(relocation, symbol) \
|
||||
{ \
|
||||
if (symbol != (asymbol *)NULL) { \
|
||||
if (symbol->flags & BSF_FORT_COMM) { \
|
||||
relocation = 0; \
|
||||
} \
|
||||
else { \
|
||||
relocation = symbol->value; \
|
||||
} \
|
||||
} \
|
||||
if (symbol->section != (asection *)NULL) { \
|
||||
relocation += symbol->section->output_section->vma + \
|
||||
symbol->section->output_offset; \
|
||||
} \
|
||||
}
|
||||
*-
|
||||
.#define HOWTO(C, R,S,B, P, BI, ABS, O, SF, NAME, INPLACE, MASKSRC, MASKDST, PC) \
|
||||
. {(unsigned)C,R,S,B, P, BI, ABS,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,false,false,FUNCTION, NAME,false,0,0,IN)
|
||||
.
|
||||
DESCRIPTION
|
||||
Helper routine to turn a symbol into a relocation value.
|
||||
|
||||
.#define HOWTO_PREPARE(relocation, symbol) \
|
||||
. { \
|
||||
. if (symbol != (asymbol *)NULL) { \
|
||||
. if (symbol->flags & BSF_FORT_COMM) { \
|
||||
. relocation = 0; \
|
||||
. } \
|
||||
. else { \
|
||||
. relocation = symbol->value; \
|
||||
. } \
|
||||
. } \
|
||||
. if (symbol->section != (asection *)NULL) { \
|
||||
. relocation += symbol->section->output_section->vma + \
|
||||
. symbol->section->output_offset; \
|
||||
. } \
|
||||
.}
|
||||
|
||||
*/
|
||||
|
||||
/*proto* reloc_chain
|
||||
*+
|
||||
typedef unsigned char bfd_byte;
|
||||
/*
|
||||
TYPEDEF
|
||||
reloc_chain
|
||||
|
||||
typedef struct relent_chain {
|
||||
arelent relent;
|
||||
struct relent_chain *next;
|
||||
} arelent_chain;
|
||||
DESCRIPTION
|
||||
|
||||
*-
|
||||
How relocs are tied together
|
||||
|
||||
.typedef unsigned char bfd_byte;
|
||||
.
|
||||
.typedef struct relent_chain {
|
||||
. arelent relent;
|
||||
. struct relent_chain *next;
|
||||
.} arelent_chain;
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*proto*
|
||||
If an 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 (eg 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.
|
||||
*; PROTO(bfd_reloc_status_enum_type,
|
||||
bfd_perform_relocation,
|
||||
/*
|
||||
FUNCTION
|
||||
bfd_perform_relocation
|
||||
|
||||
DESCRIPTION
|
||||
If an 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 (eg 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.
|
||||
|
||||
SYNOPSIS
|
||||
bfd_reloc_status_type
|
||||
bfd_perform_relocation
|
||||
(bfd * abfd,
|
||||
arelent *reloc_entry,
|
||||
PTR data,
|
||||
asection *input_section,
|
||||
bfd *output_bfd));
|
||||
bfd *output_bfd);
|
||||
*/
|
||||
|
||||
|
||||
bfd_reloc_status_enum_type
|
||||
bfd_reloc_status_type
|
||||
DEFUN(bfd_perform_relocation,(abfd,
|
||||
reloc_entry,
|
||||
data,
|
||||
@@ -441,7 +465,7 @@ DEFUN(bfd_perform_relocation,(abfd,
|
||||
bfd *output_bfd)
|
||||
{
|
||||
bfd_vma relocation;
|
||||
bfd_reloc_status_enum_type flag = bfd_reloc_ok;
|
||||
bfd_reloc_status_type flag = bfd_reloc_ok;
|
||||
bfd_vma addr = reloc_entry->address ;
|
||||
bfd_vma output_base = 0;
|
||||
reloc_howto_type *howto = reloc_entry->howto;
|
||||
@@ -460,7 +484,7 @@ DEFUN(bfd_perform_relocation,(abfd,
|
||||
}
|
||||
|
||||
if (howto->special_function){
|
||||
bfd_reloc_status_enum_type cont;
|
||||
bfd_reloc_status_type cont;
|
||||
cont = howto->special_function(abfd,
|
||||
reloc_entry,
|
||||
symbol,
|
||||
@@ -671,67 +695,120 @@ DEFUN(bfd_perform_relocation,(abfd,
|
||||
|
||||
|
||||
|
||||
/*doc*
|
||||
/*
|
||||
@node howto manager, , typedef arelent, Relocations
|
||||
SECTION
|
||||
The howto manager
|
||||
|
||||
@section The howto manager
|
||||
|
||||
|
||||
When an application wants to create a relocation, but doesn't know
|
||||
what the target machine might call it, it can find out by using this
|
||||
bit of code.
|
||||
DESCRIPTION
|
||||
When an application wants to create a relocation, but doesn't
|
||||
know what the target machine might call it, it can find out by
|
||||
using this bit of code.
|
||||
|
||||
*/
|
||||
|
||||
/*proto* bfd_reloc_code_enum_type
|
||||
/*
|
||||
TYPEDEF
|
||||
bfd_reloc_code_type
|
||||
|
||||
*+++
|
||||
DESCRIPTION
|
||||
The insides of a reloc code
|
||||
|
||||
$typedef enum
|
||||
${
|
||||
.typedef enum bfd_reloc_code_real {
|
||||
|
||||
16 bits wide, simple reloc
|
||||
16 bits wide, simple reloc
|
||||
|
||||
$ BFD_RELOC_16,
|
||||
. BFD_RELOC_16,
|
||||
|
||||
8 bits wide, but used to form an address like 0xffnn
|
||||
8 bits wide, but used to form an address like 0xffnn
|
||||
|
||||
$ BFD_RELOC_8_FFnn,
|
||||
. BFD_RELOC_8_FFnn,
|
||||
|
||||
8 bits wide, simple
|
||||
8 bits wide, simple
|
||||
|
||||
$ BFD_RELOC_8,
|
||||
. BFD_RELOC_8,
|
||||
|
||||
8 bits wide, pc relative
|
||||
8 bits wide, pc relative
|
||||
|
||||
. BFD_RELOC_8_PCREL,
|
||||
|
||||
The type of reloc used to build a contructor table - at the
|
||||
moment probably a 32 bit wide abs address, but the cpu can
|
||||
choose.
|
||||
|
||||
. BFD_RELOC_CTOR
|
||||
|
||||
. } bfd_reloc_code_real_type;
|
||||
|
||||
$ BFD_RELOC_8_PCREL
|
||||
$ } bfd_reloc_code_enum_real_type;
|
||||
|
||||
*---
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*proto* bfd_reloc_type_lookup
|
||||
This routine returns a pointer to a howto struct which when invoked,
|
||||
will perform the supplied relocation on data from the architecture
|
||||
noted.
|
||||
/*
|
||||
SECTION
|
||||
bfd_reloc_type_lookup
|
||||
|
||||
[Note] This function will go away.
|
||||
DESCRIPTION
|
||||
This routine returns a pointer to a howto struct which when
|
||||
invoked, will perform the supplied relocation on data from the
|
||||
architecture noted.
|
||||
|
||||
*; PROTO(CONST struct reloc_howto_struct *,
|
||||
bfd_reloc_type_lookup,
|
||||
(CONST bfd_arch_info_struct_type *arch, bfd_reloc_code_enum_type code));
|
||||
SYNOPSIS
|
||||
CONST struct reloc_howto_struct *
|
||||
bfd_reloc_type_lookup
|
||||
(CONST bfd_arch_info_type *arch, bfd_reloc_code_type code);
|
||||
*/
|
||||
|
||||
|
||||
CONST struct reloc_howto_struct *
|
||||
DEFUN(bfd_reloc_type_lookup,(arch, code),
|
||||
CONST bfd_arch_info_struct_type *arch AND
|
||||
bfd_reloc_code_enum_type code)
|
||||
CONST bfd_arch_info_type *arch AND
|
||||
bfd_reloc_code_type code)
|
||||
{
|
||||
return arch->reloc_type_lookup(arch, code);
|
||||
}
|
||||
|
||||
static reloc_howto_type bfd_howto_32 =
|
||||
HOWTO(0, 00,2,32,false,0,false,true,0,"VRT32", false,0xffffffff,0xffffffff,true);
|
||||
|
||||
|
||||
/*
|
||||
INTERNAL FUNCTION
|
||||
bfd_default_reloc_type_lookup
|
||||
|
||||
DESCRIPTION
|
||||
Provides a default relocation lookuperer for any architectue
|
||||
|
||||
SYNOPSIS
|
||||
CONST struct reloc_howto_struct *bfd_default_reloc_type_lookup
|
||||
(CONST struct bfd_arch_info *,
|
||||
bfd_reloc_code_type code);
|
||||
|
||||
*/
|
||||
CONST struct reloc_howto_struct *
|
||||
DEFUN(bfd_default_reloc_type_lookup,(arch, code),
|
||||
CONST struct bfd_arch_info *arch AND
|
||||
bfd_reloc_code_type code)
|
||||
{
|
||||
switch (code)
|
||||
{
|
||||
case BFD_RELOC_CTOR:
|
||||
/* The type of reloc used in a ctor, which will be as wide as the
|
||||
address - so either a 64, 32, or 16 bitter.. */
|
||||
switch (arch->bits_per_address) {
|
||||
case 64:
|
||||
BFD_FAIL();
|
||||
case 32:
|
||||
return &bfd_howto_32;
|
||||
case 16:
|
||||
BFD_FAIL();
|
||||
default:
|
||||
BFD_FAIL();
|
||||
}
|
||||
default:
|
||||
BFD_FAIL();
|
||||
}
|
||||
return (struct reloc_howto_struct *)NULL;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user