Subversion Repositories QNX 8.QNX8 IFS tool

Rev

Rev 16 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
16 pmbaty 1
#ifndef ELFFILE_H
2
#define ELFFILE_H
3
 
4
 
5
#ifdef __cplusplus
6
extern "C" {
7
#endif
8
 
9
 
10
// standard C includes
11
#include <stdint.h>
12
#include <stdlib.h>
13
 
14
 
15
// compiler-specific glue
16
#ifdef _WIN32
17
#ifndef __BYTE_ORDER__
18
#define __ORDER_BIG_ENDIAN__    4321
19
#define __ORDER_LITTLE_ENDIAN__ 1234
20
#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__ // all Windows machines are little endian
21
#endif // !__BYTE_ORDER__
22
#ifndef __builtin_bswap64
23
#ifdef _MSC_VER
24
#define __builtin_bswap64(x) _byteswap_uint64 ((unsigned long long) (x))
25
#endif // _MSC_VER
26
#endif // !__builtin_bswap64
27
#ifndef __builtin_bswap32
28
#ifdef _MSC_VER
29
#define __builtin_bswap32(x) _byteswap_ulong ((unsigned long) (x))
30
#endif // _MSC_VER
31
#endif // !__builtin_bswap32
32
#ifndef __builtin_bswap16
33
#ifdef _MSC_VER
34
#define __builtin_bswap16(x) _byteswap_ushort ((unsigned short) (x))
35
#endif // _MSC_VER
36
#endif // !__builtin_bswap32
37
#endif // _WIN32
38
#ifdef _MSC_VER
39
#define START_OF_PACKED_STRUCT() __pragma(pack(push)) __pragma(pack(1))
40
#define END_OF_PACKED_STRUCT() __pragma(pack(pop))
41
#define PACKED(thing) thing
42
#else // !_MSC_VER
43
#define START_OF_PACKED_STRUCT()
44
#define END_OF_PACKED_STRUCT()
45
#define PACKED(thing) thing __attribute__((packed))
46
#endif // _MSC_VER
47
 
48
 
49
// endianness proclamation macros
50
#define IS_HOST_LE (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
51
#define IS_HOST_BE (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
52
 
53
 
54
// structures describing Executable and Linkable Format (ELF) files and macros for accessing them
55
 
56
#define ELF_MAGIC_STR ("\x7f" "ELF") // 4 bytes found at the start of every ELF file
57
 
58
// ELF platform size
59
#define ELF_SIZE_32BIT 1 // 'platform_size' member of an ELF header: ELF file contains 32-bit structures
60
#define ELF_SIZE_64BIT 2 // 'platform_size' member of an ELF header: ELF file contains 64-bit structures
61
#define IS_ELF_32BIT(elfhdr) ((elfhdr)->u.elf.platform_size == ELF_SIZE_32BIT)
62
#define IS_ELF_64BIT(elfhdr) ((elfhdr)->u.elf.platform_size == ELF_SIZE_64BIT)
63
 
64
// ELF endianness
65
#define ELF_ENDIAN_LITTLE 1 // 'endianness' member of an ELF header: ELF file is little endian
66
#define ELF_ENDIAN_BIG    2 // 'endianness' member of an ELF header: ELF file is big endian
67
#define IS_ELF_LE(elfhdr) ((elfhdr)->u.elf.endianness == ELF_ENDIAN_LITTLE)
68
#define IS_ELF_BE(elfhdr) ((elfhdr)->u.elf.endianness == ELF_ENDIAN_LITTLE)
69
 
70
// ELF file type
71
#define ELF_TYPE_RELOCATABLE 1 // 'type' member of an ELF header: ELF file is relocatable in memory (all offsets hardcoded in it are relative)
72
#define ELF_TYPE_EXECUTABLE  2 // 'type' member of an ELF header: ELF file is executable (has an entrypoint and can be invoked by exec())
73
#define ELF_TYPE_DYNAMICLIB  3 // 'type' member of an ELF header: ELF file is a shared object (requires the dynamic linker to be loaded)
74
#define ELF_TYPE_CORE        4 // 'type' member of an ELF header: ELF file is a core dump (produced by the kernel)
75
 
76
// ELF instruction set
77
#define ELF_MACHINE_X86_64  0x3e // 'instruction_set' member of an ELF header, also used in the IFS startup header: ELF file is for x86_64 processors (62 decimal)
78
#define ELF_MACHINE_AARCH64 0xb7 // 'instruction_set' member of an ELF header, also used in the IFS startup header: ELF file is for ARM64 processors (183 decimal)
79
 
80
// ELF segment types
81
#define ELF_SEGMENTTYPE_LOADABLE 1
82
 
83
// ELF section types
84
#define ELF_SECTIONTYPE_STRINGTABLE 3
85
 
86
// ELF dynamic section types
87
#define ELF_DT_NULL    0 // marks end of dynamic section
88
#define ELF_DT_SONAME 14 // canonical name of shared object
89
 
90
 
91
// returns the actual size of an ELF structure. Handles 32- and 64-bit ELF files in low and big endianness transparently.
92
#define ELF_STRUCT_SIZE(elfhdr,elfstruct) (IS_ELF_64BIT (elfhdr) ? sizeof ((elfstruct)->u.elf64) : sizeof ((elfstruct)->u.elf32))
93
 
94
 
95
// gets a numeric value from an ELF structure. Handles 32- and 64-bit ELF files in low and big endianness transparently.
96
#define ELF_GET_NUMERIC(elfhdr,elfstruct,member) (IS_ELF_64BIT (elfhdr) ? /* is it a 64-bit ELF file ? */ \
97
   ( \
98
      (sizeof ((elfstruct)->u.elf64.member) == 1) || (IS_ELF_LE (elfhdr) && IS_HOST_LE) || (IS_ELF_BE (elfhdr) && IS_HOST_BE) ? /* single-byte, or same endianness ? */ \
99
         (elfstruct)->u.elf64.member /* same endianness, or single byte required: don't swap */ \
100
      : /* else more than one byte and different endianness: swap */ \
101
         (sizeof ((elfstruct)->u.elf64.member) == 8 ? __builtin_bswap64 ((elfstruct)->u.elf64.member) : \
102
         (sizeof ((elfstruct)->u.elf64.member) == 4 ? __builtin_bswap32 ((elfstruct)->u.elf64.member) : \
103
         /* member is necessarily a 2-byte 'word' */  __builtin_bswap16 ((elfstruct)->u.elf64.member))) \
104
   ) \
105
   : /* else peek at 32-bit ELF */ \
106
   ( \
107
      (sizeof ((elfstruct)->u.elf32.member) == 1) || (IS_ELF_LE (elfhdr) && IS_HOST_LE) || (IS_ELF_BE (elfhdr) && IS_HOST_BE) ? /* single-byte, or same endianness ? */ \
108
         (elfstruct)->u.elf32.member /* same endianness, or single byte required: don't swap */ \
109
      : /* else more than one byte and different endianness: swap */ \
110
         (sizeof ((elfstruct)->u.elf32.member) == 4 ? __builtin_bswap32 ((elfstruct)->u.elf32.member) : \
111
         /* member is necessarily a 2-byte 'word' */  __builtin_bswap16 ((elfstruct)->u.elf32.member)) \
112
   ) \
113
)
114
 
