CopyConfig.h revision 355940
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 "llvm/ADT/ArrayRef.h"
13#include "llvm/ADT/BitmaskEnum.h"
14#include "llvm/ADT/Optional.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/Allocator.h"
20#include "llvm/Support/Error.h"
21#include "llvm/Support/Regex.h"
22// Necessary for llvm::DebugCompressionType::None
23#include "llvm/Target/TargetOptions.h"
24#include <vector>
25
26namespace llvm {
27namespace objcopy {
28
29enum class FileFormat {
30  Unspecified,
31  ELF,
32  Binary,
33  IHex,
34};
35
36// This type keeps track of the machine info for various architectures. This
37// lets us map architecture names to ELF types and the e_machine value of the
38// ELF file.
39struct MachineInfo {
40  MachineInfo(uint16_t EM, uint8_t ABI, bool Is64, bool IsLittle)
41      : EMachine(EM), OSABI(ABI), Is64Bit(Is64), IsLittleEndian(IsLittle) {}
42  // Alternative constructor that defaults to NONE for OSABI.
43  MachineInfo(uint16_t EM, bool Is64, bool IsLittle)
44      : MachineInfo(EM, ELF::ELFOSABI_NONE, Is64, IsLittle) {}
45  // Default constructor for unset fields.
46  MachineInfo() : MachineInfo(0, 0, false, false) {}
47  uint16_t EMachine;
48  uint8_t OSABI;
49  bool Is64Bit;
50  bool IsLittleEndian;
51};
52
53// Flags set by --set-section-flags or --rename-section. Interpretation of these
54// is format-specific and not all flags are meaningful for all object file
55// formats. This is a bitmask; many section flags may be set.
56enum SectionFlag {
57  SecNone = 0,
58  SecAlloc = 1 << 0,
59  SecLoad = 1 << 1,
60  SecNoload = 1 << 2,
61  SecReadonly = 1 << 3,
62  SecDebug = 1 << 4,
63  SecCode = 1 << 5,
64  SecData = 1 << 6,
65  SecRom = 1 << 7,
66  SecMerge = 1 << 8,
67  SecStrings = 1 << 9,
68  SecContents = 1 << 10,
69  SecShare = 1 << 11,
70  LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ SecShare)
71};
72
73struct SectionRename {
74  StringRef OriginalName;
75  StringRef NewName;
76  Optional<SectionFlag> NewFlags;
77};
78
79struct SectionFlagsUpdate {
80  StringRef Name;
81  SectionFlag NewFlags;
82};
83
84enum class DiscardType {
85  None,   // Default
86  All,    // --discard-all (-x)
87  Locals, // --discard-locals (-X)
88};
89
90class NameOrRegex {
91  StringRef Name;
92  // Regex is shared between multiple CopyConfig instances.
93  std::shared_ptr<Regex> R;
94
95public:
96  NameOrRegex(StringRef Pattern, bool IsRegex);
97  bool operator==(StringRef S) const { return R ? R->match(S) : Name == S; }
98  bool operator!=(StringRef S) const { return !operator==(S); }
99};
100
101struct NewSymbolInfo {
102  StringRef SymbolName;
103  StringRef SectionName;
104  uint64_t Value = 0;
105  uint8_t Type = ELF::STT_NOTYPE;
106  uint8_t Bind = ELF::STB_GLOBAL;
107  uint8_t Visibility = ELF::STV_DEFAULT;
108};
109
110// Configuration for copying/stripping a single file.
111struct CopyConfig {
112  // Main input/output options
113  StringRef InputFilename;
114  FileFormat InputFormat;
115  StringRef OutputFilename;
116  FileFormat OutputFormat;
117
118  // Only applicable for --input-format=binary
119  MachineInfo BinaryArch;
120  // Only applicable when --output-format!=binary (e.g. elf64-x86-64).
121  Optional<MachineInfo> OutputArch;
122
123  // Advanced options
124  StringRef AddGnuDebugLink;
125  // Cached gnu_debuglink's target CRC
126  uint32_t GnuDebugLinkCRC32;
127  StringRef BuildIdLinkDir;
128  Optional<StringRef> BuildIdLinkInput;
129  Optional<StringRef> BuildIdLinkOutput;
130  Optional<StringRef> ExtractPartition;
131  StringRef SplitDWO;
132  StringRef SymbolsPrefix;
133  StringRef AllocSectionsPrefix;
134  DiscardType DiscardMode = DiscardType::None;
135
136  // Repeated options
137  std::vector<StringRef> AddSection;
138  std::vector<StringRef> DumpSection;
139  std::vector<NewSymbolInfo> SymbolsToAdd;
140  std::vector<NameOrRegex> KeepSection;
141  std::vector<NameOrRegex> OnlySection;
142  std::vector<NameOrRegex> SymbolsToGlobalize;
143  std::vector<NameOrRegex> SymbolsToKeep;
144  std::vector<NameOrRegex> SymbolsToLocalize;
145  std::vector<NameOrRegex> SymbolsToRemove;
146  std::vector<NameOrRegex> UnneededSymbolsToRemove;
147  std::vector<NameOrRegex> SymbolsToWeaken;
148  std::vector<NameOrRegex> ToRemove;
149  std::vector<NameOrRegex> SymbolsToKeepGlobal;
150
151  // Map options
152  StringMap<SectionRename> SectionsToRename;
153  StringMap<SectionFlagsUpdate> SetSectionFlags;
154  StringMap<StringRef> SymbolsToRename;
155
156  // ELF entry point address expression. The input parameter is an entry point
157  // address in the input ELF file. The entry address in the output file is
158  // calculated with EntryExpr(input_address), when either --set-start or
159  // --change-start is used.
160  std::function<uint64_t(uint64_t)> EntryExpr;
161
162  // Boolean options
163  bool AllowBrokenLinks = false;
164  bool DeterministicArchives = true;
165  bool ExtractDWO = false;
166  bool ExtractMainPartition = false;
167  bool KeepFileSymbols = false;
168  bool LocalizeHidden = false;
169  bool OnlyKeepDebug = false;
170  bool PreserveDates = false;
171  bool StripAll = false;
172  bool StripAllGNU = false;
173  bool StripDWO = false;
174  bool StripDebug = false;
175  bool StripNonAlloc = false;
176  bool StripSections = false;
177  bool StripUnneeded = false;
178  bool Weaken = false;
179  bool DecompressDebugSections = false;
180  DebugCompressionType CompressionType = DebugCompressionType::None;
181};
182
183// Configuration for the overall invocation of this tool. When invoked as
184// objcopy, will always contain exactly one CopyConfig. When invoked as strip,
185// will contain one or more CopyConfigs.
186struct DriverConfig {
187  SmallVector<CopyConfig, 1> CopyConfigs;
188  BumpPtrAllocator Alloc;
189};
190
191// ParseObjcopyOptions returns the config and sets the input arguments. If a
192// help flag is set then ParseObjcopyOptions will print the help messege and
193// exit.
194Expected<DriverConfig> parseObjcopyOptions(ArrayRef<const char *> ArgsArr);
195
196// ParseStripOptions returns the config and sets the input arguments. If a
197// help flag is set then ParseStripOptions will print the help messege and
198// exit. ErrorCallback is used to handle recoverable errors. An Error returned
199// by the callback aborts the parsing and is then returned by this function.
200Expected<DriverConfig>
201parseStripOptions(ArrayRef<const char *> ArgsArr,
202                  std::function<Error(Error)> ErrorCallback);
203
204} // namespace objcopy
205} // namespace llvm
206
207#endif
208