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
This commit is contained in:
Rafael Espindola
2013-04-10 03:48:25 +00:00
parent 774e7c82a8
commit a2561a0153
3 changed files with 153 additions and 109 deletions

View File

@ -27,152 +27,193 @@
namespace llvm { namespace llvm {
namespace object { 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 { namespace MachOFormat {
struct SectionBase { struct SectionBase {
char Name[16]; char Name[16];
char SegmentName[16]; char SegmentName[16];
}; };
template<bool is64Bits> template<class MachOT>
struct Section; struct Section;
template<> template<template<endianness, bool> class MachOT, endianness TargetEndianness>
struct Section<false> { struct Section<MachOT<TargetEndianness, false> > {
LLVM_MACHOB_IMPORT_TYPES(TargetEndianness)
char Name[16]; char Name[16];
char SegmentName[16]; char SegmentName[16];
support::ulittle32_t Address; MachOInt32 Address;
support::ulittle32_t Size; MachOInt32 Size;
support::ulittle32_t Offset; MachOInt32 Offset;
support::ulittle32_t Align; MachOInt32 Align;
support::ulittle32_t RelocationTableOffset; MachOInt32 RelocationTableOffset;
support::ulittle32_t NumRelocationTableEntries; MachOInt32 NumRelocationTableEntries;
support::ulittle32_t Flags; MachOInt32 Flags;
support::ulittle32_t Reserved1; MachOInt32 Reserved1;
support::ulittle32_t Reserved2; MachOInt32 Reserved2;
}; };
template<> template<template<endianness, bool> class MachOT,
struct Section<true> { endianness TargetEndianness>
struct Section<MachOT<TargetEndianness, true> > {
LLVM_MACHOB_IMPORT_TYPES(TargetEndianness)
char Name[16]; char Name[16];
char SegmentName[16]; char SegmentName[16];
support::ulittle64_t Address; MachOInt64 Address;
support::ulittle64_t Size; MachOInt64 Size;
support::ulittle32_t Offset; MachOInt32 Offset;
support::ulittle32_t Align; MachOInt32 Align;
support::ulittle32_t RelocationTableOffset; MachOInt32 RelocationTableOffset;
support::ulittle32_t NumRelocationTableEntries; MachOInt32 NumRelocationTableEntries;
support::ulittle32_t Flags; MachOInt32 Flags;
support::ulittle32_t Reserved1; MachOInt32 Reserved1;
support::ulittle32_t Reserved2; MachOInt32 Reserved2;
support::ulittle32_t Reserved3; MachOInt32 Reserved3;
}; };
template<endianness TargetEndianness>
struct RelocationEntry { struct RelocationEntry {
support::ulittle32_t Word0; LLVM_MACHOB_IMPORT_TYPES(TargetEndianness)
support::ulittle32_t Word1; MachOInt32 Word0;
MachOInt32 Word1;
}; };
template<endianness TargetEndianness>
struct SymbolTableEntryBase { struct SymbolTableEntryBase {
support::ulittle32_t StringIndex; LLVM_MACHOB_IMPORT_TYPES(TargetEndianness)
MachOInt32 StringIndex;
uint8_t Type; uint8_t Type;
uint8_t SectionIndex; uint8_t SectionIndex;
support::ulittle16_t Flags; MachOInt16 Flags;
}; };
template<bool is64Bits> template<class MachOT>
struct SymbolTableEntry; struct SymbolTableEntry;
template<> template<template<endianness, bool> class MachOT, endianness TargetEndianness,
struct SymbolTableEntry<false> { bool Is64Bits>
support::ulittle32_t StringIndex; struct SymbolTableEntry<MachOT<TargetEndianness, Is64Bits> > {
LLVM_MACHO_IMPORT_TYPES(MachOT, TargetEndianness, Is64Bits)
MachOInt32 StringIndex;
uint8_t Type; uint8_t Type;
uint8_t SectionIndex; uint8_t SectionIndex;
support::ulittle16_t Flags; MachOInt16 Flags;
support::ulittle32_t Value; MachOIntPtr Value;
};
template<>
struct SymbolTableEntry<true> {
support::ulittle32_t StringIndex;
uint8_t Type;
uint8_t SectionIndex;
support::ulittle16_t Flags;
support::ulittle64_t Value;
}; };
template<endianness TargetEndianness>
struct LoadCommand { struct LoadCommand {
support::ulittle32_t Type; LLVM_MACHOB_IMPORT_TYPES(TargetEndianness)
support::ulittle32_t Size; MachOInt32 Type;
MachOInt32 Size;
}; };
template<endianness TargetEndianness>
struct SymtabLoadCommand { struct SymtabLoadCommand {
support::ulittle32_t Type; LLVM_MACHOB_IMPORT_TYPES(TargetEndianness)
support::ulittle32_t Size; MachOInt32 Type;
support::ulittle32_t SymbolTableOffset; MachOInt32 Size;
support::ulittle32_t NumSymbolTableEntries; MachOInt32 SymbolTableOffset;
support::ulittle32_t StringTableOffset; MachOInt32 NumSymbolTableEntries;
support::ulittle32_t StringTableSize; MachOInt32 StringTableOffset;
MachOInt32 StringTableSize;
}; };
template<bool is64Bits> template<class MachOT>
struct SegmentLoadCommand; struct SegmentLoadCommand;
template<> template<template<endianness, bool> class MachOT, endianness TargetEndianness,
struct SegmentLoadCommand<false> { bool Is64Bits>
support::ulittle32_t Type; struct SegmentLoadCommand<MachOT<TargetEndianness, Is64Bits> > {
support::ulittle32_t Size; LLVM_MACHO_IMPORT_TYPES(MachOT, TargetEndianness, Is64Bits)
MachOInt32 Type;
MachOInt32 Size;
char Name[16]; char Name[16];
support::ulittle32_t VMAddress; MachOIntPtr VMAddress;
support::ulittle32_t VMSize; MachOIntPtr VMSize;
support::ulittle32_t FileOffset; MachOIntPtr FileOffset;
support::ulittle32_t FileSize; MachOIntPtr FileSize;
support::ulittle32_t MaxVMProtection; MachOInt32 MaxVMProtection;
support::ulittle32_t InitialVMProtection; MachOInt32 InitialVMProtection;
support::ulittle32_t NumSections; MachOInt32 NumSections;
support::ulittle32_t Flags; MachOInt32 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;
}; };
template<endianness TargetEndianness>
struct LinkeditDataLoadCommand { struct LinkeditDataLoadCommand {
support::ulittle32_t Type; LLVM_MACHOB_IMPORT_TYPES(TargetEndianness)
support::ulittle32_t Size; MachOInt32 Type;
support::ulittle32_t DataOffset; MachOInt32 Size;
support::ulittle32_t DataSize; MachOInt32 DataOffset;
MachOInt32 DataSize;
}; };
template<endianness TargetEndianness>
struct Header { struct Header {
support::ulittle32_t Magic; LLVM_MACHOB_IMPORT_TYPES(TargetEndianness)
support::ulittle32_t CPUType; MachOInt32 Magic;
support::ulittle32_t CPUSubtype; MachOInt32 CPUType;
support::ulittle32_t FileType; MachOInt32 CPUSubtype;
support::ulittle32_t NumLoadCommands; MachOInt32 FileType;
support::ulittle32_t SizeOfLoadCommands; MachOInt32 NumLoadCommands;
support::ulittle32_t Flags; MachOInt32 SizeOfLoadCommands;
MachOInt32 Flags;
}; };
} }
class MachOObjectFileBase : public ObjectFile { class MachOObjectFileBase : public ObjectFile {
public: public:
typedef MachOFormat::SymbolTableEntryBase SymbolTableEntryBase; typedef MachOFormat::SymbolTableEntryBase<support::little>
typedef MachOFormat::SymtabLoadCommand SymtabLoadCommand; SymbolTableEntryBase;
typedef MachOFormat::RelocationEntry RelocationEntry; typedef MachOFormat::SymtabLoadCommand<support::little> SymtabLoadCommand;
typedef MachOFormat::RelocationEntry<support::little> RelocationEntry;
typedef MachOFormat::SectionBase SectionBase; typedef MachOFormat::SectionBase SectionBase;
typedef MachOFormat::LoadCommand LoadCommand; typedef MachOFormat::LoadCommand<support::little> LoadCommand;
typedef MachOFormat::Header Header; typedef MachOFormat::Header<support::little> Header;
typedef MachOFormat::LinkeditDataLoadCommand<support::little>
LinkeditDataLoadCommand;
MachOObjectFileBase(MemoryBuffer *Object, bool Is64Bits, error_code &ec); MachOObjectFileBase(MemoryBuffer *Object, bool Is64Bits, error_code &ec);
@ -253,9 +294,11 @@ private:
template<bool is64Bits> template<bool is64Bits>
struct MachOObjectFileHelperCommon { struct MachOObjectFileHelperCommon {
typedef MachOFormat::SegmentLoadCommand<is64Bits> SegmentLoadCommand; typedef MachOFormat::SegmentLoadCommand<MachOType<support::little, is64Bits> >
typedef MachOFormat::SymbolTableEntry<is64Bits> SymbolTableEntry; SegmentLoadCommand;
typedef MachOFormat::Section<is64Bits> Section; typedef MachOFormat::SymbolTableEntry<MachOType<support::little, is64Bits> >
SymbolTableEntry;
typedef MachOFormat::Section<MachOType<support::little, is64Bits> > Section;
}; };
template<bool is64Bits> template<bool is64Bits>

View File

@ -127,8 +127,8 @@ MachOObjectFileBase::getSymbolTableEntryBase(DataRefImpl DRI,
unsigned Index = DRI.d.b; unsigned Index = DRI.d.b;
unsigned SymbolTableEntrySize = is64Bit() ? unsigned SymbolTableEntrySize = is64Bit() ?
sizeof(MachOFormat::SymbolTableEntry<true>) : sizeof(MachOObjectFile<true>::SymbolTableEntry) :
sizeof(MachOFormat::SymbolTableEntry<false>); sizeof(MachOObjectFile<false>::SymbolTableEntry);
uint64_t Offset = SymbolTableOffset + Index * SymbolTableEntrySize; uint64_t Offset = SymbolTableOffset + Index * SymbolTableEntrySize;
StringRef Data = getData(Offset, SymbolTableEntrySize); StringRef Data = getData(Offset, SymbolTableEntrySize);
@ -314,10 +314,10 @@ MachOObjectFileBase::getSectionBase(DataRefImpl DRI) const {
bool Is64 = is64Bit(); bool Is64 = is64Bit();
unsigned SegmentLoadSize = unsigned SegmentLoadSize =
Is64 ? sizeof(MachOFormat::SegmentLoadCommand<true>) : Is64 ? sizeof(MachOObjectFile<true>::SegmentLoadCommand) :
sizeof(MachOFormat::SegmentLoadCommand<false>); sizeof(MachOObjectFile<false>::SegmentLoadCommand);
unsigned SectionSize = Is64 ? sizeof(MachOFormat::Section<true>) : unsigned SectionSize = Is64 ? sizeof(MachOObjectFile<true>::Section) :
sizeof(MachOFormat::Section<false>); sizeof(MachOObjectFile<false>::Section);
uintptr_t SectionAddr = CommandAddr + SegmentLoadSize + DRI.d.b * SectionSize; uintptr_t SectionAddr = CommandAddr + SegmentLoadSize + DRI.d.b * SectionSize;
return reinterpret_cast<const SectionBase*>(SectionAddr); return reinterpret_cast<const SectionBase*>(SectionAddr);

View File

@ -199,7 +199,7 @@ static void emitDOTFile(const char *FileName, const MCFunction &f,
Out << "}\n"; Out << "}\n";
} }
static void getSectionsAndSymbols(const MachOFormat::Header *Header, static void getSectionsAndSymbols(const MachOObjectFileBase::Header *Header,
MachOObjectFileBase *MachOObj, MachOObjectFileBase *MachOObj,
std::vector<SectionRef> &Sections, std::vector<SectionRef> &Sections,
std::vector<SymbolRef> &Symbols, std::vector<SymbolRef> &Symbols,
@ -218,12 +218,13 @@ static void getSectionsAndSymbols(const MachOFormat::Header *Header,
} }
for (unsigned i = 0; i != Header->NumLoadCommands; ++i) { 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) { if (Command->Type == macho::LCT_FunctionStarts) {
// We found a function starts segment, parse the addresses for later // We found a function starts segment, parse the addresses for later
// consumption. // consumption.
const MachOFormat::LinkeditDataLoadCommand *LLC = const MachOObjectFileBase::LinkeditDataLoadCommand *LLC =
reinterpret_cast<const MachOFormat::LinkeditDataLoadCommand*>(Command); reinterpret_cast<const MachOObjectFileBase::LinkeditDataLoadCommand*>(Command);
MachOObj->ReadULEB128s(LLC->DataOffset, FoundFns); MachOObj->ReadULEB128s(LLC->DataOffset, FoundFns);
} }
@ -269,7 +270,7 @@ void llvm::DisassembleInputMachO(StringRef Filename) {
outs() << '\n' << Filename << ":\n\n"; outs() << '\n' << Filename << ":\n\n";
const MachOFormat::Header *Header = MachOOF->getHeader(); const MachOObjectFileBase::Header *Header = MachOOF->getHeader();
std::vector<SectionRef> Sections; std::vector<SectionRef> Sections;
std::vector<SymbolRef> Symbols; std::vector<SymbolRef> Symbols;