<div dir="ltr"><div>LLVM already implements its own version of almost all of binutils. The</div><div>exceptions to this rule are objcopy and strip. This is a proposal to implement</div><div>an llvm version of objcopy/strip to complete llvm’s binutils.</div><div><br></div><div>Several projects only use gnu binutils because of objcopy/strip. LLVM itself</div><div>uses objcopy in fact. Chromium and Fuchsia currently use objcopy as well. If you</div><div>want to distribute your build tools this is a problem due to licensing. It’s</div><div>also a bit of a blemish on LLVM because LLVM could be made more self sufficient</div><div>if there was an llvm version of objcopy. Additionally Chromium is one of the</div><div>popular benchmarks for LLVM so it would be nice if Chromium didn’t have to use</div><div>binutils. Using</div><div>[elftoolchain](<a href="https://sourceforge.net/p/elftoolchain/wiki/Home/">https://sourceforge.net/p/elftoolchain/wiki/Home/</a>)</div><div>solves the licensing issue for Fuchsia but is elf specific and only solves the</div><div>issue for Fuchsia. I propose implementing llvm-objcopy to be a minimum viable</div><div>replacement for objcopy.</div><div><br></div><div>I’ve gone though the sources of LLVM, Clang, Chromium, and Fuchsia to try and</div><div>find the major use cases of objcopy. Here is a list of use cases I have found</div><div>and which projects use them. This list includes some use cases not found in</div><div>these 4 projects.</div><div><br></div><div>1. Use Case: Stripping debug information of an executable to a file  </div><div>   Who uses it: LLVM, Fuchsia, Chromium</div><div><br></div><div>   ```sh</div><div>   objcopy --only-keep-debug foo foo.debug</div><div>   objcopy --strip-debug foo foo</div><div>   ```</div><div><br></div><div>   [Example use](<a href="https://github.com/llvm-mirror/llvm/blob/cd789d8cfe12aa374e66eafc748f4fc06e149ca7/cmake/modules/AddLLVM.cmake">https://github.com/llvm-mirror/llvm/blob/cd789d8cfe12aa374e66eafc748f4fc06e149ca7/cmake/modules/AddLLVM.cmake</a>)</div><div>   When it is useful:  </div><div>   This reduces the size of the file for distribution while maintaining the debug</div><div>   information in a file for later use. Anyone distributing an executable in</div><div>   anyway could benefit from this.</div><div><br></div><div>2. Use Case: Stripping debug information of a relocatable object to a file  </div><div>   Who uses it: None of the 4 projects considered</div><div><br></div><div>   ```sh</div><div>   objcopy --only-keep-debug foo.o foo.debug</div><div>   objcopy --strip-debug foo.o foo.o</div><div>   ```</div><div><br></div><div>   When it is useful:  </div><div>   In distribution of an SDK in the form of an archive it would be nice to strip</div><div>   this information. This allows debug information to be distributed separately.</div><div><br></div><div>3. Use Case: Stripping debug information of a shared library to a file  </div><div>   Who uses it: None of the 4 projects</div><div><br></div><div>   ```sh</div><div>   objcopy --only-keep-debug foo.so foo.debug</div><div>   objcopy --strip-debug foo.so foo.so</div><div>   ```</div><div><br></div><div>   When is it Useful:  </div><div>   Same benefits as the previous case. If you want to distribute a library this</div><div>   option allows you to distribute a smaller binary while maintaining the ability</div><div>   to debug.</div><div><br></div><div>4. Use Case:<span class="Apple-tab-span" style="white-space:pre">           </span>Stripping an executable</div><div>   Who uses it:<span class="Apple-tab-span" style="white-space:pre">             </span>None of the 4 projects</div><div><br></div><div>   ```sh</div><div>   objcopy --strip-all foo foo</div><div>   ```</div><div><br></div><div>   When is it useful:  </div><div>   Anytime an executable is being distributed and there is no reason to keep</div><div>   debugging information. This makes the executable smaller than simply</div><div>   stripping debug info and doesn't produce an extra file.</div><div><br></div><div>5. Use Case: “Complete stripping” an executable  </div><div>   Who uses it: None of the 4 projects</div><div>   ```sh</div><div>   eu-strip --strip-sections foo</div><div>   ```</div><div>   When is it useful:  </div><div>   This is an extreme form of stripping that even strips the section headers</div><div>   since they are not needed for loading. This is useful in the same contexts as</div><div>   stripping but some tools and dynamic linkers may be confused by it. This is</div><div>   possibly only valid on ELF unlike general stripping which is a valid option on</div><div>   multiple platforms.</div><div><br></div><div>6. Use Case: DWARF fission  </div><div>   Who uses it: Clang, Fuchsia, Chromium</div><div><br></div><div>   ```sh</div><div>   objcopy --extract-dwo foo foo.debug</div><div>   objcopy --strip-dwo foo foo</div><div>   ```</div><div><br></div><div>   [Example use  1](<a href="https://github.com/llvm-mirror/clang/blob/3efd04e48004628cfaffead00ecb1c206b0b6cb2/lib/Driver/ToolChains/CommonArgs.cpp">https://github.com/llvm-mirror/clang/blob/3efd04e48004628cfaffead00ecb1c206b0b6cb2/lib/Driver/ToolChains/CommonArgs.cpp</a>)</div><div>   [Example use 2](<a href="https://github.com/llvm-mirror/clang/blob/a0badfbffbee71c2c757d580fc852d2124dadc5a/test/Driver/split-debug.s">https://github.com/llvm-mirror/clang/blob/a0badfbffbee71c2c757d580fc852d2124dadc5a/test/Driver/split-debug.s</a>)</div><div><br></div><div>   When is it useful:  </div><div>   DWARF fission can be used to speed up large builds. In some cases builds can</div><div>   be too large to be handled and DWARF fission makes this manageable. DWARF</div><div>   fission is useful in almost any project of sufficient size.</div><div><br></div><div>7. Use Case: Converting an executable to binary  </div><div>   Who uses it: Fuchsia</div><div><br></div><div>   ```sh</div><div>   objcopy -O binary magenta.elf magenta.bin</div><div>   ```</div><div><br></div><div>   [Example use](<a href="https://fuchsia.googlesource.com/magenta/+/master/make/build.mk#20">https://fuchsia.googlesource.com/magenta/+/master/make/build.mk#20</a>)</div><div><br></div><div>   When is it useful:  </div><div>   For kernels and embedded applications that need just the raw segments.</div><div><br></div><div>8. Use Case: Adding a gdb index  </div><div>   Who uses it: Chromium</div><div><br></div><div>   ```sh</div><div>   gdb -batch foo -ex "save gdb-index dir" -ex quit</div><div>   objcopy --add-section .gdb_index="dir/foo.gdb-index" \</div><div>           --set-section-flags .gdb_index=readonly foo foo</div><div>   ```</div><div><br></div><div>   [Example use](<a href="https://cs.chromium.org/chromium/src/build/gdb-add-index?type=cs&q=objcopy&l=71">https://cs.chromium.org/chromium/src/build/gdb-add-index?type=cs&q=objcopy&l=71</a>)</div><div><br></div><div>   When is it useful:  </div><div>   Adding a gdb index reduces startup time for debugging an application. Any</div><div>   sufficiently large program with a sufficiently large amount of debug</div><div>   information can potentially benefit from this.</div><div><br></div><div>9. Use Case: Converting between formats  </div><div>   Who uses it: Fuchsia (only in Magenta GCC build)</div><div><br></div><div>   ```sh</div><div>   objcopy --target=pei-x86-64 magenta.elf <a href="http://megenta.pe">megenta.pe</a></div><div>   ```</div><div><br></div><div>   [Example use](<a href="https://fuchsia.googlesource.com/magenta/+/master/bootloader/build.mk#97">https://fuchsia.googlesource.com/magenta/+/master/bootloader/build.mk#97</a>)</div><div><br></div><div>   When is it useful:  </div><div>   This is primarily useful when you can’t directly target a needed format.</div><div><br></div><div>10. Use Case: Removing symbols not needed for relocation  </div><div>    Who uses it: Chromium</div><div><br></div><div>    ```sh</div><div>    objcopy --strip-unneeded foo foo</div><div>    ```</div><div><br></div><div>    [Example use](<a href="https://cs.chromium.org/chromium/src/third_party/libevdev/src/common.mk?type=cs&q=objcopy&l=397">https://cs.chromium.org/chromium/src/third_party/libevdev/src/common.mk?type=cs&q=objcopy&l=397</a>)</div><div><br></div><div>    When is it useful:  </div><div>    This is useful when shipping an SDK or some relocatable binaries.</div><div><br></div><div>11. Use Case: Removing local symbols  </div><div>    Who uses it: LLVM</div><div><br></div><div>    ```sh</div><div>    objcopy --discard-all foo foo</div><div>    ```</div><div><br></div><div>    [Example use](<a href="https://github.com/llvm-mirror/llvm/blob/cd789d8cfe12aa374e66eafc748f4fc06e149ca7/cmake/modules/AddLLVM.cmake">https://github.com/llvm-mirror/llvm/blob/cd789d8cfe12aa374e66eafc748f4fc06e149ca7/cmake/modules/AddLLVM.cmake</a>)</div><div>    (hidden in definition of “strip_command” using strip instead of objcopy and</div><div>    using -x instead of --discard-all)</div><div><br></div><div>    When is it useful:  </div><div>    Anytime you don’t need locals for debugging this can be useful.</div><div><br></div><div>12. Use Case: Removing a specific unwanted section  </div><div>    Who uses it: LLVM</div><div><br></div><div>    ```sh</div><div>    objcopy --remove-section=.debug_aranges foo foo</div><div>    ```</div><div><br></div><div>    [Example use](<a href="https://github.com/llvm-mirror/llvm/blob/93e6e5414ded14bcbb233baaaa5567132fee9a0c/test/DebugInfo/Inputs/fission-ranges.cc">https://github.com/llvm-mirror/llvm/blob/93e6e5414ded14bcbb233baaaa5567132fee9a0c/test/DebugInfo/Inputs/fission-ranges.cc</a>)</div><div><br></div><div>    When is it useful:</div><div>    This is useful when you know that you have an unwanted section that isn’t</div><div>    removed by one of the other stripping options. This can also be used to</div><div>    remove an existing section for replacement by a new section.</div><div><br></div><div>We would like to build this up incrementally by solving specific use cases</div><div>as they come up. To start with we would like to tackle the use cases</div><div>important to us. We primarily care about fully linked executables and not</div><div>relocatable files. I plan to implement conversion from ELF to binary first.</div><div>After that I plan on implementing stripping for ELF executables.</div><div><br></div></div>