diff options
Diffstat (limited to 'bfd/reloc.c')
-rw-r--r-- | bfd/reloc.c | 891 |
1 files changed, 457 insertions, 434 deletions
diff --git a/bfd/reloc.c b/bfd/reloc.c index e22d920..622d198 100644 --- a/bfd/reloc.c +++ b/bfd/reloc.c @@ -22,7 +22,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ SECTION Relocations -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 @@ -37,338 +36,299 @@ DESCRIPTION in a particuar section, and fill in the right bits: @menu -* typedef arelent:: -* howto manager:: +@* typedef arelent:: +@* howto manager:: @end menu */ #include "bfd.h" #include "sysdep.h" #include "libbfd.h" +#include "seclet.h" /*doc* -@node typedef arelent, howto manager, Relocations, Relocations +INODE + 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 + This is the structure of a relocation entry: +CODE_FRAGMENT +. +.typedef enum bfd_reloc_status +.{ +. {* No errors detected *} . bfd_reloc_ok, - - The relocation was performed, but there was an overflow. - +. +. {* The relocation was performed, but there was an overflow. *} . bfd_reloc_overflow, - - The address to relocate was not within the section supplied - +. +. {* The address to relocate was not within the section supplied*} . bfd_reloc_outofrange, - - Used by special functions - +. +. {* Used by special functions *} . bfd_reloc_continue, - - Unused - +. +. {* Unused *} . bfd_reloc_notsupported, - - Unsupported relocation size requested. - +. +. {* Unsupported relocation size requested. *} . bfd_reloc_other, - - The symbol to relocate against was undefined. - +. +. {* 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. - +. +. {* 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; +. +. {* Pointer to how to perform the required relocation *} +. CONST struct reloc_howto_struct *howto; +. +.} arelent; - A pointer into the canonical table of pointers +*/ -. struct symbol_cache_entry **sym_ptr_ptr; +/* +DESCRIPTION - offset in section + Here is a description of each of the fields within a relent: -. rawdata_offset address; + o sym_ptr_ptr - addend for relocation value + 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. -. bfd_vma addend; + o address - if sym is null this is the section + 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: -. struct sec *section; - Pointer to how to perform the required relocation +| char foo[]; +| main() +| { +| return foo[0x12345678]; +| } -. CONST struct reloc_howto_struct *howto; -.} arelent; + Could be compiled into: +| linkw fp,#-4 +| moveb @@#12345678,d0 +| extbl d0 +| unlk fp +| rts -*/ -/* -DESCRIPTION + This could create a reloc pointing to foo, but leave the + offset in the data (something like) - 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]; - } -DESCRIPTION - Could be compiled into: +|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 -EXAMPLE - linkw fp,#-4 - moveb @@#12345678,d0 - extbl d0 - unlk fp - rts -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: - 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 -00000006 32 _foo +| or.u r13,r0,hi16(_foo+0x12345678) +| ld.b r2,r13,lo16(_foo+0x12345678) +| jmp r1 -00000000 4e56 fffc ; linkw fp,#-4 -00000004 1039 1234 5678 ; moveb @@#12345678,d0 -0000000a 49c0 ; extbl d0 -0000000c 4e5e ; unlk fp -0000000e 4e75 ; rts -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: + This whould create two relocs, both pointing to _foo, and with + 0x12340000 in their addend field. The data would consist of: -EXAMPLE - or.u r13,r0,hi16(_foo+0x12345678) - ld.b r2,r13,lo16(_foo+0x12345678) - jmp r1 -DESCRIPTION - This whould 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 -EXAMPLE -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 -00000000 5da05678 ; or.u r13,r0,0x5678 -00000004 1c4d5678 ; ld.b r2,r13,0x5678 -00000008 f400c001 ; jmp r1 -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 + 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. -DESCRIPTION - Both relocs contains a pointer to foo, and the offsets would - contain junk. + 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 -RELOCATION RECORDS FOR [.text]: -offset type value -00000004 HI22 _foo+0x12345678 -00000008 LO10 _foo+0x12345678 + Both relocs contains a pointer to foo, and the offsets would + contain junk. -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 -DESCRIPTION +|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 + - 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. - + o 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. + */ /* SUBSUBSECTION - <<reloc_howto_type>> + <<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. + 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. +CODE_FRAGMENT +. .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. - +. {* 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; - - 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; - - 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; - - Now obsolete - +. +. {* Now obsolete *} . 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; - - Now obsolete - +. +. {* Now obsolete *} . unsigned int bitpos; - - Now obsolete - +. +. {* Now obsolete *} . 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; - - 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_type (*special_function)(); - - The textual name of the relocation type. - +. +. {* The textual name of the relocation type. *} . 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; - - 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; - - 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; - - 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. +. +. {* 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; */ /* FUNCTION - HOWTO + the HOWTO macro + DESCRIPTION The HOWTO define is horrible and will go away. @@ -386,21 +346,17 @@ DESCRIPTION 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; \ -. } \ -.} +.#define HOWTO_PREPARE(relocation, symbol) \ +. { \ +. if (symbol != (asymbol *)NULL) { \ +. if (symbol->section == &bfd_com_section) { \ +. relocation = 0; \ +. } \ +. else { \ +. relocation = symbol->value; \ +. } \ +. } \ +.} */ @@ -427,6 +383,15 @@ DESCRIPTION FUNCTION bfd_perform_relocation +SYNOPSIS + bfd_reloc_status_type + bfd_perform_relocation + (bfd * abfd, + arelent *reloc_entry, + PTR data, + asection *input_section, + bfd *output_bfd); + DESCRIPTION If an output_bfd is supplied to this function the generated image will be relocatable, the relocations are copied to the @@ -441,14 +406,6 @@ DESCRIPTION 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); */ @@ -469,29 +426,24 @@ DEFUN(bfd_perform_relocation,(abfd, bfd_vma addr = reloc_entry->address ; bfd_vma output_base = 0; reloc_howto_type *howto = reloc_entry->howto; - asection *reloc_target_output_section; - asection *reloc_target_input_section; + asection *reloc_target_output_section ; + asymbol *symbol; - if (reloc_entry->sym_ptr_ptr) { - symbol = *( reloc_entry->sym_ptr_ptr); - if ((symbol->flags & BSF_UNDEFINED) && output_bfd == (bfd *)NULL) { + symbol = *( reloc_entry->sym_ptr_ptr); + if ((symbol->section == &bfd_und_section) && output_bfd == (bfd *)NULL) { flag = bfd_reloc_undefined; } - } - else { - symbol = (asymbol*)NULL; - } if (howto->special_function){ - bfd_reloc_status_type cont; - cont = howto->special_function(abfd, - reloc_entry, - symbol, - data, - input_section); - if (cont != bfd_reloc_continue) return cont; - } + bfd_reloc_status_type cont; + cont = howto->special_function(abfd, + reloc_entry, + symbol, + data, + input_section); + if (cont != bfd_reloc_continue) return cont; + } /* Work out which section the relocation is targetted at and the @@ -499,116 +451,90 @@ DEFUN(bfd_perform_relocation,(abfd, */ - if (symbol != (asymbol *)NULL){ - if (symbol->flags & BSF_FORT_COMM) { + if (symbol->section == &bfd_com_section) { relocation = 0; } - else { + else { relocation = symbol->value; } - if (symbol->section != (asection *)NULL) - { - reloc_target_input_section = symbol->section; - } - else { - reloc_target_input_section = (asection *)NULL; - } - } - else if (reloc_entry->section != (asection *)NULL) - { - relocation = 0; - reloc_target_input_section = reloc_entry->section; - } - else { - relocation = 0; - reloc_target_input_section = (asection *)NULL; - } - - if (reloc_target_input_section != (asection *)NULL) { - reloc_target_output_section = - reloc_target_input_section->output_section; + reloc_target_output_section = symbol->section->output_section; - if (output_bfd && howto->partial_inplace==false) { + if (output_bfd && howto->partial_inplace==false) { output_base = 0; } - else { + else { output_base = reloc_target_output_section->vma; } - relocation += output_base + reloc_target_input_section->output_offset; - } + relocation += output_base + symbol->section->output_offset; + relocation += reloc_entry->addend ; - if(reloc_entry->address > (bfd_vma)(input_section->size)) - { - return bfd_reloc_outofrange; - } + if(reloc_entry->address > input_section->_cooked_size) + { + return bfd_reloc_outofrange; + } if (howto->pc_relative == true) - { - /* - Anything which started out as pc relative should end up that - way too. - - There are two ways we can see a pcrel instruction. Sometimes - the pcrel displacement has been partially calculated, it - includes the distance from the start of the section to the - instruction in it (eg sun3), and sometimes the field is - totally blank - eg m88kbcs. - */ + { + /* + Anything which started out as pc relative should end up that + way too. + + There are two ways we can see a pcrel instruction. Sometimes + the pcrel displacement has been partially calculated, it + includes the distance from the start of the section to the + instruction in it (eg sun3), and sometimes the field is + totally blank - eg m88kbcs. + */ - relocation -= - input_section->output_section->vma + input_section->output_offset; - - if (howto->pcrel_offset == true) { - relocation -= reloc_entry->address; - } + relocation -= + input_section->output_section->vma + input_section->output_offset; + if (howto->pcrel_offset == true) { + relocation -= reloc_entry->address; } + } + if (output_bfd!= (bfd *)NULL) { - if ( howto->partial_inplace == false) { - /* - This is a partial relocation, and we want to apply the relocation - to the reloc entry rather than the raw data. Modify the reloc - inplace to reflect what we now know. - */ - reloc_entry->addend = relocation ; - reloc_entry->section = reloc_target_input_section; - if (reloc_target_input_section != (asection *)NULL) { - /* If we know the output section we can forget the symbol */ - reloc_entry->sym_ptr_ptr = (asymbol**)NULL; + if ( howto->partial_inplace == false) { + /* + This is a partial relocation, and we want to apply the relocation + to the reloc entry rather than the raw data. Modify the reloc + inplace to reflect what we now know. + */ + reloc_entry->addend = relocation ; + reloc_entry->address += input_section->output_offset; + return flag; + } + else + { + /* This is a partial relocation, but inplace, so modify the + reloc record a bit. + + If we've relocated with a symbol with a section, change + into a ref to the section belonging to the symbol + */ + reloc_entry->addend = relocation ; + reloc_entry->address += input_section->output_offset; + + } - reloc_entry->address += - input_section->output_offset; - return flag; } - else - { - /* This is a partial relocation, but inplace, so modify the - reloc record a bit. - - If we've relocated with a symbol with a section, change - into a ref to the section belonging to the symbol - */ - - if (symbol != (asymbol *)NULL && reloc_target_input_section != (asection *)NULL) - { - reloc_entry->section = reloc_target_input_section; - reloc_entry->sym_ptr_ptr = (asymbol **)NULL; - } - - } - } - + else + { + reloc_entry->addend = 0; +} + /* @@ -658,37 +584,37 @@ DEFUN(bfd_perform_relocation,(abfd, #define DOIT(x) \ x = ( (x & ~howto->dst_mask) | (((x & howto->src_mask) + relocation) & howto->dst_mask)) - switch (howto->size) - { - case 0: - { - char x = bfd_get_8(abfd, (char *)data + addr); - DOIT(x); - bfd_put_8(abfd,x, (unsigned char *) data + addr); - } - break; - - case 1: - { - short x = bfd_get_16(abfd, (bfd_byte *)data + addr); - DOIT(x); - bfd_put_16(abfd, x, (unsigned char *)data + addr); - } - break; - case 2: - { - long x = bfd_get_32(abfd, (bfd_byte *) data + addr); - DOIT(x); - bfd_put_32(abfd,x, (bfd_byte *)data + addr); - } - break; - case 3: - - /* Do nothing */ - break; - default: - return bfd_reloc_other; - } + switch (howto->size) + { + case 0: + { + char x = bfd_get_8(abfd, (char *)data + addr); + DOIT(x); + bfd_put_8(abfd,x, (unsigned char *) data + addr); + } + break; + + case 1: + { + short x = bfd_get_16(abfd, (bfd_byte *)data + addr); + DOIT(x); + bfd_put_16(abfd, x, (unsigned char *)data + addr); + } + break; + case 2: + { + long x = bfd_get_32(abfd, (bfd_byte *) data + addr); + DOIT(x); + bfd_put_32(abfd,x, (bfd_byte *)data + addr); + } + break; + case 3: + + /* Do nothing */ + break; + default: + return bfd_reloc_other; + } return flag; } @@ -696,11 +622,12 @@ DEFUN(bfd_perform_relocation,(abfd, /* -@node howto manager, , typedef arelent, Relocations +INODE + howto manager, , typedef arelent, Relocations + SECTION The howto manager -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. @@ -714,34 +641,28 @@ TYPEDEF DESCRIPTION The insides of a reloc code -.typedef enum bfd_reloc_code_real { - - 16 bits wide, simple reloc - -. BFD_RELOC_16, - - 8 bits wide, but used to form an address like 0xffnn - +CODE_FRAGMENT +. +.typedef enum bfd_reloc_code_real +.{ +. {* 16 bits wide, simple reloc *} +. BFD_RELOC_16, +. +. {* 8 bits wide, but used to form an address like 0xffnn *} . BFD_RELOC_8_FFnn, - - 8 bits wide, simple - +. +. {* 8 bits wide, simple *} . 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. - +. +. {* 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; - - - */ @@ -750,15 +671,16 @@ DESCRIPTION SECTION bfd_reloc_type_lookup +SYNOPSIS + CONST struct reloc_howto_struct * + bfd_reloc_type_lookup + (CONST bfd_arch_info_type *arch, bfd_reloc_code_type code); + DESCRIPTION This routine returns a pointer to a howto struct which when invoked, will perform the supplied relocation on data from the architecture noted. -SYNOPSIS - CONST struct reloc_howto_struct * - bfd_reloc_type_lookup - (CONST bfd_arch_info_type *arch, bfd_reloc_code_type code); */ @@ -775,17 +697,18 @@ static reloc_howto_type bfd_howto_32 = /* -INTERNAL FUNCTION +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); +DESCRIPTION + Provides a default relocation lookuperer for any architectue + + */ CONST struct reloc_howto_struct * DEFUN(bfd_default_reloc_type_lookup,(arch, code), @@ -812,3 +735,103 @@ DEFUN(bfd_default_reloc_type_lookup,(arch, code), } return (struct reloc_howto_struct *)NULL; } + + + +/* +INTERNAL_FUNCTION + bfd_generic_get_relocated_section_contents + +SYNOPSIS + bfd_byte * + bfd_generic_get_relocated_section_contents(bfd *abfd, + struct bfd_seclet_struct *seclet) + +DESCRIPTION + Provides default handling of relocation effort for back ends + which can't be bothered to do it efficiently. + +*/ + +bfd_byte * +DEFUN(bfd_generic_get_relocated_section_contents,(abfd, seclet), + bfd *abfd AND + struct bfd_seclet_struct *seclet) +{ + extern bfd_error_vector_type bfd_error_vector; + + + asymbol **symbols = 0; + + /* Get enough memory to hold the stuff */ + bfd *input_bfd = seclet->u.indirect.section->owner; + asection *input_section = seclet->u.indirect.section; + + bfd_byte *data = (bfd_byte *)malloc(input_section->_raw_size); + bfd_byte *dst = data; + bfd_byte *prev_dst = data; + unsigned int gap = 0; + + bfd_size_type reloc_size = bfd_get_reloc_upper_bound(input_bfd, + input_section); + arelent **reloc_vector = (arelent **)malloc(reloc_size); + + /* read in the section */ + bfd_get_section_contents(input_bfd, + input_section, + data, + 0, + input_section->_raw_size); + +/* We're not relaxing the section, so just copy the size info */ + input_section->_cooked_size = input_section->_raw_size; + input_section->reloc_done = true; + + + if (bfd_canonicalize_reloc(input_bfd, + input_section, + reloc_vector, + seclet->u.indirect.symbols) ) + { + arelent **parent; + for (parent = reloc_vector; * parent != (arelent *)NULL; + parent++) + { + bfd_reloc_status_type r= + bfd_perform_relocation(input_bfd, + *parent, + data, + input_section, 0); + + + if (r != bfd_reloc_ok) + { + asymbol *s; + + switch (r) + { + case bfd_reloc_undefined: + bfd_error_vector.undefined_symbol(*parent, seclet); + break; + case bfd_reloc_dangerous: + bfd_error_vector.reloc_dangerous(*parent, seclet); + break; + case bfd_reloc_outofrange: + case bfd_reloc_overflow: + bfd_error_vector.reloc_value_truncated(*parent, seclet); + break; + default: + abort(); + break; + } + + } + } + } + + free((char *)reloc_vector); + return data; + + +} + |