Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:17

0001 //===- CommonConfig.h -------------------------------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 
0009 #ifndef LLVM_OBJCOPY_COMMONCONFIG_H
0010 #define LLVM_OBJCOPY_COMMONCONFIG_H
0011 
0012 #include "llvm/ADT/ArrayRef.h"
0013 #include "llvm/ADT/CachedHashString.h"
0014 #include "llvm/ADT/DenseSet.h"
0015 #include "llvm/ADT/SmallVector.h"
0016 #include "llvm/ADT/StringMap.h"
0017 #include "llvm/ADT/StringRef.h"
0018 #include "llvm/Object/ELFTypes.h"
0019 #include "llvm/Support/Compression.h"
0020 #include "llvm/Support/GlobPattern.h"
0021 #include "llvm/Support/MemoryBuffer.h"
0022 #include "llvm/Support/Regex.h"
0023 #include <optional>
0024 
0025 namespace llvm {
0026 namespace objcopy {
0027 
0028 enum class FileFormat { Unspecified, ELF, Binary, IHex, SREC };
0029 
0030 // This type keeps track of the machine info for various architectures. This
0031 // lets us map architecture names to ELF types and the e_machine value of the
0032 // ELF file.
0033 struct MachineInfo {
0034   MachineInfo(uint16_t EM, uint8_t ABI, bool Is64, bool IsLittle)
0035       : EMachine(EM), OSABI(ABI), Is64Bit(Is64), IsLittleEndian(IsLittle) {}
0036   // Alternative constructor that defaults to NONE for OSABI.
0037   MachineInfo(uint16_t EM, bool Is64, bool IsLittle)
0038       : MachineInfo(EM, ELF::ELFOSABI_NONE, Is64, IsLittle) {}
0039   // Default constructor for unset fields.
0040   MachineInfo() : MachineInfo(0, 0, false, false) {}
0041   uint16_t EMachine;
0042   uint8_t OSABI;
0043   bool Is64Bit;
0044   bool IsLittleEndian;
0045 };
0046 
0047 // Flags set by --set-section-flags or --rename-section. Interpretation of these
0048 // is format-specific and not all flags are meaningful for all object file
0049 // formats. This is a bitmask; many section flags may be set.
0050 enum SectionFlag {
0051   SecNone = 0,
0052   SecAlloc = 1 << 0,
0053   SecLoad = 1 << 1,
0054   SecNoload = 1 << 2,
0055   SecReadonly = 1 << 3,
0056   SecDebug = 1 << 4,
0057   SecCode = 1 << 5,
0058   SecData = 1 << 6,
0059   SecRom = 1 << 7,
0060   SecMerge = 1 << 8,
0061   SecStrings = 1 << 9,
0062   SecContents = 1 << 10,
0063   SecShare = 1 << 11,
0064   SecExclude = 1 << 12,
0065   SecLarge = 1 << 13,
0066   LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/SecLarge)
0067 };
0068 
0069 struct SectionRename {
0070   StringRef OriginalName;
0071   StringRef NewName;
0072   std::optional<SectionFlag> NewFlags;
0073 };
0074 
0075 struct SectionFlagsUpdate {
0076   StringRef Name;
0077   SectionFlag NewFlags;
0078 };
0079 
0080 enum class DiscardType {
0081   None,   // Default
0082   All,    // --discard-all (-x)
0083   Locals, // --discard-locals (-X)
0084 };
0085 
0086 enum class MatchStyle {
0087   Literal,  // Default for symbols.
0088   Wildcard, // Default for sections, or enabled with --wildcard (-w).
0089   Regex,    // Enabled with --regex.
0090 };
0091 
0092 class NameOrPattern {
0093   StringRef Name;
0094   // Regex is shared between multiple CommonConfig instances.
0095   std::shared_ptr<Regex> R;
0096   std::shared_ptr<GlobPattern> G;
0097   bool IsPositiveMatch = true;
0098 
0099   NameOrPattern(StringRef N) : Name(N) {}
0100   NameOrPattern(std::shared_ptr<Regex> R) : R(R) {}
0101   NameOrPattern(std::shared_ptr<GlobPattern> G, bool IsPositiveMatch)
0102       : G(G), IsPositiveMatch(IsPositiveMatch) {}
0103 
0104 public:
0105   // ErrorCallback is used to handle recoverable errors. An Error returned
0106   // by the callback aborts the parsing and is then returned by this function.
0107   static Expected<NameOrPattern>
0108   create(StringRef Pattern, MatchStyle MS,
0109          llvm::function_ref<Error(Error)> ErrorCallback);
0110 
0111   bool isPositiveMatch() const { return IsPositiveMatch; }
0112   std::optional<StringRef> getName() const {
0113     if (!R && !G)
0114       return Name;
0115     return std::nullopt;
0116   }
0117   bool operator==(StringRef S) const {
0118     return R ? R->match(S) : G ? G->match(S) : Name == S;
0119   }
0120   bool operator!=(StringRef S) const { return !operator==(S); }
0121 };
0122 
0123 // Matcher that checks symbol or section names against the command line flags
0124 // provided for that option.
0125 class NameMatcher {
0126   DenseSet<CachedHashStringRef> PosNames;
0127   SmallVector<NameOrPattern, 0> PosPatterns;
0128   SmallVector<NameOrPattern, 0> NegMatchers;
0129 
0130 public:
0131   Error addMatcher(Expected<NameOrPattern> Matcher) {
0132     if (!Matcher)
0133       return Matcher.takeError();
0134     if (Matcher->isPositiveMatch()) {
0135       if (std::optional<StringRef> MaybeName = Matcher->getName())
0136         PosNames.insert(CachedHashStringRef(*MaybeName));
0137       else
0138         PosPatterns.push_back(std::move(*Matcher));
0139     } else {
0140       NegMatchers.push_back(std::move(*Matcher));
0141     }
0142     return Error::success();
0143   }
0144   bool matches(StringRef S) const {
0145     return (PosNames.contains(CachedHashStringRef(S)) ||
0146             is_contained(PosPatterns, S)) &&
0147            !is_contained(NegMatchers, S);
0148   }
0149   bool empty() const {
0150     return PosNames.empty() && PosPatterns.empty() && NegMatchers.empty();
0151   }
0152 };
0153 
0154 enum class AdjustKind { Set, Add, Subtract };
0155 
0156 struct AddressUpdate {
0157   uint64_t Value = 0;
0158   AdjustKind Kind = AdjustKind::Add;
0159 };
0160 
0161 struct SectionPatternAddressUpdate {
0162   NameMatcher SectionPattern;
0163   AddressUpdate Update;
0164 };
0165 
0166 enum class SymbolFlag {
0167   Global,
0168   Local,
0169   Weak,
0170   Default,
0171   Hidden,
0172   Protected,
0173   File,
0174   Section,
0175   Object,
0176   Function,
0177   IndirectFunction,
0178   Debug,
0179   Constructor,
0180   Warning,
0181   Indirect,
0182   Synthetic,
0183   UniqueObject,
0184 };
0185 
0186 // Symbol info specified by --add-symbol option. Symbol flags not supported
0187 // by a concrete format should be ignored.
0188 struct NewSymbolInfo {
0189   StringRef SymbolName;
0190   StringRef SectionName;
0191   uint64_t Value = 0;
0192   SmallVector<SymbolFlag, 0> Flags;
0193   SmallVector<StringRef, 0> BeforeSyms;
0194 };
0195 
0196 // Specify section name and section body for newly added or updated section.
0197 struct NewSectionInfo {
0198   NewSectionInfo() = default;
0199   NewSectionInfo(StringRef Name, std::unique_ptr<MemoryBuffer> &&Buffer)
0200       : SectionName(Name), SectionData(std::move(Buffer)) {}
0201 
0202   StringRef SectionName;
0203   std::shared_ptr<MemoryBuffer> SectionData;
0204 };
0205 
0206 // Configuration for copying/stripping a single file.
0207 struct CommonConfig {
0208   // Main input/output options
0209   StringRef InputFilename;
0210   FileFormat InputFormat = FileFormat::Unspecified;
0211   StringRef OutputFilename;
0212   FileFormat OutputFormat = FileFormat::Unspecified;
0213 
0214   // Only applicable when --output-format!=binary (e.g. elf64-x86-64).
0215   std::optional<MachineInfo> OutputArch;
0216 
0217   // Advanced options
0218   StringRef AddGnuDebugLink;
0219   // Cached gnu_debuglink's target CRC
0220   uint32_t GnuDebugLinkCRC32;
0221   std::optional<StringRef> ExtractPartition;
0222   uint8_t GapFill = 0;
0223   uint64_t PadTo = 0;
0224   StringRef SplitDWO;
0225   StringRef SymbolsPrefix;
0226   StringRef SymbolsPrefixRemove;
0227   StringRef AllocSectionsPrefix;
0228   DiscardType DiscardMode = DiscardType::None;
0229 
0230   // Repeated options
0231   SmallVector<NewSectionInfo, 0> AddSection;
0232   SmallVector<StringRef, 0> DumpSection;
0233   SmallVector<NewSectionInfo, 0> UpdateSection;
0234   SmallVector<SectionPatternAddressUpdate, 0> ChangeSectionAddress;
0235 
0236   // Section matchers
0237   NameMatcher KeepSection;
0238   NameMatcher OnlySection;
0239   NameMatcher ToRemove;
0240 
0241   // Symbol matchers
0242   NameMatcher SymbolsToGlobalize;
0243   NameMatcher SymbolsToKeep;
0244   NameMatcher SymbolsToLocalize;
0245   NameMatcher SymbolsToRemove;
0246   NameMatcher UnneededSymbolsToRemove;
0247   NameMatcher SymbolsToWeaken;
0248   NameMatcher SymbolsToKeepGlobal;
0249   NameMatcher SymbolsToSkip;
0250 
0251   // Map options
0252   StringMap<SectionRename> SectionsToRename;
0253   StringMap<uint64_t> SetSectionAlignment;
0254   StringMap<SectionFlagsUpdate> SetSectionFlags;
0255   StringMap<uint64_t> SetSectionType;
0256   StringMap<StringRef> SymbolsToRename;
0257 
0258   // Symbol info specified by --add-symbol option.
0259   SmallVector<NewSymbolInfo, 0> SymbolsToAdd;
0260 
0261   // Integer options
0262   int64_t ChangeSectionLMAValAll = 0;
0263 
0264   // Boolean options
0265   bool DeterministicArchives = true;
0266   bool ExtractDWO = false;
0267   bool ExtractMainPartition = false;
0268   bool OnlyKeepDebug = false;
0269   bool PreserveDates = false;
0270   bool StripAll = false;
0271   bool StripAllGNU = false;
0272   bool StripDWO = false;
0273   bool StripDebug = false;
0274   bool StripNonAlloc = false;
0275   bool StripSections = false;
0276   bool StripUnneeded = false;
0277   bool Weaken = false;
0278   bool DecompressDebugSections = false;
0279 
0280   DebugCompressionType CompressionType = DebugCompressionType::None;
0281 
0282   SmallVector<std::pair<NameMatcher, llvm::DebugCompressionType>, 0>
0283       compressSections;
0284 
0285   // ErrorCallback is used to handle recoverable errors. An Error returned
0286   // by the callback aborts the execution and is then returned to the caller.
0287   // If the callback is not set, the errors are not issued.
0288   std::function<Error(Error)> ErrorCallback;
0289 };
0290 
0291 } // namespace objcopy
0292 } // namespace llvm
0293 
0294 #endif // LLVM_OBJCOPY_COMMONCONFIG_H