LLVM-OBJCOPY(1)

πŸ“¦
version 16.0.6 Β· 3 versions
, in ubuntu noble

πŸ’– LLVM-OBJCOPY(1) πŸ’–

okay bestie, welcome to the LLVM corner of the man pages, this one's called llvm-objcopy and she's literally the object copying and editing tool ✨


🌸 NAME 🌸

llvm-objcopy β€” object copying and editing tool 🫢


πŸŽ€ SYNOPSIS πŸŽ€

llvm-objcopy [options] input [output]

like… that's it. that's the whole vibe. input, maybe output, sprinkle some [options] on top and go πŸ’…


✨ DESCRIPTION ✨

okay so llvm-objcopy is a tool to copy and manipulate objects. In basic usage, it makes a semantic copy of the input to the output. But the second you start throwing options at her, the output can get modified along the way β€” like, for example, by removing sections. it's giving glow-up, but make it ELF πŸ”₯

If no output file is specified, the input file is modified in-place. yes, in-place. she's editing the original. no backup, no take-backs πŸ™ˆ

If - is specified for the input file, the input is read from the program's standard input stream. If - is specified for the output file, the output is written to the standard output stream of the program. so like, pipes? iconic. she does pipes 🌈

If the input is an archive, any requested operations will be applied to each archive member individually. every single one. she does not skip anybody πŸ’œ

ngl, the tool is still in active development, but in most scenarios it works as a drop-in replacement for GNU's objcopy. so if you're coming from GNU land, hi bestie, you're gonna be fine πŸ¦‹

more of this page is coming, don't go anywhere πŸ’–

🌈 GENERIC AND CROSS-PLATFORM OPTIONS 🌈

okay bestie, these next ones are the format-agnostic girlies πŸ’… they either literally do not care what file format you're working with, or they show up for multiple formats at once. versatile. iconic. no notes. ✨


  • --add-gnu-debuglink <debug-file> β€” adds a .gnu_debuglink section for <debug-file> into the output. cute lil pointer, very demure. πŸŽ€
  • --add-section <section=file> β€” adds a section named <section> to the output, filled with the contents of <file>. For ELF objects the section gets type SHT_NOTE if the name starts with .note; otherwise it's type SHT_PROGBITS. you can drop this flag multiple times to add multiple sections, go off. ✨

For MachO objects, <section> has to be formatted as <segment name>,<section name>.

  • --binary-architecture <arch>, -B β€” ignored for compatibility. it's just vibing in the corner, do not perceive it. πŸ™ˆ
  • --disable-deterministic-archives, -U β€” use real values for UIDs, GIDs and timestamps when you're updating archive member headers. raw and unfiltered. πŸ”₯
  • --discard-all, -x β€” removes most local symbols from the output. different file formats might limit this to a subset of the local symbols β€” for example, file and section symbols in ELF objects will not be discarded. also nukes all debug sections. bye girl πŸ‘‹
  • --dump-section <section>=<file> β€” dumps the contents of section <section> into the file <file>. can be specified multiple times to dump multiple sections into different files. heads up: <file> is unrelated to the input and output files you handed to llvm-objcopy, so the normal copying and editing operations still happen anyway. and no operations are performed on the sections before dumping them β€” they're dumped exactly as they are. πŸ’–

For MachO objects, <section> must be formatted as <segment name>,<section name>.

  • --enable-deterministic-archives, -D β€” turns on deterministic mode when copying archives, i.e. use 0 for the archive member header UIDs, GIDs and timestamp fields. this one is on by default, so she's already slaying. πŸ‘‘
  • --help, -h β€” prints a summary of command line options. the classic "wait what does this do again" button. πŸ’€
  • --only-keep-debug β€” produces a debug file as the output that only preserves the contents of sections that are useful for debugging purposes. main character energy: everything else gets cut. ✨

For ELF objects, this removes the contents of SHF_ALLOC sections that are not SHT_NOTE by making them SHT_NOBITS and shrinking the program headers where possible.

  • --only-section <section>, -j β€” removes all sections from the output except the ones named <section>. can be specified multiple times to keep multiple sections. very picky, very valid. πŸ’…

