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 
     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
     90 inline 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
    123 inline 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
    130 inline 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
    141 inline 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>
    169 inline 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