* elf32-hppa.c (hppa_type_of_stub): Correct and simplify condition

under which a plt call stub is used.
	(final_link_relocate): Similarly.
	(allocate_plt_static): Clear h-plabel except when plt entry is
	exclusively used for a plabel.
	(allocate_dynrelocs): Use the above to simplify plt sizing.
	(struct elf32_hppa_link_hash_table): Add has_22bit_branch.
	(elf32_hppa_link_hash_table_create): Init.
	(BL22_RP): Define.
	(hppa_build_one_stub): Use BL22_RP if has_22bit_branch.
	(elf32_hppa_check_relocs): Set has_22bit_branch.

	* elf32-hppa.c (elf32_hppa_check_relocs): Remove debug message.
	(final_link_relocate): Likewise.
This commit is contained in:
Alan Modra 2002-04-23 05:11:23 +00:00
parent a805a116a8
commit 067fa4a66b
2 changed files with 58 additions and 49 deletions

View File

@ -1,3 +1,20 @@
2002-04-23 Alan Modra <amodra@bigpond.net.au>
* elf32-hppa.c (hppa_type_of_stub): Correct and simplify condition
under which a plt call stub is used.
(final_link_relocate): Similarly.
(allocate_plt_static): Clear h-plabel except when plt entry is
exclusively used for a plabel.
(allocate_dynrelocs): Use the above to simplify plt sizing.
(struct elf32_hppa_link_hash_table): Add has_22bit_branch.
(elf32_hppa_link_hash_table_create): Init.
(BL22_RP): Define.
(hppa_build_one_stub): Use BL22_RP if has_22bit_branch.
(elf32_hppa_check_relocs): Set has_22bit_branch.
* elf32-hppa.c (elf32_hppa_check_relocs): Remove debug message.
(final_link_relocate): Likewise.
2002-04-22 Jakub Jelinek <jakub@redhat.com> 2002-04-22 Jakub Jelinek <jakub@redhat.com>
* elf-eh-frame.c (_bfd_elf_discard_section_eh_frame): Don't build * elf-eh-frame.c (_bfd_elf_discard_section_eh_frame): Don't build

View File

