]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/llvm/tools/llvm-objcopy/CopyConfig.h
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm-project / llvm / tools / llvm-objcopy / CopyConfig.h
1 //===- CopyConfig.h -------------------------------------------------------===//
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_TOOLS_LLVM_OBJCOPY_COPY_CONFIG_H
10 #define LLVM_TOOLS_LLVM_OBJCOPY_COPY_CONFIG_H
11
12 #include "ELF/ELFConfig.h"
13 #include "llvm/ADT/ArrayRef.h"
14 #include "llvm/ADT/BitmaskEnum.h"
15 #include "llvm/ADT/DenseSet.h"
16 #include "llvm/ADT/Optional.h"
17 #include "llvm/ADT/SmallVector.h"
18 #include "llvm/ADT/StringMap.h"
19 #include "llvm/ADT/StringRef.h"
20 #include "llvm/Object/ELFTypes.h"
21 #include "llvm/Support/Allocator.h"
22 #include "llvm/Support/Error.h"
23 #include "llvm/Support/GlobPattern.h"
24 #include "llvm/Support/Regex.h"
25 // Necessary for llvm::DebugCompressionType::None
26 #include "llvm/Target/TargetOptions.h"
27 #include <vector>
28
29 namespace llvm {
30 namespace objcopy {
31
32 enum class FileFormat {
33   Unspecified,
34   ELF,
35   Binary,
36   IHex,
37 };
38
39 // This type keeps track of the machine info for various architectures. This
40 // lets us map architecture names to ELF types and the e_machine value of the
41 // ELF file.
42 struct MachineInfo {
43   MachineInfo(uint16_t EM, uint8_t ABI, bool Is64, bool IsLittle)
44       : EMachine(EM), OSABI(ABI), Is64Bit(Is64), IsLittleEndian(IsLittle) {}
45   // Alternative constructor that defaults to NONE for OSABI.
46   MachineInfo(uint16_t EM, bool Is64, bool IsLittle)
47       : MachineInfo(EM, ELF::ELFOSABI_NONE, Is64, IsLittle) {}
48   // Default constructor for unset fields.
49   MachineInfo() : MachineInfo(0, 0, false, false) {}
50   uint16_t EMachine;
51   uint8_t OSABI;
52   bool Is64Bit;
53   bool IsLittleEndian;
54 };
55
56 // Flags set by --set-section-flags or --rename-section. Interpretation of these
57 // is format-specific and not all flags are meaningful for all object file
58 // formats. This is a bitmask; many section flags may be set.
59 enum SectionFlag {
60   SecNone = 0,
61   SecAlloc = 1 << 0,
62   SecLoad = 1 << 1,
63   SecNoload = 1 << 2,
64   SecReadonly = 1 << 3,
65   SecDebug = 1 << 4,
66   SecCode = 1 << 5,
67   SecData = 1 << 6,
68   SecRom = 1 << 7,
69   SecMerge = 1 << 8,
70   SecStrings = 1 << 9,
71   SecContents = 1 << 10,
72   SecShare = 1 << 11,
73   SecExclude = 1 << 12,
74   LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/SecExclude)
75 };
76
77 struct SectionRename {
78   StringRef OriginalName;
79   StringRef NewName;
80   Optional<SectionFlag> NewFlags;
81 };
82
83 struct SectionFlagsUpdate {
84   StringRef Name;
85   SectionFlag NewFlags;
86 };
87
88 enum class DiscardType {
89   None,   // Default
90   All,    // --discard-all (-x)
91   Locals, // --discard-locals (-X)
92 };
93
94 enum class MatchStyle {
95   Literal,  // Default for symbols.
96   Wildcard, // Default for sections, or enabled with --wildcard (-w).
97   Regex,    // Enabled with --regex.
98 };
99
100 class NameOrPattern {
101   StringRef Name;
102   // Regex is shared between multiple CopyConfig instances.
103   std::shared_ptr<Regex> R;
104   std::shared_ptr<GlobPattern> G;
105   bool IsPositiveMatch = true;
106
107   NameOrPattern(StringRef N) : Name(N) {}
108   NameOrPattern(std::shared_ptr<Regex> R) : R(R) {}
109   NameOrPattern(std::shared_ptr<GlobPattern> G, bool IsPositiveMatch)
110       : G(G), IsPositiveMatch(IsPositiveMatch) {}
111
112 public:
113   // ErrorCallback is used to handle recoverable errors. An Error returned
114   // by the callback aborts the parsing and is then returned by this function.
115   static Expected<NameOrPattern>
116   create(StringRef Pattern, MatchStyle MS,
117          llvm::function_ref<Error(Error)> ErrorCallback);
118
119   bool isPositiveMatch() const { return IsPositiveMatch; }
120   bool operator==(StringRef S) const {
121     return R ? R->match(S) : G ? G->match(S) : Name == S;
122   }
123   bool operator!=(StringRef S) const { return !operator==(S); }
124 };
125
126 // Matcher that checks symbol or section names against the command line flags
127 // provided for that option.
128 class NameMatcher {
129   std::vector<NameOrPattern> PosMatchers;
130   std::vector<NameOrPattern> NegMatchers;
131
132 public:
133   Error addMatcher(Expected<NameOrPattern> Matcher) {
134     if (!Matcher)
135       return Matcher.takeError();
136     if (Matcher->isPositiveMatch())
137       PosMatchers.push_back(std::move(*Matcher));
138     else
139       NegMatchers.push_back(std::move(*Matcher));
140     return Error::success();
141   }
142   bool matches(StringRef S) const {
143     return is_contained(PosMatchers, S) && !is_contained(NegMatchers, S);
144   }
145   bool empty() const { return PosMatchers.empty() && NegMatchers.empty(); }
146 };
147
148 // Configuration for copying/stripping a single file.
149 struct CopyConfig {
150   // Format-specific options to be initialized lazily when needed.
151   Optional<elf::ELFCopyConfig> ELF;
152
153   // Main input/output options
154   StringRef InputFilename;
155   FileFormat InputFormat = FileFormat::Unspecified;
156   StringRef OutputFilename;
157   FileFormat OutputFormat = FileFormat::Unspecified;
158
159   // Only applicable when --output-format!=binary (e.g. elf64-x86-64).
160   Optional<MachineInfo> OutputArch;
161
162   // Advanced options
163   StringRef AddGnuDebugLink;
164   // Cached gnu_debuglink's target CRC
165   uint32_t GnuDebugLinkCRC32;
166   StringRef BuildIdLinkDir;
167   Optional<StringRef> BuildIdLinkInput;
168   Optional<StringRef> BuildIdLinkOutput;
169   Optional<StringRef> ExtractPartition;
170   StringRef SplitDWO;
171   StringRef SymbolsPrefix;
172   StringRef AllocSectionsPrefix;
173   DiscardType DiscardMode = DiscardType::None;
174   Optional<StringRef> NewSymbolVisibility;
175
176   // Repeated options
177   std::vector<StringRef> AddSection;
178   std::vector<StringRef> DumpSection;
179   std::vector<StringRef> SymbolsToAdd;
180   std::vector<StringRef> RPathToAdd;
181   DenseMap<StringRef, StringRef> RPathsToUpdate;
182   DenseMap<StringRef, StringRef> InstallNamesToUpdate;
183   DenseSet<StringRef> RPathsToRemove;
184
185   // install-name-tool's id option
186   Optional<StringRef> SharedLibId;
187
188   // Section matchers
189   NameMatcher KeepSection;
190   NameMatcher OnlySection;
191   NameMatcher ToRemove;
192
193   // Symbol matchers
194   NameMatcher SymbolsToGlobalize;
195   NameMatcher SymbolsToKeep;
196   NameMatcher SymbolsToLocalize;
197   NameMatcher SymbolsToRemove;
198   NameMatcher UnneededSymbolsToRemove;
199   NameMatcher SymbolsToWeaken;
200   NameMatcher SymbolsToKeepGlobal;
201
202   // Map options
203   StringMap<SectionRename> SectionsToRename;
204   StringMap<uint64_t> SetSectionAlignment;
205   StringMap<SectionFlagsUpdate> SetSectionFlags;
206   StringMap<StringRef> SymbolsToRename;
207
208   // ELF entry point address expression. The input parameter is an entry point
209   // address in the input ELF file. The entry address in the output file is
210   // calculated with EntryExpr(input_address), when either --set-start or
211   // --change-start is used.
212   std::function<uint64_t(uint64_t)> EntryExpr;
213
214   // Boolean options
215   bool AllowBrokenLinks = false;
216   bool DeterministicArchives = true;
217   bool ExtractDWO = false;
218   bool ExtractMainPartition = false;
219   bool KeepFileSymbols = false;
220   bool LocalizeHidden = false;
221   bool OnlyKeepDebug = false;
222   bool PreserveDates = false;
223   bool StripAll = false;
224   bool StripAllGNU = false;
225   bool StripDWO = false;
226   bool StripDebug = false;
227   bool StripNonAlloc = false;
228   bool StripSections = false;
229   bool StripSwiftSymbols = false;
230   bool StripUnneeded = false;
231   bool Weaken = false;
232   bool DecompressDebugSections = false;
233   DebugCompressionType CompressionType = DebugCompressionType::None;
234
235   // parseELFConfig performs ELF-specific command-line parsing. Fills `ELF` on
236   // success or returns an Error otherwise.
237   Error parseELFConfig() {
238     if (!ELF) {
239       Expected<elf::ELFCopyConfig> ELFConfig = elf::parseConfig(*this);
240       if (!ELFConfig)
241         return ELFConfig.takeError();
242       ELF = *ELFConfig;
243     }
244     return Error::success();
245   }
246 };
247
248 // Configuration for the overall invocation of this tool. When invoked as
249 // objcopy, will always contain exactly one CopyConfig. When invoked as strip,
250 // will contain one or more CopyConfigs.
251 struct DriverConfig {
252   SmallVector<CopyConfig, 1> CopyConfigs;
253   BumpPtrAllocator Alloc;
254 };
255
256 // ParseObjcopyOptions returns the config and sets the input arguments. If a
257 // help flag is set then ParseObjcopyOptions will print the help messege and
258 // exit. ErrorCallback is used to handle recoverable errors. An Error returned
259 // by the callback aborts the parsing and is then returned by this function.
260 Expected<DriverConfig>
261 parseObjcopyOptions(ArrayRef<const char *> ArgsArr,
262                     llvm::function_ref<Error(Error)> ErrorCallback);
263
264 // ParseInstallNameToolOptions returns the config and sets the input arguments.
265 // If a help flag is set then ParseInstallNameToolOptions will print the help
266 // messege and exit.
267 Expected<DriverConfig>
268 parseInstallNameToolOptions(ArrayRef<const char *> ArgsArr);
269
270 // ParseStripOptions returns the config and sets the input arguments. If a
271 // help flag is set then ParseStripOptions will print the help messege and
272 // exit. ErrorCallback is used to handle recoverable errors. An Error returned
273 // by the callback aborts the parsing and is then returned by this function.
274 Expected<DriverConfig>
275 parseStripOptions(ArrayRef<const char *> ArgsArr,
276                   llvm::function_ref<Error(Error)> ErrorCallback);
277 } // namespace objcopy
278 } // namespace llvm
279
280 #endif