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