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.  */
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 Elf *__elf_begin_internal (int __fildes, Elf_Cmd __cmd, Elf *__ref)
444     attribute_hidden;
445extern Elf32_Ehdr *__elf32_getehdr_internal (Elf *__elf) attribute_hidden;
446extern Elf64_Ehdr *__elf64_getehdr_internal (Elf *__elf) attribute_hidden;
447extern Elf32_Ehdr *__elf32_newehdr_internal (Elf *__elf) attribute_hidden;
448extern Elf64_Ehdr *__elf64_newehdr_internal (Elf *__elf) attribute_hidden;
449extern Elf32_Phdr *__elf32_getphdr_internal (Elf *__elf) attribute_hidden;
450extern Elf64_Phdr *__elf64_getphdr_internal (Elf *__elf) attribute_hidden;
451extern Elf32_Phdr *__elf32_newphdr_internal (Elf *__elf, size_t __cnt)
452     attribute_hidden;
453extern Elf64_Phdr *__elf64_newphdr_internal (Elf *__elf, size_t __cnt)
454     attribute_hidden;
455extern int __elf_getshnum_internal (Elf *__elf, size_t *__dst)
456     attribute_hidden;
457extern int __elf_getshstrndx_internal (Elf *__elf, size_t *__dst)
458     attribute_hidden;
459extern Elf32_Shdr *__elf32_getshdr_internal (Elf_Scn *__scn) attribute_hidden;
460extern Elf64_Shdr *__elf64_getshdr_internal (Elf_Scn *__scn) attribute_hidden;
461extern Elf_Scn *__elf_getscn_internal (Elf *__elf, size_t __index)
462     attribute_hidden;
463extern Elf_Scn *__elf_nextscn_internal (Elf *__elf, Elf_Scn *__scn)
464     attribute_hidden;
465extern Elf_Data *__elf_getdata_internal (Elf_Scn *__scn, Elf_Data *__data)
466     attribute_hidden;
467extern Elf_Data *__elf_rawdata_internal (Elf_Scn *__scn, Elf_Data *__data)
468     attribute_hidden;
469extern char *__elf_strptr_internal (Elf *__elf, size_t __index,
470				    size_t __offset) attribute_hidden;
471extern Elf_Data *__elf32_xlatetom_internal (Elf_Data *__dest,
472					    const Elf_Data *__src,
473					    unsigned int __encode)
474     attribute_hidden;
475extern Elf_Data *__elf64_xlatetom_internal (Elf_Data *__dest,
476					    const Elf_Data *__src,
477					    unsigned int __encode)
478     attribute_hidden;
479extern Elf_Data *__elf32_xlatetof_internal (Elf_Data *__dest,
480					    const Elf_Data *__src,
481					    unsigned int __encode)
482     attribute_hidden;
483extern Elf_Data *__elf64_xlatetof_internal (Elf_Data *__dest,
484					    const Elf_Data *__src,
485					    unsigned int __encode)
486     attribute_hidden;
487extern unsigned int __elf_version_internal (unsigned int __version)
488     attribute_hidden;
489extern unsigned long int __elf_hash_internal (const char *__string)
490       __attribute__ ((__pure__, visibility ("hidden")));
491extern long int __elf32_checksum_internal (Elf *__elf) attribute_hidden;
492extern long int __elf64_checksum_internal (Elf *__elf) attribute_hidden;
493
494
495extern size_t __gelf_fsize_internal (Elf *__elf, Elf_Type __type,
496				     size_t __count, unsigned int __version)
497     attribute_hidden;
498extern GElf_Shdr *__gelf_getshdr_internal (Elf_Scn *__scn, GElf_Shdr *__dst)
499     attribute_hidden;
500extern GElf_Sym *__gelf_getsym_internal (Elf_Data *__data, int __ndx,
501					 GElf_Sym *__dst) attribute_hidden;
502
503
504extern 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