Home | History | Annotate | Download | only in ADT
      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
     85 inline 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
    115 inline 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
    121 inline 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
    128 inline 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>
    153 inline 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