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