mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2025-02-13 05:20:44 +00:00
* elf64-alpha.c (elf64_alpha_relax_with_lituse): Relax jsr to
undefweak to use zero register. Call elf64_alpha_relax_got_load if not all uses removed. (elf64_alpha_relax_got_load): Relax undefweak to lda zero. (elf64_alpha_relax_section): Handle undefweak symbols. (elf64_alpha_calc_dynrel_sizes): Don't add relocs for undefweak. (elf64_alpha_size_rela_got_1): Likewise. (elf64_alpha_relocate_section): Likewise.
This commit is contained in:
parent
487c435301
commit
d6ad34f6c2
@ -1,3 +1,14 @@
|
||||
2005-05-22 Richard Henderson <rth@redhat.com>
|
||||
|
||||
* elf64-alpha.c (elf64_alpha_relax_with_lituse): Relax jsr to
|
||||
undefweak to use zero register. Call elf64_alpha_relax_got_load
|
||||
if not all uses removed.
|
||||
(elf64_alpha_relax_got_load): Relax undefweak to lda zero.
|
||||
(elf64_alpha_relax_section): Handle undefweak symbols.
|
||||
(elf64_alpha_calc_dynrel_sizes): Don't add relocs for undefweak.
|
||||
(elf64_alpha_size_rela_got_1): Likewise.
|
||||
(elf64_alpha_relocate_section): Likewise.
|
||||
|
||||
2005-05-22 Richard Henderson <rth@redhat.com>
|
||||
|
||||
* elf64-alpha.c (elf64_alpha_relax_section): Only operate
|
||||
|
@ -1300,9 +1300,7 @@ elf64_alpha_relax_with_lituse (info, symval, irel)
|
||||
/* Extract the displacement from the instruction, sign-extending
|
||||
it if necessary, then test whether it is within 16 or 32 bits
|
||||
displacement from GP. */
|
||||
insn_disp = insn & 0x0000ffff;
|
||||
if (insn_disp & 0x8000)
|
||||
insn_disp |= ~0xffff; /* Negative: sign-extend. */
|
||||
insn_disp = ((insn & 0xffff) ^ 0x8000) - 0x8000;
|
||||
|
||||
xdisp = disp + insn_disp;
|
||||
fits16 = (xdisp >= - (bfd_signed_vma) 0x8000 && xdisp < 0x8000);
|
||||
@ -1371,6 +1369,19 @@ elf64_alpha_relax_with_lituse (info, symval, irel)
|
||||
bfd_vma optdest, org;
|
||||
bfd_signed_vma odisp;
|
||||
|
||||
/* For undefined weak symbols, we're mostly interested in getting
|
||||
rid of the got entry whenever possible, so optimize this to a
|
||||
use of the zero register. */
|
||||
if (info->h && info->h->root.root.type == bfd_link_hash_undefweak)
|
||||
{
|
||||
insn |= 31 << 16;
|
||||
bfd_put_32 (info->abfd, (bfd_vma) insn,
|
||||
info->contents + urel->r_offset);
|
||||
|
||||
info->changed_contents = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* If not zero, place to jump without needing pv. */
|
||||
optdest = elf64_alpha_relax_opt_call (info, symval);
|
||||
org = (info->sec->output_section->vma
|
||||
@ -1474,9 +1485,11 @@ elf64_alpha_relax_with_lituse (info, symval, irel)
|
||||
info->contents + irel->r_offset);
|
||||
info->changed_contents = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
return elf64_alpha_relax_got_load (info, symval, irel, R_ALPHA_LITERAL);
|
||||
}
|
||||
|
||||
static bfd_vma
|
||||
@ -1583,7 +1596,25 @@ elf64_alpha_relax_got_load (info, symval, irel, r_type)
|
||||
return TRUE;
|
||||
|
||||
if (r_type == R_ALPHA_LITERAL)
|
||||
disp = symval - info->gp;
|
||||
{
|
||||
/* Look for nice constant addresses. This includes the not-uncommon
|
||||
special case of 0 for undefweak symbols. */
|
||||
if ((info->h && info->h->root.root.type == bfd_link_hash_undefweak)
|
||||
|| (!info->link_info->shared
|
||||
&& (symval >= (bfd_vma)-0x8000 || symval < 0x8000)))
|
||||
{
|
||||
disp = 0;
|
||||
insn = (OP_LDA << 26) | (insn & (31 << 21)) | (31 << 16);
|
||||
insn |= (symval & 0xffff);
|
||||
r_type = R_ALPHA_NONE;
|
||||
}
|
||||
else
|
||||
{
|
||||
disp = symval - info->gp;
|
||||
insn = (OP_LDA << 26) | (insn & 0x03ff0000);
|
||||
r_type = R_ALPHA_GPREL16;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bfd_vma dtp_base, tp_base;
|
||||
@ -1592,17 +1623,26 @@ elf64_alpha_relax_got_load (info, symval, irel, r_type)
|
||||
dtp_base = alpha_get_dtprel_base (info->link_info);
|
||||
tp_base = alpha_get_tprel_base (info->link_info);
|
||||
disp = symval - (r_type == R_ALPHA_GOTDTPREL ? dtp_base : tp_base);
|
||||
|
||||
insn = (OP_LDA << 26) | (insn & (31 << 21)) | (31 << 16);
|
||||
|
||||
switch (r_type)
|
||||
{
|
||||
case R_ALPHA_GOTDTPREL:
|
||||
r_type = R_ALPHA_DTPREL16;
|
||||
break;
|
||||
case R_ALPHA_GOTTPREL:
|
||||
r_type = R_ALPHA_TPREL16;
|
||||
break;
|
||||
default:
|
||||
BFD_ASSERT (0);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (disp < -0x8000 || disp >= 0x8000)
|
||||
return TRUE;
|
||||
|
||||
/* Exchange LDQ for LDA. In the case of the TLS relocs, we're loading
|
||||
a constant, so force the base register to be $31. */
|
||||
if (r_type == R_ALPHA_LITERAL)
|
||||
insn = (OP_LDA << 26) | (insn & 0x03ff0000);
|
||||
else
|
||||
insn = (OP_LDA << 26) | (insn & (31 << 21)) | (31 << 16);
|
||||
bfd_put_32 (info->abfd, (bfd_vma) insn, info->contents + irel->r_offset);
|
||||
info->changed_contents = TRUE;
|
||||
|
||||
@ -1617,22 +1657,6 @@ elf64_alpha_relax_got_load (info, symval, irel, r_type)
|
||||
}
|
||||
|
||||
/* Smash the existing GOT relocation for its 16-bit immediate pair. */
|
||||
switch (r_type)
|
||||
{
|
||||
case R_ALPHA_LITERAL:
|
||||
r_type = R_ALPHA_GPREL16;
|
||||
break;
|
||||
case R_ALPHA_GOTDTPREL:
|
||||
r_type = R_ALPHA_DTPREL16;
|
||||
break;
|
||||
case R_ALPHA_GOTTPREL:
|
||||
r_type = R_ALPHA_TPREL16;
|
||||
break;
|
||||
default:
|
||||
BFD_ASSERT (0);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
irel->r_info = ELF64_R_INFO (ELF64_R_SYM (irel->r_info), r_type);
|
||||
info->changed_relocs = TRUE;
|
||||
|
||||
@ -2103,13 +2127,17 @@ elf64_alpha_relax_section (abfd, sec, link_info, again)
|
||||
h = (struct alpha_elf_link_hash_entry *)h->root.root.u.i.link;
|
||||
|
||||
/* If the symbol is undefined, we can't do anything with it. */
|
||||
if (h->root.root.type == bfd_link_hash_undefweak
|
||||
|| h->root.root.type == bfd_link_hash_undefined)
|
||||
if (h->root.root.type == bfd_link_hash_undefined)
|
||||
continue;
|
||||
|
||||
/* If the symbol isn't defined in the current module, again
|
||||
we can't do anything. */
|
||||
if (!h->root.def_regular)
|
||||
/* If the symbol isn't defined in the current module,
|
||||
again we can't do anything. */
|
||||
if (h->root.root.type == bfd_link_hash_undefweak)
|
||||
{
|
||||
info.tsec = bfd_abs_section_ptr;
|
||||
symval = 0;
|
||||
}
|
||||
else if (!h->root.def_regular)
|
||||
{
|
||||
/* Except for TLSGD relocs, which can sometimes be
|
||||
relaxed to GOTTPREL relocs. */
|
||||
@ -3860,9 +3888,14 @@ elf64_alpha_calc_dynrel_sizes (h, info)
|
||||
/* If the symbol is dynamic, we'll need all the relocations in their
|
||||
natural form. If this is a shared object, and it has been forced
|
||||
local, we'll need the same number of RELATIVE relocations. */
|
||||
|
||||
dynamic = alpha_elf_dynamic_symbol_p (&h->root, info);
|
||||
|
||||
/* If the symbol is a hidden undefined weak, then we never have any
|
||||
relocations. Avoid the loop which may want to add RELATIVE relocs
|
||||
based on info->shared. */
|
||||
if (h->root.root.type == bfd_link_hash_undefweak && !dynamic)
|
||||
return TRUE;
|
||||
|
||||
for (relent = h->reloc_entries; relent; relent = relent->next)
|
||||
{
|
||||
entries = alpha_dynamic_entries_for_reloc (relent->rtype, dynamic,
|
||||
@ -3950,9 +3983,14 @@ elf64_alpha_size_rela_got_1 (h, info)
|
||||
/* If the symbol is dynamic, we'll need all the relocations in their
|
||||
natural form. If this is a shared object, and it has been forced
|
||||
local, we'll need the same number of RELATIVE relocations. */
|
||||
|
||||
dynamic = alpha_elf_dynamic_symbol_p (&h->root, info);
|
||||
|
||||
/* If the symbol is a hidden undefined weak, then we never have any
|
||||
relocations. Avoid the loop which may want to add RELATIVE relocs
|
||||
based on info->shared. */
|
||||
if (h->root.root.type == bfd_link_hash_undefweak && !dynamic)
|
||||
return TRUE;
|
||||
|
||||
entries = 0;
|
||||
for (gotent = h->got_entries; gotent ; gotent = gotent->next)
|
||||
if (gotent->use_count > 0)
|
||||
@ -4445,7 +4483,7 @@ elf64_alpha_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
/* If the symbol has been forced local, output a
|
||||
RELATIVE reloc, otherwise it will be handled in
|
||||
finish_dynamic_symbol. */
|
||||
if (info->shared && !dynamic_symbol_p)
|
||||
if (info->shared && !dynamic_symbol_p && !undef_weak_ref)
|
||||
elf64_alpha_emit_dynrel (output_bfd, info, sgot, srelgot,
|
||||
gotent->got_offset, 0,
|
||||
R_ALPHA_RELATIVE, value);
|
||||
@ -4617,7 +4655,8 @@ elf64_alpha_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
}
|
||||
else if (info->shared
|
||||
&& r_symndx != 0
|
||||
&& (input_section->flags & SEC_ALLOC))
|
||||
&& (input_section->flags & SEC_ALLOC)
|
||||
&& !undef_weak_ref)
|
||||
{
|
||||
if (r_type == R_ALPHA_REFLONG)
|
||||
{
|
||||
@ -4650,6 +4689,14 @@ elf64_alpha_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
input_bfd, h->root.root.root.string);
|
||||
ret_val = FALSE;
|
||||
}
|
||||
else if ((info->shared || info->pie) && undef_weak_ref)
|
||||
{
|
||||
(*_bfd_error_handler)
|
||||
(_("%B: pc-relative relocation against undefined weak symbol %s"),
|
||||
input_bfd, h->root.root.root.string);
|
||||
ret_val = FALSE;
|
||||
}
|
||||
|
||||
|
||||
/* ??? .eh_frame references to discarded sections will be smashed
|
||||
to relocations against SHN_UNDEF. The .eh_frame format allows
|
||||
|
Loading…
x
Reference in New Issue
Block a user