How to objcopy via LLVM toolchain for armv7e-m ELF32LE?

Hi LLVM developers,

As PR35281 mentioned:

$ llvm-objcopy -O binary llvm-cortex-m7.elf llvm-cortex-m7.bin
llvm-objcopy: 'llvm-cortex-m7.elf': The file was not recognized as a valid object file.

if (ELFObjectFile<ELF64LE> *o = dyn_cast<ELFObjectFile<ELF64LE>>(&Binary)) llvm/llvm-objcopy.cpp at master · llvm-mirror/llvm · GitHub

Please give me some hints about objcopy armv7e-m ELF32LE via LLVM toolchain, thanks a lot!

Is it able to just workaround add ELF32LE?

diff --git a/tools/llvm-objcopy/llvm-objcopy.cpp b/tools/llvm-objcopy/llvm-objcopy.cpp
index 54186f6..3234c65 100644
--- a/tools/llvm-objcopy/llvm-objcopy.cpp
+++ b/tools/llvm-objcopy/llvm-objcopy.cpp
@@ -138,18 +138,19 @@ void SplitDWOToFile(const ELFObjectFile<ELFT> &ObjFile, StringRef File) {
WriteObjectFile(DWOFile, File);
}

-void CopyBinary(const ELFObjectFile<ELF64LE> &ObjFile) {
- std::unique_ptr<Object<ELF64LE>> Obj;
+template <class ELFT = ELF64LE>
+void CopyBinary(const ELFObjectFile<ELFT> &ObjFile) {
+ std::unique_ptr<Object<ELFT>> Obj;

if \(\!OutputFormat\.empty\(\) &amp;&amp; OutputFormat \!= &quot;binary&quot;\)
  error\(&quot;invalid output format &#39;&quot; \+ OutputFormat \+ &quot;&#39;&quot;\);
if \(\!OutputFormat\.empty\(\) &amp;&amp; OutputFormat == &quot;binary&quot;\)

- Obj = llvm::make_unique<BinaryObject<ELF64LE>>(ObjFile);
+ Obj = llvm::make_unique<BinaryObject<ELFT>>(ObjFile);
else
- Obj = llvm::make_unique<ELFObject<ELF64LE>>(ObjFile);
+ Obj = llvm::make_unique<ELFObject<ELFT>>(ObjFile);

if \(\!SplitDWO\.empty\(\)\)

- SplitDWOToFile<ELF64LE>(ObjFile, SplitDWO.getValue());
+ SplitDWOToFile<ELFT>(ObjFile, SplitDWO.getValue());

SectionPred RemovePred = \[\]\(const SectionBase &amp;\) \{ return false; \};

@@ -200,6 +201,9 @@ int main(int argc, char **argv) {
if (ELFObjectFile<ELF64LE> *o = dyn_cast<ELFObjectFile<ELF64LE>>(&Binary)) {
CopyBinary(*o);
return 0;
+ } else if (ELFObjectFile<ELF32LE> *o = dyn_cast<ELFObjectFile<ELF32LE>>(&Binary)) {
+ CopyBinary(*o);
+ return 0;
}
reportError(InputFilename, object_error::invalid_file_type);
}

Testcase: https://github.com/xiangzhai/mini-arm-os/tree/llvm-toolchain/00-HelloWorld

$ make
CC hello.c
CC startup.c
LD hello.elf
READ -> hello.rd
LIST -> hello.lst
COPY -> hello.bin
text data bss dec hex filename
190 14 0 204 cc hello.elf

$ make qemu
/data/project/qemu_stm32/arm-softmmu/qemu-system-arm -M stm32-p103 -nographic -kernel hello.bin

...
LED Off
Hello World!

Hi,

At the moment, we’ve only added support for 64-bit Little Endian ELF to llvm-objcopy, but I’m pretty sure most of the code should be able to handle 32-bit ELF as well, with a patch such as the one you’ve attached. Jake Ehrlich (CC’ed), who is the main developer on llvm-objcopy should be able to give you a more complete answer.

Regards,

James

Hi James,

Thanks for your kind response!

Jake has already provided the great patch https://reviews.llvm.org/D39977 The Flash Man :slight_smile: so quick response to cover ARMmbed usecase for armv7e-m!

Thanks again for your great job!