Skip to content

Commit

Permalink
[llvm-objcopy] Support the rest of the ELF formats
Browse files Browse the repository at this point in the history
We haven't been supporting anything but ELF64LE since the start. Luckily
this was always accounted for and the change is pretty trivial. B35281
requests this change for ELF32LE. This change adds support for ELF32LE,
ELF64BE, and ELF32BE with all supported features that already existed
for ELF64LE.

Differential Revision: https://reviews.llvm.org/D39977

llvm-svn: 318166
  • Loading branch information
jakehehrlich committed Nov 14, 2017
1 parent b8a11bb commit 99e2c41
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 6 deletions.
28 changes: 28 additions & 0 deletions llvm/test/tools/llvm-objcopy/elf32be.test
@@ -0,0 +1,28 @@
# RUN: yaml2obj %s > %t
# RUN: llvm-objcopy %t %t2
# RUN: llvm-readobj -file-headers -sections %t2 | FileCheck %s

!ELF
FileHeader:
Class: ELFCLASS32
Data: ELFDATA2MSB
Type: ET_EXEC
Machine: EM_X86_64
Sections:
- Name: .bss
Type: SHT_NOBITS
Flags: [ SHF_ALLOC ]
AddressAlign: 0x0000000000000010
Size: 64
- Name: .text
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
AddressAlign: 0x0000000000000010
Content: "00000000"

# CHECK: Class: 32-bit
# CHECK: DataEncoding: BigEndian

# CHECK: Name: .bss
# CHECK: Name: .text
# CHECK: Name: .shstrtab
28 changes: 28 additions & 0 deletions llvm/test/tools/llvm-objcopy/elf32le.test
@@ -0,0 +1,28 @@
# RUN: yaml2obj %s > %t
# RUN: llvm-objcopy %t %t2
# RUN: llvm-readobj -file-headers -sections %t2 | FileCheck %s

!ELF
FileHeader:
Class: ELFCLASS32
Data: ELFDATA2LSB
Type: ET_EXEC
Machine: EM_X86_64
Sections:
- Name: .bss
Type: SHT_NOBITS
Flags: [ SHF_ALLOC ]
AddressAlign: 0x0000000000000010
Size: 64
- Name: .text
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
AddressAlign: 0x0000000000000010
Content: "00000000"

# CHECK: Class: 32-bit
# CHECK: DataEncoding: LittleEndian

# CHECK: Name: .bss
# CHECK: Name: .text
# CHECK: Name: .shstrtab
28 changes: 28 additions & 0 deletions llvm/test/tools/llvm-objcopy/elf64be.test
@@ -0,0 +1,28 @@
# RUN: yaml2obj %s > %t
# RUN: llvm-objcopy %t %t2
# RUN: llvm-readobj -file-headers -sections %t2 | FileCheck %s

!ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2MSB
Type: ET_EXEC
Machine: EM_X86_64
Sections:
- Name: .bss
Type: SHT_NOBITS
Flags: [ SHF_ALLOC ]
AddressAlign: 0x0000000000000010
Size: 64
- Name: .text
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
AddressAlign: 0x0000000000000010
Content: "00000000"

# CHECK: Class: 64-bit
# CHECK: DataEncoding: BigEndian

# CHECK: Name: .bss
# CHECK: Name: .text
# CHECK: Name: .shstrtab
25 changes: 19 additions & 6 deletions llvm/tools/llvm-objcopy/llvm-objcopy.cpp
Expand Up @@ -142,18 +142,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>
void CopyBinary(const ELFObjectFile<ELFT> &ObjFile) {
std::unique_ptr<Object<ELFT>> Obj;

if (!OutputFormat.empty() && OutputFormat != "binary")
error("invalid output format '" + OutputFormat + "'");
if (!OutputFormat.empty() && OutputFormat == "binary")
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 &) { return false; };

Expand Down Expand Up @@ -225,7 +226,19 @@ int main(int argc, char **argv) {
if (!BinaryOrErr)
reportError(InputFilename, BinaryOrErr.takeError());
Binary &Binary = *BinaryOrErr.get().getBinary();
if (ELFObjectFile<ELF64LE> *o = dyn_cast<ELFObjectFile<ELF64LE>>(&Binary)) {
if (auto *o = dyn_cast<ELFObjectFile<ELF64LE>>(&Binary)) {
CopyBinary(*o);
return 0;
}
if (auto *o = dyn_cast<ELFObjectFile<ELF32LE>>(&Binary)) {
CopyBinary(*o);
return 0;
}
if (auto *o = dyn_cast<ELFObjectFile<ELF64BE>>(&Binary)) {
CopyBinary(*o);
return 0;
}
if (auto *o = dyn_cast<ELFObjectFile<ELF32BE>>(&Binary)) {
CopyBinary(*o);
return 0;
}
Expand Down

0 comments on commit 99e2c41

Please sign in to comment.