• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Internal interfaces for libelf.
2    Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 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.  */
63 enum
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.  */
76 enum
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.  */
127 typedef 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.  */
136 typedef 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.  */
146 struct 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.  */
215 typedef 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.  */
225 struct 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.  */
364 typedef void (*xfct_t) (void *, const void *, size_t, int);
365 
366 /* The table with the function pointers.  */
367 extern const xfct_t __elf_xfctstom[EV_NUM - 1][EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM] attribute_hidden;
368 extern 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. */
373 extern 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.  */
384 extern unsigned int __libelf_version attribute_hidden;
385 
386 /* The byte value used for filling gaps.  */
387 extern int __libelf_fill_byte attribute_hidden;
388 
389 /* Nonzero if the version was set.  */
390 extern 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.*/
398 extern size_t __elf32_msize (Elf_Type __type, size_t __count,
399 			     unsigned int __version);
400 extern size_t __elf64_msize (Elf_Type __type, size_t __count,
401 			     unsigned int __version);
402 
403 
404 /* Create Elf descriptor from memory image.  */
405 extern 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.  */
411 extern void __libelf_seterrno (int value) internal_function;
412 
413 /* Get the next archive header.  */
414 extern int __libelf_next_arhdr (Elf *elf) internal_function;
415 
416 /* Read all of the file associated with the descriptor.  */
417 extern char *__libelf_readall (Elf *elf) internal_function;
418 
419 /* Read the complete section table and convert the byte order if necessary.  */
420 extern int __libelf_readsections (Elf *elf) internal_function;
421 
422 /* Store the information for the raw data in the `rawdata_list' element.  */
423 extern int __libelf_set_rawdata (Elf_Scn *scn) internal_function;
424 
425 
426 /* Helper functions for elf_update.  */
427 extern off_t __elf32_updatenull (Elf *elf, int *change_bop, size_t shnum)
428      internal_function;
429 extern off_t __elf64_updatenull (Elf *elf, int *change_bop, size_t shnum)
430      internal_function;
431 
432 extern int __elf32_updatemmap (Elf *elf, int change_bo, size_t shnum)
433      internal_function;
434 extern int __elf64_updatemmap (Elf *elf, int change_bo, size_t shnum)
435      internal_function;
436 extern int __elf32_updatefile (Elf *elf, int change_bo, size_t shnum)
437      internal_function;
438 extern 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.  */
443 extern Elf *__elf_begin_internal (int __fildes, Elf_Cmd __cmd, Elf *__ref)
444      attribute_hidden;
445 extern Elf32_Ehdr *__elf32_getehdr_internal (Elf *__elf) attribute_hidden;
446 extern Elf64_Ehdr *__elf64_getehdr_internal (Elf *__elf) attribute_hidden;
447 extern Elf32_Ehdr *__elf32_newehdr_internal (Elf *__elf) attribute_hidden;
448 extern Elf64_Ehdr *__elf64_newehdr_internal (Elf *__elf) attribute_hidden;
449 extern Elf32_Phdr *__elf32_getphdr_internal (Elf *__elf) attribute_hidden;
450 extern Elf64_Phdr *__elf64_getphdr_internal (Elf *__elf) attribute_hidden;
451 extern Elf32_Phdr *__elf32_newphdr_internal (Elf *__elf, size_t __cnt)
452      attribute_hidden;
453 extern Elf64_Phdr *__elf64_newphdr_internal (Elf *__elf, size_t __cnt)
454      attribute_hidden;
455 extern int __elf_getshnum_internal (Elf *__elf, size_t *__dst)
456      attribute_hidden;
457 extern int __elf_getshstrndx_internal (Elf *__elf, size_t *__dst)
458      attribute_hidden;
459 extern Elf32_Shdr *__elf32_getshdr_internal (Elf_Scn *__scn) attribute_hidden;
460 extern Elf64_Shdr *__elf64_getshdr_internal (Elf_Scn *__scn) attribute_hidden;
461 extern Elf_Scn *__elf_getscn_internal (Elf *__elf, size_t __index)
462      attribute_hidden;
463 extern Elf_Scn *__elf_nextscn_internal (Elf *__elf, Elf_Scn *__scn)
464      attribute_hidden;
465 extern Elf_Data *__elf_getdata_internal (Elf_Scn *__scn, Elf_Data *__data)
466      attribute_hidden;
467 extern Elf_Data *__elf_rawdata_internal (Elf_Scn *__scn, Elf_Data *__data)
468      attribute_hidden;
469 extern char *__elf_strptr_internal (Elf *__elf, size_t __index,
470 				    size_t __offset) attribute_hidden;
471 extern Elf_Data *__elf32_xlatetom_internal (Elf_Data *__dest,
472 					    const Elf_Data *__src,
473 					    unsigned int __encode)
474      attribute_hidden;
475 extern Elf_Data *__elf64_xlatetom_internal (Elf_Data *__dest,
476 					    const Elf_Data *__src,
477 					    unsigned int __encode)
478      attribute_hidden;
479 extern Elf_Data *__elf32_xlatetof_internal (Elf_Data *__dest,
480 					    const Elf_Data *__src,
481 					    unsigned int __encode)
482      attribute_hidden;
483 extern Elf_Data *__elf64_xlatetof_internal (Elf_Data *__dest,
484 					    const Elf_Data *__src,
485 					    unsigned int __encode)
486      attribute_hidden;
487 extern unsigned int __elf_version_internal (unsigned int __version)
488      attribute_hidden;
489 extern unsigned long int __elf_hash_internal (const char *__string)
490        __attribute__ ((__pure__, visibility ("hidden")));
491 extern long int __elf32_checksum_internal (Elf *__elf) attribute_hidden;
492 extern long int __elf64_checksum_internal (Elf *__elf) attribute_hidden;
493 
494 
495 extern size_t __gelf_fsize_internal (Elf *__elf, Elf_Type __type,
496 				     size_t __count, unsigned int __version)
497      attribute_hidden;
498 extern GElf_Shdr *__gelf_getshdr_internal (Elf_Scn *__scn, GElf_Shdr *__dst)
499      attribute_hidden;
500 extern GElf_Sym *__gelf_getsym_internal (Elf_Data *__data, int __ndx,
501 					 GElf_Sym *__dst) attribute_hidden;
502 
503 
504 extern uint32_t __libelf_crc32 (uint32_t crc, unsigned char *buf, size_t len)
505      attribute_hidden;
506 
507 
508 /* We often have to update a flag iff a value changed.  Make this
509    convenient.  None of the parameters must have a side effect.  */
510 #ifdef __GNUC__
511 # define update_if_changed(var, exp, flag) \
512   do {									      \
513     __typeof__ (var) *_var = &(var);					      \
514     __typeof__ (exp) _exp = (exp);					      \
515     if (*_var != _exp)							      \
516       {									      \
517 	*_var = _exp;							      \
518 	(flag) |= ELF_F_DIRTY;						      \
519       }									      \
520   } while (0)
521 #else
522 # define update_if_changed(var, exp, flag) \
523   do {									      \
524     if ((var) != (exp))							      \
525       {									      \
526 	(var) = (exp);							      \
527 	(flag) |= ELF_F_DIRTY;						      \
528       }									      \
529   } while (0)
530 #endif
531 
532 #endif  /* libelfP.h */
533