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/CachedHashString.h" 14 #include "llvm/ADT/DenseSet.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/GlobPattern.h" 21 #include "llvm/Support/Regex.h" 22 // Necessary for llvm::DebugCompressionType::None 23 #include "llvm/Target/TargetOptions.h" 24 #include <vector> 25 26 namespace llvm { 27 namespace objcopy { 28 29 enum 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. 39 struct MachineInfo { MachineInfoMachineInfo40 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. MachineInfoMachineInfo43 MachineInfo(uint16_t EM, bool Is64, bool IsLittle) 44 : MachineInfo(EM, ELF::ELFOSABI_NONE, Is64, IsLittle) {} 45 // Default constructor for unset fields. MachineInfoMachineInfo46 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. 56 enum 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 SecExclude = 1 << 12, 71 LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/SecExclude) 72 }; 73 74 struct SectionRename { 75 StringRef OriginalName; 76 StringRef NewName; 77 Optional<SectionFlag> NewFlags; 78 }; 79 80 struct SectionFlagsUpdate { 81 StringRef Name; 82 SectionFlag NewFlags; 83 }; 84 85 enum class DiscardType { 86 None, // Default 87 All, // --discard-all (-x) 88 Locals, // --discard-locals (-X) 89 }; 90 91 enum class MatchStyle { 92 Literal, // Default for symbols. 93 Wildcard, // Default for sections, or enabled with --wildcard (-w). 94 Regex, // Enabled with --regex. 95 }; 96 97 class NameOrPattern { 98 StringRef Name; 99 // Regex is shared between multiple CommonConfig instances. 100 std::shared_ptr<Regex> R; 101 std::shared_ptr<GlobPattern> G; 102 bool IsPositiveMatch = true; 103 NameOrPattern(StringRef N)104 NameOrPattern(StringRef N) : Name(N) {} NameOrPattern(std::shared_ptr<Regex> R)105 NameOrPattern(std::shared_ptr<Regex> R) : R(R) {} NameOrPattern(std::shared_ptr<GlobPattern> G,bool IsPositiveMatch)106 NameOrPattern(std::shared_ptr<GlobPattern> G, bool IsPositiveMatch) 107 : G(G), IsPositiveMatch(IsPositiveMatch) {} 108 109 public: 110 // ErrorCallback is used to handle recoverable errors. An Error returned 111 // by the callback aborts the parsing and is then returned by this function. 112 static Expected<NameOrPattern> 113 create(StringRef Pattern, MatchStyle MS, 114 llvm::function_ref<Error(Error)> ErrorCallback); 115 isPositiveMatch()116 bool isPositiveMatch() const { return IsPositiveMatch; } getName()117 Optional<StringRef> getName() const { 118 if (!R && !G) 119 return Name; 120 return None; 121 } 122 bool operator==(StringRef S) const { 123 return R ? R->match(S) : G ? G->match(S) : Name == S; 124 } 125 bool operator!=(StringRef S) const { return !operator==(S); } 126 }; 127 128 // Matcher that checks symbol or section names against the command line flags 129 // provided for that option. 130 class NameMatcher { 131 DenseSet<CachedHashStringRef> PosNames; 132 std::vector<NameOrPattern> PosPatterns; 133 std::vector<NameOrPattern> NegMatchers; 134 135 public: addMatcher(Expected<NameOrPattern> Matcher)136 Error addMatcher(Expected<NameOrPattern> Matcher) { 137 if (!Matcher) 138 return Matcher.takeError(); 139 if (Matcher->isPositiveMatch()) { 140 if (Optional<StringRef> MaybeName = Matcher->getName()) 141 PosNames.insert(CachedHashStringRef(*MaybeName)); 142 else 143 PosPatterns.push_back(std::move(*Matcher)); 144 } else { 145 NegMatchers.push_back(std::move(*Matcher)); 146 } 147 return Error::success(); 148 } matches(StringRef S)149 bool matches(StringRef S) const { 150 return (PosNames.contains(CachedHashStringRef(S)) || 151 is_contained(PosPatterns, S)) && 152 !is_contained(NegMatchers, S); 153 } empty()154 bool empty() const { 155 return PosNames.empty() && PosPatterns.empty() && NegMatchers.empty(); 156 } 157 }; 158 159 enum class SymbolFlag { 160 Global, 161 Local, 162 Weak, 163 Default, 164 Hidden, 165 Protected, 166 File, 167 Section, 168 Object, 169 Function, 170 IndirectFunction, 171 Debug, 172 Constructor, 173 Warning, 174 Indirect, 175 Synthetic, 176 UniqueObject, 177 }; 178 179 // Symbol info specified by --add-symbol option. Symbol flags not supported 180 // by a concrete format should be ignored. 181 struct NewSymbolInfo { 182 StringRef SymbolName; 183 StringRef SectionName; 184 uint64_t Value = 0; 185 std::vector<SymbolFlag> Flags; 186 std::vector<StringRef> BeforeSyms; 187 }; 188 189 // Configuration for copying/stripping a single file. 190 struct CommonConfig { 191 // Main input/output options 192 StringRef InputFilename; 193 FileFormat InputFormat = FileFormat::Unspecified; 194 StringRef OutputFilename; 195 FileFormat OutputFormat = FileFormat::Unspecified; 196 197 // Only applicable when --output-format!=binary (e.g. elf64-x86-64). 198 Optional<MachineInfo> OutputArch; 199 200 // Advanced options 201 StringRef AddGnuDebugLink; 202 // Cached gnu_debuglink's target CRC 203 uint32_t GnuDebugLinkCRC32; 204 Optional<StringRef> ExtractPartition; 205 StringRef SplitDWO; 206 StringRef SymbolsPrefix; 207 StringRef AllocSectionsPrefix; 208 DiscardType DiscardMode = DiscardType::None; 209 210 // Repeated options 211 std::vector<StringRef> AddSection; 212 std::vector<StringRef> DumpSection; 213 std::vector<StringRef> RPathToAdd; 214 std::vector<StringRef> RPathToPrepend; 215 DenseMap<StringRef, StringRef> RPathsToUpdate; 216 DenseMap<StringRef, StringRef> InstallNamesToUpdate; 217 DenseSet<StringRef> RPathsToRemove; 218 219 // install-name-tool's id option 220 Optional<StringRef> SharedLibId; 221 222 // Section matchers 223 NameMatcher KeepSection; 224 NameMatcher OnlySection; 225 NameMatcher ToRemove; 226 227 // Symbol matchers 228 NameMatcher SymbolsToGlobalize; 229 NameMatcher SymbolsToKeep; 230 NameMatcher SymbolsToLocalize; 231 NameMatcher SymbolsToRemove; 232 NameMatcher UnneededSymbolsToRemove; 233 NameMatcher SymbolsToWeaken; 234 NameMatcher SymbolsToKeepGlobal; 235 236 // Map options 237 StringMap<SectionRename> SectionsToRename; 238 StringMap<uint64_t> SetSectionAlignment; 239 StringMap<SectionFlagsUpdate> SetSectionFlags; 240 StringMap<StringRef> SymbolsToRename; 241 242 // ELF entry point address expression. The input parameter is an entry point 243 // address in the input ELF file. The entry address in the output file is 244 // calculated with EntryExpr(input_address), when either --set-start or 245 // --change-start is used. 246 std::function<uint64_t(uint64_t)> EntryExpr; 247 248 // Symbol info specified by --add-symbol option. 249 std::vector<NewSymbolInfo> SymbolsToAdd; 250 251 // Boolean options 252 bool AllowBrokenLinks = false; 253 bool DeterministicArchives = true; 254 bool ExtractDWO = false; 255 bool ExtractMainPartition = false; 256 bool KeepFileSymbols = false; 257 bool KeepUndefined = false; 258 bool LocalizeHidden = false; 259 bool OnlyKeepDebug = false; 260 bool PreserveDates = false; 261 bool StripAll = false; 262 bool StripAllGNU = false; 263 bool StripDWO = false; 264 bool StripDebug = false; 265 bool StripNonAlloc = false; 266 bool StripSections = false; 267 bool StripSwiftSymbols = false; 268 bool StripUnneeded = false; 269 bool Weaken = false; 270 bool DecompressDebugSections = false; 271 // install-name-tool's --delete_all_rpaths 272 bool RemoveAllRpaths = false; 273 274 DebugCompressionType CompressionType = DebugCompressionType::None; 275 }; 276 277 } // namespace objcopy 278 } // namespace llvm 279 280 #endif // LLVM_TOOLS_LLVM_OBJCOPY_COMMONCONFIG_H 281