#include "llvm/Object/MachOObject.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/System/Host.h"
-#include "llvm/System/SwapByteOrder.h"
+#include "llvm/Support/Host.h"
+#include "llvm/Support/SwapByteOrder.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/Debug.h"
using namespace llvm;
using namespace llvm::object;
}
MachOObject::~MachOObject() {
- delete LoadCommands;
+ delete [] LoadCommands;
}
MachOObject *MachOObject::LoadFromBuffer(MemoryBuffer *Buffer,
return Object.take();
}
+StringRef MachOObject::getData(size_t Offset, size_t Size) const {
+ return Buffer->getBuffer().substr(Offset,Size);
+}
+
void MachOObject::RegisterStringTable(macho::SymtabLoadCommand &SLC) {
HasStringTable = true;
StringTable = Buffer->getBuffer().substr(SLC.StringTableOffset,
void SwapStruct(macho::DysymtabLoadCommand &Value) {
SwapValue(Value.Type);
SwapValue(Value.Size);
- SwapValue(Value.LocalSymbolIndex);
+ SwapValue(Value.LocalSymbolsIndex);
SwapValue(Value.NumLocalSymbols);
SwapValue(Value.ExternalSymbolsIndex);
SwapValue(Value.NumExternalSymbols);
ReadInMemoryStruct(*this, Buffer->getBuffer(), LCI.Offset, Res);
}
+template<>
+void SwapStruct(macho::LinkeditDataLoadCommand &Value) {
+ SwapValue(Value.Type);
+ SwapValue(Value.Size);
+ SwapValue(Value.DataOffset);
+ SwapValue(Value.DataSize);
+}
+void MachOObject::ReadLinkeditDataLoadCommand(const LoadCommandInfo &LCI,
+ InMemoryStruct<macho::LinkeditDataLoadCommand> &Res) const {
+ ReadInMemoryStruct(*this, Buffer->getBuffer(), LCI.Offset, Res);
+}
+
template<>
void SwapStruct(macho::IndirectSymbolTableEntry &Value) {
SwapValue(Value.Index);
Index * sizeof(macho::RelocationEntry));
ReadInMemoryStruct(*this, Buffer->getBuffer(), Offset, Res);
}
+
+template<>
+void SwapStruct(macho::SymbolTableEntry &Value) {
+ SwapValue(Value.StringIndex);
+ SwapValue(Value.Flags);
+ SwapValue(Value.Value);
+}
+void MachOObject::ReadSymbolTableEntry(uint64_t SymbolTableOffset,
+ unsigned Index,
+ InMemoryStruct<macho::SymbolTableEntry> &Res) const {
+ uint64_t Offset = (SymbolTableOffset +
+ Index * sizeof(macho::SymbolTableEntry));
+ ReadInMemoryStruct(*this, Buffer->getBuffer(), Offset, Res);
+}
+
+template<>
+void SwapStruct(macho::Symbol64TableEntry &Value) {
+ SwapValue(Value.StringIndex);
+ SwapValue(Value.Flags);
+ SwapValue(Value.Value);
+}
+void MachOObject::ReadSymbol64TableEntry(uint64_t SymbolTableOffset,
+ unsigned Index,
+ InMemoryStruct<macho::Symbol64TableEntry> &Res) const {
+ uint64_t Offset = (SymbolTableOffset +
+ Index * sizeof(macho::Symbol64TableEntry));
+ ReadInMemoryStruct(*this, Buffer->getBuffer(), Offset, Res);
+}
+
+
+void MachOObject::ReadULEB128s(uint64_t Index,
+ SmallVectorImpl<uint64_t> &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'; }
+void MachOObject::dumpHeader() const { printHeader(dbgs()); dbgs() << '\n'; }
+
+void MachOObject::printHeader(raw_ostream &O) const {
+ O << "('cputype', " << Header.CPUType << ")\n";
+ O << "('cpusubtype', " << Header.CPUSubtype << ")\n";
+ O << "('filetype', " << Header.FileType << ")\n";
+ O << "('num_load_commands', " << Header.NumLoadCommands << ")\n";
+ O << "('load_commands_size', " << Header.SizeOfLoadCommands << ")\n";
+ O << "('flag', " << Header.Flags << ")\n";
+
+ // Print extended header if 64-bit.
+ if (is64Bit())
+ O << "('reserved', " << Header64Ext.Reserved << ")\n";
+}
+
+void MachOObject::print(raw_ostream &O) const {
+ O << "Header:\n";
+ printHeader(O);
+ O << "Load Commands:\n";
+
+ O << "Buffer:\n";
+}