summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp')
-rw-r--r--llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp27
1 files changed, 27 insertions, 0 deletions
diff --git a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
index 9ed965cc941..9087cf63459 100644
--- a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
+++ b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
@@ -17,6 +17,7 @@
#include "llvm/Object/Binary.h"
#include "llvm/Object/COFF.h"
+#include "llvm/Support/Errc.h"
#include <cassert>
namespace llvm {
@@ -26,6 +27,30 @@ namespace coff {
using namespace object;
using namespace COFF;
+static Error handleArgs(const CopyConfig &Config, Object &Obj) {
+ // If we need to do per-symbol removals, initialize the Referenced field.
+ if (!Config.SymbolsToRemove.empty())
+ if (Error E = Obj.markSymbols())
+ return E;
+
+ // Actually do removals of symbols.
+ Obj.removeSymbols([&](const Symbol &Sym) {
+ if (is_contained(Config.SymbolsToRemove, Sym.Name)) {
+ // Explicitly removing a referenced symbol is an error.
+ if (Sym.Referenced)
+ reportError(Config.OutputFilename,
+ make_error<StringError>(
+ "not stripping symbol '" + Sym.Name +
+ "' because it is named in a relocation.",
+ llvm::errc::invalid_argument));
+ return true;
+ }
+
+ return false;
+ });
+ return Error::success();
+}
+
void executeObjcopyOnBinary(const CopyConfig &Config,
object::COFFObjectFile &In, Buffer &Out) {
COFFReader Reader(In);
@@ -34,6 +59,8 @@ void executeObjcopyOnBinary(const CopyConfig &Config,
reportError(Config.InputFilename, ObjOrErr.takeError());
Object *Obj = ObjOrErr->get();
assert(Obj && "Unable to deserialize COFF object");
+ if (Error E = handleArgs(Config, *Obj))
+ reportError(Config.InputFilename, std::move(E));
COFFWriter Writer(*Obj, Out);
if (Error E = Writer.write())
reportError(Config.OutputFilename, std::move(E));
OpenPOWER on IntegriCloud