This should be the first related issue, which posted in riscv-gnu-toolchain,
https://github.com/riscv-collab/riscv-gnu-toolchain/issues/497
If the output sections are not between gp and the symbol, then their alignments
shouldn't affect the gp relaxation. However, this patch improves this idea
even more, it limits the range to the gp+-2k, which means only the output
section which are in the [gp-2K, gp+2K) range need to be considered.
Even if the output section candidates may be different for each relax passes,
the symbol that can be relaxed ar this round will not be truncated at next
round. That is because this round you can do relaxation which means that the
section where the symbol is located is within the [gp-2K, gp+2K) range, so all
the output section alignments between them should be considered. In other
words, if the alignments between them may cause truncated, then we should
already preserve the size and won't do the gp relaxation this time.
This patch can resolve the github issue which mentioned above, and also passed
all gcc/binutils regressions of riscv-gnu-toolchain, so should be worth and
safe enough to commit.
Originally, this patch also do the same optimization for the call relaxations,
https://sourceware.org/pipermail/binutils/2022-October/123918.html
But just in case there is something that has not been considered, we only
deal with the gp relaxation at this time.
bfd/
* elfnn-riscv.c (riscv_elf_link_hash_table): Added new bfd_vma,
max_alignment_for_gp. It is used to record the maximum alignment of
the output sections, which are in the [gp-2K, gp+2k) range.
(riscv_elf_link_hash_table_create): Init max_alignment_for_gp to -1.
(_bfd_riscv_get_max_alignment): Added new parameter, gp. If gp is
zero, then all the output section alignments are possible candidates;
Otherwise, only the output sections which are in the [gp-2K, gp+2K)
range need to be considered.
(_bfd_riscv_relax_lui): Called _bfd_riscv_get_max_alignment with the
non-zero gp if the max_alignment_for_gp is -1.
(_bfd_riscv_relax_pc): Likewise.
(_bfd_riscv_relax_section): Record the first input section, so that
we can reset the max_alignment_for_gp for each repeated relax passes.
ld/
* testsuite/ld-riscv-elf/ld-riscv-elf.exp: Updated.
* testsuite/ld-riscv-elf/relax-max-align-gp.*: New testcase. It fails
without this patch.
rs6000-coff archives use a linked list of file offsets, where each
element points to the next element. The idea is to allow updating of
large archives quickly without rewriting the whole archive. (binutils
ar does not do this.) Unfortunately this is an easy target for
fuzzers to create an archive that will cause ar or any other tool
processing archives to hang. I'd implemented guards against pointing
back to the previous element, but of course that didn't last long.
So this patch implements a scheme to keep track of file offset ranges
used by elements as _bfd_read_ar_hdr is called for each element. See
the add_range function comment. I needed a place to stash the list,
so chose the obvious artdata.tdata backend extension to archive's
tdata, already used by xcoff. That involved a little cleanup, because
while it would be possible to continue using different artdata.tdata
for the big and small archives, it's nicer to use a union.
If anyone is concerned this list of element ranges might grow large
and thus significantly slow down the tools, adjacent ranges are
merged. In fact something like "ar t" will only ever have one range
on xcoff archives generated by binutils/ar. I agree there might still
be a problem with ld random element access via the armap.
include/
* coff/xcoff.h (SIZEOF_AR_FILE_HDR): Use sizeof.
(SIZEOF_AR_FILE_HDR_BIG, SIZEOF_AR_HDR, SIZEOF_AR_HDR_BIG): Likewise.
(struct ar_ranges, struct xcoff_artdata): New.
(x_artdata): Define.
(xcoff_big_format_p): Rewrite.
(xcoff_ardata, xcoff_ardata_big): Delete.
bfd/
* coff-rs6000.c: Replace uses of xcoff_ardata and
xcoff_ardata_big throughout file.
(_bfd_xcoff_archive_p): Adjust artdata.tdata allocation.
(add_range): New function.
(_bfd_xcoff_read_ar_hdr): Use it here. Fix memory leak.
(_bfd_xcoff_openr_next_archived_file): Remove old sanity
checks. Set up range for header.
(xcoff_write_archive_contents_old): Make the temporary
artdata.tdata used here to pass info down to
_bfd_compute_and_write_armap a struct xcoff_artdata.
(xcoff_write_archive_contents_big): Likewise.
* coff64-rs6000.c: Replace uses of xcoff_ardata and
xcoff_ardata_big throughout file.
(xcoff64_archive_p): Adjust artdata.tdata allocation.
This element is unused. Ideally we'd be moving archive_head and
other archive specific fields from struct bfd to here, but that's a
much larger change than this little bit of cleanup.
* libbfd-in.h (struct artdata): Delete archive_head.
* libbfd.h: Regenerate.
* archive.c,
* coff-rs6000.c,
* coff64-rs6000.c: Delete comments mentioning artdata archive_head.
Segmentation fault
FAIL: pr22269-1 (static pie undefined weak)
and others running "visibility (hidden undef)" tests
No code has any right to access bfd_link_hash_entry u.def without
first checking the type, and SYMBOL_REFERENCES_LOCAL isn't sufficient.
* elf32-sh.c (sh_elf_finish_dynamic_symbol): Don't use relative
relocs in GOT unless symbol is defined.
Do I care about out of memory conditions triggered by fuzzers? Not
much. Your operating system ought to be able to handle it by killing
the memory hog. Oh well, this one was an element of a coff-alpha
archive that said it was a little less that 2**64 in size. The
coff-alpha compression scheme expands at most 8 times, so we can do
better in bfd_get_file_size.
* bfdio.c (bfd_get_file_size): Assume elements in compressed
archive can only expand a maximum of eight times.
* coffgen.c (_bfd_coff_get_external_symbols): Sanity check
size of symbol table agains file size.
PR 30142
* peXXigen.c (_bfd_XXi_swap_scnhdr_out): Do not force the .rsrc section to be writeable.
* rescoff.c (write_coff_file): Add the SEC_READONLY flag to the .rsrc section.
AOUT and COFF targets set symcount and start_address in their object_p
functions. If these are used anywhere then it would pay to save and
restore them so that a successful match gets the values expected
rather than that for a later unsuccessful target match.
* format.c (struct bfd_preserve): Move some fields. Add
symcount, read_only and start_address.
(bfd_preserve_save): Save..
(bfd_preserve_restore): ..and restore..
(bfd_reinit): ..and zero new fields.
The last patch wasn't quite correct. bfd_preserve_restore also needs
to handle an in-memory to file backed transition, seen in a testcase
ILF object matching both pei-arm-little and pei-arm-wince-little.
There the first match is saved in preserve_match, and restored at the
end of the bfd_check_format_matches loop making the bfd in-memory. On
finding more than one match the function wants to restore the bfd back
to its original state with another bfd_preserve_restore call before
exiting with a bfd_error_file_ambiguously_recognized error.
It is also not correct to restore abfd->iostream unless the iovec
changes. abfd->iostream is a FILE* when using cache_iovec, and if
the file has been closed and reopened the iostream may have changed.
* format.c (io_reinit): New function.
(bfd_reinit, bfd_preserve_restore): Use it.
Introduce `static const struct mips_mach_extension mips_mach_32_64[]`
and `mips_mach_extends_32_64 (unsigned long base, unsigned long extension)`,
to make mipsisa32 and mipsisa64 interlink more systemtic.
Normally, the ISA mipsisa64rN has two subset: mipsisa64r(N-1) and
mipsisa32rN. `mips_mach_extensions` can hold only mipsisa64r(N-1),
so we need to introduce a new instruction `mips_mach_32_64`, which holds the pair 32vs64.
Note: R6 is not compatible with pre-R6.
bfd/ChangeLog:
* elfxx-mips.c (mips_mach_extends_p): make mipsisa32 and
mipsisa64 interlink more systematic.
(mips_mach_32_64): new struct added.
(mips_mach_extends_32_64): new function added.
This is a fuzzing PR, with a testcase involving a SHF_ALLOC and
SHF_COMPRESSED SHT_RELA section, ie. a compressed dynamic reloc
section. BFD doesn't handle compressed relocation sections, with most
of the code reading relocs using sh_size (often no bfd section is
created) but in the case of SHF_ALLOC dynamic relocs we had some code
using the bfd section size. This led to a mismatch, sh_size is
compressed, size is uncompressed, and from that some uninitialised
memory. Consistently using sh_size is enough to fix this PR, but I've
also added tests to exclude SHF_COMPRESSED reloc sections from
consideration.
PR 30362
* elf.c (bfd_section_from_shdr): Exclude reloc sections with
SHF_COMPRESSED flag from normal reloc processing.
(_bfd_elf_get_dynamic_reloc_upper_bound): Similarly exclude
SHF_COMPRESSED sections from consideration. Use sh_size when
sizing to match slurp_relocs.
(_bfd_elf_canonicalize_dynamic_reloc): Likewise.
(_bfd_elf_get_synthetic_symtab): Use NUM_SHDR_ENTRIES to size
plt relocs.
* elf32-arm.c (elf32_arm_get_synthetic_symtab): Likewise.
* elf32-ppc.c (ppc_elf_get_synthetic_symtab): Likewise.
* elf64-ppc.c (ppc64_elf_get_synthetic_symtab): Likewise.
* elfxx-mips.c (_bfd_mips_elf_get_synthetic_symtab): Likewise.
Except it isn't out of bounds because space for a larger array has
been allocated.
* dwarf2.c (struct trie_leaf): Make ranges a C99 flexible array.
(alloc_trie_leaf, insert_arange_in_trie): Adjust sizing.
If pe_ILF_object_p succeeds, pe_ILF_build_a_bfd will have changed the
bfd from being file backed to in-memory. This can have unfortunate
results for targets checked by bfd_check_format_matches after that
point as they will be matching against the created in-memory image
rather than the file. bfd_preserve_restore also has a problem if it
flips the BFD_IN_MEMORY flag, because the flag affects iostream
meaning and should be set if using _bfd_memory_iovec. To fix these
problems, save and restore iostream and iovec along with flags, and
modify bfd_reinit to make the bfd file backed again. Restoring the
iovec and iostream allows the hack in bfd_reinit keeping BFD_IN_MEMORY
(part of BFD_FLAGS_SAVED) to be removed.
One more detail: If restoring from file backed to in-memory then the
bfd needs to be forcibly removed from the cache lru list, since after
the bfd becomes in-memory a bfd_close will delete the bfd's memory
leaving the lru list pointing into freed memory.
* cache.c (bfd_cache_init): Clear BFD_CLOSED_BY_CACHE here..
(bfd_cache_lookup_worker): ..rather than here.
(bfd_cache_close): Comment.
* format.c (struct bfd_preserve): Add iovec and iostream fields.
(bfd_preserve_save): Save them..
(bfd_preserve_restore): ..and restore them, calling
bfd_cache_close if the iovec differs.
(bfd_reinit): Add preserve param. If the bfd has been flipped
to in-memory, reopen the file. Restore flags.
* peicode.h (pe_ILF_cleanup): New function.
(pe_ILF_object_p): Return it.
* bfd.c (BFD_FLAGS_SAVED): Delete.
* bfd-in2.h: Regenerate.
The bfd_elf_hash loop is taken straight from the sysV document, but it
is poorly optimized. This refactoring removes about 5 x86 insns from
the 15 insn loop.
1) The if (..) is meaningless -- we're xoring with that value, and of
course xor 0 is a nop. On x86 (at least) we actually compute the xor'd
value and then cmov. Removing the if test removes the cmov.
2) The 'h ^ g' to clear the top 4 bits is not needed, as those 4 bits
will be shifted out in the next iteration. All we need to do is sink
a mask of those 4 bits out of the loop.
3) anding with 0xf0 after shifting by 24 bits can allow betterin
encoding on RISC ISAs than masking with '0xf0 << 24' before shifting.
RISC ISAs often require materializing larger constants.
bfd/
* elf.c (bfd_elf_hash): Refactor to optimize loop.
(bfd_elf_gnu_hash): Refactor to use 32-bit type.
Having been irritated by seeing bfd/elf{32,64}-aarch64.c to be re-
generated in x86-only builds, I came across 769a27ade5 ("Re: bfd
BLD-POTFILES.in dependencies"). I think this went slightly too far, as
outside of maintainer mode dependencies will cause the subset of files
to be (re-)generated which are actually needed for the build.
Generating them all is only needed when wanting to update certain files
under bfd/po/, i.e. in maintainer mode.
In the course of looking around in an attempt to try to understand how
things are meant to work, I further noticed that ld has got things
slightly wrong too: BLD-POTFILES.in depending on $(BLD_POTFILES) isn't
quite right (the output doesn't change when any of the enumerated files
changes; it's the mere presence which matters); like in bfd it looks
like we would better extend BUILT_SOURCES accordingly.
Furthermore it became apparent that ld fails to enumerate the .c files
generated from the .l and .y ones. While in their absence it was benign
whether translatable strings in the source files were actually marked as
such, this now becomes relevant. Mark respective strings at the same
time, but skipping ones which look to be of interest for debugging
purposes only (e.g. such used by printf() enclosed in #ifdef TRACE).
A case of a string section ending with an unterminated string. Fix it
by allocating one more byte and making it zero. Also make functions
reading the data return void* so that casts are not needed.
* ecoff.c (READ): Delete type param. Allocate one extra byte
to terminate string sections with a NUL. Adjust invocation.
* elfxx-mips.c (READ): Likewise.
* libbfd-in.h (_bfd_alloc_and_read): Return a void*.
(_bfd_malloc_and_read): Likewise.
* libbfd.h: Regenerate.
Linker adds indirect symbols for versioned symbol aliases, which are
created by ".symver foo, foo@FOO", by checking symbol type, value and
section so that references to foo will be replaced by references to
foo@FOO if foo and foo@FOO have the same symbol type, value and section.
But in IR, since all symbols of the same type have the same value and
section, we can't tell if a symbol is an alias of another symbol by
their types, values and sections. We shouldn't add indirect symbols
for versioned symbol aliases in IR.
bfd/
PR ld/30281
* elflink.c (elf_link_add_object_symbols): Don't add indirect
symbols for ".symver foo, foo@FOO" aliases in IR.
ld/
PR ld/30281
* testsuite/ld-plugin/lto.exp: Add PR ld/30281 test.
* testsuite/ld-plugin/pr30281.t: New file.
* testsuite/ld-plugin/pr30281.c: Likewise.
While only a secondary issue there, the testcase of PR gas/27212 exposes
an oversight in relocation handling: Just like e.g. Arm32, which has a
similar comment and a similar check, relocations against STN_UNDEF have
to be permitted to satisfy the ELF spec.
It's wrong to have an alloc reloc section trying to use a non-alloc
symbol table.
* elf.c (assign_section_numbers <SHT_REL, SHT_RELA>): Correct
comment. Always set sh_link to .dynsym for alloc reloc
sections and to .symtab for non-alloc.
* opncls.c (bfd_get_alt_debug_link_info): Don't bother freeing
after bfd_malloc_and_get_section failure.
(get_build_id): Likewise.
(bfd_get_debug_link_info_1): Likewise. Free section contents
when crc not present.
* section.c (bfd_malloc_and_get_section): Document that the
buffer is NULL on error return.
The non-preemptible SHN_ABS symbol with a pc-relative relocation should be
disallowed when generating shared object (pic and pie). Generally, the
following cases, which refer to pr25749, will cause a symbol be
non-preemptible,
* -pie, or -shared with -symbolic
* STV_HIDDEN, STV_INTERNAL, STV_PROTECTED
* Have dynamic symbol table, but without the symbol
* VER_NDX_LOCAL
However, PCREL_HI20/LO12 relocs are always bind locally when generating
shared object, so not only the non-preemptible absolute symbol need to
be disallowed, all absolute symbol references need but except that they
are defined in linker script. If we also disallow the absolute symbol
in linker script, then the glibc-linux toolchain build failed, so regard
them as pc-relative symbols, just like what x86 did.
Maybe we should add this check for all pc-relative relocations, rather
than just handle in R_RISCV_PCREL relocs. Ideally, since the value of
SHN_ABS symbol is a constant, only S - A relocations should be allowed
in the shared object, so only BFD_RELOC_8/16/32/64 are allowed, which
means R_RISCV_32/R_RISCV_64.
bfd/
PR 28789
* elfnn-riscv.c (riscv_elf_check_relocs): The absolute symbol cannot be
referneced with pc-relative relocation when generating shared object.
ld/
PR 28789
* ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp: Updated.
* ld/testsuite/ld-riscv-elf/pcrel-reloc*: New testcases.
There are two improvements, which are all referenced to aarch64,
* R_RISCV_32 with non ABS symbol cannot be used under RV64 when making
shard objects.
* Don't need dynamic relocation for R_RISCV_32/64 under RV32/RV64 when
making shared objects, if the referenced symbol is local ABS symbol.
However, considering this link,
https://github.com/riscv-non-isa/riscv-elf-psabi-doc/issues/341
Seems like we should makes all R_RISCV_32/64 relocs with ABS symbol
that don't need any dynamic relocations when making the shared objects.
But anyway, I just sync the current behavior as aarch64 ld, in case
there are any unexpected behaviors happen.
Passed the gcc/binutils regressions in riscv-gnu-toolchain.
bfd/
* elfnn-riscv.c (riscv_elf_check_relocs): Only allow R_RISCV_32 with ABS
symbol under RV64.
(riscv_elf_relocate_section): R_RISCV_32/64 with local ABS symbol under
RV32/RV64 doesn't need any dynamic relocation when making shared objects.
I just make the implementations similar to other targets, so that will be
more easy to mainatain.
ld/
* testsuite/ld-riscv-elf/data-reloc*: New testcases.
* testsuite/ld-riscv-elf/ld-riscv-elf.exp: Added new data-reloc* testcases,
and need to make ifunc-seperate* testcases work for rv32.
* testsuite/ld-riscv-elf/ifunc-seperate-caller-nonplt.s: Likewise.
* testsuite/ld-riscv-elf/ifunc-seperate-caller-plt.s: Likewise.
These types of codes are different for each target, I am not sure what are the
best for RISC-V, so extract them out may be more easy to compare what's the
difference.
bfd/
* elfnn-riscv.c (RISCV_NEED_DYNAMIC_RELOC): New defined. Extracted
from riscv_elf_check_relocs, to see if dynamic reloc is needed for the
specific relocation.
(RISCV_GENERATE_DYNAMIC_RELOC): New defined. Extracted from
riscv_elf_relocate_section, to see if R_RISCV_32/64 need to generate
dynamic relocation.
(RISCV_COPY_INPUT_RELOC): New defined. Extracted from
riscv_elf_relocate_section, to see if R_RISCV_32/64 need to copy itslef
tp output file.
(RISCV_RESOLVED_LOCALLY): New defined. Extracted from
riscv_elf_relocate_section, to see if R_RISCV_GOT_HI20 can be resolved
locally.
This function doesn't just initialise for compression, it actually
compresses. This patch sanity checks section size before allocating
buffers for the uncompressed contents.
* compress.c (bfd_init_section_compress_status): Sanity check
section size.
We have way too much duplicated code in bfd. Apply dd3a3d0af9 and
920581c57e to pdp11.c.
* pdp11.c (bfd_free_cached_info): Free line_buf. Return true
if tdata.aout_data is NULL.