aboutsummaryrefslogtreecommitdiff
path: root/bfd/reloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'bfd/reloc.c')
-rw-r--r--bfd/reloc.c85
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);