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