1 //===- CommonConfig.h -------------------------------------------*- C++ -*-===// 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_COMMONCONFIG_H 10 #define LLVM_TOOLS_LLVM_OBJCOPY_COMMONCONFIG_H 11 12 #include "llvm/ADT/ArrayRef.h" 13 #include "llvm/ADT/DenseSet.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/GlobPattern.h" 20 #include "llvm/Support/Regex.h" 21 // Necessary for llvm::DebugCompressionType::None 22 #include "llvm/Target/TargetOptions.h" 23 #include <vector> 24 25 namespace llvm { 26 namespace objcopy { 27 28 enum class FileFormat { 29 Unspecified, 30 ELF, 31 Binary, 32 IHex, 33 }; 34 35 // This type keeps track of the machine info for various architectures. This 36 // lets us map architecture names to ELF types and the e_machine value of the 37 // ELF file. 38 struct MachineInfo { MachineInfoMachineInfo39 MachineInfo(uint16_t EM, uint8_t ABI, bool Is64, bool IsLittle) 40 : EMachine(EM), OSABI(ABI), Is64Bit(Is64), IsLittleEndian(IsLittle) {} 41 // Alternative constructor that defaults to NONE for OSABI. MachineInfoMachineInfo42 MachineInfo(uint16_t EM, bool Is64, bool IsLittle) 43 : MachineInfo(EM, ELF::ELFOSABI_NONE, Is64, IsLittle) {} 44 // Default constructor for unset fields. MachineInfoMachineInfo45 MachineInfo() : MachineInfo(0, 0, false, false) {} 46 uint16_t EMachine; 47 uint8_t OSABI; 48 bool Is64Bit; 49 bool IsLittleEndian; 50 }; 51 52 // Flags set by --set-section-flags or --rename-section. Interpretation of these 53 // is format-specific and not all flags are meaningful for all object file 54 // formats. This is a bitmask; many section flags may be set. 55 enum SectionFlag { 56 SecNone = 0, 57 SecAlloc = 1 << 0, 58 SecLoad = 1 << 1, 59 SecNoload = 1 << 2, 60 SecReadonly = 1 << 3, 61 SecDebug = 1 << 4, 62 SecCode = 1 << 5, 63 SecData = 1 << 6, 64 SecRom = 1 << 7, 65 SecMerge = 1 << 8, 66 SecStrings = 1 << 9, 67 SecContents = 1 << 10, 68 SecShare = 1 << 11, 69 SecExclude = 1 << 12, 70 LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/SecExclude) 71 }; 72 73 struct SectionRename { 74 StringRef OriginalName; 75 StringRef NewName; 76 Optional<SectionFlag> NewFlags; 77 }; 78 79 struct SectionFlagsUpdate { 80 StringRef Name; 81 SectionFlag NewFlags; 82 }; 83 84 enum class DiscardType { 85 None, // Default 86 All, // --discard-all (-x) 87 Locals, // --discard-locals (-X) 88 }; 89 90 enum class MatchStyle { 91 Literal, // Default for symbols. 92 Wildcard, // Default for sections, or enabled with --wildcard (-w). 93 Regex, // Enabled with --regex. 94 }; 95 96 class NameOrPattern { 97 StringRef Name; 98 // Regex is shared between multiple CommonConfig instances. 99 std::shared_ptr<Regex> R; 100 std::shared_ptr<GlobPattern> G; 101 bool IsPositiveMatch = true; 102 NameOrPattern(StringRef N)103 NameOrPattern(StringRef N) : Name(N) {} NameOrPattern(std::shared_ptr<Regex> R)104 NameOrPattern(std::shared_ptr<Regex> R) : R(R) {} NameOrPattern(std::shared_ptr<GlobPattern> G,bool IsPositiveMatch)105 NameOrPattern(std::shared_ptr<GlobPattern> G, bool IsPositiveMatch) 106 : G(G), IsPositiveMatch(IsPositiveMatch) {} 107 108 public: 109 // ErrorCallback is used to handle recoverable errors. An Error returned 110 // by the callback aborts the parsing and is then returned by this function. 111 static Expected<NameOrPattern> 112 create(StringRef Pattern, MatchStyle MS, 113 llvm::function_ref<Error(Error)> ErrorCallback); 114 isPositiveMatch()115 bool isPositiveMatch() const { return IsPositiveMatch; } 116 bool operator==(StringRef S) const { 117 return R ? R->match(S) : G ? G->match(S) : Name == S; 118 } 119 bool operator!=(StringRef S) const { return !operator==(S); } 120 }; 121 122 // Matcher that checks symbol or section names against the command line flags 123 // provided for that option. 124 class NameMatcher { 125 std::vector<NameOrPattern> PosMatchers; 126 std::vector<NameOrPattern> NegMatchers; 127 128 public: addMatcher(Expected<NameOrPattern> Matcher)129 Error addMatcher(Expected<NameOrPattern> Matcher) { 130 if (!Matcher) 131 return Matcher.takeError(); 132 if (Matcher->isPositiveMatch()) 133 PosMatchers.push_back(std::move(*Matcher)); 134 else 135 NegMatchers.push_back(std::move(*Matcher)); 136 return Error::success(); 137 } matches(StringRef S)138 bool matches(StringRef S) const { 139 return is_contained(PosMatchers, S) && !is_contained(NegMatchers, S); 140 } empty()141 bool empty() const { return PosMatchers.empty() && NegMatchers.empty(); } 142 }; 143 144 // Configuration for copying/stripping a single file. 145 struct CommonConfig { 146 // Main input/output options 147 StringRef InputFilename; 148 FileFormat InputFormat = FileFormat::Unspecified; 149 StringRef OutputFilename; 150 FileFormat OutputFormat = FileFormat::Unspecified; 151 152 // Only applicable when --output-format!=binary (e.g. elf64-x86-64). 153 Optional<MachineInfo> OutputArch; 154 155 // Advanced options 156 StringRef AddGnuDebugLink; 157 // Cached gnu_debuglink's target CRC 158 uint32_t GnuDebugLinkCRC32; 159 Optional<StringRef> ExtractPartition; 160 StringRef SplitDWO; 161 StringRef SymbolsPrefix; 162 StringRef AllocSectionsPrefix; 163 DiscardType DiscardMode = DiscardType::None; 164 165 // Repeated options 166 std::vector<StringRef> AddSection; 167 std::vector<StringRef> DumpSection; 168 std::vector<StringRef> RPathToAdd; 169 std::vector<StringRef> RPathToPrepend; 170 DenseMap<StringRef, StringRef> RPathsToUpdate; 171 DenseMap<StringRef, StringRef> InstallNamesToUpdate; 172 DenseSet<StringRef> RPathsToRemove; 173 174 // install-name-tool's id option 175 Optional<StringRef> SharedLibId; 176 177 // Section matchers 178 NameMatcher KeepSection; 179 NameMatcher OnlySection; 180 NameMatcher ToRemove; 181 182 // Symbol matchers 183 NameMatcher SymbolsToGlobalize; 184 NameMatcher SymbolsToKeep; 185 NameMatcher SymbolsToLocalize; 186 NameMatcher SymbolsToRemove; 187 NameMatcher UnneededSymbolsToRemove; 188 NameMatcher SymbolsToWeaken; 189 NameMatcher SymbolsToKeepGlobal; 190 191 // Map options 192 StringMap<SectionRename> SectionsToRename; 193 StringMap<uint64_t> SetSectionAlignment; 194 StringMap<SectionFlagsUpdate> SetSectionFlags; 195 StringMap<StringRef> SymbolsToRename; 196 197 // ELF entry point address expression. The input parameter is an entry point 198 // address in the input ELF file. The entry address in the output file is 199 // calculated with EntryExpr(input_address), when either --set-start or 200 // --change-start is used. 201 std::function<uint64_t(uint64_t)> EntryExpr; 202 203 // Boolean options 204 bool AllowBrokenLinks = false; 205 bool DeterministicArchives = true; 206 bool ExtractDWO = false; 207 bool ExtractMainPartition = false; 208 bool KeepFileSymbols = false; 209 bool KeepUndefined = false; 210 bool LocalizeHidden = false; 211 bool OnlyKeepDebug = false; 212 bool PreserveDates = false; 213 bool StripAll = false; 214 bool StripAllGNU = false; 215 bool StripDWO = false; 216 bool StripDebug = false; 217 bool StripNonAlloc = false; 218 bool StripSections = false; 219 bool StripSwiftSymbols = false; 220 bool StripUnneeded = false; 221 bool Weaken = false; 222 bool DecompressDebugSections = false; 223 // install-name-tool's --delete_all_rpaths 224 bool RemoveAllRpaths = false; 225 226 DebugCompressionType CompressionType = DebugCompressionType::None; 227 }; 228 229 } // namespace objcopy 230 } // namespace llvm 231 232 #endif // LLVM_TOOLS_LLVM_OBJCOPY_COMMONCONFIG_H 233