diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2020-01-17 20:45:01 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2020-01-17 20:45:01 +0000 |
commit | 706b4fc47bbc608932d3b491ae19a3b9cde9497b (patch) | |
tree | 4adf86a776049cbf7f69a1929c4babcbbef925eb /llvm/tools/llvm-objcopy/MachO/Object.cpp | |
parent | 7cc9cf2bf09f069cb2dd947ead05d0b54301fb71 (diff) |
Notes
Diffstat (limited to 'llvm/tools/llvm-objcopy/MachO/Object.cpp')
-rw-r--r-- | llvm/tools/llvm-objcopy/MachO/Object.cpp | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/llvm/tools/llvm-objcopy/MachO/Object.cpp b/llvm/tools/llvm-objcopy/MachO/Object.cpp index 264f39c28ed2..d3b4fdc2f633 100644 --- a/llvm/tools/llvm-objcopy/MachO/Object.cpp +++ b/llvm/tools/llvm-objcopy/MachO/Object.cpp @@ -10,6 +10,70 @@ const SymbolEntry *SymbolTable::getSymbolByIndex(uint32_t Index) const { return Symbols[Index].get(); } +SymbolEntry *SymbolTable::getSymbolByIndex(uint32_t Index) { + return const_cast<SymbolEntry *>( + static_cast<const SymbolTable *>(this)->getSymbolByIndex(Index)); +} + +void SymbolTable::removeSymbols( + function_ref<bool(const std::unique_ptr<SymbolEntry> &)> ToRemove) { + Symbols.erase( + std::remove_if(std::begin(Symbols), std::end(Symbols), ToRemove), + std::end(Symbols)); +} + +void Object::removeSections(function_ref<bool(const Section &)> ToRemove) { + for (LoadCommand &LC : LoadCommands) + LC.Sections.erase(std::remove_if(std::begin(LC.Sections), + std::end(LC.Sections), ToRemove), + std::end(LC.Sections)); +} + +void Object::addLoadCommand(LoadCommand LC) { + LoadCommands.push_back(std::move(LC)); +} + +template <typename SegmentType> +static void constructSegment(SegmentType &Seg, + llvm::MachO::LoadCommandType CmdType, + StringRef SegName) { + assert(SegName.size() <= sizeof(Seg.segname) && "too long segment name"); + memset(&Seg, 0, sizeof(SegmentType)); + Seg.cmd = CmdType; + strncpy(Seg.segname, SegName.data(), SegName.size()); +} + +LoadCommand &Object::addSegment(StringRef SegName) { + LoadCommand LC; + if (is64Bit()) + constructSegment(LC.MachOLoadCommand.segment_command_64_data, + MachO::LC_SEGMENT_64, SegName); + else + constructSegment(LC.MachOLoadCommand.segment_command_data, + MachO::LC_SEGMENT, SegName); + + LoadCommands.push_back(LC); + return LoadCommands.back(); +} + +/// Extracts a segment name from a string which is possibly non-null-terminated. +static StringRef extractSegmentName(const char *SegName) { + return StringRef(SegName, + strnlen(SegName, sizeof(MachO::segment_command::segname))); +} + +Optional<StringRef> LoadCommand::getSegmentName() const { + const MachO::macho_load_command &MLC = MachOLoadCommand; + switch (MLC.load_command_data.cmd) { + case MachO::LC_SEGMENT: + return extractSegmentName(MLC.segment_command_data.segname); + case MachO::LC_SEGMENT_64: + return extractSegmentName(MLC.segment_command_64_data.segname); + default: + return None; + } +} + } // end namespace macho } // end namespace objcopy } // end namespace llvm |