115
 
116
// sets a numeric value into an ELF structure. Handles 32- and 64-bit ELF files in low and big endianness transparently.
117
#define ELF_SET_NUMERIC(elfhdr,elfstruct,member,data) (IS_ELF_64BIT (elfhdr) ? /* is it a 64-bit ELF file ? */ \
118
   ((elfstruct)->u.elf64.member = ( \
119
      (sizeof ((elfstruct)->u.elf64.member) == 1) || (IS_ELF_LE (elfhdr) && IS_HOST_LE) || (IS_ELF_BE (elfhdr) && IS_HOST_BE) ? /* single-byte, or same endianness ? */ \
120
         (sizeof ((elfstruct)->u.elf64.member) == 8 ? (uint64_t) ((data)) : \
121
         (sizeof ((elfstruct)->u.elf64.member) == 4 ? (uint32_t) ((data)) : \
122
         (sizeof ((elfstruct)->u.elf64.member) == 2 ? (uint16_t) ((data)) : \
123
                                                      (uint8_t)  ((data))))) /* same endianness, or single byte required: don't swap */ \
124
      : /* else more than one byte and different endianness: swap */ \
125
         (sizeof ((elfstruct)->u.elf64.member) == 8 ? __builtin_bswap64 ((data)) : \
126
         (sizeof ((elfstruct)->u.elf64.member) == 4 ? __builtin_bswap32 ((data)) : \
127
         /* member is necessarily a 2-byte 'word' */  __builtin_bswap16 ((data)))) \
128
   )) \
