blob: 745af0ce480f04c21b80c83d62aea9a389ec001a [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"
Eugene Leviantf324f6d2019-02-06 11:00:07 +000022#include "llvm/Support/Regex.h"
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +000023// Necessary for llvm::DebugCompressionType::None
24#include "llvm/Target/TargetOptions.h"
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +000025#include <vector>
26
27namespace llvm {
28namespace objcopy {
29
Seiya Nutaecb60b72019-07-05 05:28:38 +000030enum class FileFormat {
31 Unspecified,
32 ELF,
33 Binary,
34 IHex,
35};
36
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +000037// 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.
40struct MachineInfo {
Jordan Rupprechtb0b65ca2019-04-17 07:42:31 +000041 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) {}
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +000048 uint16_t EMachine;
James Hendersonc040d5d2019-03-22 10:21:09 +000049 uint8_t OSABI;
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +000050 bool Is64Bit;
51 bool IsLittleEndian;
52};
53
Jordan Rupprechtbd95a9f2019-03-28 18:27:00 +000054// 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.
57enum 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 LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ SecShare)
72};
73
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +000074struct SectionRename {
75 StringRef OriginalName;
76 StringRef NewName;
Jordan Rupprechtbd95a9f2019-03-28 18:27:00 +000077 Optional<SectionFlag> NewFlags;
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +000078};
79
Jordan Rupprechtc8927412019-01-29 15:05:38 +000080struct SectionFlagsUpdate {
81 StringRef Name;
Jordan Rupprechtbd95a9f2019-03-28 18:27:00 +000082 SectionFlag NewFlags;
Jordan Rupprechtc8927412019-01-29 15:05:38 +000083};
84
Jordan Rupprechtd0f7bcf2019-01-30 14:58:13 +000085enum class DiscardType {
86 None, // Default
87 All, // --discard-all (-x)
88 Locals, // --discard-locals (-X)
89};
90
Eugene Leviantf324f6d2019-02-06 11:00:07 +000091class NameOrRegex {
92 StringRef Name;
93 // Regex is shared between multiple CopyConfig instances.
94 std::shared_ptr<Regex> R;
95
96public:
97 NameOrRegex(StringRef Pattern, bool IsRegex);
98 bool operator==(StringRef S) const { return R ? R->match(S) : Name == S; }
99 bool operator!=(StringRef S) const { return !operator==(S); }
100};
101
Jordan Rupprecht6c6dd6a2019-08-22 19:17:50 +0000102// Matcher that checks symbol or section names against the command line flags
103// provided for that option.
104class NameMatcher {
105 std::vector<NameOrRegex> Matchers;
106
107public:
108 void addMatcher(NameOrRegex Matcher) {
109 Matchers.push_back(std::move(Matcher));
110 }
111 bool matches(StringRef S) const { return is_contained(Matchers, S); }
112 bool empty() const { return Matchers.empty(); }
113};
114
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +0000115// Configuration for copying/stripping a single file.
116struct CopyConfig {
Seiya Nutac83eefc2019-09-24 09:38:23 +0000117 // Format-specific options to be initialized lazily when needed.
118 Optional<elf::ELFCopyConfig> ELF;
119
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +0000120 // Main input/output options
121 StringRef InputFilename;
Seiya Nutaecb60b72019-07-05 05:28:38 +0000122 FileFormat InputFormat;
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +0000123 StringRef OutputFilename;
Seiya Nutaecb60b72019-07-05 05:28:38 +0000124 FileFormat OutputFormat;
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +0000125
Jordan Rupprecht70038e02019-01-07 16:59:12 +0000126 // Only applicable when --output-format!=binary (e.g. elf64-x86-64).
127 Optional<MachineInfo> OutputArch;
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +0000128
129 // Advanced options
130 StringRef AddGnuDebugLink;
James Henderson9df38832019-05-14 10:59:04 +0000131 // Cached gnu_debuglink's target CRC
132 uint32_t GnuDebugLinkCRC32;
Jake Ehrlich8ad77792018-12-03 19:49:23 +0000133 StringRef BuildIdLinkDir;
134 Optional<StringRef> BuildIdLinkInput;
135 Optional<StringRef> BuildIdLinkOutput;
Peter Collingbourne8d58a982019-06-07 17:57:48 +0000136 Optional<StringRef> ExtractPartition;
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +0000137 StringRef SplitDWO;
138 StringRef SymbolsPrefix;
James Hendersonfa11fb32019-05-08 09:49:35 +0000139 StringRef AllocSectionsPrefix;
Jordan Rupprechtd0f7bcf2019-01-30 14:58:13 +0000140 DiscardType DiscardMode = DiscardType::None;
Seiya Nutac83eefc2019-09-24 09:38:23 +0000141 Optional<StringRef> NewSymbolVisibility;
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +0000142
143 // Repeated options
144 std::vector<StringRef> AddSection;
145 std::vector<StringRef> DumpSection;
Seiya Nutac83eefc2019-09-24 09:38:23 +0000146 std::vector<StringRef> SymbolsToAdd;
Jordan Rupprecht6c6dd6a2019-08-22 19:17:50 +0000147
148 // Section matchers
149 NameMatcher KeepSection;
150 NameMatcher OnlySection;
151 NameMatcher ToRemove;
152
153 // Symbol matchers
154 NameMatcher SymbolsToGlobalize;
155 NameMatcher SymbolsToKeep;
156 NameMatcher SymbolsToLocalize;
157 NameMatcher SymbolsToRemove;
158 NameMatcher UnneededSymbolsToRemove;
159 NameMatcher SymbolsToWeaken;
160 NameMatcher SymbolsToKeepGlobal;
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +0000161
162 // Map options
163 StringMap<SectionRename> SectionsToRename;
Fangrui Song671fb342019-10-02 12:41:25 +0000164 StringMap<uint64_t> SetSectionAlignment;
Jordan Rupprechtc8927412019-01-29 15:05:38 +0000165 StringMap<SectionFlagsUpdate> SetSectionFlags;
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +0000166 StringMap<StringRef> SymbolsToRename;
167
Eugene Leviant53350d02019-02-26 09:24:22 +0000168 // ELF entry point address expression. The input parameter is an entry point
169 // address in the input ELF file. The entry address in the output file is
170 // calculated with EntryExpr(input_address), when either --set-start or
171 // --change-start is used.
172 std::function<uint64_t(uint64_t)> EntryExpr;
173
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +0000174 // Boolean options
James Henderson66a9d0f2019-04-18 09:13:30 +0000175 bool AllowBrokenLinks = false;
Jordan Rupprechtfc780bb2018-11-01 17:36:37 +0000176 bool DeterministicArchives = true;
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +0000177 bool ExtractDWO = false;
Peter Collingbourne8d58a982019-06-07 17:57:48 +0000178 bool ExtractMainPartition = false;
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +0000179 bool KeepFileSymbols = false;
180 bool LocalizeHidden = false;
181 bool OnlyKeepDebug = false;
182 bool PreserveDates = false;
183 bool StripAll = false;
184 bool StripAllGNU = false;
185 bool StripDWO = false;
186 bool StripDebug = false;
187 bool StripNonAlloc = false;
188 bool StripSections = false;
189 bool StripUnneeded = false;
190 bool Weaken = false;
191 bool DecompressDebugSections = false;
192 DebugCompressionType CompressionType = DebugCompressionType::None;
Seiya Nutac83eefc2019-09-24 09:38:23 +0000193
194 // parseELFConfig performs ELF-specific command-line parsing. Fills `ELF` on
195 // success or returns an Error otherwise.
196 Error parseELFConfig() {
197 if (!ELF) {
198 Expected<elf::ELFCopyConfig> ELFConfig = elf::parseConfig(*this);
199 if (!ELFConfig)
200 return ELFConfig.takeError();
201 ELF = *ELFConfig;
202 }
203 return Error::success();
204 }
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +0000205};
206
207// Configuration for the overall invocation of this tool. When invoked as
208// objcopy, will always contain exactly one CopyConfig. When invoked as strip,
209// will contain one or more CopyConfigs.
210struct DriverConfig {
211 SmallVector<CopyConfig, 1> CopyConfigs;
Jordan Rupprecht5745c5f2019-02-04 18:38:00 +0000212 BumpPtrAllocator Alloc;
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +0000213};
214
215// ParseObjcopyOptions returns the config and sets the input arguments. If a
216// help flag is set then ParseObjcopyOptions will print the help messege and
217// exit.
Jordan Rupprechtad29d292019-02-21 17:05:19 +0000218Expected<DriverConfig> parseObjcopyOptions(ArrayRef<const char *> ArgsArr);
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +0000219
220// ParseStripOptions returns the config and sets the input arguments. If a
221// help flag is set then ParseStripOptions will print the help messege and
Alex Brachet77477002019-06-18 00:39:10 +0000222// exit. ErrorCallback is used to handle recoverable errors. An Error returned
223// by the callback aborts the parsing and is then returned by this function.
224Expected<DriverConfig>
225parseStripOptions(ArrayRef<const char *> ArgsArr,
226 std::function<Error(Error)> ErrorCallback);
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +0000227
228} // namespace objcopy
229} // namespace llvm
230
231#endif