Home | History | Annotate | Download | only in libelf
      1 /* Internal interfaces for libelf.
      2    Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Red Hat, Inc.
      3    Contributed by Ulrich Drepper <drepper (at) 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