diff --git a/include/llvm/Object/MachOObject.h b/include/llvm/Object/MachOObject.h index a7bf6eb7d85..51be847858a 100644 --- a/include/llvm/Object/MachOObject.h +++ b/include/llvm/Object/MachOObject.h @@ -174,6 +174,7 @@ public: void ReadSymbol64TableEntry( uint64_t SymbolTableOffset, unsigned Index, InMemoryStruct &Res) const; + void ReadULEB128s(uint64_t Index, SmallVectorImpl &Out) const; /// @} diff --git a/lib/Object/MachOObject.cpp b/lib/Object/MachOObject.cpp index 339b12043ae..9cdac8681dd 100644 --- a/lib/Object/MachOObject.cpp +++ b/lib/Object/MachOObject.cpp @@ -9,6 +9,7 @@ #include "llvm/Object/MachOObject.h" #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Host.h" #include "llvm/Support/SwapByteOrder.h" @@ -355,6 +356,31 @@ void MachOObject::ReadSymbol64TableEntry(uint64_t SymbolTableOffset, ReadInMemoryStruct(*this, Buffer->getBuffer(), Offset, Res); } + +void MachOObject::ReadULEB128s(uint64_t Index, + SmallVectorImpl &Out) const { + const char *ptr = Buffer->getBufferStart() + Index; + uint64_t data = 0; + uint64_t delta = 0; + uint32_t shift = 0; + while (true) { + assert(ptr < Buffer->getBufferEnd() && "index out of bounds"); + assert(shift < 64 && "too big for uint64_t"); + + uint8_t byte = *ptr++; + delta |= ((byte & 0x7F) << shift); + shift += 7; + if (byte < 0x80) { + if (delta == 0) + break; + data += delta; + Out.push_back(data); + delta = 0; + shift = 0; + } + } +} + /* ** */ // Object Dumping Facilities void MachOObject::dump() const { print(dbgs()); dbgs() << '\n'; } diff --git a/tools/macho-dump/macho-dump.cpp b/tools/macho-dump/macho-dump.cpp index e3c3c7cbe64..2b22c3b0fd9 100644 --- a/tools/macho-dump/macho-dump.cpp +++ b/tools/macho-dump/macho-dump.cpp @@ -318,7 +318,16 @@ static int DumpLinkeditDataCommand(MachOObject &Obj, return Error("unable to read segment load command"); outs() << " ('dataoff', " << LLC->DataOffset << ")\n" - << " ('datasize', " << LLC->DataSize << ")\n"; + << " ('datasize', " << LLC->DataSize << ")\n" + << " ('_addresses', [\n"; + + SmallVector Addresses; + Obj.ReadULEB128s(LLC->DataOffset, Addresses); + for (unsigned i = 0, e = Addresses.size(); i != e; ++i) + outs() << " # Address " << i << '\n' + << " ('address', " << format("0x%x", Addresses[i]) << "),\n"; + + outs() << " ])\n"; return 0; }