When using perf to profile large binaries, _bfd_dwarf2_find_nearest_line()
becomes a hotspot, as perf wants to get line number information
(for inline-detection purposes) for each and every sample. In Chromium
in particular (the content_shell binary), this entails going through
475k address ranges, which takes a long time when done repeatedly.
Add a radix-256 trie over the address space to quickly map address to
compilation unit spaces; for content_shell, which is 1.6 GB when some
(but not full) debug information turned is on, we go from 6 ms to
0.006 ms (6 µs) for each lookup from address to compilation unit, a 1000x
speedup.
There is a modest RAM increase of 180 MB in this binary (the existing
linked list over ranges uses about 10 MB, and the entire perf job uses
between 2–3 GB for a medium-size profile); for smaller binaries with few
ranges, there should be hardly any extra RAM usage at all.
Make ld and bfd values consistent by swapping values 0 and 2 in
link_info.warn_execstack. This has the benefit of making the value an
"extended" boolean, with 0 meaning no warning, 1 meaning warn, other
values a conditional warning.
Yes, this patch introduces fails on arm/aarch64. Not a problem with
this patch but an arm/aarch64 before_parse problem.
bfd/
* elflink.c (bfd_elf_size_dynamic_sections): Adjust
warn_execstack test.
include/
* bfdlink.h (warn_execstack): Swap 0 and 2 meaning.
ld/
* configure.ac (DEFAULT_LD_WARN_EXECSTACK): Use values of 0,
1, 2 consistent with link_info.warn_execstack.
* ld.texi: Typo fixes.
* lexsup.c (parse_args): Adjust setting of link_info.warn_execstack.
(elf_static_list_options): Adjust help message conditions.
* configure: Regenerate.
Otherwise the string table may grow and hence e.g. change a final binary
(observed with PE/COFF ones) even if really there's no change. Doing so
in fact reduces the overall amount of code, and in particular the number
of places which need to remain in sync.
Afaics there's no real equivalent to the "traditional_format" field used
when linking, so hashing is always enabled when copying / stripping.
Neither of the tools is really a linker, so whatever was originally
recorded should be retained rather than being overwritten by these
tools' versions.
So far this option had no effect when used together with e.g.
--strip-debug. Set BSF_FILE on these symbols to change that.
While altering this also join two adjacent blocks of case labeled
statements with identical code.
When a sufficiently small alignment was specified via --file-alignment,
individual section alignment shouldn't affect placement within the file.
This involves first of all clearing D_PAGED for images when section and
file alignment together don't permit paging of the image. The involved
comparison against COFF_PAGE_SIZE in turn helped point out (through a
compiler warning) that 'page_size' should be of unsigned type (as in
particular FileAlignment is). This yet in turn pointed out a dubious
error condition (which is being deleted).
For the D_PAGED case I think the enforced file alignment may still be
too high, but I'm wary of changing that logic without knowing of
possible corner cases.
Furthermore file positions in PE should be independent of the alignment
recorded in section headers anyway. Otherwise there are e.g. anomalies
following commit 6f8f6017a0 ("PR27567, Linking PE files adds alignment
section flags to executables") in that linking would use information a
subsequent processing step (e.g. stripping) wouldn't have available
anymore, and hence a binary could change in that 2nd step for no actual
reason. (Similarly stripping a binary linked with a linker pre-dating
that commit would change the binary again when stripping it a 2nd time.)
This commit fixes canonical extension order to follow the RISC-V ISA
Manual draft-20210402-1271737 or later.
bfd/ChangeLog:
* elfxx-riscv.c (riscv_recognized_prefixed_ext): Fix "K" extension
prefix to be placed before "J".
If you load a core file into GDB with the --write option, or "set
write on" (equivalent), and then poke memory expecting it to patch the
core binary, you'll notice something odd -- the write seems to
succeed, but in reality, it doesn't. The value you wrote doesn't
persist. Like so:
$ gdb -q --write -c testsuite/outputs/gdb.base/patch/gcore.test
[New LWP 615986]
Core was generated by `/home/pedro/gdb/build/gdb/testsuite/outputs/gdb.base/patch/patch'.
Program terminated with signal SIGTRAP, Trace/breakpoint trap.
#0 0x0000555555555131 in ?? ()
(gdb) p *(unsigned char *)0x0000555555555131 = 1
$1 = 1 '\001'
(gdb) p *(unsigned char *)0x0000555555555131
$2 = 185 '\271'
(gdb)
Diffing hexdumps of before/after patching, reveals that a "0x1" was
actually written somewhere in the file. The problem is that the "0x1"
was written at the wrong offset in the file...
That happens because _bfd_elf_set_section_contents does this to seek
to the section's offset:
pos = hdr->sh_offset + offset;
if (bfd_seek (abfd, pos, SEEK_SET) != 0
|| bfd_bwrite (location, count, abfd) != count)
return false;
... and 'hdr->sh_offset' is zero, so we seek to just OFFSET, which is
incorrect. The reason 'hdr->sh_offset' is zero is that
kernel-generated core files normally don't even have a section header
table (gdb-generated ones do, but that's more an accident than a
feature), and indeed elf_core_file_p doesn't even try to read sections
at all:
/* Core files are simply standard ELF formatted files that partition
the file using the execution view of the file (program header table)
rather than the linking view. In fact, there is no section header
table in a core file.
The process status information (including the contents of the general
register set) and the floating point register set are stored in a
segment of type PT_NOTE. We handcraft a couple of extra bfd sections
that allow standard bfd access to the general registers (.reg) and the
floating point registers (.reg2). */
bfd_cleanup
elf_core_file_p (bfd *abfd)
Changing _bfd_elf_set_section_contents from:
pos = hdr->sh_offset + offset;
to:
pos = section->filepos + offset;
fixes it. If we do that however, the tail end of
_bfd_elf_set_section_contents ends up as a copy of
_bfd_generic_set_section_contents, so just call the latter, thus
eliminating some duplicate code.
New GDB testcase included, which exercises both patching an executable
and patching a core file. Patching an executable already works
without this fix, because in that case BFD reads in the sections
table. Still, we had no testcase for that yet. In fact, we have no
"set write on" testcases at all, this is the first one.
Tested on x86-64 GNU/Linux, gdb, ld, binutils, and gas.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=18227
Change-Id: I0f49f58b48aabab2e269f2959b8fd8a7fe36fdce
Fix it some more.
bfd/
* elfnn-loongarch.c: Remove commented out elf_backend_* defines.
ld/
* testsuite/ld-elf/elf.exp (target_defaults_to_execstack): Match
arm*. Delete loongarch.
I hit this just now with a make -j build after touching config.bfd.
mv: cannot stat 'targmatch.new': No such file or directory
make[2]: *** [Makefile:2336: targmatch.h] Error 1
make[2]: *** Waiting for unfinished jobs....
Fix that by not removing the target of the rule, a practice that seems
likely to cause parallel running of the rule recipe. The bug goes
back to 1997, the initial c073470881 commit.
* Makefile.am (targmatch.h): rm the temp file, not targmatch.h.
* Makefile.in: Regenerate.
Various packages (glib and gtk4 for example) produces data-only objects
using `ld -r -b binary` or `objcopy`, with no elf header flags set. But
these files also have no code sections, so they should be compatible
with all ABIs.
bfd/
* elfnn-loongarch.c (elfNN_loongarch_merge_private_bfd_data):
Skip ABI checks if the input has no code sections.
Reported-by: Wu Xiaotian <yetist@gmail.com>
Suggested-by: Wang Xuerui <i@xen0n.name>
Signed-off-by: Xi Ruoyao <xry111@mengyan1223.wang>
When an IR symbol SYM is referenced in IR via __real_SYM, its resolution
should be LDPR_PREVAILING_DEF, not PREVAILING_DEF_IRONLY, since LTO
doesn't know that __real_SYM should be resolved by SYM.
bfd/
PR ld/29086
* linker.c (bfd_wrapped_link_hash_lookup): Mark SYM is referenced
via __real_SYM.
include/
PR ld/29086
* bfdlink.h (bfd_link_hash_entry): Add ref_real.
ld/
PR ld/29086
* plugin.c (get_symbols): Resolve SYM definition to
LDPR_PREVAILING_DEF for __real_SYM reference.
* testsuite/ld-plugin/lto.exp: Run PR ld/29086 test.
* testsuite/ld-plugin/pr29086.c: New file.
cris support will be built into a 32-bit bfd if using --enable-targets=all
on a 32-bit host, so we may as well make targmatch.h include cris.
* config.bfd (cris): Remove #idef BFD64.
Tidy 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.
* elf64-ppc.c (ppc64_elf_check_relocs): Tidy dynamic reloc
handling code.
(dec_dynrel_count): Do the same here.
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.
Update
commit ebb191adac
Author: H.J. Lu <hjl.tools@gmail.com>
Date: Wed Feb 9 15:51:22 2022 -0800
x86: Disallow invalid relocation against protected symbol
to allow function pointer reference and make sure that PLT entry isn't
used for function reference due to function pointer reference.
bfd/
PR ld/29087
* elf32-i386.c (elf_i386_scan_relocs): Don't set
pointer_equality_needed nor check non-canonical reference for
function pointer reference.
* elf64-x86-64.c (elf_x86_64_scan_relocs): Likewise.
ld/
PR ld/29087
* testsuite/ld-x86-64/x86-64.exp: Run PR ld/29087 tests.
* testsuite/ld-x86-64/protected-func-3.c: New file.
In static-pie case, there are IRELATIVE-relocs in
.rela.iplt (htab->irelplt), which will later be grouped
to .rela.plt. On s390, the IRELATIVE relocations are
always located in .rela.iplt - even for non-static case.
Ensure that DT_JMPREL, DT_PLTRELA, DT_PLTRELASZ is added
to the dynamic section even if htab->srelplt->size == 0.
See _bfd_elf_add_dynamic_tags in bfd/elflink.c.
bfd/
elf64-s390.c (elf_s390_size_dynamic_sections):
Enforce DT_JMPREL via htab->elf.dt_jmprel_required.
No dynamic relocs are needed for TLS defined in an executable, the
TP relative offset is known at link time.
Fixes
FAIL: Build pr22263-1
bfd/
PR ld/22263
* elf64-s390.c (elf_s390_tls_transition): Use bfd_link_dll
instead of bfd_link_pic for TLS.
(elf_s390_check_relocs): Likewise.
(allocate_dynrelocs): Likewise.
(elf_s390_relocate_section): Likewise.