| /* Copyright (C) 2007-2010 The Android Open Source Project |
| ** |
| ** This software is licensed under the terms of the GNU General Public |
| ** License version 2, as published by the Free Software Foundation, and |
| ** may be copied, distributed, and modified under those terms. |
| ** |
| ** This program 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. |
| */ |
| |
| /* |
| * Contains some helpful macros, and inline routines. |
| */ |
| |
| #ifndef ELFF_ELF_DEFS_H_ |
| #define ELFF_ELF_DEFS_H_ |
| |
| #include "elff_elf.h" |
| |
| //============================================================================= |
| // Macros. |
| //============================================================================= |
| |
| /* Increments a pointer by n bytes. |
| * Param: |
| * p - Pointer to increment. |
| * n - Number of bytes to increment the pointer with. |
| */ |
| #define INC_PTR(p, n) (reinterpret_cast<uint8_t*>(p) + (n)) |
| |
| /* Increments a constant pointer by n bytes. |
| * Param: |
| * p - Pointer to increment. |
| * n - Number of bytes to increment the pointer with. |
| */ |
| #define INC_CPTR(p, n) (reinterpret_cast<const uint8_t*>(p) + (n)) |
| |
| /* Increments a pointer of a given type by n bytes. |
| * Param: |
| * T - Pointer type |
| * p - Pointer to increment. |
| * n - Number of bytes to increment the pointer with. |
| */ |
| #define INC_PTR_T(T, p, n) \ |
| reinterpret_cast<T*> \ |
| (reinterpret_cast<uint8_t*>(p) + (n)) |
| |
| /* Increments a constant pointer of a given type by n bytes. |
| * Param: |
| * T - Pointer type |
| * p - Pointer to increment. |
| * n - Number of bytes to increment the pointer with. |
| */ |
| #define INC_CPTR_T(T, p, n) \ |
| reinterpret_cast<const T*> \ |
| (reinterpret_cast<const uint8_t*>(p) + (n)) |
| |
| /* Calculates number of entries in a static array. |
| * Param: |
| * a - Array. |
| * Return: |
| * Number of entries in the array. |
| */ |
| #define ELFF_ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a))) |
| |
| /* Calculates offset of a field inside a structure (or a class) of the |
| * given type. |
| * Param: |
| * T - Structure (or class) type. |
| * f - Name of a field (member variable) for this structure (or class). |
| */ |
| #define ELFF_FIELD_OFFSET(T, f) ((size_t)(size_t*)&(((T *)0)->f)) |
| |
| //============================================================================= |
| // Inline routines. |
| //============================================================================= |
| |
| /* Calculates byte interval between two pointers. |
| * Param: |
| * s - Starting pointer of the interval. Must be less, or equal to 'e'. |
| * e - Ending pointer of the interval. Must be greater, or equal to 's'. |
| * Return: |
| * Byte interval between two pointers. |
| */ |
| static inline size_t |
| diff_ptr(const void* s, const void* e) { |
| assert(s <= e); |
| return ((size_t)(reinterpret_cast<const uint8_t*>(e) - |
| reinterpret_cast<const uint8_t*>(s))); |
| } |
| |
| /* Gets one byte from an index inside a memory block. |
| * Param: |
| * ptr - Address of the beginning of the memory block. |
| * bt - Index of a byte inside the block to get. |
| * Return: |
| * A byte at the given index inside the given memory block. |
| */ |
| static inline uint8_t |
| get_byte(const void* ptr, uint32_t bt) { |
| return *(reinterpret_cast<const uint8_t*>(ptr) + bt); |
| } |
| |
| /* Checks if given address range is fully contained within a section. |
| * Param: |
| * rp - Beginning of the range to check. |
| * rsize - Size of the range to check. |
| * ss - Beginning of the section that should contain the checking range. |
| * ssize - Size of the section that should contain the checking range. |
| * Return: |
| * true, if given address range is fully contained within a section, or |
| * false, if any part of the address range is not contained in the secton. |
| */ |
| static inline bool |
| is_in_section(const void* rp, size_t rsize, const void* ss, size_t ssize) { |
| const void* rend = INC_CPTR(rp, rsize); |
| /* We also make sure here that increment didn't overflow the pointer. */ |
| return rp >= ss && ss != NULL && (diff_ptr(ss, rend) <= ssize) && rend >= rp; |
| } |
| |
| /* Checks if this code runs on CPU with a little-endian data format. |
| * Return: |
| * true, if this code runs on CPU with a little-endian data format, |
| * or false, if this code runs on CPU with a big-endian data format. |
| */ |
| static inline bool |
| is_little_endian_cpu(void) { |
| uint16_t tmp = 0x00FF; |
| /* Lets see if byte has flipped for little-endian. */ |
| return get_byte(&tmp, 0) == 0xFF; |
| } |
| |
| #endif // ELFF_ELF_DEFS_H_ |