Commit Graph

579 Commits

Author SHA1 Message Date
Keith Smiley 47bb456b2f [llvm-obcopy][MachO] Add error for MH_PRELOAD
Previously this would crash. Fixes https://bugs.llvm.org/show_bug.cgi?id=51877

Differential Revision: https://reviews.llvm.org/D113819
2021-11-12 19:18:34 -08:00
Kazu Hirata 4db2e4cebe Use {DenseSet,SetVector,SmallPtrSet}::contains (NFC) 2021-10-30 19:00:19 -07:00
Daniel Rodríguez Troitiño 8fbe1e7602 [llvm-objcopy] Fix misaligned access to load command data.
It seems that llvm-objcopy stores data temporarily misaligned with the
requirements of the underlaying struct from libBinaryFormat, and UBSan
generates a runtime error.

Instead of trying to reinterpret the memory as the struct itself, simply
access the `char *` pointer that we are interested in, and that do not
have alignment restrictions.

This problem was pointed out in a comment of D111164.

Differential Revision: https://reviews.llvm.org/D112744
2021-10-28 22:14:39 -07:00
Nuri Amari a299b24712 Regenerate LC_CODE_SIGNATURE during llvm-objcopy operations
**Context:**

This is a second attempt at introducing signature regeneration to llvm-objcopy. In this diff: https://reviews.llvm.org/D109840, a script was introduced to test
the validity of a code signature. In this diff: https://reviews.llvm.org/D109803 (now reverted), an effort was made to extract the signature generation behavior out of LLD into a common location for use in llvm-objcopy. In this diff: https://reviews.llvm.org/D109972 it was decided that there was no appropriate common location and that a small amount of duplication to bring signature generation to llvm-objcopy would be better. This diff introduces this duplication.

**Summary**

Prior to this change, if a LC_CODE_SIGNATURE load command
was included in the binary passed to llvm-objcopy, the command and
associated section were simply copied and included verbatim in the
new binary. If rest of the binary was modified at all, this results
in an invalid Mach-O file. This change regenerates the signature
rather than copying it.

The code_signature_lc.test test was modified to include the yaml
representation of a small signed MachO executable in order to
effectively test the signature generation.

Reviewed By: alexander-shaposhnikov, #lld-macho

Differential Revision: https://reviews.llvm.org/D111164
2021-10-26 14:51:13 -07:00
Fangrui Song 8189c4eee7 [tools] Delete redundant 'static' from namespace scope 'static const'. NFC 2021-10-18 22:38:42 -07:00
Igor Kudrin 7b424b9333 [llvm-objcopy] Rename relocation sections together with their targets.
As for now, llvm-objcopy renames only sections that are specified
explicitly in --rename-section, while GNU objcopy keeps names of
relocation sections in sync with their targets. For example:

> readelf -S test.o
...
  [ 1] .foo      PROGBITS
  [ 2] .rela.foo RELA

> objcopy --rename-section .foo=.bar test.o gnu.o
> readelf -S gnu.o
...
  [ 1] .bar      PROGBITS
  [ 2] .rela.bar RELA

> llvm-objcopy --rename-section .foo=.bar test.o llvm.o
> readelf -S llvm.o
...
  [ 1] .bar      PROGBITS
  [ 2] .rela.foo RELA

This patch makes llvm-objcopy to match the behavior of GNU objcopy better.

Differential Revision: https://reviews.llvm.org/D110352
2021-09-29 16:36:37 +07:00
Igor Kudrin 6dda6c49ce [llvm-objcopy][NFC] Add a helper method RelocationSectionBase::getNamePrefix()
Refactor handleArgs() to use that method.

Differential Revision: https://reviews.llvm.org/D110350
2021-09-24 22:02:36 +07:00
gbreynoo 3bad9616aa [llvm-objcopy][docs] Add missing options to the help output and the command guide
This change is to keep the help text and command guide of objcopy in
tandem.

- In the help output the options --rename-section and
  --set-section-flags were missing the flag exclude, which is found in
  the command guide.
- In the command guide the alias -G for --keep-global-symbol was
    missing, which is found in the help output.

Differential Revision: https://reviews.llvm.org/D110340
2021-09-24 09:44:46 +01:00
Alfonso Sánchez-Beato b25ab4f313 [llvm-objcopy][COFF] Fix test for debug dir presence
If the number of directories was 6 (equal to the DEBUG_DIRECTORY
index), patchDebugDirectory() was run even though the debug directory
is actually the 7th entry. Use <= in the comparison to fix that.