129
   : /* else poke at 32-bit ELF */ \
130
   ((elfstruct)->u.elf32.member = ( \
131
      (sizeof ((elfstruct)->u.elf32.member) == 1) || (IS_ELF_LE (elfhdr) && IS_HOST_LE) || (IS_ELF_BE (elfhdr) && IS_HOST_BE) ? /* single-byte, or same endianness ? */ \
132
         (sizeof ((elfstruct)->u.elf64.member) == 4 ? (uint32_t) ((data)) : \
133
         (sizeof ((elfstruct)->u.elf64.member) == 2 ? (uint16_t) ((data)) : \
134
                                                      (uint8_t)  ((data)))) /* same endianness, or single byte required: don't swap */ \
135
      : /* else more than one byte and different endianness: swap */ \
136
         (sizeof ((elfstruct)->u.elf32.member) == 4 ? __builtin_bswap32 ((data)) : \
137
         /* member is necessarily a 2-byte 'word' */  __builtin_bswap16 ((data))) \
138
   )) \
139
)
140
 
141
 
142
// gets a string from an ELF structure. Handles 32- and 64-bit ELF files in low and big endianness transparently.
143
#define ELF_GET_STRING(elfhdr,elfstruct,member) (IS_ELF_64BIT (elfhdr) ? (elfstruct)->u.elf64.member : (elfstruct)->u.elf32.member)
144
 
145
 
146
// sets a string into an ELF structure. Handles 32- and 64-bit ELF files in low and big endianness transparently.
147
#define ELF_SET_STRING(elfhdr,elfstruct,member,data,len) memcpy ((IS_ELF_64BIT (elfhdr) ? (elfstruct)->u.elf64.member : (elfstruct)->u.elf32.member), (data), (len)) // this macro supports 32- and 64-bit ELF files transparently
148
 
149
 