For MachO objects, <section> must be formatted as <segment name>,<section name>.

  • --redefine-sym <old>=<new> β€” renames symbols called <old> to <new> in the output. can be specified multiple times to rename multiple symbols. glow-up for your symbol table. πŸ¦‹
  • --redefine-syms <filename> β€” renames symbols in the output as described in the file <filename>. in that file, each line is a single symbol to rename, with the old name and new name separated by whitespace. leading and trailing whitespace is ignored, and so is anything following a #. can be specified multiple times to read names from multiple files. batch renaming, we love to see it. 🌸
  • --regex β€” if you specify this, symbol and section names given by other switches get treated as extended POSIX regular expression patterns. regex girlies rise 🧚
  • --remove-section <section>, -R β€” removes the specified section from the output. can be specified multiple times to remove multiple sections at once. not me deleting sections, it's giving spring cleaning 🧹

For MachO objects, <section> must be formatted as <segment name>,<section name>.

  • --set-section-alignment <section>=<align> β€” sets the alignment of section <section> to <align>. can be specified multiple times to update multiple sections. alignment is self-care bestie. ✨
  • --set-section-flags <section>=<flag>[,<flag>,...] β€” sets the section properties in the output for section <section> based on the <flag> values you gave. can be specified multiple times to update multiple sections.

the supported flag names are alloc, load, noload, readonly, exclude, debug, code, data, rom, share, contents, merge and strings. ngl, not all flags are meaningful for all object file formats β€” so some of these do nothing depending on what you're feeding her. πŸ’€

For ELF objects, the flags do this:

  • alloc = add the SHF_ALLOC flag.
  • load = if the section has SHT_NOBITS type, mark it as a SHT_PROGBITS section.
  • readonly = if this flag is not specified, add the SHF_WRITE flag.
  • exclude = add the SHF_EXCLUDE flag.
  • code = add the SHF_EXECINSTR flag.
  • merge = add the SHF_MERGE flag.
  • strings = add the SHF_STRINGS flag.
  • contents = if the section has SHT_NOBITS type, mark it as a SHT_PROGBITS section.

For COFF objects, the flags do this:

  • alloc = add the IMAGE_SCN_CNT_UNINITIALIZED_DATA and IMAGE_SCN_MEM_READ flags, unless the load flag is specified.
  • noload = add the IMAGE_SCN_LNK_REMOVE and IMAGE_SCN_MEM_READ flags.
  • readonly = if this flag is not specified, add the IMAGE_SCN_MEM_WRITE flag.
  • exclude = add the IMAGE_SCN_LNK_REMOVE and IMAGE_SCN_MEM_READ flags.
  • debug = add the IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE and IMAGE_SCN_MEM_READ flags.
  • code = add the IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE and IMAGE_SCN_MEM_READ flags.
  • data = add the IMAGE_SCN_CNT_INITIALIZED_DATA and IMAGE_SCN_MEM_READ flags.
  • share = add the IMAGE_SCN_MEM_SHARED and IMAGE_SCN_MEM_READ flags.
  • --strip-all-gnu β€” removes all symbols, debug sections and relocations from the output. this option is equivalent to GNU objcopy's --strip-all switch. periodt. πŸ’…
  • --strip-all, -S β€” for ELF objects, removes from the output all symbols and non-alloc sections that aren't within segments, except for .gnu.warning, .ARM.attribute sections and the section name table. don't worry, those three are protected. 🫢

