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 18 namespace mcld 19 { 20 21 template<size_t SIZE> 22 class SizeTraits; 23 24 template<> 25 class SizeTraits<32> 26 { 27 public: 28 typedef uint32_t Address; 29 typedef uint32_t Offset; 30 typedef uint32_t Word; 31 typedef int32_t SWord; 32 }; 33 34 template<> 35 class SizeTraits<64> 36 { 37 public: 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? 45 template<size_t SIZE> 46 class ELFSizeTraits; 47 48 template<> 49 class ELFSizeTraits<32> 50 { 51 public: 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 67 template<> 68 class ELFSizeTraits<64> 69 { 70 public: 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 alignAddress(uint64_t & pAddr,uint64_t pAlignConstraint)93inline void alignAddress(uint64_t& pAddr, uint64_t pAlignConstraint) 94 { 95 if (pAlignConstraint != 0) 96 pAddr = (pAddr + pAlignConstraint - 1) &~ (pAlignConstraint - 1); 97 } 98 99 template<size_t Constraint> 100 uint64_t Align(uint64_t pAddress); 101 102 template<> 103 inline uint64_t Align<32>(uint64_t pAddress) 104 { 105 return (pAddress + 0x1F) & (~0x1F); 106 } 107 108 template<> 109 inline 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 bswap16(uint16_t pData)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 bswap32(uint32_t pData)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 bswap64(uint64_t pData)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 156 template <size_t SizeOfStr, typename FieldType> 157 class StringSizerHelper 158 { 159 private: 160 char FIELD_TOO_SMALL[SizeOfStr <= FieldType(~0U) ? 1 : -1]; 161 public: 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