/* This file is part of Libelfpp. Libelfpp is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Libelfpp is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with Libelfpp. If not, see . Copyright (c) Alexandre Becoulet */ #ifndef ELFPP_ACCESS_HXX_ #define ELFPP_ACCESS_HXX_ #ifdef __linux__ # include #elif defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__APPLE__) # include # define __BYTE_ORDER BYTE_ORDER # define __LITTLE_ENDIAN LITTLE_ENDIAN # define __BIG_ENDIAN BIG_ENDIAN #else # error Unable to guess endianness #endif #if __BYTE_ORDER == __LITTLE_ENDIAN # define SWAPVALUE ELFDATA2MSB #elif __BYTE_ORDER == __BIG_ENDIAN # define SWAPVALUE ELFDATA2LSB #endif namespace elfpp { template unsigned int elfn_access::rel_sym(uint64_t info) { if (width == 32) return info >> 8; else return info >> 32; } template enum reloc_e elfn_access::rel_type(uint64_t info) { if (width == 32) return (enum reloc_e)(info & 0xff); else return (enum reloc_e)(info & 0xffffffff); } template uint64_t elfn_access::rel_info(unsigned int sym, enum reloc_e type) { if (width == 32) return (sym << 8) | (type & 0xff); else return ((uint64_t)sym << 32) | type; } template uint16_t elfn_access::swap(uint16_t x) { if (byteorder_ == SWAPVALUE) return (x << 8) | (x >> 8); return x; } template int16_t elfn_access::swap(int16_t x) { return swap((uint16_t)x); } template uint32_t elfn_access::swap(uint32_t x) { if (byteorder_ == SWAPVALUE) return (((x >> 24) & 0x000000ff) | ((x >> 8 ) & 0x0000ff00) | ((x << 8 ) & 0x00ff0000) | ((x << 24) & 0xff000000)); return x; } template int32_t elfn_access::swap(int32_t x) { return swap((uint32_t)x); } template uint64_t elfn_access::swap(uint64_t x) { if (byteorder_ == SWAPVALUE) return (((x >> 56) & 0x00000000000000ffLL) | ((x >> 40) & 0x000000000000ff00LL) | ((x >> 24) & 0x0000000000ff0000LL) | ((x >> 8) & 0x00000000ff000000LL) | ((x << 8) & 0x000000ff00000000LL) | ((x << 24) & 0x0000ff0000000000LL) | ((x << 40) & 0x00ff000000000000LL) | ((x << 56) & 0xff00000000000000LL)); return x; } template int64_t elfn_access::swap(int64_t x) { return swap((uint64_t)x); } template template void elfn_access::swap(X *a, Y x) { *a = swap((X)x); } } #endif