For COFF and Mach-O objects, removes all symbols, debug sections, and relocations from the output.

  • --strip-debug, -g β€” removes all debug sections from the output. no debug thoughts, head empty. πŸŽ€
  • --strip-symbol <symbol>, -N β€” removes all symbols named <symbol> from the output. can be specified multiple times to remove multiple symbols. targeted deletion, we love a precise queen. βœ‚οΈ
  • --strip-symbols <filename> β€” removes all symbols whose names appear in the file <filename> from the output. in that file, each line is a single symbol name, with leading and trailing whitespace ignored, as is anything following a #. can be specified multiple times to read names from multiple files. πŸ“‹
  • --strip-unneeded-symbol <symbol> β€” removes from the output all symbols named <symbol> that are local or undefined and aren't required by any relocation. she only leaves if nobody needs her. πŸ’…
  • --strip-unneeded-symbols <filename> β€” removes all symbols whose names appear in the file <filename> from the output, if they're local or undefined and aren't required by any relocation. in that file, each line is a single symbol name, with leading and trailing whitespace ignored, as is anything following a #. can be specified multiple times to read names from multiple files. 🌸
  • --strip-unneeded β€” removes from the output all local or undefined symbols that aren't required by relocations. also removes all debug sections. full reset, no baggage. ✨
  • --update-section <name>=<file> β€” replaces the contents of section <name> with contents from the file <file>. ⚠️ but if the section <name> is part of a segment, the new contents cannot be larger than the existing section β€” she does not stretch, no cap.
  • --version, -V β€” displays the version of the llvm-objcopy executable. the "who even are you" check. πŸ‘‘
  • --wildcard, -w β€” allows wildcard syntax for symbol-related flags. it's on by default for section-related flags. incompatible with --regex β€” pick a lane bestie, you cannot have both. πŸ’€

wildcard syntax lets you use these special symbols:

  • * β€” any number of characters β€” equivalent to .*
  • ? β€” any single character β€” equivalent to .
  • \ β€” escape the next character β€” equivalent to \
  • [a-z] β€” character class β€” equivalent to [a-z]
  • [!a-z], [^a-z] β€” negated character class β€” equivalent to [^a-z]

additionally, starting a wildcard with ! will prevent a match, even if another flag matches. for example, -w -N '*' -N '!x' will strip all symbols except for x. iconic exclusion behaviour. πŸ¦‹

the order of wildcards does not matter. for example, -w -N '*' -N '!x' is the same as -w -N '!x' -N '*'. she is unbothered by your ordering. ✨

  • @<FILE> β€” reads command-line options and commands from the response file <FILE>. yes, it's the little @ at the front, so fancy. πŸ’–

✨ ELF-SPECIFIC OPTIONS ✨

Okay bestie, these ones are ELF-only β€” like, they only work on ELF objects, periodt. If you try them on anything else, llvm-objcopy is either gonna throw an error at you or just silently ignore you (rude, but okay). πŸ’…

  • --add-symbol <name>=[<section>:]<value>[,<flags>] β€” adds a brand-new symbol called <name> to the output symbol table, sitting in the section named <section>, with the value <value>. If you don't give a <section>, the symbol gets added as an absolute symbol. The <flags> are what give the symbol its ✨properties✨. Here's what you can pass:
    • global = the symbol gets global binding.
    • local = the symbol gets local binding.
    • weak = the symbol gets weak binding.
    • default = the symbol gets default visibility.
    • hidden = the symbol gets hidden visibility.
    • protected = the symbol gets protected visibility.
    • file = the symbol becomes an STT_FILE symbol.
    • section = the symbol becomes an STT_SECTION symbol.
    • object = the symbol becomes an STT_OBJECT symbol.
    • function = the symbol becomes an STT_FUNC symbol.
    • indirect-function = the symbol becomes an STT_GNU_IFUNC symbol.

Also, these next flags are accepted but literally ignored: debug, constructor, warning, indirect, synthetic, unique-object, before. They're just there for the vibes, no cap.

