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_OBJCOPY_COMMONCONFIG_H 10 #define 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/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/MemoryBuffer.h" 21 #include "llvm/Support/Regex.h" 22 // Necessary for llvm::DebugCompressionType::None 23 #include "llvm/Target/TargetOptions.h" 24 #include <optional> 25 #include <vector> 26 27 namespace llvm { 28 namespace objcopy { 29 30 enum class FileFormat { 31 Unspecified, 32 ELF, 33 Binary, 34 IHex, 35 }; 36 37 // This type keeps track of the machine info for various architectures. This 38 // lets us map architecture names to ELF types and the e_machine value of the 39 // ELF file. 40 struct MachineInfo { MachineInfoMachineInfo41 MachineInfo(uint16_t EM, uint8_t ABI, bool Is64, bool IsLittle) 42 : EMachine(EM), OSABI(ABI), Is64Bit(Is64), IsLittleEndian(IsLittle) {} 43 // Alternative constructor that defaults to NONE for OSABI. MachineInfoMachineInfo44 MachineInfo(uint16_t EM, bool Is64, bool IsLittle) 45 : MachineInfo(EM, ELF::ELFOSABI_NONE, Is64, IsLittle) {} 46 // Default constructor for unset fields. MachineInfoMachineInfo47 MachineInfo() : MachineInfo(0, 0, false, false) {} 48 uint16_t EMachine; 49 uint8_t OSABI; 50 bool Is64Bit; 51 bool IsLittleEndian; 52 }; 53 54 // Flags set by --set-section-flags or --rename-section. Interpretation of these 55 // is format-specific and not all flags are meaningful for all object file 56 // formats. This is a bitmask; many section flags may be set. 57 enum SectionFlag { 58 SecNone = 0, 59 SecAlloc = 1 << 0, 60 SecLoad = 1 << 1, 61 SecNoload = 1 << 2, 62 SecReadonly = 1 << 3, 63 SecDebug = 1 << 4, 64 SecCode = 1 << 5, 65 SecData = 1 << 6, 66 SecRom = 1 << 7, 67 SecMerge = 1 << 8, 68 SecStrings = 1 << 9, 69 SecContents = 1 << 10, 70 SecShare = 1 << 11, 71 SecExclude = 1 << 12, 72 LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/SecExclude) 73 }; 74 75 struct SectionRename { 76 StringRef OriginalName; 77 StringRef NewName; 78 std::optional<SectionFlag> NewFlags; 79 }; 80 81 struct SectionFlagsUpdate { 82 StringRef Name; 83 SectionFlag NewFlags; 84 }; 85 86 enum class DiscardType { 87 None, // Default 88 All, // --discard-all (-x) 89 Locals, // --discard-locals (-X) 90 }; 91 92 enum class MatchStyle { 93 Literal, // Default for symbols. 94 Wildcard, // Default for sections, or enabled with --wildcard (-w). 95 Regex, // Enabled with --regex. 96 }; 97 98 class NameOrPattern { 99 StringRef Name; 100 // Regex is shared between multiple CommonConfig instances. 101 std::shared_ptr<Regex> R; 102 std::shared_ptr<GlobPattern> G; 103 bool IsPositiveMatch = true; 104 NameOrPattern(StringRef N)105 NameOrPattern(StringRef N) : Name(N) {} NameOrPattern(std::shared_ptr<Regex> R)106 NameOrPattern(std::shared_ptr<Regex> R) : R(R) {} NameOrPattern(std::shared_ptr<GlobPattern> G,bool IsPositiveMatch)107 NameOrPattern(std::shared_ptr<GlobPattern> G, bool IsPositiveMatch) 108 : G(G), IsPositiveMatch(IsPositiveMatch) {} 109 110 public: 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 isPositiveMatch()117 bool isPositiveMatch() const { return IsPositiveMatch; } getName()118 std::optional<StringRef> getName() const { 119 if (!R && !G) 120 return Name; 121 return std::nullopt; 122 } 123 bool operator==(StringRef S) const { 124 return R ? R->match(S) : G ? G->match(S) : Name == S; 125 } 126 bool operator!=(StringRef S) const { return !operator==(S); } 127 }; 128 129 // Matcher that checks symbol or section names against the command line flags 130 // provided for that option. 131 class NameMatcher { 132 DenseSet<CachedHashStringRef> PosNames; 133 std::vector<NameOrPattern> PosPatterns; 134 std::vector<NameOrPattern> NegMatchers; 135 136 public: addMatcher(Expected<NameOrPattern> Matcher)137 Error addMatcher(Expected<NameOrPattern> Matcher) { 138 if (!Matcher) 139 return Matcher.takeError(); 140 if (Matcher->isPositiveMatch()) { 141 if (std::optional<StringRef> MaybeName = Matcher->getName()) 142 PosNames.insert(CachedHashStringRef(*MaybeName)); 143 else 144 PosPatterns.push_back(std::move(*Matcher)); 145 } else { 146 NegMatchers.push_back(std::move(*Matcher)); 147 } 148 return Error::success(); 149 } matches(StringRef S)150 bool matches(StringRef S) const { 151 return (PosNames.contains(CachedHashStringRef(S)) || 152 is_contained(PosPatterns, S)) && 153 !is_contained(NegMatchers, S); 154 } empty()155 bool empty() const { 156 return PosNames.empty() && PosPatterns.empty() && NegMatchers.empty(); 157 } 158 }; 159 160 enum class SymbolFlag { 161 Global, 162 Local, 163 Weak, 164 Default, 165 Hidden, 166 Protected, 167 File, 168 Section, 169 Object, 170 Function, 171 IndirectFunction, 172 Debug, 173 Constructor, 174 Warning, 175 Indirect, 176 Synthetic, 177 UniqueObject, 178 }; 179 180 // Symbol info specified by --add-symbol option. Symbol flags not supported 181 // by a concrete format should be ignored. 182 struct NewSymbolInfo { 183 StringRef SymbolName; 184 StringRef SectionName; 185 uint64_t Value = 0; 186 std::vector<SymbolFlag> Flags; 187 std::vector<StringRef> BeforeSyms; 188 }; 189 190 // Specify section name and section body for newly added or updated section. 191 struct NewSectionInfo { 192 NewSectionInfo() = default; NewSectionInfoNewSectionInfo193 NewSectionInfo(StringRef Name, std::unique_ptr<MemoryBuffer> &&Buffer) 194 : SectionName(Name), SectionData(std::move(Buffer)) {} 195 196 StringRef SectionName; 197 std::shared_ptr<MemoryBuffer> SectionData; 198 }; 199 200 // Configuration for copying/stripping a single file. 201 struct CommonConfig { 202 // Main input/output options 203 StringRef InputFilename; 204 FileFormat InputFormat = FileFormat::Unspecified; 205 StringRef OutputFilename; 206 FileFormat OutputFormat = FileFormat::Unspecified; 207 208 // Only applicable when --output-format!=binary (e.g. elf64-x86-64). 209 std::optional<MachineInfo> OutputArch; 210 211 // Advanced options 212 StringRef AddGnuDebugLink; 213 // Cached gnu_debuglink's target CRC 214 uint32_t GnuDebugLinkCRC32; 215 std::optional<StringRef> ExtractPartition; 216 StringRef SplitDWO; 217 StringRef SymbolsPrefix; 218 StringRef AllocSectionsPrefix; 219 DiscardType DiscardMode = DiscardType::None; 220 221 // Repeated options 222 std::vector<NewSectionInfo> AddSection; 223 std::vector<StringRef> DumpSection; 224 std::vector<NewSectionInfo> UpdateSection; 225 226 // Section matchers 227 NameMatcher KeepSection; 228 NameMatcher OnlySection; 229 NameMatcher ToRemove; 230 231 // Symbol matchers 232 NameMatcher SymbolsToGlobalize; 233 NameMatcher SymbolsToKeep; 234 NameMatcher SymbolsToLocalize; 235 NameMatcher SymbolsToRemove; 236 NameMatcher UnneededSymbolsToRemove; 237 NameMatcher SymbolsToWeaken; 238 NameMatcher SymbolsToKeepGlobal; 239 240 // Map options 241 StringMap<SectionRename> SectionsToRename; 242 StringMap<uint64_t> SetSectionAlignment; 243 StringMap<SectionFlagsUpdate> SetSectionFlags; 244 StringMap<uint64_t> SetSectionType; 245 StringMap<StringRef> SymbolsToRename; 246 247 // Symbol info specified by --add-symbol option. 248 std::vector<NewSymbolInfo> SymbolsToAdd; 249 250 // Boolean options 251 bool DeterministicArchives = true; 252 bool ExtractDWO = false; 253 bool ExtractMainPartition = false; 254 bool OnlyKeepDebug = false; 255 bool PreserveDates = false; 256 bool StripAll = false; 257 bool StripAllGNU = false; 258 bool StripDWO = false; 259 bool StripDebug = false; 260 bool StripNonAlloc = false; 261 bool StripSections = false; 262 bool StripUnneeded = false; 263 bool Weaken = false; 264 bool DecompressDebugSections = false; 265 266 DebugCompressionType CompressionType = DebugCompressionType::None; 267 }; 268 269 } // namespace objcopy 270 } // namespace llvm 271 272 #endif // LLVM_OBJCOPY_COMMONCONFIG_H 273