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