15460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===- SizeTraits.h -------------------------------------------------------===//
25460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
35460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//                     The MCLinker Project
45460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
55460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// This file is distributed under the University of Illinois Open Source
65460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// License. See LICENSE.TXT for details.
75460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
85460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===//
937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#ifndef MCLD_ADT_SIZETRAITS_H_
1037b74a387bb3993387029859c2d9d051c41c724eStephen Hines#define MCLD_ADT_SIZETRAITS_H_
115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <llvm/Support/DataTypes.h>
136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <llvm/Support/ELF.h>
145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesnamespace mcld {
165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1737b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <size_t SIZE>
18affc150dc44fab1911775a49636d0ce85333b634Zonr Changclass SizeTraits;
195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2037b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <>
2137b74a387bb3993387029859c2d9d051c41c724eStephen Hinesclass SizeTraits<32> {
2237b74a387bb3993387029859c2d9d051c41c724eStephen Hines public:
235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  typedef uint32_t Address;
245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  typedef uint32_t Offset;
255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  typedef uint32_t Word;
2637b74a387bb3993387029859c2d9d051c41c724eStephen Hines  typedef int32_t SWord;
275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao};
285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2937b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <>
3037b74a387bb3993387029859c2d9d051c41c724eStephen Hinesclass SizeTraits<64> {
3137b74a387bb3993387029859c2d9d051c41c724eStephen Hines public:
325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  typedef uint64_t Address;
335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  typedef uint64_t Offset;
345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  typedef uint64_t Word;
3537b74a387bb3993387029859c2d9d051c41c724eStephen Hines  typedef int64_t SWord;
365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao};
375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// FIXME: move this to mcld internal ELF header file?
3937b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <size_t SIZE>
406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesclass ELFSizeTraits;
416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
4237b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <>
4337b74a387bb3993387029859c2d9d051c41c724eStephen Hinesclass ELFSizeTraits<32> {
4437b74a387bb3993387029859c2d9d051c41c724eStephen Hines public:
4537b74a387bb3993387029859c2d9d051c41c724eStephen Hines  typedef llvm::ELF::Elf32_Addr Addr;  // Program address
4637b74a387bb3993387029859c2d9d051c41c724eStephen Hines  typedef llvm::ELF::Elf32_Off Off;    // File offset
4737b74a387bb3993387029859c2d9d051c41c724eStephen Hines  typedef llvm::ELF::Elf32_Half Half;
4837b74a387bb3993387029859c2d9d051c41c724eStephen Hines  typedef llvm::ELF::Elf32_Word Word;
496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  typedef llvm::ELF::Elf32_Sword Sword;
506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
5137b74a387bb3993387029859c2d9d051c41c724eStephen Hines  typedef llvm::ELF::Elf32_Ehdr Ehdr;
5237b74a387bb3993387029859c2d9d051c41c724eStephen Hines  typedef llvm::ELF::Elf32_Shdr Shdr;
5337b74a387bb3993387029859c2d9d051c41c724eStephen Hines  typedef llvm::ELF::Elf32_Sym Sym;
5437b74a387bb3993387029859c2d9d051c41c724eStephen Hines  typedef llvm::ELF::Elf32_Rel Rel;
5537b74a387bb3993387029859c2d9d051c41c724eStephen Hines  typedef llvm::ELF::Elf32_Rela Rela;
5637b74a387bb3993387029859c2d9d051c41c724eStephen Hines  typedef llvm::ELF::Elf32_Phdr Phdr;
5737b74a387bb3993387029859c2d9d051c41c724eStephen Hines  typedef llvm::ELF::Elf32_Dyn Dyn;
586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines};
596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
6037b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <>
6137b74a387bb3993387029859c2d9d051c41c724eStephen Hinesclass ELFSizeTraits<64> {
6237b74a387bb3993387029859c2d9d051c41c724eStephen Hines public:
6337b74a387bb3993387029859c2d9d051c41c724eStephen Hines  typedef llvm::ELF::Elf64_Addr Addr;
6437b74a387bb3993387029859c2d9d051c41c724eStephen Hines  typedef llvm::ELF::Elf64_Off Off;
6537b74a387bb3993387029859c2d9d051c41c724eStephen Hines  typedef llvm::ELF::Elf64_Half Half;
6637b74a387bb3993387029859c2d9d051c41c724eStephen Hines  typedef llvm::ELF::Elf64_Word Word;
6737b74a387bb3993387029859c2d9d051c41c724eStephen Hines  typedef llvm::ELF::Elf64_Sword Sword;
6837b74a387bb3993387029859c2d9d051c41c724eStephen Hines  typedef llvm::ELF::Elf64_Xword Xword;
696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  typedef llvm::ELF::Elf64_Sxword Sxword;
706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
7137b74a387bb3993387029859c2d9d051c41c724eStephen Hines  typedef llvm::ELF::Elf64_Ehdr Ehdr;
7237b74a387bb3993387029859c2d9d051c41c724eStephen Hines  typedef llvm::ELF::Elf64_Shdr Shdr;
7337b74a387bb3993387029859c2d9d051c41c724eStephen Hines  typedef llvm::ELF::Elf64_Sym Sym;
7437b74a387bb3993387029859c2d9d051c41c724eStephen Hines  typedef llvm::ELF::Elf64_Rel Rel;
7537b74a387bb3993387029859c2d9d051c41c724eStephen Hines  typedef llvm::ELF::Elf64_Rela Rela;
7637b74a387bb3993387029859c2d9d051c41c724eStephen Hines  typedef llvm::ELF::Elf64_Phdr Phdr;
7737b74a387bb3993387029859c2d9d051c41c724eStephen Hines  typedef llvm::ELF::Elf64_Dyn Dyn;
786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines};
796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// alignAddress - helper function to align an address with given alignment
815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// constraint
825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao///
835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// @param pAddr - the address to be aligned
845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// @param pAlignConstraint - the alignment used to align the given address
8537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesinline void alignAddress(uint64_t& pAddr, uint64_t pAlignConstraint) {
865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pAlignConstraint != 0)
8737b74a387bb3993387029859c2d9d051c41c724eStephen Hines    pAddr = (pAddr + pAlignConstraint - 1) & ~(pAlignConstraint - 1);
885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
9037b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <size_t Constraint>
915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t Align(uint64_t pAddress);
925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
9337b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <>
9437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesinline uint64_t Align<32>(uint64_t pAddress) {
955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return (pAddress + 0x1F) & (~0x1F);
965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
9837b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <>
9937b74a387bb3993387029859c2d9d051c41c724eStephen Hinesinline uint64_t Align<64>(uint64_t pAddress) {
1005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return (pAddress + 0x3F) & (~0x3F);
1015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
103d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#ifdef bswap16
104d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#undef bswap16
105d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#endif
106d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#ifdef bswap32
107d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#undef bswap32
108d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#endif
109d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#ifdef bswap64
110d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#undef bswap64
111d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#endif
112d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
1135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// bswap16 - byte swap 16-bit version
1145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// @ref binary utilities - elfcpp_swap
11537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesinline uint16_t bswap16(uint16_t pData) {
11637b74a387bb3993387029859c2d9d051c41c724eStephen Hines  return ((pData >> 8) & 0xFF) | ((pData & 0xFF) << 8);
1175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// bswap32 - byte swap 32-bit version
1205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// @ref elfcpp_swap
12137b74a387bb3993387029859c2d9d051c41c724eStephen Hinesinline uint32_t bswap32(uint32_t pData) {
12237b74a387bb3993387029859c2d9d051c41c724eStephen Hines  return (((pData & 0xFF000000) >> 24) | ((pData & 0x00FF0000) >> 8) |
12337b74a387bb3993387029859c2d9d051c41c724eStephen Hines          ((pData & 0x0000FF00) << 8) | ((pData & 0x000000FF) << 24));
1245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// bswap64 - byte swap 64-bit version
1275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// @ref binary utilities - elfcpp_swap
12837b74a387bb3993387029859c2d9d051c41c724eStephen Hinesinline uint64_t bswap64(uint64_t pData) {
12937b74a387bb3993387029859c2d9d051c41c724eStephen Hines  return (((pData & 0xFF00000000000000ULL) >> 56) |
13037b74a387bb3993387029859c2d9d051c41c724eStephen Hines          ((pData & 0x00FF000000000000ULL) >> 40) |
13137b74a387bb3993387029859c2d9d051c41c724eStephen Hines          ((pData & 0x0000FF0000000000ULL) >> 24) |
13237b74a387bb3993387029859c2d9d051c41c724eStephen Hines          ((pData & 0x000000FF00000000ULL) >> 8) |
13337b74a387bb3993387029859c2d9d051c41c724eStephen Hines          ((pData & 0x00000000FF000000ULL) << 8) |
13437b74a387bb3993387029859c2d9d051c41c724eStephen Hines          ((pData & 0x0000000000FF0000ULL) << 24) |
13537b74a387bb3993387029859c2d9d051c41c724eStephen Hines          ((pData & 0x000000000000FF00ULL) << 40) |
13637b74a387bb3993387029859c2d9d051c41c724eStephen Hines          ((pData & 0x00000000000000FFULL) << 56));
1375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
13937b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <size_t SIZE>
14087f34658dec9097d987d254a990ea7f311bfc95fStephen Hinestypename SizeTraits<SIZE>::Word bswap(typename SizeTraits<SIZE>::Word pData);
14187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
14237b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <>
14337b74a387bb3993387029859c2d9d051c41c724eStephen Hinesinline SizeTraits<32>::Word bswap<32>(SizeTraits<32>::Word pData) {
14487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  return bswap32(pData);
14587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
14687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
14737b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <>
14837b74a387bb3993387029859c2d9d051c41c724eStephen Hinesinline SizeTraits<64>::Word bswap<64>(SizeTraits<64>::Word pData) {
14987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  return bswap64(pData);
15087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
15187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
15287f34658dec9097d987d254a990ea7f311bfc95fStephen Hinestemplate <size_t WIDTH>
15337b74a387bb3993387029859c2d9d051c41c724eStephen Hinesinline uint64_t signExtend(uint64_t pVal) {
15487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  uint64_t mask = (~((uint64_t)0)) >> (64 - WIDTH);
15587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  uint64_t sign_bit = 1 << (WIDTH - 1);
15687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
15787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  return ((pVal & mask) ^ sign_bit) - sign_bit;
15887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
15987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
16087f34658dec9097d987d254a990ea7f311bfc95fStephen Hinestemplate <>
16137b74a387bb3993387029859c2d9d051c41c724eStephen Hinesinline uint64_t signExtend<64>(uint64_t pVal) {
16287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  return pVal;
16387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines}
16487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
165affc150dc44fab1911775a49636d0ce85333b634Zonr Changtemplate <size_t SizeOfStr, typename FieldType>
16637b74a387bb3993387029859c2d9d051c41c724eStephen Hinesclass StringSizerHelper {
16737b74a387bb3993387029859c2d9d051c41c724eStephen Hines private:
168affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  char FIELD_TOO_SMALL[SizeOfStr <= FieldType(~0U) ? 1 : -1];
16937b74a387bb3993387029859c2d9d051c41c724eStephen Hines
17037b74a387bb3993387029859c2d9d051c41c724eStephen Hines public:
171affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  enum { Size = SizeOfStr };
172affc150dc44fab1911775a49636d0ce85333b634Zonr Chang};
173affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
17437b74a387bb3993387029859c2d9d051c41c724eStephen Hines#define STR_SIZE(str, fieldTy) StringSizerHelper<sizeof(str) - 1, fieldTy>::Size
1755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
17637b74a387bb3993387029859c2d9d051c41c724eStephen Hines}  // namespace mcld
177affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
17837b74a387bb3993387029859c2d9d051c41c724eStephen Hines#endif  // MCLD_ADT_SIZETRAITS_H_
179