forked from Imagelibrary/binutils-gdb
PowerPC32 treatment of absolute symbols
As already done for PowerPC64, fix dynamic relocs for absolute symbols. The patch also tidies the dynamic reloc handling code in check_relocs, removing leftover comments and code from when check_relocs was called as each object file was read in. bfd/ * elf32-ppc.c (ppc_elf_check_relocs): Set isym and ifunc earlier. Rearrange tests for dynamic relocs, handling absolute symbols. (allocate_dynrelocs): Don't allocate dynamic relocs for locally defined absolute symbols. (ppc_elf_size_dynamic_sections): Similarly. (ppc_elf_relocate_section): Similarly. ld/ * testsuite/ld-powerpc/abs32-pie.d, * testsuite/ld-powerpc/abs32-pie.r, * testsuite/ld-powerpc/abs32-reloc.s, * testsuite/ld-powerpc/abs32-shared.d, * testsuite/ld-powerpc/abs32-shared.r, * testsuite/ld-powerpc/abs32-static.d, * testsuite/ld-powerpc/abs32-static.r: New tests. * testsuite/ld-powerpc/powerpc.exp: Run them.
This commit is contained in:
129
bfd/elf32-ppc.c
129
bfd/elf32-ppc.c
@@ -2929,6 +2929,7 @@ ppc_elf_check_relocs (bfd *abfd,
|
||||
unsigned long r_symndx;
|
||||
enum elf_ppc_reloc_type r_type;
|
||||
struct elf_link_hash_entry *h;
|
||||
Elf_Internal_Sym *isym;
|
||||
int tls_type;
|
||||
struct plt_entry **ifunc;
|
||||
struct plt_entry **pltent;
|
||||
@@ -2936,13 +2937,19 @@ ppc_elf_check_relocs (bfd *abfd,
|
||||
|
||||
r_symndx = ELF32_R_SYM (rel->r_info);
|
||||
if (r_symndx < symtab_hdr->sh_info)
|
||||
h = NULL;
|
||||
{
|
||||
h = NULL;
|
||||
isym = bfd_sym_from_r_symndx (&htab->elf.sym_cache, abfd, r_symndx);
|
||||
if (isym == NULL)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
|
||||
while (h->root.type == bfd_link_hash_indirect
|
||||
|| h->root.type == bfd_link_hash_warning)
|
||||
h = (struct elf_link_hash_entry *) h->root.u.i.link;
|
||||
isym = NULL;
|
||||
}
|
||||
|
||||
/* If a relocation refers to _GLOBAL_OFFSET_TABLE_, create the .got.
|
||||
@@ -2962,13 +2969,16 @@ ppc_elf_check_relocs (bfd *abfd,
|
||||
tls_type = 0;
|
||||
r_type = ELF32_R_TYPE (rel->r_info);
|
||||
ifunc = NULL;
|
||||
if (h == NULL && htab->elf.target_os != is_vxworks)
|
||||
if (h != NULL)
|
||||
{
|
||||
if (h->type == STT_GNU_IFUNC)
|
||||
{
|
||||
h->needs_plt = 1;
|
||||
ifunc = &h->plt.plist;
|
||||
}
|
||||
}
|
||||
else if (htab->elf.target_os != is_vxworks)
|
||||
{
|
||||
Elf_Internal_Sym *isym = bfd_sym_from_r_symndx (&htab->elf.sym_cache,
|
||||
abfd, r_symndx);
|
||||
if (isym == NULL)
|
||||
return false;
|
||||
|
||||
if (ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
|
||||
{
|
||||
/* Set PLT_IFUNC flag for this sym, no GOT entry yet. */
|
||||
@@ -3294,12 +3304,10 @@ ppc_elf_check_relocs (bfd *abfd,
|
||||
htab->plt_type = PLT_OLD;
|
||||
htab->old_bfd = abfd;
|
||||
}
|
||||
if (h != NULL && h->type == STT_GNU_IFUNC)
|
||||
{
|
||||
h->needs_plt = 1;
|
||||
if (!update_plt_info (abfd, &h->plt.plist, NULL, 0))
|
||||
return false;
|
||||
}
|
||||
if (h != NULL
|
||||
&& ifunc != NULL
|
||||
&& !update_plt_info (abfd, ifunc, NULL, 0))
|
||||
return false;
|
||||
break;
|
||||
|
||||
/* This relocation describes the C++ object vtable hierarchy.
|
||||
@@ -3347,12 +3355,6 @@ ppc_elf_check_relocs (bfd *abfd,
|
||||
reliably deduce the GOT pointer value needed for
|
||||
PLT call stubs. */
|
||||
asection *s;
|
||||
Elf_Internal_Sym *isym;
|
||||
|
||||
isym = bfd_sym_from_r_symndx (&htab->elf.sym_cache,
|
||||
abfd, r_symndx);
|
||||
if (isym == NULL)
|
||||
return false;
|
||||
|
||||
s = bfd_section_from_elf_index (abfd, isym->st_shndx);
|
||||
if (s == got2)
|
||||
@@ -3421,38 +3423,21 @@ ppc_elf_check_relocs (bfd *abfd,
|
||||
}
|
||||
|
||||
dodyn:
|
||||
/* If we are creating a shared library, and this is a reloc
|
||||
against a global symbol, or a non PC relative reloc
|
||||
against a local symbol, then we need to copy the reloc
|
||||
into the shared library. However, if we are linking with
|
||||
-Bsymbolic, we do not need to copy a reloc against a
|
||||
global symbol which is defined in an object we are
|
||||
including in the link (i.e., DEF_REGULAR is set). At
|
||||
this point we have not seen all the input files, so it is
|
||||
possible that DEF_REGULAR is not set now but will be set
|
||||
later (it is never cleared). In case of a weak definition,
|
||||
DEF_REGULAR may be cleared later by a strong definition in
|
||||
a shared library. We account for that possibility below by
|
||||
storing information in the dyn_relocs field of the hash
|
||||
table entry. A similar situation occurs when creating
|
||||
shared libraries and symbol visibility changes render the
|
||||
symbol local.
|
||||
|
||||
If on the other hand, we are creating an executable, we
|
||||
may need to keep relocations for symbols satisfied by a
|
||||
dynamic library if we manage to avoid copy relocs for the
|
||||
symbol. */
|
||||
if ((bfd_link_pic (info)
|
||||
&& (must_be_dyn_reloc (info, r_type)
|
||||
|| (h != NULL
|
||||
&& (!SYMBOLIC_BIND (info, h)
|
||||
|| h->root.type == bfd_link_hash_defweak
|
||||
|| !h->def_regular))))
|
||||
|| (ELIMINATE_COPY_RELOCS
|
||||
&& !bfd_link_pic (info)
|
||||
&& h != NULL
|
||||
&& (h->root.type == bfd_link_hash_defweak
|
||||
|| !h->def_regular)))
|
||||
/* Set up information for symbols that might need dynamic
|
||||
relocations. At this point in linking we have read all
|
||||
the input files and resolved most symbols, but have not
|
||||
yet decided whether symbols are dynamic or finalized
|
||||
symbol flags. In some cases we might be setting dynamic
|
||||
reloc info for symbols that do not end up needing such.
|
||||
That's OK, adjust_dynamic_symbol and allocate_dynrelocs
|
||||
work together with this code. */
|
||||
if ((h != NULL
|
||||
&& !SYMBOL_REFERENCES_LOCAL (info, h))
|
||||
|| (bfd_link_pic (info)
|
||||
&& (h != NULL
|
||||
? !bfd_is_abs_symbol (&h->root)
|
||||
: isym->st_shndx != SHN_ABS)
|
||||
&& must_be_dyn_reloc (info, r_type)))
|
||||
{
|
||||
#ifdef DEBUG
|
||||
fprintf (stderr,
|
||||
@@ -3507,12 +3492,6 @@ ppc_elf_check_relocs (bfd *abfd,
|
||||
bool is_ifunc;
|
||||
asection *s;
|
||||
void *vpp;
|
||||
Elf_Internal_Sym *isym;
|
||||
|
||||
isym = bfd_sym_from_r_symndx (&htab->elf.sym_cache,
|
||||
abfd, r_symndx);
|
||||
if (isym == NULL)
|
||||
return false;
|
||||
|
||||
s = bfd_section_from_elf_index (abfd, isym->st_shndx);
|
||||
if (s == NULL)
|
||||
@@ -3520,7 +3499,7 @@ ppc_elf_check_relocs (bfd *abfd,
|
||||
|
||||
vpp = &elf_section_data (s)->local_dynrel;
|
||||
rel_head = (struct ppc_dyn_relocs **) vpp;
|
||||
is_ifunc = ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC;
|
||||
is_ifunc = ifunc != NULL;
|
||||
p = *rel_head;
|
||||
if (p != NULL && p->sec == sec && p->ifunc != is_ifunc)
|
||||
p = p->next;
|
||||
@@ -5170,7 +5149,8 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
|
||||
if (((bfd_link_pic (info)
|
||||
&& !((eh->tls_mask & TLS_TLS) != 0
|
||||
&& bfd_link_executable (info)
|
||||
&& SYMBOL_REFERENCES_LOCAL (info, &eh->elf)))
|
||||
&& SYMBOL_REFERENCES_LOCAL (info, &eh->elf))
|
||||
&& !bfd_is_abs_symbol (&h->root))
|
||||
|| (htab->elf.dynamic_sections_created
|
||||
&& eh->elf.dynindx != -1
|
||||
&& !SYMBOL_REFERENCES_LOCAL (info, &eh->elf)))
|
||||
@@ -5540,6 +5520,8 @@ ppc_elf_size_dynamic_sections (bfd *output_bfd,
|
||||
char *lgot_masks;
|
||||
bfd_size_type locsymcount;
|
||||
Elf_Internal_Shdr *symtab_hdr;
|
||||
Elf_Internal_Sym *local_syms;
|
||||
Elf_Internal_Sym *isym;
|
||||
|
||||
if (!is_ppc_elf (ibfd))
|
||||
continue;
|
||||
@@ -5596,8 +5578,18 @@ ppc_elf_size_dynamic_sections (bfd *output_bfd,
|
||||
local_plt = (struct plt_entry **) end_local_got;
|
||||
end_local_plt = local_plt + locsymcount;
|
||||
lgot_masks = (char *) end_local_plt;
|
||||
local_syms = (Elf_Internal_Sym *) symtab_hdr->contents;
|
||||
if (local_syms == NULL && locsymcount != 0)
|
||||
{
|
||||
local_syms = bfd_elf_get_elf_syms (ibfd, symtab_hdr, locsymcount,
|
||||
0, NULL, NULL, NULL);
|
||||
if (local_syms == NULL)
|
||||
return false;
|
||||
}
|
||||
|
||||
for (; local_got < end_local_got; ++local_got, ++lgot_masks)
|
||||
for (isym = local_syms;
|
||||
local_got < end_local_got;
|
||||
++local_got, ++lgot_masks, ++isym)
|
||||
if (*local_got > 0)
|
||||
{
|
||||
unsigned int need;
|
||||
@@ -5611,7 +5603,8 @@ ppc_elf_size_dynamic_sections (bfd *output_bfd,
|
||||
*local_got = allocate_got (htab, need);
|
||||
if (bfd_link_pic (info)
|
||||
&& !((*lgot_masks & TLS_TLS) != 0
|
||||
&& bfd_link_executable (info)))
|
||||
&& bfd_link_executable (info))
|
||||
&& isym->st_shndx != SHN_ABS)
|
||||
{
|
||||
asection *srel;
|
||||
|
||||
@@ -5684,6 +5677,15 @@ ppc_elf_size_dynamic_sections (bfd *output_bfd,
|
||||
else
|
||||
ent->plt.offset = (bfd_vma) -1;
|
||||
}
|
||||
|
||||
if (local_syms != NULL
|
||||
&& symtab_hdr->contents != (unsigned char *) local_syms)
|
||||
{
|
||||
if (!info->keep_memory)
|
||||
free (local_syms);
|
||||
else
|
||||
symtab_hdr->contents = (unsigned char *) local_syms;
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocate space for global sym dynamic relocs. */
|
||||
@@ -7796,7 +7798,10 @@ ppc_elf_relocate_section (bfd *output_bfd,
|
||||
|| !UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
|
||||
&& !(tls_ty != 0
|
||||
&& bfd_link_executable (info)
|
||||
&& SYMBOL_REFERENCES_LOCAL (info, h))))
|
||||
&& SYMBOL_REFERENCES_LOCAL (info, h))
|
||||
&& (h != NULL
|
||||
? !bfd_is_abs_symbol (&h->root)
|
||||
: sym->st_shndx != SHN_ABS)))
|
||||
{
|
||||
asection *rsec = htab->elf.srelgot;
|
||||
bfd_byte * loc;
|
||||
|
||||
26
ld/testsuite/ld-powerpc/abs32-pie.d
Normal file
26
ld/testsuite/ld-powerpc/abs32-pie.d
Normal file
@@ -0,0 +1,26 @@
|
||||
#source: abs32-reloc.s
|
||||
#as: -a32
|
||||
#ld: -melf32ppc -pie --hash-style=sysv --defsym a=1 --defsym 'HIDDEN(b=2)' --defsym c=0x12345678
|
||||
#objdump: -dr
|
||||
|
||||
.*: file format .*
|
||||
|
||||
Disassembly of section \.text:
|
||||
|
||||
00000138 <_start>:
|
||||
138: (80 fe ff f0|f0 ff fe 80) lwz r7,-16\(r30\)
|
||||
13c: (81 1e ff f8|f8 ff 1e 81) lwz r8,-8\(r30\)
|
||||
140: (81 3e ff ec|ec ff 3e 81) lwz r9,-20\(r30\)
|
||||
144: (81 5e ff f4|f4 ff 5e 81) lwz r10,-12\(r30\)
|
||||
|
||||
Disassembly of section \.got:
|
||||
|
||||
000101d8 <\.got>:
|
||||
101d8: (00 00 00 02|02 00 00 00) .*
|
||||
101dc: (00 00 00 00|00 00 00 00) .*
|
||||
101e0: (12 34 56 78|78 56 34 12) .*
|
||||
101e4: (00 00 00 01|01 00 00 00) .*
|
||||
101e8: (4e 80 00 21|21 00 80 4e) blrl
|
||||
|
||||
000101ec <_GLOBAL_OFFSET_TABLE_>:
|
||||
101ec: (00 01 01 48|48 01 01 00) 00 00 00 00 00 00 00 00 .*
|
||||
9
ld/testsuite/ld-powerpc/abs32-pie.r
Normal file
9
ld/testsuite/ld-powerpc/abs32-pie.r
Normal file
@@ -0,0 +1,9 @@
|
||||
#source: abs32-reloc.s
|
||||
#as: -a32
|
||||
#ld: -melf32ppc -pie --hash-style=sysv --defsym a=1 --defsym 'HIDDEN(b=2)' --defsym c=0x12345678
|
||||
#readelf: -rW
|
||||
|
||||
Relocation section '\.rela\.dyn' at offset .* contains 2 entries:
|
||||
Offset Info Type Sym\. Value Symbol's Name \+ Addend
|
||||
000101c8 00000016 R_PPC_RELATIVE 101c8
|
||||
000101dc 00000016 R_PPC_RELATIVE 101c8
|
||||
22
ld/testsuite/ld-powerpc/abs32-reloc.s
Normal file
22
ld/testsuite/ld-powerpc/abs32-reloc.s
Normal file
@@ -0,0 +1,22 @@
|
||||
.globl x
|
||||
.hidden x
|
||||
|
||||
.data
|
||||
.p2align 2
|
||||
x:
|
||||
.long x
|
||||
.long a
|
||||
.long b
|
||||
.long c
|
||||
|
||||
.text
|
||||
.p2align 2
|
||||
.globl _start
|
||||
.type _start,@function
|
||||
_start:
|
||||
0:
|
||||
lwz 7,x@got(30)
|
||||
lwz 8,a@got(30)
|
||||
lwz 9,b@got(30)
|
||||
lwz 10,c@got(30)
|
||||
.size _start,.-_start
|
||||
24
ld/testsuite/ld-powerpc/abs32-shared.d
Normal file
24
ld/testsuite/ld-powerpc/abs32-shared.d
Normal file
@@ -0,0 +1,24 @@
|
||||
#source: abs32-reloc.s
|
||||
#as: -a32
|
||||
#ld: -melf32ppc -shared --hash-style=sysv --defsym a=1 --defsym 'HIDDEN(b=2)' --defsym c=0x12345678
|
||||
#objdump: -dr
|
||||
|
||||
.*: file format .*
|
||||
|
||||
Disassembly of section \.text:
|
||||
|
||||
00000160 <_start>:
|
||||
160: (80 fe ff f0|f0 ff fe 80) lwz r7,-16\(r30\)
|
||||
164: (81 1e ff f8|f8 ff 1e 81) lwz r8,-8\(r30\)
|
||||
168: (81 3e ff ec|ec ff 3e 81) lwz r9,-20\(r30\)
|
||||
16c: (81 5e ff f4|f4 ff 5e 81) lwz r10,-12\(r30\)
|
||||
|
||||
Disassembly of section \.got:
|
||||
|
||||
000101f0 <\.got>:
|
||||
101f0: (00 00 00 02|02 00 00 00) .*
|
||||
.\.\.
|
||||
10200: (4e 80 00 21|21 00 80 4e) blrl
|
||||
|
||||
00010204 <_GLOBAL_OFFSET_TABLE_>:
|
||||
10204: (00 01 01 70|70 01 01 00) 00 00 00 00 00 00 00 00 .*
|
||||
13
ld/testsuite/ld-powerpc/abs32-shared.r
Normal file
13
ld/testsuite/ld-powerpc/abs32-shared.r
Normal file
@@ -0,0 +1,13 @@
|
||||
#source: abs32-reloc.s
|
||||
#as: -a32
|
||||
#ld: -melf32ppc -shared --hash-style=sysv --defsym a=1 --defsym 'HIDDEN(b=2)' --defsym c=0x12345678
|
||||
#readelf: -rW
|
||||
|
||||
Relocation section '\.rela\.dyn' at offset .* contains 6 entries:
|
||||
Offset Info Type Sym\. Value Symbol's Name \+ Addend
|
||||
000101e0 00000016 R_PPC_RELATIVE 101e0
|
||||
000101f4 00000016 R_PPC_RELATIVE 101e0
|
||||
000101e4 00000401 R_PPC_ADDR32 00000001 a \+ 0
|
||||
000101fc 00000414 R_PPC_GLOB_DAT 00000001 a \+ 0
|
||||
000101ec 00000301 R_PPC_ADDR32 12345678 c \+ 0
|
||||
000101f8 00000314 R_PPC_GLOB_DAT 12345678 c \+ 0
|
||||
26
ld/testsuite/ld-powerpc/abs32-static.d
Normal file
26
ld/testsuite/ld-powerpc/abs32-static.d
Normal file
@@ -0,0 +1,26 @@
|
||||
#source: abs32-reloc.s
|
||||
#as: -a32
|
||||
#ld: -melf32ppc -static --defsym a=1 --defsym 'HIDDEN(b=2)' --defsym c=0x12345678
|
||||
#objdump: -dr
|
||||
|
||||
.*: file format .*
|
||||
|
||||
Disassembly of section \.text:
|
||||
|
||||
01800074 <_start>:
|
||||
1800074: (80 fe ff f0|f0 ff fe 80) lwz r7,-16\(r30\)
|
||||
1800078: (81 1e ff f8|f8 ff 1e 81) lwz r8,-8\(r30\)
|
||||
180007c: (81 3e ff ec|ec ff 3e 81) lwz r9,-20\(r30\)
|
||||
1800080: (81 5e ff f4|f4 ff 5e 81) lwz r10,-12\(r30\)
|
||||
|
||||
Disassembly of section \.got:
|
||||
|
||||
01810094 <\.got>:
|
||||
1810094: (00 00 00 02|02 00 00 00) .*
|
||||
1810098: (01 81 00 84|84 00 81 01) .*
|
||||
181009c: (12 34 56 78|78 56 34 12) .*
|
||||
18100a0: (00 00 00 01|01 00 00 00) .*
|
||||
18100a4: (4e 80 00 21|21 00 80 4e) blrl
|
||||
|
||||
018100a8 <_GLOBAL_OFFSET_TABLE_>:
|
||||
\.\.\.
|
||||
6
ld/testsuite/ld-powerpc/abs32-static.r
Normal file
6
ld/testsuite/ld-powerpc/abs32-static.r
Normal file
@@ -0,0 +1,6 @@
|
||||
#source: abs32-reloc.s
|
||||
#as: -a32
|
||||
#ld: -melf32ppc -static --defsym a=1 --defsym 'HIDDEN(b=2)' --defsym c=0x12345678
|
||||
#readelf: -rW
|
||||
|
||||
There are no relocations in this file.
|
||||
@@ -173,6 +173,18 @@ set ppcelftests {
|
||||
{{objdump -dr relaxrl.d}}
|
||||
"rrelax"}
|
||||
{"build empty shared library" "-shared" "" "" "empty.s" {} "empty.so"}
|
||||
{"abs32-static" "-melf32ppc -static --defsym a=1 --defsym 'HIDDEN(b=2)' --defsym c=0x12345678" ""
|
||||
"-a32" {abs32-reloc.s}
|
||||
{{objdump {-dr} abs32-static.d}
|
||||
{readelf {-rW} abs32-static.r}} "abs32-static"}
|
||||
{"abs32-pie" "-melf32ppc -pie --hash-style=sysv --defsym a=1 --defsym 'HIDDEN(b=2)' --defsym c=0x12345678" ""
|
||||
"-a32" {abs32-reloc.s}
|
||||
{{objdump {-dr} abs32-pie.d}
|
||||
{readelf {-rW} abs32-pie.r}} "abs32-pie"}
|
||||
{"abs32-shared" "-melf32ppc -shared --hash-style=sysv --defsym a=1 --defsym 'HIDDEN(b=2)' --defsym c=0x12345678" ""
|
||||
"-a32" {abs32-reloc.s}
|
||||
{{objdump {-dr} abs32-shared.d}
|
||||
{readelf {-rW} abs32-shared.r}} "abs32-shared"}
|
||||
}
|
||||
|
||||
set ppc64elftests {
|
||||
|
||||
Reference in New Issue
Block a user