From a2561a0153237291980722383f409a6499b12efc Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Wed, 10 Apr 2013 03:48:25 +0000 Subject: [PATCH] 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 --- include/llvm/Object/MachO.h | 239 ++++++++++++++++++------------- lib/Object/MachOObjectFile.cpp | 12 +- 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 3b0ca6c3ce2..1b0ca29543a 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 +struct MachOType { + static const endianness TargetEndianness = E; + static const bool Is64Bits = B; +}; + +template +struct MachODataTypeTypedefHelperCommon { + typedef support::detail::packed_endian_specific_integral + MachOInt16; + typedef support::detail::packed_endian_specific_integral + MachOInt32; + typedef support::detail::packed_endian_specific_integral + MachOInt64; +}; + +#define LLVM_MACHOB_IMPORT_TYPES(E) \ +typedef typename MachODataTypeTypedefHelperCommon::MachOInt16 MachOInt16; \ +typedef typename MachODataTypeTypedefHelperCommon::MachOInt32 MachOInt32; \ +typedef typename MachODataTypeTypedefHelperCommon::MachOInt64 MachOInt64; + +template +struct MachODataTypeTypedefHelper; + +template class MachOT, endianness TargetEndianness> +struct MachODataTypeTypedefHelper > { + typedef MachODataTypeTypedefHelperCommon Base; + typedef typename Base::MachOInt32 MachOIntPtr; +}; + +template class MachOT, endianness TargetEndianness> +struct MachODataTypeTypedefHelper > { + typedef MachODataTypeTypedefHelperCommon Base; + typedef typename Base::MachOInt64 MachOIntPtr; +}; + +#define LLVM_MACHO_IMPORT_TYPES(MachOT, E, B) \ +LLVM_MACHOB_IMPORT_TYPES(E) \ +typedef typename \ + MachODataTypeTypedefHelper >::MachOIntPtr MachOIntPtr; + namespace MachOFormat { struct SectionBase { char Name[16]; char SegmentName[16]; }; - template + template struct Section; - template<> - struct Section { + template class MachOT, endianness TargetEndianness> + struct Section > { + 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 { + template class MachOT, + endianness TargetEndianness> + struct Section > { + 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 struct RelocationEntry { - support::ulittle32_t Word0; - support::ulittle32_t Word1; + LLVM_MACHOB_IMPORT_TYPES(TargetEndianness) + MachOInt32 Word0; + MachOInt32 Word1; }; + template 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 + template struct SymbolTableEntry; - template<> - struct SymbolTableEntry { - support::ulittle32_t StringIndex; - uint8_t Type; - uint8_t SectionIndex; - support::ulittle16_t Flags; - support::ulittle32_t Value; - }; - - template<> - struct SymbolTableEntry { - support::ulittle32_t StringIndex; + template class MachOT, endianness TargetEndianness, + bool Is64Bits> + struct SymbolTableEntry > { + 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 struct LoadCommand { - support::ulittle32_t Type; - support::ulittle32_t Size; + LLVM_MACHOB_IMPORT_TYPES(TargetEndianness) + MachOInt32 Type; + MachOInt32 Size; }; + template 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 + template struct SegmentLoadCommand; - template<> - struct SegmentLoadCommand { - support::ulittle32_t Type; - support::ulittle32_t Size; + template class MachOT, endianness TargetEndianness, + bool Is64Bits> + struct SegmentLoadCommand > { + 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 { - 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 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 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 + SymbolTableEntryBase; + typedef MachOFormat::SymtabLoadCommand SymtabLoadCommand; + typedef MachOFormat::RelocationEntry RelocationEntry; typedef MachOFormat::SectionBase SectionBase; - typedef MachOFormat::LoadCommand LoadCommand; - typedef MachOFormat::Header Header; + typedef MachOFormat::LoadCommand LoadCommand; + typedef MachOFormat::Header Header; + typedef MachOFormat::LinkeditDataLoadCommand + LinkeditDataLoadCommand; MachOObjectFileBase(MemoryBuffer *Object, bool Is64Bits, error_code &ec); @@ -253,9 +294,11 @@ private: template struct MachOObjectFileHelperCommon { - typedef MachOFormat::SegmentLoadCommand SegmentLoadCommand; - typedef MachOFormat::SymbolTableEntry SymbolTableEntry; - typedef MachOFormat::Section Section; + typedef MachOFormat::SegmentLoadCommand > + SegmentLoadCommand; + typedef MachOFormat::SymbolTableEntry > + SymbolTableEntry; + typedef MachOFormat::Section > Section; }; template diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index 20b66d94e8c..33c63b0f896 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) : - sizeof(MachOFormat::SymbolTableEntry); + sizeof(MachOObjectFile::SymbolTableEntry) : + sizeof(MachOObjectFile::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) : - sizeof(MachOFormat::SegmentLoadCommand); - unsigned SectionSize = Is64 ? sizeof(MachOFormat::Section) : - sizeof(MachOFormat::Section); + Is64 ? sizeof(MachOObjectFile::SegmentLoadCommand) : + sizeof(MachOObjectFile::SegmentLoadCommand); + unsigned SectionSize = Is64 ? sizeof(MachOObjectFile::Section) : + sizeof(MachOObjectFile::Section); uintptr_t SectionAddr = CommandAddr + SegmentLoadSize + DRI.d.b * SectionSize; return reinterpret_cast(SectionAddr); diff --git a/tools/llvm-objdump/MachODump.cpp b/tools/llvm-objdump/MachODump.cpp index b0a1aca26f4..d1e7d695f60 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 &Sections, std::vector &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(Command); + const MachOObjectFileBase::LinkeditDataLoadCommand *LLC = + reinterpret_cast(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 Sections; std::vector Symbols; -- 2.34.1