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 */ 87 static inline size_t 88 diff_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 */ 101 static inline uint8_t 102 get_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 */ 116 static inline bool 117 is_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 */ 128 static inline bool 129 is_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 #endif // ELFF_ELF_DEFS_H_ 136