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_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
     93 inline 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
    126 inline 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
    133 inline 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
    144 inline 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