diff options
Diffstat (limited to 'llvm/tools/llvm-objcopy/MachO/Object.h')
-rw-r--r-- | llvm/tools/llvm-objcopy/MachO/Object.h | 82 |
1 files changed, 68 insertions, 14 deletions
diff --git a/llvm/tools/llvm-objcopy/MachO/Object.h b/llvm/tools/llvm-objcopy/MachO/Object.h index 1cebf8253d19..dc2606eefa4a 100644 --- a/llvm/tools/llvm-objcopy/MachO/Object.h +++ b/llvm/tools/llvm-objcopy/MachO/Object.h @@ -14,6 +14,7 @@ #include "llvm/BinaryFormat/MachO.h" #include "llvm/MC/StringTableBuilder.h" #include "llvm/ObjectYAML/DWARFYAML.h" +#include "llvm/Support/StringSaver.h" #include "llvm/Support/YAMLTraits.h" #include <cstdint> #include <string> @@ -36,22 +37,32 @@ struct MachHeader { struct RelocationInfo; struct Section { - std::string Sectname; std::string Segname; - uint64_t Addr; - uint64_t Size; - uint32_t Offset; - uint32_t Align; - uint32_t RelOff; - uint32_t NReloc; - uint32_t Flags; - uint32_t Reserved1; - uint32_t Reserved2; - uint32_t Reserved3; - + std::string Sectname; + // CanonicalName is a string formatted as “<Segname>,<Sectname>". + std::string CanonicalName; + uint64_t Addr = 0; + uint64_t Size = 0; + uint32_t Offset = 0; + uint32_t Align = 0; + uint32_t RelOff = 0; + uint32_t NReloc = 0; + uint32_t Flags = 0; + uint32_t Reserved1 = 0; + uint32_t Reserved2 = 0; + uint32_t Reserved3 = 0; StringRef Content; std::vector<RelocationInfo> Relocations; + Section(StringRef SegName, StringRef SectName) + : Segname(SegName), Sectname(SectName), + CanonicalName((Twine(SegName) + Twine(',') + SectName).str()) {} + + Section(StringRef SegName, StringRef SectName, StringRef Content) + : Segname(SegName), Sectname(SectName), + CanonicalName((Twine(SegName) + Twine(',') + SectName).str()), + Content(Content) {} + MachO::SectionType getType() const { return static_cast<MachO::SectionType>(Flags & MachO::SECTION_TYPE); } @@ -72,19 +83,23 @@ struct LoadCommand { // The raw content of the payload of the load command (located right after the // corresponding struct). In some cases it is either empty or can be // copied-over without digging into its structure. - ArrayRef<uint8_t> Payload; + std::vector<uint8_t> Payload; // Some load commands can contain (inside the payload) an array of sections, // though the contents of the sections are stored separately. The struct // Section describes only sections' metadata and where to find the // corresponding content inside the binary. std::vector<Section> Sections; + + // Returns the segment name if the load command is a segment command. + Optional<StringRef> getSegmentName() const; }; // A symbol information. Fields which starts with "n_" are same as them in the // nlist. struct SymbolEntry { std::string Name; + bool Referenced = false; uint32_t Index; uint8_t n_type; uint8_t n_sect; @@ -107,11 +122,32 @@ struct SymbolEntry { struct SymbolTable { std::vector<std::unique_ptr<SymbolEntry>> Symbols; + using iterator = pointee_iterator< + std::vector<std::unique_ptr<SymbolEntry>>::const_iterator>; + + iterator begin() const { return iterator(Symbols.begin()); } + iterator end() const { return iterator(Symbols.end()); } + const SymbolEntry *getSymbolByIndex(uint32_t Index) const; + SymbolEntry *getSymbolByIndex(uint32_t Index); + void removeSymbols( + function_ref<bool(const std::unique_ptr<SymbolEntry> &)> ToRemove); +}; + +struct IndirectSymbolEntry { + // The original value in an indirect symbol table. Higher bits encode extra + // information (INDIRECT_SYMBOL_LOCAL and INDIRECT_SYMBOL_ABS). + uint32_t OriginalIndex; + /// The Symbol referenced by this entry. It's None if the index is + /// INDIRECT_SYMBOL_LOCAL or INDIRECT_SYMBOL_ABS. + Optional<SymbolEntry *> Symbol; + + IndirectSymbolEntry(uint32_t OriginalIndex, Optional<SymbolEntry *> Symbol) + : OriginalIndex(OriginalIndex), Symbol(Symbol) {} }; struct IndirectSymbolTable { - std::vector<uint32_t> Symbols; + std::vector<IndirectSymbolEntry> Symbols; }; /// The location of the string table inside the binary is described by LC_SYMTAB @@ -250,6 +286,24 @@ struct Object { Optional<size_t> DataInCodeCommandIndex; /// The index LC_FUNCTION_STARTS load comamnd if present. Optional<size_t> FunctionStartsCommandIndex; + + BumpPtrAllocator Alloc; + StringSaver NewSectionsContents; + + Object() : NewSectionsContents(Alloc) {} + + void removeSections(function_ref<bool(const Section &)> ToRemove); + void addLoadCommand(LoadCommand LC); + + /// Creates a new segment load command in the object and returns a reference + /// to the newly created load command. The caller should verify that SegName + /// is not too long (SegName.size() should be less than or equal to 16). + LoadCommand &addSegment(StringRef SegName); + + bool is64Bit() const { + return Header.Magic == MachO::MH_MAGIC_64 || + Header.Magic == MachO::MH_CIGAM_64; + } }; } // end namespace macho |