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