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@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