|
|
|
@ -462,6 +462,13 @@ rx_elf_relocate_section |
|
|
|
struct elf_link_hash_entry ** sym_hashes; |
|
|
|
Elf_Internal_Rela * rel; |
|
|
|
Elf_Internal_Rela * relend; |
|
|
|
bfd_boolean pid_mode; |
|
|
|
bfd_boolean saw_subtract = FALSE; |
|
|
|
|
|
|
|
if (elf_elfheader (output_bfd)->e_flags & E_FLAG_RX_PID) |
|
|
|
pid_mode = TRUE; |
|
|
|
else |
|
|
|
pid_mode = FALSE; |
|
|
|
|
|
|
|
symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr; |
|
|
|
sym_hashes = elf_sym_hashes (input_bfd); |
|
|
|
@ -488,6 +495,9 @@ rx_elf_relocate_section |
|
|
|
sec = NULL; |
|
|
|
relocation = 0; |
|
|
|
|
|
|
|
if (rx_stack_top == 0) |
|
|
|
saw_subtract = FALSE; |
|
|
|
|
|
|
|
if (r_symndx < symtab_hdr->sh_info) |
|
|
|
{ |
|
|
|
sym = local_syms + r_symndx; |
|
|
|
@ -553,6 +563,28 @@ rx_elf_relocate_section |
|
|
|
_bfd_error_handler (_("%B:%A: Warning: deprecated Red Hat reloc " type " detected against: %s."), \ |
|
|
|
input_bfd, input_section, name) |
|
|
|
|
|
|
|
/* Check for unsafe relocs in PID mode. These are any relocs where
|
|
|
|
an absolute address is being computed. There are special cases |
|
|
|
for relocs against symbols that are known to be referenced in |
|
|
|
crt0.o before the PID base address register has been initialised. */ |
|
|
|
#define UNSAFE_FOR_PID \ |
|
|
|
do \ |
|
|
|
{ \ |
|
|
|
if (pid_mode \ |
|
|
|
&& sec != NULL \ |
|
|
|
&& sec->flags & SEC_READONLY \ |
|
|
|
&& !(input_section->flags & SEC_DEBUGGING) \ |
|
|
|
&& strcmp (name, "__pid_base") != 0 \ |
|
|
|
&& strcmp (name, "__gp") != 0 \ |
|
|
|
&& strcmp (name, "__romdatastart") != 0 \ |
|
|
|
&& !saw_subtract) \ |
|
|
|
_bfd_error_handler (_("%B(%A): unsafe PID relocation %s at 0x%08lx (against %s in %s)"), \ |
|
|
|
input_bfd, input_section, howto->name, \ |
|
|
|
input_section->output_section->vma + input_section->output_offset + rel->r_offset, \ |
|
|
|
name, sec->name); \ |
|
|
|
} \ |
|
|
|
while (0) |
|
|
|
|
|
|
|
/* Opcode relocs are always big endian. Data relocs are bi-endian. */ |
|
|
|
switch (r_type) |
|
|
|
{ |
|
|
|
@ -573,16 +605,19 @@ rx_elf_relocate_section |
|
|
|
WARN_REDHAT ("RX_RH_8_NEG"); |
|
|
|
relocation = - relocation; |
|
|
|
case R_RX_DIR8S_PCREL: |
|
|
|
UNSAFE_FOR_PID; |
|
|
|
RANGE (-128, 127); |
|
|
|
OP (0) = relocation; |
|
|
|
break; |
|
|
|
|
|
|
|
case R_RX_DIR8S: |
|
|
|
UNSAFE_FOR_PID; |
|
|
|
RANGE (-128, 255); |
|
|
|
OP (0) = relocation; |
|
|
|
break; |
|
|
|
|
|
|
|
case R_RX_DIR8U: |
|
|
|
UNSAFE_FOR_PID; |
|
|
|
RANGE (0, 255); |
|
|
|
OP (0) = relocation; |
|
|
|
break; |
|
|
|
@ -591,6 +626,7 @@ rx_elf_relocate_section |
|
|
|
WARN_REDHAT ("RX_RH_16_NEG"); |
|
|
|
relocation = - relocation; |
|
|
|
case R_RX_DIR16S_PCREL: |
|
|
|
UNSAFE_FOR_PID; |
|
|
|
RANGE (-32768, 32767); |
|
|
|
#if RX_OPCODE_BIG_ENDIAN |
|
|
|
#else |
|
|
|
@ -601,6 +637,7 @@ rx_elf_relocate_section |
|
|
|
|
|
|
|
case R_RX_RH_16_OP: |
|
|
|
WARN_REDHAT ("RX_RH_16_OP"); |
|
|
|
UNSAFE_FOR_PID; |
|
|
|
RANGE (-32768, 32767); |
|
|
|
#if RX_OPCODE_BIG_ENDIAN |
|
|
|
OP (1) = relocation; |
|
|
|
@ -612,6 +649,7 @@ rx_elf_relocate_section |
|
|
|
break; |
|
|
|
|
|
|
|
case R_RX_DIR16S: |
|
|
|
UNSAFE_FOR_PID; |
|
|
|
RANGE (-32768, 65535); |
|
|
|
if (BIGE (output_bfd) && !(input_section->flags & SEC_CODE)) |
|
|
|
{ |
|
|
|
@ -626,6 +664,7 @@ rx_elf_relocate_section |
|
|
|
break; |
|
|
|
|
|
|
|
case R_RX_DIR16U: |
|
|
|
UNSAFE_FOR_PID; |
|
|
|
RANGE (0, 65536); |
|
|
|
#if RX_OPCODE_BIG_ENDIAN |
|
|
|
OP (1) = relocation; |
|
|
|
@ -637,6 +676,7 @@ rx_elf_relocate_section |
|
|
|
break; |
|
|
|
|
|
|
|
case R_RX_DIR16: |
|
|
|
UNSAFE_FOR_PID; |
|
|
|
RANGE (-32768, 65536); |
|
|
|
#if RX_OPCODE_BIG_ENDIAN |
|
|
|
OP (1) = relocation; |
|
|
|
@ -648,6 +688,7 @@ rx_elf_relocate_section |
|
|
|
break; |
|
|
|
|
|
|
|
case R_RX_DIR16_REV: |
|
|
|
UNSAFE_FOR_PID; |
|
|
|
RANGE (-32768, 65536); |
|
|
|
#if RX_OPCODE_BIG_ENDIAN |
|
|
|
OP (0) = relocation; |
|
|
|
@ -665,6 +706,7 @@ rx_elf_relocate_section |
|
|
|
break; |
|
|
|
|
|
|
|
case R_RX_RH_24_NEG: |
|
|
|
UNSAFE_FOR_PID; |
|
|
|
WARN_REDHAT ("RX_RH_24_NEG"); |
|
|
|
relocation = - relocation; |
|
|
|
case R_RX_DIR24S_PCREL: |
|
|
|
@ -681,6 +723,7 @@ rx_elf_relocate_section |
|
|
|
break; |
|
|
|
|
|
|
|
case R_RX_RH_24_OP: |
|
|
|
UNSAFE_FOR_PID; |
|
|
|
WARN_REDHAT ("RX_RH_24_OP"); |
|
|
|
RANGE (-0x800000, 0x7fffff); |
|
|
|
#if RX_OPCODE_BIG_ENDIAN |
|
|
|
@ -695,6 +738,7 @@ rx_elf_relocate_section |
|
|
|
break; |
|
|
|
|
|
|
|
case R_RX_DIR24S: |
|
|
|
UNSAFE_FOR_PID; |
|
|
|
RANGE (-0x800000, 0x7fffff); |
|
|
|
if (BIGE (output_bfd) && !(input_section->flags & SEC_CODE)) |
|
|
|
{ |
|
|
|
@ -711,6 +755,7 @@ rx_elf_relocate_section |
|
|
|
break; |
|
|
|
|
|
|
|
case R_RX_RH_24_UNS: |
|
|
|
UNSAFE_FOR_PID; |
|
|
|
WARN_REDHAT ("RX_RH_24_UNS"); |
|
|
|
RANGE (0, 0xffffff); |
|
|
|
#if RX_OPCODE_BIG_ENDIAN |
|
|
|
@ -725,6 +770,7 @@ rx_elf_relocate_section |
|
|
|
break; |
|
|
|
|
|
|
|
case R_RX_RH_32_NEG: |
|
|
|
UNSAFE_FOR_PID; |
|
|
|
WARN_REDHAT ("RX_RH_32_NEG"); |
|
|
|
relocation = - relocation; |
|
|
|
#if RX_OPCODE_BIG_ENDIAN |
|
|
|
@ -741,6 +787,7 @@ rx_elf_relocate_section |
|
|
|
break; |
|
|
|
|
|
|
|
case R_RX_RH_32_OP: |
|
|
|
UNSAFE_FOR_PID; |
|
|
|
WARN_REDHAT ("RX_RH_32_OP"); |
|
|
|
#if RX_OPCODE_BIG_ENDIAN |
|
|
|
OP (3) = relocation; |
|
|
|
@ -920,6 +967,7 @@ rx_elf_relocate_section |
|
|
|
/* Complex reloc handling: */ |
|
|
|
|
|
|
|
case R_RX_ABS32: |
|
|
|
UNSAFE_FOR_PID; |
|
|
|
RX_STACK_POP (relocation); |
|
|
|
#if RX_OPCODE_BIG_ENDIAN |
|
|
|
OP (3) = relocation; |
|
|
|
@ -935,6 +983,7 @@ rx_elf_relocate_section |
|
|
|
break; |
|
|
|
|
|
|
|
case R_RX_ABS32_REV: |
|
|
|
UNSAFE_FOR_PID; |
|
|
|
RX_STACK_POP (relocation); |
|
|
|
#if RX_OPCODE_BIG_ENDIAN |
|
|
|
OP (0) = relocation; |
|
|
|
@ -951,6 +1000,7 @@ rx_elf_relocate_section |
|
|
|
|
|
|
|
case R_RX_ABS24S_PCREL: |
|
|
|
case R_RX_ABS24S: |
|
|
|
UNSAFE_FOR_PID; |
|
|
|
RX_STACK_POP (relocation); |
|
|
|
RANGE (-0x800000, 0x7fffff); |
|
|
|
if (BIGE (output_bfd) && !(input_section->flags & SEC_CODE)) |
|
|
|
@ -968,6 +1018,7 @@ rx_elf_relocate_section |
|
|
|
break; |
|
|
|
|
|
|
|
case R_RX_ABS16: |
|
|
|
UNSAFE_FOR_PID; |
|
|
|
RX_STACK_POP (relocation); |
|
|
|
RANGE (-32768, 65535); |
|
|
|
#if RX_OPCODE_BIG_ENDIAN |
|
|
|
@ -980,6 +1031,7 @@ rx_elf_relocate_section |
|
|
|
break; |
|
|
|
|
|
|
|
case R_RX_ABS16_REV: |
|
|
|
UNSAFE_FOR_PID; |
|
|
|
RX_STACK_POP (relocation); |
|
|
|
RANGE (-32768, 65535); |
|
|
|
#if RX_OPCODE_BIG_ENDIAN |
|
|
|
@ -1008,6 +1060,7 @@ rx_elf_relocate_section |
|
|
|
break; |
|
|
|
|
|
|
|
case R_RX_ABS16U: |
|
|
|
UNSAFE_FOR_PID; |
|
|
|
RX_STACK_POP (relocation); |
|
|
|
RANGE (0, 65536); |
|
|
|
#if RX_OPCODE_BIG_ENDIAN |
|
|
|
@ -1020,6 +1073,7 @@ rx_elf_relocate_section |
|
|
|
break; |
|
|
|
|
|
|
|
case R_RX_ABS16UL: |
|
|
|
UNSAFE_FOR_PID; |
|
|
|
RX_STACK_POP (relocation); |
|
|
|
relocation >>= 2; |
|
|
|
RANGE (0, 65536); |
|
|
|
@ -1033,6 +1087,7 @@ rx_elf_relocate_section |
|
|
|
break; |
|
|
|
|
|
|
|
case R_RX_ABS16UW: |
|
|
|
UNSAFE_FOR_PID; |
|
|
|
RX_STACK_POP (relocation); |
|
|
|
relocation >>= 1; |
|
|
|
RANGE (0, 65536); |
|
|
|
@ -1046,18 +1101,21 @@ rx_elf_relocate_section |
|
|
|
break; |
|
|
|
|
|
|
|
case R_RX_ABS8: |
|
|
|
UNSAFE_FOR_PID; |
|
|
|
RX_STACK_POP (relocation); |
|
|
|
RANGE (-128, 255); |
|
|
|
OP (0) = relocation; |
|
|
|
break; |
|
|
|
|
|
|
|
case R_RX_ABS8U: |
|
|
|
UNSAFE_FOR_PID; |
|
|
|
RX_STACK_POP (relocation); |
|
|
|
RANGE (0, 255); |
|
|
|
OP (0) = relocation; |
|
|
|
break; |
|
|
|
|
|
|
|
case R_RX_ABS8UL: |
|
|
|
UNSAFE_FOR_PID; |
|
|
|
RX_STACK_POP (relocation); |
|
|
|
relocation >>= 2; |
|
|
|
RANGE (0, 255); |
|
|
|
@ -1065,14 +1123,16 @@ rx_elf_relocate_section |
|
|
|
break; |
|
|
|
|
|
|
|
case R_RX_ABS8UW: |
|
|
|
UNSAFE_FOR_PID; |
|
|
|
RX_STACK_POP (relocation); |
|
|
|
relocation >>= 1; |
|
|
|
RANGE (0, 255); |
|
|
|
OP (0) = relocation; |
|
|
|
break; |
|
|
|
|
|
|
|
case R_RX_ABS8S_PCREL: |
|
|
|
case R_RX_ABS8S: |
|
|
|
UNSAFE_FOR_PID; |
|
|
|
case R_RX_ABS8S_PCREL: |
|
|
|
RX_STACK_POP (relocation); |
|
|
|
RANGE (-128, 127); |
|
|
|
OP (0) = relocation; |
|
|
|
@ -1082,7 +1142,8 @@ rx_elf_relocate_section |
|
|
|
if (r_symndx < symtab_hdr->sh_info) |
|
|
|
RX_STACK_PUSH (sec->output_section->vma |
|
|
|
+ sec->output_offset |
|
|
|
+ sym->st_value); |
|
|
|
+ sym->st_value |
|
|
|
+ rel->r_addend); |
|
|
|
else |
|
|
|
{ |
|
|
|
if (h != NULL |
|
|
|
@ -1090,7 +1151,8 @@ rx_elf_relocate_section |
|
|
|
|| h->root.type == bfd_link_hash_defweak)) |
|
|
|
RX_STACK_PUSH (h->root.u.def.value |
|
|
|
+ sec->output_section->vma |
|
|
|
+ sec->output_offset); |
|
|
|
+ sec->output_offset |
|
|
|
+ rel->r_addend); |
|
|
|
else |
|
|
|
_bfd_error_handler (_("Warning: RX_SYM reloc with an unknown symbol")); |
|
|
|
} |
|
|
|
@ -1121,6 +1183,7 @@ rx_elf_relocate_section |
|
|
|
{ |
|
|
|
int32_t tmp1, tmp2; |
|
|
|
|
|
|
|
saw_subtract = TRUE; |
|
|
|
RX_STACK_POP (tmp1); |
|
|
|
RX_STACK_POP (tmp2); |
|
|
|
tmp2 -= tmp1; |
|
|
|
@ -1143,6 +1206,7 @@ rx_elf_relocate_section |
|
|
|
{ |
|
|
|
int32_t tmp1, tmp2; |
|
|
|
|
|
|
|
saw_subtract = TRUE; |
|
|
|
RX_STACK_POP (tmp1); |
|
|
|
RX_STACK_POP (tmp2); |
|
|
|
tmp1 /= tmp2; |
|
|
|
@ -2893,7 +2957,7 @@ rx_elf_merge_private_bfd_data (bfd * ibfd, bfd * obfd) |
|
|
|
} |
|
|
|
else if (old_flags != new_flags) |
|
|
|
{ |
|
|
|
flagword known_flags = E_FLAG_RX_64BIT_DOUBLES | E_FLAG_RX_DSP; |
|
|
|
flagword known_flags = E_FLAG_RX_64BIT_DOUBLES | E_FLAG_RX_DSP | E_FLAG_RX_PID; |
|
|
|
|
|
|
|
if ((old_flags ^ new_flags) & known_flags) |
|
|
|
{ |
|
|
|
|