LLVM-OBJCOPY(1)
๐ NAME ๐
llvm-objcopy โ the object copying and editing tool, bestie ๐
โจ SYNOPSIS โจ
llvm-objcopy [options] input [output]
๐ฆ 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 โ no cap, that's literally the whole job. ๐ซถ
But here's where it gets iconic: if you specify any options, the output may be modified along the way โ like, for example, by removing sections. The way that it just... does that. ๐ญ๐ฅ
And now the details you actually need, bestie, write these down:
- If no output file is specified, the input file is modified in-place. ๐ (yes, like that, careful.)
- 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. Pipes? Slay.
Also, vibe check for archives: if the input is an archive, any requested operations will be applied to each archive member individually. Every single one. Fr fr. ๐ง
๐ The tool is still in active development, but in most scenarios it works as a drop-in replacement for GNU's objcopy. Lowkey iconic of it.
โจ GENERIC AND CROSS-PLATFORM OPTIONS โจ
Okay bestie, these are the options that either don't care at all what file format you're in, or they work their magic across several formats at once. Universal queen behavior honestly. ๐
--add-gnu-debuglink <debug-file>โ Slaps a.gnu_debuglinksection into the output that points at <debug-file>. Cute little breadcrumb trail for your debugger. ๐--add-section <section=file>โ Adds a brand new section called <section> to the output, filled with whatever's inside <file>. For ELF objects the section gets typeSHT_NOTEif the name starts with.noteโ otherwise it'sSHT_PROGBITS, no in-between. You can pass this multiple times to stack up multiple sections. ๐
For MachO objects, <section> has to be formatted as <segment name>,<section name> โ comma and all, don't forget it.
--binary-architecture <arch>,-Bโ Ignored for compatibility. She's just standing there. ๐--disable-deterministic-archives,-Uโ Uses the real UID, GID and timestamp values when updating archive member headers. Like, the actual ones. Unfiltered truth. ๐--discard-all,-xโ Removes most local symbols from the output. Heads up though โ different file formats might limit this to just a subset of local symbols. For example, file and section symbols in ELF objects will not be discarded, periodt. Also removes all debug sections while it's at it.--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. Important vibe check: <file> is completely unrelated to the input and output files you gave tollvm-objcopy, so like, the normal copying and editing operations still happen anyway. And no operations are performed on the sections before dumping them โ pure, untouched content. โจ
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. uses0for archive member header UID, GID 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 contents of sections useful for debugging purposes. Diet version of your binary, debug-only edition. ๐ง
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 the sections from the output except the ones named <section>. Can be specified multiple times to keep multiple sections. Very "you're all uninvited except you three" energy. ๐
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, as is anything following a#โ so go off with your comments. Can be specified multiple times to read names from multiple files. ๐--regexโ If specified, symbol and section names given by other switches are treated as extended POSIX regular expression patterns. Fancy. ๐ฅ--remove-symbol-prefix <prefix>โ Removes <prefix> from the start of every symbol name. Total no-op for symbols that don't start with <prefix> โ she doesn't touch what isn't hers.--remove-section <section>,-Rโ Removes the specified section from the output. Can be specified multiple times to remove multiple sections simultaneously. Blocked. Uninvited. Gone. ๐
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 at once.--set-section-flags <section>=<flag>[,<flag>,...]โ Sets section properties in the output of section <section> based on the <flag> values you list. Can be specified multiple times to update multiple sections. ๐ ๏ธ
Supported flag names are alloc, load, noload, readonly, exclude, debug, code, data, rom, share, contents, merge, strings, and large. Ngl though, not all flags are meaningful for all object file formats or target architectures โ some of them are just there for the vibe.
For ELF objects, the flags have the following effects:
alloc= add theSHF_ALLOCflag.load= if the section hasSHT_NOBITStype, mark it as aSHT_PROGBITSsection.readonly= if this flag is not specified, add theSHF_WRITEflag.exclude= add theSHF_EXCLUDEflag.code= add theSHF_EXECINSTRflag.merge= add theSHF_MERGEflag.strings= add theSHF_STRINGSflag.contents= if the section hasSHT_NOBITStype, mark it as aSHT_PROGBITSsection.large= add theSHF_X86_64_LARGEon x86_64; rejected if the target architecture is not x86_64. ๐ซ
For COFF objects, the flags have the following effects:
alloc= add theIMAGE_SCN_CNT_UNINITIALIZED_DATAandIMAGE_SCN_MEM_READflags, unless theloadflag is specified.noload= add theIMAGE_SCN_LNK_REMOVEandIMAGE_SCN_MEM_READflags.readonly= if this flag is not specified, add theIMAGE_SCN_MEM_WRITEflag.exclude= add theIMAGE_SCN_LNK_REMOVEandIMAGE_SCN_MEM_READflags.debug= add theIMAGE_SCN_CNT_INITIALIZED_DATA,IMAGE_SCN_MEM_DISCARDABLEandIMAGE_SCN_MEM_READflags.code= add theIMAGE_SCN_CNT_CODE,IMAGE_SCN_MEM_EXECUTEandIMAGE_SCN_MEM_READflags.data= add theIMAGE_SCN_CNT_INITIALIZED_DATAandIMAGE_SCN_MEM_READflags.share= add theIMAGE_SCN_MEM_SHAREDandIMAGE_SCN_MEM_READflags.
--strip-all-gnuโ Removes all symbols, debug sections and relocations from the output. This option is equivalent to GNU objcopy's--strip-allswitch. Basically the certified classic. ๐--strip-all,-Sโ For ELF objects, removes from the output all symbols and non-alloc sections not within segments, except for.gnu.warning,.ARM.attributesections and the section name table โ those three get to stay, they're VIPs. ๐
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. Bye bestie, you were fun but you're taking up space. ๐--strip-symbol <symbol>,-Nโ Removes all symbols named <symbol> from the output. Can be specified multiple times to remove multiple symbols.--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 are not required by any relocation. She only takes out the ones nobody's using. ๐--strip-unneeded-symbols <filename>โ Removes all symbols whose names appear in the file <filename> from the output, if they are local or undefined and are not required by any relocation. In the 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 are not required by relocations. Also removes all debug sections. Two birds, zero regrets. ๐ฅ--update-section <name>=<file>โ Replaces the contents of the section <name> with contents from the file <file>. But careful โ if the section <name> is part of a segment, the new contents cannot be larger than the existing section. She will not stretch for you, no cap. โ ๏ธ--version,-Vโ Displays the version of thellvm-objcopyexecutable. Identity 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. ๐ฆ
Wildcard syntax allows the following 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 behavior honestly. โจ
The order of wildcards does not matter. For example, -w -N '*' -N '!x' is the same as -w -N '!x' -N '*' โ she's not picky about your order. ๐ซถ
@<FILE>โ Reads command-line options and commands from response file <FILE>. Like a little note passed to the program. ๐
okay so these next ones? they're the ELF-only girlies ๐
โ they only work on ELF objects. Try them on anything else and llvm-objcopy will either throw an error at you or just silently ignore you (which, honestly, is so passive-aggressive of it ๐ญ).
--add-symbol <name>=[<section>:]<value>[,<flags>]โ bestie, this one adds a whole new symbol called<name>to the output symbol table. It lives in the section named<section>, and its value is<value>. If you don't tell it a<section>, the symbol gets added as an absolute symbol instead. The<flags>bit changes up the symbol's properties, and here's the whole menu of accepted values: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 anSTT_FILEsymbol.sectionโ the symbol becomes anSTT_SECTIONsymbol.objectโ the symbol becomes anSTT_OBJECTsymbol.functionโ the symbol becomes anSTT_FUNCsymbol.indirect-functionโ the symbol becomes anSTT_GNU_IFUNCsymbol.
Also, these flags are technically accepted but just vibing, ignored ๐: debug, constructor, warning, indirect, synthetic, unique-object, before.
You can drop this option multiple times to add multiple symbols โ go off โจ
--allow-broken-linksโ letsllvm-objcopyremove sections even if doing so would leave you with invalid section references ๐ฌ. Any invalidsh_linkfields get set to zero, so it's like, broken but contained, yk?--change-section-lma \*{+-}<val>โ shifts the LMA of non-zero-sized segments by<val>. Move it, move it ๐บ--change-start <incr>,--adjust-startโ adds<incr>to the program's start address. Drop it multiple times and the values stack cumulatively โ main character energy, everything piles on top ๐ซ--compress-debug-sections [<format>]โ compresses the DWARF debug sections in your output using whatever<format>you named. Supported formats arezlibandzstd. Leave<format>off and it just useszlibby default ๐--compress-sections <section>=<format>โ compresses or decompresses the sections matched by<section>using the specified format. Supported formats arezlibandzstd; saynoneto decompress. When multiple options match the same section, the last one wins ๐. A wildcard<section>starting with'!'is not allowed, and heads up: sections within a segment cannot be (de)compressed ๐ซถ--decompress-debug-sectionsโ unzips any compressed DWARF debug sections in the output. We're letting them breathe ๐จ--discard-locals,-Xโ removes local symbols that start with".L"from the output. Bye local symbols, hope you had a good run ๐ฆ--extract-dwoโ nukes every section that isn't a DWARF.dwosection from the output. DWARF-only diet, no cap ๐--extract-main-partitionโ pulls the main partition out of the output.--extract-partition <name>โ pulls the partition named<name>out of the output.--gap-fill <value>โ for binary outputs, this fills the gaps between sections with<value>instead of zero. The value must be an unsigned 8-bit integer, so don't try anything fancy ๐--globalize-symbol <symbol>โ marks any defined symbols named<symbol>as global symbols in the output. Drop it multiple times to globalize multiple symbols โ glow-up for everyone โจ--globalize-symbols <filename>โ reads a list of names from<filename>and marks defined symbols with those names as global in the output. In the file, each line is one single symbol; leading and trailing whitespace gets ignored, same with anything after a'#'. Can be specified multiple times to read names from multiple files ๐--input-target <format>,-Iโ reads the input as the specified format. Peep SUPPORTED FORMATS for the list of valid<format>values. If you don't specify one,llvm-objcopywill try to figure the format out automatically โ it's giving psychic ๐ฎ--keep-file-symbolsโ keeps symbols of typeSTT_FILE, even when they'd otherwise get stripped. Protecting the file symbols with their life ๐--keep-global-symbol <symbol>,-Gโ marks all symbols local in the output, except the ones named<symbol>. Specify it multiple times to ignore multiple symbols โ VIP list only, periodt ๐--keep-global-symbols <filename>โ marks all symbols local in the output, except the ones named in the file<filename>. In the file, each line is one symbol; leading and trailing whitespace is ignored, same with anything after a'#'. Can be specified multiple times to read names from multiple files ๐--keep-section <section>โ when sections are being removed from the output, don't remove the ones named<section>. Specify it multiple times to keep multiple sections. Protected by the group chat ๐ก๏ธ--keep-symbol <symbol>,-Kโ when symbols are getting removed from the output, don't remove the ones named<symbol>. Multiple times = multiple kept symbols ๐ซถ--keep-symbols <filename>โ when removing symbols from the output, don't remove symbols named in the file<filename>. In the file, each line is one symbol; leading and trailing whitespace ignored, and so is anything after a'#'. Can be specified multiple times to read names from multiple files ๐--localize-hiddenโ marks every symbol with hidden or internal visibility as local in the output. Hidden girlies stay hidden ๐--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<filename>and marks defined non-common symbols with those names as local in the output. In the file, each line is one symbol; leading and trailing whitespace ignored, as is anything after a'#'. Can be specified multiple times to read names 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:defaulthiddeninternalprotected
The default is default, obviously ๐ซ
--no-verify-note-sectionsโ when adding note sections, this skips the check on whether the section format is valid. Living dangerously, love that for you ๐--output-target <format>,-Oโ writes the output as the specified format. See SUPPORTED FORMATS for the list of valid<format>values. If you leave it off, the output format is assumed to be whatever you gave to--input-target, or the input file's format if that option was also left off ๐--pad-to <address>โ for binary outputs, pads the output up to the load address<address>, using zero or whatever value you gave to--gap-fill. Filling in the blanks ๐ง--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. Everyone gets a lil name tag ๐ท๏ธ--preserve-dates,-pโ preserves the access and modification timestamps in the output. Time is a construct but we respect it โฐ--rename-section <old>=<new>[,<flag>,...]โ renames sections called<old>to<new>in the output, and applies any<flag>values you specified. Peep--set-section-flagsfor the list of supported flags. Can be specified multiple times to rename multiple sections ๐--set-section-type <section>=<type>โ sets the type of section<section>to the integer<type>. Multiple times = multiple sections updated ๐ฅ--set-start <addr>โ sets the start address of the output to<addr>. This one overrides any--change-startor--adjust-startyou already specified. It's the main character, the others get no lines ๐--set-symbol-visibility <symbol>=<visibility>โ changes the visibility of a symbol to the value you specify.--set-symbols-visibility <filename>=<visibility>โ reads a list of symbols from<filename>and changes their visibility to the specified value. Visibility values you can use:default,internal,hidden,protected.--skip-symbol <symbol>โ don't change the parameters of the symbol<symbol>when other options that can change a symbol's name, binding or visibility are running. It's sitting this one out ๐--skip-symbols <filename>โ don't change the parameters of the symbols named in the file<filename>when other options that can change a symbol's name, binding or visibility are running. In the file, each line is one symbol; leading and trailing whitespace ignored, as is anything after a'#'. Can be specified multiple times to read names from multiple files ๐--split-dwo <dwo-file>โ this is exactly equivalent to runningllvm-objcopywith--extract-dwoand<dwo-file>as the output file and no other options, and then running it again with--strip-dwoon the input file. Two-for-one situation, we love efficiency ๐--strip-dwoโ removes every DWARF.dwosection from the output. Gone, reduced to atoms ๐--strip-non-allocโ removes from the output all non-allocatable sections that aren't inside segments ๐งน--strip-sectionsโ removes from the output all section headers, plus all section data that isn't within segments.
โ ๏ธ heads up bestie: lots of tools will not be able to use an object that has no section headers. This is a real one, not a drill ๐ญ
--target <format>,-Fโ equivalent to setting both--input-targetand--output-targetto the specified format. See SUPPORTED FORMATS for the list of valid<format>values. One option, both jobs, iconic ๐--verify-note-sectionsโ when adding note sections, checks whether the section format is valid. This one is on by default โ--weaken-symbol <symbol>,-Wโ marks global symbols named<symbol>as weak symbols in the output. Multiple times = multiple symbols weakened ๐ช--weaken-symbols <filename>โ reads a list of names from<filename>and marks global symbols with those names as weak in the output. In the file, each line is one symbol; leading and trailing whitespace ignored, as is anything after a'#'. Can be specified multiple times to read names from multiple files ๐--weakenโ marks all defined global symbols as weak in the output. Everyone's weak now, it's a whole mood ๐ซ
๐ MACH-O-SPECIFIC OPTIONS
--keep-undefinedโ keeps undefined symbols around, even if they'd otherwise get stripped. Can't let them go ๐ฅบ
๐ช COFF-SPECIFIC OPTIONS
--subsystem <name>[:<version>]โ sets the PE subsystem, and optionally the subsystem version too. Very demure, very PE ๐
โจ SUPPORTED FORMATS โจ
okay so bestie, here's the tea on what llvm-objcopy actually eats for the --input-target, --output-target, and --target options ๐ซถ. These are the values it supports rn. And for GNU objcopy compatibility reasons, literally all of them are bfdnames. slay.
binaryihexelf32-i386elf32-x86-64elf64-x86-64elf32-iamcuelf32-littlearmelf64-aarch64elf64-littleaarch64elf32-littleriscvelf64-littleriscvelf32-powerpcelf32-powerpcleelf64-powerpcelf64-powerpcleelf32-bigmipself32-ntradbigmipself32-ntradlittlemipself32-tradbigmipself32-tradlittlemipself64-tradbigmipself64-tradlittlemipself32-sparcelf32-sparcelelf32-hexagonelf32-loongarchelf64-loongarchelf64-s390
And these next ones? llvm-objcopy supports them for --output-target only, no cap:
srec
Also, heads up: every single target except binary, ihex, and srec can have -freebsd tacked on as a suffix. cute, right? ๐
๐ง BINARY INPUT AND OUTPUT ๐ง
So if you pass binary as the value for --input-target, the input file gets embedded as a data section in an ELF relocatable object. And it gets these three symbols โ _binary_<file_name>_start, _binary_<file_name>_end, and _binary_<file_name>_size โ representing the start, end, and size of the data. Here <file_name> is the path of the input file exactly as you specified it on the command line, but with all the non-alphanumeric characters converted to _. iconic behavior tbh ๐
If you use binary as the value for --output-target, the output file will be a raw binary file containing the memory image of the input file. Symbols and relocation information? discarded, gone, not invited to the party ๐ญ. The image will start at the address of the first loadable section in the output. periodt.
๐ EXIT STATUS ๐
llvm-objcopy exits with a non-zero exit code if there's an error. Otherwise it exits with code 0. no drama, no stress ๐.
๐ BUGS ๐
to report bugs, please visit <โ https://github.com/llvm/llvm-project/labels/tools:llvm-objcopy/strip/.
โ ๏ธ also there's a known issue with--input-targetand--targetwhere only thebinaryandihexformats have any effect. the other values get ignored andllvm-objcopywill just attempt to guess the input format. not me finding out the hard way ๐
๐ฆ SEE ALSO ๐ฆ
๐ AUTHOR ๐
Maintained by the LLVM Team (https://llvm.org/). they're serving, fr fr ๐
๐ธ COPYRIGHT ๐ธ
2003-2025, LLVM Project
that's the whole page bestie, you ate ๐
โจ and for the cute lil sign-off: this was page version 19, dated 2025-01-17, aka LLVM-OBJCOPY(1) โ go forth and copy some objects ๐๐ซถ
๐ฆ where this page comes from
- opensuse-leap 16.0: llvm19 19.1.7-160000.2.2 ยท Apache-2.0 WITH LLVM-exception AND NCSA
- opensuse-leap 16.0: llvm19 19.1.7-160000.2.2 ยท Apache-2.0 WITH LLVM-exception AND NCSA
- opensuse-leap 16.0: llvm19 19.1.7-160000.2.2 ยท Apache-2.0 WITH LLVM-exception AND NCSA
- opensuse-leap 16.0: llvm19 19.1.7-160000.2.2 ยท Apache-2.0 WITH LLVM-exception AND NCSA
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms