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
diff_ptr(const void * s,const void * e)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
get_byte(const void * ptr,uint32_t bt)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
is_in_section(const void * rp,size_t rsize,const void * ss,size_t ssize)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
is_little_endian_cpu(void)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