[llvm] r179778 - At Jim Grosbach's request detemplate Object/MachO.h.
Evgeniy Stepanov
eugeni.stepanov at gmail.com
Thu Apr 18 23:50:30 PDT 2013
ERROR: AddressSanitizer: heap-buffer-overflow on address
0x610000007ff8 at pc 0xa6f0ab bp 0x7fff3caa84f0 sp 0x7fff3caa84e8
READ of size 8 at 0x610000007ff8 thread T0
#0 0xa6f0aa in getNextLoadCommandInfo
llvm/lib/Object/MachOObjectFile.cpp:1375
#1 0xa6f0aa in
llvm::object::MachOObjectFile::MachOObjectFile(llvm::MemoryBuffer*,
bool, bool, llvm::error_code&) llvm/lib/Object/MachOObjectFile.cpp:421
#2 0xa79056 in
llvm::object::ObjectFile::createMachOObjectFile(llvm::MemoryBuffer*)
llvm/lib/Object/MachOObjectFile.cpp:1498
#3 0x480ddf in llvm::DisassembleInputMachO(llvm::StringRef)
llvm/tools/llvm-objdump/MachODump.cpp:233
#4 0x4599ed in DumpInput llvm/tools/llvm-objdump/llvm-objdump.cpp:685
#5 0x4599ed in begin
/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../../include/c++/4.6/bits/stl_algo.h:4379
#6 0x4599ed in main llvm/tools/llvm-objdump/llvm-objdump.cpp:739
#7 0x7fdb5e0e776c (/lib/x86_64-linux-gnu/libc.so.6+0x2176c)
#8 0x45706c (llvm_build_asan/bin/llvm-objdump+0x45706c)
0x610000007ffd is located 0 bytes to the right of 189-byte region
[0x610000007f40,0x610000007ffd)
allocated by thread T0 here:
#0 0x446bbb in operator new(unsigned long, std::nothrow_t const&)
llvm/projects/compiler-rt/lib/asan/asan_new_delete.cc:57
#1 0xae8b9a in getNewUninitMemBuffer llvm/lib/Support/MemoryBuffer.cpp:140
#2 0xae8b9a in operator StringRef llvm/lib/Support/MemoryBuffer.cpp:121
#3 0xae8b9a in getMemoryBufferForStream(int, llvm::StringRef,
llvm::OwningPtr<llvm::MemoryBuffer>&)
llvm/lib/Support/MemoryBuffer.cpp:247
#4 0xae7938 in getSTDIN llvm/lib/Support/MemoryBuffer.cpp:425
#5 0xae7938 in llvm::MemoryBuffer::getFileOrSTDIN(llvm::StringRef,
llvm::OwningPtr<llvm::MemoryBuffer>&, long)
llvm/lib/Support/MemoryBuffer.cpp:173
#6 0x480ce3 in llvm::DisassembleInputMachO(llvm::StringRef)
llvm/tools/llvm-objdump/MachODump.cpp:227
#7 0x4599ed in DumpInput llvm/tools/llvm-objdump/llvm-objdump.cpp:685
#8 0x4599ed in begin
/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../../include/c++/4.6/bits/stl_algo.h:4379
#9 0x4599ed in main llvm/tools/llvm-objdump/llvm-objdump.cpp:739
#10 0x7fdb5e0e776c (/lib/x86_64-linux-gnu/libc.so.6+0x2176c)
See attached binary, which is 156 bytes in size.
Run "llvm-objdump -d -macho -triple=thumbv7-apple-ios".
The code in MachOObjectFile::getNextLoadCommandInfo reads 8 bytes at offset 152.
On Thu, Apr 18, 2013 at 10:08 PM, Rafael Espindola
<rafael.espindola at gmail.com> wrote:
> Author: rafael
> Date: Thu Apr 18 13:08:55 2013
> New Revision: 179778
>
> URL: http://llvm.org/viewvc/llvm-project?rev=179778&view=rev
> Log:
> At Jim Grosbach's request detemplate Object/MachO.h.
>
> We are still able to handle mixed endian objects by swapping one struct at a
> time.
>
> Added:
> llvm/trunk/test/tools/llvm-readobj/Inputs/trivial.obj.macho-arm
> Modified:
> llvm/trunk/include/llvm/Object/Binary.h
> llvm/trunk/include/llvm/Object/MachO.h
> llvm/trunk/lib/Object/MachOObjectFile.cpp
> llvm/trunk/test/tools/llvm-readobj/relocations.test
> llvm/trunk/test/tools/llvm-readobj/sections-ext.test
> llvm/trunk/test/tools/llvm-readobj/sections.test
> llvm/trunk/tools/llvm-objdump/MachODump.cpp
> llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp
> llvm/trunk/tools/llvm-readobj/MachODumper.cpp
> llvm/trunk/tools/llvm-symbolizer/LLVMSymbolize.cpp
>
> Modified: llvm/trunk/include/llvm/Object/Binary.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/Binary.h?rev=179778&r1=179777&r2=179778&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/Object/Binary.h (original)
> +++ llvm/trunk/include/llvm/Object/Binary.h Thu Apr 18 13:08:55 2013
> @@ -100,7 +100,8 @@ public:
> }
>
> bool isLittleEndian() const {
> - return !(TypeID == ID_ELF32B || TypeID == ID_ELF64B);
> + return !(TypeID == ID_ELF32B || TypeID == ID_ELF64B ||
> + TypeID == ID_MachO32B || TypeID == ID_MachO64B);
> }
> };
>
>
> Modified: llvm/trunk/include/llvm/Object/MachO.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/MachO.h?rev=179778&r1=179777&r2=179778&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/Object/MachO.h (original)
> +++ llvm/trunk/include/llvm/Object/MachO.h Thu Apr 18 13:08:55 2013
> @@ -7,8 +7,8 @@
> //
> //===----------------------------------------------------------------------===//
> //
> -// This file declares the MachOObjectFile class, which binds the MachOObject
> -// class to the generic ObjectFile wrapper.
> +// This file declares the MachOObjectFile class, which implement the ObjectFile
> +// interface for MachO files.
> //
> //===----------------------------------------------------------------------===//
>
> @@ -17,1607 +17,140 @@
>
> #include "llvm/ADT/ArrayRef.h"
> #include "llvm/ADT/SmallVector.h"
> -#include "llvm/ADT/Triple.h"
> #include "llvm/Object/MachOFormat.h"
> #include "llvm/Object/ObjectFile.h"
> -#include "llvm/Support/Casting.h"
> -#include "llvm/Support/Endian.h"
> -#include "llvm/Support/Format.h"
> #include "llvm/Support/MachO.h"
> #include "llvm/Support/raw_ostream.h"
>
> namespace llvm {
> namespace object {
>
> -using support::endianness;
> -
> -template<endianness E, bool B>
> -struct MachOType {
> - static const endianness TargetEndianness = E;
> - static const bool Is64Bits = B;
> -};
> -
> -template<endianness TargetEndianness>
> -struct MachOInt24Impl;
> -
> -template<>
> -struct MachOInt24Impl<support::little> {
> - uint8_t bytes[3];
> - operator uint32_t() const {
> - return (bytes[2] << 24) | (bytes[1] << 16) | bytes[0];
> - }
> -};
> -
> -template<>
> -struct MachOInt24Impl<support::big> {
> - uint8_t bytes[3];
> - operator uint32_t() const {
> - return (bytes[0] << 24) | (bytes[1] << 16) | bytes[2];
> - }
> -};
> -
> -template<endianness TargetEndianness>
> -struct MachODataTypeTypedefHelperCommon {
> - typedef support::detail::packed_endian_specific_integral
> - <uint16_t, TargetEndianness, support::unaligned> MachOInt16;
> - typedef support::detail::packed_endian_specific_integral
> - <uint32_t, TargetEndianness, support::unaligned> MachOInt32;
> - typedef support::detail::packed_endian_specific_integral
> - <uint64_t, TargetEndianness, support::unaligned> MachOInt64;
> - typedef MachOInt24Impl<TargetEndianness> MachOInt24;
> -};
> -
> -#define LLVM_MACHOB_IMPORT_TYPES_TYPENAME(E) \
> -typedef typename MachODataTypeTypedefHelperCommon<E>::MachOInt16 MachOInt16; \
> -typedef typename MachODataTypeTypedefHelperCommon<E>::MachOInt32 MachOInt32; \
> -typedef typename MachODataTypeTypedefHelperCommon<E>::MachOInt64 MachOInt64; \
> -typedef typename MachODataTypeTypedefHelperCommon<E>::MachOInt24 MachOInt24;
> -
> -#define LLVM_MACHOB_IMPORT_TYPES(E) \
> -typedef MachODataTypeTypedefHelperCommon<E>::MachOInt16 MachOInt16; \
> -typedef MachODataTypeTypedefHelperCommon<E>::MachOInt32 MachOInt32; \
> -typedef MachODataTypeTypedefHelperCommon<E>::MachOInt64 MachOInt64; \
> -typedef MachODataTypeTypedefHelperCommon<E>::MachOInt24 MachOInt24;
> -
> -template<class MachOT>
> -struct MachODataTypeTypedefHelper;
> -
> -template<endianness TargetEndianness>
> -struct MachODataTypeTypedefHelper<MachOType<TargetEndianness, false> > {
> - typedef MachODataTypeTypedefHelperCommon<TargetEndianness> Base;
> - typedef typename Base::MachOInt32 MachOIntPtr;
> -};
> -
> -template<endianness TargetEndianness>
> -struct MachODataTypeTypedefHelper<MachOType<TargetEndianness, true> > {
> - typedef MachODataTypeTypedefHelperCommon<TargetEndianness> Base;
> - typedef typename Base::MachOInt64 MachOIntPtr;
> -};
> -
> -#define LLVM_MACHO_IMPORT_TYPES(MachOT, E, B) \
> -LLVM_MACHOB_IMPORT_TYPES_TYPENAME(E) \
> -typedef typename \
> - MachODataTypeTypedefHelper <MachOT<E, B> >::MachOIntPtr MachOIntPtr;
> -
> -namespace MachOFormat {
> - struct SectionBase {
> - char Name[16];
> - char SegmentName[16];
> - };
> -
> - template<class MachOT>
> - struct Section;
> -
> - template<endianness TargetEndianness>
> - struct Section<MachOType<TargetEndianness, false> > {
> - LLVM_MACHOB_IMPORT_TYPES_TYPENAME(TargetEndianness)
> - char Name[16];
> - char SegmentName[16];
> - MachOInt32 Address;
> - MachOInt32 Size;
> - MachOInt32 Offset;
> - MachOInt32 Align;
> - MachOInt32 RelocationTableOffset;
> - MachOInt32 NumRelocationTableEntries;
> - MachOInt32 Flags;
> - MachOInt32 Reserved1;
> - MachOInt32 Reserved2;
> - };
> -
> - template<endianness TargetEndianness>
> - struct Section<MachOType<TargetEndianness, true> > {
> - LLVM_MACHOB_IMPORT_TYPES_TYPENAME(TargetEndianness)
> - char Name[16];
> - char SegmentName[16];
> - MachOInt64 Address;
> - MachOInt64 Size;
> - MachOInt32 Offset;
> - MachOInt32 Align;
> - MachOInt32 RelocationTableOffset;
> - MachOInt32 NumRelocationTableEntries;
> - MachOInt32 Flags;
> - MachOInt32 Reserved1;
> - MachOInt32 Reserved2;
> - MachOInt32 Reserved3;
> - };
> -
> - struct MachOInt24 {
> - uint8_t bytes[3];
> - operator uint32_t() const {
> - return (bytes[2] << 24) | (bytes[1] << 16) | bytes[0];
> - }
> - };
> -
> - template<bool HostIsLittleEndian, endianness TargetEndianness>
> - struct RelocationEntry;
> -
> - template<>
> - struct RelocationEntry<true, support::little> {
> - LLVM_MACHOB_IMPORT_TYPES(support::little)
> - MachOInt32 Address;
> - MachOInt24 SymbolNum;
> - unsigned PCRel : 1;
> - unsigned Length : 2;
> - unsigned External : 1;
> - unsigned Type : 4;
> - };
> -
> - template<>
> - struct RelocationEntry<false, support::little> {
> - LLVM_MACHOB_IMPORT_TYPES(support::little)
> - MachOInt32 Address;
> - MachOInt24 SymbolNum;
> - unsigned Type : 4;
> - unsigned External : 1;
> - unsigned Length : 2;
> - unsigned PCRel : 1;
> - };
> -
> - template<>
> - struct RelocationEntry<true, support::big> {
> - LLVM_MACHOB_IMPORT_TYPES(support::big)
> - MachOInt32 Address;
> - MachOInt24 SymbolNum;
> - unsigned Type : 4;
> - unsigned External : 1;
> - unsigned Length : 2;
> - unsigned PCRel : 1;
> - };
> -
> - template<>
> - struct RelocationEntry<false, support::big> {
> - LLVM_MACHOB_IMPORT_TYPES(support::big)
> - MachOInt32 Address;
> - MachOInt24 SymbolNum;
> - unsigned PCRel : 1;
> - unsigned Length : 2;
> - unsigned External : 1;
> - unsigned Type : 4;
> - };
> -
> - template<bool HostIsLittleEndian, endianness TargetEndianness>
> - struct ScatteredRelocationEntry;
> -
> - template<>
> - struct ScatteredRelocationEntry<true, support::little> {
> - LLVM_MACHOB_IMPORT_TYPES(support::little)
> - MachOInt24 Address;
> - unsigned Type : 4;
> - unsigned Length : 2;
> - unsigned PCRel : 1;
> - unsigned Scattered : 1;
> - MachOInt32 Value;
> - };
> -
> - template<>
> - struct ScatteredRelocationEntry<false, support::little> {
> - LLVM_MACHOB_IMPORT_TYPES(support::little)
> - MachOInt24 Address;
> - unsigned Scattered : 1;
> - unsigned PCRel : 1;
> - unsigned Length : 2;
> - unsigned Type : 4;
> - MachOInt32 Value;
> - };
> -
> - template<>
> - struct ScatteredRelocationEntry<true, support::big> {
> - LLVM_MACHOB_IMPORT_TYPES(support::big)
> - unsigned Type : 4;
> - unsigned Length : 2;
> - unsigned PCRel : 1;
> - unsigned Scattered : 1;
> - MachOInt24 Address;
> - MachOInt32 Value;
> - };
> -
> - template<>
> - struct ScatteredRelocationEntry<false, support::big> {
> - LLVM_MACHOB_IMPORT_TYPES(support::big)
> - unsigned Scattered : 1;
> - unsigned PCRel : 1;
> - unsigned Length : 2;
> - unsigned Type : 4;
> - MachOInt24 Address;
> - MachOInt32 Value;
> - };
> -
> - template<endianness TargetEndianness>
> - struct SymbolTableEntryBase {
> - LLVM_MACHOB_IMPORT_TYPES_TYPENAME(TargetEndianness)
> - MachOInt32 StringIndex;
> - uint8_t Type;
> - uint8_t SectionIndex;
> - MachOInt16 Flags;
> - };
> -
> - template<class MachOT>
> - struct SymbolTableEntry;
> -
> - template<endianness TargetEndianness, bool Is64Bits>
> - struct SymbolTableEntry<MachOType<TargetEndianness, Is64Bits> > {
> - LLVM_MACHO_IMPORT_TYPES(MachOType, TargetEndianness, Is64Bits)
> - MachOInt32 StringIndex;
> - uint8_t Type;
> - uint8_t SectionIndex;
> - MachOInt16 Flags;
> - MachOIntPtr Value;
> - };
> -
> - template<endianness TargetEndianness>
> - struct LoadCommand {
> - LLVM_MACHOB_IMPORT_TYPES_TYPENAME(TargetEndianness)
> - MachOInt32 Type;
> - MachOInt32 Size;
> - };
> -
> - template<endianness TargetEndianness>
> - struct SymtabLoadCommand {
> - LLVM_MACHOB_IMPORT_TYPES_TYPENAME(TargetEndianness)
> - MachOInt32 Type;
> - MachOInt32 Size;
> - MachOInt32 SymbolTableOffset;
> - MachOInt32 NumSymbolTableEntries;
> - MachOInt32 StringTableOffset;
> - MachOInt32 StringTableSize;
> - };
> -
> - template<class MachOT>
> - struct SegmentLoadCommand;
> -
> - template<endianness TargetEndianness, bool Is64Bits>
> - struct SegmentLoadCommand<MachOType<TargetEndianness, Is64Bits> > {
> - LLVM_MACHO_IMPORT_TYPES(MachOType, TargetEndianness, Is64Bits)
> - MachOInt32 Type;
> - MachOInt32 Size;
> - char Name[16];
> - MachOIntPtr VMAddress;
> - MachOIntPtr VMSize;
> - MachOIntPtr FileOffset;
> - MachOIntPtr FileSize;
> - MachOInt32 MaxVMProtection;
> - MachOInt32 InitialVMProtection;
> - MachOInt32 NumSections;
> - MachOInt32 Flags;
> - };
> -
> - template<endianness TargetEndianness>
> - struct LinkeditDataLoadCommand {
> - LLVM_MACHOB_IMPORT_TYPES_TYPENAME(TargetEndianness)
> - MachOInt32 Type;
> - MachOInt32 Size;
> - MachOInt32 DataOffset;
> - MachOInt32 DataSize;
> - };
> -
> - template<endianness TargetEndianness>
> - struct Header {
> - LLVM_MACHOB_IMPORT_TYPES_TYPENAME(TargetEndianness)
> - MachOInt32 Magic;
> - MachOInt32 CPUType;
> - MachOInt32 CPUSubtype;
> - MachOInt32 FileType;
> - MachOInt32 NumLoadCommands;
> - MachOInt32 SizeOfLoadCommands;
> - MachOInt32 Flags;
> - };
> -}
> -
> -class MachOObjectFileBase : public ObjectFile {
> -public:
> - typedef MachOFormat::SectionBase SectionBase;
> -
> - MachOObjectFileBase(MemoryBuffer *Object, bool IsLittleEndian, bool Is64Bits,
> - error_code &ec);
> -
> - virtual symbol_iterator begin_dynamic_symbols() const;
> - virtual symbol_iterator end_dynamic_symbols() const;
> - virtual library_iterator begin_libraries_needed() const;
> - virtual library_iterator end_libraries_needed() const;
> -
> - virtual uint8_t getBytesInAddress() const;
> - virtual StringRef getLoadName() const;
> -
> - bool is64Bit() const;
> - void ReadULEB128s(uint64_t Index, SmallVectorImpl<uint64_t> &Out) const;
> - unsigned getHeaderSize() const;
> - StringRef getData(size_t Offset, size_t Size) const;
> -
> - static inline bool classof(const Binary *v) {
> - return v->isMachO();
> - }
> -
> -protected:
> - StringRef parseSegmentOrSectionName(const char *P) const;
> -
> - virtual error_code getSymbolValue(DataRefImpl Symb, uint64_t &Val) const;
> - virtual error_code isSectionData(DataRefImpl Sec, bool &Res) const;
> - virtual error_code isSectionBSS(DataRefImpl Sec, bool &Res) const;
> - virtual error_code isSectionRequiredForExecution(DataRefImpl Sec,
> - bool &Res) const;
> - virtual error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const;
> - virtual error_code isSectionReadOnlyData(DataRefImpl Sec, bool &Res) const;
> - virtual relocation_iterator getSectionRelBegin(DataRefImpl Sec) const;
> -
> - virtual error_code getRelocationNext(DataRefImpl Rel,
> - RelocationRef &Res) const;
> -
> - virtual error_code getLibraryNext(DataRefImpl LibData, LibraryRef &Res) const;
> - virtual error_code getLibraryPath(DataRefImpl LibData, StringRef &Res) const;
> - virtual error_code getRelocationAdditionalInfo(DataRefImpl Rel,
> - int64_t &Res) const;
> -
> - std::size_t getSectionIndex(DataRefImpl Sec) const;
> -
> - typedef SmallVector<DataRefImpl, 1> SectionList;
> - SectionList Sections;
> -};
> -
> -template<endianness TargetEndianness>
> -class MachOObjectFileMiddle : public MachOObjectFileBase {
> +class MachOObjectFile : public ObjectFile {
> public:
> + struct LoadCommandInfo {
> + const char *Ptr; // Where in memory the load command is.
> + macho::LoadCommand C; // The command itself.
> + };
>
> - typedef MachOFormat::SymbolTableEntryBase<TargetEndianness>
> - SymbolTableEntryBase;
> - typedef MachOFormat::LinkeditDataLoadCommand<TargetEndianness>
> - LinkeditDataLoadCommand;
> - typedef MachOFormat::Header<TargetEndianness> Header;
> - typedef MachOFormat::SymtabLoadCommand<TargetEndianness> SymtabLoadCommand;
> - typedef MachOFormat::RelocationEntry<sys::IsLittleEndianHost, TargetEndianness> RelocationEntry;
> - typedef MachOFormat::ScatteredRelocationEntry<sys::IsLittleEndianHost, TargetEndianness>
> - ScatteredRelocationEntry;
> - typedef MachOFormat::LoadCommand<TargetEndianness> LoadCommand;
> -
> - MachOObjectFileMiddle(MemoryBuffer *Object, bool Is64Bits, error_code &ec);
> -
> - const Header *getHeader() const;
> - const LoadCommand *getLoadCommandInfo(unsigned Index) const;
> - const RelocationEntry *getRelocation(DataRefImpl Rel) const;
> - bool isRelocationScattered(const RelocationEntry *RE) const;
> - bool isRelocationPCRel(const RelocationEntry *RE) const;
> - unsigned getRelocationLength(const RelocationEntry *RE) const;
> - unsigned getRelocationTypeImpl(const RelocationEntry *RE) const;
> -
> - void moveToNextSymbol(DataRefImpl &DRI) const;
> - void printRelocationTargetName(const RelocationEntry *RE,
> - raw_string_ostream &fmt) const;
> - const SectionBase *getSectionBase(DataRefImpl DRI) const;
> - const SymbolTableEntryBase *getSymbolTableEntryBase(DataRefImpl DRI) const;
> - unsigned getCPUType() const;
> + MachOObjectFile(MemoryBuffer *Object, bool IsLittleEndian, bool Is64Bits,
> + error_code &ec);
>
> - // 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.
> - StringRef getSectionFinalSegmentName(DataRefImpl Sec) const;
> -
> - // Names are stored as 16 bytes. These returns the raw 16 bytes without
> - // interpreting them as a C string.
> - ArrayRef<char> getSectionRawName(DataRefImpl Sec) const;
> - ArrayRef<char> getSectionRawFinalSegmentName(DataRefImpl Sec) const;
> -
> - virtual error_code getSymbolFlags(DataRefImpl Symb, uint32_t &Res) const;
> - virtual error_code getSymbolNMTypeChar(DataRefImpl Symb, char &Res) const;
> + virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const;
> + virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const;
> + virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const;
> + virtual error_code getSymbolFileOffset(DataRefImpl Symb, uint64_t &Res) const;
> + virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const;
> virtual error_code getSymbolType(DataRefImpl Symb,
> SymbolRef::Type &Res) const;
> - virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const;
> + virtual error_code getSymbolNMTypeChar(DataRefImpl Symb, char &Res) const;
> + virtual error_code getSymbolFlags(DataRefImpl Symb, uint32_t &Res) const;
> virtual error_code getSymbolSection(DataRefImpl Symb,
> section_iterator &Res) const;
> - virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const;
> - virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const;
> - virtual symbol_iterator begin_symbols() const;
> - virtual unsigned getArch() const;
> - virtual StringRef getFileFormatName() const;
> - virtual symbol_iterator end_symbols() const;
> - virtual section_iterator end_sections() const;
> -
> - static bool classof(const Binary *v);
> -
> -private:
> - // Helper to advance a section or symbol iterator multiple increments at a
> - // time.
> - template<class T>
> - static error_code advance(T &it, size_t Val);
> -
> - template<class T>
> - static void advanceTo(T &it, size_t Val);
> -};
> -
> -template<class MachOT>
> -struct MachOObjectFileHelperCommon;
> -
> -template<endianness TargetEndianness, bool Is64Bits>
> -struct MachOObjectFileHelperCommon<MachOType<TargetEndianness, Is64Bits> > {
> - typedef
> - MachOFormat::SegmentLoadCommand<MachOType<TargetEndianness, Is64Bits> >
> - SegmentLoadCommand;
> - typedef MachOFormat::SymbolTableEntry<MachOType<TargetEndianness, Is64Bits> >
> - SymbolTableEntry;
> - typedef MachOFormat::Section<MachOType<TargetEndianness, Is64Bits> > Section;
> -};
> -
> -template<class MachOT>
> -struct MachOObjectFileHelper;
> -
> -template<endianness TargetEndianness>
> -struct MachOObjectFileHelper<MachOType<TargetEndianness, false> > :
> - public MachOObjectFileHelperCommon<MachOType<TargetEndianness, false> > {
> - static const macho::LoadCommandType SegmentLoadType = macho::LCT_Segment;
> -};
> -
> -template<endianness TargetEndianness>
> -struct MachOObjectFileHelper<MachOType<TargetEndianness, true> > :
> - public MachOObjectFileHelperCommon<MachOType<TargetEndianness, true> > {
> - static const macho::LoadCommandType SegmentLoadType = macho::LCT_Segment64;
> -};
> -
> -template<class MachOT>
> -class MachOObjectFile : public MachOObjectFileMiddle<MachOT::TargetEndianness> {
> -public:
> - static const endianness TargetEndianness = MachOT::TargetEndianness;
> - static const bool Is64Bits = MachOT::Is64Bits;
> -
> - typedef MachOObjectFileMiddle<MachOT::TargetEndianness> Base;
> - typedef typename Base::RelocationEntry RelocationEntry;
> - typedef typename Base::SectionBase SectionBase;
> - typedef typename Base::SymbolTableEntryBase SymbolTableEntryBase;
> - typedef typename Base::LoadCommand LoadCommand;
> -
> - typedef MachOObjectFileHelper<MachOT> Helper;
> - static const macho::LoadCommandType SegmentLoadType = Helper::SegmentLoadType;
> - typedef typename Helper::SegmentLoadCommand SegmentLoadCommand;
> - typedef typename Helper::SymbolTableEntry SymbolTableEntry;
> - typedef typename Helper::Section Section;
> -
> - MachOObjectFile(MemoryBuffer *Object, error_code &ec);
> - static bool classof(const Binary *v);
> -
> - const Section *getSection(DataRefImpl DRI) const;
> - const SymbolTableEntry *getSymbolTableEntry(DataRefImpl DRI) const;
> - const RelocationEntry *getRelocation(DataRefImpl Rel) const;
> + virtual error_code getSymbolValue(DataRefImpl Symb, uint64_t &Val) const;
>
> + virtual error_code getSectionNext(DataRefImpl Sec, SectionRef &Res) const;
> + virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const;
> virtual error_code getSectionAddress(DataRefImpl Sec, uint64_t &Res) const;
> virtual error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const;
> virtual error_code getSectionContents(DataRefImpl Sec, StringRef &Res) const;
> virtual error_code getSectionAlignment(DataRefImpl Sec, uint64_t &Res) const;
> virtual error_code isSectionText(DataRefImpl Sec, bool &Res) const;
> + virtual error_code isSectionData(DataRefImpl Sec, bool &Res) const;
> + virtual error_code isSectionBSS(DataRefImpl Sec, bool &Res) const;
> + virtual error_code isSectionRequiredForExecution(DataRefImpl Sec,
> + bool &Res) const;
> + virtual error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const;
> virtual error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const;
> + virtual error_code isSectionReadOnlyData(DataRefImpl Sec, bool &Res) const;
> + virtual error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb,
> + bool &Result) const;
> + virtual relocation_iterator getSectionRelBegin(DataRefImpl Sec) const;
> virtual relocation_iterator getSectionRelEnd(DataRefImpl Sec) const;
> +
> + virtual error_code getRelocationNext(DataRefImpl Rel,
> + RelocationRef &Res) const;
> virtual error_code getRelocationAddress(DataRefImpl Rel, uint64_t &Res) const;
> virtual error_code getRelocationOffset(DataRefImpl Rel, uint64_t &Res) const;
> virtual error_code getRelocationSymbol(DataRefImpl Rel, SymbolRef &Res) const;
> virtual error_code getRelocationType(DataRefImpl Rel, uint64_t &Res) const;
> virtual error_code getRelocationTypeName(DataRefImpl Rel,
> SmallVectorImpl<char> &Result) const;
> + virtual error_code getRelocationAdditionalInfo(DataRefImpl Rel,
> + int64_t &Res) const;
> virtual error_code getRelocationValueString(DataRefImpl Rel,
> SmallVectorImpl<char> &Result) const;
> virtual error_code getRelocationHidden(DataRefImpl Rel, bool &Result) const;
> - virtual error_code getSymbolFileOffset(DataRefImpl Symb, uint64_t &Res) const;
> - virtual error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb,
> - bool &Result) const;
> - virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const;
> - virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const;
> - virtual error_code getSectionNext(DataRefImpl Sec, SectionRef &Res) const;
> - virtual section_iterator begin_sections() const;
> - void moveToNextSection(DataRefImpl &DRI) const;
> -};
> -
> -typedef MachOObjectFileMiddle<support::little> MachOObjectFileLE;
> -typedef MachOObjectFileMiddle<support::big> MachOObjectFileBE;
> -
> -typedef MachOObjectFile<MachOType<support::little, false> >
> - MachOObjectFileLE32;
> -typedef MachOObjectFile<MachOType<support::big, false> >
> - MachOObjectFileBE32;
> -typedef MachOObjectFile<MachOType<support::little, true> >
> - MachOObjectFileLE64;
> -typedef MachOObjectFile<MachOType<support::big, true> >
> - MachOObjectFileBE64;
> -
> -template<endianness TargetEndianness>
> -MachOObjectFileMiddle<TargetEndianness>::MachOObjectFileMiddle(MemoryBuffer *O,
> - bool Is64Bits,
> - error_code &ec) :
> - MachOObjectFileBase(O, TargetEndianness == support::little, Is64Bits, ec) {
> -}
>
> -template<endianness E>
> -const typename MachOObjectFileMiddle<E>::SymbolTableEntryBase *
> -MachOObjectFileMiddle<E>::getSymbolTableEntryBase(DataRefImpl DRI) const {
> - const LoadCommand *L = getLoadCommandInfo(DRI.d.a);
> - const SymtabLoadCommand *S = reinterpret_cast<const SymtabLoadCommand *>(L);
> -
> - unsigned Index = DRI.d.b;
> -
> - unsigned SymbolTableEntrySize = is64Bit() ?
> - sizeof(MachOObjectFileLE64::SymbolTableEntry) :
> - sizeof(MachOObjectFileLE32::SymbolTableEntry);
> -
> - uint64_t Offset = S->SymbolTableOffset + Index * SymbolTableEntrySize;
> - StringRef Data = getData(Offset, SymbolTableEntrySize);
> - return reinterpret_cast<const SymbolTableEntryBase*>(Data.data());
> -}
> -
> -template<endianness E>
> -const typename MachOObjectFileMiddle<E>::Header *
> -MachOObjectFileMiddle<E>::getHeader() const {
> - StringRef Data = getData(0, sizeof(Header));
> - return reinterpret_cast<const Header*>(Data.data());
> -}
> -
> -template<endianness E>
> -const typename MachOObjectFileMiddle<E>::LoadCommand *
> -MachOObjectFileMiddle<E>::getLoadCommandInfo(unsigned Index) const {
> - assert(Index < getHeader()->NumLoadCommands);
> - uint64_t Offset;
> - uint64_t NewOffset = getHeaderSize();
> - const LoadCommand *Load;
> - unsigned I = 0;
> - do {
> - Offset = NewOffset;
> - StringRef Data = getData(Offset, sizeof(MachOObjectFileLE::LoadCommand));
> - Load = reinterpret_cast<const LoadCommand*>(Data.data());
> - NewOffset = Offset + Load->Size;
> - ++I;
> - } while (I != Index + 1);
> -
> - return reinterpret_cast<const LoadCommand*>(Load);
> -}
> -
> -template<endianness E>
> -const typename MachOObjectFileMiddle<E>::RelocationEntry *
> -MachOObjectFileMiddle<E>::getRelocation(DataRefImpl Rel) const {
> - if (const MachOObjectFile<MachOType<E, true> > *O =
> - dyn_cast<MachOObjectFile<MachOType<E, true> > >(this))
> - return O->getRelocation(Rel);
> -
> - const MachOObjectFile<MachOType<E, false> > *O =
> - cast<MachOObjectFile<MachOType<E, false> > >(this);
> - return O->getRelocation(Rel);
> -}
> -
> -template<endianness E>
> -bool
> -MachOObjectFileMiddle<E>::isRelocationScattered(const RelocationEntry *RE)
> - const {
> - if (this->getCPUType() == llvm::MachO::CPUTypeX86_64)
> - return false;
> - return RE->Address & macho::RF_Scattered;
> -}
> -
> -template<endianness E>
> -bool
> -MachOObjectFileMiddle<E>::isRelocationPCRel(const RelocationEntry *RE) const {
> - typedef MachOObjectFileMiddle<E> ObjType;
> - if (isRelocationScattered(RE)) {
> - const typename MachOObjectFileMiddle<E>::ScatteredRelocationEntry *SRE =
> - reinterpret_cast<const typename ObjType::ScatteredRelocationEntry *>(RE);
> - return SRE->PCRel;
> - }
> - return RE->PCRel;
> -}
> -
> -template<endianness E>
> -unsigned
> -MachOObjectFileMiddle<E>::getRelocationLength(const RelocationEntry *RE) const {
> - typedef MachOObjectFileMiddle<E> ObjType;
> - if (isRelocationScattered(RE)) {
> - const typename ObjType::ScatteredRelocationEntry *SRE =
> - reinterpret_cast<const typename ObjType::ScatteredRelocationEntry *>(RE);
> - return SRE->Length;
> - }
> - return RE->Length;
> -}
> -
> -template<endianness E>
> -unsigned
> -MachOObjectFileMiddle<E>::getRelocationTypeImpl(const RelocationEntry *RE)
> - const {
> - typedef MachOObjectFileMiddle<E> ObjType;
> - if (isRelocationScattered(RE)) {
> - const typename ObjType::ScatteredRelocationEntry *SRE =
> - reinterpret_cast<const typename ObjType::ScatteredRelocationEntry *>(RE);
> - return SRE->Type;
> - }
> - return RE->Type;
> -}
> -
> -// Helper to advance a section or symbol iterator multiple increments at a time.
> -template<endianness E>
> -template<class T>
> -error_code MachOObjectFileMiddle<E>::advance(T &it, size_t Val) {
> - error_code ec;
> - while (Val--) {
> - it.increment(ec);
> - }
> - return ec;
> -}
> -
> -template<endianness E>
> -template<class T>
> -void MachOObjectFileMiddle<E>::advanceTo(T &it, size_t Val) {
> - if (error_code ec = advance(it, Val))
> - report_fatal_error(ec.message());
> -}
> -
> -template<endianness E>
> -void
> -MachOObjectFileMiddle<E>::printRelocationTargetName(const RelocationEntry *RE,
> - raw_string_ostream &fmt) const {
> - bool IsScattered = isRelocationScattered(RE);
> -
> - // Target of a scattered relocation is an address. In the interest of
> - // generating pretty output, scan through the symbol table looking for a
> - // symbol that aligns with that address. If we find one, print it.
> - // Otherwise, we just print the hex address of the target.
> - if (IsScattered) {
> - uint32_t Val = RE->SymbolNum;
> -
> - error_code ec;
> - for (symbol_iterator SI = begin_symbols(), SE = end_symbols(); SI != SE;
> - SI.increment(ec)) {
> - if (ec) report_fatal_error(ec.message());
> -
> - uint64_t Addr;
> - StringRef Name;
> -
> - if ((ec = SI->getAddress(Addr)))
> - report_fatal_error(ec.message());
> - if (Addr != Val) continue;
> - if ((ec = SI->getName(Name)))
> - report_fatal_error(ec.message());
> - fmt << Name;
> - return;
> - }
> -
> - // If we couldn't find a symbol that this relocation refers to, try
> - // to find a section beginning instead.
> - for (section_iterator SI = begin_sections(), SE = end_sections(); SI != SE;
> - SI.increment(ec)) {
> - if (ec) report_fatal_error(ec.message());
> -
> - uint64_t Addr;
> - StringRef Name;
> -
> - if ((ec = SI->getAddress(Addr)))
> - report_fatal_error(ec.message());
> - if (Addr != Val) continue;
> - if ((ec = SI->getName(Name)))
> - report_fatal_error(ec.message());
> - fmt << Name;
> - return;
> - }
> -
> - fmt << format("0x%x", Val);
> - return;
> - }
> -
> - StringRef S;
> - bool isExtern = RE->External;
> - uint64_t Val = RE->Address;
> -
> - if (isExtern) {
> - symbol_iterator SI = begin_symbols();
> - advanceTo(SI, Val);
> - SI->getName(S);
> - } else {
> - section_iterator SI = begin_sections();
> - advanceTo(SI, Val);
> - SI->getName(S);
> - }
> -
> - fmt << S;
> -}
> -
> -template<endianness E>
> -const typename MachOObjectFileMiddle<E>::SectionBase *
> -MachOObjectFileMiddle<E>::getSectionBase(DataRefImpl DRI) const {
> - uintptr_t CommandAddr =
> - reinterpret_cast<uintptr_t>(getLoadCommandInfo(DRI.d.a));
> -
> - bool Is64 = is64Bit();
> - unsigned SegmentLoadSize =
> - Is64 ? sizeof(MachOObjectFileLE64::SegmentLoadCommand) :
> - sizeof(MachOObjectFileLE32::SegmentLoadCommand);
> - unsigned SectionSize = Is64 ? sizeof(MachOObjectFileLE64::Section) :
> - sizeof(MachOObjectFileLE32::Section);
> -
> - uintptr_t SectionAddr = CommandAddr + SegmentLoadSize + DRI.d.b * SectionSize;
> - return reinterpret_cast<const SectionBase*>(SectionAddr);
> -}
> -
> -template<endianness E>
> -unsigned MachOObjectFileMiddle<E>::getCPUType() const {
> - return getHeader()->CPUType;
> -}
> -
> -template<endianness E>
> -void MachOObjectFileMiddle<E>::moveToNextSymbol(DataRefImpl &DRI) const {
> - uint32_t LoadCommandCount = getHeader()->NumLoadCommands;
> - while (DRI.d.a < LoadCommandCount) {
> - const LoadCommand *L = getLoadCommandInfo(DRI.d.a);
> - if (L->Type == macho::LCT_Symtab) {
> - const SymtabLoadCommand *S =
> - reinterpret_cast<const SymtabLoadCommand *>(L);
> - if (DRI.d.b < S->NumSymbolTableEntries)
> - return;
> - }
> -
> - DRI.d.a++;
> - DRI.d.b = 0;
> - }
> -}
> -
> -template<endianness E>
> -StringRef
> -MachOObjectFileMiddle<E>::getSectionFinalSegmentName(DataRefImpl Sec) const {
> - ArrayRef<char> Raw = getSectionRawFinalSegmentName(Sec);
> - return parseSegmentOrSectionName(Raw.data());
> -}
> -
> -template<endianness E>
> -ArrayRef<char>
> -MachOObjectFileMiddle<E>::getSectionRawName(DataRefImpl Sec) const {
> - const SectionBase *Base = getSectionBase(Sec);
> - return ArrayRef<char>(Base->Name);
> -}
> -
> -template<endianness E>
> -ArrayRef<char>
> -MachOObjectFileMiddle<E>::getSectionRawFinalSegmentName(DataRefImpl Sec) const {
> - const SectionBase *Base = getSectionBase(Sec);
> - return ArrayRef<char>(Base->SegmentName);
> -}
> -
> -template<endianness E>
> -error_code MachOObjectFileMiddle<E>::getSymbolFlags(DataRefImpl DRI,
> - uint32_t &Result) const {
> - const SymbolTableEntryBase *Entry = getSymbolTableEntryBase(DRI);
> -
> - uint8_t MachOType = Entry->Type;
> - uint16_t MachOFlags = Entry->Flags;
> -
> - // TODO: Correctly set SF_ThreadLocal
> - Result = SymbolRef::SF_None;
> -
> - if ((MachOType & MachO::NlistMaskType) == MachO::NListTypeUndefined)
> - Result |= SymbolRef::SF_Undefined;
> -
> - if (MachOFlags & macho::STF_StabsEntryMask)
> - Result |= SymbolRef::SF_FormatSpecific;
> -
> - if (MachOType & MachO::NlistMaskExternal) {
> - Result |= SymbolRef::SF_Global;
> - if ((MachOType & MachO::NlistMaskType) == MachO::NListTypeUndefined)
> - Result |= SymbolRef::SF_Common;
> - }
> -
> - if (MachOFlags & (MachO::NListDescWeakRef | MachO::NListDescWeakDef))
> - Result |= SymbolRef::SF_Weak;
> -
> - if ((MachOType & MachO::NlistMaskType) == MachO::NListTypeAbsolute)
> - Result |= SymbolRef::SF_Absolute;
> -
> - return object_error::success;
> -}
> -
> -template<endianness E>
> -error_code MachOObjectFileMiddle<E>::getSymbolType(DataRefImpl Symb,
> - SymbolRef::Type &Res) const {
> - const SymbolTableEntryBase *Entry = getSymbolTableEntryBase(Symb);
> - uint8_t n_type = Entry->Type;
> -
> - Res = SymbolRef::ST_Other;
> -
> - // If this is a STAB debugging symbol, we can do nothing more.
> - if (n_type & MachO::NlistMaskStab) {
> - Res = SymbolRef::ST_Debug;
> - return object_error::success;
> - }
> -
> - switch (n_type & MachO::NlistMaskType) {
> - case MachO::NListTypeUndefined :
> - Res = SymbolRef::ST_Unknown;
> - break;
> - case MachO::NListTypeSection :
> - Res = SymbolRef::ST_Function;
> - break;
> - }
> - return object_error::success;
> -}
> -
> -template<endianness E>
> -error_code MachOObjectFileMiddle<E>::getSymbolName(DataRefImpl Symb,
> - StringRef &Res) const {
> - const LoadCommand *L = getLoadCommandInfo(Symb.d.a);
> - const SymtabLoadCommand *S = reinterpret_cast<const SymtabLoadCommand *>(L);
> - StringRef StringTable = getData(S->StringTableOffset, S->StringTableSize);
> - const SymbolTableEntryBase *Entry = getSymbolTableEntryBase(Symb);
> - const char *Start = &StringTable.data()[Entry->StringIndex];
> - Res = StringRef(Start);
> - return object_error::success;
> -}
> -
> -template<endianness E>
> -error_code
> -MachOObjectFileMiddle<E>::getSymbolSection(DataRefImpl Symb,
> - section_iterator &Res) const {
> - const SymbolTableEntryBase *Entry = getSymbolTableEntryBase(Symb);
> - uint8_t index = Entry->SectionIndex;
> -
> - if (index == 0)
> - Res = end_sections();
> - else
> - Res = section_iterator(SectionRef(Sections[index-1], this));
> -
> - return object_error::success;
> -}
> -
> -
> -template<endianness E>
> -error_code MachOObjectFileMiddle<E>::getSymbolNMTypeChar(DataRefImpl Symb,
> - char &Res) const {
> - const SymbolTableEntryBase *Entry = getSymbolTableEntryBase(Symb);
> - uint8_t Type = Entry->Type;
> - uint16_t Flags = Entry->Flags;
> -
> - char Char;
> - switch (Type & macho::STF_TypeMask) {
> - case macho::STT_Undefined:
> - Char = 'u';
> - break;
> - case macho::STT_Absolute:
> - case macho::STT_Section:
> - Char = 's';
> - break;
> - default:
> - Char = '?';
> - break;
> - }
> -
> - if (Flags & (macho::STF_External | macho::STF_PrivateExtern))
> - Char = toupper(static_cast<unsigned char>(Char));
> - Res = Char;
> - return object_error::success;
> -}
> -
> -template<endianness E>
> -error_code
> -MachOObjectFileMiddle<E>::getSectionName(DataRefImpl Sec,
> - StringRef &Result) const {
> - ArrayRef<char> Raw = getSectionRawName(Sec);
> - Result = parseSegmentOrSectionName(Raw.data());
> - return object_error::success;
> -}
> -
> -template<endianness E>
> -error_code MachOObjectFileMiddle<E>::getSymbolNext(DataRefImpl Symb,
> - SymbolRef &Res) const {
> - Symb.d.b++;
> - moveToNextSymbol(Symb);
> - Res = SymbolRef(Symb, this);
> - return object_error::success;
> -}
> -
> -template<endianness E>
> -symbol_iterator MachOObjectFileMiddle<E>::begin_symbols() const {
> - // DRI.d.a = segment number; DRI.d.b = symbol index.
> - DataRefImpl DRI;
> - moveToNextSymbol(DRI);
> - return symbol_iterator(SymbolRef(DRI, this));
> -}
> -
> -template<endianness E>
> -unsigned MachOObjectFileMiddle<E>::getArch() const {
> - switch (getCPUType()) {
> - case llvm::MachO::CPUTypeI386:
> - return Triple::x86;
> - case llvm::MachO::CPUTypeX86_64:
> - return Triple::x86_64;
> - case llvm::MachO::CPUTypeARM:
> - return Triple::arm;
> - case llvm::MachO::CPUTypePowerPC:
> - return Triple::ppc;
> - case llvm::MachO::CPUTypePowerPC64:
> - return Triple::ppc64;
> - default:
> - return Triple::UnknownArch;
> - }
> -}
> -
> -template<endianness E>
> -StringRef MachOObjectFileMiddle<E>::getFileFormatName() const {
> - unsigned CPUType = getCPUType();
> - if (!is64Bit()) {
> - switch (CPUType) {
> - case llvm::MachO::CPUTypeI386:
> - return "Mach-O 32-bit i386";
> - case llvm::MachO::CPUTypeARM:
> - return "Mach-O arm";
> - case llvm::MachO::CPUTypePowerPC:
> - return "Mach-O 32-bit ppc";
> - default:
> - assert((CPUType & llvm::MachO::CPUArchABI64) == 0 &&
> - "64-bit object file when we're not 64-bit?");
> - return "Mach-O 32-bit unknown";
> - }
> - }
> -
> - // Make sure the cpu type has the correct mask.
> - assert((CPUType & llvm::MachO::CPUArchABI64)
> - == llvm::MachO::CPUArchABI64 &&
> - "32-bit object file when we're 64-bit?");
> -
> - switch (CPUType) {
> - case llvm::MachO::CPUTypeX86_64:
> - return "Mach-O 64-bit x86-64";
> - case llvm::MachO::CPUTypePowerPC64:
> - return "Mach-O 64-bit ppc64";
> - default:
> - return "Mach-O 64-bit unknown";
> - }
> -}
> -
> -template<endianness E>
> -symbol_iterator MachOObjectFileMiddle<E>::end_symbols() const {
> - DataRefImpl DRI;
> - DRI.d.a = getHeader()->NumLoadCommands;
> - return symbol_iterator(SymbolRef(DRI, this));
> -}
> -
> -template<endianness E>
> -section_iterator MachOObjectFileMiddle<E>::end_sections() const {
> - DataRefImpl DRI;
> - DRI.d.a = getHeader()->NumLoadCommands;
> - return section_iterator(SectionRef(DRI, this));
> -}
> -
> -template<endianness E>
> -bool MachOObjectFileMiddle<E>::classof(const Binary *v) {
> - return isa<MachOObjectFile<MachOType<E, false> > >(v) ||
> - isa<MachOObjectFile<MachOType<E, true> > >(v);
> -}
> -
> -template<class MachOT>
> -MachOObjectFile<MachOT>::MachOObjectFile(MemoryBuffer *Object,
> - error_code &ec) :
> - MachOObjectFileMiddle<TargetEndianness>(Object, Is64Bits, ec) {
> - DataRefImpl DRI;
> - moveToNextSection(DRI);
> - uint32_t LoadCommandCount = this->getHeader()->NumLoadCommands;
> - while (DRI.d.a < LoadCommandCount) {
> - this->Sections.push_back(DRI);
> - DRI.d.b++;
> - moveToNextSection(DRI);
> - }
> -}
> -
> -template<class MachOT>
> -bool MachOObjectFile<MachOT>::classof(const Binary *v) {
> - return v->getType() ==
> - Base::getMachOType(TargetEndianness == support::little, Is64Bits);
> -}
> -
> -template<class MachOT>
> -const typename MachOObjectFile<MachOT>::Section *
> -MachOObjectFile<MachOT>::getSection(DataRefImpl DRI) const {
> - const SectionBase *Addr = this->getSectionBase(DRI);
> - return reinterpret_cast<const Section*>(Addr);
> -}
> -
> -template<class MachOT>
> -const typename MachOObjectFile<MachOT>::SymbolTableEntry *
> -MachOObjectFile<MachOT>::getSymbolTableEntry(DataRefImpl DRI) const {
> - const SymbolTableEntryBase *Base = this->getSymbolTableEntryBase(DRI);
> - return reinterpret_cast<const SymbolTableEntry*>(Base);
> -}
> -
> -template<class MachOT>
> -const typename MachOObjectFile<MachOT>::RelocationEntry *
> -MachOObjectFile<MachOT>::getRelocation(DataRefImpl Rel) const {
> - const Section *Sect = getSection(this->Sections[Rel.d.b]);
> - uint32_t RelOffset = Sect->RelocationTableOffset;
> - uint64_t Offset = RelOffset + Rel.d.a * sizeof(RelocationEntry);
> - StringRef Data = this->getData(Offset, sizeof(RelocationEntry));
> - return reinterpret_cast<const RelocationEntry*>(Data.data());
> -}
> -
> -template<class MachOT>
> -error_code
> -MachOObjectFile<MachOT>::getSectionAddress(DataRefImpl Sec,
> - uint64_t &Res) const {
> - const Section *Sect = getSection(Sec);
> - Res = Sect->Address;
> - return object_error::success;
> -}
> -
> -template<class MachOT>
> -error_code
> -MachOObjectFile<MachOT>::getSectionSize(DataRefImpl Sec,
> - uint64_t &Res) const {
> - const Section *Sect = getSection(Sec);
> - Res = Sect->Size;
> - return object_error::success;
> -}
> -
> -template<class MachOT>
> -error_code
> -MachOObjectFile<MachOT>::getSectionContents(DataRefImpl Sec,
> - StringRef &Res) const {
> - const Section *Sect = getSection(Sec);
> - Res = this->getData(Sect->Offset, Sect->Size);
> - return object_error::success;
> -}
> -
> -template<class MachOT>
> -error_code
> -MachOObjectFile<MachOT>::getSectionAlignment(DataRefImpl Sec,
> - uint64_t &Res) const {
> - const Section *Sect = getSection(Sec);
> - Res = uint64_t(1) << Sect->Align;
> - return object_error::success;
> -}
> -
> -template<class MachOT>
> -error_code
> -MachOObjectFile<MachOT>::isSectionText(DataRefImpl Sec, bool &Res) const {
> - const Section *Sect = getSection(Sec);
> - Res = Sect->Flags & macho::SF_PureInstructions;
> - return object_error::success;
> -}
> -
> -template<class MachOT>
> -error_code
> -MachOObjectFile<MachOT>::isSectionZeroInit(DataRefImpl Sec, bool &Res) const {
> - const Section *Sect = getSection(Sec);
> - unsigned SectionType = Sect->Flags & MachO::SectionFlagMaskSectionType;
> - Res = SectionType == MachO::SectionTypeZeroFill ||
> - SectionType == MachO::SectionTypeZeroFillLarge;
> - return object_error::success;
> -}
> -
> -template<class MachOT>
> -relocation_iterator
> -MachOObjectFile<MachOT>::getSectionRelEnd(DataRefImpl Sec) const {
> - const Section *Sect = getSection(Sec);
> - uint32_t LastReloc = Sect->NumRelocationTableEntries;
> - DataRefImpl Ret;
> - Ret.d.a = LastReloc;
> - Ret.d.b = this->getSectionIndex(Sec);
> - return relocation_iterator(RelocationRef(Ret, this));
> -}
> -
> -template<class MachOT>
> -error_code
> -MachOObjectFile<MachOT>::getRelocationAddress(DataRefImpl Rel,
> - uint64_t &Res) const {
> - const Section *Sect = getSection(this->Sections[Rel.d.b]);
> - uint64_t SectAddress = Sect->Address;
> - const RelocationEntry *RE = getRelocation(Rel);
> -
> - uint64_t RelAddr;
> - if (this->isRelocationScattered(RE))
> - RelAddr = RE->Address & 0xFFFFFF;
> - else
> - RelAddr = RE->Address;
> -
> - Res = SectAddress + RelAddr;
> - return object_error::success;
> -}
> -
> -template<class MachOT>
> -error_code
> -MachOObjectFile<MachOT>::getRelocationOffset(DataRefImpl Rel,
> - uint64_t &Res) const {
> - const RelocationEntry *RE = getRelocation(Rel);
> - if (this->isRelocationScattered(RE))
> - Res = RE->Address & 0xFFFFFF;
> - else
> - Res = RE->Address;
> - return object_error::success;
> -}
> -
> -template<class MachOT>
> -error_code
> -MachOObjectFile<MachOT>::getRelocationSymbol(DataRefImpl Rel,
> - SymbolRef &Res) const {
> - const RelocationEntry *RE = getRelocation(Rel);
> - uint32_t SymbolIdx = RE->SymbolNum;
> - bool isExtern = RE->External;
> -
> - DataRefImpl Sym;
> - this->moveToNextSymbol(Sym);
> - if (isExtern) {
> - for (unsigned i = 0; i < SymbolIdx; i++) {
> - Sym.d.b++;
> - this->moveToNextSymbol(Sym);
> - assert(Sym.d.a < this->getHeader()->NumLoadCommands &&
> - "Relocation symbol index out of range!");
> - }
> - }
> - Res = SymbolRef(Sym, this);
> - return object_error::success;
> -}
> -
> -template<class MachOT>
> -error_code MachOObjectFile<MachOT>::getRelocationType(DataRefImpl Rel,
> - uint64_t &Res) const {
> - const RelocationEntry *RE = getRelocation(Rel);
> - Res = this->getRelocationTypeImpl(RE);
> - return object_error::success;
> -}
> -
> -template<class MachOT>
> -error_code
> -MachOObjectFile<MachOT>::getRelocationTypeName(DataRefImpl Rel,
> - SmallVectorImpl<char> &Result) const {
> - // TODO: Support scattered relocations.
> - StringRef res;
> - const RelocationEntry *RE = getRelocation(Rel);
> -
> - unsigned Arch = this->getArch();
> -
> - unsigned r_type = this->getRelocationTypeImpl(RE);
> -
> - switch (Arch) {
> - case Triple::x86: {
> - static const char *const Table[] = {
> - "GENERIC_RELOC_VANILLA",
> - "GENERIC_RELOC_PAIR",
> - "GENERIC_RELOC_SECTDIFF",
> - "GENERIC_RELOC_PB_LA_PTR",
> - "GENERIC_RELOC_LOCAL_SECTDIFF",
> - "GENERIC_RELOC_TLV" };
> -
> - if (r_type > 6)
> - res = "Unknown";
> - else
> - res = Table[r_type];
> - break;
> - }
> - case Triple::x86_64: {
> - static const char *const Table[] = {
> - "X86_64_RELOC_UNSIGNED",
> - "X86_64_RELOC_SIGNED",
> - "X86_64_RELOC_BRANCH",
> - "X86_64_RELOC_GOT_LOAD",
> - "X86_64_RELOC_GOT",
> - "X86_64_RELOC_SUBTRACTOR",
> - "X86_64_RELOC_SIGNED_1",
> - "X86_64_RELOC_SIGNED_2",
> - "X86_64_RELOC_SIGNED_4",
> - "X86_64_RELOC_TLV" };
> -
> - if (r_type > 9)
> - res = "Unknown";
> - else
> - res = Table[r_type];
> - break;
> - }
> - case Triple::arm: {
> - static const char *const Table[] = {
> - "ARM_RELOC_VANILLA",
> - "ARM_RELOC_PAIR",
> - "ARM_RELOC_SECTDIFF",
> - "ARM_RELOC_LOCAL_SECTDIFF",
> - "ARM_RELOC_PB_LA_PTR",
> - "ARM_RELOC_BR24",
> - "ARM_THUMB_RELOC_BR22",
> - "ARM_THUMB_32BIT_BRANCH",
> - "ARM_RELOC_HALF",
> - "ARM_RELOC_HALF_SECTDIFF" };
> -
> - if (r_type > 9)
> - res = "Unknown";
> - else
> - res = Table[r_type];
> - break;
> - }
> - case Triple::ppc: {
> - static const char *const Table[] = {
> - "PPC_RELOC_VANILLA",
> - "PPC_RELOC_PAIR",
> - "PPC_RELOC_BR14",
> - "PPC_RELOC_BR24",
> - "PPC_RELOC_HI16",
> - "PPC_RELOC_LO16",
> - "PPC_RELOC_HA16",
> - "PPC_RELOC_LO14",
> - "PPC_RELOC_SECTDIFF",
> - "PPC_RELOC_PB_LA_PTR",
> - "PPC_RELOC_HI16_SECTDIFF",
> - "PPC_RELOC_LO16_SECTDIFF",
> - "PPC_RELOC_HA16_SECTDIFF",
> - "PPC_RELOC_JBSR",
> - "PPC_RELOC_LO14_SECTDIFF",
> - "PPC_RELOC_LOCAL_SECTDIFF" };
> -
> - res = Table[r_type];
> - break;
> - }
> - case Triple::UnknownArch:
> - res = "Unknown";
> - break;
> - }
> - Result.append(res.begin(), res.end());
> - return object_error::success;
> -}
> + virtual error_code getLibraryNext(DataRefImpl LibData, LibraryRef &Res) const;
> + virtual error_code getLibraryPath(DataRefImpl LibData, StringRef &Res) const;
>
> -template<class MachOT>
> -error_code
> -MachOObjectFile<MachOT>::getRelocationValueString(DataRefImpl Rel,
> - SmallVectorImpl<char> &Result) const {
> - const RelocationEntry *RE = getRelocation(Rel);
> -
> - unsigned Arch = this->getArch();
> - bool IsScattered = this->isRelocationScattered(RE);
> -
> - std::string fmtbuf;
> - raw_string_ostream fmt(fmtbuf);
> -
> - unsigned Type = this->getRelocationTypeImpl(RE);
> - bool IsPCRel = this->isRelocationPCRel(RE);
> -
> - // Determine any addends that should be displayed with the relocation.
> - // These require decoding the relocation type, which is triple-specific.
> -
> - // X86_64 has entirely custom relocation types.
> - if (Arch == Triple::x86_64) {
> - bool isPCRel = RE->PCRel;
> -
> - switch (Type) {
> - case macho::RIT_X86_64_GOTLoad: // X86_64_RELOC_GOT_LOAD
> - case macho::RIT_X86_64_GOT: { // X86_64_RELOC_GOT
> - this->printRelocationTargetName(RE, fmt);
> - fmt << "@GOT";
> - if (isPCRel) fmt << "PCREL";
> - break;
> - }
> - case macho::RIT_X86_64_Subtractor: { // X86_64_RELOC_SUBTRACTOR
> - DataRefImpl RelNext = Rel;
> - RelNext.d.a++;
> - const RelocationEntry *RENext = getRelocation(RelNext);
> -
> - // X86_64_SUBTRACTOR must be followed by a relocation of type
> - // X86_64_RELOC_UNSIGNED.
> - // NOTE: Scattered relocations don't exist on x86_64.
> - unsigned RType = RENext->Type;
> - if (RType != 0)
> - report_fatal_error("Expected X86_64_RELOC_UNSIGNED after "
> - "X86_64_RELOC_SUBTRACTOR.");
> -
> - // The X86_64_RELOC_UNSIGNED contains the minuend symbol,
> - // X86_64_SUBTRACTOR contains to the subtrahend.
> - this->printRelocationTargetName(RENext, fmt);
> - fmt << "-";
> - this->printRelocationTargetName(RE, fmt);
> - break;
> - }
> - case macho::RIT_X86_64_TLV:
> - this->printRelocationTargetName(RE, fmt);
> - fmt << "@TLV";
> - if (isPCRel) fmt << "P";
> - break;
> - case macho::RIT_X86_64_Signed1: // X86_64_RELOC_SIGNED1
> - this->printRelocationTargetName(RE, fmt);
> - fmt << "-1";
> - break;
> - case macho::RIT_X86_64_Signed2: // X86_64_RELOC_SIGNED2
> - this->printRelocationTargetName(RE, fmt);
> - fmt << "-2";
> - break;
> - case macho::RIT_X86_64_Signed4: // X86_64_RELOC_SIGNED4
> - this->printRelocationTargetName(RE, fmt);
> - fmt << "-4";
> - break;
> - default:
> - this->printRelocationTargetName(RE, fmt);
> - break;
> - }
> - // X86 and ARM share some relocation types in common.
> - } else if (Arch == Triple::x86 || Arch == Triple::arm) {
> - // Generic relocation types...
> - switch (Type) {
> - case macho::RIT_Pair: // GENERIC_RELOC_PAIR - prints no info
> - return object_error::success;
> - case macho::RIT_Difference: { // GENERIC_RELOC_SECTDIFF
> - DataRefImpl RelNext = Rel;
> - RelNext.d.a++;
> - const RelocationEntry *RENext = getRelocation(RelNext);
> -
> - // X86 sect diff's must be followed by a relocation of type
> - // GENERIC_RELOC_PAIR.
> - bool isNextScattered = (Arch != Triple::x86_64) &&
> - (RENext->Address & macho::RF_Scattered);
> - unsigned RType;
> - if (isNextScattered)
> - RType = (RENext->Address >> 24) & 0xF;
> - else
> - RType = RENext->Type;
> - if (RType != 1)
> - report_fatal_error("Expected GENERIC_RELOC_PAIR after "
> - "GENERIC_RELOC_SECTDIFF.");
> -
> - this->printRelocationTargetName(RE, fmt);
> - fmt << "-";
> - this->printRelocationTargetName(RENext, fmt);
> - break;
> - }
> - }
> -
> - if (Arch == Triple::x86) {
> - // All X86 relocations that need special printing were already
> - // handled in the generic code.
> - switch (Type) {
> - case macho::RIT_Generic_LocalDifference:{// GENERIC_RELOC_LOCAL_SECTDIFF
> - DataRefImpl RelNext = Rel;
> - RelNext.d.a++;
> - const RelocationEntry *RENext = getRelocation(RelNext);
> -
> - // X86 sect diff's must be followed by a relocation of type
> - // GENERIC_RELOC_PAIR.
> - bool isNextScattered = (Arch != Triple::x86_64) &&
> - (RENext->Address & macho::RF_Scattered);
> - unsigned RType;
> - if (isNextScattered)
> - RType = (RENext->Address >> 24) & 0xF;
> - else
> - RType = RENext->Type;
> - if (RType != 1)
> - report_fatal_error("Expected GENERIC_RELOC_PAIR after "
> - "GENERIC_RELOC_LOCAL_SECTDIFF.");
> -
> - this->printRelocationTargetName(RE, fmt);
> - fmt << "-";
> - this->printRelocationTargetName(RENext, fmt);
> - break;
> - }
> - case macho::RIT_Generic_TLV: {
> - this->printRelocationTargetName(RE, fmt);
> - fmt << "@TLV";
> - if (IsPCRel) fmt << "P";
> - break;
> - }
> - default:
> - this->printRelocationTargetName(RE, fmt);
> - }
> - } else { // ARM-specific relocations
> - switch (Type) {
> - case macho::RIT_ARM_Half: // ARM_RELOC_HALF
> - case macho::RIT_ARM_HalfDifference: { // ARM_RELOC_HALF_SECTDIFF
> - // Half relocations steal a bit from the length field to encode
> - // whether this is an upper16 or a lower16 relocation.
> - bool isUpper;
> - if (IsScattered)
> - isUpper = (RE->Address >> 28) & 1;
> - else
> - isUpper = (RE->Length >> 1) & 1;
> -
> - if (isUpper)
> - fmt << ":upper16:(";
> - else
> - fmt << ":lower16:(";
> - this->printRelocationTargetName(RE, fmt);
> -
> - DataRefImpl RelNext = Rel;
> - RelNext.d.a++;
> - const RelocationEntry *RENext = getRelocation(RelNext);
> -
> - // ARM half relocs must be followed by a relocation of type
> - // ARM_RELOC_PAIR.
> - bool isNextScattered = (Arch != Triple::x86_64) &&
> - (RENext->Address & macho::RF_Scattered);
> - unsigned RType;
> - if (isNextScattered)
> - RType = (RENext->Address >> 24) & 0xF;
> - else
> - RType = RENext->Type;
> -
> - if (RType != 1)
> - report_fatal_error("Expected ARM_RELOC_PAIR after "
> - "GENERIC_RELOC_HALF");
> -
> - // NOTE: The half of the target virtual address is stashed in the
> - // address field of the secondary relocation, but we can't reverse
> - // engineer the constant offset from it without decoding the movw/movt
> - // instruction to find the other half in its immediate field.
> -
> - // ARM_RELOC_HALF_SECTDIFF encodes the second section in the
> - // symbol/section pointer of the follow-on relocation.
> - if (Type == macho::RIT_ARM_HalfDifference) {
> - fmt << "-";
> - this->printRelocationTargetName(RENext, fmt);
> - }
> -
> - fmt << ")";
> - break;
> - }
> - default: {
> - this->printRelocationTargetName(RE, fmt);
> - }
> - }
> - }
> - } else
> - this->printRelocationTargetName(RE, fmt);
> -
> - fmt.flush();
> - Result.append(fmtbuf.begin(), fmtbuf.end());
> - return object_error::success;
> -}
> + virtual symbol_iterator begin_symbols() const;
> + virtual symbol_iterator end_symbols() const;
>
> -template<class MachOT>
> -error_code
> -MachOObjectFile<MachOT>::getRelocationHidden(DataRefImpl Rel,
> - bool &Result) const {
> - const RelocationEntry *RE = getRelocation(Rel);
> - unsigned Arch = this->getArch();
> - unsigned Type = this->getRelocationTypeImpl(RE);
> -
> - Result = false;
> -
> - // On arches that use the generic relocations, GENERIC_RELOC_PAIR
> - // is always hidden.
> - if (Arch == Triple::x86 || Arch == Triple::arm) {
> - if (Type == macho::RIT_Pair) Result = true;
> - } else if (Arch == Triple::x86_64) {
> - // On x86_64, X86_64_RELOC_UNSIGNED is hidden only when it follows
> - // an X864_64_RELOC_SUBTRACTOR.
> - if (Type == macho::RIT_X86_64_Unsigned && Rel.d.a > 0) {
> - DataRefImpl RelPrev = Rel;
> - RelPrev.d.a--;
> - const RelocationEntry *REPrev = this->getRelocation(RelPrev);
> + virtual symbol_iterator begin_dynamic_symbols() const;
> + virtual symbol_iterator end_dynamic_symbols() const;
>
> - unsigned PrevType = REPrev->Type;
> + virtual section_iterator begin_sections() const;
> + virtual section_iterator end_sections() const;
>
> - if (PrevType == macho::RIT_X86_64_Subtractor) Result = true;
> - }
> - }
> + virtual library_iterator begin_libraries_needed() const;
> + virtual library_iterator end_libraries_needed() const;
>
> - return object_error::success;
> -}
> + virtual uint8_t getBytesInAddress() const;
>
> -template<class MachOT>
> -error_code
> -MachOObjectFile<MachOT>::getSymbolFileOffset(DataRefImpl Symb,
> - uint64_t &Res) const {
> - const SymbolTableEntry *Entry = getSymbolTableEntry(Symb);
> - Res = Entry->Value;
> - if (Entry->SectionIndex) {
> - const Section *Sec =
> - this->getSection(this->Sections[Entry->SectionIndex-1]);
> - Res += Sec->Offset - Sec->Address;
> - }
> + virtual StringRef getFileFormatName() const;
> + virtual unsigned getArch() const;
>
> - return object_error::success;
> -}
> + virtual StringRef getLoadName() const;
>
> -template<class MachOT>
> -error_code
> -MachOObjectFile<MachOT>::sectionContainsSymbol(DataRefImpl Sec,
> - DataRefImpl Symb,
> - bool &Result) const {
> - SymbolRef::Type ST;
> - this->getSymbolType(Symb, ST);
> - if (ST == SymbolRef::ST_Unknown) {
> - Result = false;
> - return object_error::success;
> - }
> + // 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.
> + StringRef getSectionFinalSegmentName(DataRefImpl Sec) const;
>
> - uint64_t SectBegin, SectEnd;
> - getSectionAddress(Sec, SectBegin);
> - getSectionSize(Sec, SectEnd);
> - SectEnd += SectBegin;
> -
> - const SymbolTableEntry *Entry = getSymbolTableEntry(Symb);
> - uint64_t SymAddr= Entry->Value;
> - Result = (SymAddr >= SectBegin) && (SymAddr < SectEnd);
> + // Names are stored as 16 bytes. These returns the raw 16 bytes without
> + // interpreting them as a C string.
> + ArrayRef<char> getSectionRawName(DataRefImpl Sec) const;
> + ArrayRef<char> getSectionRawFinalSegmentName(DataRefImpl Sec) const;
>
> - return object_error::success;
> -}
> + // MachO specific Info about relocations.
> + bool isRelocationScattered(const macho::RelocationEntry &RE) const;
> + unsigned getPlainRelocationSymbolNum(const macho::RelocationEntry &RE) const;
> + bool getPlainRelocationExternal(const macho::RelocationEntry &RE) const;
> + bool getScatteredRelocationScattered(const macho::RelocationEntry &RE) const;
> + uint32_t getScatteredRelocationValue(const macho::RelocationEntry &RE) const;
> + unsigned getAnyRelocationAddress(const macho::RelocationEntry &RE) const;
> + unsigned getAnyRelocationPCRel(const macho::RelocationEntry &RE) const;
> + unsigned getAnyRelocationLength(const macho::RelocationEntry &RE) const;
> + unsigned getAnyRelocationType(const macho::RelocationEntry &RE) const;
> +
> + // Walk load commands.
> + LoadCommandInfo getFirstLoadCommandInfo() const;
> + LoadCommandInfo getNextLoadCommandInfo(const LoadCommandInfo &L) const;
> +
> + // MachO specific structures.
> + macho::Section getSection(DataRefImpl DRI) const;
> + macho::Section64 getSection64(DataRefImpl DRI) const;
> + macho::SymbolTableEntry getSymbolTableEntry(DataRefImpl DRI) const;
> + macho::Symbol64TableEntry getSymbol64TableEntry(DataRefImpl DRI) const;
> + macho::LinkeditDataLoadCommand
> + getLinkeditDataLoadCommand(const LoadCommandInfo &L) const;
> + macho::RelocationEntry getRelocation(DataRefImpl Rel) const;
> + macho::Header getHeader() const;
> + macho::SymtabLoadCommand getSymtabLoadCommand() const;
>
> -template<class MachOT>
> -error_code MachOObjectFile<MachOT>::getSymbolAddress(DataRefImpl Symb,
> - uint64_t &Res) const {
> - const SymbolTableEntry *Entry = getSymbolTableEntry(Symb);
> - Res = Entry->Value;
> - return object_error::success;
> -}
> + bool is64Bit() const;
> + void ReadULEB128s(uint64_t Index, SmallVectorImpl<uint64_t> &Out) const;
>
> -template<class MachOT>
> -error_code MachOObjectFile<MachOT>::getSymbolSize(DataRefImpl DRI,
> - uint64_t &Result) const {
> - uint32_t LoadCommandCount = this->getHeader()->NumLoadCommands;
> - uint64_t BeginOffset;
> - uint64_t EndOffset = 0;
> - uint8_t SectionIndex;
> -
> - const SymbolTableEntry *Entry = getSymbolTableEntry(DRI);
> - BeginOffset = Entry->Value;
> - SectionIndex = Entry->SectionIndex;
> - if (!SectionIndex) {
> - uint32_t flags = SymbolRef::SF_None;
> - this->getSymbolFlags(DRI, flags);
> - if (flags & SymbolRef::SF_Common)
> - Result = Entry->Value;
> - else
> - Result = UnknownAddressOrSize;
> - return object_error::success;
> - }
> - // Unfortunately symbols are unsorted so we need to touch all
> - // symbols from load command
> - DRI.d.b = 0;
> - uint32_t Command = DRI.d.a;
> - while (Command == DRI.d.a) {
> - this->moveToNextSymbol(DRI);
> - if (DRI.d.a < LoadCommandCount) {
> - Entry = getSymbolTableEntry(DRI);
> - if (Entry->SectionIndex == SectionIndex && Entry->Value > BeginOffset)
> - if (!EndOffset || Entry->Value < EndOffset)
> - EndOffset = Entry->Value;
> - }
> - DRI.d.b++;
> - }
> - if (!EndOffset) {
> - uint64_t Size;
> - this->getSectionSize(this->Sections[SectionIndex-1], Size);
> - this->getSectionAddress(this->Sections[SectionIndex-1], EndOffset);
> - EndOffset += Size;
> + static bool classof(const Binary *v) {
> + return v->isMachO();
> }
> - Result = EndOffset - BeginOffset;
> - return object_error::success;
> -}
>
> -template<class MachOT>
> -error_code MachOObjectFile<MachOT>::getSectionNext(DataRefImpl Sec,
> - SectionRef &Res) const {
> - Sec.d.b++;
> - moveToNextSection(Sec);
> - Res = SectionRef(Sec, this);
> - return object_error::success;
> -}
> -
> -template<class MachOT>
> -section_iterator MachOObjectFile<MachOT>::begin_sections() const {
> - DataRefImpl DRI;
> - moveToNextSection(DRI);
> - return section_iterator(SectionRef(DRI, this));
> -}
> -
> -template<class MachOT>
> -void MachOObjectFile<MachOT>::moveToNextSection(DataRefImpl &DRI) const {
> - uint32_t LoadCommandCount = this->getHeader()->NumLoadCommands;
> - while (DRI.d.a < LoadCommandCount) {
> - const LoadCommand *Command = this->getLoadCommandInfo(DRI.d.a);
> - if (Command->Type == SegmentLoadType) {
> - const SegmentLoadCommand *SegmentLoadCmd =
> - reinterpret_cast<const SegmentLoadCommand*>(Command);
> - if (DRI.d.b < SegmentLoadCmd->NumSections)
> - return;
> - }
> -
> - DRI.d.a++;
> - DRI.d.b = 0;
> - }
> -}
> +private:
> + typedef SmallVector<const char*, 1> SectionList;
> + SectionList Sections;
> + const char *SymtabLoadCmd;
> +};
>
> }
> }
>
> Modified: llvm/trunk/lib/Object/MachOObjectFile.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/MachOObjectFile.cpp?rev=179778&r1=179777&r2=179778&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Object/MachOObjectFile.cpp (original)
> +++ llvm/trunk/lib/Object/MachOObjectFile.cpp Thu Apr 18 13:08:55 2013
> @@ -15,9 +15,9 @@
> #include "llvm/Object/MachO.h"
> #include "llvm/ADT/Triple.h"
> #include "llvm/Object/MachOFormat.h"
> -#include "llvm/Support/Casting.h"
> #include "llvm/Support/DataExtractor.h"
> #include "llvm/Support/Format.h"
> +#include "llvm/Support/Host.h"
> #include "llvm/Support/MemoryBuffer.h"
> #include <cctype>
> #include <cstring>
> @@ -29,113 +29,693 @@ using namespace object;
> namespace llvm {
> namespace object {
>
> -MachOObjectFileBase::MachOObjectFileBase(MemoryBuffer *Object,
> - bool IsLittleEndian, bool Is64bits,
> - error_code &ec)
> - : ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object) {
> +struct SymbolTableEntryBase {
> + uint32_t StringIndex;
> + uint8_t Type;
> + uint8_t SectionIndex;
> + uint16_t Flags;
> +};
> +
> +struct SectionBase {
> + char Name[16];
> + char SegmentName[16];
> +};
> +
> +template<typename T>
> +static void SwapValue(T &Value) {
> + Value = sys::SwapByteOrder(Value);
> +}
> +
> +template<typename T>
> +static void SwapStruct(T &Value);
> +
> +template<>
> +void SwapStruct(macho::RelocationEntry &H) {
> + SwapValue(H.Word0);
> + SwapValue(H.Word1);
> +}
> +
> +template<>
> +void SwapStruct(macho::LoadCommand &L) {
> + SwapValue(L.Type);
> + SwapValue(L.Size);
> +}
> +
> +template<>
> +void SwapStruct(SymbolTableEntryBase &S) {
> + SwapValue(S.StringIndex);
> + SwapValue(S.Flags);
> +}
> +
> +template<>
> +void SwapStruct(macho::Section &S) {
> + SwapValue(S.Address);
> + SwapValue(S.Size);
> + SwapValue(S.Offset);
> + SwapValue(S.Align);
> + SwapValue(S.RelocationTableOffset);
> + SwapValue(S.NumRelocationTableEntries);
> + SwapValue(S.Flags);
> + SwapValue(S.Reserved1);
> + SwapValue(S.Reserved2);
> +}
> +
> +template<>
> +void SwapStruct(macho::Section64 &S) {
> + SwapValue(S.Address);
> + SwapValue(S.Size);
> + SwapValue(S.Offset);
> + SwapValue(S.Align);
> + SwapValue(S.RelocationTableOffset);
> + SwapValue(S.NumRelocationTableEntries);
> + SwapValue(S.Flags);
> + SwapValue(S.Reserved1);
> + SwapValue(S.Reserved2);
> + SwapValue(S.Reserved3);
> +}
> +
> +template<>
> +void SwapStruct(macho::SymbolTableEntry &S) {
> + SwapValue(S.StringIndex);
> + SwapValue(S.Flags);
> + SwapValue(S.Value);
> +}
> +
> +template<>
> +void SwapStruct(macho::Symbol64TableEntry &S) {
> + SwapValue(S.StringIndex);
> + SwapValue(S.Flags);
> + SwapValue(S.Value);
> +}
> +
> +template<>
> +void SwapStruct(macho::Header &H) {
> + SwapValue(H.Magic);
> + SwapValue(H.CPUType);
> + SwapValue(H.CPUSubtype);
> + SwapValue(H.FileType);
> + SwapValue(H.NumLoadCommands);
> + SwapValue(H.SizeOfLoadCommands);
> + SwapValue(H.Flags);
> +}
> +
> +template<>
> +void SwapStruct(macho::SymtabLoadCommand &C) {
> + SwapValue(C.Type);
> + SwapValue(C.Size);
> + SwapValue(C.SymbolTableOffset);
> + SwapValue(C.NumSymbolTableEntries);
> + SwapValue(C.StringTableOffset);
> + SwapValue(C.StringTableSize);
> +}
> +
> +template<>
> +void SwapStruct(macho::LinkeditDataLoadCommand &C) {
> + SwapValue(C.Type);
> + SwapValue(C.Size);
> + SwapValue(C.DataOffset);
> + SwapValue(C.DataSize);
> +}
> +
> +template<>
> +void SwapStruct(macho::SegmentLoadCommand &C) {
> + SwapValue(C.Type);
> + SwapValue(C.Size);
> + SwapValue(C.VMAddress);
> + SwapValue(C.VMSize);
> + SwapValue(C.FileOffset);
> + SwapValue(C.FileSize);
> + SwapValue(C.MaxVMProtection);
> + SwapValue(C.InitialVMProtection);
> + SwapValue(C.NumSections);
> + SwapValue(C.Flags);
> +}
> +
> +template<>
> +void SwapStruct(macho::Segment64LoadCommand &C) {
> + SwapValue(C.Type);
> + SwapValue(C.Size);
> + SwapValue(C.VMAddress);
> + SwapValue(C.VMSize);
> + SwapValue(C.FileOffset);
> + SwapValue(C.FileSize);
> + SwapValue(C.MaxVMProtection);
> + SwapValue(C.InitialVMProtection);
> + SwapValue(C.NumSections);
> + SwapValue(C.Flags);
> +}
> +
> +static bool isSwappedEndian(const MachOObjectFile *O) {
> + return O->isLittleEndian() != sys::IsLittleEndianHost;
> +}
> +
> +static macho::SegmentLoadCommand
> +getSegmentLoadCommand(const MachOObjectFile *O,
> + const MachOObjectFile::LoadCommandInfo &L) {
> + macho::SegmentLoadCommand Cmd;
> + memcpy(&Cmd, L.Ptr, sizeof(macho::SegmentLoadCommand));
> + if (isSwappedEndian(O))
> + SwapStruct(Cmd);
> + return Cmd;
> +}
> +
> +static macho::Segment64LoadCommand
> +getSegment64LoadCommand(const MachOObjectFile *O,
> + const MachOObjectFile::LoadCommandInfo &L) {
> + macho::Segment64LoadCommand Cmd;
> + memcpy(&Cmd, L.Ptr, sizeof(macho::Segment64LoadCommand));
> + if (isSwappedEndian(O))
> + SwapStruct(Cmd);
> + return Cmd;
> +}
> +
> +static uint32_t
> +getSegmentLoadCommandNumSections(const MachOObjectFile *O,
> + const MachOObjectFile::LoadCommandInfo &L) {
> + if (O->is64Bit()) {
> + macho::Segment64LoadCommand S = getSegment64LoadCommand(O, L);
> + return S.NumSections;
> + }
> + macho::SegmentLoadCommand S = getSegmentLoadCommand(O, L);
> + return S.NumSections;
> }
>
> -bool MachOObjectFileBase::is64Bit() const {
> - return isa<MachOObjectFileLE64>(this) || isa<MachOObjectFileBE64>(this);
> +static const SectionBase *
> +getSectionBase(const MachOObjectFile *O, MachOObjectFile::LoadCommandInfo L,
> + unsigned Sec) {
> + uintptr_t CommandAddr = reinterpret_cast<uintptr_t>(L.Ptr);
> +
> + bool Is64 = O->is64Bit();
> + unsigned SegmentLoadSize = Is64 ? sizeof(macho::Segment64LoadCommand) :
> + sizeof(macho::SegmentLoadCommand);
> + unsigned SectionSize = Is64 ? sizeof(macho::Section64) :
> + sizeof(macho::Section);
> +
> + uintptr_t SectionAddr = CommandAddr + SegmentLoadSize + Sec * SectionSize;
> + return reinterpret_cast<const SectionBase*>(SectionAddr);
> }
>
> -void MachOObjectFileBase::ReadULEB128s(uint64_t Index,
> - SmallVectorImpl<uint64_t> &Out) const {
> - DataExtractor extractor(ObjectFile::getData(), true, 0);
> +static const char *getPtr(const MachOObjectFile *O, size_t Offset) {
> + return O->getData().substr(Offset, 1).data();
> +}
>
> - uint32_t offset = Index;
> - uint64_t data = 0;
> - while (uint64_t delta = extractor.getULEB128(&offset)) {
> - data += delta;
> - Out.push_back(data);
> - }
> +static const char *getSymbolTableEntryPtr(const MachOObjectFile *O,
> + DataRefImpl DRI) {
> + macho::SymtabLoadCommand S = O->getSymtabLoadCommand();
> +
> + unsigned Index = DRI.d.b;
> +
> + unsigned SymbolTableEntrySize = O->is64Bit() ?
> + sizeof(macho::Symbol64TableEntry) :
> + sizeof(macho::SymbolTableEntry);
> +
> + uint64_t Offset = S.SymbolTableOffset + Index * SymbolTableEntrySize;
> + return getPtr(O, Offset);
> }
>
> -unsigned MachOObjectFileBase::getHeaderSize() const {
> - return is64Bit() ? macho::Header64Size : macho::Header32Size;
> +static SymbolTableEntryBase
> +getSymbolTableEntryBase(const MachOObjectFile *O, DataRefImpl DRI) {
> + const char *P = getSymbolTableEntryPtr(O, DRI);
> + SymbolTableEntryBase Ret;
> + memcpy(&Ret, P, sizeof(SymbolTableEntryBase));
> + if (isSwappedEndian(O))
> + SwapStruct(Ret);
> +
> + return Ret;
> }
>
> -StringRef MachOObjectFileBase::getData(size_t Offset, size_t Size) const {
> - return ObjectFile::getData().substr(Offset, Size);
> +static StringRef parseSegmentOrSectionName(const char *P) {
> + if (P[15] == 0)
> + // Null terminated.
> + return P;
> + // Not null terminated, so this is a 16 char string.
> + return StringRef(P, 16);
> }
>
> -ObjectFile *ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer) {
> - StringRef Magic = Buffer->getBuffer().slice(0, 4);
> +// Helper to advance a section or symbol iterator multiple increments at a time.
> +template<class T>
> +static error_code advance(T &it, size_t Val) {
> error_code ec;
> - ObjectFile *Ret;
> - if (Magic == "\xFE\xED\xFA\xCE")
> - Ret = new MachOObjectFileBE32(Buffer, ec);
> - else if (Magic == "\xCE\xFA\xED\xFE")
> - Ret = new MachOObjectFileLE32(Buffer, ec);
> - else if (Magic == "\xFE\xED\xFA\xCF")
> - Ret = new MachOObjectFileBE64(Buffer, ec);
> - else if (Magic == "\xCF\xFA\xED\xFE")
> - Ret = new MachOObjectFileLE64(Buffer, ec);
> - else
> - return NULL;
> + while (Val--) {
> + it.increment(ec);
> + }
> + return ec;
> +}
>
> - if (ec)
> - return NULL;
> - return Ret;
> +template<class T>
> +static void advanceTo(T &it, size_t Val) {
> + if (error_code ec = advance(it, Val))
> + report_fatal_error(ec.message());
> +}
> +
> +static unsigned getCPUType(const MachOObjectFile *O) {
> + return O->getHeader().CPUType;
> +}
> +
> +static void printRelocationTargetName(const MachOObjectFile *O,
> + const macho::RelocationEntry &RE,
> + raw_string_ostream &fmt) {
> + bool IsScattered = O->isRelocationScattered(RE);
> +
> + // Target of a scattered relocation is an address. In the interest of
> + // generating pretty output, scan through the symbol table looking for a
> + // symbol that aligns with that address. If we find one, print it.
> + // Otherwise, we just print the hex address of the target.
> + if (IsScattered) {
> + uint32_t Val = O->getPlainRelocationSymbolNum(RE);
> +
> + error_code ec;
> + for (symbol_iterator SI = O->begin_symbols(), SE = O->end_symbols();
> + SI != SE; SI.increment(ec)) {
> + if (ec) report_fatal_error(ec.message());
> +
> + uint64_t Addr;
> + StringRef Name;
> +
> + if ((ec = SI->getAddress(Addr)))
> + report_fatal_error(ec.message());
> + if (Addr != Val) continue;
> + if ((ec = SI->getName(Name)))
> + report_fatal_error(ec.message());
> + fmt << Name;
> + return;
> + }
> +
> + // If we couldn't find a symbol that this relocation refers to, try
> + // to find a section beginning instead.
> + for (section_iterator SI = O->begin_sections(), SE = O->end_sections();
> + SI != SE; SI.increment(ec)) {
> + if (ec) report_fatal_error(ec.message());
> +
> + uint64_t Addr;
> + StringRef Name;
> +
> + if ((ec = SI->getAddress(Addr)))
> + report_fatal_error(ec.message());
> + if (Addr != Val) continue;
> + if ((ec = SI->getName(Name)))
> + report_fatal_error(ec.message());
> + fmt << Name;
> + return;
> + }
> +
> + fmt << format("0x%x", Val);
> + return;
> + }
> +
> + StringRef S;
> + bool isExtern = O->getPlainRelocationExternal(RE);
> + uint64_t Val = O->getAnyRelocationAddress(RE);
> +
> + if (isExtern) {
> + symbol_iterator SI = O->begin_symbols();
> + advanceTo(SI, Val);
> + SI->getName(S);
> + } else {
> + section_iterator SI = O->begin_sections();
> + advanceTo(SI, Val);
> + SI->getName(S);
> + }
> +
> + fmt << S;
> +}
> +
> +static uint32_t getPlainRelocationAddress(const macho::RelocationEntry &RE) {
> + return RE.Word0;
> +}
> +
> +static unsigned
> +getScatteredRelocationAddress(const macho::RelocationEntry &RE) {
> + return RE.Word0 & 0xffffff;
> +}
> +
> +static bool getPlainRelocationPCRel(const MachOObjectFile *O,
> + const macho::RelocationEntry &RE) {
> + if (O->isLittleEndian())
> + return (RE.Word1 >> 24) & 1;
> + return (RE.Word1 >> 7) & 1;
> +}
> +
> +static bool
> +getScatteredRelocationPCRel(const MachOObjectFile *O,
> + const macho::RelocationEntry &RE) {
> + return (RE.Word0 >> 30) & 1;
> +}
> +
> +static unsigned getPlainRelocationLength(const MachOObjectFile *O,
> + const macho::RelocationEntry &RE) {
> + if (O->isLittleEndian())
> + return (RE.Word1 >> 25) & 3;
> + return (RE.Word1 >> 5) & 3;
> +}
> +
> +static unsigned
> +getScatteredRelocationLength(const macho::RelocationEntry &RE) {
> + return (RE.Word0 >> 28) & 3;
> +}
> +
> +static unsigned getPlainRelocationType(const MachOObjectFile *O,
> + const macho::RelocationEntry &RE) {
> + if (O->isLittleEndian())
> + return RE.Word1 >> 28;
> + return RE.Word1 & 0xf;
> +}
> +
> +static unsigned getScatteredRelocationType(const macho::RelocationEntry &RE) {
> + return (RE.Word0 >> 24) & 0xf;
> +}
> +
> +static uint32_t getSectionFlags(const MachOObjectFile *O,
> + DataRefImpl Sec) {
> + if (O->is64Bit()) {
> + macho::Section64 Sect = O->getSection64(Sec);
> + return Sect.Flags;
> + }
> + macho::Section Sect = O->getSection(Sec);
> + return Sect.Flags;
> +}
> +
> +MachOObjectFile::MachOObjectFile(MemoryBuffer *Object,
> + bool IsLittleEndian, bool Is64bits,
> + error_code &ec)
> + : ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object),
> + SymtabLoadCmd(NULL) {
> + uint32_t LoadCommandCount = this->getHeader().NumLoadCommands;
> + macho::LoadCommandType SegmentLoadType = is64Bit() ?
> + macho::LCT_Segment64 : macho::LCT_Segment;
> +
> + MachOObjectFile::LoadCommandInfo Load = getFirstLoadCommandInfo();
> + for (unsigned I = 0; I < LoadCommandCount; ++I) {
> + if (Load.C.Type == macho::LCT_Symtab) {
> + assert(!SymtabLoadCmd && "Multiple symbol tables");
> + SymtabLoadCmd = Load.Ptr;
> + }
> +
> + 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));
> + }
> + }
> + Load = getNextLoadCommandInfo(Load);
> + }
> +}
> +
> +error_code MachOObjectFile::getSymbolNext(DataRefImpl Symb,
> + SymbolRef &Res) const {
> + Symb.d.b++;
> + Res = SymbolRef(Symb, this);
> + return object_error::success;
> +}
> +
> +error_code MachOObjectFile::getSymbolName(DataRefImpl Symb,
> + StringRef &Res) const {
> + macho::SymtabLoadCommand S = getSymtabLoadCommand();
> + const char *StringTable = getPtr(this, S.StringTableOffset);
> + SymbolTableEntryBase Entry = getSymbolTableEntryBase(this, Symb);
> + const char *Start = &StringTable[Entry.StringIndex];
> + Res = StringRef(Start);
> + return object_error::success;
> +}
> +
> +error_code MachOObjectFile::getSymbolAddress(DataRefImpl Symb,
> + uint64_t &Res) const {
> + if (is64Bit()) {
> + macho::Symbol64TableEntry Entry = getSymbol64TableEntry(Symb);
> + Res = Entry.Value;
> + } else {
> + macho::SymbolTableEntry Entry = getSymbolTableEntry(Symb);
> + Res = Entry.Value;
> + }
> + return object_error::success;
> +}
> +
> +error_code
> +MachOObjectFile::getSymbolFileOffset(DataRefImpl Symb,
> + uint64_t &Res) const {
> + SymbolTableEntryBase Entry = getSymbolTableEntryBase(this, Symb);
> + getSymbolAddress(Symb, Res);
> + if (Entry.SectionIndex) {
> + uint64_t Delta;
> + DataRefImpl SecRel;
> + SecRel.d.a = Entry.SectionIndex-1;
> + if (is64Bit()) {
> + macho::Section64 Sec = getSection64(SecRel);
> + Delta = Sec.Offset - Sec.Address;
> + } else {
> + macho::Section Sec = getSection(SecRel);
> + Delta = Sec.Offset - Sec.Address;
> + }
> +
> + Res += Delta;
> + }
> +
> + return object_error::success;
> }
>
> -/*===-- Symbols -----------------------------------------------------------===*/
> +error_code MachOObjectFile::getSymbolSize(DataRefImpl DRI,
> + uint64_t &Result) const {
> + uint64_t BeginOffset;
> + uint64_t EndOffset = 0;
> + uint8_t SectionIndex;
> +
> + SymbolTableEntryBase Entry = getSymbolTableEntryBase(this, DRI);
> + uint64_t Value;
> + getSymbolAddress(DRI, Value);
> +
> + BeginOffset = Value;
> +
> + SectionIndex = Entry.SectionIndex;
> + if (!SectionIndex) {
> + uint32_t flags = SymbolRef::SF_None;
> + this->getSymbolFlags(DRI, flags);
> + if (flags & SymbolRef::SF_Common)
> + Result = Value;
> + else
> + Result = UnknownAddressOrSize;
> + return object_error::success;
> + }
> + // Unfortunately symbols are unsorted so we need to touch all
> + // symbols from load command
> + macho::SymtabLoadCommand Symtab = getSymtabLoadCommand();
> + DRI.d.b = 0;
> + while (DRI.d.b <= Symtab.NumSymbolTableEntries) {
> + Entry = getSymbolTableEntryBase(this, DRI);
> + getSymbolAddress(DRI, Value);
> + if (Entry.SectionIndex == SectionIndex && Value > BeginOffset)
> + if (!EndOffset || Value < EndOffset)
> + EndOffset = Value;
> + DRI.d.b++;
> + }
> + if (!EndOffset) {
> + uint64_t Size;
> + DataRefImpl Sec;
> + Sec.d.a = SectionIndex-1;
> + getSectionSize(Sec, Size);
> + getSectionAddress(Sec, EndOffset);
> + EndOffset += Size;
> + }
> + Result = EndOffset - BeginOffset;
> + return object_error::success;
> +}
>
> -error_code MachOObjectFileBase::getSymbolValue(DataRefImpl Symb,
> +error_code MachOObjectFile::getSymbolType(DataRefImpl Symb,
> + SymbolRef::Type &Res) const {
> + SymbolTableEntryBase Entry = getSymbolTableEntryBase(this, Symb);
> + uint8_t n_type = Entry.Type;
> +
> + Res = SymbolRef::ST_Other;
> +
> + // If this is a STAB debugging symbol, we can do nothing more.
> + if (n_type & MachO::NlistMaskStab) {
> + Res = SymbolRef::ST_Debug;
> + return object_error::success;
> + }
> +
> + switch (n_type & MachO::NlistMaskType) {
> + case MachO::NListTypeUndefined :
> + Res = SymbolRef::ST_Unknown;
> + break;
> + case MachO::NListTypeSection :
> + Res = SymbolRef::ST_Function;
> + break;
> + }
> + return object_error::success;
> +}
> +
> +error_code MachOObjectFile::getSymbolNMTypeChar(DataRefImpl Symb,
> + char &Res) const {
> + SymbolTableEntryBase Entry = getSymbolTableEntryBase(this, Symb);
> + uint8_t Type = Entry.Type;
> + uint16_t Flags = Entry.Flags;
> +
> + char Char;
> + switch (Type & macho::STF_TypeMask) {
> + case macho::STT_Undefined:
> + Char = 'u';
> + break;
> + case macho::STT_Absolute:
> + case macho::STT_Section:
> + Char = 's';
> + break;
> + default:
> + Char = '?';
> + break;
> + }
> +
> + if (Flags & (macho::STF_External | macho::STF_PrivateExtern))
> + Char = toupper(static_cast<unsigned char>(Char));
> + Res = Char;
> + return object_error::success;
> +}
> +
> +error_code MachOObjectFile::getSymbolFlags(DataRefImpl DRI,
> + uint32_t &Result) const {
> + SymbolTableEntryBase Entry = getSymbolTableEntryBase(this, DRI);
> +
> + uint8_t MachOType = Entry.Type;
> + uint16_t MachOFlags = Entry.Flags;
> +
> + // TODO: Correctly set SF_ThreadLocal
> + Result = SymbolRef::SF_None;
> +
> + if ((MachOType & MachO::NlistMaskType) == MachO::NListTypeUndefined)
> + Result |= SymbolRef::SF_Undefined;
> +
> + if (MachOFlags & macho::STF_StabsEntryMask)
> + Result |= SymbolRef::SF_FormatSpecific;
> +
> + if (MachOType & MachO::NlistMaskExternal) {
> + Result |= SymbolRef::SF_Global;
> + if ((MachOType & MachO::NlistMaskType) == MachO::NListTypeUndefined)
> + Result |= SymbolRef::SF_Common;
> + }
> +
> + if (MachOFlags & (MachO::NListDescWeakRef | MachO::NListDescWeakDef))
> + Result |= SymbolRef::SF_Weak;
> +
> + if ((MachOType & MachO::NlistMaskType) == MachO::NListTypeAbsolute)
> + Result |= SymbolRef::SF_Absolute;
> +
> + return object_error::success;
> +}
> +
> +error_code
> +MachOObjectFile::getSymbolSection(DataRefImpl Symb,
> + section_iterator &Res) const {
> + SymbolTableEntryBase Entry = getSymbolTableEntryBase(this, Symb);
> + uint8_t index = Entry.SectionIndex;
> +
> + if (index == 0) {
> + Res = end_sections();
> + } else {
> + DataRefImpl DRI;
> + DRI.d.a = index - 1;
> + Res = section_iterator(SectionRef(DRI, this));
> + }
> +
> + return object_error::success;
> +}
> +
> +error_code MachOObjectFile::getSymbolValue(DataRefImpl Symb,
> uint64_t &Val) const {
> - report_fatal_error("getSymbolValue unimplemented in MachOObjectFileBase");
> + report_fatal_error("getSymbolValue unimplemented in MachOObjectFile");
> }
>
> -symbol_iterator MachOObjectFileBase::begin_dynamic_symbols() const {
> - // TODO: implement
> - report_fatal_error("Dynamic symbols unimplemented in MachOObjectFileBase");
> +error_code MachOObjectFile::getSectionNext(DataRefImpl Sec,
> + SectionRef &Res) const {
> + Sec.d.a++;
> + Res = SectionRef(Sec, this);
> + return object_error::success;
> }
>
> -symbol_iterator MachOObjectFileBase::end_dynamic_symbols() const {
> - // TODO: implement
> - report_fatal_error("Dynamic symbols unimplemented in MachOObjectFileBase");
> +error_code
> +MachOObjectFile::getSectionName(DataRefImpl Sec,
> + StringRef &Result) const {
> + ArrayRef<char> Raw = getSectionRawName(Sec);
> + Result = parseSegmentOrSectionName(Raw.data());
> + return object_error::success;
> }
>
> -library_iterator MachOObjectFileBase::begin_libraries_needed() const {
> - // TODO: implement
> - report_fatal_error("Needed libraries unimplemented in MachOObjectFileBase");
> +error_code
> +MachOObjectFile::getSectionAddress(DataRefImpl Sec,
> + uint64_t &Res) const {
> + if (is64Bit()) {
> + macho::Section64 Sect = getSection64(Sec);
> + Res = Sect.Address;
> + } else {
> + macho::Section Sect = getSection(Sec);
> + Res = Sect.Address;
> + }
> + return object_error::success;
> }
>
> -library_iterator MachOObjectFileBase::end_libraries_needed() const {
> - // TODO: implement
> - report_fatal_error("Needed libraries unimplemented in MachOObjectFileBase");
> +error_code
> +MachOObjectFile::getSectionSize(DataRefImpl Sec,
> + uint64_t &Res) const {
> + if (is64Bit()) {
> + macho::Section64 Sect = getSection64(Sec);
> + Res = Sect.Size;
> + } else {
> + macho::Section Sect = getSection(Sec);
> + Res = Sect.Size;
> + }
> +
> + return object_error::success;
> }
>
> -StringRef MachOObjectFileBase::getLoadName() const {
> - // TODO: Implement
> - report_fatal_error("get_load_name() unimplemented in MachOObjectFileBase");
> +error_code
> +MachOObjectFile::getSectionContents(DataRefImpl Sec,
> + StringRef &Res) const {
> + uint32_t Offset;
> + uint64_t Size;
> +
> + if (is64Bit()) {
> + macho::Section64 Sect = getSection64(Sec);
> + Offset = Sect.Offset;
> + Size = Sect.Size;
> + } else {
> + macho::Section Sect =getSection(Sec);
> + Offset = Sect.Offset;
> + Size = Sect.Size;
> + }
> +
> + Res = this->getData().substr(Offset, Size);
> + return object_error::success;
> }
>
> -/*===-- Sections ----------------------------------------------------------===*/
> +error_code
> +MachOObjectFile::getSectionAlignment(DataRefImpl Sec,
> + uint64_t &Res) const {
> + uint32_t Align;
> + if (is64Bit()) {
> + macho::Section64 Sect = getSection64(Sec);
> + Align = Sect.Align;
> + } else {
> + macho::Section Sect = getSection(Sec);
> + Align = Sect.Align;
> + }
>
> -std::size_t MachOObjectFileBase::getSectionIndex(DataRefImpl Sec) const {
> - SectionList::const_iterator loc =
> - std::find(Sections.begin(), Sections.end(), Sec);
> - assert(loc != Sections.end() && "Sec is not a valid section!");
> - return std::distance(Sections.begin(), loc);
> + Res = uint64_t(1) << Align;
> + return object_error::success;
> }
>
> -StringRef MachOObjectFileBase::parseSegmentOrSectionName(const char *P) const {
> - if (P[15] == 0)
> - // Null terminated.
> - return P;
> - // Not null terminated, so this is a 16 char string.
> - return StringRef(P, 16);
> +error_code
> +MachOObjectFile::isSectionText(DataRefImpl Sec, bool &Res) const {
> + uint32_t Flags = getSectionFlags(this, Sec);
> + Res = Flags & macho::SF_PureInstructions;
> + return object_error::success;
> }
>
> -error_code MachOObjectFileBase::isSectionData(DataRefImpl DRI,
> +error_code MachOObjectFile::isSectionData(DataRefImpl DRI,
> bool &Result) const {
> // FIXME: Unimplemented.
> Result = false;
> return object_error::success;
> }
>
> -error_code MachOObjectFileBase::isSectionBSS(DataRefImpl DRI,
> +error_code MachOObjectFile::isSectionBSS(DataRefImpl DRI,
> bool &Result) const {
> // FIXME: Unimplemented.
> Result = false;
> @@ -143,21 +723,30 @@ error_code MachOObjectFileBase::isSectio
> }
>
> error_code
> -MachOObjectFileBase::isSectionRequiredForExecution(DataRefImpl Sec,
> +MachOObjectFile::isSectionRequiredForExecution(DataRefImpl Sec,
> bool &Result) const {
> // FIXME: Unimplemented.
> Result = true;
> return object_error::success;
> }
>
> -error_code MachOObjectFileBase::isSectionVirtual(DataRefImpl Sec,
> +error_code MachOObjectFile::isSectionVirtual(DataRefImpl Sec,
> bool &Result) const {
> // FIXME: Unimplemented.
> Result = false;
> return object_error::success;
> }
>
> -error_code MachOObjectFileBase::isSectionReadOnlyData(DataRefImpl Sec,
> +error_code
> +MachOObjectFile::isSectionZeroInit(DataRefImpl Sec, bool &Res) const {
> + uint32_t Flags = getSectionFlags(this, Sec);
> + unsigned SectionType = Flags & MachO::SectionFlagMaskSectionType;
> + Res = SectionType == MachO::SectionTypeZeroFill ||
> + SectionType == MachO::SectionTypeZeroFillLarge;
> + return object_error::success;
> +}
> +
> +error_code MachOObjectFile::isSectionReadOnlyData(DataRefImpl Sec,
> bool &Result) const {
> // Consider using the code from isSectionText to look for __const sections.
> // Alternately, emit S_ATTR_PURE_INSTRUCTIONS and/or S_ATTR_SOME_INSTRUCTIONS
> @@ -168,44 +757,752 @@ error_code MachOObjectFileBase::isSectio
> return object_error::success;
> }
>
> -relocation_iterator MachOObjectFileBase::getSectionRelBegin(DataRefImpl Sec) const {
> +error_code
> +MachOObjectFile::sectionContainsSymbol(DataRefImpl Sec,
> + DataRefImpl Symb,
> + bool &Result) const {
> + SymbolRef::Type ST;
> + this->getSymbolType(Symb, ST);
> + if (ST == SymbolRef::ST_Unknown) {
> + Result = false;
> + return object_error::success;
> + }
> +
> + uint64_t SectBegin, SectEnd;
> + getSectionAddress(Sec, SectBegin);
> + getSectionSize(Sec, SectEnd);
> + SectEnd += SectBegin;
> +
> + uint64_t SymAddr;
> + getSymbolAddress(Symb, SymAddr);
> + Result = (SymAddr >= SectBegin) && (SymAddr < SectEnd);
> +
> + return object_error::success;
> +}
> +
> +relocation_iterator MachOObjectFile::getSectionRelBegin(DataRefImpl Sec) const {
> DataRefImpl ret;
> - ret.d.b = getSectionIndex(Sec);
> + ret.d.b = Sec.d.a;
> return relocation_iterator(RelocationRef(ret, this));
> }
>
> +relocation_iterator
> +MachOObjectFile::getSectionRelEnd(DataRefImpl Sec) const {
> + uint32_t LastReloc;
> + if (is64Bit()) {
> + macho::Section64 Sect = getSection64(Sec);
> + LastReloc = Sect.NumRelocationTableEntries;
> + } else {
> + macho::Section Sect = getSection(Sec);
> + LastReloc = Sect.NumRelocationTableEntries;
> + }
>
> -/*===-- Relocations -------------------------------------------------------===*/
> + DataRefImpl Ret;
> + Ret.d.a = LastReloc;
> + Ret.d.b = Sec.d.a;
> + return relocation_iterator(RelocationRef(Ret, this));
> +}
>
> -error_code MachOObjectFileBase::getRelocationNext(DataRefImpl Rel,
> +error_code MachOObjectFile::getRelocationNext(DataRefImpl Rel,
> RelocationRef &Res) const {
> ++Rel.d.a;
> Res = RelocationRef(Rel, this);
> return object_error::success;
> }
>
> -error_code MachOObjectFileBase::getLibraryNext(DataRefImpl LibData,
> - LibraryRef &Res) const {
> - report_fatal_error("Needed libraries unimplemented in MachOObjectFileBase");
> +error_code
> +MachOObjectFile::getRelocationAddress(DataRefImpl Rel,
> + uint64_t &Res) const {
> + uint64_t SectAddress;
> + DataRefImpl Sec;
> + Sec.d.a = Rel.d.b;
> + if (is64Bit()) {
> + macho::Section64 Sect = getSection64(Sec);
> + SectAddress = Sect.Address;
> + } else {
> + macho::Section Sect = getSection(Sec);
> + SectAddress = Sect.Address;
> + }
> +
> + macho::RelocationEntry RE = getRelocation(Rel);
> + uint64_t RelAddr = getAnyRelocationAddress(RE);
> + Res = SectAddress + RelAddr;
> + return object_error::success;
> }
>
> -error_code MachOObjectFileBase::getLibraryPath(DataRefImpl LibData,
> - StringRef &Res) const {
> - report_fatal_error("Needed libraries unimplemented in MachOObjectFileBase");
> +error_code MachOObjectFile::getRelocationOffset(DataRefImpl Rel,
> + uint64_t &Res) const {
> + macho::RelocationEntry RE = getRelocation(Rel);
> + Res = getAnyRelocationAddress(RE);
> + return object_error::success;
> }
>
> -error_code MachOObjectFileBase::getRelocationAdditionalInfo(DataRefImpl Rel,
> - int64_t &Res) const {
> +error_code
> +MachOObjectFile::getRelocationSymbol(DataRefImpl Rel,
> + SymbolRef &Res) const {
> + macho::RelocationEntry RE = getRelocation(Rel);
> + uint32_t SymbolIdx = getPlainRelocationSymbolNum(RE);
> + bool isExtern = getPlainRelocationExternal(RE);
> +
> + DataRefImpl Sym;
> + if (isExtern) {
> + Sym.d.b = SymbolIdx;
> + }
> + Res = SymbolRef(Sym, this);
> + return object_error::success;
> +}
> +
> +error_code MachOObjectFile::getRelocationType(DataRefImpl Rel,
> + uint64_t &Res) const {
> + macho::RelocationEntry RE = getRelocation(Rel);
> + Res = getAnyRelocationType(RE);
> + return object_error::success;
> +}
> +
> +error_code
> +MachOObjectFile::getRelocationTypeName(DataRefImpl Rel,
> + SmallVectorImpl<char> &Result) const {
> + StringRef res;
> + uint64_t RType;
> + getRelocationType(Rel, RType);
> +
> + unsigned Arch = this->getArch();
> +
> + switch (Arch) {
> + case Triple::x86: {
> + static const char *const Table[] = {
> + "GENERIC_RELOC_VANILLA",
> + "GENERIC_RELOC_PAIR",
> + "GENERIC_RELOC_SECTDIFF",
> + "GENERIC_RELOC_PB_LA_PTR",
> + "GENERIC_RELOC_LOCAL_SECTDIFF",
> + "GENERIC_RELOC_TLV" };
> +
> + if (RType > 6)
> + res = "Unknown";
> + else
> + res = Table[RType];
> + break;
> + }
> + case Triple::x86_64: {
> + static const char *const Table[] = {
> + "X86_64_RELOC_UNSIGNED",
> + "X86_64_RELOC_SIGNED",
> + "X86_64_RELOC_BRANCH",
> + "X86_64_RELOC_GOT_LOAD",
> + "X86_64_RELOC_GOT",
> + "X86_64_RELOC_SUBTRACTOR",
> + "X86_64_RELOC_SIGNED_1",
> + "X86_64_RELOC_SIGNED_2",
> + "X86_64_RELOC_SIGNED_4",
> + "X86_64_RELOC_TLV" };
> +
> + if (RType > 9)
> + res = "Unknown";
> + else
> + res = Table[RType];
> + break;
> + }
> + case Triple::arm: {
> + static const char *const Table[] = {
> + "ARM_RELOC_VANILLA",
> + "ARM_RELOC_PAIR",
> + "ARM_RELOC_SECTDIFF",
> + "ARM_RELOC_LOCAL_SECTDIFF",
> + "ARM_RELOC_PB_LA_PTR",
> + "ARM_RELOC_BR24",
> + "ARM_THUMB_RELOC_BR22",
> + "ARM_THUMB_32BIT_BRANCH",
> + "ARM_RELOC_HALF",
> + "ARM_RELOC_HALF_SECTDIFF" };
> +
> + if (RType > 9)
> + res = "Unknown";
> + else
> + res = Table[RType];
> + break;
> + }
> + case Triple::ppc: {
> + static const char *const Table[] = {
> + "PPC_RELOC_VANILLA",
> + "PPC_RELOC_PAIR",
> + "PPC_RELOC_BR14",
> + "PPC_RELOC_BR24",
> + "PPC_RELOC_HI16",
> + "PPC_RELOC_LO16",
> + "PPC_RELOC_HA16",
> + "PPC_RELOC_LO14",
> + "PPC_RELOC_SECTDIFF",
> + "PPC_RELOC_PB_LA_PTR",
> + "PPC_RELOC_HI16_SECTDIFF",
> + "PPC_RELOC_LO16_SECTDIFF",
> + "PPC_RELOC_HA16_SECTDIFF",
> + "PPC_RELOC_JBSR",
> + "PPC_RELOC_LO14_SECTDIFF",
> + "PPC_RELOC_LOCAL_SECTDIFF" };
> +
> + res = Table[RType];
> + break;
> + }
> + case Triple::UnknownArch:
> + res = "Unknown";
> + break;
> + }
> + Result.append(res.begin(), res.end());
> + return object_error::success;
> +}
> +
> +error_code MachOObjectFile::getRelocationAdditionalInfo(DataRefImpl Rel,
> + int64_t &Res) const {
> Res = 0;
> return object_error::success;
> }
>
> +error_code
> +MachOObjectFile::getRelocationValueString(DataRefImpl Rel,
> + SmallVectorImpl<char> &Result) const {
> + macho::RelocationEntry RE = getRelocation(Rel);
> +
> + unsigned Arch = this->getArch();
> +
> + std::string fmtbuf;
> + raw_string_ostream fmt(fmtbuf);
> + unsigned Type = this->getAnyRelocationType(RE);
> + bool IsPCRel = this->getAnyRelocationPCRel(RE);
> +
> + // Determine any addends that should be displayed with the relocation.
> + // These require decoding the relocation type, which is triple-specific.
> +
> + // X86_64 has entirely custom relocation types.
> + if (Arch == Triple::x86_64) {
> + bool isPCRel = getAnyRelocationPCRel(RE);
> +
> + switch (Type) {
> + case macho::RIT_X86_64_GOTLoad: // X86_64_RELOC_GOT_LOAD
> + case macho::RIT_X86_64_GOT: { // X86_64_RELOC_GOT
> + printRelocationTargetName(this, RE, fmt);
> + fmt << "@GOT";
> + if (isPCRel) fmt << "PCREL";
> + break;
> + }
> + case macho::RIT_X86_64_Subtractor: { // X86_64_RELOC_SUBTRACTOR
> + DataRefImpl RelNext = Rel;
> + RelNext.d.a++;
> + macho::RelocationEntry RENext = getRelocation(RelNext);
> +
> + // X86_64_SUBTRACTOR must be followed by a relocation of type
> + // X86_64_RELOC_UNSIGNED.
> + // NOTE: Scattered relocations don't exist on x86_64.
> + unsigned RType = getAnyRelocationType(RENext);
> + if (RType != 0)
> + report_fatal_error("Expected X86_64_RELOC_UNSIGNED after "
> + "X86_64_RELOC_SUBTRACTOR.");
> +
> + // The X86_64_RELOC_UNSIGNED contains the minuend symbol,
> + // X86_64_SUBTRACTOR contains to the subtrahend.
> + printRelocationTargetName(this, RENext, fmt);
> + fmt << "-";
> + printRelocationTargetName(this, RE, fmt);
> + break;
> + }
> + case macho::RIT_X86_64_TLV:
> + printRelocationTargetName(this, RE, fmt);
> + fmt << "@TLV";
> + if (isPCRel) fmt << "P";
> + break;
> + case macho::RIT_X86_64_Signed1: // X86_64_RELOC_SIGNED1
> + printRelocationTargetName(this, RE, fmt);
> + fmt << "-1";
> + break;
> + case macho::RIT_X86_64_Signed2: // X86_64_RELOC_SIGNED2
> + printRelocationTargetName(this, RE, fmt);
> + fmt << "-2";
> + break;
> + case macho::RIT_X86_64_Signed4: // X86_64_RELOC_SIGNED4
> + printRelocationTargetName(this, RE, fmt);
> + fmt << "-4";
> + break;
> + default:
> + printRelocationTargetName(this, RE, fmt);
> + break;
> + }
> + // X86 and ARM share some relocation types in common.
> + } else if (Arch == Triple::x86 || Arch == Triple::arm) {
> + // Generic relocation types...
> + switch (Type) {
> + case macho::RIT_Pair: // GENERIC_RELOC_PAIR - prints no info
> + return object_error::success;
> + case macho::RIT_Difference: { // GENERIC_RELOC_SECTDIFF
> + DataRefImpl RelNext = Rel;
> + RelNext.d.a++;
> + macho::RelocationEntry RENext = getRelocation(RelNext);
> +
> + // X86 sect diff's must be followed by a relocation of type
> + // GENERIC_RELOC_PAIR.
> + unsigned RType = getAnyRelocationType(RENext);
> +
> + if (RType != 1)
> + report_fatal_error("Expected GENERIC_RELOC_PAIR after "
> + "GENERIC_RELOC_SECTDIFF.");
> +
> + printRelocationTargetName(this, RE, fmt);
> + fmt << "-";
> + printRelocationTargetName(this, RENext, fmt);
> + break;
> + }
> + }
> +
> + if (Arch == Triple::x86) {
> + // All X86 relocations that need special printing were already
> + // handled in the generic code.
> + switch (Type) {
> + case macho::RIT_Generic_LocalDifference:{// GENERIC_RELOC_LOCAL_SECTDIFF
> + DataRefImpl RelNext = Rel;
> + RelNext.d.a++;
> + macho::RelocationEntry RENext = getRelocation(RelNext);
> +
> + // X86 sect diff's must be followed by a relocation of type
> + // GENERIC_RELOC_PAIR.
> + unsigned RType = getAnyRelocationType(RENext);
> + if (RType != 1)
> + report_fatal_error("Expected GENERIC_RELOC_PAIR after "
> + "GENERIC_RELOC_LOCAL_SECTDIFF.");
> +
> + printRelocationTargetName(this, RE, fmt);
> + fmt << "-";
> + printRelocationTargetName(this, RENext, fmt);
> + break;
> + }
> + case macho::RIT_Generic_TLV: {
> + printRelocationTargetName(this, RE, fmt);
> + fmt << "@TLV";
> + if (IsPCRel) fmt << "P";
> + break;
> + }
> + default:
> + printRelocationTargetName(this, RE, fmt);
> + }
> + } else { // ARM-specific relocations
> + switch (Type) {
> + case macho::RIT_ARM_Half: // ARM_RELOC_HALF
> + case macho::RIT_ARM_HalfDifference: { // ARM_RELOC_HALF_SECTDIFF
> + // Half relocations steal a bit from the length field to encode
> + // whether this is an upper16 or a lower16 relocation.
> + bool isUpper = getAnyRelocationLength(RE) >> 1;
> +
> + if (isUpper)
> + fmt << ":upper16:(";
> + else
> + fmt << ":lower16:(";
> + printRelocationTargetName(this, RE, fmt);
> +
> + DataRefImpl RelNext = Rel;
> + RelNext.d.a++;
> + macho::RelocationEntry RENext = getRelocation(RelNext);
> +
> + // ARM half relocs must be followed by a relocation of type
> + // ARM_RELOC_PAIR.
> + unsigned RType = getAnyRelocationType(RENext);
> + if (RType != 1)
> + report_fatal_error("Expected ARM_RELOC_PAIR after "
> + "GENERIC_RELOC_HALF");
> +
> + // NOTE: The half of the target virtual address is stashed in the
> + // address field of the secondary relocation, but we can't reverse
> + // engineer the constant offset from it without decoding the movw/movt
> + // instruction to find the other half in its immediate field.
> +
> + // ARM_RELOC_HALF_SECTDIFF encodes the second section in the
> + // symbol/section pointer of the follow-on relocation.
> + if (Type == macho::RIT_ARM_HalfDifference) {
> + fmt << "-";
> + printRelocationTargetName(this, RENext, fmt);
> + }
> +
> + fmt << ")";
> + break;
> + }
> + default: {
> + printRelocationTargetName(this, RE, fmt);
> + }
> + }
> + }
> + } else
> + printRelocationTargetName(this, RE, fmt);
> +
> + fmt.flush();
> + Result.append(fmtbuf.begin(), fmtbuf.end());
> + return object_error::success;
> +}
> +
> +error_code
> +MachOObjectFile::getRelocationHidden(DataRefImpl Rel,
> + bool &Result) const {
> + unsigned Arch = getArch();
> + uint64_t Type;
> + getRelocationType(Rel, Type);
> +
> + Result = false;
> +
> + // On arches that use the generic relocations, GENERIC_RELOC_PAIR
> + // is always hidden.
> + if (Arch == Triple::x86 || Arch == Triple::arm) {
> + if (Type == macho::RIT_Pair) Result = true;
> + } else if (Arch == Triple::x86_64) {
> + // On x86_64, X86_64_RELOC_UNSIGNED is hidden only when it follows
> + // an X864_64_RELOC_SUBTRACTOR.
> + if (Type == macho::RIT_X86_64_Unsigned && Rel.d.a > 0) {
> + DataRefImpl RelPrev = Rel;
> + RelPrev.d.a--;
> + uint64_t PrevType;
> + getRelocationType(RelPrev, PrevType);
> + if (PrevType == macho::RIT_X86_64_Subtractor)
> + Result = true;
> + }
> + }
> +
> + return object_error::success;
> +}
> +
> +error_code MachOObjectFile::getLibraryNext(DataRefImpl LibData,
> + LibraryRef &Res) const {
> + report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
> +}
> +
> +error_code MachOObjectFile::getLibraryPath(DataRefImpl LibData,
> + StringRef &Res) const {
> + report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
> +}
> +
> +symbol_iterator MachOObjectFile::begin_symbols() const {
> + // DRI.d.a = segment number; DRI.d.b = symbol index.
> + DataRefImpl DRI;
> + return symbol_iterator(SymbolRef(DRI, this));
> +}
>
> -/*===-- Miscellaneous -----------------------------------------------------===*/
> +symbol_iterator MachOObjectFile::end_symbols() const {
> + DataRefImpl DRI;
> + if (SymtabLoadCmd) {
> + macho::SymtabLoadCommand Symtab = getSymtabLoadCommand();
> + DRI.d.b = Symtab.NumSymbolTableEntries;
> + }
> + return symbol_iterator(SymbolRef(DRI, this));
> +}
>
> -uint8_t MachOObjectFileBase::getBytesInAddress() const {
> +symbol_iterator MachOObjectFile::begin_dynamic_symbols() const {
> + // TODO: implement
> + report_fatal_error("Dynamic symbols unimplemented in MachOObjectFile");
> +}
> +
> +symbol_iterator MachOObjectFile::end_dynamic_symbols() const {
> + // TODO: implement
> + report_fatal_error("Dynamic symbols unimplemented in MachOObjectFile");
> +}
> +
> +section_iterator MachOObjectFile::begin_sections() const {
> + DataRefImpl DRI;
> + return section_iterator(SectionRef(DRI, this));
> +}
> +
> +section_iterator MachOObjectFile::end_sections() const {
> + DataRefImpl DRI;
> + DRI.d.a = Sections.size();
> + return section_iterator(SectionRef(DRI, this));
> +}
> +
> +library_iterator MachOObjectFile::begin_libraries_needed() const {
> + // TODO: implement
> + report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
> +}
> +
> +library_iterator MachOObjectFile::end_libraries_needed() const {
> + // TODO: implement
> + report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
> +}
> +
> +uint8_t MachOObjectFile::getBytesInAddress() const {
> return is64Bit() ? 8 : 4;
> }
>
> +StringRef MachOObjectFile::getFileFormatName() const {
> + unsigned CPUType = getCPUType(this);
> + if (!is64Bit()) {
> + switch (CPUType) {
> + case llvm::MachO::CPUTypeI386:
> + return "Mach-O 32-bit i386";
> + case llvm::MachO::CPUTypeARM:
> + return "Mach-O arm";
> + case llvm::MachO::CPUTypePowerPC:
> + return "Mach-O 32-bit ppc";
> + default:
> + assert((CPUType & llvm::MachO::CPUArchABI64) == 0 &&
> + "64-bit object file when we're not 64-bit?");
> + return "Mach-O 32-bit unknown";
> + }
> + }
> +
> + // Make sure the cpu type has the correct mask.
> + assert((CPUType & llvm::MachO::CPUArchABI64)
> + == llvm::MachO::CPUArchABI64 &&
> + "32-bit object file when we're 64-bit?");
> +
> + switch (CPUType) {
> + case llvm::MachO::CPUTypeX86_64:
> + return "Mach-O 64-bit x86-64";
> + case llvm::MachO::CPUTypePowerPC64:
> + return "Mach-O 64-bit ppc64";
> + default:
> + return "Mach-O 64-bit unknown";
> + }
> +}
> +
> +unsigned MachOObjectFile::getArch() const {
> + switch (getCPUType(this)) {
> + case llvm::MachO::CPUTypeI386:
> + return Triple::x86;
> + case llvm::MachO::CPUTypeX86_64:
> + return Triple::x86_64;
> + case llvm::MachO::CPUTypeARM:
> + return Triple::arm;
> + case llvm::MachO::CPUTypePowerPC:
> + return Triple::ppc;
> + case llvm::MachO::CPUTypePowerPC64:
> + return Triple::ppc64;
> + default:
> + return Triple::UnknownArch;
> + }
> +}
> +
> +StringRef MachOObjectFile::getLoadName() const {
> + // TODO: Implement
> + report_fatal_error("get_load_name() unimplemented in MachOObjectFile");
> +}
> +
> +StringRef
> +MachOObjectFile::getSectionFinalSegmentName(DataRefImpl Sec) const {
> + ArrayRef<char> Raw = getSectionRawFinalSegmentName(Sec);
> + return parseSegmentOrSectionName(Raw.data());
> +}
> +
> +ArrayRef<char>
> +MachOObjectFile::getSectionRawName(DataRefImpl Sec) const {
> + const SectionBase *Base =
> + reinterpret_cast<const SectionBase*>(Sections[Sec.d.a]);
> + return ArrayRef<char>(Base->Name);
> +}
> +
> +ArrayRef<char>
> +MachOObjectFile::getSectionRawFinalSegmentName(DataRefImpl Sec) const {
> + const SectionBase *Base =
> + reinterpret_cast<const SectionBase*>(Sections[Sec.d.a]);
> + return ArrayRef<char>(Base->SegmentName);
> +}
> +
> +bool
> +MachOObjectFile::isRelocationScattered(const macho::RelocationEntry &RE)
> + const {
> + if (getCPUType(this) == llvm::MachO::CPUTypeX86_64)
> + return false;
> + return getPlainRelocationAddress(RE) & macho::RF_Scattered;
> +}
> +
> +unsigned MachOObjectFile::getPlainRelocationSymbolNum(const macho::RelocationEntry &RE) const {
> + if (isLittleEndian())
> + return RE.Word1 & 0xffffff;
> + return RE.Word1 >> 8;
> +}
> +
> +bool MachOObjectFile::getPlainRelocationExternal(const macho::RelocationEntry &RE) const {
> + if (isLittleEndian())
> + return (RE.Word1 >> 27) & 1;
> + return (RE.Word1 >> 4) & 1;
> +}
> +
> +bool
> +MachOObjectFile::getScatteredRelocationScattered(const macho::RelocationEntry &RE) const {
> + return RE.Word0 >> 31;
> +}
> +
> +uint32_t
> +MachOObjectFile::getScatteredRelocationValue(const macho::RelocationEntry &RE) const {
> + return RE.Word1;
> +}
> +
> +unsigned
> +MachOObjectFile::getAnyRelocationAddress(const macho::RelocationEntry &RE) const {
> + if (isRelocationScattered(RE))
> + return getScatteredRelocationAddress(RE);
> + return getPlainRelocationAddress(RE);
> +}
> +
> +unsigned
> +MachOObjectFile::getAnyRelocationPCRel(const macho::RelocationEntry &RE) const {
> + if (isRelocationScattered(RE))
> + return getScatteredRelocationPCRel(this, RE);
> + return getPlainRelocationPCRel(this, RE);
> +}
> +
> +unsigned
> +MachOObjectFile::getAnyRelocationLength(const macho::RelocationEntry &RE) const {
> + if (isRelocationScattered(RE))
> + return getScatteredRelocationLength(RE);
> + return getPlainRelocationLength(this, RE);
> +}
> +
> +unsigned
> +MachOObjectFile::getAnyRelocationType(const macho::RelocationEntry &RE) const {
> + if (isRelocationScattered(RE))
> + return getScatteredRelocationType(RE);
> + return getPlainRelocationType(this, RE);
> +}
> +
> +MachOObjectFile::LoadCommandInfo
> +MachOObjectFile::getFirstLoadCommandInfo() const {
> + MachOObjectFile::LoadCommandInfo Load;
> +
> + unsigned HeaderSize = is64Bit() ? macho::Header64Size : macho::Header32Size;
> + Load.Ptr = getPtr(this, HeaderSize);
> + memcpy(&Load.C, Load.Ptr, sizeof(macho::LoadCommand));
> + if (isSwappedEndian(this))
> + SwapStruct(Load.C);
> + return Load;
> +}
> +
> +MachOObjectFile::LoadCommandInfo
> +MachOObjectFile::getNextLoadCommandInfo(const LoadCommandInfo &L) const {
> + MachOObjectFile::LoadCommandInfo Next;
> + Next.Ptr = L.Ptr + L.C.Size;
> + memcpy(&Next.C, Next.Ptr, sizeof(macho::LoadCommand));
> + if (isSwappedEndian(this))
> + SwapStruct(Next.C);
> + return Next;
> +}
> +
> +macho::Section MachOObjectFile::getSection(DataRefImpl DRI) const {
> + const SectionBase *Addr =
> + reinterpret_cast<const SectionBase*>(Sections[DRI.d.a]);
> + macho::Section Ret;
> + memcpy(&Ret, Addr, sizeof(macho::Section));
> + if (isSwappedEndian(this))
> + SwapStruct(Ret);
> + return Ret;
> +}
> +
> +macho::Section64 MachOObjectFile::getSection64(DataRefImpl DRI) const {
> + const SectionBase *Addr =
> + reinterpret_cast<const SectionBase*>(Sections[DRI.d.a]);
> + macho::Section64 Ret;
> + memcpy(&Ret, Addr, sizeof(macho::Section64));
> + if (isSwappedEndian(this))
> + SwapStruct(Ret);
> + return Ret;
> +}
> +
> +macho::SymbolTableEntry
> +MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI) const {
> + const char *P = getSymbolTableEntryPtr(this, DRI);
> + macho::SymbolTableEntry Ret;
> + memcpy(&Ret, P, sizeof(macho::SymbolTableEntry));
> + if (isSwappedEndian(this))
> + SwapStruct(Ret);
> + return Ret;
> +}
> +
> +macho::Symbol64TableEntry
> +MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI) const {
> + const char *P = getSymbolTableEntryPtr(this, DRI);
> + macho::Symbol64TableEntry Ret;
> + memcpy(&Ret, P, sizeof(macho::Symbol64TableEntry));
> + if (isSwappedEndian(this))
> + SwapStruct(Ret);
> + return Ret;
> +}
> +
> +macho::LinkeditDataLoadCommand
> +MachOObjectFile::getLinkeditDataLoadCommand(const MachOObjectFile::LoadCommandInfo &L) const {
> + macho::LinkeditDataLoadCommand Cmd;
> + memcpy(&Cmd, L.Ptr, sizeof(macho::LinkeditDataLoadCommand));
> + if (isSwappedEndian(this))
> + SwapStruct(Cmd);
> + return Cmd;
> +}
> +
> +macho::RelocationEntry
> +MachOObjectFile::getRelocation(DataRefImpl Rel) const {
> + uint32_t RelOffset;
> + DataRefImpl Sec;
> + Sec.d.a = Rel.d.b;
> + if (is64Bit()) {
> + macho::Section64 Sect = getSection64(Sec);
> + RelOffset = Sect.RelocationTableOffset;
> + } else {
> + macho::Section Sect = getSection(Sec);
> + RelOffset = Sect.RelocationTableOffset;
> + }
> +
> + uint64_t Offset = RelOffset + Rel.d.a * sizeof(macho::RelocationEntry);
> +
> + macho::RelocationEntry Ret;
> + memcpy(&Ret, getPtr(this, Offset), sizeof(macho::RelocationEntry));
> + if (isSwappedEndian(this))
> + SwapStruct(Ret);
> +
> + return Ret;
> +}
> +
> +macho::Header MachOObjectFile::getHeader() const {
> + macho::Header H;
> + memcpy(&H, getPtr(this, 0), sizeof(macho::Header));
> + if (isSwappedEndian(this))
> + SwapStruct(H);
> + return H;
> +}
> +
> +macho::SymtabLoadCommand
> +MachOObjectFile::getSymtabLoadCommand() const {
> + macho::SymtabLoadCommand Cmd;
> + memcpy(&Cmd, SymtabLoadCmd, sizeof(macho::SymtabLoadCommand));
> + if (isSwappedEndian(this))
> + SwapStruct(Cmd);
> + return Cmd;
> +}
> +
> +bool MachOObjectFile::is64Bit() const {
> + return getType() == getMachOType(false, true) ||
> + getType() == getMachOType(true, true);
> +}
> +
> +void MachOObjectFile::ReadULEB128s(uint64_t Index,
> + SmallVectorImpl<uint64_t> &Out) const {
> + DataExtractor extractor(ObjectFile::getData(), true, 0);
> +
> + uint32_t offset = Index;
> + uint64_t data = 0;
> + while (uint64_t delta = extractor.getULEB128(&offset)) {
> + data += delta;
> + Out.push_back(data);
> + }
> +}
> +
> +ObjectFile *ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer) {
> + StringRef Magic = Buffer->getBuffer().slice(0, 4);
> + error_code ec;
> + ObjectFile *Ret;
> + if (Magic == "\xFE\xED\xFA\xCE")
> + Ret = new MachOObjectFile(Buffer, false, false, ec);
> + else if (Magic == "\xCE\xFA\xED\xFE")
> + Ret = new MachOObjectFile(Buffer, true, false, ec);
> + else if (Magic == "\xFE\xED\xFA\xCF")
> + Ret = new MachOObjectFile(Buffer, false, true, ec);
> + else if (Magic == "\xCF\xFA\xED\xFE")
> + Ret = new MachOObjectFile(Buffer, true, true, ec);
> + else
> + return NULL;
> +
> + if (ec)
> + return NULL;
> + return Ret;
> +}
> +
> } // end namespace object
> } // end namespace llvm
>
> Added: llvm/trunk/test/tools/llvm-readobj/Inputs/trivial.obj.macho-arm
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/Inputs/trivial.obj.macho-arm?rev=179778&view=auto
> ==============================================================================
> Binary files llvm/trunk/test/tools/llvm-readobj/Inputs/trivial.obj.macho-arm (added) and llvm/trunk/test/tools/llvm-readobj/Inputs/trivial.obj.macho-arm Thu Apr 18 13:08:55 2013 differ
>
> Modified: llvm/trunk/test/tools/llvm-readobj/relocations.test
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/relocations.test?rev=179778&r1=179777&r2=179778&view=diff
> ==============================================================================
> --- llvm/trunk/test/tools/llvm-readobj/relocations.test (original)
> +++ llvm/trunk/test/tools/llvm-readobj/relocations.test Thu Apr 18 13:08:55 2013
> @@ -10,6 +10,8 @@ RUN: llvm-readobj -r %p/Inputs/trivial.o
> RUN: | FileCheck %s -check-prefix MACHO-PPC
> RUN: llvm-readobj -r %p/Inputs/trivial.obj.macho-ppc64 \
> RUN: | FileCheck %s -check-prefix MACHO-PPC64
> +RUN: llvm-readobj -r -expand-relocs %p/Inputs/trivial.obj.macho-arm \
> +RUN: | FileCheck %s -check-prefix MACHO-ARM
>
> COFF: Relocations [
> COFF-NEXT: Section (1) .text {
> @@ -82,3 +84,90 @@ MACHO-PPC64-NEXT: Section __la_symbol_
> MACHO-PPC64-NEXT: 0x0 0 3 1 0 dyld_stub_binding_helper
> MACHO-PPC64-NEXT: }
> MACHO-PPC64-NEXT: ]
> +
> +
> +MACHO-ARM: Relocations [
> +MACHO-ARM-NEXT: Section __text {
> +MACHO-ARM-NEXT: Relocation {
> +MACHO-ARM-NEXT: Offset: 0x38
> +MACHO-ARM-NEXT: PCRel: 0
> +MACHO-ARM-NEXT: Length: 2
> +MACHO-ARM-NEXT: Extern: N/A
> +MACHO-ARM-NEXT: Type: ARM_RELOC_SECTDIFF (2)
> +MACHO-ARM-NEXT: Symbol: _b
> +MACHO-ARM-NEXT: Scattered: 1
> +MACHO-ARM-NEXT: }
> +MACHO-ARM-NEXT: Relocation {
> +MACHO-ARM-NEXT: Offset: 0x0
> +MACHO-ARM-NEXT: PCRel: 0
> +MACHO-ARM-NEXT: Length: 2
> +MACHO-ARM-NEXT: Extern: N/A
> +MACHO-ARM-NEXT: Type: ARM_RELOC_PAIR (1)
> +MACHO-ARM-NEXT: Symbol: _b
> +MACHO-ARM-NEXT: Scattered: 1
> +MACHO-ARM-NEXT: }
> +MACHO-ARM-NEXT: Relocation {
> +MACHO-ARM-NEXT: Offset: 0x20
> +MACHO-ARM-NEXT: PCRel: 1
> +MACHO-ARM-NEXT: Length: 2
> +MACHO-ARM-NEXT: Extern: 1
> +MACHO-ARM-NEXT: Type: ARM_RELOC_BR24 (5)
> +MACHO-ARM-NEXT: Symbol: _g
> +MACHO-ARM-NEXT: Scattered: 0
> +MACHO-ARM-NEXT: }
> +MACHO-ARM-NEXT: Relocation {
> +MACHO-ARM-NEXT: Offset: 0x1C
> +MACHO-ARM-NEXT: PCRel: 0
> +MACHO-ARM-NEXT: Length: 1
> +MACHO-ARM-NEXT: Extern: 1
> +MACHO-ARM-NEXT: Type: ARM_RELOC_HALF (8)
> +MACHO-ARM-NEXT: Symbol: _g
> +MACHO-ARM-NEXT: Scattered: 0
> +MACHO-ARM-NEXT: }
> +MACHO-ARM-NEXT: Relocation {
> +MACHO-ARM-NEXT: Offset: 0x0
> +MACHO-ARM-NEXT: PCRel: 0
> +MACHO-ARM-NEXT: Length: 1
> +MACHO-ARM-NEXT: Extern: 0
> +MACHO-ARM-NEXT: Type: ARM_RELOC_PAIR (1)
> +MACHO-ARM-NEXT: Symbol: _b
> +MACHO-ARM-NEXT: Scattered: 0
> +MACHO-ARM-NEXT: }
> +MACHO-ARM-NEXT: Relocation {
> +MACHO-ARM-NEXT: Offset: 0x18
> +MACHO-ARM-NEXT: PCRel: 0
> +MACHO-ARM-NEXT: Length: 0
> +MACHO-ARM-NEXT: Extern: 1
> +MACHO-ARM-NEXT: Type: ARM_RELOC_HALF (8)
> +MACHO-ARM-NEXT: Symbol: _g
> +MACHO-ARM-NEXT: Scattered: 0
> +MACHO-ARM-NEXT: }
> +MACHO-ARM-NEXT: Relocation {
> +MACHO-ARM-NEXT: Offset: 0x0
> +MACHO-ARM-NEXT: PCRel: 0
> +MACHO-ARM-NEXT: Length: 0
> +MACHO-ARM-NEXT: Extern: 0
> +MACHO-ARM-NEXT: Type: ARM_RELOC_PAIR (1)
> +MACHO-ARM-NEXT: Symbol: _b
> +MACHO-ARM-NEXT: Scattered: 0
> +MACHO-ARM-NEXT: }
> +MACHO-ARM-NEXT: Relocation {
> +MACHO-ARM-NEXT: Offset: 0xC
> +MACHO-ARM-NEXT: PCRel: 0
> +MACHO-ARM-NEXT: Length: 2
> +MACHO-ARM-NEXT: Extern: N/A
> +MACHO-ARM-NEXT: Type: ARM_RELOC_SECTDIFF (2)
> +MACHO-ARM-NEXT: Symbol: _b
> +MACHO-ARM-NEXT: Scattered: 1
> +MACHO-ARM-NEXT: }
> +MACHO-ARM-NEXT: Relocation {
> +MACHO-ARM-NEXT: Offset: 0x0
> +MACHO-ARM-NEXT: PCRel: 0
> +MACHO-ARM-NEXT: Length: 2
> +MACHO-ARM-NEXT: Extern: N/A
> +MACHO-ARM-NEXT: Type: ARM_RELOC_PAIR (1)
> +MACHO-ARM-NEXT: Symbol: _b
> +MACHO-ARM-NEXT: Scattered: 1
> +MACHO-ARM-NEXT: }
> +MACHO-ARM-NEXT: }
> +MACHO-ARM-NEXT: ]
>
> Modified: llvm/trunk/test/tools/llvm-readobj/sections-ext.test
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/sections-ext.test?rev=179778&r1=179777&r2=179778&view=diff
> ==============================================================================
> --- llvm/trunk/test/tools/llvm-readobj/sections-ext.test (original)
> +++ llvm/trunk/test/tools/llvm-readobj/sections-ext.test Thu Apr 18 13:08:55 2013
> @@ -10,6 +10,8 @@ RUN: llvm-readobj -s -st -sr -sd %p/Inpu
> RUN: | FileCheck %s -check-prefix MACHO-PPC
> RUN: llvm-readobj -s -st -sr -sd %p/Inputs/trivial.obj.macho-ppc64 \
> RUN: | FileCheck %s -check-prefix MACHO-PPC64
> +RUN: llvm-readobj -expand-relocs -s -st -sr -sd %p/Inputs/trivial.obj.macho-arm \
> +RUN: | FileCheck %s -check-prefix MACHO-ARM
>
> COFF: Sections [
> COFF-NEXT: Section {
> @@ -562,3 +564,278 @@ MACHO-PPC64-NEXT: 0000: 00000000 0
> MACHO-PPC64-NEXT: )
> MACHO-PPC64-NEXT: }
> MACHO-PPC64-NEXT: ]
> +
> +MACHO-ARM: Sections [
> +MACHO-ARM-NEXT: Section {
> +MACHO-ARM-NEXT: Index: 0
> +MACHO-ARM-NEXT: Name: __text (5F 5F 74 65 78 74 00 00 00 00 00 00 00 00 00 00)
> +MACHO-ARM-NEXT: Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00)
> +MACHO-ARM-NEXT: Address: 0x0
> +MACHO-ARM-NEXT: Size: 0x3C
> +MACHO-ARM-NEXT: Offset: 664
> +MACHO-ARM-NEXT: Alignment: 2
> +MACHO-ARM-NEXT: RelocationOffset: 0x2E0
> +MACHO-ARM-NEXT: RelocationCount: 9
> +MACHO-ARM-NEXT: Type: 0x0
> +MACHO-ARM-NEXT: Attributes [ (0x800004)
> +MACHO-ARM-NEXT: PureInstructions (0x800000)
> +MACHO-ARM-NEXT: SomeInstructions (0x4)
> +MACHO-ARM-NEXT: ]
> +MACHO-ARM-NEXT: Reserved1: 0x0
> +MACHO-ARM-NEXT: Reserved2: 0x0
> +MACHO-ARM-NEXT: Relocations [
> +MACHO-ARM-NEXT: Relocation {
> +MACHO-ARM-NEXT: Offset: 0x38
> +MACHO-ARM-NEXT: PCRel: 0
> +MACHO-ARM-NEXT: Length: 2
> +MACHO-ARM-NEXT: Extern: N/A
> +MACHO-ARM-NEXT: Type: ARM_RELOC_SECTDIFF (2)
> +MACHO-ARM-NEXT: Symbol: _b
> +MACHO-ARM-NEXT: Scattered: 1
> +MACHO-ARM-NEXT: }
> +MACHO-ARM-NEXT: Relocation {
> +MACHO-ARM-NEXT: Offset: 0x0
> +MACHO-ARM-NEXT: PCRel: 0
> +MACHO-ARM-NEXT: Length: 2
> +MACHO-ARM-NEXT: Extern: N/A
> +MACHO-ARM-NEXT: Type: ARM_RELOC_PAIR (1)
> +MACHO-ARM-NEXT: Symbol: _b
> +MACHO-ARM-NEXT: Scattered: 1
> +MACHO-ARM-NEXT: }
> +MACHO-ARM-NEXT: Relocation {
> +MACHO-ARM-NEXT: Offset: 0x20
> +MACHO-ARM-NEXT: PCRel: 1
> +MACHO-ARM-NEXT: Length: 2
> +MACHO-ARM-NEXT: Extern: 1
> +MACHO-ARM-NEXT: Type: ARM_RELOC_BR24 (5)
> +MACHO-ARM-NEXT: Symbol: _g
> +MACHO-ARM-NEXT: Scattered: 0
> +MACHO-ARM-NEXT: }
> +MACHO-ARM-NEXT: Relocation {
> +MACHO-ARM-NEXT: Offset: 0x1C
> +MACHO-ARM-NEXT: PCRel: 0
> +MACHO-ARM-NEXT: Length: 1
> +MACHO-ARM-NEXT: Extern: 1
> +MACHO-ARM-NEXT: Type: ARM_RELOC_HALF (8)
> +MACHO-ARM-NEXT: Symbol: _g
> +MACHO-ARM-NEXT: Scattered: 0
> +MACHO-ARM-NEXT: }
> +MACHO-ARM-NEXT: Relocation {
> +MACHO-ARM-NEXT: Offset: 0x0
> +MACHO-ARM-NEXT: PCRel: 0
> +MACHO-ARM-NEXT: Length: 1
> +MACHO-ARM-NEXT: Extern: 0
> +MACHO-ARM-NEXT: Type: ARM_RELOC_PAIR (1)
> +MACHO-ARM-NEXT: Symbol: _b
> +MACHO-ARM-NEXT: Scattered: 0
> +MACHO-ARM-NEXT: }
> +MACHO-ARM-NEXT: Relocation {
> +MACHO-ARM-NEXT: Offset: 0x18
> +MACHO-ARM-NEXT: PCRel: 0
> +MACHO-ARM-NEXT: Length: 0
> +MACHO-ARM-NEXT: Extern: 1
> +MACHO-ARM-NEXT: Type: ARM_RELOC_HALF (8)
> +MACHO-ARM-NEXT: Symbol: _g
> +MACHO-ARM-NEXT: Scattered: 0
> +MACHO-ARM-NEXT: }
> +MACHO-ARM-NEXT: Relocation {
> +MACHO-ARM-NEXT: Offset: 0x0
> +MACHO-ARM-NEXT: PCRel: 0
> +MACHO-ARM-NEXT: Length: 0
> +MACHO-ARM-NEXT: Extern: 0
> +MACHO-ARM-NEXT: Type: ARM_RELOC_PAIR (1)
> +MACHO-ARM-NEXT: Symbol: _b
> +MACHO-ARM-NEXT: Scattered: 0
> +MACHO-ARM-NEXT: }
> +MACHO-ARM-NEXT: Relocation {
> +MACHO-ARM-NEXT: Offset: 0xC
> +MACHO-ARM-NEXT: PCRel: 0
> +MACHO-ARM-NEXT: Length: 2
> +MACHO-ARM-NEXT: Extern: N/A
> +MACHO-ARM-NEXT: Type: ARM_RELOC_SECTDIFF (2)
> +MACHO-ARM-NEXT: Symbol: _b
> +MACHO-ARM-NEXT: Scattered: 1
> +MACHO-ARM-NEXT: }
> +MACHO-ARM-NEXT: Relocation {
> +MACHO-ARM-NEXT: Offset: 0x0
> +MACHO-ARM-NEXT: PCRel: 0
> +MACHO-ARM-NEXT: Length: 2
> +MACHO-ARM-NEXT: Extern: N/A
> +MACHO-ARM-NEXT: Type: ARM_RELOC_PAIR (1)
> +MACHO-ARM-NEXT: Symbol: _b
> +MACHO-ARM-NEXT: Scattered: 1
> +MACHO-ARM-NEXT: }
> +MACHO-ARM-NEXT: ]
> +MACHO-ARM-NEXT: Symbols [
> +MACHO-ARM-NEXT: Symbol {
> +MACHO-ARM-NEXT: Name: _f (4)
> +MACHO-ARM-NEXT: Type: 0xF
> +MACHO-ARM-NEXT: Section: __text (0x1)
> +MACHO-ARM-NEXT: RefType: UndefinedNonLazy (0x0)
> +MACHO-ARM-NEXT: Flags [ (0x0)
> +MACHO-ARM-NEXT: ]
> +MACHO-ARM-NEXT: Value: 0x10
> +MACHO-ARM-NEXT: }
> +MACHO-ARM-NEXT: Symbol {
> +MACHO-ARM-NEXT: Name: _h (1)
> +MACHO-ARM-NEXT: Type: 0xF
> +MACHO-ARM-NEXT: Section: __text (0x1)
> +MACHO-ARM-NEXT: RefType: UndefinedNonLazy (0x0)
> +MACHO-ARM-NEXT: Flags [ (0x0)
> +MACHO-ARM-NEXT: ]
> +MACHO-ARM-NEXT: Value: 0x0
> +MACHO-ARM-NEXT: }
> +MACHO-ARM-NEXT: ]
> +MACHO-ARM-NEXT: SectionData (
> +MACHO-ARM-NEXT: 0000: 04009FE5 00009FE7 1EFF2FE1 38000000 |........../.8...|
> +MACHO-ARM-NEXT: 0010: 80402DE9 0D70A0E1 000000E3 000040E3 |. at -..p........@.|
> +MACHO-ARM-NEXT: 0020: F6FFFFEB 0C009FE5 00009FE7 000090E5 |................|
> +MACHO-ARM-NEXT: 0030: 8040BDE8 1EFF2FE1 10000000 |. at ..../.....|
> +MACHO-ARM-NEXT: )
> +MACHO-ARM-NEXT: }
> +MACHO-ARM-NEXT: Section {
> +MACHO-ARM-NEXT: Index: 1
> +MACHO-ARM-NEXT: Name: __textcoal_nt (5F 5F 74 65 78 74 63 6F 61 6C 5F 6E 74 00 00 00)
> +MACHO-ARM-NEXT: Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00)
> +MACHO-ARM-NEXT: Address: 0x3C
> +MACHO-ARM-NEXT: Size: 0x0
> +MACHO-ARM-NEXT: Offset: 724
> +MACHO-ARM-NEXT: Alignment: 0
> +MACHO-ARM-NEXT: RelocationOffset: 0x0
> +MACHO-ARM-NEXT: RelocationCount: 0
> +MACHO-ARM-NEXT: Type: 0xB
> +MACHO-ARM-NEXT: Attributes [ (0x800000)
> +MACHO-ARM-NEXT: PureInstructions (0x800000)
> +MACHO-ARM-NEXT: ]
> +MACHO-ARM-NEXT: Reserved1: 0x0
> +MACHO-ARM-NEXT: Reserved2: 0x0
> +MACHO-ARM-NEXT: Relocations [
> +MACHO-ARM-NEXT: ]
> +MACHO-ARM-NEXT: Symbols [
> +MACHO-ARM-NEXT: ]
> +MACHO-ARM-NEXT: SectionData (
> +MACHO-ARM-NEXT: )
> +MACHO-ARM-NEXT: }
> +MACHO-ARM-NEXT: Section {
> +MACHO-ARM-NEXT: Index: 2
> +MACHO-ARM-NEXT: Name: __const_coal (5F 5F 63 6F 6E 73 74 5F 63 6F 61 6C 00 00 00 00)
> +MACHO-ARM-NEXT: Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00)
> +MACHO-ARM-NEXT: Address: 0x3C
> +MACHO-ARM-NEXT: Size: 0x0
> +MACHO-ARM-NEXT: Offset: 724
> +MACHO-ARM-NEXT: Alignment: 0
> +MACHO-ARM-NEXT: RelocationOffset: 0x0
> +MACHO-ARM-NEXT: RelocationCount: 0
> +MACHO-ARM-NEXT: Type: 0xB
> +MACHO-ARM-NEXT: Attributes [ (0x0)
> +MACHO-ARM-NEXT: ]
> +MACHO-ARM-NEXT: Reserved1: 0x0
> +MACHO-ARM-NEXT: Reserved2: 0x0
> +MACHO-ARM-NEXT: Relocations [
> +MACHO-ARM-NEXT: ]
> +MACHO-ARM-NEXT: Symbols [
> +MACHO-ARM-NEXT: ]
> +MACHO-ARM-NEXT: SectionData (
> +MACHO-ARM-NEXT: )
> +MACHO-ARM-NEXT: }
> +MACHO-ARM-NEXT: Section {
> +MACHO-ARM-NEXT: Index: 3
> +MACHO-ARM-NEXT: Name: __picsymbolstub4 (5F 5F 70 69 63 73 79 6D 62 6F 6C 73 74 75 62 34)
> +MACHO-ARM-NEXT: Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00)
> +MACHO-ARM-NEXT: Address: 0x3C
> +MACHO-ARM-NEXT: Size: 0x0
> +MACHO-ARM-NEXT: Offset: 724
> +MACHO-ARM-NEXT: Alignment: 0
> +MACHO-ARM-NEXT: RelocationOffset: 0x0
> +MACHO-ARM-NEXT: RelocationCount: 0
> +MACHO-ARM-NEXT: Type: 0x8
> +MACHO-ARM-NEXT: Attributes [ (0x0)
> +MACHO-ARM-NEXT: ]
> +MACHO-ARM-NEXT: Reserved1: 0x0
> +MACHO-ARM-NEXT: Reserved2: 0x10
> +MACHO-ARM-NEXT: Relocations [
> +MACHO-ARM-NEXT: ]
> +MACHO-ARM-NEXT: Symbols [
> +MACHO-ARM-NEXT: ]
> +MACHO-ARM-NEXT: SectionData (
> +MACHO-ARM-NEXT: )
> +MACHO-ARM-NEXT: }
> +MACHO-ARM-NEXT: Section {
> +MACHO-ARM-NEXT: Index: 4
> +MACHO-ARM-NEXT: Name: __StaticInit (5F 5F 53 74 61 74 69 63 49 6E 69 74 00 00 00 00)
> +MACHO-ARM-NEXT: Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00)
> +MACHO-ARM-NEXT: Address: 0x3C
> +MACHO-ARM-NEXT: Size: 0x0
> +MACHO-ARM-NEXT: Offset: 724
> +MACHO-ARM-NEXT: Alignment: 0
> +MACHO-ARM-NEXT: RelocationOffset: 0x0
> +MACHO-ARM-NEXT: RelocationCount: 0
> +MACHO-ARM-NEXT: Type: 0x0
> +MACHO-ARM-NEXT: Attributes [ (0x800000)
> +MACHO-ARM-NEXT: PureInstructions (0x800000)
> +MACHO-ARM-NEXT: ]
> +MACHO-ARM-NEXT: Reserved1: 0x0
> +MACHO-ARM-NEXT: Reserved2: 0x0
> +MACHO-ARM-NEXT: Relocations [
> +MACHO-ARM-NEXT: ]
> +MACHO-ARM-NEXT: Symbols [
> +MACHO-ARM-NEXT: ]
> +MACHO-ARM-NEXT: SectionData (
> +MACHO-ARM-NEXT: )
> +MACHO-ARM-NEXT: }
> +MACHO-ARM-NEXT: Section {
> +MACHO-ARM-NEXT: Index: 5
> +MACHO-ARM-NEXT: Name: __data (5F 5F 64 61 74 61 00 00 00 00 00 00 00 00 00 00)
> +MACHO-ARM-NEXT: Segment: __DATA (5F 5F 44 41 54 41 00 00 00 00 00 00 00 00 00 00)
> +MACHO-ARM-NEXT: Address: 0x3C
> +MACHO-ARM-NEXT: Size: 0x4
> +MACHO-ARM-NEXT: Offset: 724
> +MACHO-ARM-NEXT: Alignment: 2
> +MACHO-ARM-NEXT: RelocationOffset: 0x0
> +MACHO-ARM-NEXT: RelocationCount: 0
> +MACHO-ARM-NEXT: Type: 0x0
> +MACHO-ARM-NEXT: Attributes [ (0x0)
> +MACHO-ARM-NEXT: ]
> +MACHO-ARM-NEXT: Reserved1: 0x0
> +MACHO-ARM-NEXT: Reserved2: 0x0
> +MACHO-ARM-NEXT: Relocations [
> +MACHO-ARM-NEXT: ]
> +MACHO-ARM-NEXT: Symbols [
> +MACHO-ARM-NEXT: Symbol {
> +MACHO-ARM-NEXT: Name: _b (10)
> +MACHO-ARM-NEXT: Type: 0xF
> +MACHO-ARM-NEXT: Section: __data (0x6)
> +MACHO-ARM-NEXT: RefType: UndefinedNonLazy (0x0)
> +MACHO-ARM-NEXT: Flags [ (0x0)
> +MACHO-ARM-NEXT: ]
> +MACHO-ARM-NEXT: Value: 0x3C
> +MACHO-ARM-NEXT: }
> +MACHO-ARM-NEXT: ]
> +MACHO-ARM-NEXT: SectionData (
> +MACHO-ARM-NEXT: 0000: 2A000000 |*...|
> +MACHO-ARM-NEXT: )
> +MACHO-ARM-NEXT: }
> +MACHO-ARM-NEXT: Section {
> +MACHO-ARM-NEXT: Index: 6
> +MACHO-ARM-NEXT: Name: __nl_symbol_ptr (5F 5F 6E 6C 5F 73 79 6D 62 6F 6C 5F 70 74 72 00)
> +MACHO-ARM-NEXT: Segment: __DATA (5F 5F 44 41 54 41 00 00 00 00 00 00 00 00 00 00)
> +MACHO-ARM-NEXT: Address: 0x40
> +MACHO-ARM-NEXT: Size: 0x8
> +MACHO-ARM-NEXT: Offset: 728
> +MACHO-ARM-NEXT: Alignment: 2
> +MACHO-ARM-NEXT: RelocationOffset: 0x0
> +MACHO-ARM-NEXT: RelocationCount: 0
> +MACHO-ARM-NEXT: Type: 0x6
> +MACHO-ARM-NEXT: Attributes [ (0x0)
> +MACHO-ARM-NEXT: ]
> +MACHO-ARM-NEXT: Reserved1: 0x0
> +MACHO-ARM-NEXT: Reserved2: 0x0
> +MACHO-ARM-NEXT: Relocations [
> +MACHO-ARM-NEXT: ]
> +MACHO-ARM-NEXT: Symbols [
> +MACHO-ARM-NEXT: ]
> +MACHO-ARM-NEXT: SectionData (
> +MACHO-ARM-NEXT: 0000: 00000000 00000000 |........|
> +MACHO-ARM-NEXT: )
> +MACHO-ARM-NEXT: }
> +MACHO-ARM-NEXT: ]
>
> Modified: llvm/trunk/test/tools/llvm-readobj/sections.test
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/sections.test?rev=179778&r1=179777&r2=179778&view=diff
> ==============================================================================
> --- llvm/trunk/test/tools/llvm-readobj/sections.test (original)
> +++ llvm/trunk/test/tools/llvm-readobj/sections.test Thu Apr 18 13:08:55 2013
> @@ -10,6 +10,8 @@ RUN: llvm-readobj -s %p/Inputs/trivial.o
> RUN: | FileCheck %s -check-prefix MACHO-PPC
> RUN: llvm-readobj -s %p/Inputs/trivial.obj.macho-ppc64 \
> RUN: | FileCheck %s -check-prefix MACHO-PPC64
> +RUN: llvm-readobj -s %p/Inputs/trivial.obj.macho-arm \
> +RUN: | FileCheck %s -check-prefix MACHO-ARM
>
> COFF: Sections [
> COFF-NEXT: Section {
> @@ -329,3 +331,122 @@ MACHO-PPC64-NEXT: Reserved1: 0x2
> MACHO-PPC64-NEXT: Reserved2: 0x0
> MACHO-PPC64-NEXT: }
> MACHO-PPC64-NEXT: ]
> +
> +MACHO-ARM: Sections [
> +MACHO-ARM-NEXT: Section {
> +MACHO-ARM-NEXT: Index: 0
> +MACHO-ARM-NEXT: Name: __text (5F 5F 74 65 78 74 00 00 00 00 00 00 00 00 00 00)
> +MACHO-ARM-NEXT: Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00)
> +MACHO-ARM-NEXT: Address: 0x0
> +MACHO-ARM-NEXT: Size: 0x3C
> +MACHO-ARM-NEXT: Offset: 664
> +MACHO-ARM-NEXT: Alignment: 2
> +MACHO-ARM-NEXT: RelocationOffset: 0x2E0
> +MACHO-ARM-NEXT: RelocationCount: 9
> +MACHO-ARM-NEXT: Type: 0x0
> +MACHO-ARM-NEXT: Attributes [ (0x800004)
> +MACHO-ARM-NEXT: PureInstructions (0x800000)
> +MACHO-ARM-NEXT: SomeInstructions (0x4)
> +MACHO-ARM-NEXT: ]
> +MACHO-ARM-NEXT: Reserved1: 0x0
> +MACHO-ARM-NEXT: Reserved2: 0x0
> +MACHO-ARM-NEXT: }
> +MACHO-ARM-NEXT: Section {
> +MACHO-ARM-NEXT: Index: 1
> +MACHO-ARM-NEXT: Name: __textcoal_nt (5F 5F 74 65 78 74 63 6F 61 6C 5F 6E 74 00 00 00)
> +MACHO-ARM-NEXT: Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00)
> +MACHO-ARM-NEXT: Address: 0x3C
> +MACHO-ARM-NEXT: Size: 0x0
> +MACHO-ARM-NEXT: Offset: 724
> +MACHO-ARM-NEXT: Alignment: 0
> +MACHO-ARM-NEXT: RelocationOffset: 0x0
> +MACHO-ARM-NEXT: RelocationCount: 0
> +MACHO-ARM-NEXT: Type: 0xB
> +MACHO-ARM-NEXT: Attributes [ (0x800000)
> +MACHO-ARM-NEXT: PureInstructions (0x800000)
> +MACHO-ARM-NEXT: ]
> +MACHO-ARM-NEXT: Reserved1: 0x0
> +MACHO-ARM-NEXT: Reserved2: 0x0
> +MACHO-ARM-NEXT: }
> +MACHO-ARM-NEXT: Section {
> +MACHO-ARM-NEXT: Index: 2
> +MACHO-ARM-NEXT: Name: __const_coal (5F 5F 63 6F 6E 73 74 5F 63 6F 61 6C 00 00 00 00)
> +MACHO-ARM-NEXT: Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00)
> +MACHO-ARM-NEXT: Address: 0x3C
> +MACHO-ARM-NEXT: Size: 0x0
> +MACHO-ARM-NEXT: Offset: 724
> +MACHO-ARM-NEXT: Alignment: 0
> +MACHO-ARM-NEXT: RelocationOffset: 0x0
> +MACHO-ARM-NEXT: RelocationCount: 0
> +MACHO-ARM-NEXT: Type: 0xB
> +MACHO-ARM-NEXT: Attributes [ (0x0)
> +MACHO-ARM-NEXT: ]
> +MACHO-ARM-NEXT: Reserved1: 0x0
> +MACHO-ARM-NEXT: Reserved2: 0x0
> +MACHO-ARM-NEXT: }
> +MACHO-ARM-NEXT: Section {
> +MACHO-ARM-NEXT: Index: 3
> +MACHO-ARM-NEXT: Name: __picsymbolstub4 (5F 5F 70 69 63 73 79 6D 62 6F 6C 73 74 75 62 34)
> +MACHO-ARM-NEXT: Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00)
> +MACHO-ARM-NEXT: Address: 0x3C
> +MACHO-ARM-NEXT: Size: 0x0
> +MACHO-ARM-NEXT: Offset: 724
> +MACHO-ARM-NEXT: Alignment: 0
> +MACHO-ARM-NEXT: RelocationOffset: 0x0
> +MACHO-ARM-NEXT: RelocationCount: 0
> +MACHO-ARM-NEXT: Type: 0x8
> +MACHO-ARM-NEXT: Attributes [ (0x0)
> +MACHO-ARM-NEXT: ]
> +MACHO-ARM-NEXT: Reserved1: 0x0
> +MACHO-ARM-NEXT: Reserved2: 0x10
> +MACHO-ARM-NEXT: }
> +MACHO-ARM-NEXT: Section {
> +MACHO-ARM-NEXT: Index: 4
> +MACHO-ARM-NEXT: Name: __StaticInit (5F 5F 53 74 61 74 69 63 49 6E 69 74 00 00 00 00)
> +MACHO-ARM-NEXT: Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00)
> +MACHO-ARM-NEXT: Address: 0x3C
> +MACHO-ARM-NEXT: Size: 0x0
> +MACHO-ARM-NEXT: Offset: 724
> +MACHO-ARM-NEXT: Alignment: 0
> +MACHO-ARM-NEXT: RelocationOffset: 0x0
> +MACHO-ARM-NEXT: RelocationCount: 0
> +MACHO-ARM-NEXT: Type: 0x0
> +MACHO-ARM-NEXT: Attributes [ (0x800000)
> +MACHO-ARM-NEXT: PureInstructions (0x800000)
> +MACHO-ARM-NEXT: ]
> +MACHO-ARM-NEXT: Reserved1: 0x0
> +MACHO-ARM-NEXT: Reserved2: 0x0
> +MACHO-ARM-NEXT: }
> +MACHO-ARM-NEXT: Section {
> +MACHO-ARM-NEXT: Index: 5
> +MACHO-ARM-NEXT: Name: __data (5F 5F 64 61 74 61 00 00 00 00 00 00 00 00 00 00)
> +MACHO-ARM-NEXT: Segment: __DATA (5F 5F 44 41 54 41 00 00 00 00 00 00 00 00 00 00)
> +MACHO-ARM-NEXT: Address: 0x3C
> +MACHO-ARM-NEXT: Size: 0x4
> +MACHO-ARM-NEXT: Offset: 724
> +MACHO-ARM-NEXT: Alignment: 2
> +MACHO-ARM-NEXT: RelocationOffset: 0x0
> +MACHO-ARM-NEXT: RelocationCount: 0
> +MACHO-ARM-NEXT: Type: 0x0
> +MACHO-ARM-NEXT: Attributes [ (0x0)
> +MACHO-ARM-NEXT: ]
> +MACHO-ARM-NEXT: Reserved1: 0x0
> +MACHO-ARM-NEXT: Reserved2: 0x0
> +MACHO-ARM-NEXT: }
> +MACHO-ARM-NEXT: Section {
> +MACHO-ARM-NEXT: Index: 6
> +MACHO-ARM-NEXT: Name: __nl_symbol_ptr (5F 5F 6E 6C 5F 73 79 6D 62 6F 6C 5F 70 74 72 00)
> +MACHO-ARM-NEXT: Segment: __DATA (5F 5F 44 41 54 41 00 00 00 00 00 00 00 00 00 00)
> +MACHO-ARM-NEXT: Address: 0x40
> +MACHO-ARM-NEXT: Size: 0x8
> +MACHO-ARM-NEXT: Offset: 728
> +MACHO-ARM-NEXT: Alignment: 2
> +MACHO-ARM-NEXT: RelocationOffset: 0x0
> +MACHO-ARM-NEXT: RelocationCount: 0
> +MACHO-ARM-NEXT: Type: 0x6
> +MACHO-ARM-NEXT: Attributes [ (0x0)
> +MACHO-ARM-NEXT: ]
> +MACHO-ARM-NEXT: Reserved1: 0x0
> +MACHO-ARM-NEXT: Reserved2: 0x0
> +MACHO-ARM-NEXT: }
> +MACHO-ARM-NEXT:]
>
> Modified: llvm/trunk/tools/llvm-objdump/MachODump.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objdump/MachODump.cpp?rev=179778&r1=179777&r2=179778&view=diff
> ==============================================================================
> --- llvm/trunk/tools/llvm-objdump/MachODump.cpp (original)
> +++ llvm/trunk/tools/llvm-objdump/MachODump.cpp Thu Apr 18 13:08:55 2013
> @@ -53,7 +53,7 @@ static cl::opt<bool>
> static cl::opt<std::string>
> DSYMFile("dsym", cl::desc("Use .dSYM file for debug info"));
>
> -static const Target *GetTarget(const MachOObjectFileBase *MachOObj) {
> +static const Target *GetTarget(const MachOObjectFile *MachOObj) {
> // Figure out the target triple.
> if (TripleName.empty()) {
> llvm::Triple TT("unknown-unknown-unknown");
> @@ -93,7 +93,7 @@ struct SymbolSorter {
>
> // Print additional information about an address, if available.
> static void DumpAddress(uint64_t Address, ArrayRef<SectionRef> Sections,
> - const MachOObjectFileBase *MachOObj, raw_ostream &OS) {
> + const MachOObjectFile *MachOObj, raw_ostream &OS) {
> for (unsigned i = 0; i != Sections.size(); ++i) {
> uint64_t SectAddr = 0, SectSize = 0;
> Sections[i].getAddress(SectAddr);
> @@ -184,14 +184,12 @@ static void emitDOTFile(const char *File
> Out << "}\n";
> }
>
> -template<endianness E>
> static void
> -getSectionsAndSymbols(const typename MachOObjectFileMiddle<E>::Header *Header,
> - const MachOObjectFileMiddle<E> *MachOObj,
> +getSectionsAndSymbols(const macho::Header Header,
> + MachOObjectFile *MachOObj,
> std::vector<SectionRef> &Sections,
> std::vector<SymbolRef> &Symbols,
> SmallVectorImpl<uint64_t> &FoundFns) {
> - typedef MachOObjectFileMiddle<E> ObjType;
> error_code ec;
> for (symbol_iterator SI = MachOObj->begin_symbols(),
> SE = MachOObj->end_symbols(); SI != SE; SI.increment(ec))
> @@ -205,23 +203,23 @@ getSectionsAndSymbols(const typename Mac
> Sections.push_back(*SI);
> }
>
> - for (unsigned i = 0; i != Header->NumLoadCommands; ++i) {
> - const typename ObjType::LoadCommand *Command =
> - MachOObj->getLoadCommandInfo(i);
> - if (Command->Type == macho::LCT_FunctionStarts) {
> + MachOObjectFile::LoadCommandInfo Command =
> + MachOObj->getFirstLoadCommandInfo();
> + for (unsigned i = 0; i != Header.NumLoadCommands; ++i) {
> + if (Command.C.Type == macho::LCT_FunctionStarts) {
> // We found a function starts segment, parse the addresses for later
> // consumption.
> - const typename ObjType::LinkeditDataLoadCommand *LLC =
> - reinterpret_cast<const typename ObjType::LinkeditDataLoadCommand*>(Command);
> + macho::LinkeditDataLoadCommand LLC =
> + MachOObj->getLinkeditDataLoadCommand(Command);
>
> - MachOObj->ReadULEB128s(LLC->DataOffset, FoundFns);
> + MachOObj->ReadULEB128s(LLC.DataOffset, FoundFns);
> }
> + Command = MachOObj->getNextLoadCommandInfo(Command);
> }
> }
>
> -template<endianness E>
> static void DisassembleInputMachO2(StringRef Filename,
> - MachOObjectFileMiddle<E> *MachOOF);
> + MachOObjectFile *MachOOF);
>
> void llvm::DisassembleInputMachO(StringRef Filename) {
> OwningPtr<MemoryBuffer> Buff;
> @@ -231,20 +229,14 @@ void llvm::DisassembleInputMachO(StringR
> return;
> }
>
> - OwningPtr<MachOObjectFileBase> MachOOF(static_cast<MachOObjectFileBase*>(
> + OwningPtr<MachOObjectFile> MachOOF(static_cast<MachOObjectFile*>(
> ObjectFile::createMachOObjectFile(Buff.take())));
>
> - if (MachOObjectFileLE *O = dyn_cast<MachOObjectFileLE>(MachOOF.get())) {
> - DisassembleInputMachO2(Filename, O);
> - return;
> - }
> - MachOObjectFileBE *O = cast<MachOObjectFileBE>(MachOOF.get());
> - DisassembleInputMachO2(Filename, O);
> + DisassembleInputMachO2(Filename, MachOOF.get());
> }
>
> -template<endianness E>
> static void DisassembleInputMachO2(StringRef Filename,
> - MachOObjectFileMiddle<E> *MachOOF) {
> + MachOObjectFile *MachOOF) {
> const Target *TheTarget = GetTarget(MachOOF);
> if (!TheTarget) {
> // GetTarget prints out stuff.
> @@ -273,8 +265,7 @@ static void DisassembleInputMachO2(Strin
>
> outs() << '\n' << Filename << ":\n\n";
>
> - const typename MachOObjectFileMiddle<E>::Header *Header =
> - MachOOF->getHeader();
> + macho::Header Header = MachOOF->getHeader();
>
> std::vector<SectionRef> Sections;
> std::vector<SymbolRef> Symbols;
>
> Modified: llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp?rev=179778&r1=179777&r2=179778&view=diff
> ==============================================================================
> --- llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp (original)
> +++ llvm/trunk/tools/llvm-objdump/llvm-objdump.cpp Thu Apr 18 13:08:55 2013
> @@ -191,14 +191,6 @@ bool llvm::RelocAddressLess(RelocationRe
> return a_addr < b_addr;
> }
>
> -StringRef
> -getSectionFinalSegmentName(const MachOObjectFileBase *MachO, DataRefImpl DR) {
> - if (const MachOObjectFileLE *O = dyn_cast<MachOObjectFileLE>(MachO))
> - return O->getSectionFinalSegmentName(DR);
> - const MachOObjectFileBE *O = dyn_cast<MachOObjectFileBE>(MachO);
> - return O->getSectionFinalSegmentName(DR);
> -}
> -
> static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
> const Target *TheTarget = getTarget(Obj);
> // getTarget() will have already issued a diagnostic if necessary, so
> @@ -263,10 +255,10 @@ static void DisassembleObject(const Obje
> std::sort(Rels.begin(), Rels.end(), RelocAddressLess);
>
> StringRef SegmentName = "";
> - if (const MachOObjectFileBase *MachO =
> - dyn_cast<const MachOObjectFileBase>(Obj)) {
> + if (const MachOObjectFile *MachO =
> + dyn_cast<const MachOObjectFile>(Obj)) {
> DataRefImpl DR = i->getRawDataRefImpl();
> - SegmentName = getSectionFinalSegmentName(MachO, DR);
> + SegmentName = MachO->getSectionFinalSegmentName(DR);
> }
> StringRef name;
> if (error(i->getName(name))) break;
> @@ -608,10 +600,10 @@ static void PrintSymbolTable(const Objec
> else if (Section == o->end_sections())
> outs() << "*UND*";
> else {
> - if (const MachOObjectFileBase *MachO =
> - dyn_cast<const MachOObjectFileBase>(o)) {
> + if (const MachOObjectFile *MachO =
> + dyn_cast<const MachOObjectFile>(o)) {
> DataRefImpl DR = Section->getRawDataRefImpl();
> - StringRef SegmentName = getSectionFinalSegmentName(MachO, DR);
> + StringRef SegmentName = MachO->getSectionFinalSegmentName(DR);
> outs() << SegmentName << ",";
> }
> StringRef SectionName;
>
> Modified: llvm/trunk/tools/llvm-readobj/MachODumper.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/MachODumper.cpp?rev=179778&r1=179777&r2=179778&view=diff
> ==============================================================================
> --- llvm/trunk/tools/llvm-readobj/MachODumper.cpp (original)
> +++ llvm/trunk/tools/llvm-readobj/MachODumper.cpp Thu Apr 18 13:08:55 2013
> @@ -27,7 +27,7 @@ namespace {
>
> class MachODumper : public ObjDumper {
> public:
> - MachODumper(const MachOObjectFileBase *Obj, StreamWriter& Writer)
> + MachODumper(const MachOObjectFile *Obj, StreamWriter& Writer)
> : ObjDumper(Writer)
> , Obj(Obj) { }
>
> @@ -43,14 +43,12 @@ private:
>
> void printRelocation(section_iterator SecI, relocation_iterator RelI);
>
> - template<support::endianness E>
> - void printRelocation(const MachOObjectFileMiddle<E> *Obj,
> + void printRelocation(const MachOObjectFile *Obj,
> section_iterator SecI, relocation_iterator RelI);
>
> - template<support::endianness E>
> - void printSections(const MachOObjectFileMiddle<E> *Obj);
> + void printSections(const MachOObjectFile *Obj);
>
> - const MachOObjectFileBase *Obj;
> + const MachOObjectFile *Obj;
> };
>
> } // namespace
> @@ -61,7 +59,7 @@ namespace llvm {
> error_code createMachODumper(const object::ObjectFile *Obj,
> StreamWriter& Writer,
> OwningPtr<ObjDumper> &Result) {
> - const MachOObjectFileBase *MachOObj = dyn_cast<MachOObjectFileBase>(Obj);
> + const MachOObjectFile *MachOObj = dyn_cast<MachOObjectFile>(Obj);
> if (!MachOObj)
> return readobj_error::unsupported_obj_file_format;
>
> @@ -164,59 +162,53 @@ namespace {
> };
> }
>
> -template<class MachOT>
> -static void getSection(const MachOObjectFile<MachOT> *Obj,
> - DataRefImpl DRI,
> +static void getSection(const MachOObjectFile *Obj,
> + DataRefImpl Sec,
> MachOSection &Section) {
> - const typename MachOObjectFile<MachOT>::Section *Sect = Obj->getSection(DRI);
> - Section.Address = Sect->Address;
> - Section.Size = Sect->Size;
> - Section.Offset = Sect->Offset;
> - Section.Alignment = Sect->Align;
> - Section.RelocationTableOffset = Sect->RelocationTableOffset;
> - Section.NumRelocationTableEntries = Sect->NumRelocationTableEntries;
> - Section.Flags = Sect->Flags;
> - Section.Reserved1 = Sect->Reserved1;
> - Section.Reserved2 = Sect->Reserved2;
> -}
> -
> -static void getSection(const MachOObjectFileBase *Obj,
> - DataRefImpl DRI,
> - MachOSection &Section) {
> - if (const MachOObjectFileLE32 *O = dyn_cast<MachOObjectFileLE32>(Obj))
> - return getSection(O, DRI, Section);
> - if (const MachOObjectFileLE64 *O = dyn_cast<MachOObjectFileLE64>(Obj))
> - return getSection(O, DRI, Section);
> - if (const MachOObjectFileBE32 *O = dyn_cast<MachOObjectFileBE32>(Obj))
> - return getSection(O, DRI, Section);
> - const MachOObjectFileBE64 *O = cast<MachOObjectFileBE64>(Obj);
> - getSection(O, DRI, Section);
> + if (!Obj->is64Bit()) {
> + macho::Section Sect = Obj->getSection(Sec);
> + Section.Address = Sect.Address;
> + Section.Size = Sect.Size;
> + Section.Offset = Sect.Offset;
> + Section.Alignment = Sect.Align;
> + Section.RelocationTableOffset = Sect.RelocationTableOffset;
> + Section.NumRelocationTableEntries = Sect.NumRelocationTableEntries;
> + Section.Flags = Sect.Flags;
> + Section.Reserved1 = Sect.Reserved1;
> + Section.Reserved2 = Sect.Reserved2;
> + return;
> + }
> + macho::Section64 Sect = Obj->getSection64(Sec);
> + Section.Address = Sect.Address;
> + Section.Size = Sect.Size;
> + Section.Offset = Sect.Offset;
> + Section.Alignment = Sect.Align;
> + Section.RelocationTableOffset = Sect.RelocationTableOffset;
> + Section.NumRelocationTableEntries = Sect.NumRelocationTableEntries;
> + Section.Flags = Sect.Flags;
> + Section.Reserved1 = Sect.Reserved1;
> + Section.Reserved2 = Sect.Reserved2;
> }
>
> -template<class MachOT>
> -static void getSymbol(const MachOObjectFile<MachOT> *Obj,
> - DataRefImpl DRI,
> - MachOSymbol &Symbol) {
> - const typename MachOObjectFile<MachOT>::SymbolTableEntry *Entry =
> - Obj->getSymbolTableEntry(DRI);
> - Symbol.StringIndex = Entry->StringIndex;
> - Symbol.Type = Entry->Type;
> - Symbol.SectionIndex = Entry->SectionIndex;
> - Symbol.Flags = Entry->Flags;
> - Symbol.Value = Entry->Value;
> -}
>
> -static void getSymbol(const MachOObjectFileBase *Obj,
> +static void getSymbol(const MachOObjectFile *Obj,
> DataRefImpl DRI,
> MachOSymbol &Symbol) {
> - if (const MachOObjectFileLE32 *O = dyn_cast<MachOObjectFileLE32>(Obj))
> - return getSymbol(O, DRI, Symbol);
> - if (const MachOObjectFileLE64 *O = dyn_cast<MachOObjectFileLE64>(Obj))
> - return getSymbol(O, DRI, Symbol);
> - if (const MachOObjectFileBE32 *O = dyn_cast<MachOObjectFileBE32>(Obj))
> - return getSymbol(O, DRI, Symbol);
> - const MachOObjectFileBE64 *O = cast<MachOObjectFileBE64>(Obj);
> - getSymbol(O, DRI, Symbol);
> + if (!Obj->is64Bit()) {
> + macho::SymbolTableEntry Entry = Obj->getSymbolTableEntry(DRI);
> + Symbol.StringIndex = Entry.StringIndex;
> + Symbol.Type = Entry.Type;
> + Symbol.SectionIndex = Entry.SectionIndex;
> + Symbol.Flags = Entry.Flags;
> + Symbol.Value = Entry.Value;
> + return;
> + }
> + macho::Symbol64TableEntry Entry = Obj->getSymbol64TableEntry(DRI);
> + Symbol.StringIndex = Entry.StringIndex;
> + Symbol.Type = Entry.Type;
> + Symbol.SectionIndex = Entry.SectionIndex;
> + Symbol.Flags = Entry.Flags;
> + Symbol.Value = Entry.Value;
> }
>
> void MachODumper::printFileHeaders() {
> @@ -224,14 +216,10 @@ void MachODumper::printFileHeaders() {
> }
>
> void MachODumper::printSections() {
> - if (const MachOObjectFileLE *O = dyn_cast<MachOObjectFileLE>(Obj))
> - return printSections(O);
> - const MachOObjectFileBE *O = cast<MachOObjectFileBE>(Obj);
> - return printSections(O);
> + return printSections(Obj);
> }
>
> -template<support::endianness E>
> -void MachODumper::printSections(const MachOObjectFileMiddle<E> *Obj) {
> +void MachODumper::printSections(const MachOObjectFile *Obj) {
> ListScope Group(W, "Sections");
>
> int SectionIndex = -1;
> @@ -344,14 +332,10 @@ void MachODumper::printRelocations() {
>
> void MachODumper::printRelocation(section_iterator SecI,
> relocation_iterator RelI) {
> - if (const MachOObjectFileLE *O = dyn_cast<MachOObjectFileLE>(Obj))
> - return printRelocation(O, SecI, RelI);
> - const MachOObjectFileBE *O = cast<MachOObjectFileBE>(Obj);
> - return printRelocation(O, SecI, RelI);
> + return printRelocation(Obj, SecI, RelI);
> }
>
> -template<support::endianness E>
> -void MachODumper::printRelocation(const MachOObjectFileMiddle<E> *Obj,
> +void MachODumper::printRelocation(const MachOObjectFile *Obj,
> section_iterator SecI,
> relocation_iterator RelI) {
> uint64_t Offset;
> @@ -364,31 +348,30 @@ void MachODumper::printRelocation(const
> if (error(Symbol.getName(SymbolName))) return;
>
> DataRefImpl DR = RelI->getRawDataRefImpl();
> - const typename MachOObjectFileMiddle<E>::RelocationEntry *RE =
> - Obj->getRelocation(DR);
> + macho::RelocationEntry RE = Obj->getRelocation(DR);
> bool IsScattered = Obj->isRelocationScattered(RE);
>
> if (opts::ExpandRelocs) {
> DictScope Group(W, "Relocation");
> W.printHex("Offset", Offset);
> - W.printNumber("PCRel", Obj->isRelocationPCRel(RE));
> - W.printNumber("Length", Obj->getRelocationLength(RE));
> + W.printNumber("PCRel", Obj->getAnyRelocationPCRel(RE));
> + W.printNumber("Length", Obj->getAnyRelocationLength(RE));
> if (IsScattered)
> W.printString("Extern", StringRef("N/A"));
> else
> - W.printNumber("Extern", RE->External);
> - W.printNumber("Type", RelocName, RE->Type);
> + W.printNumber("Extern", Obj->getPlainRelocationExternal(RE));
> + W.printNumber("Type", RelocName, Obj->getAnyRelocationType(RE));
> W.printString("Symbol", SymbolName.size() > 0 ? SymbolName : "-");
> W.printNumber("Scattered", IsScattered);
> } else {
> raw_ostream& OS = W.startLine();
> OS << W.hex(Offset)
> - << " " << Obj->isRelocationPCRel(RE)
> - << " " << Obj->getRelocationLength(RE);
> + << " " << Obj->getAnyRelocationPCRel(RE)
> + << " " << Obj->getAnyRelocationLength(RE);
> if (IsScattered)
> OS << " n/a";
> else
> - OS << " " << RE->External;
> + OS << " " << Obj->getPlainRelocationExternal(RE);
> OS << " " << RelocName
> << " " << IsScattered
> << " " << (SymbolName.size() > 0 ? SymbolName : "-")
>
> Modified: llvm/trunk/tools/llvm-symbolizer/LLVMSymbolize.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-symbolizer/LLVMSymbolize.cpp?rev=179778&r1=179777&r2=179778&view=diff
> ==============================================================================
> --- llvm/trunk/tools/llvm-symbolizer/LLVMSymbolize.cpp (original)
> +++ llvm/trunk/tools/llvm-symbolizer/LLVMSymbolize.cpp Thu Apr 18 13:08:55 2013
> @@ -233,7 +233,7 @@ LLVMSymbolizer::getOrCreateModuleInfo(co
> // On Darwin we may find DWARF in separate object file in
> // resource directory.
> ObjectFile *DbgObj = Obj;
> - if (isa<MachOObjectFileBase>(Obj)) {
> + if (isa<MachOObjectFile>(Obj)) {
> const std::string &ResourceName =
> getDarwinDWARFResourceForModule(ModuleName);
> ObjectFile *ResourceObj = getObjectFile(ResourceName);
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
-------------- next part --------------
A non-text attachment was scrubbed...
Name: z
Type: application/octet-stream
Size: 156 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20130419/923d6f05/attachment.obj>
More information about the llvm-commits
mailing list