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

source code of llvm/include/llvm/ObjCopy/CommonConfig.h