1//===- SizeTraits.h -------------------------------------------------------===// 2// 3// The MCLinker Project 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9#ifndef MCLD_SIZE_TRAITS_H 10#define MCLD_SIZE_TRAITS_H 11#ifdef ENABLE_UNITTEST 12#include <gtest.h> 13#endif 14 15#include <llvm/Support/DataTypes.h> 16#include <llvm/Support/ELF.h> 17 18namespace mcld 19{ 20 21template<size_t SIZE> 22class SizeTraits; 23 24template<> 25class SizeTraits<32> 26{ 27public: 28 typedef uint32_t Address; 29 typedef uint32_t Offset; 30 typedef uint32_t Word; 31 typedef int32_t SWord; 32}; 33 34template<> 35class SizeTraits<64> 36{ 37public: 38 typedef uint64_t Address; 39 typedef uint64_t Offset; 40 typedef uint64_t Word; 41 typedef int64_t SWord; 42}; 43 44// FIXME: move this to mcld internal ELF header file? 45template<size_t SIZE> 46class ELFSizeTraits; 47 48template<> 49class ELFSizeTraits<32> 50{ 51public: 52 typedef llvm::ELF::Elf32_Addr Addr; // Program address 53 typedef llvm::ELF::Elf32_Off Off; // File offset 54 typedef llvm::ELF::Elf32_Half Half; 55 typedef llvm::ELF::Elf32_Word Word; 56 typedef llvm::ELF::Elf32_Sword Sword; 57 58 typedef llvm::ELF::Elf32_Ehdr Ehdr; 59 typedef llvm::ELF::Elf32_Shdr Shdr; 60 typedef llvm::ELF::Elf32_Sym Sym; 61 typedef llvm::ELF::Elf32_Rel Rel; 62 typedef llvm::ELF::Elf32_Rela Rela; 63 typedef llvm::ELF::Elf32_Phdr Phdr; 64 typedef llvm::ELF::Elf32_Dyn Dyn; 65}; 66 67template<> 68class ELFSizeTraits<64> 69{ 70public: 71 typedef llvm::ELF::Elf64_Addr Addr; 72 typedef llvm::ELF::Elf64_Off Off; 73 typedef llvm::ELF::Elf64_Half Half; 74 typedef llvm::ELF::Elf64_Word Word; 75 typedef llvm::ELF::Elf64_Sword Sword; 76 typedef llvm::ELF::Elf64_Xword Xword; 77 typedef llvm::ELF::Elf64_Sxword Sxword; 78 79 typedef llvm::ELF::Elf64_Ehdr Ehdr; 80 typedef llvm::ELF::Elf64_Shdr Shdr; 81 typedef llvm::ELF::Elf64_Sym Sym; 82 typedef llvm::ELF::Elf64_Rel Rel; 83 typedef llvm::ELF::Elf64_Rela Rela; 84 typedef llvm::ELF::Elf64_Phdr Phdr; 85 typedef llvm::ELF::Elf64_Dyn Dyn; 86}; 87 88/// alignAddress - helper function to align an address with given alignment 89/// constraint 90/// 91/// @param pAddr - the address to be aligned 92/// @param pAlignConstraint - the alignment used to align the given address 93inline void alignAddress(uint64_t& pAddr, uint64_t pAlignConstraint) 94{ 95 if (pAlignConstraint != 0) 96 pAddr = (pAddr + pAlignConstraint - 1) &~ (pAlignConstraint - 1); 97} 98 99template<size_t Constraint> 100uint64_t Align(uint64_t pAddress); 101 102template<> 103inline uint64_t Align<32>(uint64_t pAddress) 104{ 105 return (pAddress + 0x1F) & (~0x1F); 106} 107 108template<> 109inline uint64_t Align<64>(uint64_t pAddress) 110{ 111 return (pAddress + 0x3F) & (~0x3F); 112} 113 114#ifdef bswap16 115#undef bswap16 116#endif 117#ifdef bswap32 118#undef bswap32 119#endif 120#ifdef bswap64 121#undef bswap64 122#endif 123 124/// bswap16 - byte swap 16-bit version 125/// @ref binary utilities - elfcpp_swap 126inline uint16_t bswap16(uint16_t pData) 127{ 128 return ((pData >> 8) & 0xFF) | ((pData & 0xFF) << 8); 129} 130 131/// bswap32 - byte swap 32-bit version 132/// @ref elfcpp_swap 133inline uint32_t bswap32(uint32_t pData) 134{ 135 return (((pData & 0xFF000000) >> 24) | 136 ((pData & 0x00FF0000) >> 8) | 137 ((pData & 0x0000FF00) << 8) | 138 ((pData & 0x000000FF) << 24)); 139 140} 141 142/// bswap64 - byte swap 64-bit version 143/// @ref binary utilities - elfcpp_swap 144inline uint64_t bswap64(uint64_t pData) 145{ 146 return (((pData & 0xFF00000000000000ULL) >> 56) | 147 ((pData & 0x00FF000000000000ULL) >> 40) | 148 ((pData & 0x0000FF0000000000ULL) >> 24) | 149 ((pData & 0x000000FF00000000ULL) >> 8) | 150 ((pData & 0x00000000FF000000ULL) << 8) | 151 ((pData & 0x0000000000FF0000ULL) << 24) | 152 ((pData & 0x000000000000FF00ULL) << 40) | 153 ((pData & 0x00000000000000FFULL) << 56)); 154} 155 156template <size_t SizeOfStr, typename FieldType> 157class StringSizerHelper 158{ 159private: 160 char FIELD_TOO_SMALL[SizeOfStr <= FieldType(~0U) ? 1 : -1]; 161public: 162 enum { Size = SizeOfStr }; 163}; 164 165#define STR_SIZE(str, fieldTy) StringSizerHelper<sizeof(str)-1, fieldTy>::Size 166 167} // namespace of mcld 168 169#endif 170 171