$npx -y skills add mohitmishra786/low-level-dev-skills --skill binutilsGNU binutils skill for binary manipulation and analysis. Use when using ar for static libraries, strip or objcopy for binary processing, addr2line for converting addresses to source locations, strings for text extraction, or c++filt for C++ name demangling. Activates on queries a
| 1 | # GNU Binutils |
| 2 | |
| 3 | ## Purpose |
| 4 | |
| 5 | Guide agents through the binutils toolset for binary manipulation: static libraries, stripping, address-to-source mapping, and symbol demangling. |
| 6 | |
| 7 | ## Triggers |
| 8 | |
| 9 | - "How do I create a static library?" |
| 10 | - "How do I strip a binary but keep a debug file?" |
| 11 | - "I have an address from a crash — how do I find the source line?" |
| 12 | - "How do I demangle a C++ symbol name?" |
| 13 | - "How do I extract/replace sections in a binary?" |
| 14 | |
| 15 | ## Workflow |
| 16 | |
| 17 | ### 1. `ar` — static library management |
| 18 | |
| 19 | ```bash |
| 20 | # Create static library |
| 21 | ar rcs libfoo.a foo.o bar.o baz.o |
| 22 | |
| 23 | # List contents |
| 24 | ar t libfoo.a |
| 25 | |
| 26 | # Extract an object |
| 27 | ar x libfoo.a foo.o |
| 28 | |
| 29 | # Add/replace an object |
| 30 | ar r libfoo.a newbar.o |
| 31 | |
| 32 | # Delete an object |
| 33 | ar d libfoo.a oldbar.o |
| 34 | |
| 35 | # Show symbol index |
| 36 | nm libfoo.a |
| 37 | |
| 38 | # Rebuild symbol index (after modifying archive externally) |
| 39 | ranlib libfoo.a |
| 40 | ``` |
| 41 | |
| 42 | For LTO archives: use `gcc-ar`/`gcc-ranlib` or `llvm-ar` instead of plain `ar`. |
| 43 | |
| 44 | ### 2. `strip` — remove debug info |
| 45 | |
| 46 | ```bash |
| 47 | # Strip all debug info (reduce binary size) |
| 48 | strip --strip-all prog |
| 49 | |
| 50 | # Strip only debug sections (keep symbol table) |
| 51 | strip --strip-debug prog |
| 52 | |
| 53 | # Strip unneeded symbols (keep needed for linking) |
| 54 | strip --strip-unneeded prog |
| 55 | |
| 56 | # In-place |
| 57 | strip prog |
| 58 | |
| 59 | # To a new file |
| 60 | strip -o prog.stripped prog |
| 61 | ``` |
| 62 | |
| 63 | ### 3. `objcopy` — binary section manipulation |
| 64 | |
| 65 | ```bash |
| 66 | # Separate debug info from binary |
| 67 | objcopy --only-keep-debug prog prog.debug |
| 68 | objcopy --strip-debug prog |
| 69 | |
| 70 | # Add debuglink (GDB finds prog.debug automatically) |
| 71 | objcopy --add-gnu-debuglink=prog.debug prog |
| 72 | |
| 73 | # Convert binary to another format |
| 74 | objcopy -O binary prog prog.bin # raw binary (embedded) |
| 75 | objcopy -O srec prog prog.srec # Motorola S-record |
| 76 | |
| 77 | # Add a section from a file |
| 78 | objcopy --add-section .resources=data.bin prog |
| 79 | |
| 80 | # Remove a section |
| 81 | objcopy --remove-section .comment prog |
| 82 | |
| 83 | # Change section flags |
| 84 | objcopy --set-section-flags .data=alloc,contents,load,readonly prog |
| 85 | |
| 86 | # Embed a binary file as a symbol |
| 87 | objcopy -I binary -O elf64-x86-64 \ |
| 88 | --rename-section .data=.rodata,alloc,load,readonly,data,contents \ |
| 89 | data.bin data.o |
| 90 | # Then link data.o; access via _binary_data_bin_start / _binary_data_bin_end |
| 91 | ``` |
| 92 | |
| 93 | ### 4. `addr2line` — address to source |
| 94 | |
| 95 | ```bash |
| 96 | # Convert a crash address to source:line |
| 97 | addr2line -e prog -f 0x400a12 |
| 98 | # Output: |
| 99 | # my_function |
| 100 | # /home/user/src/main.c:42 |
| 101 | |
| 102 | # Multiple addresses |
| 103 | addr2line -e prog -f 0x400a12 0x400b34 0x400c56 |
| 104 | |
| 105 | # Inline frames (-i) |
| 106 | addr2line -e prog -f -i 0x400a12 |
| 107 | |
| 108 | # Common use: pipe from backtrace output |
| 109 | cat crash.log | grep '0x[0-9a-f]' | grep -o '0x[0-9a-f]*' | \ |
| 110 | addr2line -e prog -f -i |
| 111 | ``` |
| 112 | |
| 113 | Requires the binary to have debug info (compiled with `-g`). For stripped binaries, use the unstripped version or a `.debug` file. |
| 114 | |
| 115 | ### 5. `c++filt` — demangle C++ symbols |
| 116 | |
| 117 | ```bash |
| 118 | # Demangle a single symbol |
| 119 | c++filt _ZN3foo3barEv |
| 120 | # Output: foo::bar() |
| 121 | |
| 122 | # Demangle from nm output |
| 123 | nm prog | c++filt |
| 124 | |
| 125 | # Demangle from crash log |
| 126 | cat crash.log | c++filt |
| 127 | ``` |
| 128 | |
| 129 | Alternative: `nm -C prog` (demangle directly in nm). |
| 130 | |
| 131 | ### 6. `strings` — extract printable strings |
| 132 | |
| 133 | ```bash |
| 134 | strings prog # all strings >= 4 chars |
| 135 | strings -n 8 prog # minimum length 8 |
| 136 | strings -t x prog # with offset (hex) |
| 137 | strings -t d prog # with offset (decimal) |
| 138 | |
| 139 | # Search for specific strings |
| 140 | strings prog | grep "version" |
| 141 | strings prog | grep "Copyright" |
| 142 | ``` |
| 143 | |
| 144 | ### 7. `readelf` and `objdump` quick reference |
| 145 | |
| 146 | (Full coverage in `skills/binaries/elf-inspection`) |
| 147 | |
| 148 | ```bash |
| 149 | # Symbol lookup for crash address (alternative to addr2line) |
| 150 | objdump -d -M intel prog | grep -A5 "400a12:" |
| 151 | |
| 152 | # Find which object file defines a symbol |
| 153 | objdump -t prog | grep my_function |
| 154 | ``` |
| 155 | |
| 156 | ### 8. Cross-binutils |
| 157 | |
| 158 | For cross-compilation, use the target-prefixed versions: |
| 159 | |
| 160 | ```bash |
| 161 | aarch64-linux-gnu-strip prog |
| 162 | aarch64-linux-gnu-objcopy --only-keep-debug prog prog.debug |
| 163 | aarch64-linux-gnu-addr2line -e prog 0x400a12 |
| 164 | arm-none-eabi-nm libfirmware.a |
| 165 | ``` |
| 166 | |
| 167 | For a complete command cheatsheet covering all tools (ar, strip, objcopy, addr2line, strings, c++filt), see [references/cheatsheet.md](references/cheatsheet.md). |
| 168 | |
| 169 | ## Related skills |
| 170 | |
| 171 | - Use `skills/binaries/elf-inspection` for `readelf`, `nm`, `ldd`, `objdump` inspection |
| 172 | - Use `skills/binaries/linkers-lto` for linker flags and LTO |
| 173 | - Use `skills/debuggers/core-dumps` for debug file management with `objcopy --add-gnu-debuglink` |