150
// Executable and Linkable Format master header structure type definition
151
START_OF_PACKED_STRUCT () // we need byte-alignment for this struct
152
typedef PACKED (struct) elf_header_s
153
{
154
   PACKED (union)
155
   {
156
      PACKED (struct)
157
      {
158
         uint8_t magic[4];                     // offset 0: "\x7f" + "ELF"
159
         uint8_t platform_size;                // offset 4: 1 = 32-bit, 2 = 64-bit
160
         uint8_t endianness;                   // offset 5: 1 = little endian, 2 = big endian
161
         uint8_t header_version;               // offset 6: typically 1
162
         uint8_t os_abi;                       // offset 7: 0 = SysV, 1 = HP/UX, 2 = NetBSD, 3 = Linux, 4 = GNU/Hurd, 6 = Solaris, 7 = AIX, 8 = IRIX, 9 = FreeBSD, 10 = Tru64, 11 = Novell, 12 = OpenBSD, 13 = OpenVMS, 14 = NonStop kernel, 15 = AROS, 16 = FenixOS, 17 = Nuxi CloudABI, 18 = OpenVOS
163
         uint8_t spare[8];                     // offset 8: zeroes
164
         uint16_t type;                        // offset 16: 1 = relocatable, 2 = executable, 3 = shared, 4 = core dump
165
         uint16_t instruction_set;             // offset 18: 2 = Sparc, 3 = i386, 8 = MIPS, 20 = PowerPC, 40 = ARM, 42 = SuperH, 50 = IA-64, 62 = x86_64, 183 = AArch64, 243 = RISC-V
166
         uint32_t elf_version;                 // offset 20: typically 1
167
      } elf;
168
      PACKED (struct) // size == 52
169
      {
170
         uint8_t magic[4];                     // offset 0: "\x7f" + "ELF"
171
         uint8_t platform_size;                // offset 4: 1 = 32-bit, 2 = 64-bit
172
         uint8_t endianness;                   // offset 5: 1 = little endian, 2 = big endian
173
         uint8_t header_version;               // offset 6: typically 1
174
         uint8_t os_abi;                       // offset 7: 0 = SysV, 1 = HP/UX, 2 = NetBSD, 3 = Linux, 4 = GNU/Hurd, 6 = Solaris, 7 = AIX, 8 = IRIX, 9 = FreeBSD, 10 = Tru64, 11 = Novell, 12 = OpenBSD, 13 = OpenVMS, 14 = NonStop kernel, 15 = AROS, 16 = FenixOS, 17 = Nuxi CloudABI, 18 = OpenVOS
175
         uint8_t spare[8];                     // offset 8: zeroes
176
         uint16_t type;                        // offset 16: 1 = relocatable, 2 = executable, 3 = shared, 4 = core dump
177
         uint16_t instruction_set;             // offset 18: 2 = Sparc, 3 = i386, 8 = MIPS, 20 = PowerPC, 40 = ARM, 42 = SuperH, 50 = IA-64, 62 = x86_64, 183 = AArch64, 243 = RISC-V
178
         uint32_t elf_version;                 // offset 20: typically 1
179
         uint32_t entrypoint_offset;           // offset 24: offset to program entrypoint
180
         uint32_t program_header_table_offset; // offset 28: offset to program header table
181
         uint32_t section_header_table_offset; // offset 32: offset to section header table
182
         uint32_t flags;                       // offset 36: flags (architecture-dependent, none for x86)
183
         uint16_t header_size;                 // offset 40: size of ELF header, 52 for 32-bit ELF and 64 for 64-bit ELF -- DO NOT USE sizeof() ON THE elf_header_s STRUCT BECAUSE OF THE UNION! WRITE THE CORRECT SIZE YOURSELF!
184
         uint16_t program_header_item_size;    // offset 42: size of an entry in the program header table
185
         uint16_t program_header_table_len;    // offset 44: number of entries in the program header table
186
         uint16_t section_header_item_size;    // offset 46: size of an entry in the section header table
187
         uint16_t section_header_table_len;    // offset 48: number of entries in the section header table
188
         uint16_t section_header_names_idx;    // offset 50: index of the entry in the section header table that contains the section names
189
      } elf32; // size == 52
190
      PACKED (struct) // size == 64
191
      {
192
         uint8_t magic[4];                     // offset 0: "\x7f" + "ELF"
193
         uint8_t platform_size;                // offset 4: 1 = 32-bit, 2 = 64-bit
194
         uint8_t endianness;                   // offset 5: 1 = little endian, 2 = big endian
195
         uint8_t header_version;               // offset 6: typically 1
196
         uint8_t os_abi;                       // offset 7: 0 = SysV, 1 = HP/UX, 2 = NetBSD, 3 = Linux, 4 = GNU/Hurd, 6 = Solaris, 7 = AIX, 8 = IRIX, 9 = FreeBSD, 10 = Tru64, 11 = Novell, 12 = OpenBSD, 13 = OpenVMS, 14 = NonStop kernel, 15 = AROS, 16 = FenixOS, 17 = Nuxi CloudABI, 18 = OpenVOS
197
         uint8_t spare[8];                     // offset 8: zeroes
198
         uint16_t type;                        // offset 16: 1 = relocatable, 2 = executable, 3 = shared, 4 = core dump
199
         uint16_t instruction_set;             // offset 18: 2 = Sparc, 3 = i386, 8 = MIPS, 20 = PowerPC, 40 = ARM, 42 = SuperH, 50 = IA-64, 62 = x86_64, 183 = AArch64, 243 = RISC-V
200
         uint32_t elf_version;                 // offset 20: typically 1
201
         uint64_t entrypoint_offset;           // offset 24: program entry offset
202
         uint64_t program_header_table_offset; // offset 32: offset to program header table
203
         uint64_t section_header_table_offset; // offset 40: offset to section header table
204
         uint32_t flags;                       // offset 48: flags (architecture-dependent, none for x86)
205
         uint16_t header_size;                 // offset 52: size of ELF header, 52 for 32-bit ELF and 64 for 64-bit ELF
206
         uint16_t program_header_item_size;    // offset 54: size of an entry in the program header table
207
         uint16_t program_header_table_len;    // offset 56: number of entries in the program header table
208
         uint16_t section_header_item_size;    // offset 58: size of an entry in the section header table
209
         uint16_t section_header_table_len;    // offset 60: number of entries in the section header table
210
         uint16_t section_header_names_idx;    // offset 62: index of the entry in the section header table that contains the section names
211
      } elf64; // size == 64
212
   } u;
213
} elf_header_t;
214
END_OF_PACKED_STRUCT () // restore default alignment
215
 
