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