diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2013-04-10 03:48:25 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2013-04-10 03:48:25 +0000 |
commit | a2561a0153237291980722383f409a6499b12efc (patch) | |
tree | 4626dff1b1c7fb3b694c460de6c22692c535ad45 | |
parent | 774e7c82a84189a1f8194a63dc8040136ca6b4d8 (diff) |
Template the MachO types over endianness.
For now they are still only used as little endian.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179147 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/llvm/Object/MachO.h | 239 | ||||
-rw-r--r-- | lib/Object/MachOObjectFile.cpp | 12 | ||||
-rw-r--r-- | tools/llvm-objdump/MachODump.cpp | 11 |
3 files changed, 153 insertions, 109 deletions
diff --git a/include/llvm/Object/MachO.h b/include/llvm/Object/MachO.h index 3b0ca6c3ce..1b0ca29543 100644 --- a/include/llvm/Object/MachO.h +++ b/include/llvm/Object/MachO.h @@ -27,152 +27,193 @@ namespace llvm { namespace object { +using support::endianness; + +template<endianness E, bool B> +struct MachOType { + static const endianness TargetEndianness = E; + static const bool Is64Bits = B; +}; + +template<endianness TargetEndianness> +struct MachODataTypeTypedefHelperCommon { + typedef support::detail::packed_endian_specific_integral + <uint16_t, TargetEndianness, support::unaligned> MachOInt16; + typedef support::detail::packed_endian_specific_integral + <uint32_t, TargetEndianness, support::unaligned> MachOInt32; + typedef support::detail::packed_endian_specific_integral + <uint64_t, TargetEndianness, support::unaligned> MachOInt64; +}; + +#define LLVM_MACHOB_IMPORT_TYPES(E) \ +typedef typename MachODataTypeTypedefHelperCommon<E>::MachOInt16 MachOInt16; \ +typedef typename MachODataTypeTypedefHelperCommon<E>::MachOInt32 MachOInt32; \ +typedef typename MachODataTypeTypedefHelperCommon<E>::MachOInt64 MachOInt64; + +template<class MachOT> +struct MachODataTypeTypedefHelper; + +template<template<endianness, bool> class MachOT, endianness TargetEndianness> +struct MachODataTypeTypedefHelper<MachOT<TargetEndianness, false> > { + typedef MachODataTypeTypedefHelperCommon<TargetEndianness> Base; + typedef typename Base::MachOInt32 MachOIntPtr; +}; + +template<template<endianness, bool> class MachOT, endianness TargetEndianness> +struct MachODataTypeTypedefHelper<MachOT<TargetEndianness, true> > { + typedef MachODataTypeTypedefHelperCommon<TargetEndianness> Base; + typedef typename Base::MachOInt64 MachOIntPtr; +}; + +#define LLVM_MACHO_IMPORT_TYPES(MachOT, E, B) \ +LLVM_MACHOB_IMPORT_TYPES(E) \ +typedef typename \ + MachODataTypeTypedefHelper <MachOT<E, B> >::MachOIntPtr MachOIntPtr; + namespace MachOFormat { struct SectionBase { char Name[16]; char SegmentName[16]; }; - template<bool is64Bits> + template<class MachOT> struct Section; - template<> - struct Section<false> { + template<template<endianness, bool> class MachOT, endianness TargetEndianness> + struct Section<MachOT<TargetEndianness, false> > { + LLVM_MACHOB_IMPORT_TYPES(TargetEndianness) char Name[16]; char SegmentName[16]; - support::ulittle32_t Address; - support::ulittle32_t Size; - support::ulittle32_t Offset; - support::ulittle32_t Align; - support::ulittle32_t RelocationTableOffset; - support::ulittle32_t NumRelocationTableEntries; - support::ulittle32_t Flags; - support::ulittle32_t Reserved1; - support::ulittle32_t Reserved2; + MachOInt32 Address; + MachOInt32 Size; + MachOInt32 Offset; + MachOInt32 Align; + MachOInt32 RelocationTableOffset; + MachOInt32 NumRelocationTableEntries; + MachOInt32 Flags; + MachOInt32 Reserved1; + MachOInt32 Reserved2; }; - template<> - struct Section<true> { + template<template<endianness, bool> class MachOT, + endianness TargetEndianness> + struct Section<MachOT<TargetEndianness, true> > { + LLVM_MACHOB_IMPORT_TYPES(TargetEndianness) char Name[16]; char SegmentName[16]; - support::ulittle64_t Address; - support::ulittle64_t Size; - support::ulittle32_t Offset; - support::ulittle32_t Align; - support::ulittle32_t RelocationTableOffset; - support::ulittle32_t NumRelocationTableEntries; - support::ulittle32_t Flags; - support::ulittle32_t Reserved1; - support::ulittle32_t Reserved2; - support::ulittle32_t Reserved3; + MachOInt64 Address; + MachOInt64 Size; + MachOInt32 Offset; + MachOInt32 Align; + MachOInt32 RelocationTableOffset; + MachOInt32 NumRelocationTableEntries; + MachOInt32 Flags; + MachOInt32 Reserved1; + MachOInt32 Reserved2; + MachOInt32 Reserved3; }; + template<endianness TargetEndianness> struct RelocationEntry { - support::ulittle32_t Word0; - support::ulittle32_t Word1; + LLVM_MACHOB_IMPORT_TYPES(TargetEndianness) + MachOInt32 Word0; + MachOInt32 Word1; }; + template<endianness TargetEndianness> struct SymbolTableEntryBase { - support::ulittle32_t StringIndex; + LLVM_MACHOB_IMPORT_TYPES(TargetEndianness) + MachOInt32 StringIndex; uint8_t Type; uint8_t SectionIndex; - support::ulittle16_t Flags; + MachOInt16 Flags; }; - template<bool is64Bits> + template<class MachOT> struct SymbolTableEntry; - template<> - struct SymbolTableEntry<false> { - support::ulittle32_t StringIndex; - uint8_t Type; - uint8_t SectionIndex; - support::ulittle16_t Flags; - support::ulittle32_t Value; - }; - - template<> - struct SymbolTableEntry<true> { - support::ulittle32_t StringIndex; + template<template<endianness, bool> class MachOT, endianness TargetEndianness, + bool Is64Bits> + struct SymbolTableEntry<MachOT<TargetEndianness, Is64Bits> > { + LLVM_MACHO_IMPORT_TYPES(MachOT, TargetEndianness, Is64Bits) + MachOInt32 StringIndex; uint8_t Type; uint8_t SectionIndex; - support::ulittle16_t Flags; - support::ulittle64_t Value; + MachOInt16 Flags; + MachOIntPtr Value; }; + template<endianness TargetEndianness> struct LoadCommand { - support::ulittle32_t Type; - support::ulittle32_t Size; + LLVM_MACHOB_IMPORT_TYPES(TargetEndianness) + MachOInt32 Type; + MachOInt32 Size; }; + template<endianness TargetEndianness> struct SymtabLoadCommand { - support::ulittle32_t Type; - support::ulittle32_t Size; - support::ulittle32_t SymbolTableOffset; - support::ulittle32_t NumSymbolTableEntries; - support::ulittle32_t StringTableOffset; - support::ulittle32_t StringTableSize; + LLVM_MACHOB_IMPORT_TYPES(TargetEndianness) + MachOInt32 Type; + MachOInt32 Size; + MachOInt32 SymbolTableOffset; + MachOInt32 NumSymbolTableEntries; + MachOInt32 StringTableOffset; + MachOInt32 StringTableSize; }; - template<bool is64Bits> + template<class MachOT> struct SegmentLoadCommand; - template<> - struct SegmentLoadCommand<false> { - support::ulittle32_t Type; - support::ulittle32_t Size; + template<template<endianness, bool> class MachOT, endianness TargetEndianness, + bool Is64Bits> + struct SegmentLoadCommand<MachOT<TargetEndianness, Is64Bits> > { + LLVM_MACHO_IMPORT_TYPES(MachOT, TargetEndianness, Is64Bits) + MachOInt32 Type; + MachOInt32 Size; char Name[16]; - support::ulittle32_t VMAddress; - support::ulittle32_t VMSize; - support::ulittle32_t FileOffset; - support::ulittle32_t FileSize; - support::ulittle32_t MaxVMProtection; - support::ulittle32_t InitialVMProtection; - support::ulittle32_t NumSections; - support::ulittle32_t Flags; - }; - - template<> - struct SegmentLoadCommand<true> { - support::ulittle32_t Type; - support::ulittle32_t Size; - char Name[16]; - support::ulittle64_t VMAddress; - support::ulittle64_t VMSize; - support::ulittle64_t FileOffset; - support::ulittle64_t FileSize; - support::ulittle32_t MaxVMProtection; - support::ulittle32_t InitialVMProtection; - support::ulittle32_t NumSections; - support::ulittle32_t Flags; + MachOIntPtr VMAddress; + MachOIntPtr VMSize; + MachOIntPtr FileOffset; + MachOIntPtr FileSize; + MachOInt32 MaxVMProtection; + MachOInt32 InitialVMProtection; + MachOInt32 NumSections; + MachOInt32 Flags; }; + template<endianness TargetEndianness> struct LinkeditDataLoadCommand { - support::ulittle32_t Type; - support::ulittle32_t Size; - support::ulittle32_t DataOffset; - support::ulittle32_t DataSize; + LLVM_MACHOB_IMPORT_TYPES(TargetEndianness) + MachOInt32 Type; + MachOInt32 Size; + MachOInt32 DataOffset; + MachOInt32 DataSize; }; + template<endianness TargetEndianness> struct Header { - support::ulittle32_t Magic; - support::ulittle32_t CPUType; - support::ulittle32_t CPUSubtype; - support::ulittle32_t FileType; - support::ulittle32_t NumLoadCommands; - support::ulittle32_t SizeOfLoadCommands; - support::ulittle32_t Flags; + LLVM_MACHOB_IMPORT_TYPES(TargetEndianness) + MachOInt32 Magic; + MachOInt32 CPUType; + MachOInt32 CPUSubtype; + MachOInt32 FileType; + MachOInt32 NumLoadCommands; + MachOInt32 SizeOfLoadCommands; + MachOInt32 Flags; }; } class MachOObjectFileBase : public ObjectFile { public: - typedef MachOFormat::SymbolTableEntryBase SymbolTableEntryBase; - typedef MachOFormat::SymtabLoadCommand SymtabLoadCommand; - typedef MachOFormat::RelocationEntry RelocationEntry; + typedef MachOFormat::SymbolTableEntryBase<support::little> + SymbolTableEntryBase; + typedef MachOFormat::SymtabLoadCommand<support::little> SymtabLoadCommand; + typedef MachOFormat::RelocationEntry<support::little> RelocationEntry; typedef MachOFormat::SectionBase SectionBase; - typedef MachOFormat::LoadCommand LoadCommand; - typedef MachOFormat::Header Header; + typedef MachOFormat::LoadCommand<support::little> LoadCommand; + typedef MachOFormat::Header<support::little> Header; + typedef MachOFormat::LinkeditDataLoadCommand<support::little> + LinkeditDataLoadCommand; MachOObjectFileBase(MemoryBuffer *Object, bool Is64Bits, error_code &ec); @@ -253,9 +294,11 @@ private: template<bool is64Bits> struct MachOObjectFileHelperCommon { - typedef MachOFormat::SegmentLoadCommand<is64Bits> SegmentLoadCommand; - typedef MachOFormat::SymbolTableEntry<is64Bits> SymbolTableEntry; - typedef MachOFormat::Section<is64Bits> Section; + typedef MachOFormat::SegmentLoadCommand<MachOType<support::little, is64Bits> > + SegmentLoadCommand; + typedef MachOFormat::SymbolTableEntry<MachOType<support::little, is64Bits> > + SymbolTableEntry; + typedef MachOFormat::Section<MachOType<support::little, is64Bits> > Section; }; template<bool is64Bits> diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index 20b66d94e8..33c63b0f89 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -127,8 +127,8 @@ MachOObjectFileBase::getSymbolTableEntryBase(DataRefImpl DRI, unsigned Index = DRI.d.b; unsigned SymbolTableEntrySize = is64Bit() ? - sizeof(MachOFormat::SymbolTableEntry<true>) : - sizeof(MachOFormat::SymbolTableEntry<false>); + sizeof(MachOObjectFile<true>::SymbolTableEntry) : + sizeof(MachOObjectFile<false>::SymbolTableEntry); uint64_t Offset = SymbolTableOffset + Index * SymbolTableEntrySize; StringRef Data = getData(Offset, SymbolTableEntrySize); @@ -314,10 +314,10 @@ MachOObjectFileBase::getSectionBase(DataRefImpl DRI) const { bool Is64 = is64Bit(); unsigned SegmentLoadSize = - Is64 ? sizeof(MachOFormat::SegmentLoadCommand<true>) : - sizeof(MachOFormat::SegmentLoadCommand<false>); - unsigned SectionSize = Is64 ? sizeof(MachOFormat::Section<true>) : - sizeof(MachOFormat::Section<false>); + Is64 ? sizeof(MachOObjectFile<true>::SegmentLoadCommand) : + sizeof(MachOObjectFile<false>::SegmentLoadCommand); + unsigned SectionSize = Is64 ? sizeof(MachOObjectFile<true>::Section) : + sizeof(MachOObjectFile<false>::Section); uintptr_t SectionAddr = CommandAddr + SegmentLoadSize + DRI.d.b * SectionSize; return reinterpret_cast<const SectionBase*>(SectionAddr); diff --git a/tools/llvm-objdump/MachODump.cpp b/tools/llvm-objdump/MachODump.cpp index b0a1aca26f..d1e7d695f6 100644 --- a/tools/llvm-objdump/MachODump.cpp +++ b/tools/llvm-objdump/MachODump.cpp @@ -199,7 +199,7 @@ static void emitDOTFile(const char *FileName, const MCFunction &f, Out << "}\n"; } -static void getSectionsAndSymbols(const MachOFormat::Header *Header, +static void getSectionsAndSymbols(const MachOObjectFileBase::Header *Header, MachOObjectFileBase *MachOObj, std::vector<SectionRef> &Sections, std::vector<SymbolRef> &Symbols, @@ -218,12 +218,13 @@ static void getSectionsAndSymbols(const MachOFormat::Header *Header, } for (unsigned i = 0; i != Header->NumLoadCommands; ++i) { - const MachOFormat::LoadCommand *Command = MachOObj->getLoadCommandInfo(i); + const MachOObjectFileBase::LoadCommand *Command = + MachOObj->getLoadCommandInfo(i); if (Command->Type == macho::LCT_FunctionStarts) { // We found a function starts segment, parse the addresses for later // consumption. - const MachOFormat::LinkeditDataLoadCommand *LLC = - reinterpret_cast<const MachOFormat::LinkeditDataLoadCommand*>(Command); + const MachOObjectFileBase::LinkeditDataLoadCommand *LLC = + reinterpret_cast<const MachOObjectFileBase::LinkeditDataLoadCommand*>(Command); MachOObj->ReadULEB128s(LLC->DataOffset, FoundFns); } @@ -269,7 +270,7 @@ void llvm::DisassembleInputMachO(StringRef Filename) { outs() << '\n' << Filename << ":\n\n"; - const MachOFormat::Header *Header = MachOOF->getHeader(); + const MachOObjectFileBase::Header *Header = MachOOF->getHeader(); std::vector<SectionRef> Sections; std::vector<SymbolRef> Symbols; |