You can specify this multiple times to add a whole squad of symbols. πŸ‘‘

  • --allow-broken-links β€” lets llvm-objcopy remove sections even when doing so would leave invalid section references behind. Any invalid sh_link fields get set to zero. Fixing the mess, bestie. 🫢
  • --change-start <incr>, --adjust-start β€” adds <incr> to the program's start address. Can be specified multiple times, and when you do, the values stack up cumulatively. πŸ”₯
  • --compress-debug-sections [<format>] β€” compresses the DWARF debug sections in the output using whatever format you name. Supported formats are zlib and zstd. If you leave <format> out, it uses zlib.
  • --decompress-debug-sections β€” decompresses any compressed DWARF debug sections in the output.
  • --discard-locals, -X β€” yeets every local symbol starting with ".L" right out of the output. πŸ’€
  • --extract-dwo β€” removes all sections from the output that aren't DWARF .dwo sections.
  • --extract-main-partition β€” extracts the main partition from the output.
  • --extract-partition <name> β€” extracts the partition named <name> from the output.
  • --globalize-symbol <symbol> β€” marks any defined symbols named <symbol> as global symbols in the output. Specify it multiple times to globalize multiple symbols.
  • --globalize-symbols <filename> β€” reads a list of names from the file <filename> and marks defined symbols with those names as global in the output. In the file, each line is one symbol; leading and trailing whitespace is ignored, and so is anything after a #. Can be specified multiple times to pull names from multiple files. πŸ“„
  • --input-target <format>, -I β€” reads the input as the format you name. Peep SUPPORTED FORMATS for the list of valid <format> values. If you don't say anything, llvm-objcopy tries to figure the format out on its own. πŸ”
  • --keep-file-symbols β€” keeps symbols of type STT_FILE, even when they'd normally get stripped.
  • --keep-global-symbol <symbol>, -G β€” makes every symbol local in the output except the ones named <symbol>. Specify it multiple times to spare multiple symbols.
  • --keep-global-symbols <filename> β€” makes every symbol local in the output except the ones named in the file <filename>. Same file rules: one symbol per line, leading/trailing whitespace ignored, and anything after a # ignored too. Can be specified multiple times to read from multiple files.
  • --keep-section <section> β€” when removing sections from the output, don't remove the ones named <section>. Specify it multiple times to keep multiple sections. πŸŽ€
  • --keep-symbol <symbol>, -K β€” when removing symbols from the output, don't remove the ones named <symbol>. Specify it multiple times to keep multiple symbols.
  • --keep-symbols <filename> β€” when removing symbols from the output, don't remove the ones named in the file <filename>. One symbol per line, leading/trailing whitespace ignored, and everything after a # ignored. Can be specified multiple times to read from multiple files.
  • --localize-hidden β€” makes every symbol with hidden or internal visibility local in the output.
  • --localize-symbol <symbol>, -L β€” marks any defined non-common symbol named <symbol> as a local symbol in the output. Specify it multiple times to localize multiple symbols.
  • --localize-symbols <filename> β€” reads a list of names from the file <filename> and marks defined non-common symbols with those names as local in the output. One symbol per line, leading/trailing whitespace ignored, and anything after a # ignored too. Can be specified multiple times to read from multiple files.
  • --new-symbol-visibility <visibility> β€” sets the visibility of the symbols that get automatically created when you use binary input or --add-symbol. Valid options are:
    • default
    • hidden
    • internal
    • protected

The default is default. ✨

  • --output-target <format>, -O β€” writes the output as the format you name. See SUPPORTED FORMATS for the valid <format> values. If you don't specify it, the output format is assumed to match whatever you gave to --input-target, or the input file's format if that option wasn't given either.
  • --prefix-alloc-sections <prefix> β€” slaps <prefix> onto the front of the names of every allocatable section in the output.
  • --prefix-symbols <prefix> β€” slaps <prefix> onto the front of every single symbol name in the output.
  • --preserve-dates, -p β€” preserves the access and modification timestamps in the output. πŸ•°οΈ
  • --rename-section <old>=<new>[,<flag>,...] β€” renames sections called <old> to <new> in the output, and applies any <flag> values you list. Check --set-section-flags for the list of supported flags. Specify it multiple times to rename multiple sections.
  • --set-section-type <section>=<type> β€” sets the type of section <section> to the integer <type>. Can be specified multiple times to update multiple sections.
  • --set-start-addr <addr> β€” sets the start address of the output to <addr>. This overrides any --change-start or --adjust-start options you specified earlier. πŸ’₯
  • --split-dwo <dwo-file> β€” same as running llvm-objcopy with --extract-dwo and <dwo-file> as the output file and no other options, and then running --strip-dwo on the input file.
  • --strip-dwo β€” removes every DWARF .dwo section from the output.
  • --strip-non-alloc β€” removes from the output every non-allocatable section that isn't inside segments.
  • --strip-sections β€” removes from the output all section headers and all section data that isn't inside segments. Heads up bestie: lots of tools won't be able to use an object with no section headers at all. 😭
  • --target <format>, -F β€” equivalent to setting --input-target and --output-target to the format you name. See SUPPORTED FORMATS for the valid <format> values.
  • --weaken-symbol <symbol>, -W β€” marks any global symbol named <symbol> as a weak symbol in the output. Specify it multiple times to weaken multiple symbols.
  • --weaken-symbols <filename> β€” reads a list of names from the file <filename> and marks global symbols with those names as weak in the output. One symbol per line, leading/trailing whitespace ignored, and anything after a # ignored too. Can be specified multiple times to read from multiple files.
  • --weaken β€” marks every defined global symbol as weak in the output.