216
 
217
// Executable and Linkable Format program header structure type definition
218
START_OF_PACKED_STRUCT () // we need byte-alignment for this struct
219
typedef PACKED (struct) elf_program_header_s
220
{
221
   PACKED (union)
222
   {
223
      PACKED (struct)
224
      {
225
         uint32_t segment_type; // offset 0: type of segment (0: unused table entry, 1: loadable, 2: dynamic linking information, 3: interpreter information, 4: auxiliary information, 5: reserved, 6: this very segment, 7: TLS template)
226
      } elf;
227
      PACKED (struct) // size == 32
228
      {
229
         uint32_t segment_type;   // offset 0: type of segment (0: unused table entry, 1: loadable, 2: dynamic linking information, 3: interpreter information, 4: auxiliary information, 5: reserved, 6: this very segment, 7: TLS template)
230
         uint32_t file_offset;    // offset 4: file offset of this segment
231
         uint32_t virtual_addr;   // offset 8: virtual address where this segment should be mapped in memory
232
         uint32_t physical_addr;  // offset 12: on systems where this is relevant, PHYSICAL address where this segment should be mapped in memory
233
         uint32_t size_in_file;   // offset 16: size of this segment in the ELF file (may be zero)
234
         uint32_t size_in_memory; // offset 20: size of this segment in memory (may be zero)
235
         uint32_t segment_flags;  // offset 24: bitmap of segment flags (1: executable, 2: writable, 4: readable)
236
         uint32_t alignment;      // offset 28: memory alignment (0 or 1 mean non alignment, else must be a power of 2 where virtual_addr == file_offset % alignment)
237
      } elf32; // size == 32
238
      PACKED (struct) // size == 56
239
      {
240
         uint32_t segment_type;   // offset 0: type of segment (0: unused table entry, 1: loadable, 2: dynamic linking information, 3: interpreter information, 4: auxiliary information, 5: reserved, 6: this very segment, 7: TLS template)
241
         uint32_t segment_flags;  // offset 4: bitmap of segment flags (1: executable, 2: writable, 4: readable)
242
         uint64_t file_offset;    // offset 8: file offset of this segment
243
         uint64_t virtual_addr;   // offset 16: virtual address where this segment should be mapped in memory
244
         uint64_t physical_addr;  // offset 24: on systems where this is relevant, PHYSICAL address where this segment should be mapped in memory
245
         uint64_t size_in_file;   // offset 32: size of this segment in the ELF file (may be zero)
246
         uint64_t size_in_memory; // offset 40: size of this segment in memory (may be zero)
247
         uint64_t alignment;      // offset 48: memory alignment (0 or 1 mean non alignment, else must be a power of 2 where virtual_addr == file_offset % alignment)
248
      } elf64; // size == 56
249
   } u;
250
} elf_program_header_t;
251
END_OF_PACKED_STRUCT () // restore default alignment
252
 
