blob: acf783c7f278953ab2e039381777a433b4ae82eb [file] [log] [blame]
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +00001//===- CopyConfig.h -------------------------------------------------------===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +00006//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLVM_TOOLS_LLVM_OBJCOPY_COPY_CONFIG_H
10#define LLVM_TOOLS_LLVM_OBJCOPY_COPY_CONFIG_H
11
Seiya Nutac83eefc2019-09-24 09:38:23 +000012#include "ELF/ELFConfig.h"
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +000013#include "llvm/ADT/ArrayRef.h"
Jordan Rupprechtbd95a9f2019-03-28 18:27:00 +000014#include "llvm/ADT/BitmaskEnum.h"
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +000015#include "llvm/ADT/Optional.h"
16#include "llvm/ADT/SmallVector.h"
17#include "llvm/ADT/StringMap.h"
18#include "llvm/ADT/StringRef.h"
Eugene Leviant51c1f642019-02-25 14:12:41 +000019#include "llvm/Object/ELFTypes.h"
Jordan Rupprecht5745c5f2019-02-04 18:38:00 +000020#include "llvm/Support/Allocator.h"
Jordan Rupprechtad29d292019-02-21 17:05:19 +000021#include "llvm/Support/Error.h"
Jordan Rupprechtedeebad2019-10-17 20:51:00 +000022#include "llvm/Support/GlobPattern.h"
Eugene Leviantf324f6d2019-02-06 11:00:07 +000023#include "llvm/Support/Regex.h"
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +000024// Necessary for llvm::DebugCompressionType::None
25#include "llvm/Target/TargetOptions.h"
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +000026#include <vector>
27
28namespace llvm {
29namespace objcopy {
30
Seiya Nutaecb60b72019-07-05 05:28:38 +000031enum class FileFormat {
32 Unspecified,
33 ELF,
34 Binary,
35 IHex,
36};
37
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +000038// This type keeps track of the machine info for various architectures. This
39// lets us map architecture names to ELF types and the e_machine value of the
40// ELF file.
41struct MachineInfo {
Jordan Rupprechtb0b65ca2019-04-17 07:42:31 +000042 MachineInfo(uint16_t EM, uint8_t ABI, bool Is64, bool IsLittle)
43 : EMachine(EM), OSABI(ABI), Is64Bit(Is64), IsLittleEndian(IsLittle) {}
44 // Alternative constructor that defaults to NONE for OSABI.
45 MachineInfo(uint16_t EM, bool Is64, bool IsLittle)
46 : MachineInfo(EM, ELF::ELFOSABI_NONE, Is64, IsLittle) {}
47 // Default constructor for unset fields.
48 MachineInfo() : MachineInfo(0, 0, false, false) {}
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +000049 uint16_t EMachine;
James Hendersonc040d5d2019-03-22 10:21:09 +000050 uint8_t OSABI;
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +000051 bool Is64Bit;
52 bool IsLittleEndian;
53};
54
Jordan Rupprechtbd95a9f2019-03-28 18:27:00 +000055// Flags set by --set-section-flags or --rename-section. Interpretation of these
56// is format-specific and not all flags are meaningful for all object file
57// formats. This is a bitmask; many section flags may be set.
58enum SectionFlag {
59 SecNone = 0,
60 SecAlloc = 1 << 0,
61 SecLoad = 1 << 1,
62 SecNoload = 1 << 2,
63 SecReadonly = 1 << 3,
64 SecDebug = 1 << 4,
65 SecCode = 1 << 5,
66 SecData = 1 << 6,
67 SecRom = 1 << 7,
68 SecMerge = 1 << 8,
69 SecStrings = 1 << 9,
70 SecContents = 1 << 10,
71 SecShare = 1 << 11,
Sergey Dmitrieve4463222020-01-20 17:06:03 -080072 SecExclude = 1 << 12,
73 LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/SecExclude)
Jordan Rupprechtbd95a9f2019-03-28 18:27:00 +000074};
75
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +000076struct SectionRename {
77 StringRef OriginalName;
78 StringRef NewName;
Jordan Rupprechtbd95a9f2019-03-28 18:27:00 +000079 Optional<SectionFlag> NewFlags;
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +000080};
81
Jordan Rupprechtc8927412019-01-29 15:05:38 +000082struct SectionFlagsUpdate {
83 StringRef Name;
Jordan Rupprechtbd95a9f2019-03-28 18:27:00 +000084 SectionFlag NewFlags;
Jordan Rupprechtc8927412019-01-29 15:05:38 +000085};
86
Jordan Rupprechtd0f7bcf2019-01-30 14:58:13 +000087enum class DiscardType {
88 None, // Default
89 All, // --discard-all (-x)
90 Locals, // --discard-locals (-X)
91};
92
Jordan Rupprechtedeebad2019-10-17 20:51:00 +000093enum class MatchStyle {
94 Literal, // Default for symbols.
95 Wildcard, // Default for sections, or enabled with --wildcard (-w).
96 Regex, // Enabled with --regex.
97};
98
99class NameOrPattern {
Eugene Leviantf324f6d2019-02-06 11:00:07 +0000100 StringRef Name;
101 // Regex is shared between multiple CopyConfig instances.
102 std::shared_ptr<Regex> R;
Jordan Rupprechtedeebad2019-10-17 20:51:00 +0000103 std::shared_ptr<GlobPattern> G;
104 bool IsPositiveMatch = true;
105
106 NameOrPattern(StringRef N) : Name(N) {}
107 NameOrPattern(std::shared_ptr<Regex> R) : R(R) {}
108 NameOrPattern(std::shared_ptr<GlobPattern> G, bool IsPositiveMatch)
109 : G(G), IsPositiveMatch(IsPositiveMatch) {}
Eugene Leviantf324f6d2019-02-06 11:00:07 +0000110
111public:
Jordan Rupprechtedeebad2019-10-17 20:51:00 +0000112 // ErrorCallback is used to handle recoverable errors. An Error returned
113 // by the callback aborts the parsing and is then returned by this function.
114 static Expected<NameOrPattern>
115 create(StringRef Pattern, MatchStyle MS,
116 llvm::function_ref<Error(Error)> ErrorCallback);
117
118 bool isPositiveMatch() const { return IsPositiveMatch; }
119 bool operator==(StringRef S) const {
120 return R ? R->match(S) : G ? G->match(S) : Name == S;
121 }
Eugene Leviantf324f6d2019-02-06 11:00:07 +0000122 bool operator!=(StringRef S) const { return !operator==(S); }
123};
124
Jordan Rupprecht6c6dd6a2019-08-22 19:17:50 +0000125// Matcher that checks symbol or section names against the command line flags
126// provided for that option.
127class NameMatcher {
Jordan Rupprechtedeebad2019-10-17 20:51:00 +0000128 std::vector<NameOrPattern> PosMatchers;
129 std::vector<NameOrPattern> NegMatchers;
Jordan Rupprecht6c6dd6a2019-08-22 19:17:50 +0000130
131public:
Jordan Rupprechtedeebad2019-10-17 20:51:00 +0000132 Error addMatcher(Expected<NameOrPattern> Matcher) {
133 if (!Matcher)
134 return Matcher.takeError();
135 if (Matcher->isPositiveMatch())
136 PosMatchers.push_back(std::move(*Matcher));
137 else
138 NegMatchers.push_back(std::move(*Matcher));
139 return Error::success();
Jordan Rupprecht6c6dd6a2019-08-22 19:17:50 +0000140 }
Jordan Rupprechtedeebad2019-10-17 20:51:00 +0000141 bool matches(StringRef S) const {
142 return is_contained(PosMatchers, S) && !is_contained(NegMatchers, S);
143 }
144 bool empty() const { return PosMatchers.empty() && NegMatchers.empty(); }
Jordan Rupprecht6c6dd6a2019-08-22 19:17:50 +0000145};
146
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +0000147// Configuration for copying/stripping a single file.
148struct CopyConfig {
Seiya Nutac83eefc2019-09-24 09:38:23 +0000149 // Format-specific options to be initialized lazily when needed.
150 Optional<elf::ELFCopyConfig> ELF;
151
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +0000152 // Main input/output options
153 StringRef InputFilename;
Alexander Shaposhnikovc54959c2019-11-19 23:30:52 -0800154 FileFormat InputFormat = FileFormat::Unspecified;
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +0000155 StringRef OutputFilename;
Alexander Shaposhnikovc54959c2019-11-19 23:30:52 -0800156 FileFormat OutputFormat = FileFormat::Unspecified;
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +0000157
Jordan Rupprecht70038e02019-01-07 16:59:12 +0000158 // Only applicable when --output-format!=binary (e.g. elf64-x86-64).
159 Optional<MachineInfo> OutputArch;
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +0000160
161 // Advanced options
162 StringRef AddGnuDebugLink;
James Henderson9df38832019-05-14 10:59:04 +0000163 // Cached gnu_debuglink's target CRC
164 uint32_t GnuDebugLinkCRC32;
Jake Ehrlich8ad77792018-12-03 19:49:23 +0000165 StringRef BuildIdLinkDir;
166 Optional<StringRef> BuildIdLinkInput;
167 Optional<StringRef> BuildIdLinkOutput;
Peter Collingbourne8d58a982019-06-07 17:57:48 +0000168 Optional<StringRef> ExtractPartition;
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +0000169 StringRef SplitDWO;
170 StringRef SymbolsPrefix;
James Hendersonfa11fb32019-05-08 09:49:35 +0000171 StringRef AllocSectionsPrefix;
Jordan Rupprechtd0f7bcf2019-01-30 14:58:13 +0000172 DiscardType DiscardMode = DiscardType::None;
Seiya Nutac83eefc2019-09-24 09:38:23 +0000173 Optional<StringRef> NewSymbolVisibility;
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +0000174
175 // Repeated options
176 std::vector<StringRef> AddSection;
177 std::vector<StringRef> DumpSection;
Seiya Nutac83eefc2019-09-24 09:38:23 +0000178 std::vector<StringRef> SymbolsToAdd;
Alexander Shaposhnikovc54959c2019-11-19 23:30:52 -0800179 std::vector<StringRef> RPathToAdd;
Jordan Rupprecht6c6dd6a2019-08-22 19:17:50 +0000180
181 // Section matchers
182 NameMatcher KeepSection;
183 NameMatcher OnlySection;
184 NameMatcher ToRemove;
185
186 // Symbol matchers
187 NameMatcher SymbolsToGlobalize;
188 NameMatcher SymbolsToKeep;
189 NameMatcher SymbolsToLocalize;
190 NameMatcher SymbolsToRemove;
191 NameMatcher UnneededSymbolsToRemove;
192 NameMatcher SymbolsToWeaken;
193 NameMatcher SymbolsToKeepGlobal;
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +0000194
195 // Map options
196 StringMap<SectionRename> SectionsToRename;
Fangrui Song671fb342019-10-02 12:41:25 +0000197 StringMap<uint64_t> SetSectionAlignment;
Jordan Rupprechtc8927412019-01-29 15:05:38 +0000198 StringMap<SectionFlagsUpdate> SetSectionFlags;
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +0000199 StringMap<StringRef> SymbolsToRename;
200
Eugene Leviant53350d02019-02-26 09:24:22 +0000201 // ELF entry point address expression. The input parameter is an entry point
202 // address in the input ELF file. The entry address in the output file is
203 // calculated with EntryExpr(input_address), when either --set-start or
204 // --change-start is used.
205 std::function<uint64_t(uint64_t)> EntryExpr;
206
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +0000207 // Boolean options
James Henderson66a9d0f2019-04-18 09:13:30 +0000208 bool AllowBrokenLinks = false;
Jordan Rupprechtfc780bb2018-11-01 17:36:37 +0000209 bool DeterministicArchives = true;
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +0000210 bool ExtractDWO = false;
Peter Collingbourne8d58a982019-06-07 17:57:48 +0000211 bool ExtractMainPartition = false;
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +0000212 bool KeepFileSymbols = false;
213 bool LocalizeHidden = false;
214 bool OnlyKeepDebug = false;
215 bool PreserveDates = false;
216 bool StripAll = false;
217 bool StripAllGNU = false;
218 bool StripDWO = false;
219 bool StripDebug = false;
220 bool StripNonAlloc = false;
221 bool StripSections = false;
Alexander Shaposhnikov842a8cc2020-05-26 16:49:56 -0700222 bool StripSwiftSymbols = false;
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +0000223 bool StripUnneeded = false;
224 bool Weaken = false;
225 bool DecompressDebugSections = false;
226 DebugCompressionType CompressionType = DebugCompressionType::None;
Seiya Nutac83eefc2019-09-24 09:38:23 +0000227
228 // parseELFConfig performs ELF-specific command-line parsing. Fills `ELF` on
229 // success or returns an Error otherwise.
230 Error parseELFConfig() {
231 if (!ELF) {
232 Expected<elf::ELFCopyConfig> ELFConfig = elf::parseConfig(*this);
233 if (!ELFConfig)
234 return ELFConfig.takeError();
235 ELF = *ELFConfig;
236 }
237 return Error::success();
238 }
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +0000239};
240
241// Configuration for the overall invocation of this tool. When invoked as
242// objcopy, will always contain exactly one CopyConfig. When invoked as strip,
243// will contain one or more CopyConfigs.
244struct DriverConfig {
245 SmallVector<CopyConfig, 1> CopyConfigs;
Jordan Rupprecht5745c5f2019-02-04 18:38:00 +0000246 BumpPtrAllocator Alloc;
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +0000247};
248
249// ParseObjcopyOptions returns the config and sets the input arguments. If a
250// help flag is set then ParseObjcopyOptions will print the help messege and
Jordan Rupprechtedeebad2019-10-17 20:51:00 +0000251// exit. ErrorCallback is used to handle recoverable errors. An Error returned
252// by the callback aborts the parsing and is then returned by this function.
253Expected<DriverConfig>
254parseObjcopyOptions(ArrayRef<const char *> ArgsArr,
255 llvm::function_ref<Error(Error)> ErrorCallback);
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +0000256
Alexander Shaposhnikovc54959c2019-11-19 23:30:52 -0800257// ParseInstallNameToolOptions returns the config and sets the input arguments.
258// If a help flag is set then ParseInstallNameToolOptions will print the help
259// messege and exit.
260Expected<DriverConfig>
261parseInstallNameToolOptions(ArrayRef<const char *> ArgsArr);
262
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +0000263// ParseStripOptions returns the config and sets the input arguments. If a
264// help flag is set then ParseStripOptions will print the help messege and
Alex Brachet77477002019-06-18 00:39:10 +0000265// exit. ErrorCallback is used to handle recoverable errors. An Error returned
266// by the callback aborts the parsing and is then returned by this function.
267Expected<DriverConfig>
268parseStripOptions(ArrayRef<const char *> ArgsArr,
Jordan Rupprechtedeebad2019-10-17 20:51:00 +0000269 llvm::function_ref<Error(Error)> ErrorCallback);
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +0000270} // namespace objcopy
271} // namespace llvm
272
273#endif