diff options
author | Antonio Frighetto <me@antoniofrighetto.com> | 2023-08-30 17:30:10 +0200 |
---|---|---|
committer | Antonio Frighetto <me@antoniofrighetto.com> | 2023-09-05 18:51:12 +0200 |
commit | 282bf213ee2f0fc0c259efa4e9f6283a1f1a2ae1 (patch) | |
tree | a24647c697cc9c3c0aef13512ef0536294c4089f /llvm/lib/Object/MachOObjectFile.cpp | |
parent | d227c8a1200081fdab14e93165927787544c5f12 (diff) | |
download | llvm-282bf213ee2f0fc0c259efa4e9f6283a1f1a2ae1.zip llvm-282bf213ee2f0fc0c259efa4e9f6283a1f1a2ae1.tar.gz llvm-282bf213ee2f0fc0c259efa4e9f6283a1f1a2ae1.tar.bz2 |
[llvm-nm][MachO] Add support for `MH_FILESET`
Support printing of symbols for MachO of `MH_FILESET` type.
This is achieved by extending `dumpSymbolNamesFromObject`
to encompass fileset handling, and including an offset in
`MachOObjectFile` class to locate embedded MachO headers.
Differential Revision: https://reviews.llvm.org/D159294
Diffstat (limited to 'llvm/lib/Object/MachOObjectFile.cpp')
-rw-r--r-- | llvm/lib/Object/MachOObjectFile.cpp | 68 |
1 files changed, 43 insertions, 25 deletions
diff --git a/llvm/lib/Object/MachOObjectFile.cpp b/llvm/lib/Object/MachOObjectFile.cpp index 6ca83a9..aa57de1 100644 --- a/llvm/lib/Object/MachOObjectFile.cpp +++ b/llvm/lib/Object/MachOObjectFile.cpp @@ -108,9 +108,11 @@ getSectionPtr(const MachOObjectFile &O, MachOObjectFile::LoadCommandInfo L, return reinterpret_cast<const char*>(SectionAddr); } -static const char *getPtr(const MachOObjectFile &O, size_t Offset) { - assert(Offset <= O.getData().size()); - return O.getData().data() + Offset; +static const char *getPtr(const MachOObjectFile &O, size_t Offset, + size_t MachOFilesetEntryOffset = 0) { + assert(Offset <= O.getData().size() && + MachOFilesetEntryOffset <= O.getData().size()); + return O.getData().data() + Offset + MachOFilesetEntryOffset; } static MachO::nlist_base @@ -208,7 +210,8 @@ getFirstLoadCommandInfo(const MachOObjectFile &Obj) { if (sizeof(MachO::load_command) > Obj.getHeader().sizeofcmds) return malformedError("load command 0 extends past the end all load " "commands in the file"); - return getLoadCommandInfo(Obj, getPtr(Obj, HeaderSize), 0); + return getLoadCommandInfo( + Obj, getPtr(Obj, HeaderSize, Obj.getMachOFilesetEntryOffset()), 0); } static Expected<MachOObjectFile::LoadCommandInfo> @@ -217,7 +220,8 @@ getNextLoadCommandInfo(const MachOObjectFile &Obj, uint32_t LoadCommandIndex, unsigned HeaderSize = Obj.is64Bit() ? sizeof(MachO::mach_header_64) : sizeof(MachO::mach_header); if (L.Ptr + L.C.cmdsize + sizeof(MachO::load_command) > - Obj.getData().data() + HeaderSize + Obj.getHeader().sizeofcmds) + Obj.getData().data() + Obj.getMachOFilesetEntryOffset() + HeaderSize + + Obj.getHeader().sizeofcmds) return malformedError("load command " + Twine(LoadCommandIndex + 1) + " extends past the end all load commands in the file"); return getLoadCommandInfo(Obj, L.Ptr + L.C.cmdsize, LoadCommandIndex + 1); @@ -231,7 +235,8 @@ static void parseHeader(const MachOObjectFile &Obj, T &Header, "file"); return; } - if (auto HeaderOrErr = getStructOrErr<T>(Obj, getPtr(Obj, 0))) + if (auto HeaderOrErr = getStructOrErr<T>( + Obj, getPtr(Obj, 0, Obj.getMachOFilesetEntryOffset()))) Header = *HeaderOrErr; else Err = HeaderOrErr.takeError(); @@ -1247,12 +1252,12 @@ static bool isLoadCommandObsolete(uint32_t cmd) { Expected<std::unique_ptr<MachOObjectFile>> MachOObjectFile::create(MemoryBufferRef Object, bool IsLittleEndian, bool Is64Bits, uint32_t UniversalCputype, - uint32_t UniversalIndex) { + uint32_t UniversalIndex, + size_t MachOFilesetEntryOffset) { Error Err = Error::success(); - std::unique_ptr<MachOObjectFile> Obj( - new MachOObjectFile(std::move(Object), IsLittleEndian, - Is64Bits, Err, UniversalCputype, - UniversalIndex)); + std::unique_ptr<MachOObjectFile> Obj(new MachOObjectFile( + std::move(Object), IsLittleEndian, Is64Bits, Err, UniversalCputype, + UniversalIndex, MachOFilesetEntryOffset)); if (Err) return std::move(Err); return std::move(Obj); @@ -1261,8 +1266,10 @@ MachOObjectFile::create(MemoryBufferRef Object, bool IsLittleEndian, MachOObjectFile::MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian, bool Is64bits, Error &Err, uint32_t UniversalCputype, - uint32_t UniversalIndex) - : ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object) { + uint32_t UniversalIndex, + size_t MachOFilesetEntryOffset) + : ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object), + MachOFilesetEntryOffset(MachOFilesetEntryOffset) { ErrorAsOutParameter ErrAsOutParam(&Err); uint64_t SizeOfHeaders; uint32_t cputype; @@ -4761,6 +4768,11 @@ MachOObjectFile::getThreadCommand(const LoadCommandInfo &L) const { return getStruct<MachO::thread_command>(*this, L.Ptr); } +MachO::fileset_entry_command +MachOObjectFile::getFilesetEntryLoadCommand(const LoadCommandInfo &L) const { + return getStruct<MachO::fileset_entry_command>(*this, L.Ptr); +} + MachO::any_relocation_info MachOObjectFile::getRelocation(DataRefImpl Rel) const { uint32_t Offset; @@ -5300,23 +5312,29 @@ bool MachOObjectFile::isRelocatableObject() const { return getHeader().filetype == MachO::MH_OBJECT; } -Expected<std::unique_ptr<MachOObjectFile>> -ObjectFile::createMachOObjectFile(MemoryBufferRef Buffer, - uint32_t UniversalCputype, - uint32_t UniversalIndex) { +/// Create a MachOObjectFile instance from a given buffer. +/// +/// \param Buffer Memory buffer containing the MachO binary data. +/// \param UniversalCputype CPU type when the MachO part of a universal binary. +/// \param UniversalIndex Index of the MachO within a universal binary. +/// \param MachOFilesetEntryOffset Offset of the MachO entry in a fileset MachO. +/// \returns A std::unique_ptr to a MachOObjectFile instance on success. +Expected<std::unique_ptr<MachOObjectFile>> ObjectFile::createMachOObjectFile( + MemoryBufferRef Buffer, uint32_t UniversalCputype, uint32_t UniversalIndex, + size_t MachOFilesetEntryOffset) { StringRef Magic = Buffer.getBuffer().slice(0, 4); if (Magic == "\xFE\xED\xFA\xCE") - return MachOObjectFile::create(Buffer, false, false, - UniversalCputype, UniversalIndex); + return MachOObjectFile::create(Buffer, false, false, UniversalCputype, + UniversalIndex, MachOFilesetEntryOffset); if (Magic == "\xCE\xFA\xED\xFE") - return MachOObjectFile::create(Buffer, true, false, - UniversalCputype, UniversalIndex); + return MachOObjectFile::create(Buffer, true, false, UniversalCputype, + UniversalIndex, MachOFilesetEntryOffset); if (Magic == "\xFE\xED\xFA\xCF") - return MachOObjectFile::create(Buffer, false, true, - UniversalCputype, UniversalIndex); + return MachOObjectFile::create(Buffer, false, true, UniversalCputype, + UniversalIndex, MachOFilesetEntryOffset); if (Magic == "\xCF\xFA\xED\xFE") - return MachOObjectFile::create(Buffer, true, true, - UniversalCputype, UniversalIndex); + return MachOObjectFile::create(Buffer, true, true, UniversalCputype, + UniversalIndex, MachOFilesetEntryOffset); return make_error<GenericBinaryError>("Unrecognized MachO magic number", object_error::invalid_file_type); } |