diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2013-04-26 20:07:33 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2013-04-26 20:07:33 +0000 |
commit | 2173e1839c2d00f7f980450dd537047b7b376e6b (patch) | |
tree | 88a1b23ce0c311290c8aae04f3b4cc7d21cec65f /include | |
parent | fbb2c7adc23b20141c5f78bbee07ae22028473a7 (diff) | |
download | external_llvm-2173e1839c2d00f7f980450dd537047b7b376e6b.zip external_llvm-2173e1839c2d00f7f980450dd537047b7b376e6b.tar.gz external_llvm-2173e1839c2d00f7f980450dd537047b7b376e6b.tar.bz2 |
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.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@180624 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include')
-rw-r--r-- | include/llvm/ADT/InMemoryStruct.h | 77 | ||||
-rw-r--r-- | include/llvm/Object/MachO.h | 22 | ||||
-rw-r--r-- | include/llvm/Object/MachOObject.h | 212 |
3 files changed, 22 insertions, 289 deletions
diff --git a/include/llvm/ADT/InMemoryStruct.h b/include/llvm/ADT/InMemoryStruct.h deleted file mode 100644 index a560845..0000000 --- a/include/llvm/ADT/InMemoryStruct.h +++ /dev/null @@ -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 diff --git a/include/llvm/Object/MachO.h b/include/llvm/Object/MachO.h index d8598eb..98d3788 100644 --- a/include/llvm/Object/MachO.h +++ b/include/llvm/Object/MachO.h @@ -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; }; } diff --git a/include/llvm/Object/MachOObject.h b/include/llvm/Object/MachOObject.h deleted file mode 100644 index 50ee25b..0000000 --- a/include/llvm/Object/MachOObject.h +++ /dev/null @@ -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 |