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