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