Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
14 | pmbaty | 1 | //===- CommonConfig.h -------------------------------------------*- C++ -*-===// |
2 | // |
||
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
||
4 | // See https://llvm.org/LICENSE.txt for license information. |
||
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
||
6 | // |
||
7 | //===----------------------------------------------------------------------===// |
||
8 | |||
9 | #ifndef LLVM_OBJCOPY_COMMONCONFIG_H |
||
10 | #define LLVM_OBJCOPY_COMMONCONFIG_H |
||
11 | |||
12 | #include "llvm/ADT/ArrayRef.h" |
||
13 | #include "llvm/ADT/CachedHashString.h" |
||
14 | #include "llvm/ADT/DenseSet.h" |
||
15 | #include "llvm/ADT/SmallVector.h" |
||
16 | #include "llvm/ADT/StringMap.h" |
||
17 | #include "llvm/ADT/StringRef.h" |
||
18 | #include "llvm/Object/ELFTypes.h" |
||
19 | #include "llvm/Support/GlobPattern.h" |
||
20 | #include "llvm/Support/MemoryBuffer.h" |
||
21 | #include "llvm/Support/Regex.h" |
||
22 | // Necessary for llvm::DebugCompressionType::None |
||
23 | #include "llvm/Target/TargetOptions.h" |
||
24 | #include <optional> |
||
25 | #include <vector> |
||
26 | |||
27 | namespace llvm { |
||
28 | namespace objcopy { |
||
29 | |||
30 | enum class FileFormat { |
||
31 | Unspecified, |
||
32 | ELF, |
||
33 | Binary, |
||
34 | IHex, |
||
35 | }; |
||
36 | |||
37 | // This type keeps track of the machine info for various architectures. This |
||
38 | // lets us map architecture names to ELF types and the e_machine value of the |
||
39 | // ELF file. |
||
40 | struct MachineInfo { |
||
41 | MachineInfo(uint16_t EM, uint8_t ABI, bool Is64, bool IsLittle) |
||
42 | : EMachine(EM), OSABI(ABI), Is64Bit(Is64), IsLittleEndian(IsLittle) {} |
||
43 | // Alternative constructor that defaults to NONE for OSABI. |
||
44 | MachineInfo(uint16_t EM, bool Is64, bool IsLittle) |
||
45 | : MachineInfo(EM, ELF::ELFOSABI_NONE, Is64, IsLittle) {} |
||
46 | // Default constructor for unset fields. |
||
47 | MachineInfo() : MachineInfo(0, 0, false, false) {} |
||
48 | uint16_t EMachine; |
||
49 | uint8_t OSABI; |
||
50 | bool Is64Bit; |
||
51 | bool IsLittleEndian; |
||
52 | }; |
||
53 | |||
54 | // Flags set by --set-section-flags or --rename-section. Interpretation of these |
||
55 | // is format-specific and not all flags are meaningful for all object file |
||
56 | // formats. This is a bitmask; many section flags may be set. |
||
57 | enum SectionFlag { |
||
58 | SecNone = 0, |
||
59 | SecAlloc = 1 << 0, |
||
60 | SecLoad = 1 << 1, |
||
61 | SecNoload = 1 << 2, |
||
62 | SecReadonly = 1 << 3, |
||
63 | SecDebug = 1 << 4, |
||
64 | SecCode = 1 << 5, |
||
65 | SecData = 1 << 6, |
||
66 | SecRom = 1 << 7, |
||
67 | SecMerge = 1 << 8, |
||
68 | SecStrings = 1 << 9, |
||
69 | SecContents = 1 << 10, |
||
70 | SecShare = 1 << 11, |
||
71 | SecExclude = 1 << 12, |
||
72 | LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/SecExclude) |
||
73 | }; |
||
74 | |||
75 | struct SectionRename { |
||
76 | StringRef OriginalName; |
||
77 | StringRef NewName; |
||
78 | std::optional<SectionFlag> NewFlags; |
||
79 | }; |
||
80 | |||
81 | struct SectionFlagsUpdate { |
||
82 | StringRef Name; |
||
83 | SectionFlag NewFlags; |
||
84 | }; |
||
85 | |||
86 | enum class DiscardType { |
||
87 | None, // Default |
||
88 | All, // --discard-all (-x) |
||
89 | Locals, // --discard-locals (-X) |
||
90 | }; |
||
91 | |||
92 | enum class MatchStyle { |
||
93 | Literal, // Default for symbols. |
||
94 | Wildcard, // Default for sections, or enabled with --wildcard (-w). |
||
95 | Regex, // Enabled with --regex. |
||
96 | }; |
||
97 | |||
98 | class NameOrPattern { |
||
99 | StringRef Name; |
||
100 | // Regex is shared between multiple CommonConfig instances. |
||
101 | std::shared_ptr<Regex> R; |
||
102 | std::shared_ptr<GlobPattern> G; |
||
103 | bool IsPositiveMatch = true; |
||
104 | |||
105 | NameOrPattern(StringRef N) : Name(N) {} |
||
106 | NameOrPattern(std::shared_ptr<Regex> R) : R(R) {} |
||
107 | NameOrPattern(std::shared_ptr<GlobPattern> G, bool IsPositiveMatch) |
||
108 | : G(G), IsPositiveMatch(IsPositiveMatch) {} |
||
109 | |||
110 | public: |
||
111 | // ErrorCallback is used to handle recoverable errors. An Error returned |
||
112 | // by the callback aborts the parsing and is then returned by this function. |
||
113 | static Expected<NameOrPattern> |
||
114 | create(StringRef Pattern, MatchStyle MS, |
||
115 | llvm::function_ref<Error(Error)> ErrorCallback); |
||
116 | |||
117 | bool isPositiveMatch() const { return IsPositiveMatch; } |
||
118 | std::optional<StringRef> getName() const { |
||
119 | if (!R && !G) |
||
120 | return Name; |
||
121 | return std::nullopt; |
||
122 | } |
||
123 | bool operator==(StringRef S) const { |
||
124 | return R ? R->match(S) : G ? G->match(S) : Name == S; |
||
125 | } |
||
126 | bool operator!=(StringRef S) const { return !operator==(S); } |
||
127 | }; |
||
128 | |||
129 | // Matcher that checks symbol or section names against the command line flags |
||
130 | // provided for that option. |
||
131 | class NameMatcher { |
||
132 | DenseSet<CachedHashStringRef> PosNames; |
||
133 | std::vector<NameOrPattern> PosPatterns; |
||
134 | std::vector<NameOrPattern> NegMatchers; |
||
135 | |||
136 | public: |
||
137 | Error addMatcher(Expected<NameOrPattern> Matcher) { |
||
138 | if (!Matcher) |
||
139 | return Matcher.takeError(); |
||
140 | if (Matcher->isPositiveMatch()) { |
||
141 | if (std::optional<StringRef> MaybeName = Matcher->getName()) |
||
142 | PosNames.insert(CachedHashStringRef(*MaybeName)); |
||
143 | else |
||
144 | PosPatterns.push_back(std::move(*Matcher)); |
||
145 | } else { |
||
146 | NegMatchers.push_back(std::move(*Matcher)); |
||
147 | } |
||
148 | return Error::success(); |
||
149 | } |
||
150 | bool matches(StringRef S) const { |
||
151 | return (PosNames.contains(CachedHashStringRef(S)) || |
||
152 | is_contained(PosPatterns, S)) && |
||
153 | !is_contained(NegMatchers, S); |
||
154 | } |
||
155 | bool empty() const { |
||
156 | return PosNames.empty() && PosPatterns.empty() && NegMatchers.empty(); |
||
157 | } |
||
158 | }; |
||
159 | |||
160 | enum class SymbolFlag { |
||
161 | Global, |
||
162 | Local, |
||
163 | Weak, |
||
164 | Default, |
||
165 | Hidden, |
||
166 | Protected, |
||
167 | File, |
||
168 | Section, |
||
169 | Object, |
||
170 | Function, |
||
171 | IndirectFunction, |
||
172 | Debug, |
||
173 | Constructor, |
||
174 | Warning, |
||
175 | Indirect, |
||
176 | Synthetic, |
||
177 | UniqueObject, |
||
178 | }; |
||
179 | |||
180 | // Symbol info specified by --add-symbol option. Symbol flags not supported |
||
181 | // by a concrete format should be ignored. |
||
182 | struct NewSymbolInfo { |
||
183 | StringRef SymbolName; |
||
184 | StringRef SectionName; |
||
185 | uint64_t Value = 0; |
||
186 | std::vector<SymbolFlag> Flags; |
||
187 | std::vector<StringRef> BeforeSyms; |
||
188 | }; |
||
189 | |||
190 | // Specify section name and section body for newly added or updated section. |
||
191 | struct NewSectionInfo { |
||
192 | NewSectionInfo() = default; |
||
193 | NewSectionInfo(StringRef Name, std::unique_ptr<MemoryBuffer> &&Buffer) |
||
194 | : SectionName(Name), SectionData(std::move(Buffer)) {} |
||
195 | |||
196 | StringRef SectionName; |
||
197 | std::shared_ptr<MemoryBuffer> SectionData; |
||
198 | }; |
||
199 | |||
200 | // Configuration for copying/stripping a single file. |
||
201 | struct CommonConfig { |
||
202 | // Main input/output options |
||
203 | StringRef InputFilename; |
||
204 | FileFormat InputFormat = FileFormat::Unspecified; |
||
205 | StringRef OutputFilename; |
||
206 | FileFormat OutputFormat = FileFormat::Unspecified; |
||
207 | |||
208 | // Only applicable when --output-format!=binary (e.g. elf64-x86-64). |
||
209 | std::optional<MachineInfo> OutputArch; |
||
210 | |||
211 | // Advanced options |
||
212 | StringRef AddGnuDebugLink; |
||
213 | // Cached gnu_debuglink's target CRC |
||
214 | uint32_t GnuDebugLinkCRC32; |
||
215 | std::optional<StringRef> ExtractPartition; |
||
216 | StringRef SplitDWO; |
||
217 | StringRef SymbolsPrefix; |
||
218 | StringRef AllocSectionsPrefix; |
||
219 | DiscardType DiscardMode = DiscardType::None; |
||
220 | |||
221 | // Repeated options |
||
222 | std::vector<NewSectionInfo> AddSection; |
||
223 | std::vector<StringRef> DumpSection; |
||
224 | std::vector<NewSectionInfo> UpdateSection; |
||
225 | |||
226 | // Section matchers |
||
227 | NameMatcher KeepSection; |
||
228 | NameMatcher OnlySection; |
||
229 | NameMatcher ToRemove; |
||
230 | |||
231 | // Symbol matchers |
||
232 | NameMatcher SymbolsToGlobalize; |
||
233 | NameMatcher SymbolsToKeep; |
||
234 | NameMatcher SymbolsToLocalize; |
||
235 | NameMatcher SymbolsToRemove; |
||
236 | NameMatcher UnneededSymbolsToRemove; |
||
237 | NameMatcher SymbolsToWeaken; |
||
238 | NameMatcher SymbolsToKeepGlobal; |
||
239 | |||
240 | // Map options |
||
241 | StringMap<SectionRename> SectionsToRename; |
||
242 | StringMap<uint64_t> SetSectionAlignment; |
||
243 | StringMap<SectionFlagsUpdate> SetSectionFlags; |
||
244 | StringMap<uint64_t> SetSectionType; |
||
245 | StringMap<StringRef> SymbolsToRename; |
||
246 | |||
247 | // Symbol info specified by --add-symbol option. |
||
248 | std::vector<NewSymbolInfo> SymbolsToAdd; |
||
249 | |||
250 | // Boolean options |
||
251 | bool DeterministicArchives = true; |
||
252 | bool ExtractDWO = false; |
||
253 | bool ExtractMainPartition = false; |
||
254 | bool OnlyKeepDebug = false; |
||
255 | bool PreserveDates = false; |
||
256 | bool StripAll = false; |
||
257 | bool StripAllGNU = false; |
||
258 | bool StripDWO = false; |
||
259 | bool StripDebug = false; |
||
260 | bool StripNonAlloc = false; |
||
261 | bool StripSections = false; |
||
262 | bool StripUnneeded = false; |
||
263 | bool Weaken = false; |
||
264 | bool DecompressDebugSections = false; |
||
265 | |||
266 | DebugCompressionType CompressionType = DebugCompressionType::None; |
||
267 | }; |
||
268 | |||
269 | } // namespace objcopy |
||
270 | } // namespace llvm |
||
271 | |||
272 | #endif // LLVM_OBJCOPY_COMMONCONFIG_H |