[llvm] r180624 - Use llvm/Object/MachO.h in macho-dumper. Drop the old macho parser.
Eric Christopher
echristo at gmail.com
Fri Apr 26 14:33:26 PDT 2013
Woot!
Thanks Rafael!
-eric
On Fri, Apr 26, 2013 at 9:07 PM, Rafael Espindola
<rafael.espindola at gmail.com> wrote:
> Author: rafael
> Date: Fri Apr 26 15:07:33 2013
> New Revision: 180624
>
> URL: http://llvm.org/viewvc/llvm-project?rev=180624&view=rev
> Log:
> Use llvm/Object/MachO.h in macho-dumper. Drop the old macho parser.
>
> For Mach-O there were 2 implementations for parsing object files. A
> standalone llvm/Object/MachOObject.h and llvm/Object/MachO.h which
> implements the generic interface in llvm/Object/ObjectFile.h.
>
> This patch adds the missing features to MachO.h, moves macho-dump to
> use MachO.h and removes ObjectFile.h.
>
> In addition to making sure that check-all is clean, I checked that the
> new version produces exactly the same output in all Mach-O files in a
> llvm+clang build directory (including executables and shared
> libraries).
>
> To test the performance, I ran macho-dump over all the files in a
> llvm+clang build directory again, but this time redirecting the output
> to /dev/null. Both the old and new versions take about 4.6 seconds
> (2.5 user) to finish.
>
> Removed:
> llvm/trunk/include/llvm/ADT/InMemoryStruct.h
> llvm/trunk/include/llvm/Object/MachOObject.h
> llvm/trunk/lib/Object/MachOObject.cpp
> Modified:
> llvm/trunk/include/llvm/Object/MachO.h
> llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h
> llvm/trunk/lib/Object/CMakeLists.txt
> llvm/trunk/lib/Object/MachOObjectFile.cpp
> llvm/trunk/tools/llvm-rtdyld/llvm-rtdyld.cpp
> llvm/trunk/tools/macho-dump/macho-dump.cpp
>
> Removed: llvm/trunk/include/llvm/ADT/InMemoryStruct.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/InMemoryStruct.h?rev=180623&view=auto
> ==============================================================================
> --- llvm/trunk/include/llvm/ADT/InMemoryStruct.h (original)
> +++ llvm/trunk/include/llvm/ADT/InMemoryStruct.h (removed)
> @@ -1,77 +0,0 @@
> -//===- InMemoryStruct.h - Indirect Struct Access Smart Pointer --*- C++ -*-===//
> -//
> -// The LLVM Compiler Infrastructure
> -//
> -// This file is distributed under the University of Illinois Open Source
> -// License. See LICENSE.TXT for details.
> -//
> -//===----------------------------------------------------------------------===//
> -
> -#ifndef LLVM_ADT_INMEMORYSTRUCT_H
> -#define LLVM_ADT_INMEMORYSTRUCT_H
> -
> -#include <cassert>
> -
> -namespace llvm {
> -
> -/// \brief Helper object for abstracting access to an in-memory structure which
> -/// may require some kind of temporary storage.
> -///
> -/// This class is designed to be used for accessing file data structures which
> -/// in the common case can be accessed from a direct pointer to a memory mapped
> -/// object, but which in some cases may require indirect access to a temporary
> -/// structure (which, for example, may have undergone endianness translation).
> -template<typename T>
> -class InMemoryStruct {
> - typedef T value_type;
> - typedef value_type &reference;
> - typedef value_type *pointer;
> - typedef const value_type &const_reference;
> - typedef const value_type *const_pointer;
> -
> - /// \brief The smart pointer target.
> - value_type *Target;
> -
> - /// \brief A temporary object which can be used as a target of the smart
> - /// pointer.
> - value_type Contents;
> -
> -private:
> -
> -public:
> - InMemoryStruct() : Target(0) {}
> - InMemoryStruct(reference Value) : Target(&Contents), Contents(Value) {}
> - InMemoryStruct(pointer Value) : Target(Value) {}
> - InMemoryStruct(const InMemoryStruct<T> &Value) { *this = Value; }
> -
> - void operator=(const InMemoryStruct<T> &Value) {
> - if (Value.Target != &Value.Contents) {
> - Target = Value.Target;
> - } else {
> - Target = &Contents;
> - Contents = Value.Contents;
> - }
> - }
> -
> - const_reference operator*() const {
> - assert(Target && "Cannot dereference null pointer");
> - return *Target;
> - }
> - reference operator*() {
> - assert(Target && "Cannot dereference null pointer");
> - return *Target;
> - }
> -
> - const_pointer operator->() const {
> - return Target;
> - }
> - pointer operator->() {
> - return Target;
> - }
> -
> - operator bool() const { return Target != 0; }
> -};
> -
> -}
> -
> -#endif
>
> Modified: llvm/trunk/include/llvm/Object/MachO.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/MachO.h?rev=180624&r1=180623&r2=180624&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/Object/MachO.h (original)
> +++ llvm/trunk/include/llvm/Object/MachO.h Fri Apr 26 15:07:33 2013
> @@ -106,6 +106,9 @@ public:
>
> virtual StringRef getLoadName() const;
>
> + relocation_iterator getSectionRelBegin(unsigned Index) const;
> + relocation_iterator getSectionRelEnd(unsigned Index) const;
> +
> // In a MachO file, sections have a segment name. This is used in the .o
> // files. They have a single segment, but this field specifies which segment
> // a section should be put in in the final object.
> @@ -134,14 +137,32 @@ public:
> // MachO specific structures.
> macho::Section getSection(DataRefImpl DRI) const;
> macho::Section64 getSection64(DataRefImpl DRI) const;
> + macho::Section getSection(const LoadCommandInfo &L, unsigned Index) const;
> + macho::Section64 getSection64(const LoadCommandInfo &L, unsigned Index) const;
> macho::SymbolTableEntry getSymbolTableEntry(DataRefImpl DRI) const;
> macho::Symbol64TableEntry getSymbol64TableEntry(DataRefImpl DRI) const;
> +
> macho::LinkeditDataLoadCommand
> getLinkeditDataLoadCommand(const LoadCommandInfo &L) const;
> + macho::SegmentLoadCommand
> + getSegmentLoadCommand(const LoadCommandInfo &L) const;
> + macho::Segment64LoadCommand
> + getSegment64LoadCommand(const LoadCommandInfo &L) const;
> + macho::LinkerOptionsLoadCommand
> + getLinkerOptionsLoadCommand(const LoadCommandInfo &L) const;
> +
> macho::RelocationEntry getRelocation(DataRefImpl Rel) const;
> macho::Header getHeader() const;
> + macho::Header64Ext getHeader64Ext() const;
> + macho::IndirectSymbolTableEntry
> + getIndirectSymbolTableEntry(const macho::DysymtabLoadCommand &DLC,
> + unsigned Index) const;
> + macho::DataInCodeTableEntry getDataInCodeTableEntry(uint32_t DataOffset,
> + unsigned Index) const;
> macho::SymtabLoadCommand getSymtabLoadCommand() const;
> + macho::DysymtabLoadCommand getDysymtabLoadCommand() const;
>
> + StringRef getStringTableData() const;
> bool is64Bit() const;
> void ReadULEB128s(uint64_t Index, SmallVectorImpl<uint64_t> &Out) const;
>
> @@ -153,6 +174,7 @@ private:
> typedef SmallVector<const char*, 1> SectionList;
> SectionList Sections;
> const char *SymtabLoadCmd;
> + const char *DysymtabLoadCmd;
> };
>
> }
>
> Removed: llvm/trunk/include/llvm/Object/MachOObject.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/MachOObject.h?rev=180623&view=auto
> ==============================================================================
> --- llvm/trunk/include/llvm/Object/MachOObject.h (original)
> +++ llvm/trunk/include/llvm/Object/MachOObject.h (removed)
> @@ -1,212 +0,0 @@
> -//===- MachOObject.h - Mach-O Object File Wrapper ---------------*- C++ -*-===//
> -//
> -// The LLVM Compiler Infrastructure
> -//
> -// This file is distributed under the University of Illinois Open Source
> -// License. See LICENSE.TXT for details.
> -//
> -//===----------------------------------------------------------------------===//
> -
> -#ifndef LLVM_OBJECT_MACHOOBJECT_H
> -#define LLVM_OBJECT_MACHOOBJECT_H
> -
> -#include "llvm/ADT/InMemoryStruct.h"
> -#include "llvm/ADT/OwningPtr.h"
> -#include "llvm/ADT/StringRef.h"
> -#include "llvm/Object/MachOFormat.h"
> -#include <string>
> -
> -namespace llvm {
> -
> -class MemoryBuffer;
> -class raw_ostream;
> -
> -namespace object {
> -
> -/// \brief Wrapper object for manipulating Mach-O object files.
> -///
> -/// This class is designed to implement a full-featured, efficient, portable,
> -/// and robust Mach-O interface to Mach-O object files. It does not attempt to
> -/// smooth over rough edges in the Mach-O format or generalize access to object
> -/// independent features.
> -///
> -/// The class is designed around accessing the Mach-O object which is expected
> -/// to be fully loaded into memory.
> -///
> -/// This class is *not* suitable for concurrent use. For efficient operation,
> -/// the class uses APIs which rely on the ability to cache the results of
> -/// certain calls in internal objects which are not safe for concurrent
> -/// access. This allows the API to be zero-copy on the common paths.
> -//
> -// FIXME: It would be cool if we supported a "paged" MemoryBuffer
> -// implementation. This would allow us to implement a more sensible version of
> -// MemoryObject which can work like a MemoryBuffer, but be more efficient for
> -// objects which are in the current address space.
> -class MachOObject {
> -public:
> - struct LoadCommandInfo {
> - /// The load command information.
> - macho::LoadCommand Command;
> -
> - /// The offset to the start of the load command in memory.
> - uint64_t Offset;
> - };
> -
> -private:
> - OwningPtr<MemoryBuffer> Buffer;
> -
> - /// Whether the object is little endian.
> - bool IsLittleEndian;
> - /// Whether the object is 64-bit.
> - bool Is64Bit;
> - /// Whether the object is swapped endianness from the host.
> - bool IsSwappedEndian;
> - /// Whether the string table has been registered.
> - bool HasStringTable;
> -
> - /// The cached information on the load commands.
> - LoadCommandInfo *LoadCommands;
> - mutable unsigned NumLoadedCommands;
> -
> - /// The cached copy of the header.
> - macho::Header Header;
> - macho::Header64Ext Header64Ext;
> -
> - /// Cache string table information.
> - StringRef StringTable;
> -
> -private:
> - MachOObject(MemoryBuffer *Buffer, bool IsLittleEndian, bool Is64Bit);
> -
> -public:
> - ~MachOObject();
> -
> - /// \brief Load a Mach-O object from a MemoryBuffer object.
> - ///
> - /// \param Buffer - The buffer to load the object from. This routine takes
> - /// exclusive ownership of the buffer (which is passed to the returned object
> - /// on success).
> - /// \param ErrorStr [out] - If given, will be set to a user readable error
> - /// message on failure.
> - /// \returns The loaded object, or null on error.
> - static MachOObject *LoadFromBuffer(MemoryBuffer *Buffer,
> - std::string *ErrorStr = 0);
> -
> - /// @name File Information
> - /// @{
> -
> - bool isLittleEndian() const { return IsLittleEndian; }
> - bool isSwappedEndian() const { return IsSwappedEndian; }
> - bool is64Bit() const { return Is64Bit; }
> -
> - unsigned getHeaderSize() const {
> - return Is64Bit ? macho::Header64Size : macho::Header32Size;
> - }
> -
> - StringRef getData(size_t Offset, size_t Size) const;
> -
> - /// @}
> - /// @name String Table Data
> - /// @{
> -
> - StringRef getStringTableData() const {
> - assert(HasStringTable && "String table has not been registered!");
> - return StringTable;
> - }
> -
> - StringRef getStringAtIndex(unsigned Index) const {
> - size_t End = getStringTableData().find('\0', Index);
> - return getStringTableData().slice(Index, End);
> - }
> -
> - void RegisterStringTable(macho::SymtabLoadCommand &SLC);
> -
> - /// @}
> - /// @name Object Header Access
> - /// @{
> -
> - const macho::Header &getHeader() const { return Header; }
> - const macho::Header64Ext &getHeader64Ext() const {
> - assert(is64Bit() && "Invalid access!");
> - return Header64Ext;
> - }
> -
> - /// @}
> - /// @name Object Structure Access
> - /// @{
> -
> - // TODO: Would be useful to have an iterator based version
> - // of this.
> - /// \brief Retrieve the information for the given load command.
> - const LoadCommandInfo &getLoadCommandInfo(unsigned Index) const;
> -
> - void ReadSegmentLoadCommand(
> - const LoadCommandInfo &LCI,
> - InMemoryStruct<macho::SegmentLoadCommand> &Res) const;
> - void ReadSegment64LoadCommand(
> - const LoadCommandInfo &LCI,
> - InMemoryStruct<macho::Segment64LoadCommand> &Res) const;
> - void ReadSymtabLoadCommand(
> - const LoadCommandInfo &LCI,
> - InMemoryStruct<macho::SymtabLoadCommand> &Res) const;
> - void ReadDysymtabLoadCommand(
> - const LoadCommandInfo &LCI,
> - InMemoryStruct<macho::DysymtabLoadCommand> &Res) const;
> - void ReadLinkeditDataLoadCommand(
> - const LoadCommandInfo &LCI,
> - InMemoryStruct<macho::LinkeditDataLoadCommand> &Res) const;
> - void ReadLinkerOptionsLoadCommand(
> - const LoadCommandInfo &LCI,
> - InMemoryStruct<macho::LinkerOptionsLoadCommand> &Res) const;
> - void ReadIndirectSymbolTableEntry(
> - const macho::DysymtabLoadCommand &DLC,
> - unsigned Index,
> - InMemoryStruct<macho::IndirectSymbolTableEntry> &Res) const;
> - void ReadSection(
> - const LoadCommandInfo &LCI,
> - unsigned Index,
> - InMemoryStruct<macho::Section> &Res) const;
> - void ReadSection64(
> - const LoadCommandInfo &LCI,
> - unsigned Index,
> - InMemoryStruct<macho::Section64> &Res) const;
> - void ReadRelocationEntry(
> - uint64_t RelocationTableOffset, unsigned Index,
> - InMemoryStruct<macho::RelocationEntry> &Res) const;
> - void ReadSymbolTableEntry(
> - uint64_t SymbolTableOffset, unsigned Index,
> - InMemoryStruct<macho::SymbolTableEntry> &Res) const;
> - void ReadSymbol64TableEntry(
> - uint64_t SymbolTableOffset, unsigned Index,
> - InMemoryStruct<macho::Symbol64TableEntry> &Res) const;
> - void ReadDataInCodeTableEntry(
> - uint64_t TableOffset, unsigned Index,
> - InMemoryStruct<macho::DataInCodeTableEntry> &Res) const;
> - void ReadULEB128s(uint64_t Index, SmallVectorImpl<uint64_t> &Out) const;
> -
> - /// @}
> -
> - /// @name Object Dump Facilities
> - /// @{
> - /// dump - Support for debugging, callable in GDB: V->dump()
> - //
> - void dump() const;
> - void dumpHeader() const;
> -
> - /// print - Implement operator<< on Value.
> - ///
> - void print(raw_ostream &O) const;
> - void printHeader(raw_ostream &O) const;
> -
> - /// @}
> -};
> -
> -inline raw_ostream &operator<<(raw_ostream &OS, const MachOObject &V) {
> - V.print(OS);
> - return OS;
> -}
> -
> -} // end namespace object
> -} // end namespace llvm
> -
> -#endif
>
> Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h?rev=180624&r1=180623&r2=180624&view=diff
> ==============================================================================
> --- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h (original)
> +++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.h Fri Apr 26 15:07:33 2013
> @@ -16,7 +16,7 @@
>
> #include "RuntimeDyldImpl.h"
> #include "llvm/ADT/IndexedMap.h"
> -#include "llvm/Object/MachOObject.h"
> +#include "llvm/Object/MachO.h"
> #include "llvm/Support/Format.h"
>
> using namespace llvm;
>
> Modified: llvm/trunk/lib/Object/CMakeLists.txt
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/CMakeLists.txt?rev=180624&r1=180623&r2=180624&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Object/CMakeLists.txt (original)
> +++ llvm/trunk/lib/Object/CMakeLists.txt Fri Apr 26 15:07:33 2013
> @@ -4,7 +4,6 @@ add_llvm_library(LLVMObject
> COFFObjectFile.cpp
> ELFObjectFile.cpp
> Error.cpp
> - MachOObject.cpp
> MachOObjectFile.cpp
> Object.cpp
> ObjectFile.cpp
>
> Removed: llvm/trunk/lib/Object/MachOObject.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/MachOObject.cpp?rev=180623&view=auto
> ==============================================================================
> --- llvm/trunk/lib/Object/MachOObject.cpp (original)
> +++ llvm/trunk/lib/Object/MachOObject.cpp (removed)
> @@ -1,422 +0,0 @@
> -//===- MachOObject.cpp - Mach-O Object File Wrapper -----------------------===//
> -//
> -// The LLVM Compiler Infrastructure
> -//
> -// This file is distributed under the University of Illinois Open Source
> -// License. See LICENSE.TXT for details.
> -//
> -//===----------------------------------------------------------------------===//
> -
> -#include "llvm/Object/MachOObject.h"
> -#include "llvm/ADT/SmallVector.h"
> -#include "llvm/ADT/StringRef.h"
> -#include "llvm/Support/DataExtractor.h"
> -#include "llvm/Support/Debug.h"
> -#include "llvm/Support/Host.h"
> -#include "llvm/Support/MemoryBuffer.h"
> -#include "llvm/Support/SwapByteOrder.h"
> -#include "llvm/Support/raw_ostream.h"
> -
> -using namespace llvm;
> -using namespace llvm::object;
> -
> -/* Translation Utilities */
> -
> -template<typename T>
> -static void SwapValue(T &Value) {
> - Value = sys::SwapByteOrder(Value);
> -}
> -
> -template<typename T>
> -static void SwapStruct(T &Value);
> -
> -template<typename T>
> -static void ReadInMemoryStruct(const MachOObject &MOO,
> - StringRef Buffer, uint64_t Base,
> - InMemoryStruct<T> &Res) {
> - typedef T struct_type;
> - uint64_t Size = sizeof(struct_type);
> -
> - // Check that the buffer contains the expected data.
> - if (Base + Size > Buffer.size()) {
> - Res = 0;
> - return;
> - }
> -
> - // Check whether we can return a direct pointer.
> - struct_type *Ptr = reinterpret_cast<struct_type *>(
> - const_cast<char *>(Buffer.data() + Base));
> - if (!MOO.isSwappedEndian()) {
> - Res = Ptr;
> - return;
> - }
> -
> - // Otherwise, copy the struct and translate the values.
> - Res = *Ptr;
> - SwapStruct(*Res);
> -}
> -
> -/* *** */
> -
> -MachOObject::MachOObject(MemoryBuffer *Buffer_, bool IsLittleEndian_,
> - bool Is64Bit_)
> - : Buffer(Buffer_), IsLittleEndian(IsLittleEndian_), Is64Bit(Is64Bit_),
> - IsSwappedEndian(IsLittleEndian != sys::IsLittleEndianHost),
> - HasStringTable(false), LoadCommands(0), NumLoadedCommands(0) {
> - // Load the common header.
> - memcpy(&Header, Buffer->getBuffer().data(), sizeof(Header));
> - if (IsSwappedEndian) {
> - SwapValue(Header.Magic);
> - SwapValue(Header.CPUType);
> - SwapValue(Header.CPUSubtype);
> - SwapValue(Header.FileType);
> - SwapValue(Header.NumLoadCommands);
> - SwapValue(Header.SizeOfLoadCommands);
> - SwapValue(Header.Flags);
> - }
> -
> - if (is64Bit()) {
> - memcpy(&Header64Ext, Buffer->getBuffer().data() + sizeof(Header),
> - sizeof(Header64Ext));
> - if (IsSwappedEndian) {
> - SwapValue(Header64Ext.Reserved);
> - }
> - }
> -
> - // Create the load command array if sane.
> - if (getHeader().NumLoadCommands < (1 << 20))
> - LoadCommands = new LoadCommandInfo[getHeader().NumLoadCommands];
> -}
> -
> -MachOObject::~MachOObject() {
> - delete [] LoadCommands;
> -}
> -
> -MachOObject *MachOObject::LoadFromBuffer(MemoryBuffer *Buffer,
> - std::string *ErrorStr) {
> - // First, check the magic value and initialize the basic object info.
> - bool IsLittleEndian = false, Is64Bit = false;
> - StringRef Magic = Buffer->getBuffer().slice(0, 4);
> - if (Magic == "\xFE\xED\xFA\xCE") {
> - } else if (Magic == "\xCE\xFA\xED\xFE") {
> - IsLittleEndian = true;
> - } else if (Magic == "\xFE\xED\xFA\xCF") {
> - Is64Bit = true;
> - } else if (Magic == "\xCF\xFA\xED\xFE") {
> - IsLittleEndian = true;
> - Is64Bit = true;
> - } else {
> - if (ErrorStr) *ErrorStr = "not a Mach object file (invalid magic)";
> - return 0;
> - }
> -
> - // Ensure that the at least the full header is present.
> - unsigned HeaderSize = Is64Bit ? macho::Header64Size : macho::Header32Size;
> - if (Buffer->getBufferSize() < HeaderSize) {
> - if (ErrorStr) *ErrorStr = "not a Mach object file (invalid header)";
> - return 0;
> - }
> -
> - OwningPtr<MachOObject> Object(new MachOObject(Buffer, IsLittleEndian,
> - Is64Bit));
> -
> - // Check for bogus number of load commands.
> - if (Object->getHeader().NumLoadCommands >= (1 << 20)) {
> - if (ErrorStr) *ErrorStr = "not a Mach object file (unreasonable header)";
> - return 0;
> - }
> -
> - if (ErrorStr) *ErrorStr = "";
> - 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,
> - SLC.StringTableSize);
> -}
> -
> -const MachOObject::LoadCommandInfo &
> -MachOObject::getLoadCommandInfo(unsigned Index) const {
> - assert(Index < getHeader().NumLoadCommands && "Invalid index!");
> -
> - // Load the command, if necessary.
> - if (Index >= NumLoadedCommands) {
> - uint64_t Offset;
> - if (Index == 0) {
> - Offset = getHeaderSize();
> - } else {
> - const LoadCommandInfo &Prev = getLoadCommandInfo(Index - 1);
> - Offset = Prev.Offset + Prev.Command.Size;
> - }
> -
> - LoadCommandInfo &Info = LoadCommands[Index];
> - memcpy(&Info.Command, Buffer->getBuffer().data() + Offset,
> - sizeof(macho::LoadCommand));
> - if (IsSwappedEndian) {
> - SwapValue(Info.Command.Type);
> - SwapValue(Info.Command.Size);
> - }
> - Info.Offset = Offset;
> - NumLoadedCommands = Index + 1;
> - }
> -
> - return LoadCommands[Index];
> -}
> -
> -template<>
> -void SwapStruct(macho::SegmentLoadCommand &Value) {
> - SwapValue(Value.Type);
> - SwapValue(Value.Size);
> - SwapValue(Value.VMAddress);
> - SwapValue(Value.VMSize);
> - SwapValue(Value.FileOffset);
> - SwapValue(Value.FileSize);
> - SwapValue(Value.MaxVMProtection);
> - SwapValue(Value.InitialVMProtection);
> - SwapValue(Value.NumSections);
> - SwapValue(Value.Flags);
> -}
> -void MachOObject::ReadSegmentLoadCommand(const LoadCommandInfo &LCI,
> - InMemoryStruct<macho::SegmentLoadCommand> &Res) const {
> - ReadInMemoryStruct(*this, Buffer->getBuffer(), LCI.Offset, Res);
> -}
> -
> -template<>
> -void SwapStruct(macho::Segment64LoadCommand &Value) {
> - SwapValue(Value.Type);
> - SwapValue(Value.Size);
> - SwapValue(Value.VMAddress);
> - SwapValue(Value.VMSize);
> - SwapValue(Value.FileOffset);
> - SwapValue(Value.FileSize);
> - SwapValue(Value.MaxVMProtection);
> - SwapValue(Value.InitialVMProtection);
> - SwapValue(Value.NumSections);
> - SwapValue(Value.Flags);
> -}
> -void MachOObject::ReadSegment64LoadCommand(const LoadCommandInfo &LCI,
> - InMemoryStruct<macho::Segment64LoadCommand> &Res) const {
> - ReadInMemoryStruct(*this, Buffer->getBuffer(), LCI.Offset, Res);
> -}
> -
> -template<>
> -void SwapStruct(macho::SymtabLoadCommand &Value) {
> - SwapValue(Value.Type);
> - SwapValue(Value.Size);
> - SwapValue(Value.SymbolTableOffset);
> - SwapValue(Value.NumSymbolTableEntries);
> - SwapValue(Value.StringTableOffset);
> - SwapValue(Value.StringTableSize);
> -}
> -void MachOObject::ReadSymtabLoadCommand(const LoadCommandInfo &LCI,
> - InMemoryStruct<macho::SymtabLoadCommand> &Res) const {
> - ReadInMemoryStruct(*this, Buffer->getBuffer(), LCI.Offset, Res);
> -}
> -
> -template<>
> -void SwapStruct(macho::DysymtabLoadCommand &Value) {
> - SwapValue(Value.Type);
> - SwapValue(Value.Size);
> - SwapValue(Value.LocalSymbolsIndex);
> - SwapValue(Value.NumLocalSymbols);
> - SwapValue(Value.ExternalSymbolsIndex);
> - SwapValue(Value.NumExternalSymbols);
> - SwapValue(Value.UndefinedSymbolsIndex);
> - SwapValue(Value.NumUndefinedSymbols);
> - SwapValue(Value.TOCOffset);
> - SwapValue(Value.NumTOCEntries);
> - SwapValue(Value.ModuleTableOffset);
> - SwapValue(Value.NumModuleTableEntries);
> - SwapValue(Value.ReferenceSymbolTableOffset);
> - SwapValue(Value.NumReferencedSymbolTableEntries);
> - SwapValue(Value.IndirectSymbolTableOffset);
> - SwapValue(Value.NumIndirectSymbolTableEntries);
> - SwapValue(Value.ExternalRelocationTableOffset);
> - SwapValue(Value.NumExternalRelocationTableEntries);
> - SwapValue(Value.LocalRelocationTableOffset);
> - SwapValue(Value.NumLocalRelocationTableEntries);
> -}
> -void MachOObject::ReadDysymtabLoadCommand(const LoadCommandInfo &LCI,
> - InMemoryStruct<macho::DysymtabLoadCommand> &Res) const {
> - 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::LinkerOptionsLoadCommand &Value) {
> - SwapValue(Value.Type);
> - SwapValue(Value.Size);
> - SwapValue(Value.Count);
> -}
> -void MachOObject::ReadLinkerOptionsLoadCommand(const LoadCommandInfo &LCI,
> - InMemoryStruct<macho::LinkerOptionsLoadCommand> &Res) const {
> - ReadInMemoryStruct(*this, Buffer->getBuffer(), LCI.Offset, Res);
> -}
> -
> -template<>
> -void SwapStruct(macho::IndirectSymbolTableEntry &Value) {
> - SwapValue(Value.Index);
> -}
> -void
> -MachOObject::ReadIndirectSymbolTableEntry(const macho::DysymtabLoadCommand &DLC,
> - unsigned Index,
> - InMemoryStruct<macho::IndirectSymbolTableEntry> &Res) const {
> - uint64_t Offset = (DLC.IndirectSymbolTableOffset +
> - Index * sizeof(macho::IndirectSymbolTableEntry));
> - ReadInMemoryStruct(*this, Buffer->getBuffer(), Offset, Res);
> -}
> -
> -
> -template<>
> -void SwapStruct(macho::Section &Value) {
> - SwapValue(Value.Address);
> - SwapValue(Value.Size);
> - SwapValue(Value.Offset);
> - SwapValue(Value.Align);
> - SwapValue(Value.RelocationTableOffset);
> - SwapValue(Value.NumRelocationTableEntries);
> - SwapValue(Value.Flags);
> - SwapValue(Value.Reserved1);
> - SwapValue(Value.Reserved2);
> -}
> -void MachOObject::ReadSection(const LoadCommandInfo &LCI,
> - unsigned Index,
> - InMemoryStruct<macho::Section> &Res) const {
> - assert(LCI.Command.Type == macho::LCT_Segment &&
> - "Unexpected load command info!");
> - uint64_t Offset = (LCI.Offset + sizeof(macho::SegmentLoadCommand) +
> - Index * sizeof(macho::Section));
> - ReadInMemoryStruct(*this, Buffer->getBuffer(), Offset, Res);
> -}
> -
> -template<>
> -void SwapStruct(macho::Section64 &Value) {
> - SwapValue(Value.Address);
> - SwapValue(Value.Size);
> - SwapValue(Value.Offset);
> - SwapValue(Value.Align);
> - SwapValue(Value.RelocationTableOffset);
> - SwapValue(Value.NumRelocationTableEntries);
> - SwapValue(Value.Flags);
> - SwapValue(Value.Reserved1);
> - SwapValue(Value.Reserved2);
> - SwapValue(Value.Reserved3);
> -}
> -void MachOObject::ReadSection64(const LoadCommandInfo &LCI,
> - unsigned Index,
> - InMemoryStruct<macho::Section64> &Res) const {
> - assert(LCI.Command.Type == macho::LCT_Segment64 &&
> - "Unexpected load command info!");
> - uint64_t Offset = (LCI.Offset + sizeof(macho::Segment64LoadCommand) +
> - Index * sizeof(macho::Section64));
> - ReadInMemoryStruct(*this, Buffer->getBuffer(), Offset, Res);
> -}
> -
> -template<>
> -void SwapStruct(macho::RelocationEntry &Value) {
> - SwapValue(Value.Word0);
> - SwapValue(Value.Word1);
> -}
> -void MachOObject::ReadRelocationEntry(uint64_t RelocationTableOffset,
> - unsigned Index,
> - InMemoryStruct<macho::RelocationEntry> &Res) const {
> - uint64_t Offset = (RelocationTableOffset +
> - 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);
> -}
> -
> -template<>
> -void SwapStruct(macho::DataInCodeTableEntry &Value) {
> - SwapValue(Value.Offset);
> - SwapValue(Value.Length);
> - SwapValue(Value.Kind);
> -}
> -void MachOObject::ReadDataInCodeTableEntry(uint64_t TableOffset,
> - unsigned Index,
> - InMemoryStruct<macho::DataInCodeTableEntry> &Res) const {
> - uint64_t Offset = (TableOffset +
> - Index * sizeof(macho::DataInCodeTableEntry));
> - ReadInMemoryStruct(*this, Buffer->getBuffer(), Offset, Res);
> -}
> -
> -void MachOObject::ReadULEB128s(uint64_t Index,
> - SmallVectorImpl<uint64_t> &Out) const {
> - DataExtractor extractor(Buffer->getBuffer(), true, 0);
> -
> - uint32_t offset = Index;
> - uint64_t data = 0;
> - while (uint64_t delta = extractor.getULEB128(&offset)) {
> - data += delta;
> - Out.push_back(data);
> - }
> -}
> -
> -/* ** */
> -// 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";
> -}
>
> Modified: llvm/trunk/lib/Object/MachOObjectFile.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/MachOObjectFile.cpp?rev=180624&r1=180623&r2=180624&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Object/MachOObjectFile.cpp (original)
> +++ llvm/trunk/lib/Object/MachOObjectFile.cpp Fri Apr 26 15:07:33 2013
> @@ -120,6 +120,11 @@ void SwapStruct(macho::Header &H) {
> }
>
> template<>
> +void SwapStruct(macho::Header64Ext &E) {
> + SwapValue(E.Reserved);
> +}
> +
> +template<>
> void SwapStruct(macho::SymtabLoadCommand &C) {
> SwapValue(C.Type);
> SwapValue(C.Size);
> @@ -130,6 +135,30 @@ void SwapStruct(macho::SymtabLoadCommand
> }
>
> template<>
> +void SwapStruct(macho::DysymtabLoadCommand &C) {
> + SwapValue(C.Type);
> + SwapValue(C.Size);
> + SwapValue(C.LocalSymbolsIndex);
> + SwapValue(C.NumLocalSymbols);
> + SwapValue(C.ExternalSymbolsIndex);
> + SwapValue(C.NumExternalSymbols);
> + SwapValue(C.UndefinedSymbolsIndex);
> + SwapValue(C.NumUndefinedSymbols);
> + SwapValue(C.TOCOffset);
> + SwapValue(C.NumTOCEntries);
> + SwapValue(C.ModuleTableOffset);
> + SwapValue(C.NumModuleTableEntries);
> + SwapValue(C.ReferenceSymbolTableOffset);
> + SwapValue(C.NumReferencedSymbolTableEntries);
> + SwapValue(C.IndirectSymbolTableOffset);
> + SwapValue(C.NumIndirectSymbolTableEntries);
> + SwapValue(C.ExternalRelocationTableOffset);
> + SwapValue(C.NumExternalRelocationTableEntries);
> + SwapValue(C.LocalRelocationTableOffset);
> + SwapValue(C.NumLocalRelocationTableEntries);
> +}
> +
> +template<>
> void SwapStruct(macho::LinkeditDataLoadCommand &C) {
> SwapValue(C.Type);
> SwapValue(C.Size);
> @@ -165,6 +194,25 @@ void SwapStruct(macho::Segment64LoadComm
> SwapValue(C.Flags);
> }
>
> +template<>
> +void SwapStruct(macho::IndirectSymbolTableEntry &C) {
> + SwapValue(C.Index);
> +}
> +
> +template<>
> +void SwapStruct(macho::LinkerOptionsLoadCommand &C) {
> + SwapValue(C.Type);
> + SwapValue(C.Size);
> + SwapValue(C.Count);
> +}
> +
> +template<>
> +void SwapStruct(macho::DataInCodeTableEntry &C) {
> + SwapValue(C.Offset);
> + SwapValue(C.Length);
> + SwapValue(C.Kind);
> +}
> +
> template<typename T>
> T getStruct(const MachOObjectFile *O, const char *P) {
> T Cmd;
> @@ -174,32 +222,20 @@ T getStruct(const MachOObjectFile *O, co
> return Cmd;
> }
>
> -static macho::SegmentLoadCommand
> -getSegmentLoadCommand(const MachOObjectFile *O,
> - const MachOObjectFile::LoadCommandInfo &L) {
> - return getStruct<macho::SegmentLoadCommand>(O, L.Ptr);
> -}
> -
> -static macho::Segment64LoadCommand
> -getSegment64LoadCommand(const MachOObjectFile *O,
> - const MachOObjectFile::LoadCommandInfo &L) {
> - return getStruct<macho::Segment64LoadCommand>(O, L.Ptr);
> -}
> -
> static uint32_t
> getSegmentLoadCommandNumSections(const MachOObjectFile *O,
> const MachOObjectFile::LoadCommandInfo &L) {
> if (O->is64Bit()) {
> - macho::Segment64LoadCommand S = getSegment64LoadCommand(O, L);
> + macho::Segment64LoadCommand S = O->getSegment64LoadCommand(L);
> return S.NumSections;
> }
> - macho::SegmentLoadCommand S = getSegmentLoadCommand(O, L);
> + macho::SegmentLoadCommand S = O->getSegmentLoadCommand(L);
> return S.NumSections;
> }
>
> -static const SectionBase *
> -getSectionBase(const MachOObjectFile *O, MachOObjectFile::LoadCommandInfo L,
> - unsigned Sec) {
> +static const char *
> +getSectionPtr(const MachOObjectFile *O, MachOObjectFile::LoadCommandInfo L,
> + unsigned Sec) {
> uintptr_t CommandAddr = reinterpret_cast<uintptr_t>(L.Ptr);
>
> bool Is64 = O->is64Bit();
> @@ -209,7 +245,7 @@ getSectionBase(const MachOObjectFile *O,
> sizeof(macho::Section);
>
> uintptr_t SectionAddr = CommandAddr + SegmentLoadSize + Sec * SectionSize;
> - return reinterpret_cast<const SectionBase*>(SectionAddr);
> + return reinterpret_cast<const char*>(SectionAddr);
> }
>
> static const char *getPtr(const MachOObjectFile *O, size_t Offset) {
> @@ -377,7 +413,7 @@ MachOObjectFile::MachOObjectFile(MemoryB
> bool IsLittleEndian, bool Is64bits,
> error_code &ec)
> : ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object),
> - SymtabLoadCmd(NULL) {
> + SymtabLoadCmd(NULL), DysymtabLoadCmd(NULL) {
> uint32_t LoadCommandCount = this->getHeader().NumLoadCommands;
> macho::LoadCommandType SegmentLoadType = is64Bit() ?
> macho::LCT_Segment64 : macho::LCT_Segment;
> @@ -387,13 +423,14 @@ MachOObjectFile::MachOObjectFile(MemoryB
> if (Load.C.Type == macho::LCT_Symtab) {
> assert(!SymtabLoadCmd && "Multiple symbol tables");
> SymtabLoadCmd = Load.Ptr;
> - }
> -
> - if (Load.C.Type == SegmentLoadType) {
> + } else if (Load.C.Type == macho::LCT_Dysymtab) {
> + assert(!DysymtabLoadCmd && "Multiple dynamic symbol tables");
> + DysymtabLoadCmd = Load.Ptr;
> + } else if (Load.C.Type == SegmentLoadType) {
> uint32_t NumSections = getSegmentLoadCommandNumSections(this, Load);
> for (unsigned J = 0; J < NumSections; ++J) {
> - const SectionBase *Sec = getSectionBase(this, Load, J);
> - Sections.push_back(reinterpret_cast<const char*>(Sec));
> + const char *Sec = getSectionPtr(this, Load, J);
> + Sections.push_back(Sec);
> }
> }
>
> @@ -416,10 +453,9 @@ error_code MachOObjectFile::getSymbolNex
>
> error_code MachOObjectFile::getSymbolName(DataRefImpl Symb,
> StringRef &Res) const {
> - macho::SymtabLoadCommand S = getSymtabLoadCommand();
> - const char *StringTable = getPtr(this, S.StringTableOffset);
> + StringRef StringTable = getStringTableData();
> SymbolTableEntryBase Entry = getSymbolTableEntryBase(this, Symb);
> - const char *Start = &StringTable[Entry.StringIndex];
> + const char *Start = &StringTable.data()[Entry.StringIndex];
> Res = StringRef(Start);
> return object_error::success;
> }
> @@ -1271,6 +1307,18 @@ StringRef MachOObjectFile::getLoadName()
> report_fatal_error("get_load_name() unimplemented in MachOObjectFile");
> }
>
> +relocation_iterator MachOObjectFile::getSectionRelBegin(unsigned Index) const {
> + DataRefImpl DRI;
> + DRI.d.a = Index;
> + return getSectionRelBegin(DRI);
> +}
> +
> +relocation_iterator MachOObjectFile::getSectionRelEnd(unsigned Index) const {
> + DataRefImpl DRI;
> + DRI.d.a = Index;
> + return getSectionRelEnd(DRI);
> +}
> +
> StringRef
> MachOObjectFile::getSectionFinalSegmentName(DataRefImpl Sec) const {
> ArrayRef<char> Raw = getSectionRawFinalSegmentName(Sec);
> @@ -1375,6 +1423,18 @@ macho::Section64 MachOObjectFile::getSec
> return getStruct<macho::Section64>(this, Sections[DRI.d.a]);
> }
>
> +macho::Section MachOObjectFile::getSection(const LoadCommandInfo &L,
> + unsigned Index) const {
> + const char *Sec = getSectionPtr(this, L, Index);
> + return getStruct<macho::Section>(this, Sec);
> +}
> +
> +macho::Section64 MachOObjectFile::getSection64(const LoadCommandInfo &L,
> + unsigned Index) const {
> + const char *Sec = getSectionPtr(this, L, Index);
> + return getStruct<macho::Section64>(this, Sec);
> +}
> +
> macho::SymbolTableEntry
> MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI) const {
> const char *P = reinterpret_cast<const char *>(DRI.p);
> @@ -1392,6 +1452,21 @@ MachOObjectFile::getLinkeditDataLoadComm
> return getStruct<macho::LinkeditDataLoadCommand>(this, L.Ptr);
> }
>
> +macho::SegmentLoadCommand
> +MachOObjectFile::getSegmentLoadCommand(const LoadCommandInfo &L) const {
> + return getStruct<macho::SegmentLoadCommand>(this, L.Ptr);
> +}
> +
> +macho::Segment64LoadCommand
> +MachOObjectFile::getSegment64LoadCommand(const LoadCommandInfo &L) const {
> + return getStruct<macho::Segment64LoadCommand>(this, L.Ptr);
> +}
> +
> +macho::LinkerOptionsLoadCommand
> +MachOObjectFile::getLinkerOptionsLoadCommand(const LoadCommandInfo &L) const {
> + return getStruct<macho::LinkerOptionsLoadCommand>(this, L.Ptr);
> +}
> +
> macho::RelocationEntry
> MachOObjectFile::getRelocation(DataRefImpl Rel) const {
> const char *P = reinterpret_cast<const char *>(Rel.p);
> @@ -1402,11 +1477,39 @@ macho::Header MachOObjectFile::getHeader
> return getStruct<macho::Header>(this, getPtr(this, 0));
> }
>
> -macho::SymtabLoadCommand
> -MachOObjectFile::getSymtabLoadCommand() const {
> +macho::Header64Ext MachOObjectFile::getHeader64Ext() const {
> + return
> + getStruct<macho::Header64Ext>(this, getPtr(this, sizeof(macho::Header)));
> +}
> +
> +macho::IndirectSymbolTableEntry MachOObjectFile::getIndirectSymbolTableEntry(
> + const macho::DysymtabLoadCommand &DLC,
> + unsigned Index) const {
> + uint64_t Offset = DLC.IndirectSymbolTableOffset +
> + Index * sizeof(macho::IndirectSymbolTableEntry);
> + return getStruct<macho::IndirectSymbolTableEntry>(this, getPtr(this, Offset));
> +}
> +
> +macho::DataInCodeTableEntry
> +MachOObjectFile::getDataInCodeTableEntry(uint32_t DataOffset,
> + unsigned Index) const {
> + uint64_t Offset = DataOffset + Index * sizeof(macho::DataInCodeTableEntry);
> + return getStruct<macho::DataInCodeTableEntry>(this, getPtr(this, Offset));
> +}
> +
> +macho::SymtabLoadCommand MachOObjectFile::getSymtabLoadCommand() const {
> return getStruct<macho::SymtabLoadCommand>(this, SymtabLoadCmd);
> }
>
> +macho::DysymtabLoadCommand MachOObjectFile::getDysymtabLoadCommand() const {
> + return getStruct<macho::DysymtabLoadCommand>(this, DysymtabLoadCmd);
> +}
> +
> +StringRef MachOObjectFile::getStringTableData() const {
> + macho::SymtabLoadCommand S = getSymtabLoadCommand();
> + return getData().substr(S.StringTableOffset, S.StringTableSize);
> +}
> +
> bool MachOObjectFile::is64Bit() const {
> return getType() == getMachOType(false, true) ||
> getType() == getMachOType(true, true);
>
> Modified: llvm/trunk/tools/llvm-rtdyld/llvm-rtdyld.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-rtdyld/llvm-rtdyld.cpp?rev=180624&r1=180623&r2=180624&view=diff
> ==============================================================================
> --- llvm/trunk/tools/llvm-rtdyld/llvm-rtdyld.cpp (original)
> +++ llvm/trunk/tools/llvm-rtdyld/llvm-rtdyld.cpp Fri Apr 26 15:07:33 2013
> @@ -17,7 +17,7 @@
> #include "llvm/ExecutionEngine/ObjectBuffer.h"
> #include "llvm/ExecutionEngine/ObjectImage.h"
> #include "llvm/ExecutionEngine/RuntimeDyld.h"
> -#include "llvm/Object/MachOObject.h"
> +#include "llvm/Object/MachO.h"
> #include "llvm/Support/CommandLine.h"
> #include "llvm/Support/ManagedStatic.h"
> #include "llvm/Support/Memory.h"
>
> Modified: llvm/trunk/tools/macho-dump/macho-dump.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/macho-dump/macho-dump.cpp?rev=180624&r1=180623&r2=180624&view=diff
> ==============================================================================
> --- llvm/trunk/tools/macho-dump/macho-dump.cpp (original)
> +++ llvm/trunk/tools/macho-dump/macho-dump.cpp Fri Apr 26 15:07:33 2013
> @@ -11,9 +11,10 @@
> //
> //===----------------------------------------------------------------------===//
>
> -#include "llvm/Object/MachOObject.h"
> +#include "llvm/Object/MachO.h"
> #include "llvm/ADT/StringExtras.h"
> #include "llvm/ADT/Twine.h"
> +#include "llvm/Support/Casting.h"
> #include "llvm/Support/CommandLine.h"
> #include "llvm/Support/Format.h"
> #include "llvm/Support/ManagedStatic.h"
> @@ -66,7 +67,8 @@ static void DumpSegmentCommandData(Strin
> outs() << " ('flags', " << Flags << ")\n";
> }
>
> -static int DumpSectionData(MachOObject &Obj, unsigned Index, StringRef Name,
> +static int DumpSectionData(const MachOObjectFile &Obj, unsigned Index,
> + StringRef Name,
> StringRef SegmentName, uint64_t Address,
> uint64_t Size, uint32_t Offset,
> uint32_t Align, uint32_t RelocationTableOffset,
> @@ -92,26 +94,22 @@ static int DumpSectionData(MachOObject &
> outs() << " ),\n";
>
> // Dump the relocation entries.
> - int Res = 0;
> outs() << " ('_relocations', [\n";
> - for (unsigned i = 0; i != NumRelocationTableEntries; ++i) {
> - InMemoryStruct<macho::RelocationEntry> RE;
> - Obj.ReadRelocationEntry(RelocationTableOffset, i, RE);
> - if (!RE) {
> - Res = Error("unable to read relocation table entry '" + Twine(i) + "'");
> - break;
> - }
> -
> - outs() << " # Relocation " << i << "\n";
> - outs() << " (('word-0', " << format("0x%x", RE->Word0) << "),\n";
> - outs() << " ('word-1', " << format("0x%x", RE->Word1) << ")),\n";
> + unsigned RelNum = 0;
> + error_code EC;
> + for (relocation_iterator I = Obj.getSectionRelBegin(Index),
> + E = Obj.getSectionRelEnd(Index); I != E; I.increment(EC), ++RelNum) {
> + macho::RelocationEntry RE = Obj.getRelocation(I->getRawDataRefImpl());
> + outs() << " # Relocation " << RelNum << "\n";
> + outs() << " (('word-0', " << format("0x%x", RE.Word0) << "),\n";
> + outs() << " ('word-1', " << format("0x%x", RE.Word1) << ")),\n";
> }
> outs() << " ])\n";
>
> // Dump the section data, if requested.
> if (ShowSectionData) {
> outs() << " ('_section_data', '";
> - StringRef Data = Obj.getData(Offset, Size);
> + StringRef Data = Obj.getData().substr(Offset, Size);
> for (unsigned i = 0; i != Data.size(); ++i) {
> if (i && (i % 4) == 0)
> outs() << ' ';
> @@ -121,208 +119,162 @@ static int DumpSectionData(MachOObject &
> outs() << "')\n";
> }
>
> - return Res;
> + return 0;
> }
>
> -static int DumpSegmentCommand(MachOObject &Obj,
> - const MachOObject::LoadCommandInfo &LCI) {
> - InMemoryStruct<macho::SegmentLoadCommand> SLC;
> - Obj.ReadSegmentLoadCommand(LCI, SLC);
> - if (!SLC)
> - return Error("unable to read segment load command");
> -
> - DumpSegmentCommandData(StringRef(SLC->Name, 16), SLC->VMAddress,
> - SLC->VMSize, SLC->FileOffset, SLC->FileSize,
> - SLC->MaxVMProtection, SLC->InitialVMProtection,
> - SLC->NumSections, SLC->Flags);
> +static int DumpSegmentCommand(const MachOObjectFile &Obj,
> + const MachOObjectFile::LoadCommandInfo &LCI) {
> + macho::SegmentLoadCommand SLC = Obj.getSegmentLoadCommand(LCI);
> +
> + DumpSegmentCommandData(StringRef(SLC.Name, 16), SLC.VMAddress,
> + SLC.VMSize, SLC.FileOffset, SLC.FileSize,
> + SLC.MaxVMProtection, SLC.InitialVMProtection,
> + SLC.NumSections, SLC.Flags);
>
> // Dump the sections.
> - int Res = 0;
> outs() << " ('sections', [\n";
> - for (unsigned i = 0; i != SLC->NumSections; ++i) {
> - InMemoryStruct<macho::Section> Sect;
> - Obj.ReadSection(LCI, i, Sect);
> - if (!SLC) {
> - Res = Error("unable to read section '" + Twine(i) + "'");
> - break;
> - }
> -
> - if ((Res = DumpSectionData(Obj, i, StringRef(Sect->Name, 16),
> - StringRef(Sect->SegmentName, 16), Sect->Address,
> - Sect->Size, Sect->Offset, Sect->Align,
> - Sect->RelocationTableOffset,
> - Sect->NumRelocationTableEntries, Sect->Flags,
> - Sect->Reserved1, Sect->Reserved2)))
> - break;
> + for (unsigned i = 0; i != SLC.NumSections; ++i) {
> + macho::Section Sect = Obj.getSection(LCI, i);
> + DumpSectionData(Obj, i, StringRef(Sect.Name, 16),
> + StringRef(Sect.SegmentName, 16), Sect.Address,
> + Sect.Size, Sect.Offset, Sect.Align,
> + Sect.RelocationTableOffset,
> + Sect.NumRelocationTableEntries, Sect.Flags,
> + Sect.Reserved1, Sect.Reserved2);
> }
> outs() << " ])\n";
>
> - return Res;
> + return 0;
> }
>
> -static int DumpSegment64Command(MachOObject &Obj,
> - const MachOObject::LoadCommandInfo &LCI) {
> - InMemoryStruct<macho::Segment64LoadCommand> SLC;
> - Obj.ReadSegment64LoadCommand(LCI, SLC);
> - if (!SLC)
> - return Error("unable to read segment load command");
> -
> - DumpSegmentCommandData(StringRef(SLC->Name, 16), SLC->VMAddress,
> - SLC->VMSize, SLC->FileOffset, SLC->FileSize,
> - SLC->MaxVMProtection, SLC->InitialVMProtection,
> - SLC->NumSections, SLC->Flags);
> +static int DumpSegment64Command(const MachOObjectFile &Obj,
> + const MachOObjectFile::LoadCommandInfo &LCI) {
> + macho::Segment64LoadCommand SLC = Obj.getSegment64LoadCommand(LCI);
> + DumpSegmentCommandData(StringRef(SLC.Name, 16), SLC.VMAddress,
> + SLC.VMSize, SLC.FileOffset, SLC.FileSize,
> + SLC.MaxVMProtection, SLC.InitialVMProtection,
> + SLC.NumSections, SLC.Flags);
>
> // Dump the sections.
> - int Res = 0;
> outs() << " ('sections', [\n";
> - for (unsigned i = 0; i != SLC->NumSections; ++i) {
> - InMemoryStruct<macho::Section64> Sect;
> - Obj.ReadSection64(LCI, i, Sect);
> - if (!SLC) {
> - Res = Error("unable to read section '" + Twine(i) + "'");
> - break;
> - }
> + for (unsigned i = 0; i != SLC.NumSections; ++i) {
> + macho::Section64 Sect = Obj.getSection64(LCI, i);
>
> - if ((Res = DumpSectionData(Obj, i, StringRef(Sect->Name, 16),
> - StringRef(Sect->SegmentName, 16), Sect->Address,
> - Sect->Size, Sect->Offset, Sect->Align,
> - Sect->RelocationTableOffset,
> - Sect->NumRelocationTableEntries, Sect->Flags,
> - Sect->Reserved1, Sect->Reserved2,
> - Sect->Reserved3)))
> - break;
> + DumpSectionData(Obj, i, StringRef(Sect.Name, 16),
> + StringRef(Sect.SegmentName, 16), Sect.Address,
> + Sect.Size, Sect.Offset, Sect.Align,
> + Sect.RelocationTableOffset,
> + Sect.NumRelocationTableEntries, Sect.Flags,
> + Sect.Reserved1, Sect.Reserved2,
> + Sect.Reserved3);
> }
> outs() << " ])\n";
>
> - return Res;
> + return 0;
> }
>
> -static void DumpSymbolTableEntryData(MachOObject &Obj,
> +static void DumpSymbolTableEntryData(const MachOObjectFile &Obj,
> unsigned Index, uint32_t StringIndex,
> uint8_t Type, uint8_t SectionIndex,
> - uint16_t Flags, uint64_t Value) {
> + uint16_t Flags, uint64_t Value,
> + StringRef StringTable) {
> + const char *Name = &StringTable.data()[StringIndex];
> outs() << " # Symbol " << Index << "\n";
> outs() << " (('n_strx', " << StringIndex << ")\n";
> outs() << " ('n_type', " << format("0x%x", Type) << ")\n";
> outs() << " ('n_sect', " << uint32_t(SectionIndex) << ")\n";
> outs() << " ('n_desc', " << Flags << ")\n";
> outs() << " ('n_value', " << Value << ")\n";
> - outs() << " ('_string', '" << Obj.getStringAtIndex(StringIndex) << "')\n";
> + outs() << " ('_string', '" << Name << "')\n";
> outs() << " ),\n";
> }
>
> -static int DumpSymtabCommand(MachOObject &Obj,
> - const MachOObject::LoadCommandInfo &LCI) {
> - InMemoryStruct<macho::SymtabLoadCommand> SLC;
> - Obj.ReadSymtabLoadCommand(LCI, SLC);
> - if (!SLC)
> - return Error("unable to read segment load command");
> -
> - outs() << " ('symoff', " << SLC->SymbolTableOffset << ")\n";
> - outs() << " ('nsyms', " << SLC->NumSymbolTableEntries << ")\n";
> - outs() << " ('stroff', " << SLC->StringTableOffset << ")\n";
> - outs() << " ('strsize', " << SLC->StringTableSize << ")\n";
> +static int DumpSymtabCommand(const MachOObjectFile &Obj) {
> + macho::SymtabLoadCommand SLC = Obj.getSymtabLoadCommand();
>
> - // Cache the string table data.
> - Obj.RegisterStringTable(*SLC);
> + outs() << " ('symoff', " << SLC.SymbolTableOffset << ")\n";
> + outs() << " ('nsyms', " << SLC.NumSymbolTableEntries << ")\n";
> + outs() << " ('stroff', " << SLC.StringTableOffset << ")\n";
> + outs() << " ('strsize', " << SLC.StringTableSize << ")\n";
>
> // Dump the string data.
> outs() << " ('_string_data', '";
> - outs().write_escaped(Obj.getStringTableData(),
> + StringRef StringTable = Obj.getStringTableData();
> + outs().write_escaped(StringTable,
> /*UseHexEscapes=*/true) << "')\n";
>
> // Dump the symbol table.
> - int Res = 0;
> outs() << " ('_symbols', [\n";
> - for (unsigned i = 0; i != SLC->NumSymbolTableEntries; ++i) {
> + error_code EC;
> + unsigned SymNum = 0;
> + for (symbol_iterator I = Obj.begin_symbols(), E = Obj.end_symbols(); I != E;
> + I.increment(EC), ++SymNum) {
> + DataRefImpl DRI = I->getRawDataRefImpl();
> if (Obj.is64Bit()) {
> - InMemoryStruct<macho::Symbol64TableEntry> STE;
> - Obj.ReadSymbol64TableEntry(SLC->SymbolTableOffset, i, STE);
> - if (!STE) {
> - Res = Error("unable to read symbol: '" + Twine(i) + "'");
> - break;
> - }
> -
> - DumpSymbolTableEntryData(Obj, i, STE->StringIndex, STE->Type,
> - STE->SectionIndex, STE->Flags, STE->Value);
> + macho::Symbol64TableEntry STE = Obj.getSymbol64TableEntry(DRI);
> + DumpSymbolTableEntryData(Obj, SymNum, STE.StringIndex, STE.Type,
> + STE.SectionIndex, STE.Flags, STE.Value,
> + StringTable);
> } else {
> - InMemoryStruct<macho::SymbolTableEntry> STE;
> - Obj.ReadSymbolTableEntry(SLC->SymbolTableOffset, i, STE);
> - if (!SLC) {
> - Res = Error("unable to read symbol: '" + Twine(i) + "'");
> - break;
> - }
> -
> - DumpSymbolTableEntryData(Obj, i, STE->StringIndex, STE->Type,
> - STE->SectionIndex, STE->Flags, STE->Value);
> + macho::SymbolTableEntry STE = Obj.getSymbolTableEntry(DRI);
> + DumpSymbolTableEntryData(Obj, SymNum, STE.StringIndex, STE.Type,
> + STE.SectionIndex, STE.Flags, STE.Value,
> + StringTable);
> }
> }
> outs() << " ])\n";
>
> - return Res;
> + return 0;
> }
>
> -static int DumpDysymtabCommand(MachOObject &Obj,
> - const MachOObject::LoadCommandInfo &LCI) {
> - InMemoryStruct<macho::DysymtabLoadCommand> DLC;
> - Obj.ReadDysymtabLoadCommand(LCI, DLC);
> - if (!DLC)
> - return Error("unable to read segment load command");
> -
> - outs() << " ('ilocalsym', " << DLC->LocalSymbolsIndex << ")\n";
> - outs() << " ('nlocalsym', " << DLC->NumLocalSymbols << ")\n";
> - outs() << " ('iextdefsym', " << DLC->ExternalSymbolsIndex << ")\n";
> - outs() << " ('nextdefsym', " << DLC->NumExternalSymbols << ")\n";
> - outs() << " ('iundefsym', " << DLC->UndefinedSymbolsIndex << ")\n";
> - outs() << " ('nundefsym', " << DLC->NumUndefinedSymbols << ")\n";
> - outs() << " ('tocoff', " << DLC->TOCOffset << ")\n";
> - outs() << " ('ntoc', " << DLC->NumTOCEntries << ")\n";
> - outs() << " ('modtaboff', " << DLC->ModuleTableOffset << ")\n";
> - outs() << " ('nmodtab', " << DLC->NumModuleTableEntries << ")\n";
> - outs() << " ('extrefsymoff', " << DLC->ReferenceSymbolTableOffset << ")\n";
> +static int DumpDysymtabCommand(const MachOObjectFile &Obj) {
> + macho::DysymtabLoadCommand DLC = Obj.getDysymtabLoadCommand();
> +
> + outs() << " ('ilocalsym', " << DLC.LocalSymbolsIndex << ")\n";
> + outs() << " ('nlocalsym', " << DLC.NumLocalSymbols << ")\n";
> + outs() << " ('iextdefsym', " << DLC.ExternalSymbolsIndex << ")\n";
> + outs() << " ('nextdefsym', " << DLC.NumExternalSymbols << ")\n";
> + outs() << " ('iundefsym', " << DLC.UndefinedSymbolsIndex << ")\n";
> + outs() << " ('nundefsym', " << DLC.NumUndefinedSymbols << ")\n";
> + outs() << " ('tocoff', " << DLC.TOCOffset << ")\n";
> + outs() << " ('ntoc', " << DLC.NumTOCEntries << ")\n";
> + outs() << " ('modtaboff', " << DLC.ModuleTableOffset << ")\n";
> + outs() << " ('nmodtab', " << DLC.NumModuleTableEntries << ")\n";
> + outs() << " ('extrefsymoff', " << DLC.ReferenceSymbolTableOffset << ")\n";
> outs() << " ('nextrefsyms', "
> - << DLC->NumReferencedSymbolTableEntries << ")\n";
> - outs() << " ('indirectsymoff', " << DLC->IndirectSymbolTableOffset << ")\n";
> + << DLC.NumReferencedSymbolTableEntries << ")\n";
> + outs() << " ('indirectsymoff', " << DLC.IndirectSymbolTableOffset << ")\n";
> outs() << " ('nindirectsyms', "
> - << DLC->NumIndirectSymbolTableEntries << ")\n";
> - outs() << " ('extreloff', " << DLC->ExternalRelocationTableOffset << ")\n";
> - outs() << " ('nextrel', " << DLC->NumExternalRelocationTableEntries << ")\n";
> - outs() << " ('locreloff', " << DLC->LocalRelocationTableOffset << ")\n";
> - outs() << " ('nlocrel', " << DLC->NumLocalRelocationTableEntries << ")\n";
> + << DLC.NumIndirectSymbolTableEntries << ")\n";
> + outs() << " ('extreloff', " << DLC.ExternalRelocationTableOffset << ")\n";
> + outs() << " ('nextrel', " << DLC.NumExternalRelocationTableEntries << ")\n";
> + outs() << " ('locreloff', " << DLC.LocalRelocationTableOffset << ")\n";
> + outs() << " ('nlocrel', " << DLC.NumLocalRelocationTableEntries << ")\n";
>
> // Dump the indirect symbol table.
> - int Res = 0;
> outs() << " ('_indirect_symbols', [\n";
> - for (unsigned i = 0; i != DLC->NumIndirectSymbolTableEntries; ++i) {
> - InMemoryStruct<macho::IndirectSymbolTableEntry> ISTE;
> - Obj.ReadIndirectSymbolTableEntry(*DLC, i, ISTE);
> - if (!ISTE) {
> - Res = Error("unable to read segment load command");
> - break;
> - }
> -
> + for (unsigned i = 0; i != DLC.NumIndirectSymbolTableEntries; ++i) {
> + macho::IndirectSymbolTableEntry ISTE =
> + Obj.getIndirectSymbolTableEntry(DLC, i);
> outs() << " # Indirect Symbol " << i << "\n";
> outs() << " (('symbol_index', "
> - << format("0x%x", ISTE->Index) << "),),\n";
> + << format("0x%x", ISTE.Index) << "),),\n";
> }
> outs() << " ])\n";
>
> - return Res;
> + return 0;
> }
>
> -static int DumpLinkeditDataCommand(MachOObject &Obj,
> - const MachOObject::LoadCommandInfo &LCI) {
> - InMemoryStruct<macho::LinkeditDataLoadCommand> LLC;
> - Obj.ReadLinkeditDataLoadCommand(LCI, LLC);
> - if (!LLC)
> - return Error("unable to read segment load command");
> -
> - outs() << " ('dataoff', " << LLC->DataOffset << ")\n"
> - << " ('datasize', " << LLC->DataSize << ")\n"
> +static int
> +DumpLinkeditDataCommand(const MachOObjectFile &Obj,
> + const MachOObjectFile::LoadCommandInfo &LCI) {
> + macho::LinkeditDataLoadCommand LLC = Obj.getLinkeditDataLoadCommand(LCI);
> + outs() << " ('dataoff', " << LLC.DataOffset << ")\n"
> + << " ('datasize', " << LLC.DataSize << ")\n"
> << " ('_addresses', [\n";
>
> SmallVector<uint64_t, 8> Addresses;
> - Obj.ReadULEB128s(LLC->DataOffset, 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";
> @@ -332,28 +284,22 @@ static int DumpLinkeditDataCommand(MachO
> return 0;
> }
>
> -static int DumpDataInCodeDataCommand(MachOObject &Obj,
> - const MachOObject::LoadCommandInfo &LCI) {
> - InMemoryStruct<macho::LinkeditDataLoadCommand> LLC;
> - Obj.ReadLinkeditDataLoadCommand(LCI, LLC);
> - if (!LLC)
> - return Error("unable to read data-in-code load command");
> -
> - outs() << " ('dataoff', " << LLC->DataOffset << ")\n"
> - << " ('datasize', " << LLC->DataSize << ")\n"
> +static int
> +DumpDataInCodeDataCommand(const MachOObjectFile &Obj,
> + const MachOObjectFile::LoadCommandInfo &LCI) {
> + macho::LinkeditDataLoadCommand LLC = Obj.getLinkeditDataLoadCommand(LCI);
> + outs() << " ('dataoff', " << LLC.DataOffset << ")\n"
> + << " ('datasize', " << LLC.DataSize << ")\n"
> << " ('_data_regions', [\n";
>
> -
> - unsigned NumRegions = LLC->DataSize / 8;
> + unsigned NumRegions = LLC.DataSize / 8;
> for (unsigned i = 0; i < NumRegions; ++i) {
> - InMemoryStruct<macho::DataInCodeTableEntry> DICE;
> - Obj.ReadDataInCodeTableEntry(LLC->DataOffset, i, DICE);
> - if (!DICE)
> - return Error("unable to read DataInCodeTableEntry");
> + macho::DataInCodeTableEntry DICE =
> + Obj.getDataInCodeTableEntry(LLC.DataOffset, i);
> outs() << " # DICE " << i << "\n"
> - << " ('offset', " << DICE->Offset << ")\n"
> - << " ('length', " << DICE->Length << ")\n"
> - << " ('kind', " << DICE->Kind << ")\n";
> + << " ('offset', " << DICE.Offset << ")\n"
> + << " ('length', " << DICE.Length << ")\n"
> + << " ('kind', " << DICE.Kind << ")\n";
> }
>
> outs() <<" ])\n";
> @@ -361,99 +307,111 @@ static int DumpDataInCodeDataCommand(Mac
> return 0;
> }
>
> -static int DumpLinkerOptionsCommand(MachOObject &Obj,
> - const MachOObject::LoadCommandInfo &LCI) {
> - InMemoryStruct<macho::LinkerOptionsLoadCommand> LOLC;
> - Obj.ReadLinkerOptionsLoadCommand(LCI, LOLC);
> - if (!LOLC)
> - return Error("unable to read linker options load command");
> -
> - outs() << " ('count', " << LOLC->Count << ")\n"
> - << " ('_strings', [\n";
> -
> - uint64_t DataSize = LOLC->Size - sizeof(macho::LinkerOptionsLoadCommand);
> - StringRef Data = Obj.getData(
> - LCI.Offset + sizeof(macho::LinkerOptionsLoadCommand), DataSize);
> - for (unsigned i = 0; i != LOLC->Count; ++i) {
> - std::pair<StringRef,StringRef> Split = Data.split('\0');
> - outs() << "\t\"";
> - outs().write_escaped(Split.first);
> - outs() << "\",\n";
> - Data = Split.second;
> - }
> - outs() <<" ])\n";
> +static int
> +DumpLinkerOptionsCommand(const MachOObjectFile &Obj,
> + const MachOObjectFile::LoadCommandInfo &LCI) {
> + macho::LinkerOptionsLoadCommand LOLC = Obj.getLinkerOptionsLoadCommand(LCI);
> + outs() << " ('count', " << LOLC.Count << ")\n"
> + << " ('_strings', [\n";
> +
> + uint64_t DataSize = LOLC.Size - sizeof(macho::LinkerOptionsLoadCommand);
> + const char *P = LCI.Ptr + sizeof(macho::LinkerOptionsLoadCommand);
> + StringRef Data(P, DataSize);
> + for (unsigned i = 0; i != LOLC.Count; ++i) {
> + std::pair<StringRef,StringRef> Split = Data.split('\0');
> + outs() << "\t\"";
> + outs().write_escaped(Split.first);
> + outs() << "\",\n";
> + Data = Split.second;
> + }
> + outs() <<" ])\n";
>
> return 0;
> }
>
> -
> -static int DumpLoadCommand(MachOObject &Obj, unsigned Index) {
> - const MachOObject::LoadCommandInfo &LCI = Obj.getLoadCommandInfo(Index);
> - int Res = 0;
> -
> - outs() << " # Load Command " << Index << "\n"
> - << " (('command', " << LCI.Command.Type << ")\n"
> - << " ('size', " << LCI.Command.Size << ")\n";
> - switch (LCI.Command.Type) {
> +static int DumpLoadCommand(const MachOObjectFile &Obj,
> + MachOObjectFile::LoadCommandInfo &LCI) {
> + switch (LCI.C.Type) {
> case macho::LCT_Segment:
> - Res = DumpSegmentCommand(Obj, LCI);
> - break;
> + return DumpSegmentCommand(Obj, LCI);
> case macho::LCT_Segment64:
> - Res = DumpSegment64Command(Obj, LCI);
> - break;
> + return DumpSegment64Command(Obj, LCI);
> case macho::LCT_Symtab:
> - Res = DumpSymtabCommand(Obj, LCI);
> - break;
> + return DumpSymtabCommand(Obj);
> case macho::LCT_Dysymtab:
> - Res = DumpDysymtabCommand(Obj, LCI);
> - break;
> + return DumpDysymtabCommand(Obj);
> case macho::LCT_CodeSignature:
> case macho::LCT_SegmentSplitInfo:
> case macho::LCT_FunctionStarts:
> - Res = DumpLinkeditDataCommand(Obj, LCI);
> - break;
> + return DumpLinkeditDataCommand(Obj, LCI);
> case macho::LCT_DataInCode:
> - Res = DumpDataInCodeDataCommand(Obj, LCI);
> - break;
> + return DumpDataInCodeDataCommand(Obj, LCI);
> case macho::LCT_LinkerOptions:
> - Res = DumpLinkerOptionsCommand(Obj, LCI);
> - break;
> + return DumpLinkerOptionsCommand(Obj, LCI);
> default:
> - Warning("unknown load command: " + Twine(LCI.Command.Type));
> - break;
> + Warning("unknown load command: " + Twine(LCI.C.Type));
> + return 0;
> }
> - outs() << " ),\n";
> +}
> +
>
> +static int DumpLoadCommand(const MachOObjectFile &Obj, unsigned Index,
> + MachOObjectFile::LoadCommandInfo &LCI) {
> + outs() << " # Load Command " << Index << "\n"
> + << " (('command', " << LCI.C.Type << ")\n"
> + << " ('size', " << LCI.C.Size << ")\n";
> + int Res = DumpLoadCommand(Obj, LCI);
> + outs() << " ),\n";
> return Res;
> }
>
> +static void printHeader(const MachOObjectFile *Obj,
> + const macho::Header &Header) {
> + outs() << "('cputype', " << Header.CPUType << ")\n";
> + outs() << "('cpusubtype', " << Header.CPUSubtype << ")\n";
> + outs() << "('filetype', " << Header.FileType << ")\n";
> + outs() << "('num_load_commands', " << Header.NumLoadCommands << ")\n";
> + outs() << "('load_commands_size', " << Header.SizeOfLoadCommands << ")\n";
> + outs() << "('flag', " << Header.Flags << ")\n";
> +
> + // Print extended header if 64-bit.
> + if (Obj->is64Bit()) {
> + macho::Header64Ext Header64Ext = Obj->getHeader64Ext();
> + outs() << "('reserved', " << Header64Ext.Reserved << ")\n";
> + }
> +}
> +
> int main(int argc, char **argv) {
> ProgramName = argv[0];
> llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
>
> cl::ParseCommandLineOptions(argc, argv, "llvm Mach-O dumping tool\n");
>
> - // Load the input file.
> - std::string ErrorStr;
> - OwningPtr<MemoryBuffer> InputBuffer;
> - if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputFile, InputBuffer))
> - return Error("unable to read input: '" + ec.message() + "'");
> -
> - // Construct the Mach-O wrapper object.
> - OwningPtr<MachOObject> InputObject(
> - MachOObject::LoadFromBuffer(InputBuffer.take(), &ErrorStr));
> + OwningPtr<Binary> Binary;
> + if (error_code EC = createBinary(InputFile, Binary))
> + return Error("unable to read input: '" + EC.message() + "'");
> +
> + const MachOObjectFile *InputObject = dyn_cast<MachOObjectFile>(Binary.get());
> if (!InputObject)
> - return Error("unable to load object: '" + ErrorStr + "'");
> + return Error("Not a MachO object");
>
> // Print the header
> - InputObject->printHeader(outs());
> + macho::Header Header = InputObject->getHeader();
> + printHeader(InputObject, Header);
>
> // Print the load commands.
> int Res = 0;
> + MachOObjectFile::LoadCommandInfo Command =
> + InputObject->getFirstLoadCommandInfo();
> outs() << "('load_commands', [\n";
> - for (unsigned i = 0; i != InputObject->getHeader().NumLoadCommands; ++i)
> - if ((Res = DumpLoadCommand(*InputObject, i)))
> + for (unsigned i = 0; ; ++i) {
> + if (DumpLoadCommand(*InputObject, i, Command))
> break;
> +
> + if (i == Header.NumLoadCommands - 1)
> + break;
> + Command = InputObject->getNextLoadCommandInfo(Command);
> + }
> outs() << "])\n";
>
> return Res;
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list