.plt stub for lazy linking, --stub-group-size=N ld switch,
import stub fix, extra DIR14F reloc to fix abort in tc_gen_reloc
This commit is contained in:
parent
5506e1a5d8
commit
47d89dba5e
10 changed files with 300 additions and 86 deletions
|
@ -1,3 +1,40 @@
|
||||||
|
2000-09-27 Alan Modra <alan@linuxcare.com.au>
|
||||||
|
|
||||||
|
* elf32-hppa.c (plt_stub): New.
|
||||||
|
(PLT_STUB_ENTRY): Define.
|
||||||
|
(elf32_hppa_link_hash_table): Change multi_subspace to packed
|
||||||
|
boolean. Add need_plt_stub, has_12bit_branch and has_17bit_branch.
|
||||||
|
(elf32_hppa_link_hash_table_create): Init to suit.
|
||||||
|
(elf32_hppa_check_relocs): Set has_12bit_branch and
|
||||||
|
has_17bit_branch as appropriate.
|
||||||
|
(elf32_hppa_adjust_dynamic_symbol): Set need_plt_stub for
|
||||||
|
non-local functions.
|
||||||
|
(elf32_hppa_size_dynamic_sections): Correct setting of reltext.
|
||||||
|
Add space for plt_stub as needed.
|
||||||
|
(elf32_hppa_finish_dynamic_symbol): Point .plt entries for global
|
||||||
|
functions at plt_stub.
|
||||||
|
(elf32_hppa_finish_dynamic_sections): Write plt_stub.
|
||||||
|
(elf32_hppa_create_dynamic_sections): Leave .plt executable.
|
||||||
|
|
||||||
|
* elf32-hppa.h (elf32_hppa_size_stubs): Add group_size param.
|
||||||
|
* elf32-hppa.c (elf32_hppa_size_stubs): Likewise. Use it instead
|
||||||
|
of fixed size, and if negative, disable handling of input sections
|
||||||
|
before stub section. Set up default stub group size depending
|
||||||
|
on detected branch relocs.
|
||||||
|
(hppa_build_one_stub): Use lrsel and rrsel for import stubs to
|
||||||
|
ensure different offsets from sym_value aren't rounded to
|
||||||
|
different 2k blocks. Use lrsel and rrsel for other stubs too for
|
||||||
|
consistency rather than necessity.
|
||||||
|
(elf32_hppa_check_relocs): Handle R_PARISC_DIR14F.
|
||||||
|
(final_link_relocate): Likewise.
|
||||||
|
(elf32_hppa_relocate_section): Likewise.
|
||||||
|
|
||||||
|
* elf-hppa.h (elf_hppa_howto_table): Add R_PARISC_DIR14F reloc.
|
||||||
|
(_bfd_elf_hppa_gen_reloc_type): Generate them.
|
||||||
|
(elf_hppa_final_link_relocate): Handle them.
|
||||||
|
(elf_hppa_relocate_insn): Likewise.
|
||||||
|
(_bfd_elf_hppa_gen_reloc_type): Add missing e_ldsel and e_rdsel cases.
|
||||||
|
|
||||||
2000-09-26 Hans-Peter Nilsson <hp@axis.com>
|
2000-09-26 Hans-Peter Nilsson <hp@axis.com>
|
||||||
|
|
||||||
* elfcode.h (elf_object_p): Preserve and clear abfd section
|
* elfcode.h (elf_object_p): Preserve and clear abfd section
|
||||||
|
|
|
@ -118,8 +118,8 @@ static reloc_howto_type elf_hppa_howto_table[ELF_HOWTO_TABLE_SIZE] =
|
||||||
bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", false, 0, 0, false },
|
bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", false, 0, 0, false },
|
||||||
{ R_PARISC_DIR14R, 0, 0, 14, false, 0, complain_overflow_bitfield,
|
{ R_PARISC_DIR14R, 0, 0, 14, false, 0, complain_overflow_bitfield,
|
||||||
bfd_elf_generic_reloc, "R_PARISC_DIR14R", false, 0, 0, false },
|
bfd_elf_generic_reloc, "R_PARISC_DIR14R", false, 0, 0, false },
|
||||||
{ R_PARISC_UNIMPLEMENTED, 0, 0, 0, false, 0, complain_overflow_bitfield,
|
{ R_PARISC_DIR14F, 0, 0, 14, false, 0, complain_overflow_bitfield,
|
||||||
bfd_elf_generic_reloc, "R_PARISC_UNIMPLEMENTED", false, 0, 0, false },
|
bfd_elf_generic_reloc, "R_PARISC_DIR14F", false, 0, 0, false },
|
||||||
/* 8 */
|
/* 8 */
|
||||||
{ R_PARISC_PCREL12F, 0, 0, 12, true, 0, complain_overflow_bitfield,
|
{ R_PARISC_PCREL12F, 0, 0, 12, true, 0, complain_overflow_bitfield,
|
||||||
bfd_elf_generic_reloc, "R_PARISC_PCREL12F", false, 0, 0, false },
|
bfd_elf_generic_reloc, "R_PARISC_PCREL12F", false, 0, 0, false },
|
||||||
|
@ -657,8 +657,12 @@ _bfd_elf_hppa_gen_reloc_type (abfd, base_type, format, field, ignore, sym)
|
||||||
case 14:
|
case 14:
|
||||||
switch (field)
|
switch (field)
|
||||||
{
|
{
|
||||||
|
case e_fsel:
|
||||||
|
final_type = R_PARISC_DIR14F;
|
||||||
|
break;
|
||||||
case e_rsel:
|
case e_rsel:
|
||||||
case e_rrsel:
|
case e_rrsel:
|
||||||
|
case e_rdsel:
|
||||||
final_type = R_PARISC_DIR14R;
|
final_type = R_PARISC_DIR14R;
|
||||||
break;
|
break;
|
||||||
case e_rtsel:
|
case e_rtsel:
|
||||||
|
@ -686,6 +690,7 @@ _bfd_elf_hppa_gen_reloc_type (abfd, base_type, format, field, ignore, sym)
|
||||||
break;
|
break;
|
||||||
case e_rsel:
|
case e_rsel:
|
||||||
case e_rrsel:
|
case e_rrsel:
|
||||||
|
case e_rdsel:
|
||||||
final_type = R_PARISC_DIR17R;
|
final_type = R_PARISC_DIR17R;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -698,6 +703,7 @@ _bfd_elf_hppa_gen_reloc_type (abfd, base_type, format, field, ignore, sym)
|
||||||
{
|
{
|
||||||
case e_lsel:
|
case e_lsel:
|
||||||
case e_lrsel:
|
case e_lrsel:
|
||||||
|
case e_ldsel:
|
||||||
case e_nlsel:
|
case e_nlsel:
|
||||||
case e_nlrsel:
|
case e_nlrsel:
|
||||||
final_type = R_PARISC_DIR21L;
|
final_type = R_PARISC_DIR21L;
|
||||||
|
@ -763,6 +769,7 @@ _bfd_elf_hppa_gen_reloc_type (abfd, base_type, format, field, ignore, sym)
|
||||||
{
|
{
|
||||||
case e_rsel:
|
case e_rsel:
|
||||||
case e_rrsel:
|
case e_rrsel:
|
||||||
|
case e_rdsel:
|
||||||
/* R_PARISC_DLTREL14R for elf64, R_PARISC_DPREL14R for elf32 */
|
/* R_PARISC_DLTREL14R for elf64, R_PARISC_DPREL14R for elf32 */
|
||||||
final_type = base_type + OFFSET_14R_FROM_21L;
|
final_type = base_type + OFFSET_14R_FROM_21L;
|
||||||
break;
|
break;
|
||||||
|
@ -780,6 +787,7 @@ _bfd_elf_hppa_gen_reloc_type (abfd, base_type, format, field, ignore, sym)
|
||||||
{
|
{
|
||||||
case e_lsel:
|
case e_lsel:
|
||||||
case e_lrsel:
|
case e_lrsel:
|
||||||
|
case e_ldsel:
|
||||||
case e_nlsel:
|
case e_nlsel:
|
||||||
case e_nlrsel:
|
case e_nlrsel:
|
||||||
/* R_PARISC_DLTREL21L for elf64, R_PARISC_DPREL21L for elf32 */
|
/* R_PARISC_DLTREL21L for elf64, R_PARISC_DPREL21L for elf32 */
|
||||||
|
@ -817,6 +825,7 @@ _bfd_elf_hppa_gen_reloc_type (abfd, base_type, format, field, ignore, sym)
|
||||||
{
|
{
|
||||||
case e_rsel:
|
case e_rsel:
|
||||||
case e_rrsel:
|
case e_rrsel:
|
||||||
|
case e_rdsel:
|
||||||
final_type = R_PARISC_PCREL14R;
|
final_type = R_PARISC_PCREL14R;
|
||||||
break;
|
break;
|
||||||
case e_fsel:
|
case e_fsel:
|
||||||
|
@ -832,6 +841,7 @@ _bfd_elf_hppa_gen_reloc_type (abfd, base_type, format, field, ignore, sym)
|
||||||
{
|
{
|
||||||
case e_rsel:
|
case e_rsel:
|
||||||
case e_rrsel:
|
case e_rrsel:
|
||||||
|
case e_rdsel:
|
||||||
final_type = R_PARISC_PCREL17R;
|
final_type = R_PARISC_PCREL17R;
|
||||||
break;
|
break;
|
||||||
case e_fsel:
|
case e_fsel:
|
||||||
|
@ -847,6 +857,7 @@ _bfd_elf_hppa_gen_reloc_type (abfd, base_type, format, field, ignore, sym)
|
||||||
{
|
{
|
||||||
case e_lsel:
|
case e_lsel:
|
||||||
case e_lrsel:
|
case e_lrsel:
|
||||||
|
case e_ldsel:
|
||||||
case e_nlsel:
|
case e_nlsel:
|
||||||
case e_nlrsel:
|
case e_nlrsel:
|
||||||
final_type = R_PARISC_PCREL21L;
|
final_type = R_PARISC_PCREL21L;
|
||||||
|
@ -1712,6 +1723,7 @@ elf_hppa_final_link_relocate (rel, input_bfd, output_bfd,
|
||||||
case R_PARISC_DIR17R:
|
case R_PARISC_DIR17R:
|
||||||
case R_PARISC_DIR17F:
|
case R_PARISC_DIR17F:
|
||||||
case R_PARISC_DIR14R:
|
case R_PARISC_DIR14R:
|
||||||
|
case R_PARISC_DIR14F:
|
||||||
case R_PARISC_DIR14WR:
|
case R_PARISC_DIR14WR:
|
||||||
case R_PARISC_DIR14DR:
|
case R_PARISC_DIR14DR:
|
||||||
case R_PARISC_DIR16F:
|
case R_PARISC_DIR16F:
|
||||||
|
@ -1728,7 +1740,8 @@ elf_hppa_final_link_relocate (rel, input_bfd, output_bfd,
|
||||||
else if (r_type == R_PARISC_DIR17F
|
else if (r_type == R_PARISC_DIR17F
|
||||||
|| r_type == R_PARISC_DIR16F
|
|| r_type == R_PARISC_DIR16F
|
||||||
|| r_type == R_PARISC_DIR16WF
|
|| r_type == R_PARISC_DIR16WF
|
||||||
|| r_type == R_PARISC_DIR16DF)
|
|| r_type == R_PARISC_DIR16DF
|
||||||
|
|| r_type == R_PARISC_DIR14F)
|
||||||
value = hppa_field_adjust (value, addend, e_fsel);
|
value = hppa_field_adjust (value, addend, e_fsel);
|
||||||
else
|
else
|
||||||
value = hppa_field_adjust (value, addend, e_rrsel);
|
value = hppa_field_adjust (value, addend, e_rrsel);
|
||||||
|
@ -2055,6 +2068,7 @@ elf_hppa_relocate_insn (insn, sym_value, r_type)
|
||||||
case R_PARISC_PLTOFF14F:
|
case R_PARISC_PLTOFF14F:
|
||||||
case R_PARISC_PLTOFF16F:
|
case R_PARISC_PLTOFF16F:
|
||||||
case R_PARISC_DIR14R:
|
case R_PARISC_DIR14R:
|
||||||
|
case R_PARISC_DIR14F:
|
||||||
case R_PARISC_DIR16F:
|
case R_PARISC_DIR16F:
|
||||||
case R_PARISC_LTOFF16F:
|
case R_PARISC_LTOFF16F:
|
||||||
return (insn & ~ 0x3fff) | low_sign_unext (sym_value, 14);
|
return (insn & ~ 0x3fff) | low_sign_unext (sym_value, 14);
|
||||||
|
|
238
bfd/elf32-hppa.c
238
bfd/elf32-hppa.c
|
@ -120,6 +120,18 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||||
#define GOT_ENTRY_SIZE 4
|
#define GOT_ENTRY_SIZE 4
|
||||||
#define ELF_DYNAMIC_INTERPRETER "/lib/ld.so.1"
|
#define ELF_DYNAMIC_INTERPRETER "/lib/ld.so.1"
|
||||||
|
|
||||||
|
static const bfd_byte plt_stub[] =
|
||||||
|
{
|
||||||
|
0x0e, 0x80, 0x10, 0x96, /* 1: ldw 0(%r20),%r22 */
|
||||||
|
0xea, 0xc0, 0xc0, 0x00, /* bv %r0(%r22) */
|
||||||
|
0x0e, 0x88, 0x10, 0x95, /* ldw 4(%r20),%r21 */
|
||||||
|
#define PLT_STUB_ENTRY (3*4)
|
||||||
|
0xea, 0x9f, 0x1f, 0xdd, /* b,l 1b,%r20 */
|
||||||
|
0xd6, 0x80, 0x1c, 0x1e, /* depi 0,31,2,%r20 */
|
||||||
|
0x00, 0xc0, 0xff, 0xee, /* 9: .word fixup_func */
|
||||||
|
0xde, 0xad, 0xbe, 0xef /* .word fixup_ltp */
|
||||||
|
};
|
||||||
|
|
||||||
/* Section name for stubs is the associated section name plus this
|
/* Section name for stubs is the associated section name plus this
|
||||||
string. */
|
string. */
|
||||||
#define STUB_SUFFIX ".stub"
|
#define STUB_SUFFIX ".stub"
|
||||||
|
@ -240,9 +252,6 @@ struct elf32_hppa_link_hash_table {
|
||||||
/* Linker stub bfd. */
|
/* Linker stub bfd. */
|
||||||
bfd *stub_bfd;
|
bfd *stub_bfd;
|
||||||
|
|
||||||
/* Whether we support multiple sub-spaces for shared libs. */
|
|
||||||
boolean multi_subspace;
|
|
||||||
|
|
||||||
/* Linker call-backs. */
|
/* Linker call-backs. */
|
||||||
asection * (*add_stub_section) PARAMS ((const char *, asection *));
|
asection * (*add_stub_section) PARAMS ((const char *, asection *));
|
||||||
void (*layout_sections_again) PARAMS ((void));
|
void (*layout_sections_again) PARAMS ((void));
|
||||||
|
@ -268,6 +277,17 @@ struct elf32_hppa_link_hash_table {
|
||||||
asection *srelplt;
|
asection *srelplt;
|
||||||
asection *sdynbss;
|
asection *sdynbss;
|
||||||
asection *srelbss;
|
asection *srelbss;
|
||||||
|
|
||||||
|
/* Whether we support multiple sub-spaces for shared libs. */
|
||||||
|
unsigned int multi_subspace:1;
|
||||||
|
|
||||||
|
/* Flags set when PCREL12F and PCREL17F branches detected. Used to
|
||||||
|
select suitable defaults for the stub group size. */
|
||||||
|
unsigned int has_12bit_branch:1;
|
||||||
|
unsigned int has_17bit_branch:1;
|
||||||
|
|
||||||
|
/* Set if we need a .plt stub to support lazy dynamic linking. */
|
||||||
|
unsigned int need_plt_stub:1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -498,7 +518,6 @@ elf32_hppa_link_hash_table_create (abfd)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
ret->stub_bfd = NULL;
|
ret->stub_bfd = NULL;
|
||||||
ret->multi_subspace = 0;
|
|
||||||
ret->add_stub_section = NULL;
|
ret->add_stub_section = NULL;
|
||||||
ret->layout_sections_again = NULL;
|
ret->layout_sections_again = NULL;
|
||||||
ret->stub_group = NULL;
|
ret->stub_group = NULL;
|
||||||
|
@ -508,6 +527,10 @@ elf32_hppa_link_hash_table_create (abfd)
|
||||||
ret->srelplt = NULL;
|
ret->srelplt = NULL;
|
||||||
ret->sdynbss = NULL;
|
ret->sdynbss = NULL;
|
||||||
ret->srelbss = NULL;
|
ret->srelbss = NULL;
|
||||||
|
ret->multi_subspace = 0;
|
||||||
|
ret->has_12bit_branch = 0;
|
||||||
|
ret->has_17bit_branch = 0;
|
||||||
|
ret->need_plt_stub = 0;
|
||||||
|
|
||||||
return &ret->root.root;
|
return &ret->root.root;
|
||||||
}
|
}
|
||||||
|
@ -896,11 +919,11 @@ hppa_build_one_stub (gen_entry, in_arg)
|
||||||
+ stub_sec->output_section->vma);
|
+ stub_sec->output_section->vma);
|
||||||
|
|
||||||
bfd_put_32 (stub_bfd, (bfd_vma) BL_R1, loc);
|
bfd_put_32 (stub_bfd, (bfd_vma) BL_R1, loc);
|
||||||
val = hppa_field_adjust (sym_value, (bfd_signed_vma) -8, e_lsel);
|
val = hppa_field_adjust (sym_value, (bfd_signed_vma) -8, e_lrsel);
|
||||||
insn = hppa_rebuild_insn ((int) ADDIL_R1, val, 21);
|
insn = hppa_rebuild_insn ((int) ADDIL_R1, val, 21);
|
||||||
bfd_put_32 (stub_bfd, insn, loc + 4);
|
bfd_put_32 (stub_bfd, insn, loc + 4);
|
||||||
|
|
||||||
val = hppa_field_adjust (sym_value, (bfd_signed_vma) -8, e_rsel) >> 2;
|
val = hppa_field_adjust (sym_value, (bfd_signed_vma) -8, e_rrsel) >> 2;
|
||||||
insn = hppa_rebuild_insn ((int) BE_SR4_R1, val, 17);
|
insn = hppa_rebuild_insn ((int) BE_SR4_R1, val, 17);
|
||||||
bfd_put_32 (stub_bfd, insn, loc + 8);
|
bfd_put_32 (stub_bfd, insn, loc + 8);
|
||||||
size = 12;
|
size = 12;
|
||||||
|
@ -918,17 +941,22 @@ hppa_build_one_stub (gen_entry, in_arg)
|
||||||
if (stub_entry->stub_type == hppa_stub_import_shared)
|
if (stub_entry->stub_type == hppa_stub_import_shared)
|
||||||
insn = ADDIL_R19;
|
insn = ADDIL_R19;
|
||||||
#endif
|
#endif
|
||||||
val = hppa_field_adjust (sym_value, (bfd_signed_vma) 0, e_lsel),
|
val = hppa_field_adjust (sym_value, (bfd_signed_vma) 0, e_lrsel),
|
||||||
insn = hppa_rebuild_insn ((int) insn, val, 21);
|
insn = hppa_rebuild_insn ((int) insn, val, 21);
|
||||||
bfd_put_32 (stub_bfd, insn, loc);
|
bfd_put_32 (stub_bfd, insn, loc);
|
||||||
|
|
||||||
val = hppa_field_adjust (sym_value, (bfd_signed_vma) 0, e_rsel);
|
/* It is critical to use lrsel/rrsel here because we are using
|
||||||
|
two different offsets (+0 and +4) from sym_value. If we use
|
||||||
|
lsel/rsel then with unfortunate sym_values we will round
|
||||||
|
sym_value+4 up to the next 2k block leading to a mis-match
|
||||||
|
between the lsel and rsel value. */
|
||||||
|
val = hppa_field_adjust (sym_value, (bfd_signed_vma) 0, e_rrsel);
|
||||||
insn = hppa_rebuild_insn ((int) LDW_R1_R21, val, 14);
|
insn = hppa_rebuild_insn ((int) LDW_R1_R21, val, 14);
|
||||||
bfd_put_32 (stub_bfd, insn, loc + 4);
|
bfd_put_32 (stub_bfd, insn, loc + 4);
|
||||||
|
|
||||||
if (hplink->multi_subspace)
|
if (hplink->multi_subspace)
|
||||||
{
|
{
|
||||||
val = hppa_field_adjust (sym_value, (bfd_signed_vma) 4, e_rsel);
|
val = hppa_field_adjust (sym_value, (bfd_signed_vma) 4, e_rrsel);
|
||||||
insn = hppa_rebuild_insn ((int) LDW_R1_DLT, val, 14);
|
insn = hppa_rebuild_insn ((int) LDW_R1_DLT, val, 14);
|
||||||
bfd_put_32 (stub_bfd, insn, loc + 8);
|
bfd_put_32 (stub_bfd, insn, loc + 8);
|
||||||
|
|
||||||
|
@ -942,7 +970,7 @@ hppa_build_one_stub (gen_entry, in_arg)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bfd_put_32 (stub_bfd, (bfd_vma) BV_R0_R21, loc + 8);
|
bfd_put_32 (stub_bfd, (bfd_vma) BV_R0_R21, loc + 8);
|
||||||
val = hppa_field_adjust (sym_value, (bfd_signed_vma) 4, e_rsel);
|
val = hppa_field_adjust (sym_value, (bfd_signed_vma) 4, e_rrsel);
|
||||||
insn = hppa_rebuild_insn ((int) LDW_R1_DLT, val, 14);
|
insn = hppa_rebuild_insn ((int) LDW_R1_DLT, val, 14);
|
||||||
bfd_put_32 (stub_bfd, insn, loc + 12);
|
bfd_put_32 (stub_bfd, insn, loc + 12);
|
||||||
|
|
||||||
|
@ -1146,8 +1174,6 @@ elf32_hppa_create_dynamic_sections (abfd, info)
|
||||||
bfd *abfd;
|
bfd *abfd;
|
||||||
struct bfd_link_info *info;
|
struct bfd_link_info *info;
|
||||||
{
|
{
|
||||||
flagword flags;
|
|
||||||
asection *s;
|
|
||||||
struct elf32_hppa_link_hash_table *hplink;
|
struct elf32_hppa_link_hash_table *hplink;
|
||||||
|
|
||||||
/* Don't try to create the .plt and .got twice. */
|
/* Don't try to create the .plt and .got twice. */
|
||||||
|
@ -1159,14 +1185,7 @@ elf32_hppa_create_dynamic_sections (abfd, info)
|
||||||
if (! _bfd_elf_create_dynamic_sections (abfd, info))
|
if (! _bfd_elf_create_dynamic_sections (abfd, info))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* Our .plt just contains pointers. I suppose we should be using
|
hplink->splt = bfd_get_section_by_name (abfd, ".plt");
|
||||||
.plt.got but .plt.got doesn't make too much sense without a .plt
|
|
||||||
section. Set the flags to say the .plt isn't executable. */
|
|
||||||
s = bfd_get_section_by_name (abfd, ".plt");
|
|
||||||
flags = bfd_get_section_flags (abfd, s);
|
|
||||||
if (! bfd_set_section_flags (abfd, s, flags & ~SEC_CODE))
|
|
||||||
return false;
|
|
||||||
hplink->splt = s;
|
|
||||||
hplink->srelplt = bfd_get_section_by_name (abfd, ".rela.plt");
|
hplink->srelplt = bfd_get_section_by_name (abfd, ".rela.plt");
|
||||||
|
|
||||||
hplink->sgot = bfd_get_section_by_name (abfd, ".got");
|
hplink->sgot = bfd_get_section_by_name (abfd, ".got");
|
||||||
|
@ -1278,11 +1297,15 @@ elf32_hppa_check_relocs (abfd, info, sec, relocs)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case R_PARISC_PCREL12F:
|
case R_PARISC_PCREL12F:
|
||||||
|
hplink->has_12bit_branch = 1;
|
||||||
|
/* Fall thru. */
|
||||||
case R_PARISC_PCREL17C:
|
case R_PARISC_PCREL17C:
|
||||||
case R_PARISC_PCREL17F:
|
case R_PARISC_PCREL17F:
|
||||||
|
hplink->has_17bit_branch = 1;
|
||||||
|
/* Fall thru. */
|
||||||
case R_PARISC_PCREL22F:
|
case R_PARISC_PCREL22F:
|
||||||
/* Handle calls, and function pointers as they might need to
|
/* Function calls might need to go through the .plt, and
|
||||||
go through the .plt, and might require long branch stubs. */
|
might require long branch stubs. */
|
||||||
if (h == NULL)
|
if (h == NULL)
|
||||||
{
|
{
|
||||||
/* We know local syms won't need a .plt entry, and if
|
/* We know local syms won't need a .plt entry, and if
|
||||||
|
@ -1329,7 +1352,8 @@ elf32_hppa_check_relocs (abfd, info, sec, relocs)
|
||||||
|
|
||||||
case R_PARISC_DIR17F: /* Used for external branches. */
|
case R_PARISC_DIR17F: /* Used for external branches. */
|
||||||
case R_PARISC_DIR17R:
|
case R_PARISC_DIR17R:
|
||||||
case R_PARISC_DIR14R: /* Used for load/store from absolute locn. */
|
case R_PARISC_DIR14F: /* Used for load/store from absolute locn. */
|
||||||
|
case R_PARISC_DIR14R:
|
||||||
case R_PARISC_DIR21L: /* As above, and for ext branches too. */
|
case R_PARISC_DIR21L: /* As above, and for ext branches too. */
|
||||||
#if 1
|
#if 1
|
||||||
/* Help debug shared library creation. Any of the above
|
/* Help debug shared library creation. Any of the above
|
||||||
|
@ -1932,6 +1956,8 @@ elf32_hppa_adjust_dynamic_symbol (info, h)
|
||||||
/* We also need to make an entry in the .rela.plt section. */
|
/* We also need to make an entry in the .rela.plt section. */
|
||||||
s = hplink->srelplt;
|
s = hplink->srelplt;
|
||||||
s->_raw_size += sizeof (Elf32_External_Rela);
|
s->_raw_size += sizeof (Elf32_External_Rela);
|
||||||
|
|
||||||
|
hplink->need_plt_stub = 1;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -2295,28 +2321,22 @@ elf32_hppa_size_dynamic_sections (output_bfd, info)
|
||||||
if (s->_raw_size != 0)
|
if (s->_raw_size != 0)
|
||||||
{
|
{
|
||||||
asection *target;
|
asection *target;
|
||||||
|
const char *outname;
|
||||||
|
|
||||||
/* Remember whether there are any reloc sections other
|
/* Remember whether there are any reloc sections other
|
||||||
than .rela.plt. */
|
than .rela.plt. */
|
||||||
if (strcmp (name+5, ".plt") != 0)
|
if (strcmp (name+5, ".plt") != 0)
|
||||||
{
|
relocs = true;
|
||||||
const char *outname;
|
|
||||||
|
|
||||||
relocs = true;
|
/* If this relocation section applies to a read only
|
||||||
|
section, then we probably need a DT_TEXTREL entry. */
|
||||||
/* If this relocation section applies to a read only
|
outname = bfd_get_section_name (output_bfd,
|
||||||
section, then we probably need a DT_TEXTREL
|
s->output_section);
|
||||||
entry. The entries in the .rela.plt section
|
target = bfd_get_section_by_name (output_bfd, outname + 5);
|
||||||
really apply to the .got section, which we
|
if (target != NULL
|
||||||
created ourselves and so know is not readonly. */
|
&& (target->flags & SEC_READONLY) != 0
|
||||||
outname = bfd_get_section_name (output_bfd,
|
&& (target->flags & SEC_ALLOC) != 0)
|
||||||
s->output_section);
|
reltext = true;
|
||||||
target = bfd_get_section_by_name (output_bfd, outname + 5);
|
|
||||||
if (target != NULL
|
|
||||||
&& (target->flags & SEC_READONLY) != 0
|
|
||||||
&& (target->flags & SEC_ALLOC) != 0)
|
|
||||||
reltext = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We use the reloc_count field as a counter if we need
|
/* We use the reloc_count field as a counter if we need
|
||||||
to copy relocs into the output file. */
|
to copy relocs into the output file. */
|
||||||
|
@ -2324,7 +2344,22 @@ elf32_hppa_size_dynamic_sections (output_bfd, info)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (strcmp (name, ".plt") == 0)
|
else if (strcmp (name, ".plt") == 0)
|
||||||
;
|
{
|
||||||
|
if (hplink->need_plt_stub)
|
||||||
|
{
|
||||||
|
/* Make space for the plt stub at the end of the .plt
|
||||||
|
section. We want this stub right at the end, up
|
||||||
|
against the .got section. */
|
||||||
|
int gotalign = bfd_section_alignment (dynobj, hplink->sgot);
|
||||||
|
int pltalign = bfd_section_alignment (dynobj, s);
|
||||||
|
bfd_size_type mask;
|
||||||
|
|
||||||
|
if (gotalign > pltalign)
|
||||||
|
bfd_set_section_alignment (dynobj, s, gotalign);
|
||||||
|
mask = ((bfd_size_type) 1 << gotalign) - 1;
|
||||||
|
s->_raw_size = (s->_raw_size + sizeof (plt_stub) + mask) & ~mask;
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (strcmp (name, ".got") == 0)
|
else if (strcmp (name, ".got") == 0)
|
||||||
;
|
;
|
||||||
else
|
else
|
||||||
|
@ -2413,12 +2448,13 @@ elf32_hppa_size_dynamic_sections (output_bfd, info)
|
||||||
instruction. */
|
instruction. */
|
||||||
|
|
||||||
boolean
|
boolean
|
||||||
elf32_hppa_size_stubs (output_bfd, stub_bfd, info, multi_subspace,
|
elf32_hppa_size_stubs (output_bfd, stub_bfd, info, multi_subspace, group_size,
|
||||||
add_stub_section, layout_sections_again)
|
add_stub_section, layout_sections_again)
|
||||||
bfd *output_bfd;
|
bfd *output_bfd;
|
||||||
bfd *stub_bfd;
|
bfd *stub_bfd;
|
||||||
struct bfd_link_info *info;
|
struct bfd_link_info *info;
|
||||||
boolean multi_subspace;
|
boolean multi_subspace;
|
||||||
|
bfd_signed_vma group_size;
|
||||||
asection * (*add_stub_section) PARAMS ((const char *, asection *));
|
asection * (*add_stub_section) PARAMS ((const char *, asection *));
|
||||||
void (*layout_sections_again) PARAMS ((void));
|
void (*layout_sections_again) PARAMS ((void));
|
||||||
{
|
{
|
||||||
|
@ -2429,6 +2465,8 @@ elf32_hppa_size_stubs (output_bfd, stub_bfd, info, multi_subspace,
|
||||||
unsigned int bfd_indx, bfd_count;
|
unsigned int bfd_indx, bfd_count;
|
||||||
int top_id, top_index;
|
int top_id, top_index;
|
||||||
struct elf32_hppa_link_hash_table *hplink;
|
struct elf32_hppa_link_hash_table *hplink;
|
||||||
|
bfd_size_type stub_group_size;
|
||||||
|
boolean stubs_always_before_branch;
|
||||||
boolean stub_changed = 0;
|
boolean stub_changed = 0;
|
||||||
boolean ret = 0;
|
boolean ret = 0;
|
||||||
|
|
||||||
|
@ -2439,6 +2477,20 @@ elf32_hppa_size_stubs (output_bfd, stub_bfd, info, multi_subspace,
|
||||||
hplink->multi_subspace = multi_subspace;
|
hplink->multi_subspace = multi_subspace;
|
||||||
hplink->add_stub_section = add_stub_section;
|
hplink->add_stub_section = add_stub_section;
|
||||||
hplink->layout_sections_again = layout_sections_again;
|
hplink->layout_sections_again = layout_sections_again;
|
||||||
|
stubs_always_before_branch = group_size < 0;
|
||||||
|
if (group_size < 0)
|
||||||
|
stub_group_size = -group_size;
|
||||||
|
else
|
||||||
|
stub_group_size = group_size;
|
||||||
|
if (stub_group_size == 1)
|
||||||
|
{
|
||||||
|
/* Default values. */
|
||||||
|
stub_group_size = 8000000;
|
||||||
|
if (hplink->has_17bit_branch || hplink->multi_subspace)
|
||||||
|
stub_group_size = 250000;
|
||||||
|
if (hplink->has_12bit_branch)
|
||||||
|
stub_group_size = 7812;
|
||||||
|
}
|
||||||
|
|
||||||
/* Count the number of input BFDs and find the top input section id. */
|
/* Count the number of input BFDs and find the top input section id. */
|
||||||
for (input_bfd = info->input_bfds, bfd_count = 0, top_id = 0;
|
for (input_bfd = info->input_bfds, bfd_count = 0, top_id = 0;
|
||||||
|
@ -2490,7 +2542,7 @@ elf32_hppa_size_stubs (output_bfd, stub_bfd, info, multi_subspace,
|
||||||
section != NULL;
|
section != NULL;
|
||||||
section = section->next)
|
section = section->next)
|
||||||
{
|
{
|
||||||
if ((section->flags & SEC_CODE) != 0 && section->index <= top_index)
|
if ((section->flags & SEC_CODE) != 0)
|
||||||
input_list[section->index] = NULL;
|
input_list[section->index] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2546,7 +2598,7 @@ elf32_hppa_size_stubs (output_bfd, stub_bfd, info, multi_subspace,
|
||||||
total = tail->_raw_size;
|
total = tail->_raw_size;
|
||||||
while ((prev = PREV_SEC (curr)) != NULL
|
while ((prev = PREV_SEC (curr)) != NULL
|
||||||
&& ((total += curr->output_offset - prev->output_offset)
|
&& ((total += curr->output_offset - prev->output_offset)
|
||||||
< 250000))
|
< stub_group_size))
|
||||||
curr = prev;
|
curr = prev;
|
||||||
|
|
||||||
/* OK, the size from the start of CURR to the end is less
|
/* OK, the size from the start of CURR to the end is less
|
||||||
|
@ -2570,14 +2622,17 @@ elf32_hppa_size_stubs (output_bfd, stub_bfd, info, multi_subspace,
|
||||||
|
|
||||||
/* But wait, there's more! Input sections up to 250000
|
/* But wait, there's more! Input sections up to 250000
|
||||||
bytes before the stub section can be handled by it too. */
|
bytes before the stub section can be handled by it too. */
|
||||||
total = 0;
|
if (!stubs_always_before_branch)
|
||||||
while (prev != NULL
|
|
||||||
&& ((total += tail->output_offset - prev->output_offset)
|
|
||||||
< 250000))
|
|
||||||
{
|
{
|
||||||
tail = prev;
|
total = 0;
|
||||||
prev = PREV_SEC (tail);
|
while (prev != NULL
|
||||||
hplink->stub_group[tail->id].link_sec = curr;
|
&& ((total += tail->output_offset - prev->output_offset)
|
||||||
|
< stub_group_size))
|
||||||
|
{
|
||||||
|
tail = prev;
|
||||||
|
prev = PREV_SEC (tail);
|
||||||
|
hplink->stub_group[tail->id].link_sec = curr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
tail = prev;
|
tail = prev;
|
||||||
}
|
}
|
||||||
|
@ -3256,6 +3311,7 @@ final_link_relocate (input_section, contents, rel, value, hplink, sym_sec, h)
|
||||||
switch (r_type)
|
switch (r_type)
|
||||||
{
|
{
|
||||||
case R_PARISC_DIR32:
|
case R_PARISC_DIR32:
|
||||||
|
case R_PARISC_DIR14F:
|
||||||
case R_PARISC_DIR17F:
|
case R_PARISC_DIR17F:
|
||||||
case R_PARISC_PCREL17C:
|
case R_PARISC_PCREL17C:
|
||||||
case R_PARISC_PCREL14F:
|
case R_PARISC_PCREL14F:
|
||||||
|
@ -3688,6 +3744,7 @@ elf32_hppa_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||||
|
|
||||||
case R_PARISC_DIR17F:
|
case R_PARISC_DIR17F:
|
||||||
case R_PARISC_DIR17R:
|
case R_PARISC_DIR17R:
|
||||||
|
case R_PARISC_DIR14F:
|
||||||
case R_PARISC_DIR14R:
|
case R_PARISC_DIR14R:
|
||||||
case R_PARISC_DIR21L:
|
case R_PARISC_DIR21L:
|
||||||
case R_PARISC_DPREL14F:
|
case R_PARISC_DPREL14F:
|
||||||
|
@ -3871,7 +3928,6 @@ elf32_hppa_finish_dynamic_symbol (output_bfd, info, h, sym)
|
||||||
if (h->plt.offset != (bfd_vma) -1)
|
if (h->plt.offset != (bfd_vma) -1)
|
||||||
{
|
{
|
||||||
bfd_vma value;
|
bfd_vma value;
|
||||||
Elf_Internal_Rela rel;
|
|
||||||
|
|
||||||
/* This symbol has an entry in the procedure linkage table. Set
|
/* This symbol has an entry in the procedure linkage table. Set
|
||||||
it up.
|
it up.
|
||||||
|
@ -3879,15 +3935,7 @@ elf32_hppa_finish_dynamic_symbol (output_bfd, info, h, sym)
|
||||||
The format of a plt entry is
|
The format of a plt entry is
|
||||||
<funcaddr>
|
<funcaddr>
|
||||||
<__gp>
|
<__gp>
|
||||||
<used by ld.so>
|
*/
|
||||||
|
|
||||||
The last field is present only for plt entries that are used
|
|
||||||
by global plabels. */
|
|
||||||
|
|
||||||
/* We do not actually care about the value in the PLT entry if
|
|
||||||
we are creating a shared library and the symbol is still
|
|
||||||
undefined; We create a dynamic relocation to fill in the
|
|
||||||
correct value. */
|
|
||||||
value = 0;
|
value = 0;
|
||||||
if (h->root.type == bfd_link_hash_defined
|
if (h->root.type == bfd_link_hash_defined
|
||||||
|| h->root.type == bfd_link_hash_defweak)
|
|| h->root.type == bfd_link_hash_defweak)
|
||||||
|
@ -3898,22 +3946,10 @@ elf32_hppa_finish_dynamic_symbol (output_bfd, info, h, sym)
|
||||||
+ h->root.u.def.section->output_section->vma);
|
+ h->root.u.def.section->output_section->vma);
|
||||||
}
|
}
|
||||||
|
|
||||||
bfd_put_32 (hplink->splt->owner,
|
|
||||||
value,
|
|
||||||
hplink->splt->contents + h->plt.offset);
|
|
||||||
bfd_put_32 (hplink->splt->owner,
|
|
||||||
elf_gp (hplink->splt->output_section->owner),
|
|
||||||
hplink->splt->contents + h->plt.offset + 4);
|
|
||||||
if (PLABEL_PLT_ENTRY_SIZE != PLT_ENTRY_SIZE
|
|
||||||
&& ((struct elf32_hppa_link_hash_entry *) h)->plabel
|
|
||||||
&& h->dynindx != -1)
|
|
||||||
{
|
|
||||||
memset (hplink->splt->contents + h->plt.offset + 8,
|
|
||||||
0, PLABEL_PLT_ENTRY_SIZE - PLT_ENTRY_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! ((struct elf32_hppa_link_hash_entry *) h)->pic_call)
|
if (! ((struct elf32_hppa_link_hash_entry *) h)->pic_call)
|
||||||
{
|
{
|
||||||
|
Elf_Internal_Rela rel;
|
||||||
|
|
||||||
/* Create a dynamic IPLT relocation for this entry. */
|
/* Create a dynamic IPLT relocation for this entry. */
|
||||||
rel.r_offset = (h->plt.offset
|
rel.r_offset = (h->plt.offset
|
||||||
+ hplink->splt->output_offset
|
+ hplink->splt->output_offset
|
||||||
|
@ -3921,6 +3957,15 @@ elf32_hppa_finish_dynamic_symbol (output_bfd, info, h, sym)
|
||||||
if (! ((struct elf32_hppa_link_hash_entry *) h)->plt_abs
|
if (! ((struct elf32_hppa_link_hash_entry *) h)->plt_abs
|
||||||
&& h->dynindx != -1)
|
&& h->dynindx != -1)
|
||||||
{
|
{
|
||||||
|
/* To support lazy linking, the function pointer is
|
||||||
|
initialised to point to a special stub stored at the
|
||||||
|
end of the .plt. This is only done for plt entries
|
||||||
|
with a non-*ABS* dynamic relocation. */
|
||||||
|
value = (hplink->splt->output_offset
|
||||||
|
+ hplink->splt->output_section->vma
|
||||||
|
+ hplink->splt->_raw_size
|
||||||
|
- sizeof (plt_stub)
|
||||||
|
+ PLT_STUB_ENTRY);
|
||||||
rel.r_info = ELF32_R_INFO (h->dynindx, R_PARISC_IPLT);
|
rel.r_info = ELF32_R_INFO (h->dynindx, R_PARISC_IPLT);
|
||||||
rel.r_addend = 0;
|
rel.r_addend = 0;
|
||||||
}
|
}
|
||||||
|
@ -3940,6 +3985,20 @@ elf32_hppa_finish_dynamic_symbol (output_bfd, info, h, sym)
|
||||||
hplink->srelplt->reloc_count++;
|
hplink->srelplt->reloc_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bfd_put_32 (hplink->splt->owner,
|
||||||
|
value,
|
||||||
|
hplink->splt->contents + h->plt.offset);
|
||||||
|
bfd_put_32 (hplink->splt->owner,
|
||||||
|
elf_gp (hplink->splt->output_section->owner),
|
||||||
|
hplink->splt->contents + h->plt.offset + 4);
|
||||||
|
if (PLABEL_PLT_ENTRY_SIZE != PLT_ENTRY_SIZE
|
||||||
|
&& ((struct elf32_hppa_link_hash_entry *) h)->plabel
|
||||||
|
&& h->dynindx != -1)
|
||||||
|
{
|
||||||
|
memset (hplink->splt->contents + h->plt.offset + 8,
|
||||||
|
0, PLABEL_PLT_ENTRY_SIZE - PLT_ENTRY_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
|
if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
|
||||||
{
|
{
|
||||||
/* Mark the symbol as undefined, rather than as defined in
|
/* Mark the symbol as undefined, rather than as defined in
|
||||||
|
@ -4122,17 +4181,38 @@ elf32_hppa_finish_dynamic_sections (output_bfd, info)
|
||||||
hplink->sgot->contents);
|
hplink->sgot->contents);
|
||||||
|
|
||||||
/* The second entry is reserved for use by the dynamic linker. */
|
/* The second entry is reserved for use by the dynamic linker. */
|
||||||
bfd_put_32 (output_bfd, (bfd_vma) 0, hplink->sgot->contents + 4);
|
memset (hplink->sgot->contents + GOT_ENTRY_SIZE, 0, GOT_ENTRY_SIZE);
|
||||||
|
|
||||||
/* Set .got entry size. */
|
/* Set .got entry size. */
|
||||||
elf_section_data (hplink->sgot->output_section)
|
elf_section_data (hplink->sgot->output_section)
|
||||||
->this_hdr.sh_entsize = GOT_ENTRY_SIZE;
|
->this_hdr.sh_entsize = GOT_ENTRY_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set plt entry size. */
|
|
||||||
if (hplink->splt->_raw_size != 0)
|
if (hplink->splt->_raw_size != 0)
|
||||||
elf_section_data (hplink->splt->output_section)
|
{
|
||||||
->this_hdr.sh_entsize = PLT_ENTRY_SIZE;
|
/* Set plt entry size. */
|
||||||
|
elf_section_data (hplink->splt->output_section)
|
||||||
|
->this_hdr.sh_entsize = PLT_ENTRY_SIZE;
|
||||||
|
|
||||||
|
if (hplink->need_plt_stub)
|
||||||
|
{
|
||||||
|
/* Set up the .plt stub. */
|
||||||
|
memcpy (hplink->splt->contents
|
||||||
|
+ hplink->splt->_raw_size - sizeof (plt_stub),
|
||||||
|
plt_stub, sizeof (plt_stub));
|
||||||
|
|
||||||
|
if ((hplink->splt->output_offset
|
||||||
|
+ hplink->splt->output_section->vma
|
||||||
|
+ hplink->splt->_raw_size)
|
||||||
|
!= (hplink->sgot->output_offset
|
||||||
|
+ hplink->sgot->output_section->vma))
|
||||||
|
{
|
||||||
|
(*_bfd_error_handler)
|
||||||
|
(_(".got section not immediately after .plt section"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
#include "elf/hppa.h"
|
#include "elf/hppa.h"
|
||||||
|
|
||||||
boolean elf32_hppa_size_stubs
|
boolean elf32_hppa_size_stubs
|
||||||
PARAMS ((bfd *, bfd *, struct bfd_link_info *, boolean,
|
PARAMS ((bfd *, bfd *, struct bfd_link_info *, boolean, bfd_signed_vma,
|
||||||
asection * (*) PARAMS ((const char *, asection *)),
|
asection * (*) PARAMS ((const char *, asection *)),
|
||||||
void (*) PARAMS ((void))));
|
void (*) PARAMS ((void))));
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
(hppa_fix_adjustable): Undo 2000-09-23 change.
|
(hppa_fix_adjustable): Undo 2000-09-23 change.
|
||||||
(hppa_force_relocation): Likewise. Add fx_addsy assertion.
|
(hppa_force_relocation): Likewise. Add fx_addsy assertion.
|
||||||
Correct distance calculation.
|
Correct distance calculation.
|
||||||
|
(tc_gen_reloc): Print the file name and line number if we can't
|
||||||
|
handle a fixup.
|
||||||
|
|
||||||
From John David Anglin <dave@hiauly1.hia.nrc.ca>
|
From John David Anglin <dave@hiauly1.hia.nrc.ca>
|
||||||
* config/tc-hppa.c (nonzero_dibits): Define.
|
* config/tc-hppa.c (nonzero_dibits): Define.
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
2000-09-27 Alan Modra <alan@linuxcare.com.au>
|
||||||
|
|
||||||
|
* hppa.h (R_PARISC_DIR14F): Add.
|
||||||
|
|
||||||
2000-09-14 Alexandre Oliva <aoliva@redhat.com>
|
2000-09-14 Alexandre Oliva <aoliva@redhat.com>
|
||||||
|
|
||||||
* sh.h (R_SH_GOT32, R_SH_PLT32, R_SH_COPY, R_SH_GLOB_DAT,
|
* sh.h (R_SH_GOT32, R_SH_PLT32, R_SH_COPY, R_SH_GLOB_DAT,
|
||||||
|
|
|
@ -121,6 +121,9 @@ RELOC_NUMBER (R_PARISC_DIR17F, 4)
|
||||||
RELOC_NUMBER (R_PARISC_DIR14R, 6)
|
RELOC_NUMBER (R_PARISC_DIR14R, 6)
|
||||||
/* load/store (1) RR(symbol, addend) */
|
/* load/store (1) RR(symbol, addend) */
|
||||||
|
|
||||||
|
RELOC_NUMBER (R_PARISC_DIR14F, 7)
|
||||||
|
/* load/store (1) symbol, addend */
|
||||||
|
|
||||||
/* PC-relative relocation types
|
/* PC-relative relocation types
|
||||||
Typically used for calls.
|
Typically used for calls.
|
||||||
Note PCREL17C and PCREL17F differ only in overflow handling.
|
Note PCREL17C and PCREL17F differ only in overflow handling.
|
||||||
|
|
12
ld/ChangeLog
12
ld/ChangeLog
|
@ -1,3 +1,15 @@
|
||||||
|
2000-09-28 Alan Modra <alan@linuxcare.com.au>
|
||||||
|
|
||||||
|
* ld.texinfo (HPPA ELF32): New section.
|
||||||
|
|
||||||
|
* emultempl/hppaelf.em (group_size): New.
|
||||||
|
(hppaelf_finish): Pass group_size to elf32_hppa_size_stubs.
|
||||||
|
(PARSE_AND_LIST_PROLOGUE): Add OPTION_STUBGROUP_SIZE.
|
||||||
|
(PARSE_AND_LIST_LONGOPTS): Add --stub-group-size. Duplicate
|
||||||
|
options to prevent abbreviations matching.
|
||||||
|
(PARSE_AND_LIST_OPTIONS): Describe the above. Reformat.
|
||||||
|
(PARSE_AND_LIST_ARGS_CASES): Handle it.
|
||||||
|
|
||||||
2000-09-21 Michael Sokolov <msokolov@ivan.Harhan.ORG>
|
2000-09-21 Michael Sokolov <msokolov@ivan.Harhan.ORG>
|
||||||
|
|
||||||
* emultempl/m68kelf.em: Conditionalise the embedded relocs feature
|
* emultempl/m68kelf.em: Conditionalise the embedded relocs feature
|
||||||
|
|
|
@ -44,6 +44,10 @@ static lang_input_statement_type *stub_file;
|
||||||
stubs. */
|
stubs. */
|
||||||
static int multi_subspace = 0;
|
static int multi_subspace = 0;
|
||||||
|
|
||||||
|
/* Maximum size of a group of input sections that can be handled by
|
||||||
|
one stub section. A value of +/-1 indicates the bfd back-end
|
||||||
|
should use a suitable default size. */
|
||||||
|
static bfd_signed_vma group_size = 1;
|
||||||
|
|
||||||
/* This is called before the input files are opened. We create a new
|
/* This is called before the input files are opened. We create a new
|
||||||
fake input file to hold the stub sections. */
|
fake input file to hold the stub sections. */
|
||||||
|
@ -292,6 +296,7 @@ hppaelf_finish ()
|
||||||
stub_file->the_bfd,
|
stub_file->the_bfd,
|
||||||
&link_info,
|
&link_info,
|
||||||
multi_subspace,
|
multi_subspace,
|
||||||
|
group_size,
|
||||||
&hppaelf_add_stub_section,
|
&hppaelf_add_stub_section,
|
||||||
&hppaelf_layaout_sections_again))
|
&hppaelf_layaout_sections_again))
|
||||||
{
|
{
|
||||||
|
@ -349,16 +354,31 @@ EOF
|
||||||
#
|
#
|
||||||
PARSE_AND_LIST_PROLOGUE='
|
PARSE_AND_LIST_PROLOGUE='
|
||||||
#define OPTION_MULTI_SUBSPACE 301
|
#define OPTION_MULTI_SUBSPACE 301
|
||||||
|
#define OPTION_STUBGROUP_SIZE (OPTION_MULTI_SUBSPACE + 1)
|
||||||
'
|
'
|
||||||
|
|
||||||
|
# The options are repeated below so that no abbreviations are allowed.
|
||||||
|
# Otherwise -s matches stub-group-size
|
||||||
PARSE_AND_LIST_LONGOPTS='
|
PARSE_AND_LIST_LONGOPTS='
|
||||||
{ "multi-subspace", no_argument, NULL, OPTION_MULTI_SUBSPACE},
|
{ "multi-subspace", no_argument, NULL, OPTION_MULTI_SUBSPACE },
|
||||||
|
{ "multi-subspace", no_argument, NULL, OPTION_MULTI_SUBSPACE },
|
||||||
|
{ "stub-group-size", required_argument, NULL, OPTION_STUBGROUP_SIZE },
|
||||||
|
{ "stub-group-size", required_argument, NULL, OPTION_STUBGROUP_SIZE },
|
||||||
'
|
'
|
||||||
|
|
||||||
PARSE_AND_LIST_OPTIONS='
|
PARSE_AND_LIST_OPTIONS='
|
||||||
fprintf (file, _("\
|
fprintf (file, _("\
|
||||||
--multi-subspace Generate import and export stubs to support\n\
|
--multi-subspace Generate import and export stubs to support\n\
|
||||||
multiple sub-space shared libraries\n"
|
multiple sub-space shared libraries\n"
|
||||||
|
));
|
||||||
|
fprintf (file, _("\
|
||||||
|
--stub-group-size=N Maximum size of a group of input sections that can be\n\
|
||||||
|
handled by one stub section. A negative value\n\
|
||||||
|
locates all stubs before their branches (with a\n\
|
||||||
|
group size of -N), while a positive value allows\n\
|
||||||
|
two groups of input sections, one before, and one\n\
|
||||||
|
after each stub section. Values of +/-1 indicate\n\
|
||||||
|
the linker should choose suitable defaults."
|
||||||
));
|
));
|
||||||
'
|
'
|
||||||
|
|
||||||
|
@ -366,6 +386,15 @@ PARSE_AND_LIST_ARGS_CASES='
|
||||||
case OPTION_MULTI_SUBSPACE:
|
case OPTION_MULTI_SUBSPACE:
|
||||||
multi_subspace = 1;
|
multi_subspace = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case OPTION_STUBGROUP_SIZE:
|
||||||
|
{
|
||||||
|
const char *end;
|
||||||
|
group_size = bfd_scan_vma (optarg, &end, 0);
|
||||||
|
if (*end)
|
||||||
|
einfo (_("%P%F: invalid number `%s'\''\n"), optarg);
|
||||||
|
}
|
||||||
|
break;
|
||||||
'
|
'
|
||||||
|
|
||||||
# Put these extra hppaelf routines in ld_${EMULATION_NAME}_emulation
|
# Put these extra hppaelf routines in ld_${EMULATION_NAME}_emulation
|
||||||
|
|
|
@ -3904,6 +3904,7 @@ functionality are not listed.
|
||||||
* H8/300:: @code{ld} and the H8/300
|
* H8/300:: @code{ld} and the H8/300
|
||||||
* i960:: @code{ld} and the Intel 960 family
|
* i960:: @code{ld} and the Intel 960 family
|
||||||
* ARM:: @code{ld} and the ARM family
|
* ARM:: @code{ld} and the ARM family
|
||||||
|
* HPPA ELF32:: @code{ld} and HPPA 32-bit ELF
|
||||||
@ifset TICOFF
|
@ifset TICOFF
|
||||||
* TI COFF:: @code{ld} and TI COFF
|
* TI COFF:: @code{ld} and TI COFF
|
||||||
@end ifset
|
@end ifset
|
||||||
|
@ -4047,6 +4048,38 @@ But it also sets the bottom bit of the address, so that it can be
|
||||||
branched to using a BX instruction, and the program will start
|
branched to using a BX instruction, and the program will start
|
||||||
executing in Thumb mode straight away.
|
executing in Thumb mode straight away.
|
||||||
|
|
||||||
|
@node HPPA ELF32
|
||||||
|
@section @code{ld} and HPPA 32-bit ELF support
|
||||||
|
@cindex HPPA multiple sub-space stubs
|
||||||
|
@kindex --multi-subspace
|
||||||
|
When generating a shared library, @code{ld} will by default generate
|
||||||
|
import stubs suitable for use with a single sub-space application.
|
||||||
|
The @samp{--multi-subspace} switch causes @code{ld} to generate export
|
||||||
|
stubs, and different (larger) import stubs suitable for use with
|
||||||
|
multiple sub-spaces.
|
||||||
|
|
||||||
|
@cindex HPPA stub grouping
|
||||||
|
@kindex --stub-group-size=@var{N}
|
||||||
|
Long branch stubs and import/export stubs are placed by @code{ld} in
|
||||||
|
stub sections located between groups of input sections.
|
||||||
|
@samp{--stub-group-size} specifies the maximum size of a group of input
|
||||||
|
sections handled by one stub section. Since branch offsets are signed,
|
||||||
|
a stub section may serve two groups of input sections, one group before
|
||||||
|
the stub section, and one group after it. However, when using
|
||||||
|
conditional branches that require stubs, it may be better (for branch
|
||||||
|
prediction) that stub sections only serve one group of input sections.
|
||||||
|
A negative value for @samp{N} chooses this scheme, ensuring that
|
||||||
|
branches to stubs always use a negative offset. Two special values of
|
||||||
|
@samp{N} are recognized, @samp{1} and @samp{-1}. These both instruct
|
||||||
|
@code{ld} to automatically size input section groups for the branch types
|
||||||
|
detected, with the same behaviour regarding stub placement as other
|
||||||
|
positive or negative values of @samp{N} respectively.
|
||||||
|
|
||||||
|
Note that @samp{--stub-group-size} does not split input sections. A
|
||||||
|
single input section larger than the group size specified will of course
|
||||||
|
create a larger group (of one section). If input sections are too
|
||||||
|
large, it may not be possible for a branch to reach its stub.
|
||||||
|
|
||||||
@ifset TICOFF
|
@ifset TICOFF
|
||||||
@node TI COFF
|
@node TI COFF
|
||||||
@section @code{ld}'s support for various TI COFF versions
|
@section @code{ld}'s support for various TI COFF versions
|
||||||
|
|
Loading…
Reference in a new issue