X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=elfcpp%2Felfcpp_swap.h;h=4ccb48e289951271c28b169310ec1cc957346fd9;hb=3ee0cd9e55368d162aea19a42369f3ee2a1356f3;hp=06852761588f8d8d345d919187563e174d7d5bba;hpb=15d5fa160781daaf2e5c2b1d130f996a502016ea;p=binutils-gdb.git diff --git a/elfcpp/elfcpp_swap.h b/elfcpp/elfcpp_swap.h index 06852761588..4ccb48e2899 100644 --- a/elfcpp/elfcpp_swap.h +++ b/elfcpp/elfcpp_swap.h @@ -1,6 +1,6 @@ // elfcpp_swap.h -- Handle swapping for elfcpp -*- C++ -*- -// Copyright 2006, 2007, 2008, 2009 Free Software Foundation, Inc. +// Copyright (C) 2006-2021 Free Software Foundation, Inc. // Written by Ian Lance Taylor . // This file is part of elfcpp. @@ -46,15 +46,19 @@ #ifdef HAVE_BYTESWAP_H #include -#else +#endif // defined(HAVE_BYTESWAP_H) + // Provide our own versions of the byteswap functions. -inline uint16_t +#if !HAVE_DECL_BSWAP_16 +static inline uint16_t bswap_16(uint16_t v) { return ((v >> 8) & 0xff) | ((v & 0xff) << 8); } +#endif // !HAVE_DECL_BSWAP16 -inline uint32_t +#if !HAVE_DECL_BSWAP_32 +static inline uint32_t bswap_32(uint32_t v) { return ( ((v & 0xff000000) >> 24) @@ -62,8 +66,10 @@ bswap_32(uint32_t v) | ((v & 0x0000ff00) << 8) | ((v & 0x000000ff) << 24)); } +#endif // !HAVE_DECL_BSWAP32 -inline uint64_t +#if !HAVE_DECL_BSWAP_64 +static inline uint64_t bswap_64(uint64_t v) { return ( ((v & 0xff00000000000000ULL) >> 56) @@ -75,7 +81,7 @@ bswap_64(uint64_t v) | ((v & 0x000000000000ff00ULL) << 40) | ((v & 0x00000000000000ffULL) << 56)); } -#endif // !defined(HAVE_BYTESWAP_H) +#endif // !HAVE_DECL_BSWAP64 // gcc 4.3 and later provides __builtin_bswap32 and __builtin_bswap64. @@ -430,6 +436,71 @@ struct Swap_unaligned<64, true> } }; +// Swap_aligned32 is a template based on size and on whether the +// target is big endian. It defines the type Valtype and the +// functions readval and writeval. The functions read and write +// values of the appropriate size out of buffers which may not be +// 64-bit aligned, but are 32-bit aligned. + +template +struct Swap_aligned32 +{ + typedef typename Valtype_base::Valtype Valtype; + + static inline Valtype + readval(const unsigned char* wv) + { return Swap::readval( + reinterpret_cast(wv)); } + + static inline void + writeval(unsigned char* wv, Valtype v) + { Swap::writeval(reinterpret_cast(wv), v); } +}; + +template<> +struct Swap_aligned32<64, true> +{ + typedef Valtype_base<64>::Valtype Valtype; + + static inline Valtype + readval(const unsigned char* wv) + { + return ((static_cast(Swap<32, true>::readval(wv)) << 32) + | static_cast(Swap<32, true>::readval(wv + 4))); + } + + static inline void + writeval(unsigned char* wv, Valtype v) + { + typedef Valtype_base<32>::Valtype Valtype32; + + Swap<32, true>::writeval(wv, static_cast(v >> 32)); + Swap<32, true>::writeval(wv + 4, static_cast(v)); + } +}; + +template<> +struct Swap_aligned32<64, false> +{ + typedef Valtype_base<64>::Valtype Valtype; + + static inline Valtype + readval(const unsigned char* wv) + { + return ((static_cast(Swap<32, false>::readval(wv + 4)) << 32) + | static_cast(Swap<32, false>::readval(wv))); + } + + static inline void + writeval(unsigned char* wv, Valtype v) + { + typedef Valtype_base<32>::Valtype Valtype32; + + Swap<32, false>::writeval(wv + 4, static_cast(v >> 32)); + Swap<32, false>::writeval(wv, static_cast(v)); + } +}; + } // End namespace elfcpp. #endif // !defined(ELFCPP_SWAP_H)