aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorJeff Law <law@redhat.com>1993-12-14 07:36:15 +0000
committerJeff Law <law@redhat.com>1993-12-14 07:36:15 +0000
commita36b6f1d05754890fe380571cff36c54fcc20065 (patch)
treece574b30fd13dcec197ce7b8a0dcde3d37ce7f64 /bfd
parent9d5a9b20fed1032fe96027b2edb6bef752722ef0 (diff)
downloadgdb-a36b6f1d05754890fe380571cff36c54fcc20065.zip
gdb-a36b6f1d05754890fe380571cff36c54fcc20065.tar.gz
gdb-a36b6f1d05754890fe380571cff36c54fcc20065.tar.bz2
* elf32-hppa.c (hppa_elf_gen_reloc_type): Handle 'T' field
selectors for PIC code. * som.c (hppa_som_gen_reloc_type): Handle 'T' field selectors. (som_write_fixups): Handle R_DLT_REL, R_FSEL, R_RSEL, R_LSEL relocations needed by PIC.
Diffstat (limited to 'bfd')
-rw-r--r--bfd/ChangeLog9
-rw-r--r--bfd/elf32-hppa.c95
-rw-r--r--bfd/som.c46
3 files changed, 128 insertions, 22 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index c29f2fe..b045532 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,12 @@
+Mon Dec 13 23:34:48 1993 Jeffrey A. Law (law@snake.cs.utah.edu)
+
+ * elf32-hppa.c (hppa_elf_gen_reloc_type): Handle 'T' field
+ selectors for PIC code.
+
+ * som.c (hppa_som_gen_reloc_type): Handle 'T' field selectors.
+ (som_write_fixups): Handle R_DLT_REL, R_FSEL, R_RSEL, R_LSEL
+ relocations needed by PIC.
+
Tue Dec 7 15:47:51 1993 Stu Grossman (grossman at cygnus.com)
* nlmcode.h: Fixes to avoid compiler warnings...
diff --git a/bfd/elf32-hppa.c b/bfd/elf32-hppa.c
index b677e4d..4f15c62 100644
--- a/bfd/elf32-hppa.c
+++ b/bfd/elf32-hppa.c
@@ -524,11 +524,15 @@ hppa_elf_gen_reloc_type (abfd, base_type, format, field)
case e_rpsel:
final_type = R_HPPA_PLABEL_R11;
break;
- case e_lpsel:
case e_tsel:
- case e_ltsel:
+ final_type = R_HPPA_DLT_11;
+ break;
case e_rtsel:
+ final_type = R_HPPA_DLT_R11;
+ break;
+ case e_lpsel:
+ case e_ltsel:
case e_lsel:
case e_lrsel:
case e_lssel:
@@ -564,10 +568,15 @@ hppa_elf_gen_reloc_type (abfd, base_type, format, field)
case e_rpsel:
final_type = R_HPPA_PLABEL_R14;
break;
- case e_lpsel:
case e_tsel:
- case e_ltsel:
+ final_type = R_HPPA_DLT_14;
+ break;
case e_rtsel:
+ final_type = R_HPPA_DLT_R14;
+ break;
+
+ case e_lpsel:
+ case e_ltsel:
case e_fsel:
case e_lsel:
@@ -626,6 +635,9 @@ hppa_elf_gen_reloc_type (abfd, base_type, format, field)
case e_lpsel:
final_type = R_HPPA_PLABEL_L21;
break;
+ case e_ltsel:
+ final_type = R_HPPA_PLABEL_L21;
+ break;
case e_rsel:
case e_rssel:
case e_rdsel:
@@ -646,6 +658,9 @@ hppa_elf_gen_reloc_type (abfd, base_type, format, field)
case e_psel:
final_type = R_HPPA_PLABEL_32;
break;
+ case e_tsel:
+ final_type == R_HPPA_DLT_32;
+ break;
default:
UNDEFINED;
final_type = base_type;
@@ -1561,7 +1576,16 @@ hppa_elf_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd)
jump after the call returns (GCC optimization). */
if (insn & 2)
- insn = BLE_N_XXX_0_0;
+ {
+ insn = BLE_N_XXX_0_0;
+ bfd_put_32 (abfd, insn, hit_data);
+ r_type = R_HPPA_ABS_CALL_17;
+ r_pcrel = 0;
+ insn = hppa_elf_relocate_insn (abfd, input_section, insn,
+ addr, symbol_in, sym_value,
+ r_addend, r_type, r_format,
+ r_field, r_pcrel);
+ }
else
{
unsigned long old_delay_slot_insn = bfd_get_32 (abfd, hit_data + 4);
@@ -1584,16 +1608,29 @@ hppa_elf_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd)
new_delay_slot_insn |= ((31 << 21) | (31 << 16));
bfd_put_32 (abfd, new_delay_slot_insn, hit_data + 4);
insn = BLE_XXX_0_0;
- bfd_put_32 (abfd, insn, hit_data);
r_type = R_HPPA_ABS_CALL_17;
r_pcrel = 0;
insn = hppa_elf_relocate_insn (abfd, input_section, insn,
addr, symbol_in, sym_value,
r_addend, r_type, r_format,
r_field, r_pcrel);
- bfd_put_32 (abfd, insn, hit_data + 4);
+ bfd_put_32 (abfd, insn, hit_data);
return bfd_reloc_ok;
}
+ else if (rtn_reg == 31)
+ {
+ /* The return register is r31, so this is a millicode
+ call. Do not perform any instruction reordering. */
+ insn = BLE_XXX_0_0;
+ r_type = R_HPPA_ABS_CALL_17;
+ r_pcrel = 0;
+ insn = hppa_elf_relocate_insn (abfd, input_section, insn,
+ addr, symbol_in, sym_value,
+ r_addend, r_type, r_format,
+ r_field, r_pcrel);
+ bfd_put_32 (abfd, insn, hit_data);
+ return bfd_reloc_ok;
+ }
else
{
/* Check to see if the delay slot instruction has a
@@ -1619,6 +1656,20 @@ hppa_elf_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd)
return bfd_reloc_ok;
}
}
+ else if (rtn_reg == 31)
+ {
+ /* The return register is r31, so this is a millicode call.
+ Perform no instruction reordering in this case. */
+ insn = BLE_XXX_0_0;
+ r_type = R_HPPA_ABS_CALL_17;
+ r_pcrel = 0;
+ insn = hppa_elf_relocate_insn (abfd, input_section, insn,
+ addr, symbol_in, sym_value,
+ r_addend, r_type, r_format,
+ r_field, r_pcrel);
+ bfd_put_32 (abfd, insn, hit_data);
+ return bfd_reloc_ok;
+ }
else
{
/* Check to see if the delay slot instruction has a
@@ -2363,7 +2414,9 @@ hppa_elf_build_arg_reloc_stub (abfd, output_bfd, reloc_entry,
sizeof (asymbol *));
reloc_entry->sym_ptr_ptr[0] = stub_sym;
if (reloc_entry->howto->type != R_HPPA_PLABEL_32
- && (get_opcode(insn) == BLE || get_opcode (insn) == BE))
+ && (get_opcode(insn) == BLE
+ || get_opcode (insn) == BE
+ || get_opcode (insn) == BL))
reloc_entry->howto = bfd_reloc_type_lookup (abfd, R_HPPA_STUB_CALL_17);
}
else
@@ -2385,7 +2438,9 @@ hppa_elf_build_arg_reloc_stub (abfd, output_bfd, reloc_entry,
sizeof (asymbol *));
reloc_entry->sym_ptr_ptr[0] = stub_sym;
if (reloc_entry->howto->type != R_HPPA_PLABEL_32
- && (get_opcode (insn) == BLE || get_opcode (insn) == BE))
+ && (get_opcode (insn) == BLE
+ || get_opcode (insn) == BE
+ || get_opcode (insn) == BL))
reloc_entry->howto = bfd_reloc_type_lookup (abfd, R_HPPA_STUB_CALL_17);
/* Generate common code for all stubs. */
@@ -2796,6 +2851,20 @@ hppa_elf_build_long_branch_stub (abfd, output_bfd, reloc_entry, symbol, data)
if (strcmp (symbol->name, "$$dyncall") == 0)
dyncall = true;
+
+ /* If we are creating a call from a stub to another stub, then
+ never do the instruction reordering. We can tell if we are
+ going to be calling one stub from another by the fact that
+ the symbol name has '_stub_' (arg. reloc. stub) or '_lb_stub_'
+ prepended to the name. Alternatively, the section of the
+ symbol will be '.hppa_linker_stubs'. */
+
+ if ((strncmp (symbol->name, "_stub_", 6) == 0)
+ || (strncmp (symbol->name, "_lb_stub_", 9) == 0))
+ {
+ BFD_ASSERT (strcmp (symbol->section->name, ".hppa_linker_stubs") == 0);
+ rtn_adjust = false;
+ }
/* Check to see if we modify the return pointer
in the delay slot of the branch. */
@@ -2812,6 +2881,8 @@ hppa_elf_build_long_branch_stub (abfd, output_bfd, reloc_entry, symbol, data)
if (get_opcode (delay_insn) == LDO
&& (((delay_insn & 0x001f0000) >> 16) == rtn_reg))
rtn_adjust = false;
+ if (milli)
+ rtn_adjust = false;
}
}
@@ -2896,12 +2967,13 @@ hppa_elf_build_long_branch_stub (abfd, output_bfd, reloc_entry, symbol, data)
/* 2. Make the call. */
if (!milli)
{
- NEW_INSTRUCTION (stub_entry, BE_N_XXX_0_31);
+ NEW_INSTRUCTION (stub_entry, BE_XXX_0_31);
hppa_elf_stub_reloc (stub_desc,
abfd,
target_sym,
CURRENT_STUB_OFFSET (stub_entry),
R_HPPA_ABS_CALL_R17);
+ NEW_INSTRUCTION (stub_entry, COPY_2_31);
}
else
{
@@ -2931,12 +3003,13 @@ hppa_elf_build_long_branch_stub (abfd, output_bfd, reloc_entry, symbol, data)
CURRENT_STUB_OFFSET (stub_entry),
R_HPPA_L21);
- NEW_INSTRUCTION (stub_entry, BE_N_XXX_0_31);
+ NEW_INSTRUCTION (stub_entry, BE_XXX_0_31);
hppa_elf_stub_reloc (stub_desc,
abfd,
target_sym,
CURRENT_STUB_OFFSET (stub_entry),
R_HPPA_ABS_CALL_R17);
+ NEW_INSTRUCTION (stub_entry, COPY_2_31);
}
}
return stub_sym;
diff --git a/bfd/som.c b/bfd/som.c
index 08ef811..de23ef4 100644
--- a/bfd/som.c
+++ b/bfd/som.c
@@ -1356,11 +1356,18 @@ hppa_som_gen_reloc_type (abfd, base_type, format, field)
case e_psel:
case e_lpsel:
case e_rpsel:
+ final_types[0] = final_type;
+ final_types[1] = NULL;
+ final_types[2] = NULL;
+ *final_type = base_type;
+ break;
+
case e_tsel:
case e_ltsel:
case e_rtsel:
- final_types[0] = final_type;
- final_types[1] = NULL;
+ final_types[0] = (int *) bfd_alloc_by_size_t (abfd, sizeof (int));
+ *final_types[0] = R_FSEL;
+ final_types[1] = final_type;
final_types[2] = NULL;
*final_type = base_type;
break;
@@ -1409,15 +1416,20 @@ hppa_som_gen_reloc_type (abfd, base_type, format, field)
if (field == e_psel
|| field == e_lpsel
|| field == e_rpsel)
- {
- /* A PLABEL relocation that has a size of 32 bits must
- be a R_DATA_PLABEL. All others are R_CODE_PLABELs. */
- if (format == 32)
- *final_type = R_DATA_PLABEL;
- else
- *final_type = R_CODE_PLABEL;
- }
- /* A relocatoin in the data space is always a full 32bits. */
+ {
+ /* A PLABEL relocation that has a size of 32 bits must
+ be a R_DATA_PLABEL. All others are R_CODE_PLABELs. */
+ if (format == 32)
+ *final_type = R_DATA_PLABEL;
+ else
+ *final_type = R_CODE_PLABEL;
+ }
+ /* PIC stuff. */
+ else if (field == e_tsel
+ || field == e_ltsel
+ || field == e_rtsel)
+ *final_type = R_DLT_REL;
+ /* A relocation in the data space is always a full 32bits. */
else if (format == 32)
*final_type = R_DATA_ONE_SYMBOL;
@@ -2197,6 +2209,9 @@ som_write_fixups (abfd, current_offset, total_reloc_sizep)
case R_S_MODE:
case R_D_MODE:
case R_R_MODE:
+ case R_FSEL:
+ case R_LSEL:
+ case R_RSEL:
reloc_offset = bfd_reloc->address;
break;
@@ -2249,6 +2264,7 @@ som_write_fixups (abfd, current_offset, total_reloc_sizep)
case R_DATA_ONE_SYMBOL:
case R_DATA_PLABEL:
case R_CODE_PLABEL:
+ case R_DLT_REL:
/* Account for any addend. */
if (bfd_reloc->addend)
p = som_reloc_addend (abfd, bfd_reloc->addend, p,
@@ -2306,6 +2322,14 @@ som_write_fixups (abfd, current_offset, total_reloc_sizep)
}
break;
+ case R_FSEL:
+ case R_LSEL:
+ case R_RSEL:
+ bfd_put_8 (abfd, bfd_reloc->howto->type, p);
+ subspace_reloc_size += 1;
+ p += 1;
+ break;
+
/* Put a "R_RESERVED" relocation in the stream if
we hit something we do not understand. The linker
will complain loudly if this ever happens. */