253
 
254
// Executable and Linkable Format section header structure type definition
255
START_OF_PACKED_STRUCT () // we need byte-alignment for this struct
256
typedef PACKED (struct) elf_section_header_s
257
{
258
   PACKED (union)
259
   {
260
      PACKED (struct)
261
      {
262
         uint32_t name_offset; // offset 0: offset in the string table of the name of this section
263
         uint32_t type;        // offset 4: section type (0: unused, 1: program data, 2: symbols table, 3: strings table, 4: relocs with addends, 5: symbols hash table, 6: dyld info, 7: notes, 8: BSS, 9: relocs without addends, 11: dyld symbols table, 14: constructors, 15: destructors, 16, preconstructors, 17: group, 18: extended section indices, 19: number of typedefs ...)
264
      } elf;
265
      PACKED (struct) // size == 40
266
      {
267
         uint32_t name_offset;  // offset 0: offset in the string table of the name of this section
268
         uint32_t type;         // offset 4: section type (0: unused, 1: program data, 2: symbols table, 3: strings table, 4: relocs with addends, 5: symbols hash table, 6: dyld info, 7: notes, 8: BSS, 9: relocs without addends, 11: dyld symbols table, 14: constructors, 15: destructors, 16, preconstructors, 17: group, 18: extended section indices, 19: number of typedefs ...)
269
         uint32_t flags;        // offset 8: bitmapped flags (1: writable, 2: takes RAM, 4: executable, 8: reserved, 16: mergeable, 32: contains C-strings, 64: sh_info contains SHT index, 128: preserve order, 256: OS-specific, 512: group member, 1024: TLS template ...)
270
         uint32_t virtual_addr; // offset 12: address in virtual memory where this section may be loaded
271
         uint32_t file_offset;  // offset 16: offset of this section in the ELF file
272
         uint32_t size;         // offset 20: size of this section
273
         uint32_t linked_index; // offset 24: optional section index of an associated section
274
         uint32_t info;         // offset 28: optional extra information
275
         uint32_t alignment;    // offset 32: required memory alignment (must be a power of 2)
276
         uint32_t entry_size;   // offset 36: for table-like sections, size of an element in the table
277
      } elf32; // size == 40
278
      PACKED (struct) // size == 64
279
      {
280
         uint32_t name_offset;  // offset 0: offset in the string table of the name of this section
281
         uint32_t type;         // offset 4: section type (0: unused, 1: program data, 2: symbols table, 3: strings table, 4: relocs with addends, 5: symbols hash table, 6: dyld info, 7: notes, 8: BSS, 9: relocs without addends, 11: dyld symbols table, 14: constructors, 15: destructors, 16, preconstructors, 17: group, 18: extended section indices, 19: number of typedefs ...)
282
         uint64_t flags;        // offset 8: bitmapped flags (1: writable, 2: takes RAM, 4: executable, 8: reserved, 16: mergeable, 32: contains C-strings, 64: sh_info contains SHT index, 128: preserve order, 256: OS-specific, 512: group member, 1024: TLS template ...)
283
         uint64_t virtual_addr; // offset 16: address in virtual memory where this section may be loaded
284
         uint64_t file_offset;  // offset 24: offset of this section in the ELF file
285
         uint64_t size;         // offset 32: size of this section
286
         uint32_t linked_index; // offset 40: optional section index of an associated section
287
         uint32_t info;         // offset 44: optional extra information
288
         uint64_t alignment;    // offset 48: required memory alignment (must be a power of 2)
289
         uint64_t entry_size;   // offset 56: for table-like sections, size of an element in the table
290
      } elf64; // size == 64
291
   } u;
292
} elf_section_header_t;
293
END_OF_PACKED_STRUCT () // restore default alignment
294
 