This fixes https://llvm.org/PR51243

Differential Revision: https://reviews.llvm.org/D106940

Reviewed by: jhenderson
2021-09-10 09:57:18 +01:00
Alexey Lapshin 50467c0852 [llvm-objcopy][NFC] Refactor CopyConfig structure - categorize options.
This patch continues refactoring done by D99055. It puts format specific
options into the correponding CopyConfig structures.

Differential Revision: https://reviews.llvm.org/D102277
2021-09-08 19:16:38 +03:00
Alfonso Sánchez-Beato cdd407286a [llvm-objcopy] [COFF] Consider section flags when adding section
The --set-section-flags option was being ignored when adding a new
section. Take it into account if present.

Fixes https://llvm.org/PR51244

Reviewed By: jhenderson, MaskRay

Differential Revision: https://reviews.llvm.org/D106942
2021-08-25 23:11:41 +03:00
Igor Kudrin 68616584c3 [llvm-objcopy][ELF] Avoid reordering section headers
As for now, llvm-objcopy sorts section headers according to the offsets
of the sections in the input file. That can corrupt section references
in the dynamic symbol table because it is a loadable section and as such
is not updated by the tool. Even though the section references are not
required for loading the binary correctly, they are still handy for a
user who analyzes the file.

While the patch removes global reordering of section headers, it layouts
the sections in the same way as before, i.e. according to their original
offsets. All that helps the output file to resemble the input better.

Note that the patch removes sorting SHT_GROUP sections to the start of
the list, which was introduced in D62620 in order to ensure that they
come before the group members, along with the corresponding test. The
original issue was caused by the sorting of section headers, so dropping
the sorting also resolves the issue.

Differential Revision: https://reviews.llvm.org/D107653
2021-08-12 17:12:09 +07:00
Igor Kudrin 2bb4ebb19e [llvm-objcopy][ELF][NFC] Remove unneeded methods of Object
The patch removes mutable accessor methods for sections and segments.
As for now, const variants of them are not used because all callers have
mutable access to an instance of Object. On the other hand, they do not
actually modify the sets, so it looks better to keep only const ones.

Differential Revision: https://reviews.llvm.org/D107652
2021-08-09 15:44:03 +07:00
Pirama Arumuga Nainar 16ebb7ab5c [llvm-objcopy] [COFF] Do not patch debug entries if PointerToRawData is zero
Fix an edge case missed by https://reviews.llvm.org/D78921.  For e.g.,
the Repro debug entry (generated with the /Brepro linker flag) does not
have a debug-directory payload.  Do not attempt to patch Debug entries
without a payload.

Differential Revision: https://reviews.llvm.org/D107324
2021-08-06 09:23:25 -07:00
Simon Pilgrim 43ff058e78 [llvm-objcopy] IHexELFBuilder::addDataSections - fix evaluation ordering static analyzer warning
As detailed on https://pvs-studio.com/en/blog/posts/cpp/0771/ and raised on D62583, the SecNo++ increment is not guaranteed to occur before the second use of SecNo in the same addSection() call.

This patch pulls out the increment (just for clarity) and replaces the second use of SecNo with a constant zero value (we're using stable_sort so the value isn't critical).

Differential Revision: https://reviews.llvm.org/D107273
2021-08-03 12:16:59 +01:00
Daniel Rodríguez Troitiño d6704e5ed9 [llvm-objcopy][MachO] Ignore all LC_SUB_* commands.
The LC_SUB_FRAMEWORK, LC_SUB_UMBRELLA, LC_SUB_CLIENT, and LC_SUB_LIBRARY
are used to indicate related libraries, binaries or framework names.
Their only payload is the string with the name of the object. Adding
those commands to the list of ignored/skipped load commands will avoid
an error that stop the process of copying/stripping and will copy their
contents verbatim.

Additionally, in order to have a test for this case, `yaml2obj` now
allows those four commands to contain a `Content`.

