blob: 9087cf63459eea3ee856f3ee920a214b48f446eb [file] [log] [blame]
Martin Storsjoe84a0b52018-12-19 07:24:38 +00001//===- COFFObjcopy.cpp ----------------------------------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "COFFObjcopy.h"
11#include "Buffer.h"
12#include "CopyConfig.h"
13#include "Object.h"
14#include "Reader.h"
15#include "Writer.h"
16#include "llvm-objcopy.h"
17
18#include "llvm/Object/Binary.h"
19#include "llvm/Object/COFF.h"
Martin Storsjo10b72962019-01-10 21:28:24 +000020#include "llvm/Support/Errc.h"
Martin Storsjoe84a0b52018-12-19 07:24:38 +000021#include <cassert>
22
23namespace llvm {
24namespace objcopy {
25namespace coff {
26
27using namespace object;
28using namespace COFF;
29
Martin Storsjo10b72962019-01-10 21:28:24 +000030static Error handleArgs(const CopyConfig &Config, Object &Obj) {
31 // If we need to do per-symbol removals, initialize the Referenced field.
32 if (!Config.SymbolsToRemove.empty())
33 if (Error E = Obj.markSymbols())
34 return E;
35
36 // Actually do removals of symbols.
37 Obj.removeSymbols([&](const Symbol &Sym) {
38 if (is_contained(Config.SymbolsToRemove, Sym.Name)) {
39 // Explicitly removing a referenced symbol is an error.
40 if (Sym.Referenced)
41 reportError(Config.OutputFilename,
42 make_error<StringError>(
43 "not stripping symbol '" + Sym.Name +
44 "' because it is named in a relocation.",
45 llvm::errc::invalid_argument));
46 return true;
47 }
48
49 return false;
50 });
51 return Error::success();
52}
53
Martin Storsjoe84a0b52018-12-19 07:24:38 +000054void executeObjcopyOnBinary(const CopyConfig &Config,
55 object::COFFObjectFile &In, Buffer &Out) {
56 COFFReader Reader(In);
Martin Storsjo0a5d5b12018-12-30 20:35:43 +000057 Expected<std::unique_ptr<Object>> ObjOrErr = Reader.create();
58 if (!ObjOrErr)
59 reportError(Config.InputFilename, ObjOrErr.takeError());
60 Object *Obj = ObjOrErr->get();
Martin Storsjoe84a0b52018-12-19 07:24:38 +000061 assert(Obj && "Unable to deserialize COFF object");
Martin Storsjo10b72962019-01-10 21:28:24 +000062 if (Error E = handleArgs(Config, *Obj))
63 reportError(Config.InputFilename, std::move(E));
Martin Storsjoe84a0b52018-12-19 07:24:38 +000064 COFFWriter Writer(*Obj, Out);
Martin Storsjo0a5d5b12018-12-30 20:35:43 +000065 if (Error E = Writer.write())
66 reportError(Config.OutputFilename, std::move(E));
Martin Storsjoe84a0b52018-12-19 07:24:38 +000067}
68
69} // end namespace coff
70} // end namespace objcopy
71} // end namespace llvm