blob: aff3631a487c70dc5591eaff916ea44ed2fb4e83 [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
12#include "llvm/ADT/ArrayRef.h"
Jordan Rupprechtbd95a9f2019-03-28 18:27:00 +000013#include "llvm/ADT/BitmaskEnum.h"
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +000014#include "llvm/ADT/Optional.h"
15#include "llvm/ADT/SmallVector.h"
16#include "llvm/ADT/StringMap.h"
17#include "llvm/ADT/StringRef.h"
Eugene Leviant51c1f642019-02-25 14:12:41 +000018#include "llvm/Object/ELFTypes.h"
Jordan Rupprecht5745c5f2019-02-04 18:38:00 +000019#include "llvm/Support/Allocator.h"
Jordan Rupprechtad29d292019-02-21 17:05:19 +000020#include "llvm/Support/Error.h"
Eugene Leviantf324f6d2019-02-06 11:00:07 +000021#include "llvm/Support/Regex.h"
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +000022// Necessary for llvm::DebugCompressionType::None
23#include "llvm/Target/TargetOptions.h"
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +000024#include <vector>
25
26namespace llvm {
27namespace objcopy {
28
Seiya Nutaecb60b72019-07-05 05:28:38 +000029enum class FileFormat {
30 Unspecified,
31 ELF,
32 Binary,
33 IHex,
34};
35
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +000036// 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 {
Jordan Rupprechtb0b65ca2019-04-17 07:42:31 +000040 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) {}
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +000047 uint16_t EMachine;
James Hendersonc040d5d2019-03-22 10:21:09 +000048 uint8_t OSABI;
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +000049 bool Is64Bit;
50 bool IsLittleEndian;
51};
52
Jordan Rupprechtbd95a9f2019-03-28 18:27:00 +000053// 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
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +000073struct SectionRename {
74 StringRef OriginalName;
75 StringRef NewName;
Jordan Rupprechtbd95a9f2019-03-28 18:27:00 +000076 Optional<SectionFlag> NewFlags;
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +000077};
78
Jordan Rupprechtc8927412019-01-29 15:05:38 +000079struct SectionFlagsUpdate {
80 StringRef Name;
Jordan Rupprechtbd95a9f2019-03-28 18:27:00 +000081 SectionFlag NewFlags;
Jordan Rupprechtc8927412019-01-29 15:05:38 +000082};
83
Jordan Rupprechtd0f7bcf2019-01-30 14:58:13 +000084enum class DiscardType {
85 None, // Default
86 All, // --discard-all (-x)
87 Locals, // --discard-locals (-X)
88};
89
Eugene Leviantf324f6d2019-02-06 11:00:07 +000090class 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
Eugene Leviant51c1f642019-02-25 14:12:41 +0000101struct 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
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +0000110// Configuration for copying/stripping a single file.
111struct CopyConfig {
112 // Main input/output options
113 StringRef InputFilename;
Seiya Nutaecb60b72019-07-05 05:28:38 +0000114 FileFormat InputFormat;
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +0000115 StringRef OutputFilename;
Seiya Nutaecb60b72019-07-05 05:28:38 +0000116 FileFormat OutputFormat;
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +0000117
Jordan Rupprecht70038e02019-01-07 16:59:12 +0000118 // Only applicable for --input-format=binary
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +0000119 MachineInfo BinaryArch;
Jordan Rupprecht70038e02019-01-07 16:59:12 +0000120 // Only applicable when --output-format!=binary (e.g. elf64-x86-64).
121 Optional<MachineInfo> OutputArch;
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +0000122
123 // Advanced options
124 StringRef AddGnuDebugLink;
James Henderson9df38832019-05-14 10:59:04 +0000125 // Cached gnu_debuglink's target CRC
126 uint32_t GnuDebugLinkCRC32;
Jake Ehrlich8ad77792018-12-03 19:49:23 +0000127 StringRef BuildIdLinkDir;
128 Optional<StringRef> BuildIdLinkInput;
129 Optional<StringRef> BuildIdLinkOutput;
Peter Collingbourne8d58a982019-06-07 17:57:48 +0000130 Optional<StringRef> ExtractPartition;
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +0000131 StringRef SplitDWO;
132 StringRef SymbolsPrefix;
James Hendersonfa11fb32019-05-08 09:49:35 +0000133 StringRef AllocSectionsPrefix;
Jordan Rupprechtd0f7bcf2019-01-30 14:58:13 +0000134 DiscardType DiscardMode = DiscardType::None;
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +0000135
136 // Repeated options
137 std::vector<StringRef> AddSection;
138 std::vector<StringRef> DumpSection;
Eugene Leviant51c1f642019-02-25 14:12:41 +0000139 std::vector<NewSymbolInfo> SymbolsToAdd;
Eugene Leviantf324f6d2019-02-06 11:00:07 +0000140 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;
Eugene Leviant2db10622019-02-13 07:34:54 +0000146 std::vector<NameOrRegex> UnneededSymbolsToRemove;
Eugene Leviantf324f6d2019-02-06 11:00:07 +0000147 std::vector<NameOrRegex> SymbolsToWeaken;
148 std::vector<NameOrRegex> ToRemove;
149 std::vector<NameOrRegex> SymbolsToKeepGlobal;
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +0000150
151 // Map options
152 StringMap<SectionRename> SectionsToRename;
Jordan Rupprechtc8927412019-01-29 15:05:38 +0000153 StringMap<SectionFlagsUpdate> SetSectionFlags;
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +0000154 StringMap<StringRef> SymbolsToRename;
155
Eugene Leviant53350d02019-02-26 09:24:22 +0000156 // 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
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +0000162 // Boolean options
James Henderson66a9d0f2019-04-18 09:13:30 +0000163 bool AllowBrokenLinks = false;
Jordan Rupprechtfc780bb2018-11-01 17:36:37 +0000164 bool DeterministicArchives = true;
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +0000165 bool ExtractDWO = false;
Peter Collingbourne8d58a982019-06-07 17:57:48 +0000166 bool ExtractMainPartition = false;
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +0000167 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;
Jordan Rupprecht5745c5f2019-02-04 18:38:00 +0000188 BumpPtrAllocator Alloc;
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +0000189};
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.
Jordan Rupprechtad29d292019-02-21 17:05:19 +0000194Expected<DriverConfig> parseObjcopyOptions(ArrayRef<const char *> ArgsArr);
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +0000195
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
Alex Brachet77477002019-06-18 00:39:10 +0000198// 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);
Alexander Shaposhnikov8d0b74c2018-10-11 22:33:50 +0000203
204} // namespace objcopy
205} // namespace llvm
206
207#endif