SizeTraits.h revision 87f34658dec9097d987d254a990ea7f311bfc95f
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#ifdef ENABLE_UNITTEST
12#include <gtest.h>
13#endif
14
15#include <llvm/Support/DataTypes.h>
16#include <llvm/Support/ELF.h>
17
18namespace mcld
19{
20
21template<size_t SIZE>
22class SizeTraits;
23
24template<>
25class SizeTraits<32>
26{
27public:
28  typedef uint32_t Address;
29  typedef uint32_t Offset;
30  typedef uint32_t Word;
31  typedef int32_t  SWord;
32};
33
34template<>
35class SizeTraits<64>
36{
37public:
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?
45template<size_t SIZE>
46class ELFSizeTraits;
47
48template<>
49class ELFSizeTraits<32>
50{
51public:
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
67template<>
68class ELFSizeTraits<64>
69{
70public:
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
93inline void alignAddress(uint64_t& pAddr, uint64_t pAlignConstraint)
94{
95  if (pAlignConstraint != 0)
96    pAddr = (pAddr + pAlignConstraint - 1) &~ (pAlignConstraint - 1);
97}
98
99template<size_t Constraint>
100uint64_t Align(uint64_t pAddress);
101
102template<>
103inline uint64_t Align<32>(uint64_t pAddress)
104{
105  return (pAddress + 0x1F) & (~0x1F);
106}
107
108template<>
109inline 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
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
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
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
156template<size_t SIZE>
157typename SizeTraits<SIZE>::Word bswap(typename SizeTraits<SIZE>::Word pData);
158
159template<>
160inline SizeTraits<32>::Word bswap<32>(SizeTraits<32>::Word pData)
161{
162  return bswap32(pData);
163}
164
165template<>
166inline SizeTraits<64>::Word bswap<64>(SizeTraits<64>::Word pData)
167{
168  return bswap64(pData);
169}
170
171template <size_t WIDTH>
172inline uint64_t signExtend(uint64_t pVal)
173{
174  uint64_t mask = (~((uint64_t)0)) >> (64 - WIDTH);
175  uint64_t sign_bit = 1 << (WIDTH - 1);
176
177  return ((pVal & mask) ^ sign_bit) - sign_bit;
178}
179
180template <>
181inline uint64_t signExtend<64>(uint64_t pVal)
182{
183  return pVal;
184}
185
186template <size_t SizeOfStr, typename FieldType>
187class StringSizerHelper
188{
189private:
190  char FIELD_TOO_SMALL[SizeOfStr <= FieldType(~0U) ? 1 : -1];
191public:
192  enum { Size = SizeOfStr };
193};
194
195#define STR_SIZE(str, fieldTy) StringSizerHelper<sizeof(str)-1, fieldTy>::Size
196
197} // namespace of mcld
198
199#endif
200
201