1/* Copyright (C) 2007-2010 The Android Open Source Project 2** 3** This software is licensed under the terms of the GNU General Public 4** License version 2, as published by the Free Software Foundation, and 5** may be copied, distributed, and modified under those terms. 6** 7** This program is distributed in the hope that it will be useful, 8** but WITHOUT ANY WARRANTY; without even the implied warranty of 9** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10** GNU General Public License for more details. 11*/ 12 13/* 14 * Contains some helpful macros, and inline routines. 15 */ 16 17#ifndef ELFF_ELF_DEFS_H_ 18#define ELFF_ELF_DEFS_H_ 19 20#include "elff_elf.h" 21 22//============================================================================= 23// Macros. 24//============================================================================= 25 26/* Increments a pointer by n bytes. 27 * Param: 28 * p - Pointer to increment. 29 * n - Number of bytes to increment the pointer with. 30 */ 31#define INC_PTR(p, n) (reinterpret_cast<uint8_t*>(p) + (n)) 32 33/* Increments a constant pointer by n bytes. 34 * Param: 35 * p - Pointer to increment. 36 * n - Number of bytes to increment the pointer with. 37 */ 38#define INC_CPTR(p, n) (reinterpret_cast<const uint8_t*>(p) + (n)) 39 40/* Increments a pointer of a given type by n bytes. 41 * Param: 42 * T - Pointer type 43 * p - Pointer to increment. 44 * n - Number of bytes to increment the pointer with. 45 */ 46#define INC_PTR_T(T, p, n) \ 47 reinterpret_cast<T*> \ 48 (reinterpret_cast<uint8_t*>(p) + (n)) 49 50/* Increments a constant pointer of a given type by n bytes. 51 * Param: 52 * T - Pointer type 53 * p - Pointer to increment. 54 * n - Number of bytes to increment the pointer with. 55 */ 56#define INC_CPTR_T(T, p, n) \ 57 reinterpret_cast<const T*> \ 58 (reinterpret_cast<const uint8_t*>(p) + (n)) 59 60/* Calculates number of entries in a static array. 61 * Param: 62 * a - Array. 63 * Return: 64 * Number of entries in the array. 65 */ 66#define ELFF_ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a))) 67 68/* Calculates offset of a field inside a structure (or a class) of the 69 * given type. 70 * Param: 71 * T - Structure (or class) type. 72 * f - Name of a field (member variable) for this structure (or class). 73 */ 74#define ELFF_FIELD_OFFSET(T, f) ((size_t)(size_t*)&(((T *)0)->f)) 75 76//============================================================================= 77// Inline routines. 78//============================================================================= 79 80/* Calculates byte interval between two pointers. 81 * Param: 82 * s - Starting pointer of the interval. Must be less, or equal to 'e'. 83 * e - Ending pointer of the interval. Must be greater, or equal to 's'. 84 * Return: 85 * Byte interval between two pointers. 86 */ 87static inline size_t 88diff_ptr(const void* s, const void* e) { 89 assert(s <= e); 90 return ((size_t)(reinterpret_cast<const uint8_t*>(e) - 91 reinterpret_cast<const uint8_t*>(s))); 92} 93 94/* Gets one byte from an index inside a memory block. 95 * Param: 96 * ptr - Address of the beginning of the memory block. 97 * bt - Index of a byte inside the block to get. 98 * Return: 99 * A byte at the given index inside the given memory block. 100 */ 101static inline uint8_t 102get_byte(const void* ptr, uint32_t bt) { 103 return *(reinterpret_cast<const uint8_t*>(ptr) + bt); 104} 105 106/* Checks if given address range is fully contained within a section. 107 * Param: 108 * rp - Beginning of the range to check. 109 * rsize - Size of the range to check. 110 * ss - Beginning of the section that should contain the checking range. 111 * ssize - Size of the section that should contain the checking range. 112 * Return: 113 * true, if given address range is fully contained within a section, or 114 * false, if any part of the address range is not contained in the secton. 115 */ 116static inline bool 117is_in_section(const void* rp, size_t rsize, const void* ss, size_t ssize) { 118 const void* rend = INC_CPTR(rp, rsize); 119 /* We also make sure here that increment didn't overflow the pointer. */ 120 return rp >= ss && ss != NULL && (diff_ptr(ss, rend) <= ssize) && rend >= rp; 121} 122 123/* Checks if this code runs on CPU with a little-endian data format. 124 * Return: 125 * true, if this code runs on CPU with a little-endian data format, 126 * or false, if this code runs on CPU with a big-endian data format. 127 */ 128static inline bool 129is_little_endian_cpu(void) { 130 uint16_t tmp = 0x00FF; 131 /* Lets see if byte has flipped for little-endian. */ 132 return get_byte(&tmp, 0) == 0xFF; 133} 134 135/* Use in printf() statements to dump 64-bit values 136 */ 137#ifdef _WIN32 138# define FMT_I64 "I64" 139#else 140# define FMT_I64 "ll" 141#endif 142 143#endif // ELFF_ELF_DEFS_H_ 144