aboutsummaryrefslogtreecommitdiffstats
path: root/elff/elf_defs.h
blob: 8687f0f68709bf3ec4856cafc33e67d64cc7650f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/* 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_