295
 
296
// Executable and Linkable Format dynamic section entry structure type definition
297
START_OF_PACKED_STRUCT () // we need byte-alignment for this struct
298
typedef PACKED (struct) elf_dynamic_section_entry_s
299
{
300
   PACKED (union)
301
   {
302
      PACKED (struct) // size == 8
303
      {
304
         int32_t tag; // dynamic entry type (one of ELF_DT_xxx #defines)
305
         uint32_t value; // value (as integer, or as pointed address)
306
      } elf32; // size == 8
307
      PACKED (struct) // size == 16
308
      {
309
         int64_t tag; // dynamic entry type (one of ELF_DT_xxx #defines)
310
         uint64_t value; // value (as integer, or as pointed address)
311
      } elf64; // size == 16
312
   } u;
313
} elf_dynamic_section_entry_t;
314
END_OF_PACKED_STRUCT () // restore default alignment
315
 
316
 
317
static inline elf_section_header_t *elf_get_section_header_by_name (const elf_header_t *elf, const char *section_name)
318
{
319
   // convenience helper function that returns a pointer to a section header by its associated name stored in the section headers strings table
320
 
321
   elf_section_header_t *shdr_shstrtab; // section header of the section header strings table
322
   elf_section_header_t *shdr;
323
   size_t table_count;
324
   size_t table_index;
325
   char *shstrtab; // section header strings table
326
   char *name;
327
 
328
   shdr_shstrtab = (elf_section_header_t *) ((uint8_t *) elf + ELF_GET_NUMERIC (elf, elf, section_header_table_offset) + (size_t) ELF_GET_NUMERIC (elf, elf, section_header_item_size) * ELF_GET_NUMERIC (elf, elf, section_header_names_idx)); // quick access to section header for the section that contains the section names
38 pmbaty 329
   shstrtab = (char *) ((uint8_t *) elf + ELF_GET_NUMERIC (elf, shdr_shstrtab, file_offset)); // locate the start of the strings table that contains the section names
16 pmbaty 330
 
331
   // cycle through the sections table
332
   table_count = ELF_GET_NUMERIC (elf, elf, section_header_table_len);
333
   for (table_index = 0; table_index < table_count; table_index++)
334
   {
335
      shdr = (elf_section_header_t *) ((uint8_t *) elf + ELF_GET_NUMERIC (elf, elf, section_header_table_offset) + (size_t) ELF_GET_NUMERIC (elf, elf, section_header_item_size) * table_index); // quick access to section header
336
      name = &shstrtab[ELF_GET_NUMERIC (elf, shdr, name_offset)]; // peek at its name
337
      if (strcmp (name, section_name) == 0)
338
         return (shdr); // if found, return a pointer to this section header
339
   }
340
 
341
   return (NULL); // section not found
342
}
343
 
344
 
345
// undefine the helpers we no longer need
346
#undef START_OF_PACKED_STRUCT
347
#undef END_OF_PACKED_STRUCT
348
#undef PACKED
349
 
350
 
351
#ifdef __cplusplus
352
}
353
#endif
354
 
355
 
356
#endif // ELFFILE_H