//===- SizeTraits.h -------------------------------------------------------===// // // The MCLinker Project // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #ifndef MCLD_ADT_SIZETRAITS_H_ #define MCLD_ADT_SIZETRAITS_H_ #include #include namespace mcld { template class SizeTraits; template <> class SizeTraits<32> { public: typedef uint32_t Address; typedef uint32_t Offset; typedef uint32_t Word; typedef int32_t SWord; }; template <> class SizeTraits<64> { public: typedef uint64_t Address; typedef uint64_t Offset; typedef uint64_t Word; typedef int64_t SWord; }; // FIXME: move this to mcld internal ELF header file? template class ELFSizeTraits; template <> class ELFSizeTraits<32> { public: typedef llvm::ELF::Elf32_Addr Addr; // Program address typedef llvm::ELF::Elf32_Off Off; // File offset typedef llvm::ELF::Elf32_Half Half; typedef llvm::ELF::Elf32_Word Word; typedef llvm::ELF::Elf32_Sword Sword; typedef llvm::ELF::Elf32_Ehdr Ehdr; typedef llvm::ELF::Elf32_Shdr Shdr; typedef llvm::ELF::Elf32_Sym Sym; typedef llvm::ELF::Elf32_Rel Rel; typedef llvm::ELF::Elf32_Rela Rela; typedef llvm::ELF::Elf32_Phdr Phdr; typedef llvm::ELF::Elf32_Dyn Dyn; }; template <> class ELFSizeTraits<64> { public: typedef llvm::ELF::Elf64_Addr Addr; typedef llvm::ELF::Elf64_Off Off; typedef llvm::ELF::Elf64_Half Half; typedef llvm::ELF::Elf64_Word Word; typedef llvm::ELF::Elf64_Sword Sword; typedef llvm::ELF::Elf64_Xword Xword; typedef llvm::ELF::Elf64_Sxword Sxword; typedef llvm::ELF::Elf64_Ehdr Ehdr; typedef llvm::ELF::Elf64_Shdr Shdr; typedef llvm::ELF::Elf64_Sym Sym; typedef llvm::ELF::Elf64_Rel Rel; typedef llvm::ELF::Elf64_Rela Rela; typedef llvm::ELF::Elf64_Phdr Phdr; typedef llvm::ELF::Elf64_Dyn Dyn; }; /// alignAddress - helper function to align an address with given alignment /// constraint /// /// @param pAddr - the address to be aligned /// @param pAlignConstraint - the alignment used to align the given address inline void alignAddress(uint64_t& pAddr, uint64_t pAlignConstraint) { if (pAlignConstraint != 0) pAddr = (pAddr + pAlignConstraint - 1) & ~(pAlignConstraint - 1); } template uint64_t Align(uint64_t pAddress); template <> inline uint64_t Align<32>(uint64_t pAddress) { return (pAddress + 0x1F) & (~0x1F); } template <> inline uint64_t Align<64>(uint64_t pAddress) { return (pAddress + 0x3F) & (~0x3F); } #ifdef bswap16 #undef bswap16 #endif #ifdef bswap32 #undef bswap32 #endif #ifdef bswap64 #undef bswap64 #endif /// bswap16 - byte swap 16-bit version /// @ref binary utilities - elfcpp_swap inline uint16_t bswap16(uint16_t pData) { return ((pData >> 8) & 0xFF) | ((pData & 0xFF) << 8); } /// bswap32 - byte swap 32-bit version /// @ref elfcpp_swap inline uint32_t bswap32(uint32_t pData) { return (((pData & 0xFF000000) >> 24) | ((pData & 0x00FF0000) >> 8) | ((pData & 0x0000FF00) << 8) | ((pData & 0x000000FF) << 24)); } /// bswap64 - byte swap 64-bit version /// @ref binary utilities - elfcpp_swap inline uint64_t bswap64(uint64_t pData) { return (((pData & 0xFF00000000000000ULL) >> 56) | ((pData & 0x00FF000000000000ULL) >> 40) | ((pData & 0x0000FF0000000000ULL) >> 24) | ((pData & 0x000000FF00000000ULL) >> 8) | ((pData & 0x00000000FF000000ULL) << 8) | ((pData & 0x0000000000FF0000ULL) << 24) | ((pData & 0x000000000000FF00ULL) << 40) | ((pData & 0x00000000000000FFULL) << 56)); } template typename SizeTraits::Word bswap(typename SizeTraits::Word pData); template <> inline SizeTraits<32>::Word bswap<32>(SizeTraits<32>::Word pData) { return bswap32(pData); } template <> inline SizeTraits<64>::Word bswap<64>(SizeTraits<64>::Word pData) { return bswap64(pData); } template inline uint64_t signExtend(uint64_t pVal) { uint64_t mask = (~((uint64_t)0)) >> (64 - WIDTH); uint64_t sign_bit = 1 << (WIDTH - 1); return ((pVal & mask) ^ sign_bit) - sign_bit; } template <> inline uint64_t signExtend<64>(uint64_t pVal) { return pVal; } template class StringSizerHelper { private: char FIELD_TOO_SMALL[SizeOfStr <= FieldType(~0U) ? 1 : -1]; public: enum { Size = SizeOfStr }; }; #define STR_SIZE(str, fieldTy) StringSizerHelper::Size } // namespace mcld #endif // MCLD_ADT_SIZETRAITS_H_