summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-objcopy/llvm-objcopy.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/tools/llvm-objcopy/llvm-objcopy.cpp')
-rw-r--r--llvm/tools/llvm-objcopy/llvm-objcopy.cpp88
1 files changed, 65 insertions, 23 deletions
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);
}
OpenPOWER on IntegriCloud