diff options
Diffstat (limited to 'llvm/tools/llvm-objcopy')
-rw-r--r-- | llvm/tools/llvm-objcopy/Object.cpp | 15 | ||||
-rw-r--r-- | llvm/tools/llvm-objcopy/Object.h | 3 | ||||
-rw-r--r-- | llvm/tools/llvm-objcopy/llvm-objcopy.cpp | 88 |
3 files changed, 77 insertions, 29 deletions
diff --git a/llvm/tools/llvm-objcopy/Object.cpp b/llvm/tools/llvm-objcopy/Object.cpp index d677579ea23..5b2138436d5 100644 --- a/llvm/tools/llvm-objcopy/Object.cpp +++ b/llvm/tools/llvm-objcopy/Object.cpp @@ -28,8 +28,10 @@ #include <utility> #include <vector> -using namespace llvm; -using namespace llvm::objcopy; +namespace llvm { +namespace objcopy { +namespace elf { + using namespace object; using namespace ELF; @@ -1165,7 +1167,9 @@ template <class ELFT> void ELFWriter<ELFT>::writeEhdr() { Ehdr.e_machine = Obj.Machine; Ehdr.e_version = Obj.Version; Ehdr.e_entry = Obj.Entry; - Ehdr.e_phnum = size(Obj.segments()); + // We have to use the fully-qualified name llvm::size + // since some compilers complain on ambiguous resolution. + Ehdr.e_phnum = llvm::size(Obj.segments()); Ehdr.e_phoff = (Ehdr.e_phnum != 0) ? Obj.ProgramHdrSegment.Offset : 0; Ehdr.e_phentsize = (Ehdr.e_phnum != 0) ? sizeof(Elf_Phdr) : 0; Ehdr.e_flags = Obj.Flags; @@ -1597,9 +1601,6 @@ void BinaryWriter::finalize() { SecWriter = llvm::make_unique<BinarySectionWriter>(Buf); } -namespace llvm { -namespace objcopy { - template class BinaryELFBuilder<ELF64LE>; template class BinaryELFBuilder<ELF64BE>; template class BinaryELFBuilder<ELF32LE>; @@ -1614,5 +1615,7 @@ template class ELFWriter<ELF64LE>; template class ELFWriter<ELF64BE>; template class ELFWriter<ELF32LE>; template class ELFWriter<ELF32BE>; + +} // end namespace elf } // end namespace objcopy } // end namespace llvm diff --git a/llvm/tools/llvm-objcopy/Object.h b/llvm/tools/llvm-objcopy/Object.h index 1019391fa89..38ef21ffec9 100644 --- a/llvm/tools/llvm-objcopy/Object.h +++ b/llvm/tools/llvm-objcopy/Object.h @@ -30,6 +30,7 @@ namespace llvm { enum class DebugCompressionType; namespace objcopy { +namespace elf { class SectionBase; class Section; @@ -765,6 +766,8 @@ public: return *Segments.back(); } }; + +} // end namespace elf } // end namespace objcopy } // end namespace llvm diff --git a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp index b7dbf6c66b3..b7e2361cc01 100644 --- a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp +++ b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp @@ -53,13 +53,6 @@ #include <system_error> #include <utility> -using namespace llvm; -using namespace llvm::objcopy; -using namespace object; -using namespace ELF; - -using SectionPred = std::function<bool(const SectionBase &Sec)>; - namespace llvm { namespace objcopy { @@ -92,6 +85,16 @@ LLVM_ATTRIBUTE_NORETURN void reportError(StringRef File, Error E) { } // end namespace objcopy } // end namespace llvm +// TODO: move everything enclosed in the namespace llvm::objcopy::elf +// into separate header+cpp files. +namespace llvm { +namespace objcopy { +namespace elf { + +using namespace object; +using namespace ELF; +using SectionPred = std::function<bool(const SectionBase &Sec)>; + static bool isDebugSection(const SectionBase &Sec) { return StringRef(Sec.Name).startswith(".debug") || StringRef(Sec.Name).startswith(".zdebug") || Sec.Name == ".gdb_index"; @@ -513,18 +516,39 @@ static void handleArgs(const CopyConfig &Config, Object &Obj, Obj.addSection<GnuDebugLinkSection>(Config.AddGnuDebugLink); } -static void executeElfObjcopyOnBinary(const CopyConfig &Config, Reader &Reader, - Buffer &Out, ElfType OutputElfType) { +void executeObjcopyOnRawBinary(const CopyConfig &Config, MemoryBuffer &In, + Buffer &Out) { + BinaryReader Reader(Config.BinaryArch, &In); std::unique_ptr<Object> Obj = Reader.create(); + const ElfType OutputElfType = getOutputElfType(Config.BinaryArch); handleArgs(Config, *Obj, Reader, OutputElfType); + std::unique_ptr<Writer> Writer = + createWriter(Config, *Obj, Out, OutputElfType); + Writer->finalize(); + Writer->write(); +} +void executeObjcopyOnBinary(const CopyConfig &Config, + object::ELFObjectFileBase &In, Buffer &Out) { + ELFReader Reader(&In); + std::unique_ptr<Object> Obj = Reader.create(); + const ElfType OutputElfType = getOutputElfType(In); + handleArgs(Config, *Obj, Reader, OutputElfType); std::unique_ptr<Writer> Writer = createWriter(Config, *Obj, Out, OutputElfType); Writer->finalize(); Writer->write(); } +} // end namespace elf +} // end namespace objcopy +} // end namespace llvm + +using namespace llvm; +using namespace llvm::object; +using namespace llvm::objcopy; + // For regular archives this function simply calls llvm::writeArchive, // For thin archives it writes the archive file itself as well as its members. static Error deepWriteArchive(StringRef ArcName, @@ -554,8 +578,29 @@ static Error deepWriteArchive(StringRef ArcName, return Error::success(); } -static void executeElfObjcopyOnArchive(const CopyConfig &Config, - const Archive &Ar) { +/// The function executeObjcopyOnRawBinary does the dispatch based on the format +/// of the output specified by the command line options. +static void executeObjcopyOnRawBinary(const CopyConfig &Config, + MemoryBuffer &In, Buffer &Out) { + // TODO: llvm-objcopy should parse CopyConfig.OutputFormat to recognize + // formats other than ELF / "binary" and invoke + // elf::executeObjcopyOnRawBinary, macho::executeObjcopyOnRawBinary or + // coff::executeObjcopyOnRawBinary accordingly. + return elf::executeObjcopyOnRawBinary(Config, In, Out); +} + +/// The function executeObjcopyOnBinary does the dispatch based on the format +/// of the input binary (ELF, MachO or COFF). +static void executeObjcopyOnBinary(const CopyConfig &Config, object::Binary &In, + Buffer &Out) { + if (auto *ELFBinary = dyn_cast<object::ELFObjectFileBase>(&In)) + return elf::executeObjcopyOnBinary(Config, *ELFBinary, Out); + else + error("Unsupported object file format"); +} + +static void executeObjcopyOnArchive(const CopyConfig &Config, + const Archive &Ar) { std::vector<NewArchiveMember> NewArchiveMembers; Error Err = Error::success(); for (const Archive::Child &Child : Ar.children(Err)) { @@ -569,8 +614,7 @@ static void executeElfObjcopyOnArchive(const CopyConfig &Config, reportError(Ar.getFileName(), ChildNameOrErr.takeError()); MemBuffer MB(ChildNameOrErr.get()); - ELFReader Reader(Bin); - executeElfObjcopyOnBinary(Config, Reader, MB, getOutputElfType(*Bin)); + executeObjcopyOnBinary(Config, *Bin, MB); Expected<NewArchiveMember> Member = NewArchiveMember::getOldMember(Child, true); @@ -605,7 +649,10 @@ static void restoreDateOnFile(StringRef Filename, reportError(Filename, EC); } -static void executeElfObjcopy(const CopyConfig &Config) { +/// The function executeObjcopy does the higher level dispatch based on the type +/// of input (raw binary, archive or single object file) and takes care of the +/// format-agnostic modifications, i.e. preserving dates. +static void executeObjcopy(const CopyConfig &Config) { sys::fs::file_status Stat; if (Config.PreserveDates) if (auto EC = sys::fs::status(Config.InputFilename, Stat)) @@ -615,11 +662,8 @@ static void executeElfObjcopy(const CopyConfig &Config) { auto BufOrErr = MemoryBuffer::getFile(Config.InputFilename); if (!BufOrErr) reportError(Config.InputFilename, BufOrErr.getError()); - FileBuffer FB(Config.OutputFilename); - BinaryReader Reader(Config.BinaryArch, BufOrErr->get()); - executeElfObjcopyOnBinary(Config, Reader, FB, - getOutputElfType(Config.BinaryArch)); + executeObjcopyOnRawBinary(Config, *BufOrErr->get(), FB); } else { Expected<OwningBinary<llvm::object::Binary>> BinaryOrErr = createBinary(Config.InputFilename); @@ -627,12 +671,10 @@ static void executeElfObjcopy(const CopyConfig &Config) { reportError(Config.InputFilename, BinaryOrErr.takeError()); if (Archive *Ar = dyn_cast<Archive>(BinaryOrErr.get().getBinary())) { - executeElfObjcopyOnArchive(Config, *Ar); + executeObjcopyOnArchive(Config, *Ar); } else { FileBuffer FB(Config.OutputFilename); - Binary *Bin = BinaryOrErr.get().getBinary(); - ELFReader Reader(Bin); - executeElfObjcopyOnBinary(Config, Reader, FB, getOutputElfType(*Bin)); + executeObjcopyOnBinary(Config, *BinaryOrErr.get().getBinary(), FB); } } @@ -652,5 +694,5 @@ int main(int argc, char **argv) { else DriverConfig = parseObjcopyOptions(makeArrayRef(argv + 1, argc)); for (const CopyConfig &CopyConfig : DriverConfig.CopyConfigs) - executeElfObjcopy(CopyConfig); + executeObjcopy(CopyConfig); } |