/* 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_ |