blob: 100f349a8e367c5f8f505e0fbc495c8e23888e2b [file] [log] [blame]
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00001/* Internal interfaces for libelf.
2 Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005 Red Hat, Inc.
3 Contributed by Ulrich Drepper <drepper@redhat.com>, 1998.
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, version 2.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software Foundation,
16 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
17
18#ifndef _LIBELFP_H
19#define _LIBELFP_H 1
20
21#include <ar.h>
22#include <gelf.h>
23#include <stdint.h>
24
25/* gettext helper macros. */
26#define _(Str) dgettext ("libelf", Str)
27
28
29/* Helper Macros to write 32 bit and 64 bit functions. */
30#define __elfw2_(Bits, Name) __elf##Bits##_##Name
31#define elfw2_(Bits, Name) elf##Bits##_##Name
32#define ElfW2_(Bits, Name) Elf##Bits##_##Name
33#define ELFW2_(Bits, Name) ELF##Bits##_##Name
34#define ELFW_(Name, Bits) Name##Bits
35#define __elfw2(Bits, Name) __elfw2_(Bits, Name)
36#define elfw2(Bits, Name) elfw2_(Bits, Name)
37#define ElfW2(Bits, Name) ElfW2_(Bits, Name)
38#define ELFW2(Bits, Name) ELFW2_(Bits, Name)
39#define ELFW(Name, Bits) ELFW_(Name, Bits)
40
41
42/* Sizes of the external types, for 32 bits objects. */
43#define ELF32_FSZ_ADDR 4
44#define ELF32_FSZ_OFF 4
45#define ELF32_FSZ_HALF 2
46#define ELF32_FSZ_WORD 4
47#define ELF32_FSZ_SWORD 4
48#define ELF32_FSZ_XWORD 8
49#define ELF32_FSZ_SXWORD 8
50
51/* Same for 64 bits objects. */
52#define ELF64_FSZ_ADDR 8
53#define ELF64_FSZ_OFF 8
54#define ELF64_FSZ_HALF 2
55#define ELF64_FSZ_WORD 4
56#define ELF64_FSZ_SWORD 4
57#define ELF64_FSZ_XWORD 8
58#define ELF64_FSZ_SXWORD 8
59
60
61/* This is an extension of the ELF_F_* enumeration. The values here are
62 not part of the library interface, they are only used internally. */
63enum
64{
65 ELF_F_MMAPPED = 0x40,
66 ELF_F_MALLOCED = 0x80,
67 ELF_F_FILEDATA = 0x100
68};
69
70
71/* Get definition of all the external types. */
72#include "exttypes.h"
73
74
75/* Error values. */
76enum
77{
78 ELF_E_NOERROR = 0,
79 ELF_E_UNKNOWN_ERROR,
80 ELF_E_UNKNOWN_VERSION,
81 ELF_E_UNKNOWN_TYPE,
82 ELF_E_INVALID_HANDLE,
83 ELF_E_SOURCE_SIZE,
84 ELF_E_DEST_SIZE,
85 ELF_E_INVALID_ENCODING,
86 ELF_E_NOMEM,
87 ELF_E_INVALID_FILE,
88 ELF_E_INVALID_OP,
89 ELF_E_NO_VERSION,
90 ELF_E_INVALID_CMD,
91 ELF_E_RANGE,
92 ELF_E_ARCHIVE_FMAG,
93 ELF_E_INVALID_ARCHIVE,
94 ELF_E_NO_ARCHIVE,
95 ELF_E_NO_INDEX,
96 ELF_E_READ_ERROR,
97 ELF_E_WRITE_ERROR,
98 ELF_E_INVALID_CLASS,
99 ELF_E_INVALID_INDEX,
100 ELF_E_INVALID_OPERAND,
101 ELF_E_INVALID_SECTION,
102 ELF_E_INVALID_COMMAND,
103 ELF_E_WRONG_ORDER_EHDR,
104 ELF_E_FD_DISABLED,
105 ELF_E_FD_MISMATCH,
106 ELF_E_OFFSET_RANGE,
107 ELF_E_NOT_NUL_SECTION,
108 ELF_E_DATA_MISMATCH,
109 ELF_E_INVALID_SECTION_HEADER,
110 ELF_E_INVALID_DATA,
111 ELF_E_DATA_ENCODING,
112 ELF_E_SECTION_TOO_SMALL,
113 ELF_E_INVALID_ALIGN,
114 ELF_E_INVALID_SHENTSIZE,
115 ELF_E_UPDATE_RO,
116 ELF_E_NOFILE,
117 ELF_E_GROUP_NOT_REL,
118 ELF_E_INVALID_PHDR,
119 ELF_E_NO_PHDR,
120 /* Keep this as the last entry. */
121 ELF_E_NUM
122};
123
124
125/* The visible `Elf_Data' type is not sufficent for some operations due
126 to a misdesigned interface. Extend it for internal purposes. */
127typedef struct
128{
129 Elf_Data d;
130 Elf_Scn *s;
131} Elf_Data_Scn;
132
133
134/* List of `Elf_Data' descriptors. This is what makes up the section
135 contents. */
136typedef struct Elf_Data_List
137{
138 /* `data' *must* be the first element in the struct. */
139 Elf_Data_Scn data;
140 struct Elf_Data_List *next;
141 int flags;
142} Elf_Data_List;
143
144
145/* Descriptor for ELF section. */
146struct Elf_Scn
147{
148 /* We have to distinguish several different situations:
149
150 1. the section is user created. Therefore there is no file or memory
151 region to read the data from. Here we have two different subcases:
152
153 a) data was not yet added (before the first `elf_newdata' call)
154
155 b) at least one data set is available
156
157 2. this is a section from a file/memory region. We have to read the
158 current content in one data block if we have to. But we don't
159 read the data until it is necessary. So we have the subcases:
160
161 a) the section in the file has size zero (for whatever reason)
162
163 b) the data of the file is not (yet) read
164
165 c) the data is read and available.
166
167 In addition to this we have different data sets, the raw and the converted
168 data. This distinction only exists for the data read from the file.
169 All user-added data set (all but the first when read from the file or
170 all of them for user-create sections) are the same in both formats.
171 We don't create the converted data before it is necessary.
172
173 The `data_read' element signals whether data is available in the
174 raw format.
175
176 If there is data from the file/memory region or if read one data
177 set is added the `rawdata_list_read' pointer in non-NULL and points
178 to the last filled data set. `raw_datalist_rear' is therefore NULL
179 only if there is no data set at all.
180
181 This so far allows to distinguish all but two cases (given that the
182 `rawdata_list' and `data_list' entries are initialized to zero) is
183 between not yet loaded data from the file/memory region and a section
184 with zero size and type ELF_T_BYTE. */
185 Elf_Data_List data_list; /* List of data buffers. */
186 Elf_Data_List *data_list_rear; /* Pointer to the rear of the data list. */
187
188 Elf_Data_Scn rawdata; /* Uninterpreted data of the section. */
189
190 int data_read; /* Nonzero if the section was created by the
191 user or if the data from the file/memory
192 is read. */
193
194 size_t index; /* Index of this section. */
195 struct Elf *elf; /* The underlying ELF file. */
196
197 union
198 {
199 Elf32_Shdr *e32; /* Pointer to 32bit section header. */
200 Elf64_Shdr *e64; /* Pointer to 64bit section header. */
201 } shdr;
202
203 unsigned int shdr_flags; /* Section header modified? */
204 unsigned int flags; /* Section changed in size? */
205
206 char *rawdata_base; /* The unmodified data of the section. */
207 char *data_base; /* The converted data of the section. */
208
209 struct Elf_ScnList *list; /* Pointer the the section list element the
210 data is in. */
211};
212
213
214/* List of section. */
215typedef struct Elf_ScnList
216{
217 unsigned int cnt; /* Number of elements of 'data' used. */
218 unsigned int max; /* Number of elements of 'data' allocated. */
219 struct Elf_ScnList *next; /* Next block of sections. */
220 struct Elf_Scn data[0]; /* Section data. */
221} Elf_ScnList;
222
223
224/* The ELF descriptor. */
225struct Elf
226{
227 /* What kind of file is underneath (ELF file, archive...). */
228 Elf_Kind kind;
229
230 /* Command used to create this descriptor. */
231 Elf_Cmd cmd;
232
233 /* The binary class. */
234 unsigned int class;
235
236 /* The used file descriptor. -1 if not available anymore. */
237 int fildes;
238
239 /* Offset in the archive this file starts or zero. */
240 off_t start_offset;
241
242 /* Size of the file in the archive or the entire file size, or ~0
243 for an (yet) unknown size. */
244 size_t maximum_size;
245
246 /* Address to which the file was mapped. NULL if not mapped. */
247 void *map_address;
248
249 /* Describes the way the memory was allocated and if the dirty bit is
250 signalled it means that the whole file has to be rewritten since
251 the layout changed. */
252 int flags;
253
254 /* When created for an archive member this points to the descriptor
255 for the archive. */
256 Elf *parent;
257
258 /* Lock to handle multithreaded programs. */
259 rwlock_define (,lock);
260
261 /* Reference counting for the descriptor. */
262 int ref_count;
263
264 struct Elf *next; /* Used in list of archive descriptors. */
265
266 union
267 {
268 struct
269 {
270 int ehdr_flags; /* Flags (dirty) for ELF header. */
271 int phdr_flags; /* Flags (dirty|malloc) for program header. */
272 int shdr_malloced; /* Nonzero if shdr array was allocated. */
273
274 /* The next fields are only useful when testing for ==/!= NULL. */
275 void *ehdr;
276 void *shdr;
277 void *phdr;
278
279 Elf_ScnList *scns_last; /* Last element in the section list.
280 If NULL the data has not yet been
281 read from the file. */
282 unsigned int scnincr; /* Number of sections allocate the last
283 time. */
284 off64_t sizestr_offset; /* Offset of the size string in the parent
285 if this is an archive member. */
286 } elf;
287
288 struct
289 {
290 int ehdr_flags; /* Flags (dirty) for ELF header. */
291 int phdr_flags; /* Flags (dirty|malloc) for program header. */
292 int shdr_malloced; /* Nonzero if shdr array was allocated. */
293
294 Elf32_Ehdr *ehdr; /* Pointer to the ELF header. This is
295 never malloced. */
296 Elf32_Shdr *shdr; /* Used when reading from a file. */
297 Elf32_Phdr *phdr; /* Pointer to the program header array. */
298 Elf_ScnList *scns_last; /* Last element in the section list.
299 If NULL the data has not yet been
300 read from the file. */
301 unsigned int scnincr; /* Number of sections allocate the last
302 time. */
303 off64_t sizestr_offset; /* Offset of the size string in the parent
304 if this is an archive member. */
305 Elf32_Ehdr ehdr_mem; /* Memory used for ELF header when not
306 mmaped. */
307 char __e32scnspad[sizeof (Elf64_Ehdr) - sizeof (Elf32_Ehdr)];
308
309 /* The section array. */
310 Elf_ScnList scns;
311 } elf32;
312
313 struct
314 {
315 int ehdr_flags; /* Flags (dirty) for ELF header. */
316 int phdr_flags; /* Flags (dirty|malloc) for program header. */
317 int shdr_malloced; /* Nonzero if shdr array was allocated. */
318
319 Elf64_Ehdr *ehdr; /* Pointer to the ELF header. This is
320 never malloced. */
321 Elf64_Shdr *shdr; /* Used when reading from a file. */
322 Elf64_Phdr *phdr; /* Pointer to the program header array. */
323 Elf_ScnList *scns_last; /* Last element in the section list.
324 If NULL the data has not yet been
325 read from the file. */
326 unsigned int scnincr; /* Number of sections allocate the last
327 time. */
328 off64_t sizestr_offset; /* Offset of the size string in the parent
329 if this is an archive member. */
330 Elf64_Ehdr ehdr_mem; /* Memory used for ELF header when not
331 mmaped. */
332
333 /* The section array. */
334 Elf_ScnList scns;
335 } elf64;
336
337 struct
338 {
339 int has_index; /* Set when file has index. 0 means
340 undecided, > 0 means it has one. */
341 Elf_Arsym *ar_sym; /* Symbol table returned by elf_getarsym. */
342 size_t ar_sym_num; /* Number of entries in `ar_sym'. */
343 char *long_names; /* If no index is available but long names
344 are used this elements points to the data.*/
345 size_t long_names_len; /* Length of the long name table. */
346 off_t offset; /* Offset in file we are currently at.
347 elf_next() advances this to the next
348 member of the archive. */
349 Elf_Arhdr elf_ar_hdr; /* Structure returned by 'elf_getarhdr'. */
350 struct ar_hdr ar_hdr; /* Header read from file. */
351 char ar_name[16]; /* NUL terminated ar_name of elf_ar_hdr. */
352 char raw_name[17]; /* This is a buffer for the NUL terminated
353 named raw_name used in the elf_ar_hdr. */
354 struct Elf *children; /* List of all descriptors for this archive. */
355 } ar;
356 } state;
357
358 /* There absolutely never must be anything following the union. */
359};
360
361
362/* Type of the conversion functions. These functions will convert the
363 byte order. */
364typedef void (*xfct_t) (void *, const void *, size_t, int);
365
366/* The table with the function pointers. */
367extern const xfct_t __elf_xfctstom[EV_NUM - 1][EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM] attribute_hidden;
368extern const xfct_t __elf_xfctstof[EV_NUM - 1][EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM] attribute_hidden;
369
370
371/* Array with sizes of the external types indexed by ELF version, binary
372 class, and type. */
373extern const size_t __libelf_type_sizes[EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM] attribute_hidden;
374/* We often have to access the size for a type in the current version. */
375#if EV_NUM != 2
376# define elf_typesize(class,type,n) \
377 elfw2(class,fsize) (type, n, __libelf_version)
378#else
379# define elf_typesize(class,type,n) \
380 (__libelf_type_sizes[EV_CURRENT - 1][ELFW(ELFCLASS,class) - 1][type] * n)
381#endif
382
383/* Currently selected version of the ELF specification. */
384extern unsigned int __libelf_version attribute_hidden;
385
386/* The byte value used for filling gaps. */
387extern int __libelf_fill_byte attribute_hidden;
388
389/* Nonzero if the version was set. */
390extern int __libelf_version_initialized attribute_hidden;
391
392
393/* The libelf API does not have such a function but it is still useful.
394 Get the memory size for the given type.
395
396 These functions cannot be marked internal since they are aliases
397 of the export elfXX_fsize functions.*/
398extern size_t __elf32_msize (Elf_Type __type, size_t __count,
399 unsigned int __version);
400extern size_t __elf64_msize (Elf_Type __type, size_t __count,
401 unsigned int __version);
402
403
404/* Create Elf descriptor from memory image. */
405extern Elf *__libelf_read_mmaped_file (int fildes, void *map_address,
406 off_t offset, size_t maxsize,
407 Elf_Cmd cmd, Elf *parent)
408 internal_function;
409
410/* Set error value. */
411extern void __libelf_seterrno (int value) internal_function;
412
413/* Get the next archive header. */
414extern int __libelf_next_arhdr (Elf *elf) internal_function;
415
416/* Read all of the file associated with the descriptor. */
417extern char *__libelf_readall (Elf *elf) internal_function;
418
419/* Read the complete section table and convert the byte order if necessary. */
420extern int __libelf_readsections (Elf *elf) internal_function;
421
422/* Store the information for the raw data in the `rawdata_list' element. */
423extern int __libelf_set_rawdata (Elf_Scn *scn) internal_function;
424
425
426/* Helper functions for elf_update. */
427extern off_t __elf32_updatenull (Elf *elf, int *change_bop, size_t shnum)
428 internal_function;
429extern off_t __elf64_updatenull (Elf *elf, int *change_bop, size_t shnum)
430 internal_function;
431
432extern int __elf32_updatemmap (Elf *elf, int change_bo, size_t shnum)
433 internal_function;
434extern int __elf64_updatemmap (Elf *elf, int change_bo, size_t shnum)
435 internal_function;
436extern int __elf32_updatefile (Elf *elf, int change_bo, size_t shnum)
437 internal_function;
438extern int __elf64_updatefile (Elf *elf, int change_bo, size_t shnum)
439 internal_function;
440
441
442/* Alias for exported functions to avoid PLT entries. */
443extern int __elf_end_internal (Elf *__elf);
444extern Elf *__elf_begin_internal (int __fildes, Elf_Cmd __cmd, Elf *__ref)
445 attribute_hidden;
446extern Elf32_Ehdr *__elf32_getehdr_internal (Elf *__elf) attribute_hidden;
447extern Elf64_Ehdr *__elf64_getehdr_internal (Elf *__elf) attribute_hidden;
448extern Elf32_Ehdr *__elf32_newehdr_internal (Elf *__elf) attribute_hidden;
449extern Elf64_Ehdr *__elf64_newehdr_internal (Elf *__elf) attribute_hidden;
450extern Elf32_Phdr *__elf32_getphdr_internal (Elf *__elf) attribute_hidden;
451extern Elf64_Phdr *__elf64_getphdr_internal (Elf *__elf) attribute_hidden;
452extern Elf32_Phdr *__elf32_newphdr_internal (Elf *__elf, size_t __cnt)
453 attribute_hidden;
454extern Elf64_Phdr *__elf64_newphdr_internal (Elf *__elf, size_t __cnt)
455 attribute_hidden;
456extern int __elf_getshnum_internal (Elf *__elf, size_t *__dst)
457 attribute_hidden;
458extern int __elf_getshstrndx_internal (Elf *__elf, size_t *__dst)
459 attribute_hidden;
460extern Elf32_Shdr *__elf32_getshdr_internal (Elf_Scn *__scn) attribute_hidden;
461extern Elf64_Shdr *__elf64_getshdr_internal (Elf_Scn *__scn) attribute_hidden;
462extern Elf_Scn *__elf_getscn_internal (Elf *__elf, size_t __index)
463 attribute_hidden;
464extern Elf_Scn *__elf_nextscn_internal (Elf *__elf, Elf_Scn *__scn)
465 attribute_hidden;
466extern Elf_Data *__elf_getdata_internal (Elf_Scn *__scn, Elf_Data *__data)
467 attribute_hidden;
468extern Elf_Data *__elf_rawdata_internal (Elf_Scn *__scn, Elf_Data *__data)
469 attribute_hidden;
470extern char *__elf_strptr_internal (Elf *__elf, size_t __index,
471 size_t __offset) attribute_hidden;
472extern Elf_Data *__elf32_xlatetom_internal (Elf_Data *__dest,
473 const Elf_Data *__src,
474 unsigned int __encode)
475 attribute_hidden;
476extern Elf_Data *__elf64_xlatetom_internal (Elf_Data *__dest,
477 const Elf_Data *__src,
478 unsigned int __encode)
479 attribute_hidden;
480extern Elf_Data *__elf32_xlatetof_internal (Elf_Data *__dest,
481 const Elf_Data *__src,
482 unsigned int __encode)
483 attribute_hidden;
484extern Elf_Data *__elf64_xlatetof_internal (Elf_Data *__dest,
485 const Elf_Data *__src,
486 unsigned int __encode)
487 attribute_hidden;
488extern unsigned int __elf_version_internal (unsigned int __version)
489 attribute_hidden;
490extern unsigned long int __elf_hash_internal (const char *__string)
491 __attribute__ ((__pure__, visibility ("hidden")));
492extern long int __elf32_checksum_internal (Elf *__elf) attribute_hidden;
493extern long int __elf64_checksum_internal (Elf *__elf) attribute_hidden;
494
495
496extern GElf_Ehdr *__gelf_getehdr_internal (Elf *__elf, GElf_Ehdr *__dest);
497extern size_t __gelf_fsize_internal (Elf *__elf, Elf_Type __type,
498 size_t __count, unsigned int __version)
499 attribute_hidden;
500extern GElf_Shdr *__gelf_getshdr_internal (Elf_Scn *__scn, GElf_Shdr *__dst)
501 attribute_hidden;
502extern GElf_Sym *__gelf_getsym_internal (Elf_Data *__data, int __ndx,
503 GElf_Sym *__dst) attribute_hidden;
504
505
506extern uint32_t __libelf_crc32 (uint32_t crc, unsigned char *buf, size_t len)
507 attribute_hidden;
508
509
510/* We often have to update a flag iff a value changed. Make this
511 convenient. None of the parameters must have a side effect. */
512#ifdef __GNUC__
513# define update_if_changed(var, exp, flag) \
514 do { \
515 __typeof__ (var) *_var = &(var); \
516 __typeof__ (exp) _exp = (exp); \
517 if (*_var != _exp) \
518 { \
519 *_var = _exp; \
520 (flag) |= ELF_F_DIRTY; \
521 } \
522 } while (0)
523#else
524# define update_if_changed(var, exp, flag) \
525 do { \
526 if ((var) != (exp)) \
527 { \
528 (var) = (exp); \
529 (flag) |= ELF_F_DIRTY; \
530 } \
531 } while (0)
532#endif
533
534#endif /* libelfP.h */