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