summaryrefslogtreecommitdiff
path: root/llvm/tools/llvm-objcopy/MachO/Object.h
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/tools/llvm-objcopy/MachO/Object.h')
-rw-r--r--llvm/tools/llvm-objcopy/MachO/Object.h82
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