diff options
Diffstat (limited to 'bfd/reloc.c')
-rw-r--r-- | bfd/reloc.c | 85 |
1 files changed, 71 insertions, 14 deletions
diff --git a/bfd/reloc.c b/bfd/reloc.c index 20dd050..93fccdb 100644 --- a/bfd/reloc.c +++ b/bfd/reloc.c @@ -1032,6 +1032,7 @@ _bfd_relocate_contents (howto, input_bfd, relocation, location) bfd_vma check; bfd_signed_vma signed_check; bfd_vma add; + bfd_signed_vma signed_add; if (howto->rightshift == 0) { @@ -1056,18 +1057,24 @@ _bfd_relocate_contents (howto, input_bfd, relocation, location) /* Add in the value from the object file, shifted down so that it is a straight number. */ add = x & howto->src_mask; + if ((add & (((~ howto->src_mask) >> 1) & howto->src_mask)) == 0) + signed_add = add; + else + signed_add = add | ((bfd_vma) -1 &~ howto->src_mask); if (howto->bitpos == 0) { check += add; - signed_check += add; + signed_check += signed_add; } else { - add >>= howto->bitpos; - check += add; - signed_check += (add - | ((bfd_vma) -1 - &~ ((bfd_vma) -1 >> howto->bitpos))); + check += add >> howto->bitpos; + if (signed_add >= 0) + signed_check += signed_add >> howto->bitpos; + else + signed_check += ((signed_add >> howto->bitpos) + | ((bfd_vma) -1 + &~ ((bfd_vma) -1 >> howto->bitpos))); } switch (howto->complain_on_overflow) @@ -1184,6 +1191,7 @@ CODE_FRAGMENT . BFD_RELOC_64, . BFD_RELOC_32, . BFD_RELOC_16, +. BFD_RELOC_14, . BFD_RELOC_8, . . {* PC-relative relocations *} @@ -1208,6 +1216,10 @@ CODE_FRAGMENT . {* 32-bit pc-relative, shifted right 2 bits (i.e., 30-bit . word displacement, e.g. for SPARC) *} . BFD_RELOC_32_PCREL_S2, +. {* signed 16-bit pc-relative, shifted right 2 bits (e.g. for MIPS) *} +. BFD_RELOC_16_PCREL_S2, +. {* this is used on the Alpha *} +. BFD_RELOC_23_PCREL_S2, . . {* High 22 bits of 32-bit value, placed into lower 22 bits of . target word; simple reloc. *} @@ -1215,6 +1227,13 @@ CODE_FRAGMENT . {* Low 10 bits. *} . BFD_RELOC_LO10, . +. {* For systems that allocate a Global Pointer register, these are +. displacements off that register. These relocation types are +. handled specially, because the value the register will have is +. decided relatively late. *} +. BFD_RELOC_GPREL16, +. BFD_RELOC_GPREL32, +. . {* Reloc types used for i960/b.out. *} . BFD_RELOC_I960_CALLJ, . @@ -1256,13 +1275,50 @@ CODE_FRAGMENT . BFD_RELOC_SPARC_LO7, . {* end-sanitize-v9 *} . +. {* Alpha ECOFF relocations. Some of these treat the symbol or "addend" +. in some special way. *} +. {* For GPDISP_HI16 ("gpdisp") relocations, the symbol is ignored when +. writing; when reading, it will be the absolute section symbol. The +. addend is the displacement in bytes of the "lda" instruction from +. the "ldah" instruction (which is at the address of this reloc). *} +. BFD_RELOC_ALPHA_GPDISP_HI16, +. {* For GPDISP_LO16 ("ignore") relocations, the symbol is handled as +. with GPDISP_HI16 relocs. The addend is ignored when writing the +. relocations out, and is filled in with the file's GP value on +. reading, for convenience. *} +. BFD_RELOC_ALPHA_GPDISP_LO16, +. +. {* The Alpha LITERAL/LITUSE relocs are produced by a symbol reference; +. the assembler turns it into a LDQ instruction to load the address of +. the symbol, and then fills in a register in the real instruction. +. +. The LITERAL reloc, at the LDQ instruction, refers to the .lita +. section symbol. The addend is ignored when writing, but is filled +. in with the file's GP value on reading, for convenience, as with the +. GPDISP_LO16 reloc. +. +. The LITUSE reloc, on the instruction using the loaded address, gives +. information to the linker that it might be able to use to optimize +. away some literal section references. The symbol is ignored (read +. as the absolute section symbol), and the "addend" indicates the type +. of instruction using the register: +. 1 - "memory" fmt insn +. 2 - byte-manipulation (byte offset reg) +. 3 - jsr (target of branch) +. +. The GNU linker currently doesn't do any of this optimizing. *} +. BFD_RELOC_ALPHA_LITERAL, +. BFD_RELOC_ALPHA_LITUSE, +. +. {* The HINT relocation indicates a value that should be filled into the +. "hint" field of a jmp/jsr/ret instruction, for possible branch- +. prediction logic which may be provided on some processors. *} +. BFD_RELOC_ALPHA_HINT, +. . {* Bits 27..2 of the relocation address shifted right 2 bits; . simple reloc otherwise. *} . BFD_RELOC_MIPS_JMP, . -. {* signed 16-bit pc-relative, shifted right 2 bits (e.g. for MIPS) *} -. BFD_RELOC_16_PCREL_S2, -. . {* High 16 bits of 32-bit value; simple reloc. *} . BFD_RELOC_HI16, . {* High 16 bits of 32-bit value but the low 16 bits will be sign @@ -1273,8 +1329,8 @@ CODE_FRAGMENT . {* Low 16 bits. *} . BFD_RELOC_LO16, . -. {* 16 bit relocation relative to the global pointer. *} -. BFD_RELOC_MIPS_GPREL, +. {* relocation relative to the global pointer. *} +.#define BFD_RELOC_MIPS_GPREL BFD_RELOC_GPREL16 . . {* Relocation against a MIPS literal section. *} . BFD_RELOC_MIPS_LITERAL, @@ -1282,7 +1338,7 @@ CODE_FRAGMENT . {* MIPS ELF relocations. *} . BFD_RELOC_MIPS_GOT16, . BFD_RELOC_MIPS_CALL16, -. BFD_RELOC_MIPS_GPREL32, +.#define BFD_RELOC_MIPS_GPREL32 BFD_RELOC_GPREL32 . . {* These are, so far, specific to HPPA processors. I'm not sure that some . don't duplicate other reloc types, such as BFD_RELOC_32 and _32_PCREL. @@ -1483,6 +1539,7 @@ DESCRIPTION don't do relaxing -- i.e., does nothing. */ +/*ARGSUSED*/ boolean bfd_generic_relax_section (abfd, section, link_info, symbols) bfd *abfd; @@ -1534,7 +1591,7 @@ bfd_generic_get_relocated_section_contents (abfd, link_info, link_order, data, /* read in the section */ bfd_get_section_contents(input_bfd, input_section, - data, + (PTR) data, 0, input_section->_raw_size); @@ -1556,7 +1613,7 @@ bfd_generic_get_relocated_section_contents (abfd, link_info, link_order, data, bfd_reloc_status_type r= bfd_perform_relocation(input_bfd, *parent, - data, + (PTR) data, input_section, relocateable ? abfd : (bfd *) NULL, &error_message); |