objcopy: Usage, Options & Common CI Errors
objcopy rewrites object files: split debug info, change formats, or embed data.
objcopy is the companion to strip. The headline CI use is the split-debug workflow - keep a small stripped binary to ship and a separate .debug file to symbolize crashes - plus turning ELF into raw firmware images.
What it does
objcopy copies an object file to another, optionally transforming it: extracting debug info, stripping, converting output format (-O), adding or removing sections, and embedding files as data sections. It is the general-purpose binary transformer of binutils.
Common usage
objcopy --only-keep-debug app app.debug
objcopy --strip-debug app
objcopy --add-gnu-debuglink=app.debug app
objcopy -O binary firmware.elf firmware.bin # raw image
objcopy --add-section .note=note.bin app app2Options
| Flag | What it does |
|---|---|
| --only-keep-debug | Output just the debug sections |
| --strip-debug / --strip-all | Remove debug / all symbols |
| --add-gnu-debuglink=<file> | Link a binary to its debug file |
| -O binary | Emit a raw binary (firmware image) |
| --add-section name=file | Embed file as a new section |
Common errors in CI
The split-debug ordering matters: run --only-keep-debug to create app.debug BEFORE stripping, then --add-gnu-debuglink so the debugger can find it. "objcopy: app: Bad value" usually means an option targeting a section/format the file does not have. When converting ELF to a flat image with -O binary, the output has no headers - sizes/addresses come from the section layout, so a wrong linker script produces a bloated or gapped .bin.