Differential Revision: https://reviews.llvm.org/D106412
2021-07-28 17:35:26 -07:00
Fangrui Song c5d8bd5a35 [llvm-objcopy] Fix section group flag read/write when operating on a cross-endian object file 2021-07-26 15:09:15 -07:00
Fangrui Song 792c206e2b [llvm-objcopy] Drop GRP_COMDAT if the group signature is localized
See [GRP_COMDAT group with STB_LOCAL signature](https://groups.google.com/g/generic-abi/c/2X6mR-s2zoc)
objcopy PR: https://sourceware.org/bugzilla/show_bug.cgi?id=27931

GRP_COMDAT deduplication is purely based on the signature symbol name in
ld.lld/GNU ld/gold. The local/global status is not part of the equation.

If the signature symbol is localized by --localize-hidden or
--keep-global-symbol, the intention is likely to make the group fully
localized. Drop GRP_COMDAT to suppress deduplication.

Reviewed By: jhenderson

Differential Revision: https://reviews.llvm.org/D106782
2021-07-26 09:05:18 -07:00
Derek Schuff 7cb25f5387 [llvm-strip][WebAssembly] Support strip flags
Summary:
Add support for the basic section stripping (and keeping) flags for wasm:
strip with no flags, --strip-all, --strip-debug,
--only-section, --keep-section, and --only-keep-debug.

Factor section removal into a function and use a predicate chain like
the ELF implementation.

Reviewers: jhenderson, sbc100

Differential Revision: https://reviews.llvm.org/D73820
2021-07-14 14:17:02 -07:00
Fangrui Song 0144e625b9 [llvm-objcopy] Improve performance of long pattern lists
Some users use a long list of fixed patterns (PR50404) and
O(|patterns|*|symbols|) can be too slow. Such usage typically does not use
--regex or --wildcard. We can use a DenseSet<CachedHashStringRef> to optimize
name lookups.

Reviewed By: jhenderson

Differential Revision: https://reviews.llvm.org/D105218
2021-07-12 09:03:34 -07:00
Daniel Rodríguez Troitiño b77533fb70 [llvm-strip] Support grouped options in llvm-strip
GNU and Apple `strip` implementations seems to support grouped options.
Enable the support for grouped options introduced in
https://reviews.llvm.org/D83639 for `llvm-strip` invocations.

Includes test that checks that both the grouped and non grouped
invocations produces the same result.

Reviewed By: alexander-shaposhnikov, MaskRay

Differential Revision: https://reviews.llvm.org/D105249
2021-07-01 13:36:45 -07:00
Fangrui Song 814dffa4b7 [llvm-objcopy][MachO] Support LC_LINKER_OPTIMIZATION_HINT load command
The load command is currently specific to arm64 and holds information
for instruction rewriting, e.g.  converting a GOT load to an ADR to
compute a local address.
(On ELF the information is usually conveyed by relocations, e.g.
R_X86_64_REX_GOTPCRELX, R_PPC64_TOC16_HA)

Reviewed By: alexander-shaposhnikov

Differential Revision: https://reviews.llvm.org/D104968
2021-06-29 18:47:55 -07:00
Alexander Shaposhnikov 6d72845a85 [llvm-objcopy][MachO] Code cleanup
1. Remove unnecessary templates.
2. Fix potentially unaligned reads inside constructSection.

Test plan: make check-all

Differential revision: https://reviews.llvm.org/D105089
2021-06-29 14:08:23 -07:00
Fangrui Song 69937a8080 [llvm-objcopy][MachO] Support ARM64_RELOC_ADDEND
An ARM64_RELOC_ADDEND relocation reuses the symbol field for the addend value.
We should pass through such relocations.

Reviewed By: alexander-shaposhnikov

Differential Revision: https://reviews.llvm.org/D104967
2021-06-29 11:23:30 -07:00
Alexander Shaposhnikov 6229369e50 Revert "[llvm-objcopy][MachO] Minor code cleanup"
This reverts commit c94cf97b53
since it appears to have broken linaro-clang-armv7-quick build bot
and needs further investigation.
2021-06-29 01:18:48 -07:00
Alexander Shaposhnikov c94cf97b53 [llvm-objcopy][MachO] Minor code cleanup
Remove unnecessary template in MachOReader.cpp. NFC.
2021-06-28 22:51:02 -07:00
Fangrui Song f1e2d5851b [OptTable] Rename PrintHelp to printHelp
To be consistent with other member functions and match the coding standard.
2021-06-24 14:47:03 -07:00
Martin Storsjö 42f74e8249 [llvm] Rename StringRef _lower() method calls to _insensitive()
This is a mechanical change. This actually also renames the
similarly named methods in the SmallString class, however these
methods don't seem to be used outside of the llvm subproject, so
this doesn't break building of the rest of the monorepo.
2021-06-25 00:22:01 +03:00
Fangrui Song 011b502ce8 [llvm-objcopy][MachO] Fix namespace style issues 2021-06-23 00:31:52 -07:00
Fangrui Song 3accff2553 [llvm-objcopy] Fix some namespace style issues
https://llvm.org/docs/CodingStandards.html#use-namespace-qualifiers-to-implement-previously-declared-functions

Reviewed By: jhenderson

Differential Revision: https://reviews.llvm.org/D104693
2021-06-22 09:19:48 -07:00
Fangrui Song 3f873e9b51 [llvm-objcopy] Internalize some symbols 2021-06-21 23:49:25 -07:00
Fangrui Song f14e6e4451 [llvm-objcopy] Delete empty namespace. NFC 2021-06-21 23:44:07 -07:00
Fangrui Song d619cf5ac5 [llvm-objcopy][MachO] Copy LC_LINKER_OPTIMIZATION_HINT
This fixes `error: unsupported load command (cmd=0x2e)`
2021-06-16 12:09:50 -07:00
Fangrui Song 1de18ad8d7 [llvm-objcopy] Make ihex writer similar to binary writer
There is no need to differentiate whether `UseSegments` is true or
false. Unifying the cases makes the behavior closer to BinaryWriter.

This improves compatibility with objcopy because SHF_ALLOC sections not in
a PT_LOAD will not be skipped. Such cases are usually erroneous input, though.

Reviewed By: jhenderson

Differential Revision: https://reviews.llvm.org/D104186
2021-06-16 10:08:20 -07:00
David Blaikie 02c718301b llvm-objcopy: fix section size truncation/extension when dumping sections
Since this only comes up with inputs containing sections at least 4GB
large (I guess I could use a bzero section or something, so the input
file doesn't have to be 4GB, but even then the output file would have to
be 4GB, right?) I've skipped testing this. If there's a nice way to test
this without needing 4GB inputs or output files.

The subtlety here is demonstrated by this code:

struct t { operator uint64_t(); };
static_assert(std::is_same_v<int, decltype(std::declval<bool>() ? 0 : std::declval<t>())>);
static_assert(std::is_same_v<uint64_t, decltype(std::declval<bool>() ? 0 : std::declval<uint64_t>())>);

Because of this difference, the original source code was getting an int
type (truncating the actual size) and then extending it again, resulting
in bogus values (I haven't thought through this hard enough to explain
why the resulting value was 0xffff... - sign extension, possible UB, but
in any case it's the wrong answer - in this particular case I was
looking at that resulted in a size so large that we couldn't open a file
large enough to write to and ended up with a rather vague:

error: 'file_name.o': Invalid argument
2021-06-12 19:00:10 -07:00
Ian McIntyre 5899278758 [llvm-objcopy] Exclude empty sections in IHexWriter output
IHexWriter was evaluating a section's physical address when deciding if
that section should be written to an output. This approach does not
account for a zero-sized section that has the same physical address as a
sized section. The behavior varies from GNU objcopy, and may result in a
HEX file that does not include all program sections.

The IHexWriter now excludes zero-sized sections when deciding what
should be written to the output. This affects the contents of the
writer's `Sections` collection; we will not try to insert multiple
sections that could have the same physical address. The behavior seems
consistent with GNU objcopy, which always excludes empty sections,
no matter the address.

The new test case evaluates the IHexWriter behavior when provided a
variety of empty sections that overlap or append a filled section. See
the input file's comments for more information. Given that test input,
and the change to the IHexWriter, GNU objcopy and llvm-objcopy produce
the same output.

Reviewed By: jhenderson, MaskRay, evgeny777

Differential Revision: https://reviews.llvm.org/D101332
2021-06-12 12:23:07 -07:00
Alexander Shaposhnikov 0276cc742b [llvm-objcopy][MachO] Do not strip symbols with the flag REFERENCED_DYNAMICALLY set
Do not strip symbols having the flag REFERENCED_DYNAMICALLY set.

Test plan: make check-all

Differential revision: https://reviews.llvm.org/D104092
2021-06-11 16:34:59 -07:00
Alexey Lapshin 83cc4478a0 [llvm-objcopy][NFC] Refactor CopyConfig structure - remove lazy options processing.
During reviewing D102277 it was decided to remove lazy options processing
from llvm-objcopy CopyConfig structure. This patch transforms processing of ELF
lazy options into the in-place processing.

Differential Revision: https://reviews.llvm.org/D103260
2021-05-31 14:40:27 +03:00
Sergey Dmitriev 1fb5278882 [llvm-strip] Add support for '--' for delimiting options from input files
This will allow to use llvm-strip with file names that begin with dashes.

Reviewed By: jhenderson

Differential Revision: https://reviews.llvm.org/D102825
2021-05-20 03:33:51 -07:00
Alexey Lapshin 081c62501e [llvm-objcopy] Refactor CopyConfig structure.
This patch prepares llvm-objcopy to move its implementation
into a separate library. To make it possible it is necessary
to minimize internal dependencies.

Differential Revision: https://reviews.llvm.org/D99055
2021-05-20 13:14:51 +03:00
Sergey Dmitriev f24f140290 [llvm-objcopy] Add support for '--' for delimiting options from input/output files
This will allow to use llvm-objcopy with file names that begin with dashes.

Reviewed By: jhenderson

Differential Revision: https://reviews.llvm.org/D102665
2021-05-19 01:56:46 -07:00
Alex Orlov d8e65585f7 Fixed llvm-objcopy to add correct symbol table for ELF with program headers.
This fixes the following bugs:
https://bugs.llvm.org/show_bug.cgi?id=43935

Reviewed By: jhenderson

Differential Revision: https://reviews.llvm.org/D102258
2021-05-12 12:39:30 +04:00
Fangrui Song b3336bfa2e [llvm-objcopy][ELF] --only-keep-debug: set offset/size of segments with no sections to zero
PR50160: we currently ignore non-PT_PHDR segments with no sections, not
accounting for its p_offset and p_filesz: this can cause an out-of-bounds write
in `writeSegmentData` if the p_offset+p_filesz is larger than the total file
size.

This can be fixed by setting p_offset=p_filesz=0. The logic nicely unifies with
the logic added in D90897.

Reviewed By: jhenderson, rupprecht

Differential Revision: https://reviews.llvm.org/D101560
2021-05-05 10:26:57 -07:00
Fangrui Song 96f3a63076 [llvm-objcopy] --dump-section: error if '=' is missing or filename is empty
Fix PR45416: the diagnostic when '=' is missing is misleading.
`FileOutputBuffer::create` returns successfully when the filename is empty
(the temporary file is `.tmp%%%%%%%`), but `FileOutputBuffer::commit` will error when
renaming `.tmp%%%%%%%` to the empty name).

Reviewed By: jhenderson

Differential Revision: https://reviews.llvm.org/D101697
2021-05-04 17:30:57 -07:00
Alexander Shaposhnikov 86f291ebb2 [llvm-objcopy][MachO] Add support for LC_THREAD/LC_UNIXTHREAD
Add support for LC_THREAD/LC_UNIXTHREAD
(these load commands can be copied over without any modifications).

Test plan: make check-all

Differential revision: https://reviews.llvm.org/D101384
2021-04-28 16:29:33 -07:00
Alexander Shaposhnikov 412437aec0 Revert "[llvm-objcopy][MachO] Add support for LC_THREAD/LC_UNIXTHREAD"
This reverts commit 4dfddf715b
since it breaks some build bots (e.g. clang-ppc64be-linux)
2021-04-27 16:19:59 -07:00
Alexander Shaposhnikov 4dfddf715b [llvm-objcopy][MachO] Add support for LC_THREAD/LC_UNIXTHREAD
Add support for LC_THREAD/LC_UNIXTHREAD
(these load commands can be copied over without any modifications).

Test plan: make check-all

Differential revision: https://reviews.llvm.org/D101384
2021-04-27 15:54:51 -07:00
Nico Weber 1ede08a290 [llvm-objcopy] clang-format a line 2021-04-16 07:24:43 -04:00
Alexey Lapshin ee8a5e4bc2 Fix chrome os failure after 021de7cf80.
chrome os build failed after D98511:
https://bugs.chromium.org/p/chromium/issues/detail?id=1197970

This patch fixes permission issue appeared after D98511.
2021-04-12 15:28:32 +03:00
Alexey Lapshin 972b6a3a34 [llvm-objcopy][Support] move writeToOutput helper function to Support.
writeToOutput function is useful when it is necessary to create different kinds
of streams(based on stream name) and when we need to use a temporary file
while writing(which would be renamed into the resulting file in a success case).
This patch moves the writeToStream helper into the Support library.

Differential Revision: https://reviews.llvm.org/D98426
2021-03-22 15:41:10 +03:00