• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)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
bswap16(uint16_t pData)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
bswap32(uint32_t pData)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
bswap64(uint64_t pData)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