* 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.
This commit is contained in:
Jeff Law 1993-12-14 07:36:15 +00:00
parent 9d5a9b20fe
commit a36b6f1d05
3 changed files with 128 additions and 22 deletions

View File

@ -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...

View File

@ -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;

View File

@ -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. */