mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-21 02:24:17 +08:00
* bfd/elf64-alpha.c (elf64_alpha_relocate_section): Use the
got_enties of the default symbol for the default versioned symbol. Patch from hjl@gnu.ai.mit.edu, modified not to use alloca in the loop.
This commit is contained in:
@ -1,3 +1,10 @@
|
||||
Mon Oct 13 21:24:04 1997 Richard Henderson <rth@cygnus.com>
|
||||
|
||||
* bfd/elf64-alpha.c (elf64_alpha_relocate_section): Use the
|
||||
got_enties of the default symbol for the default versioned
|
||||
symbol. Patch from hjl@gnu.ai.mit.edu, modified not to use
|
||||
alloca in the loop.
|
||||
|
||||
Mon Oct 13 17:37:37 1997 Nick Clifton <nickc@cygnus.com>
|
||||
|
||||
* elf32-v850.c (v850_elf_final_link_relocate): Only use the bottom
|
||||
|
@ -329,6 +329,22 @@ elf64_alpha_mkobject (abfd)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static boolean
|
||||
elf64_alpha_object_p (abfd)
|
||||
bfd *abfd;
|
||||
{
|
||||
/* Allocate our special target data. */
|
||||
struct alpha_elf_obj_tdata *new_tdata;
|
||||
new_tdata = bfd_zalloc (abfd, sizeof (struct alpha_elf_obj_tdata));
|
||||
if (new_tdata == NULL)
|
||||
return false;
|
||||
new_tdata->root = *abfd->tdata.elf_obj_data;
|
||||
abfd->tdata.any = new_tdata;
|
||||
|
||||
/* Set the right machine number for an Alpha ELF file. */
|
||||
return bfd_default_set_arch_mach (abfd, bfd_arch_alpha, 0);
|
||||
}
|
||||
|
||||
/* In case we're on a 32-bit machine, construct a 64-bit "-1" value
|
||||
from smaller values. Start with zero, widen, *then* decrement. */
|
||||
@ -539,7 +555,8 @@ static reloc_howto_type elf64_alpha_howto_table[] =
|
||||
false), /* pcrel_offset */
|
||||
|
||||
/* Push a value on the reloc evaluation stack. */
|
||||
HOWTO (ALPHA_R_OP_PUSH, /* type */
|
||||
/* Not implemented -- it's dumb. */
|
||||
HOWTO (R_ALPHA_OP_PUSH, /* type */
|
||||
0, /* rightshift */
|
||||
0, /* size (0 = byte, 1 = short, 2 = long) */
|
||||
0, /* bitsize */
|
||||
@ -555,7 +572,8 @@ static reloc_howto_type elf64_alpha_howto_table[] =
|
||||
|
||||
/* Store the value from the stack at the given address. Store it in
|
||||
a bitfield of size r_size starting at bit position r_offset. */
|
||||
HOWTO (ALPHA_R_OP_STORE, /* type */
|
||||
/* Not implemented -- it's dumb. */
|
||||
HOWTO (R_ALPHA_OP_STORE, /* type */
|
||||
0, /* rightshift */
|
||||
4, /* size (0 = byte, 1 = short, 2 = long) */
|
||||
64, /* bitsize */
|
||||
@ -571,7 +589,8 @@ static reloc_howto_type elf64_alpha_howto_table[] =
|
||||
|
||||
/* Subtract the reloc address from the value on the top of the
|
||||
relocation stack. */
|
||||
HOWTO (ALPHA_R_OP_PSUB, /* type */
|
||||
/* Not implemented -- it's dumb. */
|
||||
HOWTO (R_ALPHA_OP_PSUB, /* type */
|
||||
0, /* rightshift */
|
||||
0, /* size (0 = byte, 1 = short, 2 = long) */
|
||||
0, /* bitsize */
|
||||
@ -587,7 +606,8 @@ static reloc_howto_type elf64_alpha_howto_table[] =
|
||||
|
||||
/* Shift the value on the top of the relocation stack right by the
|
||||
given value. */
|
||||
HOWTO (ALPHA_R_OP_PRSHIFT, /* type */
|
||||
/* Not implemented -- it's dumb. */
|
||||
HOWTO (R_ALPHA_OP_PRSHIFT, /* type */
|
||||
0, /* rightshift */
|
||||
0, /* size (0 = byte, 1 = short, 2 = long) */
|
||||
0, /* bitsize */
|
||||
@ -601,7 +621,146 @@ static reloc_howto_type elf64_alpha_howto_table[] =
|
||||
0, /* dst_mask */
|
||||
false), /* pcrel_offset */
|
||||
|
||||
/* Change the value of GP used by +r_addend until the next GPVALUE or the
|
||||
end of the input bfd. */
|
||||
/* Not implemented -- it's dumb. */
|
||||
HOWTO (R_ALPHA_GPVALUE,
|
||||
0, /* rightshift */
|
||||
0, /* size (0 = byte, 1 = short, 2 = long) */
|
||||
0, /* bitsize */
|
||||
false, /* pc_relative */
|
||||
0, /* bitpos */
|
||||
complain_overflow_dont, /* complain_on_overflow */
|
||||
elf64_alpha_reloc_bad, /* special_function */
|
||||
"GPVALUE", /* name */
|
||||
false, /* partial_inplace */
|
||||
0, /* src_mask */
|
||||
0, /* dst_mask */
|
||||
false), /* pcrel_offset */
|
||||
|
||||
/* The high 16 bits of the displacement from GP to the target. */
|
||||
/* XXX: Not implemented. */
|
||||
HOWTO (R_ALPHA_GPRELHIGH,
|
||||
0, /* rightshift */
|
||||
0, /* size (0 = byte, 1 = short, 2 = long) */
|
||||
0, /* bitsize */
|
||||
false, /* pc_relative */
|
||||
0, /* bitpos */
|
||||
complain_overflow_dont, /* complain_on_overflow */
|
||||
elf64_alpha_reloc_bad, /* special_function */
|
||||
"GPRELHIGH", /* name */
|
||||
false, /* partial_inplace */
|
||||
0, /* src_mask */
|
||||
0, /* dst_mask */
|
||||
false), /* pcrel_offset */
|
||||
|
||||
/* The low 16 bits of the displacement from GP to the target. */
|
||||
/* XXX: Not implemented. */
|
||||
HOWTO (R_ALPHA_GPRELLOW,
|
||||
0, /* rightshift */
|
||||
0, /* size (0 = byte, 1 = short, 2 = long) */
|
||||
0, /* bitsize */
|
||||
false, /* pc_relative */
|
||||
0, /* bitpos */
|
||||
complain_overflow_dont, /* complain_on_overflow */
|
||||
elf64_alpha_reloc_bad, /* special_function */
|
||||
"GPRELLOW", /* name */
|
||||
false, /* partial_inplace */
|
||||
0, /* src_mask */
|
||||
0, /* dst_mask */
|
||||
false), /* pcrel_offset */
|
||||
|
||||
/* A 16-bit displacement from the GP to the target. */
|
||||
/* XXX: Not implemented. */
|
||||
HOWTO (R_ALPHA_IMMED_GP_16,
|
||||
0, /* rightshift */
|
||||
0, /* size (0 = byte, 1 = short, 2 = long) */
|
||||
0, /* bitsize */
|
||||
false, /* pc_relative */
|
||||
0, /* bitpos */
|
||||
complain_overflow_dont, /* complain_on_overflow */
|
||||
elf64_alpha_reloc_bad, /* special_function */
|
||||
"IMMED_GP_16", /* name */
|
||||
false, /* partial_inplace */
|
||||
0, /* src_mask */
|
||||
0, /* dst_mask */
|
||||
false), /* pcrel_offset */
|
||||
|
||||
/* The high bits of a 32-bit displacement from the GP to the target; the
|
||||
low bits are supplied in the subsequent R_ALPHA_IMMED_LO32 relocs. */
|
||||
/* XXX: Not implemented. */
|
||||
HOWTO (R_ALPHA_IMMED_GP_HI32,
|
||||
0, /* rightshift */
|
||||
0, /* size (0 = byte, 1 = short, 2 = long) */
|
||||
0, /* bitsize */
|
||||
false, /* pc_relative */
|
||||
0, /* bitpos */
|
||||
complain_overflow_dont, /* complain_on_overflow */
|
||||
elf64_alpha_reloc_bad, /* special_function */
|
||||
"IMMED_GP_HI32", /* name */
|
||||
false, /* partial_inplace */
|
||||
0, /* src_mask */
|
||||
0, /* dst_mask */
|
||||
false), /* pcrel_offset */
|
||||
|
||||
/* The high bits of a 32-bit displacement to the starting address of the
|
||||
current section (the relocation target is ignored); the low bits are
|
||||
supplied in the subsequent R_ALPHA_IMMED_LO32 relocs. */
|
||||
/* XXX: Not implemented. */
|
||||
HOWTO (R_ALPHA_IMMED_SCN_HI32,
|
||||
0, /* rightshift */
|
||||
0, /* size (0 = byte, 1 = short, 2 = long) */
|
||||
0, /* bitsize */
|
||||
false, /* pc_relative */
|
||||
0, /* bitpos */
|
||||
complain_overflow_dont, /* complain_on_overflow */
|
||||
elf64_alpha_reloc_bad, /* special_function */
|
||||
"IMMED_SCN_HI32", /* name */
|
||||
false, /* partial_inplace */
|
||||
0, /* src_mask */
|
||||
0, /* dst_mask */
|
||||
false), /* pcrel_offset */
|
||||
|
||||
/* The high bits of a 32-bit displacement from the previous br, bsr, jsr
|
||||
or jmp insn (as tagged by a BRADDR or HINT reloc) to the target; the
|
||||
low bits are supplied by subsequent R_ALPHA_IMMED_LO32 relocs. */
|
||||
/* XXX: Not implemented. */
|
||||
HOWTO (R_ALPHA_IMMED_BR_HI32,
|
||||
0, /* rightshift */
|
||||
0, /* size (0 = byte, 1 = short, 2 = long) */
|
||||
0, /* bitsize */
|
||||
false, /* pc_relative */
|
||||
0, /* bitpos */
|
||||
complain_overflow_dont, /* complain_on_overflow */
|
||||
elf64_alpha_reloc_bad, /* special_function */
|
||||
"IMMED_BR_HI32", /* name */
|
||||
false, /* partial_inplace */
|
||||
0, /* src_mask */
|
||||
0, /* dst_mask */
|
||||
false), /* pcrel_offset */
|
||||
|
||||
/* The low 16 bits of a displacement calculated in a previous HI32 reloc. */
|
||||
/* XXX: Not implemented. */
|
||||
HOWTO (R_ALPHA_IMMED_LO32,
|
||||
0, /* rightshift */
|
||||
0, /* size (0 = byte, 1 = short, 2 = long) */
|
||||
0, /* bitsize */
|
||||
false, /* pc_relative */
|
||||
0, /* bitpos */
|
||||
complain_overflow_dont, /* complain_on_overflow */
|
||||
elf64_alpha_reloc_bad, /* special_function */
|
||||
"IMMED_LO32", /* name */
|
||||
false, /* partial_inplace */
|
||||
0, /* src_mask */
|
||||
0, /* dst_mask */
|
||||
false), /* pcrel_offset */
|
||||
|
||||
/* Misc ELF relocations. */
|
||||
|
||||
/* A dynamic relocation to copy the target into our .dynbss section. */
|
||||
/* Not generated, as all Alpha objects use PIC, so it is not needed. It
|
||||
is present because every other ELF has one, but should not be used
|
||||
because .dynbss is an ugly thing. */
|
||||
HOWTO (R_ALPHA_COPY,
|
||||
0,
|
||||
0,
|
||||
@ -616,6 +775,7 @@ static reloc_howto_type elf64_alpha_howto_table[] =
|
||||
0,
|
||||
true),
|
||||
|
||||
/* A dynamic relocation for a .got entry. */
|
||||
HOWTO (R_ALPHA_GLOB_DAT,
|
||||
0,
|
||||
0,
|
||||
@ -630,6 +790,7 @@ static reloc_howto_type elf64_alpha_howto_table[] =
|
||||
0,
|
||||
true),
|
||||
|
||||
/* A dynamic relocation for a .plt entry. */
|
||||
HOWTO (R_ALPHA_JMP_SLOT,
|
||||
0,
|
||||
0,
|
||||
@ -644,6 +805,7 @@ static reloc_howto_type elf64_alpha_howto_table[] =
|
||||
0,
|
||||
true),
|
||||
|
||||
/* A dynamic relocation to add the base of the DSO to a 64-bit field. */
|
||||
HOWTO (R_ALPHA_RELATIVE,
|
||||
0,
|
||||
0,
|
||||
@ -850,23 +1012,14 @@ elf64_alpha_info_to_howto (abfd, cache_ptr, dst)
|
||||
#define PLT_HEADER_WORD4 0x6b7b0000 /* jmp $27,($27) */
|
||||
|
||||
#define PLT_ENTRY_SIZE 12
|
||||
#define PLT_ENTRY_WORD1 0x279f0000 /* ldah $28, 0($31) */
|
||||
#define PLT_ENTRY_WORD2 0x239c0000 /* lda $28, 0($28) */
|
||||
#define PLT_ENTRY_WORD3 0xc3e00000 /* br $31, plt0 */
|
||||
#define PLT_ENTRY_WORD1 0xc3800000 /* br $28, plt0 */
|
||||
#define PLT_ENTRY_WORD2 0
|
||||
#define PLT_ENTRY_WORD3 0
|
||||
|
||||
#define MAX_GOT_ENTRIES (64*1024 / 8)
|
||||
|
||||
#define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so"
|
||||
|
||||
/* Set the right machine number for an Alpha ELF file. */
|
||||
|
||||
static boolean
|
||||
elf64_alpha_object_p (abfd)
|
||||
bfd *abfd;
|
||||
{
|
||||
return bfd_default_set_arch_mach (abfd, bfd_arch_alpha, 0);
|
||||
}
|
||||
|
||||
/* Handle an Alpha specific section when reading an object file. This
|
||||
is called when elfcode.h finds a section with an unknown type.
|
||||
FIXME: We need to handle the SHF_MIPS_GPREL flag, but I'm not sure
|
||||
@ -1785,7 +1938,8 @@ elf64_alpha_adjust_dynamic_symbol (info, h)
|
||||
|
||||
if (h->root.type != bfd_link_hash_undefweak
|
||||
&& alpha_elf_dynamic_symbol_p (h, info)
|
||||
&& (h->type == STT_FUNC
|
||||
&& ((h->type == STT_FUNC
|
||||
&& !(ah->flags & ALPHA_ELF_LINK_HASH_LU_ADDR))
|
||||
|| (h->type == STT_NOTYPE
|
||||
&& ah->flags == ALPHA_ELF_LINK_HASH_LU_FUNC))
|
||||
/* Don't prevent otherwise valid programs from linking by attempting
|
||||
@ -1946,6 +2100,7 @@ elf64_alpha_merge_gots (a, b)
|
||||
for (ae = *start; ae ; ae = ae->next)
|
||||
if (ae->gotobj == a && ae->addend == be->addend)
|
||||
{
|
||||
ae->flags |= be->flags;
|
||||
*pbe = be->next;
|
||||
goto global_found;
|
||||
}
|
||||
@ -2297,7 +2452,8 @@ elf64_alpha_size_dynamic_sections (output_bfd, info)
|
||||
s->output_section);
|
||||
target = bfd_get_section_by_name (output_bfd, outname + 5);
|
||||
if (target != NULL
|
||||
&& (target->flags & SEC_READONLY) != 0)
|
||||
&& (target->flags & SEC_READONLY) != 0
|
||||
&& (target->flags & SEC_ALLOC) != 0)
|
||||
reltext = true;
|
||||
|
||||
if (strcmp(name, ".rela.plt") == 0)
|
||||
@ -2610,6 +2766,39 @@ elf64_alpha_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
if (h != NULL)
|
||||
{
|
||||
gotent = h->got_entries;
|
||||
|
||||
/* We may be looking at a default versioned symbol, which
|
||||
won't have the got entries we set up earlier. Go find
|
||||
the original. */
|
||||
if (!gotent)
|
||||
{
|
||||
struct alpha_elf_link_hash_entry *v;
|
||||
char *p, *name;
|
||||
size_t len;
|
||||
|
||||
p = strchr (h->root.root.root.string, ELF_VER_CHR);
|
||||
BFD_ASSERT (p != NULL && p[1] == ELF_VER_CHR);
|
||||
|
||||
len = p - h->root.root.root.string;
|
||||
name = bfd_malloc (len + 1);
|
||||
if (name == NULL)
|
||||
return false;
|
||||
memcpy (name, h->root.root.root.string, len);
|
||||
name[len] = '\0';
|
||||
|
||||
v = alpha_elf_link_hash_lookup (alpha_elf_hash_table (info),
|
||||
name, false, false, false);
|
||||
BFD_ASSERT (v != NULL);
|
||||
while (v->got_entries == NULL)
|
||||
{
|
||||
BFD_ASSERT (v->root.root.type==bfd_link_hash_indirect);
|
||||
v = (struct alpha_elf_link_hash_entry *)
|
||||
v->root.root.u.i.link;
|
||||
}
|
||||
gotent = v->got_entries;
|
||||
free (name);
|
||||
}
|
||||
|
||||
while (gotent->gotobj != gotobj || gotent->addend != addend)
|
||||
gotent = gotent->next;
|
||||
|
||||
@ -2687,6 +2876,7 @@ elf64_alpha_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
case R_ALPHA_REFQUAD:
|
||||
{
|
||||
Elf_Internal_Rela outrel;
|
||||
boolean skip;
|
||||
|
||||
/* Careful here to remember RELATIVE relocations for global
|
||||
variables for symbolic shared objects. */
|
||||
@ -2719,9 +2909,29 @@ elf64_alpha_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||
BFD_ASSERT(srel != NULL);
|
||||
}
|
||||
|
||||
outrel.r_offset = (input_section->output_section->vma
|
||||
+ input_section->output_offset
|
||||
+ rel->r_offset);
|
||||
skip = false;
|
||||
|
||||
if (elf_section_data (input_section)->stab_info == NULL)
|
||||
outrel.r_offset = rel->r_offset;
|
||||
else
|
||||
{
|
||||
bfd_vma off;
|
||||
|
||||
off = (_bfd_stab_section_offset
|
||||
(output_bfd, &elf_hash_table (info)->stab_info,
|
||||
input_section,
|
||||
&elf_section_data (input_section)->stab_info,
|
||||
rel->r_offset));
|
||||
if (off == (bfd_vma) -1)
|
||||
skip = true;
|
||||
outrel.r_offset = off;
|
||||
}
|
||||
|
||||
if (! skip)
|
||||
outrel.r_offset += (input_section->output_section->vma
|
||||
+ input_section->output_offset);
|
||||
else
|
||||
memset (&outrel, 0, sizeof outrel);
|
||||
|
||||
bfd_elf64_swap_reloca_out (output_bfd, &outrel,
|
||||
((Elf64_External_Rela *)
|
||||
@ -2821,16 +3031,10 @@ elf64_alpha_finish_dynamic_symbol (output_bfd, info, h, sym)
|
||||
/* Fill in the entry in the procedure linkage table. */
|
||||
{
|
||||
unsigned insn1, insn2, insn3;
|
||||
long hi, lo;
|
||||
|
||||
/* decompose the reloc offset for the plt for ldah+lda */
|
||||
hi = plt_index * sizeof(Elf64_External_Rela);
|
||||
lo = ((hi & 0xffff) ^ 0x8000) - 0x8000;
|
||||
hi = (hi - lo) >> 16;
|
||||
|
||||
insn1 = PLT_ENTRY_WORD1 | (hi & 0xffff);
|
||||
insn2 = PLT_ENTRY_WORD2 | (lo & 0xffff);
|
||||
insn3 = PLT_ENTRY_WORD3 | ((-(h->plt_offset + 12) >> 2) & 0x1fffff);
|
||||
insn1 = PLT_ENTRY_WORD1 | ((-(h->plt_offset + 4) >> 2) & 0x1fffff);
|
||||
insn2 = PLT_ENTRY_WORD2;
|
||||
insn3 = PLT_ENTRY_WORD3;
|
||||
|
||||
bfd_put_32 (output_bfd, insn1, splt->contents + h->plt_offset);
|
||||
bfd_put_32 (output_bfd, insn2, splt->contents + h->plt_offset + 4);
|
||||
@ -3715,9 +3919,9 @@ elf64_alpha_ecoff_debug_swap =
|
||||
|
||||
#define bfd_elf64_mkobject \
|
||||
elf64_alpha_mkobject
|
||||
|
||||
#define elf_backend_object_p \
|
||||
elf64_alpha_object_p
|
||||
|
||||
#define elf_backend_section_from_shdr \
|
||||
elf64_alpha_section_from_shdr
|
||||
#define elf_backend_fake_sections \
|
||||
|
Reference in New Issue
Block a user