/
CopyConfig.h
225 lines (197 loc) · 6.74 KB
/
CopyConfig.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
//===- CopyConfig.h -------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_TOOLS_LLVM_OBJCOPY_COPY_CONFIG_H
#define LLVM_TOOLS_LLVM_OBJCOPY_COPY_CONFIG_H
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/BitmaskEnum.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Object/ELFTypes.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/Regex.h"
// Necessary for llvm::DebugCompressionType::None
#include "llvm/Target/TargetOptions.h"
#include <vector>
namespace llvm {
namespace objcopy {
enum class FileFormat {
Unspecified,
ELF,
Binary,
IHex,
};
// This type keeps track of the machine info for various architectures. This
// lets us map architecture names to ELF types and the e_machine value of the
// ELF file.
struct MachineInfo {
MachineInfo(uint16_t EM, uint8_t ABI, bool Is64, bool IsLittle)
: EMachine(EM), OSABI(ABI), Is64Bit(Is64), IsLittleEndian(IsLittle) {}
// Alternative constructor that defaults to NONE for OSABI.
MachineInfo(uint16_t EM, bool Is64, bool IsLittle)
: MachineInfo(EM, ELF::ELFOSABI_NONE, Is64, IsLittle) {}
// Default constructor for unset fields.
MachineInfo() : MachineInfo(0, 0, false, false) {}
uint16_t EMachine;
uint8_t OSABI;
bool Is64Bit;
bool IsLittleEndian;
};
// Flags set by --set-section-flags or --rename-section. Interpretation of these
// is format-specific and not all flags are meaningful for all object file
// formats. This is a bitmask; many section flags may be set.
enum SectionFlag {
SecNone = 0,
SecAlloc = 1 << 0,
SecLoad = 1 << 1,
SecNoload = 1 << 2,
SecReadonly = 1 << 3,
SecDebug = 1 << 4,
SecCode = 1 << 5,
SecData = 1 << 6,
SecRom = 1 << 7,
SecMerge = 1 << 8,
SecStrings = 1 << 9,
SecContents = 1 << 10,
SecShare = 1 << 11,
LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ SecShare)
};
struct SectionRename {
StringRef OriginalName;
StringRef NewName;
Optional<SectionFlag> NewFlags;
};
struct SectionFlagsUpdate {
StringRef Name;
SectionFlag NewFlags;
};
enum class DiscardType {
None, // Default
All, // --discard-all (-x)
Locals, // --discard-locals (-X)
};
class NameOrRegex {
StringRef Name;
// Regex is shared between multiple CopyConfig instances.
std::shared_ptr<Regex> R;
public:
NameOrRegex(StringRef Pattern, bool IsRegex);
bool operator==(StringRef S) const { return R ? R->match(S) : Name == S; }
bool operator!=(StringRef S) const { return !operator==(S); }
};
// Matcher that checks symbol or section names against the command line flags
// provided for that option.
class NameMatcher {
std::vector<NameOrRegex> Matchers;
public:
void addMatcher(NameOrRegex Matcher) {
Matchers.push_back(std::move(Matcher));
}
bool matches(StringRef S) const { return is_contained(Matchers, S); }
bool empty() const { return Matchers.empty(); }
};
struct NewSymbolInfo {
StringRef SymbolName;
StringRef SectionName;
uint64_t Value = 0;
uint8_t Type = ELF::STT_NOTYPE;
uint8_t Bind = ELF::STB_GLOBAL;
uint8_t Visibility = ELF::STV_DEFAULT;
};
// Configuration for copying/stripping a single file.
struct CopyConfig {
// Main input/output options
StringRef InputFilename;
FileFormat InputFormat;
StringRef OutputFilename;
FileFormat OutputFormat;
// Only applicable for --input-format=binary
MachineInfo BinaryArch;
// Only applicable when --output-format!=binary (e.g. elf64-x86-64).
Optional<MachineInfo> OutputArch;
// Advanced options
StringRef AddGnuDebugLink;
// Cached gnu_debuglink's target CRC
uint32_t GnuDebugLinkCRC32;
StringRef BuildIdLinkDir;
Optional<StringRef> BuildIdLinkInput;
Optional<StringRef> BuildIdLinkOutput;
Optional<StringRef> ExtractPartition;
StringRef SplitDWO;
StringRef SymbolsPrefix;
StringRef AllocSectionsPrefix;
DiscardType DiscardMode = DiscardType::None;
Optional<uint8_t> NewSymbolVisibility;
// Repeated options
std::vector<StringRef> AddSection;
std::vector<StringRef> DumpSection;
std::vector<NewSymbolInfo> SymbolsToAdd;
// Section matchers
NameMatcher KeepSection;
NameMatcher OnlySection;
NameMatcher ToRemove;
// Symbol matchers
NameMatcher SymbolsToGlobalize;
NameMatcher SymbolsToKeep;
NameMatcher SymbolsToLocalize;
NameMatcher SymbolsToRemove;
NameMatcher UnneededSymbolsToRemove;
NameMatcher SymbolsToWeaken;
NameMatcher SymbolsToKeepGlobal;
// Map options
StringMap<SectionRename> SectionsToRename;
StringMap<SectionFlagsUpdate> SetSectionFlags;
StringMap<StringRef> SymbolsToRename;
// ELF entry point address expression. The input parameter is an entry point
// address in the input ELF file. The entry address in the output file is
// calculated with EntryExpr(input_address), when either --set-start or
// --change-start is used.
std::function<uint64_t(uint64_t)> EntryExpr;
// Boolean options
bool AllowBrokenLinks = false;
bool DeterministicArchives = true;
bool ExtractDWO = false;
bool ExtractMainPartition = false;
bool KeepFileSymbols = false;
bool LocalizeHidden = false;
bool OnlyKeepDebug = false;
bool PreserveDates = false;
bool StripAll = false;
bool StripAllGNU = false;
bool StripDWO = false;
bool StripDebug = false;
bool StripNonAlloc = false;
bool StripSections = false;
bool StripUnneeded = false;
bool Weaken = false;
bool DecompressDebugSections = false;
DebugCompressionType CompressionType = DebugCompressionType::None;
};
// Configuration for the overall invocation of this tool. When invoked as
// objcopy, will always contain exactly one CopyConfig. When invoked as strip,
// will contain one or more CopyConfigs.
struct DriverConfig {
SmallVector<CopyConfig, 1> CopyConfigs;
BumpPtrAllocator Alloc;
};
// ParseObjcopyOptions returns the config and sets the input arguments. If a
// help flag is set then ParseObjcopyOptions will print the help messege and
// exit.
Expected<DriverConfig> parseObjcopyOptions(ArrayRef<const char *> ArgsArr);
// ParseStripOptions returns the config and sets the input arguments. If a
// help flag is set then ParseStripOptions will print the help messege and
// exit. ErrorCallback is used to handle recoverable errors. An Error returned
// by the callback aborts the parsing and is then returned by this function.
Expected<DriverConfig>
parseStripOptions(ArrayRef<const char *> ArgsArr,
std::function<Error(Error)> ErrorCallback);
} // namespace objcopy
} // namespace llvm
#endif