* 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:
parent
9d5a9b20fe
commit
a36b6f1d05
|
@ -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)
|
Tue Dec 7 15:47:51 1993 Stu Grossman (grossman at cygnus.com)
|
||||||
|
|
||||||
* nlmcode.h: Fixes to avoid compiler warnings...
|
* nlmcode.h: Fixes to avoid compiler warnings...
|
||||||
|
|
|
@ -524,11 +524,15 @@ hppa_elf_gen_reloc_type (abfd, base_type, format, field)
|
||||||
case e_rpsel:
|
case e_rpsel:
|
||||||
final_type = R_HPPA_PLABEL_R11;
|
final_type = R_HPPA_PLABEL_R11;
|
||||||
break;
|
break;
|
||||||
case e_lpsel:
|
|
||||||
case e_tsel:
|
case e_tsel:
|
||||||
case e_ltsel:
|
final_type = R_HPPA_DLT_11;
|
||||||
|
break;
|
||||||
case e_rtsel:
|
case e_rtsel:
|
||||||
|
final_type = R_HPPA_DLT_R11;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case e_lpsel:
|
||||||
|
case e_ltsel:
|
||||||
case e_lsel:
|
case e_lsel:
|
||||||
case e_lrsel:
|
case e_lrsel:
|
||||||
case e_lssel:
|
case e_lssel:
|
||||||
|
@ -564,10 +568,15 @@ hppa_elf_gen_reloc_type (abfd, base_type, format, field)
|
||||||
case e_rpsel:
|
case e_rpsel:
|
||||||
final_type = R_HPPA_PLABEL_R14;
|
final_type = R_HPPA_PLABEL_R14;
|
||||||
break;
|
break;
|
||||||
case e_lpsel:
|
|
||||||
case e_tsel:
|
case e_tsel:
|
||||||
case e_ltsel:
|
final_type = R_HPPA_DLT_14;
|
||||||
|
break;
|
||||||
case e_rtsel:
|
case e_rtsel:
|
||||||
|
final_type = R_HPPA_DLT_R14;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case e_lpsel:
|
||||||
|
case e_ltsel:
|
||||||
|
|
||||||
case e_fsel:
|
case e_fsel:
|
||||||
case e_lsel:
|
case e_lsel:
|
||||||
|
@ -626,6 +635,9 @@ hppa_elf_gen_reloc_type (abfd, base_type, format, field)
|
||||||
case e_lpsel:
|
case e_lpsel:
|
||||||
final_type = R_HPPA_PLABEL_L21;
|
final_type = R_HPPA_PLABEL_L21;
|
||||||
break;
|
break;
|
||||||
|
case e_ltsel:
|
||||||
|
final_type = R_HPPA_PLABEL_L21;
|
||||||
|
break;
|
||||||
case e_rsel:
|
case e_rsel:
|
||||||
case e_rssel:
|
case e_rssel:
|
||||||
case e_rdsel:
|
case e_rdsel:
|
||||||
|
@ -646,6 +658,9 @@ hppa_elf_gen_reloc_type (abfd, base_type, format, field)
|
||||||
case e_psel:
|
case e_psel:
|
||||||
final_type = R_HPPA_PLABEL_32;
|
final_type = R_HPPA_PLABEL_32;
|
||||||
break;
|
break;
|
||||||
|
case e_tsel:
|
||||||
|
final_type == R_HPPA_DLT_32;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
UNDEFINED;
|
UNDEFINED;
|
||||||
final_type = base_type;
|
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). */
|
jump after the call returns (GCC optimization). */
|
||||||
|
|
||||||
if (insn & 2)
|
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
|
else
|
||||||
{
|
{
|
||||||
unsigned long old_delay_slot_insn = bfd_get_32 (abfd, hit_data + 4);
|
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));
|
new_delay_slot_insn |= ((31 << 21) | (31 << 16));
|
||||||
bfd_put_32 (abfd, new_delay_slot_insn, hit_data + 4);
|
bfd_put_32 (abfd, new_delay_slot_insn, hit_data + 4);
|
||||||
insn = BLE_XXX_0_0;
|
insn = BLE_XXX_0_0;
|
||||||
bfd_put_32 (abfd, insn, hit_data);
|
|
||||||
r_type = R_HPPA_ABS_CALL_17;
|
r_type = R_HPPA_ABS_CALL_17;
|
||||||
r_pcrel = 0;
|
r_pcrel = 0;
|
||||||
insn = hppa_elf_relocate_insn (abfd, input_section, insn,
|
insn = hppa_elf_relocate_insn (abfd, input_section, insn,
|
||||||
addr, symbol_in, sym_value,
|
addr, symbol_in, sym_value,
|
||||||
r_addend, r_type, r_format,
|
r_addend, r_type, r_format,
|
||||||
r_field, r_pcrel);
|
r_field, r_pcrel);
|
||||||
bfd_put_32 (abfd, insn, hit_data + 4);
|
bfd_put_32 (abfd, insn, hit_data);
|
||||||
return bfd_reloc_ok;
|
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
|
else
|
||||||
{
|
{
|
||||||
/* Check to see if the delay slot instruction has a
|
/* 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;
|
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
|
else
|
||||||
{
|
{
|
||||||
/* Check to see if the delay slot instruction has a
|
/* 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 *));
|
sizeof (asymbol *));
|
||||||
reloc_entry->sym_ptr_ptr[0] = stub_sym;
|
reloc_entry->sym_ptr_ptr[0] = stub_sym;
|
||||||
if (reloc_entry->howto->type != R_HPPA_PLABEL_32
|
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);
|
reloc_entry->howto = bfd_reloc_type_lookup (abfd, R_HPPA_STUB_CALL_17);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -2385,7 +2438,9 @@ hppa_elf_build_arg_reloc_stub (abfd, output_bfd, reloc_entry,
|
||||||
sizeof (asymbol *));
|
sizeof (asymbol *));
|
||||||
reloc_entry->sym_ptr_ptr[0] = stub_sym;
|
reloc_entry->sym_ptr_ptr[0] = stub_sym;
|
||||||
if (reloc_entry->howto->type != R_HPPA_PLABEL_32
|
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);
|
reloc_entry->howto = bfd_reloc_type_lookup (abfd, R_HPPA_STUB_CALL_17);
|
||||||
|
|
||||||
/* Generate common code for all stubs. */
|
/* 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)
|
if (strcmp (symbol->name, "$$dyncall") == 0)
|
||||||
dyncall = true;
|
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
|
/* Check to see if we modify the return pointer
|
||||||
in the delay slot of the branch. */
|
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
|
if (get_opcode (delay_insn) == LDO
|
||||||
&& (((delay_insn & 0x001f0000) >> 16) == rtn_reg))
|
&& (((delay_insn & 0x001f0000) >> 16) == rtn_reg))
|
||||||
rtn_adjust = false;
|
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. */
|
/* 2. Make the call. */
|
||||||
if (!milli)
|
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,
|
hppa_elf_stub_reloc (stub_desc,
|
||||||
abfd,
|
abfd,
|
||||||
target_sym,
|
target_sym,
|
||||||
CURRENT_STUB_OFFSET (stub_entry),
|
CURRENT_STUB_OFFSET (stub_entry),
|
||||||
R_HPPA_ABS_CALL_R17);
|
R_HPPA_ABS_CALL_R17);
|
||||||
|
NEW_INSTRUCTION (stub_entry, COPY_2_31);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -2931,12 +3003,13 @@ hppa_elf_build_long_branch_stub (abfd, output_bfd, reloc_entry, symbol, data)
|
||||||
CURRENT_STUB_OFFSET (stub_entry),
|
CURRENT_STUB_OFFSET (stub_entry),
|
||||||
R_HPPA_L21);
|
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,
|
hppa_elf_stub_reloc (stub_desc,
|
||||||
abfd,
|
abfd,
|
||||||
target_sym,
|
target_sym,
|
||||||
CURRENT_STUB_OFFSET (stub_entry),
|
CURRENT_STUB_OFFSET (stub_entry),
|
||||||
R_HPPA_ABS_CALL_R17);
|
R_HPPA_ABS_CALL_R17);
|
||||||
|
NEW_INSTRUCTION (stub_entry, COPY_2_31);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return stub_sym;
|
return stub_sym;
|
||||||
|
|
46
bfd/som.c
46
bfd/som.c
|
@ -1356,11 +1356,18 @@ hppa_som_gen_reloc_type (abfd, base_type, format, field)
|
||||||
case e_psel:
|
case e_psel:
|
||||||
case e_lpsel:
|
case e_lpsel:
|
||||||
case e_rpsel:
|
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_tsel:
|
||||||
case e_ltsel:
|
case e_ltsel:
|
||||||
case e_rtsel:
|
case e_rtsel:
|
||||||
final_types[0] = final_type;
|
final_types[0] = (int *) bfd_alloc_by_size_t (abfd, sizeof (int));
|
||||||
final_types[1] = NULL;
|
*final_types[0] = R_FSEL;
|
||||||
|
final_types[1] = final_type;
|
||||||
final_types[2] = NULL;
|
final_types[2] = NULL;
|
||||||
*final_type = base_type;
|
*final_type = base_type;
|
||||||
break;
|
break;
|
||||||
|
@ -1409,15 +1416,20 @@ hppa_som_gen_reloc_type (abfd, base_type, format, field)
|
||||||
if (field == e_psel
|
if (field == e_psel
|
||||||
|| field == e_lpsel
|
|| field == e_lpsel
|
||||||
|| field == e_rpsel)
|
|| field == e_rpsel)
|
||||||
{
|
{
|
||||||
/* A PLABEL relocation that has a size of 32 bits must
|
/* A PLABEL relocation that has a size of 32 bits must
|
||||||
be a R_DATA_PLABEL. All others are R_CODE_PLABELs. */
|
be a R_DATA_PLABEL. All others are R_CODE_PLABELs. */
|
||||||
if (format == 32)
|
if (format == 32)
|
||||||
*final_type = R_DATA_PLABEL;
|
*final_type = R_DATA_PLABEL;
|
||||||
else
|
else
|
||||||
*final_type = R_CODE_PLABEL;
|
*final_type = R_CODE_PLABEL;
|
||||||
}
|
}
|
||||||
/* A relocatoin in the data space is always a full 32bits. */
|
/* 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)
|
else if (format == 32)
|
||||||
*final_type = R_DATA_ONE_SYMBOL;
|
*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_S_MODE:
|
||||||
case R_D_MODE:
|
case R_D_MODE:
|
||||||
case R_R_MODE:
|
case R_R_MODE:
|
||||||
|
case R_FSEL:
|
||||||
|
case R_LSEL:
|
||||||
|
case R_RSEL:
|
||||||
reloc_offset = bfd_reloc->address;
|
reloc_offset = bfd_reloc->address;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -2249,6 +2264,7 @@ som_write_fixups (abfd, current_offset, total_reloc_sizep)
|
||||||
case R_DATA_ONE_SYMBOL:
|
case R_DATA_ONE_SYMBOL:
|
||||||
case R_DATA_PLABEL:
|
case R_DATA_PLABEL:
|
||||||
case R_CODE_PLABEL:
|
case R_CODE_PLABEL:
|
||||||
|
case R_DLT_REL:
|
||||||
/* Account for any addend. */
|
/* Account for any addend. */
|
||||||
if (bfd_reloc->addend)
|
if (bfd_reloc->addend)
|
||||||
p = som_reloc_addend (abfd, bfd_reloc->addend, p,
|
p = som_reloc_addend (abfd, bfd_reloc->addend, p,
|
||||||
|
@ -2306,6 +2322,14 @@ som_write_fixups (abfd, current_offset, total_reloc_sizep)
|
||||||
}
|
}
|
||||||
break;
|
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
|
/* Put a "R_RESERVED" relocation in the stream if
|
||||||
we hit something we do not understand. The linker
|
we hit something we do not understand. The linker
|
||||||
will complain loudly if this ever happens. */
|
will complain loudly if this ever happens. */
|
||||||
|
|
Loading…
Reference in New Issue