| /* 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; | |
| } | |
| /* Use in printf() statements to dump 64-bit values | |
| */ | |
| #ifdef _WIN32 | |
| # define FMT_I64 "I64" | |
| #else | |
| # define FMT_I64 "ll" | |
| #endif | |
| #endif // ELFF_ELF_DEFS_H_ |