summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2013-04-10 03:48:25 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2013-04-10 03:48:25 +0000
commita2561a0153237291980722383f409a6499b12efc (patch)
tree4626dff1b1c7fb3b694c460de6c22692c535ad45
parent774e7c82a84189a1f8194a63dc8040136ca6b4d8 (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.h239
-rw-r--r--lib/Object/MachOObjectFile.cpp12
-rw-r--r--tools/llvm-objdump/MachODump.cpp11
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;