[llvm] r345217 - [llvm-objcopy] Introduce dispatch mechanism based on the input
Alexander Shaposhnikov via llvm-commits
llvm-commits at lists.llvm.org
Wed Oct 24 15:49:06 PDT 2018
Author: alexshap
Date: Wed Oct 24 15:49:06 2018
New Revision: 345217
URL: http://llvm.org/viewvc/llvm-project?rev=345217&view=rev
Log:
[llvm-objcopy] Introduce dispatch mechanism based on the input
In this diff we introduce dispatch mechanism based on
the type of the input (archive, object file, raw binary)
and the format (coff, elf, macho).
We also move the ELF-specific code into the namespace llvm::objcopy::elf.
Test plan: make check-all
Differential revision: https://reviews.llvm.org/D53311
Modified:
llvm/trunk/tools/llvm-objcopy/Object.cpp
llvm/trunk/tools/llvm-objcopy/Object.h
llvm/trunk/tools/llvm-objcopy/llvm-objcopy.cpp
Modified: llvm/trunk/tools/llvm-objcopy/Object.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/Object.cpp?rev=345217&r1=345216&r2=345217&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objcopy/Object.cpp (original)
+++ llvm/trunk/tools/llvm-objcopy/Object.cpp Wed Oct 24 15:49:06 2018
@@ -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<ELF
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
Modified: llvm/trunk/tools/llvm-objcopy/Object.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/Object.h?rev=345217&r1=345216&r2=345217&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objcopy/Object.h (original)
+++ llvm/trunk/tools/llvm-objcopy/Object.h Wed Oct 24 15:49:06 2018
@@ -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
Modified: llvm/trunk/tools/llvm-objcopy/llvm-objcopy.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/llvm-objcopy.cpp?rev=345217&r1=345216&r2=345217&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objcopy/llvm-objcopy.cpp (original)
+++ llvm/trunk/tools/llvm-objcopy/llvm-objcopy.cpp Wed Oct 24 15:49:06 2018
@@ -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
} // 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
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
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(c
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
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 Copy
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 Copy
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);
}
More information about the llvm-commits
mailing list