🍎 MACH-O-SPECIFIC OPTIONS 🍎

  • --keep-undefined β€” keeps undefined symbols, even when they'd otherwise get stripped.

πŸͺŸ COFF-SPECIFIC OPTIONS πŸͺŸ

  • --subsystem <name>[:<version>] β€” sets the PE subsystem, and optionally the subsystem version too.

🌈 SUPPORTED FORMATS 🌈

These are the values llvm-objcopy currently supports for the --input-target, --output-target, and --target options. For GNU objcopy compatibility, all the values are bfdnames. iykyk. πŸ’…

  • binary
  • ihex
  • elf32-i386
  • elf32-x86-64
  • elf64-x86-64
  • elf32-iamcu
  • elf32-littlearm
  • elf64-aarch64
  • elf64-littleaarch64
  • elf32-littleriscv
  • elf64-littleriscv
  • elf32-powerpc
  • elf32-powerpcle
  • elf64-powerpc
  • elf64-powerpcle
  • elf32-bigmips
  • elf32-ntradbigmips
  • elf32-ntradlittlemips
  • elf32-tradbigmips
  • elf32-tradlittlemips
  • elf64-tradbigmips
  • elf64-tradlittlemips
  • elf32-sparc
  • elf32-sparcel

Also, every target except binary and ihex can have -freebsd tacked on as a suffix. πŸ¦‹


🧚 BINARY INPUT AND OUTPUT 🧚

If you use binary as the value for --input-target, the input file gets embedded as a data section inside an ELF relocatable object. It comes with the symbols _binary_<file_name>_start, _binary_<file_name>_end, and _binary_<file_name>_size representing the start, end, and size of the data β€” where <file_name> is the path of the input file exactly as you wrote it on the command line, with every non-alphanumeric character converted to _. 🌸

If you use binary as the value for --output-target, the output file becomes a raw binary file containing the memory image of the input file. Symbols and relocation info get tossed out entirely. The image starts at the address of the first loadable section in the output.


πŸšͺ EXIT STATUS πŸšͺ

llvm-objcopy exits with a non-zero exit code if there's an error. Otherwise, it exits with code 0. Simple as that. ✨


πŸ› BUGS πŸ›

To report bugs, please visit <https://github.com/llvm/llvm-project/labels/tools:llvm-objcopy/strip/>.

There's a known issue where --input-target and --target only actually do anything for the binary and ihex formats. Any other value just gets ignored, and llvm-objcopy will try to guess the input format instead. πŸ’€


πŸ‘€ SEE ALSO πŸ‘€

llvm-strip(1)


πŸ‘‘ AUTHOR πŸ‘‘

Maintained by the LLVM Team (<https://llvm.org/>).

okay bestie, the legal bit, and then we're done for real πŸ’…

2003-2024, LLVM Project 🫢

that's it. that's the whole thing. the LLVM Project has been holding it down since 2003 and is still going strong in 2024, no cap ✨ like... two decades of compilers and object file magic?? we love a long-running icon πŸ‘‘


and that's a wrap on the whole LLVM-OBJCOPY(1) page, fr fr πŸŽ€ you made it to the end, which is genuinely main character energy πŸ’–

cute lil' sign-off for the receipts 🧾✨

  • this was page 15 of the manual πŸ’…
  • dated 2024-04-14 🌸
  • and it lives under the name LLVM-OBJCOPY(1) πŸ¦‹

go copy some objects, bestie. you got this. periodt πŸ’œ

πŸ“¦ where this page comes from