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