@ -203,9 +203,6 @@ struct elf32_hppa_link_hash_entry {
#endif #endif
} *dyn_relocs; } *dyn_relocs;
/* Set during a static link if we detect a function is PIC. */
unsigned int maybe_pic_call:1;
/* Set if the only reason we need a .plt entry is for a non-PIC to /* Set if the only reason we need a .plt entry is for a non-PIC to
PIC function call. */ PIC function call. */
unsigned int pic_call:1; unsigned int pic_call:1;
@ -255,10 +252,11 @@ struct elf32_hppa_link_hash_table {
/* Whether we support multiple sub-spaces for shared libs. */ /* Whether we support multiple sub-spaces for shared libs. */
unsigned int multi_subspace:1; unsigned int multi_subspace:1;
/* Flags set when PCREL12F and PCREL17F branches detected. Used to /* Flags set when various size branches are detected. Used to
select suitable defaults for the stub group size. */ select suitable defaults for the stub group size. */
unsigned int has_12bit_branch:1; unsigned int has_12bit_branch:1;
unsigned int has_17bit_branch:1; unsigned int has_17bit_branch:1;
unsigned int has_22bit_branch:1;
/* Set if we need a .plt stub to support lazy dynamic linking. */ /* Set if we need a .plt stub to support lazy dynamic linking. */
unsigned int need_plt_stub:1; unsigned int need_plt_stub:1;
@ -460,7 +458,6 @@ hppa_link_hash_newfunc (entry, table, string)
eh = (struct elf32_hppa_link_hash_entry *) entry; eh = (struct elf32_hppa_link_hash_entry *) entry;
eh->stub_cache = NULL; eh->stub_cache = NULL;
eh->dyn_relocs = NULL; eh->dyn_relocs = NULL;
eh->maybe_pic_call = 0;
eh->pic_call = 0; eh->pic_call = 0;
eh->plabel = 0; eh->plabel = 0;
} }
@ -508,6 +505,7 @@ elf32_hppa_link_hash_table_create (abfd)
ret->multi_subspace = 0; ret->multi_subspace = 0;
ret->has_12bit_branch = 0; ret->has_12bit_branch = 0;
ret->has_17bit_branch = 0; ret->has_17bit_branch = 0;
ret->has_22bit_branch = 0;
ret->need_plt_stub = 0; ret->need_plt_stub = 0;
ret->sym_sec.abfd = NULL; ret->sym_sec.abfd = NULL;
@ -683,21 +681,12 @@ hppa_type_of_stub (input_sec, rel, hash, destination)
unsigned int r_type; unsigned int r_type;
if (hash != NULL if (hash != NULL
&& (((hash->elf.root.type == bfd_link_hash_defined && hash->elf.plt.offset != (bfd_vma) -1
|| hash->elf.root.type == bfd_link_hash_defweak) && (hash->elf.dynindx != -1 || hash->pic_call)
&& hash->elf.root.u.def.section->output_section == NULL) && !hash->plabel)
|| (hash->elf.root.type == bfd_link_hash_defweak
&& hash->elf.dynindx != -1
&& hash->elf.plt.offset != (bfd_vma) -1)
|| hash->elf.root.type == bfd_link_hash_undefweak
|| hash->elf.root.type == bfd_link_hash_undefined
|| (hash->maybe_pic_call && !(input_sec->flags & SEC_HAS_GOT_REF))))
{ {
/* If output_section is NULL, then it's a symbol defined in a /* We need an import stub. Decide between hppa_stub_import
shared library. We will need an import stub. Decide between and hppa_stub_import_shared later. */
hppa_stub_import and hppa_stub_import_shared later. For
shared links we need stubs for undefined or weak syms too;
They will presumably be resolved by the dynamic linker. */
return hppa_stub_import; return hppa_stub_import;
} }
@ -755,6 +744,7 @@ hppa_type_of_stub (input_sec, rel, hash, destination)
#define BE_SR0_R21 0xe2a00000 /* be 0(%sr0,%r21) */ #define BE_SR0_R21 0xe2a00000 /* be 0(%sr0,%r21) */
#define STW_RP 0x6bc23fd1 /* stw %rp,-24(%sr0,%sp) */ #define STW_RP 0x6bc23fd1 /* stw %rp,-24(%sr0,%sp) */
#define BL22_RP 0xe800a002 /* b,l,n XXX,%rp */
#define BL_RP 0xe8400002 /* b,l,n XXX,%rp */ #define BL_RP 0xe8400002 /* b,l,n XXX,%rp */
#define NOP 0x08000240 /* nop */ #define NOP 0x08000240 /* nop */
#define LDW_RP 0x4bc23fd1 /* ldw -24(%sr0,%sp),%rp */ #define LDW_RP 0x4bc23fd1 /* ldw -24(%sr0,%sp),%rp */
@ -944,7 +934,9 @@ hppa_build_one_stub (gen_entry, in_arg)
+ stub_sec->output_offset + stub_sec->output_offset
+ stub_sec->output_section->vma); + stub_sec->output_section->vma);
if (sym_value - 8 + 0x40000 >= 0x80000) if (sym_value - 8 + (1 << (17 + 1)) >= (1 << (17 + 2))
&& (!htab->has_22bit_branch
|| sym_value - 8 + (1 << (22 + 1)) >= (1 << (22 + 2))))
{ {
(*_bfd_error_handler) (*_bfd_error_handler)
(_("%s(%s+0x%lx): cannot reach %s, recompile with -ffunction-sections"), (_("%s(%s+0x%lx): cannot reach %s, recompile with -ffunction-sections"),
@ -957,7 +949,10 @@ hppa_build_one_stub (gen_entry, in_arg)
} }
val = hppa_field_adjust (sym_value, (bfd_signed_vma) -8, e_fsel) >> 2; val = hppa_field_adjust (sym_value, (bfd_signed_vma) -8, e_fsel) >> 2;
insn = hppa_rebuild_insn ((int) BL_RP, val, 17); if (!htab->has_22bit_branch)
insn = hppa_rebuild_insn ((int) BL_RP, val, 17);
else
insn = hppa_rebuild_insn ((int) BL22_RP, val, 22);
bfd_put_32 (stub_bfd, insn, loc); bfd_put_32 (stub_bfd, insn, loc);
bfd_put_32 (stub_bfd, (bfd_vma) NOP, loc + 4); bfd_put_32 (stub_bfd, (bfd_vma) NOP, loc + 4);
@ -1276,12 +1271,16 @@ elf32_hppa_check_relocs (abfd, info, sec, relocs)
case R_PARISC_PCREL12F: case R_PARISC_PCREL12F:
htab->has_12bit_branch = 1; htab->has_12bit_branch = 1;
/* Fall thru. */ goto branch_common;
case R_PARISC_PCREL17C: case R_PARISC_PCREL17C:
case R_PARISC_PCREL17F: case R_PARISC_PCREL17F:
htab->has_17bit_branch = 1; htab->has_17bit_branch = 1;
/* Fall thru. */ goto branch_common;
case R_PARISC_PCREL22F: case R_PARISC_PCREL22F:
htab->has_22bit_branch = 1;
branch_common:
/* Function calls might need to go through the .plt, and /* Function calls might need to go through the .plt, and
might require long branch stubs. */ might require long branch stubs. */
if (h == NULL) if (h == NULL)
@ -1335,7 +1334,7 @@ elf32_hppa_check_relocs (abfd, info, sec, relocs)
case R_PARISC_DIR14F: /* 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_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 0
/* Help debug shared library creation. Any of the above /* Help debug shared library creation. Any of the above
relocs can be used in shared libs, but they may cause relocs can be used in shared libs, but they may cause
pages to become unshared. */ pages to become unshared. */
@ -1851,19 +1850,10 @@ elf32_hppa_adjust_dynamic_symbol (info, h)
unsigned int power_of_two; unsigned int power_of_two;
/* If this is a function, put it in the procedure linkage table. We /* If this is a function, put it in the procedure linkage table. We
will fill in the contents of the procedure linkage table later, will fill in the contents of the procedure linkage table later. */
when we know the address of the .got section. */
if (h->type == STT_FUNC if (h->type == STT_FUNC
|| (h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0) || (h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0)
{ {
if (!info->shared
&& h->plt.refcount > 0
&& (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0
&& (h->root.u.def.section->flags & SEC_HAS_GOT_REF) != 0)
{
((struct elf32_hppa_link_hash_entry *) h)->maybe_pic_call = 1;
}
if (h->plt.refcount <= 0 if (h->plt.refcount <= 0
|| ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0 || ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0
&& h->root.type != bfd_link_hash_defweak && h->root.type != bfd_link_hash_defweak
@ -1880,7 +1870,10 @@ elf32_hppa_adjust_dynamic_symbol (info, h)
/* As a special sop to the hppa ABI, we keep a .plt entry /* As a special sop to the hppa ABI, we keep a .plt entry
for functions in sections containing PIC code. */ for functions in sections containing PIC code. */
if (((struct elf32_hppa_link_hash_entry *) h)->maybe_pic_call) if (!info->shared
&& h->plt.refcount > 0
&& (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0
&& (h->root.u.def.section->flags & SEC_HAS_GOT_REF) != 0)
((struct elf32_hppa_link_hash_entry *) h)->pic_call = 1; ((struct elf32_hppa_link_hash_entry *) h)->pic_call = 1;
else else
{ {
@ -2009,7 +2002,6 @@ mark_PIC_calls (h, inf)
} }
h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT; h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
((struct elf32_hppa_link_hash_entry *) h)->maybe_pic_call = 1;
((struct elf32_hppa_link_hash_entry *) h)->pic_call = 1; ((struct elf32_hppa_link_hash_entry *) h)->pic_call = 1;
return true; return true;
@ -2039,6 +2031,7 @@ allocate_plt_static (h, inf)
{ {
/* Make an entry in the .plt section for non-pic code that is /* Make an entry in the .plt section for non-pic code that is
calling pic code. */ calling pic code. */
((struct elf32_hppa_link_hash_entry *) h)->plabel = 0;
s = htab->splt; s = htab->splt;
h->plt.offset = s->_raw_size; h->plt.offset = s->_raw_size;
s->_raw_size += PLT_ENTRY_SIZE; s->_raw_size += PLT_ENTRY_SIZE;
@ -2058,7 +2051,11 @@ allocate_plt_static (h, inf)
if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info, h)) if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info, h))
{ {
/* Allocate these later. */ /* Allocate these later. From this point on, h->plabel
means that the plt entry is only used by a plabel.
We'll be using a normal plt entry for this symbol, so
clear the plabel indicator. */
((struct elf32_hppa_link_hash_entry *) h)->plabel = 0;
} }
else if (((struct elf32_hppa_link_hash_entry *) h)->plabel) else if (((struct elf32_hppa_link_hash_entry *) h)->plabel)
{ {
@ -2109,7 +2106,7 @@ allocate_dynrelocs (h, inf)
if (htab->elf.dynamic_sections_created if (htab->elf.dynamic_sections_created
&& h->plt.offset != (bfd_vma) -1 && h->plt.offset != (bfd_vma) -1
&& !((struct elf32_hppa_link_hash_entry *) h)->pic_call && !((struct elf32_hppa_link_hash_entry *) h)->pic_call
&& WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info, h)) && !((struct elf32_hppa_link_hash_entry *) h)->plabel)
{ {
/* Make an entry in the .plt section. */ /* Make an entry in the .plt section. */
s = htab->splt; s = htab->splt;
@ -3359,19 +3356,14 @@ final_link_relocate (input_section, contents, rel, value, htab, sym_sec, h)
case R_PARISC_PCREL12F: case R_PARISC_PCREL12F:
case R_PARISC_PCREL17F: case R_PARISC_PCREL17F:
case R_PARISC_PCREL22F: case R_PARISC_PCREL22F:
/* If this is a call to a function defined in another dynamic /* If this call should go via the plt, find the import stub in
library, or if it is a call to a PIC function in the same the stub hash. */
object, or if this is a shared link and it is a call to a
weak symbol which may or may not be in the same object, then
find the import stub in the stub hash. */
if (sym_sec == NULL if (sym_sec == NULL
|| sym_sec->output_section == NULL || sym_sec->output_section == NULL
|| (h != NULL || (h != NULL
&& ((h->maybe_pic_call && h->elf.plt.offset != (bfd_vma) -1
&& !(input_section->flags & SEC_HAS_GOT_REF)) && (h->elf.dynindx != -1 || h->pic_call)
|| (h->elf.root.type == bfd_link_hash_defweak && !h->plabel))
&& h->elf.dynindx != -1
&& h->elf.plt.offset != (bfd_vma) -1))))
{ {
stub_entry = hppa_get_stub_entry (input_section, sym_sec, stub_entry = hppa_get_stub_entry (input_section, sym_sec,
h, rel, htab); h, rel, htab);
@ -3426,7 +3418,7 @@ final_link_relocate (input_section, contents, rel, value, htab, sym_sec, h)
== (((int) OP_ADDIL << 26) | (27 << 21))) == (((int) OP_ADDIL << 26) | (27 << 21)))
{ {
insn &= ~ (0x1f << 21); insn &= ~ (0x1f << 21);
#if 1 /* debug them. */ #if 0 /* debug them. */
(*_bfd_error_handler) (*_bfd_error_handler)
(_("%s(%s+0x%lx): fixing %s"), (_("%s(%s+0x%lx): fixing %s"),
bfd_archive_filename (input_bfd), bfd_archive_filename (input_bfd),