| This is bfd.info, produced by makeinfo version 4.1 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 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. */ |
| 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. */ |
| boolean partial_inplace; |
| |
| /* The src_mask selects which parts of the read in data |
| are to be used in the relocation sum. E.g., if this was an 8 bit |
| byte 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_vma src_mask; |
| |
| /* The dst_mask selects which 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_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. */ |
| 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. |
| |