* 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:
parent
a805a116a8
commit
067fa4a66b
|
@ -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
|
||||||
|
|
|
@ -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),
|
||||||
|
|
Loading…
Reference in New Issue