In check_relocs, bfd_link_pic true means ld is producing a shared
library or a position independent executable. !bfd_link_pic means a
fixed position (ie. static) executable since the relocatable linking
case is excluded. So it is appropriate to continue using bfd_link_pic
when testing whether non-pcrelative relocations should be dynamic, and
!bfd_link_pic for the special case of ifunc in static executables.
However, -Bsymbolic shouldn't affect PIEs (they are executables so
none of their symbols should be overridden) and PIEs can support copy
relocations, thus bfd_link_executable should be used in those cases
rather than bfd_link_pic.
I've also removed the test of ELIMINATE_COPY_RELOCS in check_relocs.
We can sort out what to do regarding copy relocs later, which allows
the code in check_relocs to be simplified.
* elf64-ppc.c (ppc64_elf_check_relocs): Use bfd_link_executable
in choosing between different actions for shared library and
non-shared library cases. Delete ELIMINATE_COPY_RELOCS test.
(dec_dynrel_count): Likewise. Account for ifunc special case.
(ppc64_elf_adjust_dynamic_symbol): Copy relocs are for executables,
not non-pic.
(allocate_dynrelocs): Comment fixes. Delete ELIMINATE_COPY_RELOCS
test.
This patch corrects the set of dynamic relocations recognised by gold
as supported by glibc, and teaches ld.bfd to report an error similar
to the gold error. Note that ld --noinhibit-exec can be used to
produce an output, supporting older ld with newer glibc if the set of
supported glibc dynamic relocations changes.
bfd/
* elf64-ppc.c (ppc64_glibc_dynamic_reloc): New function.
(ppc64_elf_relocate_section): Error if emitting unsupported
dynamic relocations.
gold/
* powerpc.cc (Target_powerpc::Scan::check_non_pic): Move REL24
to 32-bit supported.
Some versions of clang apparently generate non-PIC on powerpc64le to
access common symbols. Since a common symbol and a strong definition
with the same name should resolve to the strong definition we have the
possibility of non-PIC attempting to access shared library variables.
This is really a clanger since powerpc64le is supposed to be PIC by
default, but let's see if ld can cope by generating .dynbss copies.
* elf64-ppc.c (must_be_dyn_reloc): Return 0 for TOC16 relocs.
(ppc64_elf_check_relocs): Support dynamic/copy relocs for TOC16.
(ppc64_elf_adjust_dynamic_symbol): Don't keep dynamic reloc when
needs_copy even if all relocs are in rw sections.
(dec_dynrel_count): Handle TOC16 relocs.
(ppc64_elf_relocate_section): Support dynamic relocs for TOC16.
(ppc64_elf_finish_dynamic_symbol): Adjust to handle needs_copy
semantic change.
PC-relative relocs typically use the addend in adjusting what they are
relative to. For example:
bcl 20,31,1f
1: mflr 12
addi 12,12,xxx-1b
generates "R_PPC64_REL16 xxx+0x4" for the addi (when little-endian).
The addend reflects the fact that you want the offset relative to the
previous insn not the current one in this case.
So the question is, will we ever want to do something like that for an
instruction using R_PPC64_GOT_PCREL34? I thought so at the time I
first implemented support in ld but at the time I think the hardware
was possibly going to support pcrel+offset+reg addressing. In which
case you might want something like:
load_big_offset_into_r2
pld 3,sym-big_offset@got@pcrel(2)
which would be a way of supporting more than 8G offsets from code to
the GOT. We could do the same with
load_big_offset_into_r2
pla 9,sym-big_offset@got@pcrel
ldx 3,9,2
However, this is really a poor version of TOC-pointer relative code.
So let's go with an addend on R_PPC64_GOT_PCREL34 meaning that
sym+addend should be put in a GOT entry, and the relocation calculate
the pc-relative offset to that GOT entry.
Note that this is an extension to the ABI, which says (by the
expression given for GOT relocs) that non-zero addends on GOT and PLT
relocs are ignored. This is true for all GOT/PLT relocs, not just the
pcrel ones.
* elf64-ppc.c (ppc64_elf_check_relocs): Interpret an addend in
GOT_PCREL and PLT_PCREL relocs as affecting the value stored
in the GOT/PLT entry rather than affecting the offset to that
GOI/PLT entry.
(ppc64_elf_edit_toc, ppc64_elf_relocate_section): Likewise.
The loads and stores handled in the second instruction of a sequence
marked by R_PPC64_PCREL_OPT may be a prefix instruction. For example:
pld ra,symbol@got@pcrel
0:
pld rt,off(ra)
.reloc 0b-8,R_PPC64_PCREL_OPT,(.-8)-(0b-8)
can be optimised to
pld rt,symbol+off@pcrel
pnop
* elf64-ppc.c (xlate_pcrel_opt): Handle prefix loads and stores
in second instruction.
(ppc64_elf_relocate_section): Likewise.
We can easily support an offset on the second instruction of a
sequence marked with R_PPC64_PCREL_OPT. For example,
pla ra,symbol@pcrel
ld rt,off(ra)
can be optimised to
pld rt,symbol+off@pcrel
nop
* elf64-ppc.c (xlate_pcrel_opt): Add poff parameter. Allow offset
on second insn, return it in poff.
(ppc64_elf_relocate_section): Add offset to paddi addend for
PCREL_OPT.
Found on a GOT reference to __ehdr_start, which is tweaked to be
undefined weak at some stages of linking. SYMBOL_REFERENCES_LOCAL
isn't a sufficient test.
* elf64-ppc.c (ppc64_elf_edit_toc): Exclude undefined weak
symbols from GOT optimisation.
These are done in ppc64_elf_edit_toc, which now also garbage collects
unused GOT entries. The checks for legitimate instructions weren't
being done for the GOT relocs, unless the file also happened to have a
toc section.
* elf64-ppc.c (struct ppc64_elf_obj_tdata): Rename has_gotrel
to has_optrel.
(struct _ppc64_elf_section_data): Likewise.
(ppc64_elf_check_relocs): Set has_optrel for more relocs.
(ppc64_elf_edit_toc): Do ha/lo insn checks in GOT loop rather
than TOC loop. Check PLT16 insns too.
This patch supports using pcrel instructions in TLS code sequences. A
number of new relocations are needed, gas operand modifiers to
generate those relocations, and new TLS optimisation. For
optimisation it turns out that the new pcrel GD and LD sequences can
be distinguished from the non-pcrel GD and LD sequences by there being
different relocations on the new sequence. The final "add ra,rb,13"
on IE sequences similarly needs a new relocation, or as I chose, a
modification of R_PPC64_TLS. On pcrel IE code, the R_PPC64_TLS points
one byte into the "add" instruction rather than being on the
instruction boundary.
GD:
pla 3,z@got@tlsgd@pcrel # R_PPC64_GOT_TLSGD34
bl __tls_get_addr@notoc(z@tlsgd) # R_PPC64_TLSGD and R_PPC64_REL24_NOTOC
edited to IE
pld 3,z@got@tprel@pcrel
add 3,3,13
edited to LE
paddi 3,13,z@tprel
nop
LD:
pla 3,z@got@tlsld@pcrel # R_PPC64_GOT_TLSLD34
bl __tls_get_addr@notoc(z@tlsld) # R_PPC64_TLSLD and R_PPC64_REL24_NOTOC
..
paddi 9,3,z2@dtprel
pld 10,z3@got@dtprel@pcrel
add 10,10,3
edited to LE
paddi 3,13,0x1000
nop
IE:
pld 9,z@got@tprel@pcrel # R_PPC64_GOT_TPREL34
add 3,9,z@tls@pcrel # R_PPC64_TLS at insn+1
ldx 4,9,z@tls@pcrel
lwax 5,9,z@tls@pcrel
stdx 5,9,z@tls@pcrel
edited to LE
paddi 9,13,z@tprel
nop
ld 4,0(9)
lwa 5,0(9)
std 5,0(9)
LE:
paddi 10,13,z@tprel
include/
* elf/ppc64.h (R_PPC64_TPREL34, R_PPC64_DTPREL34),
(R_PPC64_GOT_TLSGD34, R_PPC64_GOT_TLSLD34),
(R_PPC64_GOT_TPREL34, R_PPC64_GOT_DTPREL34): Define.
(IS_PPC64_TLS_RELOC): Include new tls relocs.
bfd/
* reloc.c (BFD_RELOC_PPC64_TPREL34, BFD_RELOC_PPC64_DTPREL34),
(BFD_RELOC_PPC64_GOT_TLSGD34, BFD_RELOC_PPC64_GOT_TLSLD34),
(BFD_RELOC_PPC64_GOT_TPREL34, BFD_RELOC_PPC64_GOT_DTPREL34),
(BFD_RELOC_PPC64_TLS_PCREL): New pcrel tls relocs.
* elf64-ppc.c (ppc64_elf_howto_raw): Add howtos for pcrel tls relocs.
(ppc64_elf_reloc_type_lookup): Translate pcrel tls relocs.
(must_be_dyn_reloc, dec_dynrel_count): Add R_PPC64_TPREL64.
(ppc64_elf_check_relocs): Support pcrel tls relocs.
(ppc64_elf_tls_optimize, ppc64_elf_relocate_section): Likewise.
* bfd-in2.h: Regenerate.
* libbfd.h: Regenerate.
gas/
* config/tc-ppc.c (ppc_elf_suffix): Map "tls@pcrel", "got@tlsgd@pcrel",
"got@tlsld@pcrel", "got@tprel@pcrel", and "got@dtprel@pcrel".
(fixup_size, md_assemble): Handle pcrel tls relocs.
(ppc_force_relocation, ppc_fix_adjustable): Likewise.
(md_apply_fix, tc_gen_reloc): Likewise.
ld/
* testsuite/ld-powerpc/tlsgd.d,
* testsuite/ld-powerpc/tlsgd.s,
* testsuite/ld-powerpc/tlsie.d,
* testsuite/ld-powerpc/tlsie.s,
* testsuite/ld-powerpc/tlsld.d,
* testsuite/ld-powerpc/tlsld.s: New tests.
* testsuite/ld-powerpc/powerpc.exp: Run them.
It's not correct to use non-STT_TLS symbols with TLS relocation, not
that it matters much when editing relocs, but this edited reloc can be
output by --emit-relocs. So don't use a symbol on the reloc.
* elf64-ppc.c (ppc64_elf_relocate_section): Don't bother selecting
a TLS section symbol for edited relocs. Tighten TLS symbol/reloc
match test.
This saves a bit in tls_mask, and fixes a bug that could be triggered
in the unlikely case that both @got (usual ELF style) and @toc
(PowerOpen style) code was used to set up args for __tls_get_addr.
* elf64-ppc.c (TLS_EXPLICIT): Define as 256.
(ppc64_elf_check_relocs): Don't store TLS_EXPLICIT even if char
is more than 8 bits.
(ppc64_elf_tls_optimize): Likewise. Make tls_set, tls_clear, and
tls_type vars unsigned int.
(ppc64_elf_relocate_section): Use r_type rather than TLS_EXPLICIT
to select r_type edit.
Choose a better name, that reflects why the flag is set (GD to IE
optimisation) rather than what the flag produces (TPREL64 reloc on
a single GOT entry replacing a tls_index pair).
* elf32-ppc.c (TLS_GDIE): Rename from TLS_TPRELGD throughout file.
Correct comment.
* elf64-ppc.c (TLS_GDIE): Likewise.
I don't expect anyone will have hit this bug. You'd need a TLS
segment of 2G before you'd notice.
* elf64-ppc.c (ppc64_elf_tls_optimize): Correct test for allowed
range of tp-relative offsets.
It is possible to create shared libraries on PowerPC using
-ftls-model=inital-exec or -ftls-model=local-exec. The first is half
reasonable, getting you a shared library that can't be dlopen'd but
otherwise is reasonable. The second is quite bad. Not only do you
lose being able to dlopen, the library also has dynamic text
relocations. Worse, the TPREL16_LO, TPREL16_HA and other TPREL16
dynamic relocs emitted were wrong, resulting in wrong values being
applied by ld.so.
Using the first TLS section symbol in dynamic relocations for local
TLS symbols doesn't work. It's wrong because TLS symbols used by TLS
relocs have values relative to the TLS segment, whereas the TLS
section symbols are addresses. This patch instead uses a symbol index
of zero which is used elsewhere by PowerPC on dynamic TLS relocs.
It's not strictly ABI compliant to use a non-TLS symbol with TLS
relocs but symbol index zero can be interpreted as "no symbol". Not
using the first TLS section symbol means it doesn't need to be dynamic.
The patch also fixes a further problem with PowerPC32 dynamic TPREL16*
relocs, which shouldn't have the symbol value in the addend as we do
for non-TLS symbols.
bfd/
* elflink.c (_bfd_elf_omit_section_dynsym_default): Don't keep
tls_sec.
(_bfd_elf_init_1_index_section): Prefer not using TLS sections.
(_bfd_elf_init_2_index_sections): Likewise.
* elf64-ppc.c (ppc64_elf_relocate_section): When emitting dynamic
relocations for local TLS symbols, use STN_UNDEF as the relocation
symbol.
* elf32-ppc.c (ppc_elf_relocate_section): Likewise, and don't
leave TLS symbol value in the addend.
ld/
* testsuite/ld-powerpc/tlsso.r: Update.
* testsuite/ld-powerpc/tlsso32.g: Update.
* testsuite/ld-powerpc/tlsso32.r: Update.
* testsuite/ld-powerpc/tlstocso.r: Update.
* testsuite/ld-cris/tls-dso-dtpoffd2.d: Update.
* testsuite/ld-cris/tls-dso-dtpoffd4.d: Update.
* testsuite/ld-cris/tls-dso-tpoffgotcomm1.d: Update.
* testsuite/ld-cris/tls-gd-1.d: Update.
* testsuite/ld-cris/tls-gd-1h.d: Update.
* testsuite/ld-cris/tls-gd-2.d: Update.
* testsuite/ld-cris/tls-gd-2h.d: Update.
* testsuite/ld-cris/tls-ie-10.d: Update.
* testsuite/ld-cris/tls-ie-11.d: Update.
* testsuite/ld-cris/tls-ie-8.d: Update.
* testsuite/ld-cris/tls-ie-9.d: Update.
* testsuite/ld-cris/tls-js1.d: Update.
* testsuite/ld-cris/tls-ld-4.d: Update.
* testsuite/ld-cris/tls-ld-5.d: Update.
* testsuite/ld-cris/tls-ld-6.d: Update.
* testsuite/ld-cris/tls-ld-7.d: Update.
* testsuite/ld-cris/tls-ldgd-14.d: Update.
* testsuite/ld-cris/tls-ldgd-15.d: Update.
* testsuite/ld-cris/tls-ldgdx-14.d: Update.
* testsuite/ld-cris/tls-ldgdx-15.d: Update.
* testsuite/ld-cris/tls-local-54.d: Update.
* testsuite/ld-cris/tls-local-60.d: Update.
* testsuite/ld-cris/tls-local-61.d: Update.
* testsuite/ld-cris/tls-local-63.d: Update.
* testsuite/ld-cris/tls-local-64.d: Update.
* testsuite/ld-cris/tls-ok-30.d: Update.
* testsuite/ld-cris/tls-ok-32.d: Update.
* testsuite/ld-cris/tls-ok-34.d: Update.
* testsuite/ld-mips-elf/tls-multi-got-1.got: Update.
* testsuite/ld-mips-elf/tls-multi-got-1.r: Update.
* testsuite/ld-mips-elf/tlsdyn-pie-o32.d: Update.
* testsuite/ld-mips-elf/tlsdyn-pie-o32.got: Update.
* testsuite/ld-mips-elf/tlslib-o32-hidden.got: Update.
* testsuite/ld-mips-elf/tlslib-o32-ver.got: Update.
* testsuite/ld-mips-elf/tlslib-o32.got: Update.
* testsuite/ld-s390/tlspic.rd: Update.
* testsuite/ld-s390/tlspic_64.rd: Update.
* testsuite/ld-sparc/tlssunnopic32.rd: Update.
* testsuite/ld-sparc/tlssunnopic64.rd: Update.
* testsuite/ld-sparc/tlssunpic32.rd: Update.
* testsuite/ld-sparc/tlssunpic64.rd: Update.
While the skiboot linker script bears some culpability in this PR,
it's also true that the GOT indirect to GOT relative optimisation for
16-bit offsets isn't safe. At least, it isn't safe to remove the GOT
entry based on distance between the GOT pointer and symbol calculated
from the preliminary layout. So this patch removes that optimisation,
and reduces the range allowed for 32-bit and 34-bit offsets.
PR 24704
bfd/
* elf64-ppc.c (R_PPC64_GOT16_DS): Don't set has_gotrel.
(ppc64_elf_edit_toc): Don't remove R_PPC64_GOT16_DS got entries.
Reduce range of offsets allowed for other GOT relocs.
ld/
* testsuite/ld-powerpc/elfv2exe.d: Update.
* testsuite/ld-powerpc/elfv2so.d: Update.
Calls from functions that don't have a valid toc pointer in r2 (these
calls are marked with _NOTOC relocs) to functions that require r2
valid must go via the callee global entry point. This patch corrects
the condition the linker was using to detect functions that require r2
to be valid. Values of both zero and one in st_other local entry bits
mean a function doesn't care about r2.
* elf64-ppc.c (ppc64_elf_inline_plt): Correct st_other test for
functions that require r2 valid to use local entry.
(ppc64_elf_size_stubs, ppc64_elf_relocate_section): Likewise.
"paddi rt,sym@pcrel" as an abbreviation for "paddi rt,0,sym@pcrel,1"
is invalid, so replace with "pla rt,sym@pcrel" which is a valid form
of "pla rt,sym@pcrel(0),1".
* elf64-ppc.c: Fix comments involving paddi.
bfd/
* elf64-ppc.c (ppc64_elf_check_relocs): Set has_gotrel for
R_PPC64_GOT_PCREL34.
(xlate_pcrel_opt): New function.
(ppc64_elf_edit_toc): Handle R_PPC64_GOT_PCREL34.
(ppc64_elf_relocate_section): Edit GOT indirect to GOT relative
for R_PPC64_GOT_PCREL34. Implement R_PPC64_PCREL_OPT optimisation.
ld/
* testsuite/ld-powerpc/pcrelopt.s,
* testsuite/ld-powerpc/pcrelopt.d,
* testsuite/ld-powerpc/pcrelopt.sec: New test.
* testsuite/ld-powerpc/powerpc.exp: Run it.
When optimising inline plt calls to __tls_get_addr without tls marker
relocs, ld should zap any toc restore insn after the bctrl, to stop a
load-hit-store stall.
* elf64-ppc.c (ppc64_elf_relocate_section <tls_ldgd_opt>): When
editing an old-style __tls_get_addr call, replace a toc restore
insn with a nop.
All of the backend relocate_section functions that interpret reloc
numbers assuming the input file is of the expected type (ie. same as
output or very similar) really ought to be checking input file type.
Not many do, and those that do currently just assert. This patch
replaces the assertion with a more graceful exit.
PR 23980
* elf32-i386.c (elf_i386_relocate_section): Exit with wrong format
error rather than asserting input file is as expected.
* elf32-s390.c (elf_s390_relocate_section): Likewise.
* elf32-sh.c (sh_elf_relocate_section): Likewise.
* elf32-xtensa.c (elf_xtensa_relocate_section): Likewise.
* elf64-ppc.c (ppc64_elf_relocate_section): Likewise.
* elf64-s390.c (elf_s390_relocate_section): Likewise.
* elf64-x86-64.c (elf_x86_64_relocate_section): Likewise.
* elf32-ppc.c (ppc_elf_relocate_section): Exit with wrong format
error if input file is not ppc32 ELF.
IFUNC resolvers must always be called via their global entry point.
They will be called from ld.so rather than from the local executable.
PR 23937
bfd/
* elf64-ppc.c (write_plt_relocs_for_local_syms): Don't add local
entry offset for ifuncs.
ld/
* testsuite/ld-powerpc/pr23937.d,
* testsuite/ld-powerpc/pr23937.s: New test.
* testsuite/ld-powerpc/powerpc.exp: Run it.
This PR shows a fuzzed binary triggering a segfault via a bad
relocation in .debug_line. It turns out that unlike normal
relocations applied to a section, the linker applies those with
symbols from discarded sections via _bfd_clear_contents without
checking that the relocation is within the section bounds. The same
thing now happens when reading debug sections since commit
a4cd947aca, the PR23425 fix.
PR 23770
PR 23425
* reloc.c (_bfd_clear_contents): Replace "location" param with
"buf" and "off". Bounds check "off". Return status.
* cofflink.c (_bfd_coff_generic_relocate_section): Update
_bfd_clear_contents call.
* elf-bfd.h (RELOC_AGAINST_DISCARDED_SECTION): Likewise.
* elf32-arc.c (elf_arc_relocate_section): Likewise.
* elf32-i386.c (elf_i386_relocate_section): Likewise.
* elf32-metag.c (metag_final_link_relocate): Likewise.
* elf32-nds32.c (nds32_elf_get_relocated_section_contents): Likewise.
* elf32-ppc.c (ppc_elf_relocate_section): Likewise.
* elf32-visium.c (visium_elf_relocate_section): Likewise.
* elf64-ppc.c (ppc64_elf_relocate_section): Likewise.
* elf64-x86-64.c *(elf_x86_64_relocate_section): Likewise.
* libbfd-in.h (_bfd_clear_contents): Update prototype.
* libbfd.h: Regenerate.
This patch uses the newly defined high-part REL16 relocs to emit
relocations on the notoc stubs as we already do for other stubs.
* elf64-ppc.c (num_relocs_for_offset): New function.
(emit_relocs_for_offset): New function.
(use_global_in_relocs): New function, split out from..
(ppc_build_one_stub): ..here. Output relocations for notoc stubs.
(ppc_size_one_stub): Calculate reloc count for notoc stubs.
(ppc64_elf_size_stubs): Don't count undefined syms in stub_globals.
This patch rearranges ppc_size_one_stub to make it a little easier to
compare against ppc_build_one_stub, and makes a few other random
changes that might help for future maintenance. There should be no
functional changes here.
The patch also fixes code examples in comments. A couple of "ori"
instructions lacked the source register operand, and "@high" is the
correct reloc modifier to use in a sequence building a 64-bit value.
(@hi reports overflow of a 32-bit signed value.)
* elf64-ppc.c: Correct _notoc stub comments.
(ppc_build_one_stub): Simplify output of branch for notoc
long branch stub. Don't include label offset of 8 bytes in
"off" calculation for notoc plt stub. Don't emit insns to get pc.
(build_offset): Emit insns to get pc here instead.
(size_offset): Add 4 extra insns.
(plt_stub_size): Adjust for "off" and size_offset changes.
(ppc_size_one_stub): Rearrange code into a switch, duplicating
some to better match ppc_build_one_stub.
The "-fPIC" and "-mcmodel=small" parts of these messages isn't always
true, so lets dispense with that and just report the type of stub
causing trouble.
* elf64-ppc.c (ppc64_elf_relocate_section): Revise "call lacks
nop" error message.
These take up far too many lines in the files. This patch introduces
a replacement for the HOWTO macro that simplifies the relow howto
initialization. Apart from the two relocs mentioned in the ChangeLog,
no relocation howto is changed.
* elf64-ppc.c (HOW): Define.
(ONES): Delete.
(ppc64_elf_howto_raw): Use HOW to initialize entries.
* elf32-ppc.c (HOW): Define.
(ppc_elf_howto_raw): Use HOW to initialize entries, updating
R_PPC_VLE_REL15 and R_PPC_VLE_REL24 to use bitpos=0.
ppc_stub_long_branch_notoc will never need more than a 32-bit offset
for the r12 offset since the stub target must be in range of a
branch instruction.
* elf64-ppc.c: Correct ppc_stub_long_branch_notoc example.
Formatting.
This patch generates EH info for the new _notoc linkage stubs, to
support unwinding from asynchronous signal handlers. Unwinding
through the __tls_get_addr_opt stub was already supported, but that
was just a single stub. With multiple stubs the EH opcodes need to be
emitted and sized when iterating over stubs, so this is done when
emitting and sizing the stub code. Emitting the CIEs and FDEs is done
when sizing the stubs, as we did before in order to have the linker
generated FDEs indexed in .eh_frame_hdr. I moved the final tweaks to
FDEs from ppc64_elf_finish_dynamic_sections to ppc64_elf_build_stubs
simply because it's tidier to be done with them at that point.
bfd/
* elf64-ppc.c (struct map_stub): Delete tls_get_addr_opt_bctrl.
Add lr_restore, eh_size and eh_base.
(eh_advance, eh_advance_size): New functions.
(build_tls_get_addr_stub): Emit EH info for stub.
(ppc_build_one_stub): Likewise for _notoc stubs.
(ppc_size_one_stub): Size EH info for stub.
(group_sections): Init new map_stub fields.
(stub_eh_frame_size): Delete.
(ppc64_elf_size_stubs): Size EH info for stubs. Set up dummy EH
program for stubs.
(ppc64_elf_build_stubs): Reinit new map_stub fields. Set FDE
offset to stub section here..
(ppc64_elf_finish_dynamic_sections): ..rather than here.
ld/
* testsuite/ld-powerpc/notoc.s: Generate some cfi.
* testsuite/ld-powerpc/notoc.d: Adjust.
* testsuite/ld-powerpc/notoc.wf: New file.
* testsuite/ld-powerpc/powerpc.exp: Run "ext" and "notoc" tests
as run_ld_link_tests rather than run_dump_test.
This patch fixes a bug in the handling of the __tls_get_addr_opt
stub. Calls via this stub don't have a toc restoring instruction
following the "bl", and the stub itself doesn't have an initial toc
save instruction. Thus it is incorrect to skip over the first
instruction when a __tls_get_addr call is marked with a tocsave
reloc.
* elf64-ppc.c (ppc64_elf_relocate_section): Don't skip first
instruction of __tls_get_addr_opt stub.
(plt_stub_size): Omit ALWAYS_EMIT_R2SAVE condition when
dealing with __tls_get_addr_opt stub.
(build_tls_get_addr_stub, ppc_size_one_stub): Likewise.
R_PPC64_REL24_NOTOC is used on calls like "bl foo@notoc" to tell the
linker that linkage stubs for PLT calls or long branches can't use r2
for pic addressing. Instead, new stubs that generate pc-relative
addresses are used. One complication is that pc-relative offsets to
the PLT may need to be 64-bit in large programs, in contrast to the
toc-relative addressing used by older PLT linkage stubs where a 32-bit
offset is sufficient until the PLT itself exceeds 2G in size.
.eh_frame info to cover the _notoc stubs is yet to be implemented.
bfd/
* elf64-ppc.c (ADDI_R12_R11, ADDI_R12_R12, LIS_R12),
(ADDIS_R12_R11, ORIS_R12_R12_0, ORI_R12_R12_0),
(SLDI_R12_R12_32, LDX_R12_R11_R12, ADD_R12_R11_R12): Define.
(ppc64_elf_howto_raw): Add R_PPC64_REL24_NOTOC entry.
(ppc64_elf_reloc_type_lookup): Support R_PPC64_REL24_NOTOC.
(ppc_stub_type): Add ppc_stub_long_branch_notoc,
ppc_stub_long_branch_both, ppc_stub_plt_branch_notoc,
ppc_stub_plt_branch_both, ppc_stub_plt_call_notoc, and
ppc_stub_plt_call_both.
(is_branch_reloc): Add R_PPC64_REL24_NOTOC.
(build_offset, size_offset): New functions.
(plt_stub_size): Support plt_call_notoc and plt_call_both.
(ppc_build_one_stub, ppc_size_one_stub): Support new stubs.
(toc_adjusting_stub_needed): Handle R_PPC64_REL24_NOTOC.
(ppc64_elf_size_stubs): Likewise, and new stubs.
(ppc64_elf_build_stubs, ppc64_elf_relocate_section): Likewise.
* reloc.c: Add BFD_RELOC_PPC64_REL24_NOTOC.
* bfd-in2.h: Regenerate.
* libbfd.h: Regenerate.
gas/
* config/tc-ppc.c (ppc_elf_suffix): Support @notoc.
(ppc_force_relocation, ppc_fix_adjustable): Handle REL24_NOTOC.
ld/
* testsuite/ld-powerpc/ext.d,
* testsuite/ld-powerpc/ext.s,
* testsuite/ld-powerpc/ext.lnk,
* testsuite/ld-powerpc/notoc.d,
* testsuite/ld-powerpc/notoc.s: New tests.
* testsuite/ld-powerpc/powerpc.exp: Run them.
Not a lot is conveyed by putting _r2off in a stub symbol that can't be
seen by inspecting the stub code or the toc restoring instruction
immediately after a call via such a stub. Also, we don't distinguish
plt_call stub symbols from plt_call_r2save stub symbols, so this patch
makes long branch and plt branch stub symbols consistent with that
decision.
bfd/
* elf64-ppc.c (ppc_build_one_stub): Lose "_r2off" in stub symbols.
ld/
* testsuite/ld-powerpc/elfv2exe.d: Adjust for stub symbol change.
* testsuite/ld-powerpc/tocopt6.d: Likewise.
This patch sets stub_offset in ppc_size_one_stub rather than in
ppc_build_one_stub. That allows the plt stub alignment to be done in
just ppc_size_one_stub rather than both functions. The patch also
corrects the place where the alignment was done, fixing a possible
error in .eh_frame data, and tidies some offset calculations.
bfd/
* elf64-ppc.c (plt_stub_pad): Delay plt_stub_size call until needed.
(ppc_build_one_stub): Don't set stub_offset, instead assert that
it is sane. Don't adjust stub_offset for alignment. Adjust size
calculation. Use "targ" temp when calculating offsets.
(ppc_size_one_stub): Set stub_offset here. Use "targ" temp when
calculating offsets. Adjust for alignment before setting
tls_get_addr_opt_bctrl.
ld/
* testsuite/ld-powerpc/powerpc.exp: Run tlsopt5 with plt alignment.
* testsuite/ld-powerpc/tlsopt5.s: Add extra call.
* testsuite/ld-powerpc/tlsopt5.wf: Adjust expected output.
* testsuite/ld-powerpc/tlsopt5.d: Likewise.
This adds support for ".localentry 1", a new st_other
STO_PPC64_LOCAL_MASK encoding that signifies a function with a single
entry point like ".localentry 0", but unlike a ".localentry 0"
function does not preserve r2.
include/
* elf/ppc64.h: Specify byte offset to local entry for values
of two to six in STO_PPC64_LOCAL_MASK. Clarify r2 return
value for such functions when entering via global entry point.
Specify meaning of a value of one in STO_PPC64_LOCAL_MASK.
bfd/
* elf64-ppc.c (ppc64_elf_size_stubs): Use a ppc_stub_long_branch_r2off
for calls to symbols with STO_PPC64_LOCAL_MASK bits set to 1.
gas/
* config/tc-ppc.c (ppc_elf_localentry): Allow .localentry values
of 1 and 7 to directly set value into STO_PPC64_LOCAL_MASK bits.
ld/testsuite/
* ld-powerpc/elfv2.s: Add .localentry f5,1 testcase.
* ld-powerpc/elfv2exe.d: Update.
* ld-powerpc/elfv2so.d: Update.
Fixes a number of build errors like the following
.../elf32-arm.c: In function 'elf32_arm_nabi_write_core_note':
.../elf32-arm.c:2177: error: #pragma GCC diagnostic not allowed inside functions
.../elf32-arm.c:2186: error: #pragma GCC diagnostic not allowed inside functions
See the comment in diagnostics.h.
include/
* diagnostics.h: Comment on macro usage.
bfd/
* elf32-arm.c (elf32_arm_nabi_write_core_note): Don't use
DIAGNOTIC_PUSH and DIAGNOSTIC_POP unconditionally.
* elf32-ppc.c (ppc_elf_write_core_note): Likewise.
* elf32-s390.c (elf_s390_write_core_note): Likewise.
* elf64-ppc.c (ppc64_elf_write_core_note): Likewise.
* elf64-s390.c (elf_s390_write_core_note): Likewise.
* elfxx-aarch64.c (_bfd_aarch64_elf_write_core_note): Likewise.
And report the two input files that are incompatible rather than
reporting that an input file is incompatible with the output.
bfd/
* elf-bfd.h (_bfd_elf_ppc_merge_fp_attributes): Update prototype.
* elf32-ppc.c (_bfd_elf_ppc_merge_fp_attributes): Return error
on mismatch. Remove "warning: " from messages. Track last bfd
used to set tags.
(ppc_elf_merge_obj_attributes): Likewise. Handle status from
_bfd_elf_ppc_merge_fp_attributes.
* elf64-ppc.c (ppc64_elf_merge_private_bfd_data): Handle status
from _bfd_elf_ppc_merge_fp_attributes.
ld/
* testsuite/ld-powerpc/attr-gnu-4-12.d: Update expected output.
* testsuite/ld-powerpc/attr-gnu-4-13.d: Likewise.
* testsuite/ld-powerpc/attr-gnu-4-21.d: Likewise.
* testsuite/ld-powerpc/attr-gnu-4-23.d: Likewise.
* testsuite/ld-powerpc/attr-gnu-4-31.d: Likewise.
* testsuite/ld-powerpc/attr-gnu-4-32.d: Likewise.
* testsuite/ld-powerpc/attr-gnu-8-23.d: Likewise.
* testsuite/ld-powerpc/attr-gnu-12-21.d: Likewise.
.gnu.attributes entries from linker input files are merged to the
output file, the output having the union of compatible input
attributes. Incompatible attributes generally cause a linker error
and no output. However in some cases only a warning is emitted, and
one of the incompatible input attributes is passed on to the output.
PowerPC tends to emit warnings rather than errors, and the output
takes the first input attribute. For example, if we have two input
files with Tag_GNU_Power_ABI_FP, the first with a value signifying
"double-precision hard float, IBM long double", the second with a
value signifying "double-precision hard float, IEEE long double",
we'll get a warning about incompatible long double types and the
output will say "double-precision hard float, IBM long double".
The output attribute of course isn't correct. It would be correct to
specify "IBM and IEEE long double", but we don't have a way to
represent that currently. While it would be possible to extend the
encoding, there isn't much gain in doing so. A shared library
providing support for both long double types should link against
objects using either long double type without warning or error. That
is what you'd get if such a shared library had no Tag_GNU_Power_ABI_FP
attribute.
So this patch provides a way for the backend to omit .gnu.attributes
tags from the output.
* elf-bfd.h (ATTR_TYPE_FLAG_ERROR, ATTR_TYPE_HAS_ERROR): Define.
* elf-attrs.c (is_default_attr): Handle ATTR_TYPE_HAS_ERROR.
* elf32-ppc.c (_bfd_elf_ppc_merge_fp_attributes): Use
ATTR_TYPE_FLAG_INT_VAL. Set ATTR_TYPE_HAS_ERROR on finding
incompatible attribute.
(ppc_elf_merge_obj_attributes): Likewise. Return
_bfd_elf_merge_object_attributes result.
* elf64-ppc.c (ppc64_elf_merge_private_bfd_data): Return
_bfd_elf_merge_object_attributes result.
https://sourceware.org/ml/binutils/2013-05/msg00271.html was supposed
to banish "file format is ambiguous" errors for ELF. It didn't,
because the code supposedly detecting formats that implement
match_priority didn't work. That was due to not placing all matching
targets into the vector of matching targets. ELF objects should all
match the generic ELF target (priority 2), plus one or more machine
specific targets (priority 1), and perhaps a single machine specific
target with OS/ABI set (priority 0, best match). So the armel object
in the testcase actually matches elf32-littlearm,
elf32-littlearm-symbian, and elf32-littlearm-vxworks (all priority 1),
and elf32-little (priority 2). As the PR reported, elf32-little
wasn't seen as matching. Fixing that part of the problem wasn't too
difficult but matching the generic ELF target as well as the ARM ELF
targets resulted in ARM testsuite failures.
These proved to be the annoying reordering of stubs that occurs from
time to time due to the stub names containing the section id.
Matching another target causes more sections to be created in
elf_object_p. If section ids change, stub names change, which results
in different hashing and can therefore result in different hash table
traversal and stub creation order. That particular problem is fixed
by resetting section_id to the initial state before attempting each
target match, and taking a snapshot of its value after a successful
match.
PR 22458
* format.c (struct bfd_preserve): Add section_id.
(bfd_preserve_save, bfd_preserve_restore): Save and restore
_bfd_section_id.
(bfd_reinit): Set _bfd_section_id.
(bfd_check_format_matches): Put all matches of any priority into
matching_vector. Save initial section id and start each attempted
match at that section id.
* libbfd-in.h (_bfd_section_id): Declare.
* section.c (_bfd_section_id): Rename from section_id and make
global. Adjust uses.
(bfd_get_next_section_id): Delete.
* elf64-ppc.c (ppc64_elf_setup_section_lists): Replace use of
bfd_get_section_id with _bfd_section_id.
* libbfd.h: Regenerate.
* bfd-in2.h: Regenerate.