aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Object/MachOObjectFile.cpp
diff options
context:
space:
mode:
authorAntonio Frighetto <me@antoniofrighetto.com>2023-08-30 17:30:10 +0200
committerAntonio Frighetto <me@antoniofrighetto.com>2023-09-05 18:51:12 +0200
commit282bf213ee2f0fc0c259efa4e9f6283a1f1a2ae1 (patch)
treea24647c697cc9c3c0aef13512ef0536294c4089f /llvm/lib/Object/MachOObjectFile.cpp
parentd227c8a1200081fdab14e93165927787544c5f12 (diff)
downloadllvm-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.cpp68
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);
}