1 /*- 2 * Copyright (c) 2006,2008-2010 Joseph Koshy 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27 #ifndef _PRIVATE_LIBELF_H_ 28 #define _PRIVATE_LIBELF_H_ 29 30 #include <sys/param.h> 31 #include <sys/endian.h> 32 #include <sys/queue.h> 33 #include <sys/mman.h> 34 #include <sys/stat.h> 35 #include <sys/types.h> 36 #include <assert.h> 37 #include <errno.h> 38 #include <limits.h> 39 #include <stddef.h> 40 #include <stdint.h> 41 #include <unistd.h> 42 43 /* _libelf_config.h */ 44 #if defined(__DragonFly__) 45 #define LIBELF_ARCH EM_X86_64 46 #define LIBELF_BYTEORDER ELFDATA2LSB 47 #define LIBELF_CLASS ELFCLASS64 48 #endif /* __DragonFly__ */ 49 50 /* _elftc.h */ 51 #if defined(__DragonFly__) 52 #define ELFTC_BYTE_ORDER _BYTE_ORDER 53 #define ELFTC_BYTE_ORDER_LITTLE_ENDIAN _LITTLE_ENDIAN 54 #define ELFTC_BYTE_ORDER_BIG_ENDIAN _BIG_ENDIAN 55 #define ELFTC_HAVE_MMAP 1 56 #define STAILQ_FOREACH_SAFE STAILQ_FOREACH_MUTABLE 57 #endif 58 59 #if 1 60 #define _libelf_allocate_data __ei_libelf_allocate_data 61 #define _libelf_allocate_elf __ei_libelf_allocate_elf 62 #define _libelf_allocate_scn __ei_libelf_allocate_scn 63 #define _libelf_cvt_ADDR64_tom __ei_libelf_cvt_ADDR64_tom 64 #define _libelf_cvt_BYTE_tox __ei_libelf_cvt_BYTE_tox 65 #define _libelf_cvt_CAP64_tom __ei_libelf_cvt_CAP64_tom 66 #define _libelf_cvt_DYN64_tom __ei_libelf_cvt_DYN64_tom 67 #define _libelf_cvt_EHDR64_tom __ei_libelf_cvt_EHDR64_tom 68 #define _libelf_cvt_GNUHASH64_tom __ei_libelf_cvt_GNUHASH64_tom 69 #define _libelf_cvt_HALF_tom __ei_libelf_cvt_HALF_tom 70 #define _libelf_cvt_LWORD_tom __ei_libelf_cvt_LWORD_tom 71 #define _libelf_cvt_MOVE64_tom __ei_libelf_cvt_MOVE64_tom 72 #define _libelf_cvt_NOTE_tom __ei_libelf_cvt_NOTE_tom 73 #define _libelf_cvt_OFF64_tom __ei_libelf_cvt_OFF64_tom 74 #define _libelf_cvt_PHDR64_tom __ei_libelf_cvt_PHDR64_tom 75 #define _libelf_cvt_REL64_tom __ei_libelf_cvt_REL64_tom 76 #define _libelf_cvt_RELA64_tom __ei_libelf_cvt_RELA64_tom 77 #define _libelf_cvt_SHDR64_tom __ei_libelf_cvt_SHDR64_tom 78 #define _libelf_cvt_SWORD_tom __ei_libelf_cvt_SWORD_tom 79 #define _libelf_cvt_SXWORD_tom __ei_libelf_cvt_SXWORD_tom 80 #define _libelf_cvt_SYM64_tom __ei_libelf_cvt_SYM64_tom 81 #define _libelf_cvt_SYMINFO64_tom __ei_libelf_cvt_SYMINFO64_tom 82 #define _libelf_cvt_VDEF64_tom __ei_libelf_cvt_VDEF64_tom 83 #define _libelf_cvt_VNEED64_tom __ei_libelf_cvt_VNEED64_tom 84 #define _libelf_cvt_WORD_tom __ei_libelf_cvt_WORD_tom 85 #define _libelf_cvt_XWORD_tom __ei_libelf_cvt_XWORD_tom 86 #define _libelf_ehdr __ei_libelf_ehdr 87 #define _libelf_fsize __ei_libelf_fsize 88 #define _libelf_get_translator __ei_libelf_get_translator 89 #define _libelf_getshdr __ei_libelf_getshdr 90 #define _libelf_init_elf __ei_libelf_init_elf 91 #define _libelf_load_extended __ei_libelf_load_extended 92 #define _libelf_load_section_headers __ei_libelf_load_section_headers 93 #define _libelf_memory __ei_libelf_memory 94 #define _libelf_msize __ei_libelf_msize 95 #define _libelf_open_object __ei_libelf_open_object 96 #define _libelf_read_special_file __ei_libelf_read_special_file 97 #define _libelf_release_data __ei_libelf_release_data 98 #define _libelf_release_elf __ei_libelf_release_elf 99 #define _libelf_release_scn __ei_libelf_release_scn 100 #define _libelf_xlate_shtype __ei_libelf_xlate_shtype 101 #define _libelf __ei_libelf 102 103 #define elf64_fsize __ei_elf64_fsize 104 #define elf_getscn __ei_elf_getscn 105 106 #define elf_begin _ei_elf_begin 107 #define elf_end _ei_elf_end 108 #define elf_errmsg _ei_elf_errmsg 109 #define elf_errno _ei_elf_errno 110 #define elf_getdata _ei_elf_getdata 111 #define elf_nextscn _ei_elf_nextscn 112 #define elf_strptr _ei_elf_strptr 113 #define elf_version _ei_elf_version 114 #define gelf_getshdr _ei_gelf_getshdr 115 #define gelf_getsym _ei_gelf_getsym 116 #endif 117 118 /* elfdefinitions.h */ 119 /* 120 * Offsets in the `ei_ident[]` field of an ELF executable header. 121 */ 122 #define _ELF_DEFINE_EI_OFFSETS() \ 123 _ELF_DEFINE_EI(EI_MAG0, 0, "magic number") \ 124 _ELF_DEFINE_EI(EI_MAG1, 1, "magic number") \ 125 _ELF_DEFINE_EI(EI_MAG2, 2, "magic number") \ 126 _ELF_DEFINE_EI(EI_MAG3, 3, "magic number") \ 127 _ELF_DEFINE_EI(EI_CLASS, 4, "file class") \ 128 _ELF_DEFINE_EI(EI_DATA, 5, "data encoding") \ 129 _ELF_DEFINE_EI(EI_VERSION, 6, "file version") \ 130 _ELF_DEFINE_EI(EI_OSABI, 7, "OS ABI kind") \ 131 _ELF_DEFINE_EI(EI_ABIVERSION, 8, "OS ABI version") \ 132 _ELF_DEFINE_EI(EI_PAD, 9, "padding start") \ 133 _ELF_DEFINE_EI(EI_NIDENT, 16, "total size") 134 135 #undef _ELF_DEFINE_EI 136 #define _ELF_DEFINE_EI(N, V, DESCR) N = V , 137 enum { 138 _ELF_DEFINE_EI_OFFSETS() 139 EI__LAST__ 140 }; 141 142 /* 143 * The ELF class of an object. 144 */ 145 #define _ELF_DEFINE_ELFCLASS() \ 146 _ELF_DEFINE_EC(ELFCLASSNONE, 0, "Unknown ELF class") \ 147 _ELF_DEFINE_EC(ELFCLASS32, 1, "32 bit objects") \ 148 _ELF_DEFINE_EC(ELFCLASS64, 2, "64 bit objects") 149 150 #undef _ELF_DEFINE_EC 151 #define _ELF_DEFINE_EC(N, V, DESCR) N = V , 152 enum { 153 _ELF_DEFINE_ELFCLASS() 154 EC__LAST__ 155 }; 156 157 /* 158 * Endianness of data in an ELF object. 159 */ 160 161 #define _ELF_DEFINE_ELF_DATA_ENDIANNESS() \ 162 _ELF_DEFINE_ED(ELFDATANONE, 0, "Unknown data endianness") \ 163 _ELF_DEFINE_ED(ELFDATA2LSB, 1, "little endian") \ 164 _ELF_DEFINE_ED(ELFDATA2MSB, 2, "big endian") 165 166 #undef _ELF_DEFINE_ED 167 #define _ELF_DEFINE_ED(N, V, DESCR) N = V , 168 enum { 169 _ELF_DEFINE_ELF_DATA_ENDIANNESS() 170 ED__LAST__ 171 }; 172 173 /* 174 * Values of the magic numbers used in identification array. 175 */ 176 #define _ELF_DEFINE_ELF_MAGIC() \ 177 _ELF_DEFINE_EMAG(ELFMAG0, 0x7FU) \ 178 _ELF_DEFINE_EMAG(ELFMAG1, 'E') \ 179 _ELF_DEFINE_EMAG(ELFMAG2, 'L') \ 180 _ELF_DEFINE_EMAG(ELFMAG3, 'F') 181 182 #undef _ELF_DEFINE_EMAG 183 #define _ELF_DEFINE_EMAG(N, V) N = V , 184 enum { 185 _ELF_DEFINE_ELF_MAGIC() 186 ELFMAG__LAST__ 187 }; 188 189 /* 190 * ELF Machine types: (EM_*). 191 */ 192 #define _ELF_DEFINE_ELF_MACHINES() \ 193 _ELF_DEFINE_EM(EM_NONE, 0, "No machine") \ 194 _ELF_DEFINE_EM(EM_386, 3, "Intel 80386") \ 195 _ELF_DEFINE_EM(EM_X86_64, 62, "AMD x86-64 architecture") 196 197 #undef _ELF_DEFINE_EM 198 #define _ELF_DEFINE_EM(N, V, DESCR) N = V , 199 enum { 200 _ELF_DEFINE_ELF_MACHINES() 201 EM__LAST__ 202 }; 203 204 /* ELF file format version numbers. */ 205 #define EV_NONE 0 206 #define EV_CURRENT 1 207 208 /* 209 * Special section indices. 210 */ 211 #define _ELF_DEFINE_SECTION_INDICES() \ 212 _ELF_DEFINE_SHN(SHN_UNDEF, 0, "undefined section") \ 213 _ELF_DEFINE_SHN(SHN_LORESERVE, 0xFF00U, "start of reserved area") \ 214 _ELF_DEFINE_SHN(SHN_LOPROC, 0xFF00U, \ 215 "start of processor-specific range") \ 216 _ELF_DEFINE_SHN(SHN_BEFORE, 0xFF00U, "used for section ordering") \ 217 _ELF_DEFINE_SHN(SHN_AFTER, 0xFF01U, "used for section ordering") \ 218 _ELF_DEFINE_SHN(SHN_AMD64_LCOMMON, 0xFF02U, "large common block label") \ 219 _ELF_DEFINE_SHN(SHN_MIPS_ACOMMON, 0xFF00U, \ 220 "allocated common symbols in a DSO") \ 221 _ELF_DEFINE_SHN(SHN_MIPS_TEXT, 0xFF01U, "Reserved (obsolete)") \ 222 _ELF_DEFINE_SHN(SHN_MIPS_DATA, 0xFF02U, "Reserved (obsolete)") \ 223 _ELF_DEFINE_SHN(SHN_MIPS_SCOMMON, 0xFF03U, \ 224 "gp-addressable common symbols") \ 225 _ELF_DEFINE_SHN(SHN_MIPS_SUNDEFINED, 0xFF04U, \ 226 "gp-addressable undefined symbols") \ 227 _ELF_DEFINE_SHN(SHN_MIPS_LCOMMON, 0xFF05U, "local common symbols") \ 228 _ELF_DEFINE_SHN(SHN_MIPS_LUNDEFINED, 0xFF06U, \ 229 "local undefined symbols") \ 230 _ELF_DEFINE_SHN(SHN_HIPROC, 0xFF1FU, \ 231 "end of processor-specific range") \ 232 _ELF_DEFINE_SHN(SHN_LOOS, 0xFF20U, \ 233 "start of OS-specific range") \ 234 _ELF_DEFINE_SHN(SHN_SUNW_IGNORE, 0xFF3FU, "used by dtrace") \ 235 _ELF_DEFINE_SHN(SHN_HIOS, 0xFF3FU, \ 236 "end of OS-specific range") \ 237 _ELF_DEFINE_SHN(SHN_ABS, 0xFFF1U, "absolute references") \ 238 _ELF_DEFINE_SHN(SHN_COMMON, 0xFFF2U, "references to COMMON areas") \ 239 _ELF_DEFINE_SHN(SHN_XINDEX, 0xFFFFU, "extended index") \ 240 _ELF_DEFINE_SHN(SHN_HIRESERVE, 0xFFFFU, "end of reserved area") 241 242 #undef _ELF_DEFINE_SHN 243 #define _ELF_DEFINE_SHN(N, V, DESCR) N = V , 244 enum { 245 _ELF_DEFINE_SECTION_INDICES() 246 SHN__LAST__ 247 }; 248 249 /* 250 * Section types. 251 */ 252 253 #define _ELF_DEFINE_SECTION_TYPES() \ 254 _ELF_DEFINE_SHT(SHT_NULL, 0, "inactive header") \ 255 _ELF_DEFINE_SHT(SHT_PROGBITS, 1, "program defined information") \ 256 _ELF_DEFINE_SHT(SHT_SYMTAB, 2, "symbol table") \ 257 _ELF_DEFINE_SHT(SHT_STRTAB, 3, "string table") \ 258 _ELF_DEFINE_SHT(SHT_RELA, 4, \ 259 "relocation entries with addends") \ 260 _ELF_DEFINE_SHT(SHT_HASH, 5, "symbol hash table") \ 261 _ELF_DEFINE_SHT(SHT_DYNAMIC, 6, \ 262 "information for dynamic linking") \ 263 _ELF_DEFINE_SHT(SHT_NOTE, 7, "additional notes") \ 264 _ELF_DEFINE_SHT(SHT_NOBITS, 8, "section occupying no space") \ 265 _ELF_DEFINE_SHT(SHT_REL, 9, \ 266 "relocation entries without addends") \ 267 _ELF_DEFINE_SHT(SHT_SHLIB, 10, "reserved") \ 268 _ELF_DEFINE_SHT(SHT_DYNSYM, 11, "symbol table") \ 269 _ELF_DEFINE_SHT(SHT_INIT_ARRAY, 14, \ 270 "pointers to initialization functions") \ 271 _ELF_DEFINE_SHT(SHT_FINI_ARRAY, 15, \ 272 "pointers to termination functions") \ 273 _ELF_DEFINE_SHT(SHT_PREINIT_ARRAY, 16, \ 274 "pointers to functions called before initialization") \ 275 _ELF_DEFINE_SHT(SHT_GROUP, 17, "defines a section group") \ 276 _ELF_DEFINE_SHT(SHT_SYMTAB_SHNDX, 18, \ 277 "used for extended section numbering") \ 278 _ELF_DEFINE_SHT(SHT_LOOS, 0x60000000UL, \ 279 "start of OS-specific range") \ 280 _ELF_DEFINE_SHT(SHT_SUNW_dof, 0x6FFFFFF4UL, \ 281 "used by dtrace") \ 282 _ELF_DEFINE_SHT(SHT_SUNW_cap, 0x6FFFFFF5UL, \ 283 "capability requirements") \ 284 _ELF_DEFINE_SHT(SHT_GNU_ATTRIBUTES, 0x6FFFFFF5UL, \ 285 "object attributes") \ 286 _ELF_DEFINE_SHT(SHT_SUNW_SIGNATURE, 0x6FFFFFF6UL, \ 287 "module verification signature") \ 288 _ELF_DEFINE_SHT(SHT_GNU_HASH, 0x6FFFFFF6UL, \ 289 "GNU Hash sections") \ 290 _ELF_DEFINE_SHT(SHT_GNU_LIBLIST, 0x6FFFFFF7UL, \ 291 "List of libraries to be prelinked") \ 292 _ELF_DEFINE_SHT(SHT_SUNW_ANNOTATE, 0x6FFFFFF7UL, \ 293 "special section where unresolved references are allowed") \ 294 _ELF_DEFINE_SHT(SHT_SUNW_DEBUGSTR, 0x6FFFFFF8UL, \ 295 "debugging information") \ 296 _ELF_DEFINE_SHT(SHT_CHECKSUM, 0x6FFFFFF8UL, \ 297 "checksum for dynamic shared objects") \ 298 _ELF_DEFINE_SHT(SHT_SUNW_DEBUG, 0x6FFFFFF9UL, \ 299 "debugging information") \ 300 _ELF_DEFINE_SHT(SHT_SUNW_move, 0x6FFFFFFAUL, \ 301 "information to handle partially initialized symbols") \ 302 _ELF_DEFINE_SHT(SHT_SUNW_COMDAT, 0x6FFFFFFBUL, \ 303 "section supporting merging of multiple copies of data") \ 304 _ELF_DEFINE_SHT(SHT_SUNW_syminfo, 0x6FFFFFFCUL, \ 305 "additional symbol information") \ 306 _ELF_DEFINE_SHT(SHT_SUNW_verdef, 0x6FFFFFFDUL, \ 307 "symbol versioning information") \ 308 _ELF_DEFINE_SHT(SHT_SUNW_verneed, 0x6FFFFFFEUL, \ 309 "symbol versioning requirements") \ 310 _ELF_DEFINE_SHT(SHT_SUNW_versym, 0x6FFFFFFFUL, \ 311 "symbol versioning table") \ 312 _ELF_DEFINE_SHT(SHT_HIOS, 0x6FFFFFFFUL, \ 313 "end of OS-specific range") \ 314 _ELF_DEFINE_SHT(SHT_LOPROC, 0x70000000UL, \ 315 "start of processor-specific range") \ 316 _ELF_DEFINE_SHT(SHT_ARM_EXIDX, 0x70000001UL, \ 317 "exception index table") \ 318 _ELF_DEFINE_SHT(SHT_ARM_PREEMPTMAP, 0x70000002UL, \ 319 "BPABI DLL dynamic linking preemption map") \ 320 _ELF_DEFINE_SHT(SHT_ARM_ATTRIBUTES, 0x70000003UL, \ 321 "object file compatibility attributes") \ 322 _ELF_DEFINE_SHT(SHT_ARM_DEBUGOVERLAY, 0x70000004UL, \ 323 "overlay debug information") \ 324 _ELF_DEFINE_SHT(SHT_ARM_OVERLAYSECTION, 0x70000005UL, \ 325 "overlay debug information") \ 326 _ELF_DEFINE_SHT(SHT_MIPS_LIBLIST, 0x70000000UL, \ 327 "DSO library information used in link") \ 328 _ELF_DEFINE_SHT(SHT_MIPS_MSYM, 0x70000001UL, \ 329 "MIPS symbol table extension") \ 330 _ELF_DEFINE_SHT(SHT_MIPS_CONFLICT, 0x70000002UL, \ 331 "symbol conflicting with DSO-defined symbols ") \ 332 _ELF_DEFINE_SHT(SHT_MIPS_GPTAB, 0x70000003UL, \ 333 "global pointer table") \ 334 _ELF_DEFINE_SHT(SHT_MIPS_UCODE, 0x70000004UL, \ 335 "reserved") \ 336 _ELF_DEFINE_SHT(SHT_MIPS_DEBUG, 0x70000005UL, \ 337 "reserved (obsolete debug information)") \ 338 _ELF_DEFINE_SHT(SHT_MIPS_REGINFO, 0x70000006UL, \ 339 "register usage information") \ 340 _ELF_DEFINE_SHT(SHT_MIPS_PACKAGE, 0x70000007UL, \ 341 "OSF reserved") \ 342 _ELF_DEFINE_SHT(SHT_MIPS_PACKSYM, 0x70000008UL, \ 343 "OSF reserved") \ 344 _ELF_DEFINE_SHT(SHT_MIPS_RELD, 0x70000009UL, \ 345 "dynamic relocation") \ 346 _ELF_DEFINE_SHT(SHT_MIPS_IFACE, 0x7000000BUL, \ 347 "subprogram interface information") \ 348 _ELF_DEFINE_SHT(SHT_MIPS_CONTENT, 0x7000000CUL, \ 349 "section content classification") \ 350 _ELF_DEFINE_SHT(SHT_MIPS_OPTIONS, 0x7000000DUL, \ 351 "general options") \ 352 _ELF_DEFINE_SHT(SHT_MIPS_DELTASYM, 0x7000001BUL, \ 353 "Delta C++: symbol table") \ 354 _ELF_DEFINE_SHT(SHT_MIPS_DELTAINST, 0x7000001CUL, \ 355 "Delta C++: instance table") \ 356 _ELF_DEFINE_SHT(SHT_MIPS_DELTACLASS, 0x7000001DUL, \ 357 "Delta C++: class table") \ 358 _ELF_DEFINE_SHT(SHT_MIPS_DWARF, 0x7000001EUL, \ 359 "DWARF debug information") \ 360 _ELF_DEFINE_SHT(SHT_MIPS_DELTADECL, 0x7000001FUL, \ 361 "Delta C++: declarations") \ 362 _ELF_DEFINE_SHT(SHT_MIPS_SYMBOL_LIB, 0x70000020UL, \ 363 "symbol-to-library mapping") \ 364 _ELF_DEFINE_SHT(SHT_MIPS_EVENTS, 0x70000021UL, \ 365 "event locations") \ 366 _ELF_DEFINE_SHT(SHT_MIPS_TRANSLATE, 0x70000022UL, \ 367 "???") \ 368 _ELF_DEFINE_SHT(SHT_MIPS_PIXIE, 0x70000023UL, \ 369 "special pixie sections") \ 370 _ELF_DEFINE_SHT(SHT_MIPS_XLATE, 0x70000024UL, \ 371 "address translation table") \ 372 _ELF_DEFINE_SHT(SHT_MIPS_XLATE_DEBUG, 0x70000025UL, \ 373 "SGI internal address translation table") \ 374 _ELF_DEFINE_SHT(SHT_MIPS_WHIRL, 0x70000026UL, \ 375 "intermediate code") \ 376 _ELF_DEFINE_SHT(SHT_MIPS_EH_REGION, 0x70000027UL, \ 377 "C++ exception handling region info") \ 378 _ELF_DEFINE_SHT(SHT_MIPS_XLATE_OLD, 0x70000028UL, \ 379 "obsolete") \ 380 _ELF_DEFINE_SHT(SHT_MIPS_PDR_EXCEPTION, 0x70000029UL, \ 381 "runtime procedure descriptor table exception information") \ 382 _ELF_DEFINE_SHT(SHT_MIPS_ABIFLAGS, 0x7000002AUL, \ 383 "ABI flags") \ 384 _ELF_DEFINE_SHT(SHT_SPARC_GOTDATA, 0x70000000UL, \ 385 "SPARC-specific data") \ 386 _ELF_DEFINE_SHT(SHT_AMD64_UNWIND, 0x70000001UL, \ 387 "unwind tables for the AMD64") \ 388 _ELF_DEFINE_SHT(SHT_ORDERED, 0x7FFFFFFFUL, \ 389 "sort entries in the section") \ 390 _ELF_DEFINE_SHT(SHT_HIPROC, 0x7FFFFFFFUL, \ 391 "end of processor-specific range") \ 392 _ELF_DEFINE_SHT(SHT_LOUSER, 0x80000000UL, \ 393 "start of application-specific range") \ 394 _ELF_DEFINE_SHT(SHT_HIUSER, 0xFFFFFFFFUL, \ 395 "end of application-specific range") 396 397 #undef _ELF_DEFINE_SHT 398 #define _ELF_DEFINE_SHT(N, V, DESCR) N = V , 399 enum { 400 _ELF_DEFINE_SECTION_TYPES() 401 SHT__LAST__ = SHT_HIUSER 402 }; 403 404 #define PN_XNUM 0xFFFFU /* Use extended section numbering. */ 405 406 /** 407 ** ELF Types. 408 **/ 409 410 typedef uint64_t Elf64_Addr; /* Program address. */ 411 typedef uint16_t Elf64_Half; /* Unsigned medium integer. */ 412 typedef uint64_t Elf64_Off; /* File offset. */ 413 typedef int32_t Elf64_Sword; /* Signed integer. */ 414 typedef uint32_t Elf64_Word; /* Unsigned integer. */ 415 typedef uint64_t Elf64_Lword; /* Unsigned long integer. */ 416 typedef uint64_t Elf64_Xword; /* Unsigned long integer. */ 417 typedef int64_t Elf64_Sxword; /* Signed long integer. */ 418 419 /* 420 * Capability descriptors. 421 */ 422 typedef struct { 423 Elf64_Xword c_tag; /* Type of entry. */ 424 union { 425 Elf64_Xword c_val; /* Integer value. */ 426 Elf64_Addr c_ptr; /* Pointer value. */ 427 } c_un; 428 } Elf64_Cap; 429 430 /* 431 * Dynamic section entries. 432 */ 433 typedef struct { 434 Elf64_Sxword d_tag; /* Type of entry. */ 435 union { 436 Elf64_Xword d_val; /* Integer value. */ 437 Elf64_Addr d_ptr; /* Pointer value; */ 438 } d_un; 439 } Elf64_Dyn; 440 441 /* 442 * The executable header (EHDR). 443 */ 444 typedef struct { 445 unsigned char e_ident[EI_NIDENT]; /* ELF identification. */ 446 Elf64_Half e_type; /* Object file type (ET_*). */ 447 Elf64_Half e_machine; /* Machine type (EM_*). */ 448 Elf64_Word e_version; /* File format version (EV_*). */ 449 Elf64_Addr e_entry; /* Start address. */ 450 Elf64_Off e_phoff; /* File offset to the PHDR table. */ 451 Elf64_Off e_shoff; /* File offset to the SHDRheader. */ 452 Elf64_Word e_flags; /* Flags (EF_*). */ 453 Elf64_Half e_ehsize; /* Elf header size in bytes. */ 454 Elf64_Half e_phentsize; /* PHDR table entry size in bytes. */ 455 Elf64_Half e_phnum; /* Number of PHDR entries. */ 456 Elf64_Half e_shentsize; /* SHDR table entry size in bytes. */ 457 Elf64_Half e_shnum; /* Number of SHDR entries. */ 458 Elf64_Half e_shstrndx; /* Index of section name string table. */ 459 } Elf64_Ehdr; 460 461 /* 462 * Note descriptors. 463 */ 464 465 typedef struct { 466 uint32_t n_namesz; /* Length of note's name. */ 467 uint32_t n_descsz; /* Length of note's value. */ 468 uint32_t n_type; /* Type of note. */ 469 } Elf_Note; 470 471 /* 472 * Program Header Table (PHDR) entries. 473 */ 474 typedef struct { 475 Elf64_Word p_type; /* Type of segment. */ 476 Elf64_Word p_flags; /* Segment flags. */ 477 Elf64_Off p_offset; /* File offset to segment. */ 478 Elf64_Addr p_vaddr; /* Virtual address in memory. */ 479 Elf64_Addr p_paddr; /* Physical address (if relevant). */ 480 Elf64_Xword p_filesz; /* Size of segment in file. */ 481 Elf64_Xword p_memsz; /* Size of segment in memory. */ 482 Elf64_Xword p_align; /* Alignment constraints. */ 483 } Elf64_Phdr; 484 485 /* 486 * Move entries, for describing data in COMMON blocks in a compact 487 * manner. 488 */ 489 typedef struct { 490 Elf64_Lword m_value; /* Initialization value. */ 491 Elf64_Xword m_info; /* Encoded size and index. */ 492 Elf64_Xword m_poffset; /* Offset relative to symbol. */ 493 Elf64_Half m_repeat; /* Repeat count. */ 494 Elf64_Half m_stride; /* Number of units to skip. */ 495 } Elf64_Move; 496 497 /* 498 * Section Header Table (SHDR) entries. 499 */ 500 typedef struct { 501 Elf64_Word sh_name; /* index of section name */ 502 Elf64_Word sh_type; /* section type */ 503 Elf64_Xword sh_flags; /* section flags */ 504 Elf64_Addr sh_addr; /* in-memory address of section */ 505 Elf64_Off sh_offset; /* file offset of section */ 506 Elf64_Xword sh_size; /* section size in bytes */ 507 Elf64_Word sh_link; /* section header table link */ 508 Elf64_Word sh_info; /* extra information */ 509 Elf64_Xword sh_addralign; /* alignment constraint */ 510 Elf64_Xword sh_entsize; /* size for fixed-size entries */ 511 } Elf64_Shdr; 512 513 /* 514 * Symbol table entries. 515 */ 516 typedef struct { 517 Elf64_Word st_name; /* index of symbol's name */ 518 unsigned char st_info; /* type and binding attributes */ 519 unsigned char st_other; /* visibility */ 520 Elf64_Half st_shndx; /* index of related section */ 521 Elf64_Addr st_value; /* value for the symbol */ 522 Elf64_Xword st_size; /* size of associated data */ 523 } Elf64_Sym; 524 525 /* 526 * Syminfo descriptors, containing additional symbol information. 527 */ 528 typedef struct { 529 Elf64_Half si_boundto; /* Entry index with additional flags. */ 530 Elf64_Half si_flags; /* Flags. */ 531 } Elf64_Syminfo; 532 533 /* 534 * Relocation descriptors. 535 */ 536 typedef struct { 537 Elf64_Addr r_offset; /* location to apply relocation to */ 538 Elf64_Xword r_info; /* type+section for relocation */ 539 } Elf64_Rel; 540 541 typedef struct { 542 Elf64_Addr r_offset; /* location to apply relocation to */ 543 Elf64_Xword r_info; /* type+section for relocation */ 544 Elf64_Sxword r_addend; /* constant addend */ 545 } Elf64_Rela; 546 547 /* 548 * Symbol versioning structures. 549 */ 550 typedef struct { 551 Elf64_Word vda_name; /* Index to name. */ 552 Elf64_Word vda_next; /* Offset to next entry. */ 553 } Elf64_Verdaux; 554 555 typedef struct { 556 Elf64_Word vna_hash; /* Hash value of dependency name. */ 557 Elf64_Half vna_flags; /* Flags. */ 558 Elf64_Half vna_other; /* Unused. */ 559 Elf64_Word vna_name; /* Offset to dependency name. */ 560 Elf64_Word vna_next; /* Offset to next vernaux entry. */ 561 } Elf64_Vernaux; 562 563 typedef struct { 564 Elf64_Half vd_version; /* Version information. */ 565 Elf64_Half vd_flags; /* Flags. */ 566 Elf64_Half vd_ndx; /* Index into the versym section. */ 567 Elf64_Half vd_cnt; /* Number of aux entries. */ 568 Elf64_Word vd_hash; /* Hash value of name. */ 569 Elf64_Word vd_aux; /* Offset to aux entries. */ 570 Elf64_Word vd_next; /* Offset to next version definition. */ 571 } Elf64_Verdef; 572 573 typedef struct { 574 Elf64_Half vn_version; /* Version number. */ 575 Elf64_Half vn_cnt; /* Number of aux entries. */ 576 Elf64_Word vn_file; /* Offset of associated file name. */ 577 Elf64_Word vn_aux; /* Offset of vernaux array. */ 578 Elf64_Word vn_next; /* Offset of next verneed entry. */ 579 } Elf64_Verneed; 580 581 /* 582 * The header for GNU-style hash sections. 583 */ 584 585 typedef struct { 586 uint32_t gh_nbuckets; /* Number of hash buckets. */ 587 uint32_t gh_symndx; /* First visible symbol in .dynsym. */ 588 uint32_t gh_maskwords; /* #maskwords used in bloom filter. */ 589 uint32_t gh_shift2; /* Bloom filter shift count. */ 590 } Elf_GNU_Hash_Header; 591 592 /* libelf.h */ 593 /* Library private data structures */ 594 typedef struct _Elf Elf; 595 typedef struct _Elf_Scn Elf_Scn; 596 597 /* File types */ 598 typedef enum { 599 ELF_K_NONE = 0, 600 ELF_K_AR, /* `ar' archives */ 601 ELF_K_COFF, /* COFF files (unsupported) */ 602 ELF_K_ELF, /* ELF files */ 603 ELF_K_NUM 604 } Elf_Kind; 605 606 /* Data types */ 607 typedef enum { 608 ELF_T_ADDR, 609 ELF_T_BYTE, 610 ELF_T_CAP, 611 ELF_T_DYN, 612 ELF_T_EHDR, 613 ELF_T_HALF, 614 ELF_T_LWORD, 615 ELF_T_MOVE, 616 ELF_T_MOVEP, 617 ELF_T_NOTE, 618 ELF_T_OFF, 619 ELF_T_PHDR, 620 ELF_T_REL, 621 ELF_T_RELA, 622 ELF_T_SHDR, 623 ELF_T_SWORD, 624 ELF_T_SXWORD, 625 ELF_T_SYMINFO, 626 ELF_T_SYM, 627 ELF_T_VDEF, 628 ELF_T_VNEED, 629 ELF_T_WORD, 630 ELF_T_XWORD, 631 ELF_T_GNUHASH, /* GNU style hash tables. */ 632 ELF_T_NUM 633 } Elf_Type; 634 635 #define ELF_T_FIRST ELF_T_ADDR 636 #define ELF_T_LAST ELF_T_GNUHASH 637 638 /* Commands */ 639 typedef enum { 640 ELF_C_NULL = 0, 641 ELF_C_CLR, 642 ELF_C_FDDONE, 643 ELF_C_FDREAD, 644 ELF_C_RDWR, 645 ELF_C_READ, 646 ELF_C_SET, 647 ELF_C_WRITE, 648 ELF_C_NUM 649 } Elf_Cmd; 650 651 /* 652 * An `Elf_Data' structure describes data in an 653 * ELF section. 654 */ 655 typedef struct _Elf_Data { 656 /* 657 * `Public' members that are part of the ELF(3) API. 658 */ 659 uint64_t d_align; 660 void *d_buf; 661 uint64_t d_off; 662 uint64_t d_size; 663 Elf_Type d_type; 664 unsigned int d_version; 665 } Elf_Data; 666 667 /* 668 * An `Elf_Arhdr' structure describes an archive 669 * header. 670 */ 671 typedef struct { 672 time_t ar_date; 673 char *ar_name; /* archive member name */ 674 gid_t ar_gid; 675 mode_t ar_mode; 676 char *ar_rawname; /* 'raw' member name */ 677 size_t ar_size; 678 uid_t ar_uid; 679 680 /* 681 * Members that are not part of the public API. 682 */ 683 unsigned int ar_flags; 684 } Elf_Arhdr; 685 686 /* 687 * An `Elf_Arsym' describes an entry in the archive 688 * symbol table. 689 */ 690 typedef struct { 691 off_t as_off; /* byte offset to member's header */ 692 unsigned long as_hash; /* elf_hash() value for name */ 693 char *as_name; /* null terminated symbol name */ 694 } Elf_Arsym; 695 696 /* 697 * Error numbers. 698 */ 699 700 enum Elf_Error { 701 ELF_E_NONE, /* No error */ 702 ELF_E_ARCHIVE, /* Malformed ar(1) archive */ 703 ELF_E_ARGUMENT, /* Invalid argument */ 704 ELF_E_CLASS, /* Mismatched ELF class */ 705 ELF_E_DATA, /* Invalid data descriptor */ 706 ELF_E_HEADER, /* Missing or malformed ELF header */ 707 ELF_E_IO, /* I/O error */ 708 ELF_E_LAYOUT, /* Layout constraint violation */ 709 ELF_E_MODE, /* Wrong mode for ELF descriptor */ 710 ELF_E_RANGE, /* Value out of range */ 711 ELF_E_RESOURCE, /* Resource exhaustion */ 712 ELF_E_SECTION, /* Invalid section descriptor */ 713 ELF_E_SEQUENCE, /* API calls out of sequence */ 714 ELF_E_UNIMPL, /* Feature is unimplemented */ 715 ELF_E_VERSION, /* Unknown API version */ 716 ELF_E_NUM /* Max error number */ 717 }; 718 719 /* 720 * Flags defined by the API. 721 */ 722 723 #define ELF_F_LAYOUT 0x001U /* application will layout the file */ 724 #define ELF_F_DIRTY 0x002U /* a section or ELF file is dirty */ 725 726 #ifdef __cplusplus 727 extern "C" { 728 #endif 729 static 730 Elf *elf_begin(int _fd, Elf_Cmd _cmd, Elf *_elf); 731 static 732 int elf_end(Elf *_elf); 733 static 734 const char *elf_errmsg(int _error); 735 static 736 int elf_errno(void); 737 static 738 Elf_Data *elf_getdata(Elf_Scn *, Elf_Data *); 739 static 740 char *elf_strptr(Elf *_elf, size_t _section, size_t _offset); 741 static 742 unsigned int elf_version(unsigned int _version); 743 static 744 Elf_Scn *elf_nextscn(Elf *_elf, Elf_Scn *_scn); 745 #ifdef __cplusplus 746 } 747 #endif 748 749 /* gelf.h */ 750 typedef Elf64_Shdr GElf_Shdr; /* Section header */ 751 typedef Elf64_Sym GElf_Sym; /* Symbol table entries */ 752 753 #ifdef __cplusplus 754 extern "C" { 755 #endif 756 static 757 GElf_Shdr *gelf_getshdr(Elf_Scn *_scn, GElf_Shdr *_dst); 758 static 759 GElf_Sym *gelf_getsym(Elf_Data *_src, int _index, GElf_Sym *_dst); 760 #ifdef __cplusplus 761 } 762 #endif 763 764 /* _libelf.h */ 765 /* 766 * Library-private data structures. 767 */ 768 769 #define LIBELF_MSG_SIZE 256 770 771 struct _libelf_globals { 772 int libelf_arch; 773 unsigned int libelf_byteorder; 774 int libelf_class; 775 int libelf_error; 776 int libelf_fillchar; 777 unsigned int libelf_version; 778 unsigned char libelf_msg[LIBELF_MSG_SIZE]; 779 }; 780 781 #if 0 782 extern struct _libelf_globals _libelf; 783 #endif 784 785 #define LIBELF_PRIVATE(N) (_libelf.libelf_##N) 786 787 #define LIBELF_ELF_ERROR_MASK 0xFF 788 #define LIBELF_OS_ERROR_SHIFT 8 789 790 #define LIBELF_ERROR(E, O) (((E) & LIBELF_ELF_ERROR_MASK) | \ 791 ((O) << LIBELF_OS_ERROR_SHIFT)) 792 793 #define LIBELF_SET_ERROR(E, O) do { \ 794 LIBELF_PRIVATE(error) = LIBELF_ERROR(ELF_E_##E, (O)); \ 795 } while (0) 796 797 /* 798 * Flags for library internal use. These use the upper 16 bits of the 799 * `e_flags' field. 800 */ 801 802 #define LIBELF_F_DATA_MALLOCED 0x040000U /* whether data was malloc'ed */ 803 #define LIBELF_F_RAWFILE_MALLOC 0x080000U /* whether e_rawfile was malloc'ed */ 804 #define LIBELF_F_RAWFILE_MMAP 0x100000U /* whether e_rawfile was mmap'ed */ 805 #define LIBELF_F_SHDRS_LOADED 0x200000U /* whether all shdrs were read in */ 806 #define LIBELF_F_SPECIAL_FILE 0x400000U /* non-regular file */ 807 808 struct _Elf { 809 int e_activations; /* activation count */ 810 unsigned int e_byteorder; /* ELFDATA* */ 811 int e_class; /* ELFCLASS* */ 812 Elf_Cmd e_cmd; /* ELF_C_* used at creation time */ 813 int e_fd; /* associated file descriptor */ 814 unsigned int e_flags; /* ELF_F_* & LIBELF_F_* flags */ 815 Elf_Kind e_kind; /* ELF_K_* */ 816 Elf *e_parent; /* non-NULL for archive members */ 817 unsigned char *e_rawfile; /* uninterpreted bytes */ 818 size_t e_rawsize; /* size of uninterpreted bytes */ 819 unsigned int e_version; /* file version */ 820 821 /* 822 * Header information for archive members. See the 823 * LIBELF_F_AR_HEADER flag. 824 */ 825 union { 826 Elf_Arhdr *e_arhdr; /* translated header */ 827 unsigned char *e_rawhdr; /* untranslated header */ 828 } e_hdr; 829 830 union { 831 struct { /* ar(1) archives */ 832 off_t e_next; /* set by elf_rand()/elf_next() */ 833 int e_nchildren; 834 unsigned char *e_rawstrtab; /* file name strings */ 835 size_t e_rawstrtabsz; 836 unsigned char *e_rawsymtab; /* symbol table */ 837 size_t e_rawsymtabsz; 838 Elf_Arsym *e_symtab; 839 size_t e_symtabsz; 840 } e_ar; 841 struct { /* regular ELF files */ 842 union { 843 #if 0 844 Elf32_Ehdr *e_ehdr32; 845 #endif 846 Elf64_Ehdr *e_ehdr64; 847 } e_ehdr; 848 union { 849 #if 0 850 Elf32_Phdr *e_phdr32; 851 #endif 852 Elf64_Phdr *e_phdr64; 853 } e_phdr; 854 STAILQ_HEAD(, _Elf_Scn) e_scn; /* section list */ 855 size_t e_nphdr; /* number of Phdr entries */ 856 size_t e_nscn; /* number of sections */ 857 size_t e_strndx; /* string table section index */ 858 } e_elf; 859 } e_u; 860 }; 861 862 /* 863 * The internal descriptor wrapping the "Elf_Data" type. 864 */ 865 struct _Libelf_Data { 866 Elf_Data d_data; /* The exported descriptor. */ 867 Elf_Scn *d_scn; /* The containing section */ 868 unsigned int d_flags; 869 STAILQ_ENTRY(_Libelf_Data) d_next; 870 }; 871 872 struct _Elf_Scn { 873 union { 874 #if 0 875 Elf32_Shdr s_shdr32; 876 #endif 877 Elf64_Shdr s_shdr64; 878 } s_shdr; 879 STAILQ_HEAD(, _Libelf_Data) s_data; /* translated data */ 880 STAILQ_HEAD(, _Libelf_Data) s_rawdata; /* raw data */ 881 STAILQ_ENTRY(_Elf_Scn) s_next; 882 struct _Elf *s_elf; /* parent ELF descriptor */ 883 unsigned int s_flags; /* flags for the section as a whole */ 884 size_t s_ndx; /* index# for this section */ 885 uint64_t s_offset; /* managed by elf_update() */ 886 uint64_t s_rawoff; /* original offset in the file */ 887 uint64_t s_size; /* managed by elf_update() */ 888 }; 889 890 enum { 891 ELF_TOFILE, 892 ELF_TOMEMORY 893 }; 894 895 /* PRIVATE */ 896 897 /* elf.c */ 898 static struct _libelf_globals _libelf = { 899 .libelf_arch = LIBELF_ARCH, 900 .libelf_byteorder = LIBELF_BYTEORDER, 901 .libelf_class = LIBELF_CLASS, 902 .libelf_error = 0, 903 .libelf_fillchar = 0, 904 .libelf_version = EV_NONE 905 }; 906 907 /* libelf_msize.c */ 908 struct msize { 909 size_t msz64; 910 }; 911 912 static struct msize msize[ELF_T_NUM] = { 913 [ELF_T_ADDR] = { .msz64 = sizeof(Elf64_Addr) }, 914 [ELF_T_BYTE] = { .msz64 = 1 }, 915 [ELF_T_CAP] = { .msz64 = sizeof(Elf64_Cap) }, 916 [ELF_T_DYN] = { .msz64 = sizeof(Elf64_Dyn) }, 917 [ELF_T_EHDR] = { .msz64 = sizeof(Elf64_Ehdr) }, 918 [ELF_T_GNUHASH] = { .msz64 = 1 }, 919 [ELF_T_HALF] = { .msz64 = sizeof(Elf64_Half) }, 920 [ELF_T_LWORD] = { .msz64 = sizeof(Elf64_Lword) }, 921 [ELF_T_MOVE] = { .msz64 = sizeof(Elf64_Move) }, 922 [ELF_T_MOVEP] = { .msz64 = 0 }, 923 [ELF_T_NOTE] = { .msz64 = 1 }, 924 [ELF_T_OFF] = { .msz64 = sizeof(Elf64_Off) }, 925 [ELF_T_PHDR] = { .msz64 = sizeof(Elf64_Phdr) }, 926 [ELF_T_REL] = { .msz64 = sizeof(Elf64_Rel) }, 927 [ELF_T_RELA] = { .msz64 = sizeof(Elf64_Rela) }, 928 [ELF_T_SHDR] = { .msz64 = sizeof(Elf64_Shdr) }, 929 [ELF_T_SWORD] = { .msz64 = sizeof(Elf64_Sword) }, 930 [ELF_T_SXWORD] = { .msz64 = sizeof(Elf64_Sxword) }, 931 [ELF_T_SYMINFO] = { .msz64 = sizeof(Elf64_Syminfo) }, 932 [ELF_T_SYM] = { .msz64 = sizeof(Elf64_Sym) }, 933 [ELF_T_VDEF] = { .msz64 = 1 }, 934 [ELF_T_VNEED] = { .msz64 = 1 }, 935 [ELF_T_WORD] = { .msz64 = sizeof(Elf64_Word) }, 936 [ELF_T_XWORD] = { .msz64 = sizeof(Elf64_Xword) }, 937 }; 938 939 static size_t 940 _libelf_msize(Elf_Type t, int elfclass, unsigned int version) 941 { 942 size_t sz; 943 944 assert(/*elfclass == ELFCLASS32 ||*/ elfclass == ELFCLASS64); 945 assert((signed) t >= ELF_T_FIRST && t <= ELF_T_LAST); 946 947 if (version != EV_CURRENT) { 948 LIBELF_SET_ERROR(VERSION, 0); 949 return (0); 950 } 951 952 sz = /* (elfclass == ELFCLASS32) ? msize[t].msz32 : */ msize[t].msz64; 953 954 return (sz); 955 } 956 957 /* libelf_fsize.c */ 958 struct tfsize { 959 size_t fsz64; 960 }; 961 962 static struct tfsize tfsize[ELF_T_NUM] = { 963 [ELF_T_ADDR] = { .fsz64 = sizeof(Elf64_Addr) }, 964 [ELF_T_BYTE] = { .fsz64 = 1 }, 965 [ELF_T_CAP] = { .fsz64 = sizeof(Elf64_Xword)+sizeof(Elf64_Xword)+0 }, 966 [ELF_T_DYN] = { .fsz64 = sizeof(Elf64_Sxword)+sizeof(Elf64_Xword)+0 }, 967 [ELF_T_EHDR] = { .fsz64 = EI_NIDENT 968 +sizeof(Elf64_Half)+sizeof(Elf64_Half) 969 +sizeof(Elf64_Word)+sizeof(Elf64_Addr) 970 +sizeof(Elf64_Off)+ sizeof(Elf64_Off) 971 +sizeof(Elf64_Word)+sizeof(Elf64_Half) 972 +sizeof(Elf64_Half)+sizeof(Elf64_Half) 973 +sizeof(Elf64_Half)+sizeof(Elf64_Half) 974 +sizeof(Elf64_Half)+0 }, 975 [ELF_T_GNUHASH] = { .fsz64 = 1 }, 976 [ELF_T_HALF] = { .fsz64 = sizeof(Elf64_Half) }, 977 [ELF_T_LWORD] = { .fsz64 = sizeof(Elf64_Lword) }, 978 [ELF_T_MOVE] = { .fsz64 = sizeof(Elf64_Lword)+sizeof(Elf64_Xword) 979 +sizeof(Elf64_Xword)+sizeof(Elf64_Half) 980 +sizeof(Elf64_Half)+0 }, 981 [ELF_T_MOVEP] = { .fsz64 = 0 }, 982 [ELF_T_NOTE] = { .fsz64 = 1 }, 983 [ELF_T_OFF] = { .fsz64 = sizeof(Elf64_Off) }, 984 [ELF_T_PHDR] = { .fsz64 = sizeof(Elf64_Word)+sizeof(Elf64_Word) 985 +sizeof(Elf64_Off)+ sizeof(Elf64_Addr) 986 +sizeof(Elf64_Addr)+sizeof(Elf64_Xword) 987 +sizeof(Elf64_Xword)+sizeof(Elf64_Xword)+0 }, 988 [ELF_T_REL] = { .fsz64 = sizeof(Elf64_Addr)+sizeof(Elf64_Xword)+0 }, 989 [ELF_T_RELA] = { .fsz64 = sizeof(Elf64_Addr)+sizeof(Elf64_Xword) 990 +sizeof(Elf64_Sxword)+0 }, 991 [ELF_T_SHDR] = { .fsz64 = sizeof(Elf64_Word)+sizeof(Elf64_Word) 992 +sizeof(Elf64_Xword)+sizeof(Elf64_Addr) 993 +sizeof(Elf64_Off)+ sizeof(Elf64_Xword) 994 +sizeof(Elf64_Word)+sizeof(Elf64_Word) 995 +sizeof(Elf64_Xword)+sizeof(Elf64_Xword)+0 }, 996 [ELF_T_SWORD] = { .fsz64 = sizeof(Elf64_Sword) }, 997 [ELF_T_SXWORD] = { .fsz64 = sizeof(Elf64_Sxword) }, 998 [ELF_T_SYMINFO] = { .fsz64 = sizeof(Elf64_Half)+sizeof(Elf64_Half)+0 }, 999 [ELF_T_SYM] = { .fsz64 = sizeof(Elf64_Word)+1+1+sizeof(Elf64_Half) 1000 +sizeof(Elf64_Addr)+sizeof(Elf64_Xword)+0 }, 1001 [ELF_T_VDEF] = { .fsz64 = 1 }, 1002 [ELF_T_VNEED] = { .fsz64 = 1 }, 1003 [ELF_T_WORD] = { .fsz64 = sizeof(Elf64_Word) }, 1004 [ELF_T_XWORD] = { .fsz64 = sizeof(Elf64_Xword) }, 1005 }; 1006 1007 static size_t 1008 _libelf_fsize(Elf_Type t, int ec, unsigned int v, size_t c) 1009 { 1010 size_t sz; 1011 1012 sz = 0; 1013 if (v != EV_CURRENT) 1014 LIBELF_SET_ERROR(VERSION, 0); 1015 else if ((int) t < ELF_T_FIRST || t > ELF_T_LAST) 1016 LIBELF_SET_ERROR(ARGUMENT, 0); 1017 else { 1018 sz = ec == ELFCLASS64 ? tfsize[t].fsz64 : /* tfsize[t].fsz32 */ 0; 1019 if (sz == 0) 1020 LIBELF_SET_ERROR(UNIMPL, 0); 1021 } 1022 1023 return (sz*c); 1024 } 1025 1026 /* gelf_fsize.c */ 1027 static size_t 1028 elf64_fsize(Elf_Type t, size_t c, unsigned int v) 1029 { 1030 return (_libelf_fsize(t, ELFCLASS64, v, c)); 1031 } 1032 1033 /* libelf_allocate.h */ 1034 static Elf * 1035 _libelf_allocate_elf(void) 1036 { 1037 Elf *e; 1038 1039 if ((e = malloc(sizeof(*e))) == NULL) { 1040 LIBELF_SET_ERROR(RESOURCE, errno); 1041 return NULL; 1042 } 1043 1044 e->e_activations = 1; 1045 e->e_hdr.e_rawhdr = NULL; 1046 e->e_byteorder = ELFDATANONE; 1047 e->e_class = ELFCLASSNONE; 1048 e->e_cmd = ELF_C_NULL; 1049 e->e_fd = -1; 1050 e->e_flags = 0; 1051 e->e_kind = ELF_K_NONE; 1052 e->e_parent = NULL; 1053 e->e_rawfile = NULL; 1054 e->e_rawsize = 0; 1055 e->e_version = LIBELF_PRIVATE(version); 1056 1057 (void) memset(&e->e_u, 0, sizeof(e->e_u)); 1058 1059 return (e); 1060 } 1061 1062 static void 1063 _libelf_init_elf(Elf *e, Elf_Kind kind) 1064 { 1065 assert(e != NULL); 1066 assert(e->e_kind == ELF_K_NONE); 1067 1068 e->e_kind = kind; 1069 1070 switch (kind) { 1071 case ELF_K_ELF: 1072 STAILQ_INIT(&e->e_u.e_elf.e_scn); 1073 break; 1074 default: 1075 break; 1076 } 1077 } 1078 1079 #define FREE(P) do { \ 1080 if (P) \ 1081 free(P); \ 1082 } while (0) 1083 1084 static Elf * 1085 _libelf_release_elf(Elf *e) 1086 { 1087 #if 0 1088 Elf_Arhdr *arh; 1089 #endif 1090 1091 switch (e->e_kind) { 1092 #if 0 1093 case ELF_K_AR: 1094 FREE(e->e_u.e_ar.e_symtab); 1095 break; 1096 #endif 1097 1098 case ELF_K_ELF: 1099 switch (e->e_class) { 1100 #if 0 1101 case ELFCLASS32: 1102 FREE(e->e_u.e_elf.e_ehdr.e_ehdr32); 1103 FREE(e->e_u.e_elf.e_phdr.e_phdr32); 1104 break; 1105 #endif 1106 case ELFCLASS64: 1107 FREE(e->e_u.e_elf.e_ehdr.e_ehdr64); 1108 FREE(e->e_u.e_elf.e_phdr.e_phdr64); 1109 break; 1110 } 1111 1112 assert(STAILQ_EMPTY(&e->e_u.e_elf.e_scn)); 1113 1114 #if 0 1115 if (e->e_flags & LIBELF_F_AR_HEADER) { 1116 arh = e->e_hdr.e_arhdr; 1117 FREE(arh->ar_name); 1118 FREE(arh->ar_rawname); 1119 free(arh); 1120 } 1121 #endif 1122 1123 break; 1124 1125 default: 1126 break; 1127 } 1128 1129 free(e); 1130 1131 return (NULL); 1132 } 1133 1134 #undef FREE 1135 1136 static struct _Libelf_Data * 1137 _libelf_allocate_data(Elf_Scn *s) 1138 { 1139 struct _Libelf_Data *d; 1140 1141 if ((d = calloc((size_t) 1, sizeof(*d))) == NULL) { 1142 LIBELF_SET_ERROR(RESOURCE, 0); 1143 return (NULL); 1144 } 1145 1146 d->d_scn = s; 1147 1148 return (d); 1149 } 1150 1151 static struct _Libelf_Data * 1152 _libelf_release_data(struct _Libelf_Data *d) 1153 { 1154 1155 if (d->d_flags & LIBELF_F_DATA_MALLOCED) 1156 free(d->d_data.d_buf); 1157 1158 free(d); 1159 1160 return (NULL); 1161 } 1162 1163 static Elf_Scn * 1164 _libelf_allocate_scn(Elf *e, size_t ndx) 1165 { 1166 Elf_Scn *s; 1167 1168 if ((s = calloc((size_t) 1, sizeof(Elf_Scn))) == NULL) { 1169 LIBELF_SET_ERROR(RESOURCE, errno); 1170 return (NULL); 1171 } 1172 1173 s->s_elf = e; 1174 s->s_ndx = ndx; 1175 1176 STAILQ_INIT(&s->s_data); 1177 STAILQ_INIT(&s->s_rawdata); 1178 1179 STAILQ_INSERT_TAIL(&e->e_u.e_elf.e_scn, s, s_next); 1180 1181 return (s); 1182 } 1183 1184 static Elf_Scn * 1185 _libelf_release_scn(Elf_Scn *s) 1186 { 1187 Elf *e; 1188 struct _Libelf_Data *d, *td; 1189 1190 assert(s != NULL); 1191 1192 STAILQ_FOREACH_SAFE(d, &s->s_data, d_next, td) { 1193 STAILQ_REMOVE(&s->s_data, d, _Libelf_Data, d_next); 1194 d = _libelf_release_data(d); 1195 } 1196 1197 STAILQ_FOREACH_SAFE(d, &s->s_rawdata, d_next, td) { 1198 assert((d->d_flags & LIBELF_F_DATA_MALLOCED) == 0); 1199 STAILQ_REMOVE(&s->s_rawdata, d, _Libelf_Data, d_next); 1200 d = _libelf_release_data(d); 1201 } 1202 1203 e = s->s_elf; 1204 1205 assert(e != NULL); 1206 1207 STAILQ_REMOVE(&e->e_u.e_elf.e_scn, s, _Elf_Scn, s_next); 1208 1209 free(s); 1210 1211 return (NULL); 1212 } 1213 1214 /* libelf_data.c */ 1215 static int 1216 _libelf_xlate_shtype(uint32_t sht) 1217 { 1218 /* 1219 * Look for known section types. 1220 */ 1221 switch (sht) { 1222 case SHT_DYNAMIC: 1223 return (ELF_T_DYN); 1224 case SHT_DYNSYM: 1225 return (ELF_T_SYM); 1226 case SHT_FINI_ARRAY: 1227 return (ELF_T_ADDR); 1228 case SHT_GNU_HASH: 1229 return (ELF_T_GNUHASH); 1230 case SHT_GNU_LIBLIST: 1231 return (ELF_T_WORD); 1232 case SHT_GROUP: 1233 return (ELF_T_WORD); 1234 case SHT_HASH: 1235 return (ELF_T_WORD); 1236 case SHT_INIT_ARRAY: 1237 return (ELF_T_ADDR); 1238 case SHT_NOBITS: 1239 return (ELF_T_BYTE); 1240 case SHT_NOTE: 1241 return (ELF_T_NOTE); 1242 case SHT_PREINIT_ARRAY: 1243 return (ELF_T_ADDR); 1244 case SHT_PROGBITS: 1245 return (ELF_T_BYTE); 1246 case SHT_REL: 1247 return (ELF_T_REL); 1248 case SHT_RELA: 1249 return (ELF_T_RELA); 1250 case SHT_STRTAB: 1251 return (ELF_T_BYTE); 1252 case SHT_SYMTAB: 1253 return (ELF_T_SYM); 1254 case SHT_SYMTAB_SHNDX: 1255 return (ELF_T_WORD); 1256 case SHT_SUNW_dof: 1257 return (ELF_T_BYTE); 1258 case SHT_SUNW_move: 1259 return (ELF_T_MOVE); 1260 case SHT_SUNW_syminfo: 1261 return (ELF_T_SYMINFO); 1262 case SHT_SUNW_verdef: /* == SHT_GNU_verdef */ 1263 return (ELF_T_VDEF); 1264 case SHT_SUNW_verneed: /* == SHT_GNU_verneed */ 1265 return (ELF_T_VNEED); 1266 case SHT_SUNW_versym: /* == SHT_GNU_versym */ 1267 return (ELF_T_HALF); 1268 default: 1269 /* 1270 * Values in the range [SHT_LOOS..SHT_HIUSER] (i.e., 1271 * OS, processor and user-defined section types) are 1272 * legal, but since we do not know anything more about 1273 * their semantics, we return a type of ELF_T_BYTE. 1274 */ 1275 if (sht >= SHT_LOOS && sht <= SHT_HIUSER) 1276 return (ELF_T_BYTE); 1277 1278 /* 1279 * Other values are unsupported. 1280 */ 1281 return (-1); 1282 } 1283 } 1284 1285 /* libelf_convert.c */ 1286 #define SWAP_BYTE(X) do { (void) (X); } while (0) 1287 #define SWAP_IDENT(X) do { (void) (X); } while (0) 1288 #define SWAP_HALF(X) do { \ 1289 uint16_t _x = (uint16_t) (X); \ 1290 uint32_t _t = _x & 0xFFU; \ 1291 _t <<= 8U; _x >>= 8U; _t |= _x & 0xFFU; \ 1292 (X) = (uint16_t) _t; \ 1293 } while (0) 1294 #define _SWAP_WORD(X, T) do { \ 1295 uint32_t _x = (uint32_t) (X); \ 1296 uint32_t _t = _x & 0xFF; \ 1297 _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ 1298 _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ 1299 _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ 1300 (X) = (T) _t; \ 1301 } while (0) 1302 #define SWAP_SWORD(X) _SWAP_WORD(X, /* Elf32_Sword */ Elf64_Sword) 1303 #define SWAP_WORD(X) _SWAP_WORD(X, /* Elf32_Word */ Elf64_Word) 1304 #define _SWAP_WORD64(X, T) do { \ 1305 uint64_t _x = (uint64_t) (X); \ 1306 uint64_t _t = _x & 0xFF; \ 1307 _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ 1308 _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ 1309 _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ 1310 _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ 1311 _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ 1312 _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ 1313 _t <<= 8; _x >>= 8; _t |= _x & 0xFF; \ 1314 (X) = (T) _t; \ 1315 } while (0) 1316 #define SWAP_ADDR64(X) _SWAP_WORD64(X, Elf64_Addr) 1317 #define SWAP_LWORD(X) _SWAP_WORD64(X, Elf64_Lword) 1318 #define SWAP_OFF64(X) _SWAP_WORD64(X, Elf64_Off) 1319 #define SWAP_SXWORD(X) _SWAP_WORD64(X, Elf64_Sxword) 1320 #define SWAP_XWORD(X) _SWAP_WORD64(X, Elf64_Xword) 1321 1322 #define READ_BYTE(P,X) do { \ 1323 const unsigned char *const _p = \ 1324 (const unsigned char *) (P); \ 1325 (X) = _p[0]; \ 1326 (P) = (P) + 1; \ 1327 } while (0) 1328 #define READ_HALF(P,X) do { \ 1329 uint16_t _t; \ 1330 unsigned char *const _q = (unsigned char *) &_t; \ 1331 const unsigned char *const _p = \ 1332 (const unsigned char *) (P); \ 1333 _q[0] = _p[0]; \ 1334 _q[1] = _p[1]; \ 1335 (P) = (P) + 2; \ 1336 (X) = _t; \ 1337 } while (0) 1338 #define _READ_WORD(P,X,T) do { \ 1339 uint32_t _t; \ 1340 unsigned char *const _q = (unsigned char *) &_t; \ 1341 const unsigned char *const _p = \ 1342 (const unsigned char *) (P); \ 1343 _q[0] = _p[0]; \ 1344 _q[1] = _p[1]; \ 1345 _q[2] = _p[2]; \ 1346 _q[3] = _p[3]; \ 1347 (P) = (P) + 4; \ 1348 (X) = (T) _t; \ 1349 } while (0) 1350 #define READ_SWORD(P,X) _READ_WORD(P, X, /*Elf32_Sword*/ Elf64_Sword) 1351 #define READ_WORD(P,X) _READ_WORD(P, X, /*Elf32_Word*/ Elf64_Word) 1352 #define _READ_WORD64(P,X,T) do { \ 1353 uint64_t _t; \ 1354 unsigned char *const _q = (unsigned char *) &_t; \ 1355 const unsigned char *const _p = \ 1356 (const unsigned char *) (P); \ 1357 _q[0] = _p[0]; \ 1358 _q[1] = _p[1]; \ 1359 _q[2] = _p[2]; \ 1360 _q[3] = _p[3]; \ 1361 _q[4] = _p[4]; \ 1362 _q[5] = _p[5]; \ 1363 _q[6] = _p[6]; \ 1364 _q[7] = _p[7]; \ 1365 (P) = (P) + 8; \ 1366 (X) = (T) _t; \ 1367 } while (0) 1368 #define READ_ADDR64(P,X) _READ_WORD64(P, X, Elf64_Addr) 1369 #define READ_LWORD(P,X) _READ_WORD64(P, X, Elf64_Lword) 1370 #define READ_OFF64(P,X) _READ_WORD64(P, X, Elf64_Off) 1371 #define READ_SXWORD(P,X) _READ_WORD64(P, X, Elf64_Sxword) 1372 #define READ_XWORD(P,X) _READ_WORD64(P, X, Elf64_Xword) 1373 #define READ_IDENT(P,X) do { \ 1374 (void) memcpy((X), (P), sizeof((X))); \ 1375 (P) = (P) + EI_NIDENT; \ 1376 } while (0) 1377 1378 #define ROUNDUP2(V,N) (V) = ((((V) + (N) - 1)) & ~((N) - 1)) 1379 1380 static int 1381 _libelf_cvt_ADDR64_tom(unsigned char *dst, size_t dsz, unsigned char *src, 1382 size_t count, int byteswap) 1383 { 1384 Elf64_Addr t, *d = (Elf64_Addr *) (uintptr_t) dst; 1385 size_t c; 1386 1387 if (dsz < count * sizeof(Elf64_Addr)) 1388 return (0); 1389 1390 if (!byteswap) { 1391 (void) memcpy(dst, src, count * sizeof(*d)); 1392 return (1); 1393 } 1394 1395 for (c = 0; c < count; c++) { 1396 READ_ADDR64(src,t); 1397 SWAP_ADDR64(t); 1398 *d++ = t; 1399 } 1400 1401 return (1); 1402 } 1403 1404 static int 1405 _libelf_cvt_CAP64_tom(unsigned char *dst, size_t dsz, unsigned char *src, 1406 size_t count, int byteswap) 1407 { 1408 Elf64_Cap t, *d; 1409 unsigned char *s,*s0; 1410 size_t fsz; 1411 1412 fsz = elf64_fsize(ELF_T_CAP, (size_t) 1, EV_CURRENT); 1413 d = ((Elf64_Cap *) (uintptr_t) dst) + (count - 1); 1414 s0 = src + (count - 1) * fsz; 1415 1416 if (dsz < count * sizeof(Elf64_Cap)) 1417 return (0); 1418 1419 while (count--) { 1420 s = s0; 1421 /* Read an Elf64_Cap */ 1422 READ_XWORD(s,t.c_tag); 1423 READ_XWORD(s,t.c_un.c_val); 1424 /**/ 1425 if (byteswap) { 1426 /* Swap an Elf64_Cap */ 1427 SWAP_XWORD(t.c_tag); 1428 SWAP_XWORD(t.c_un.c_val); 1429 /**/ 1430 } 1431 *d-- = t; s0 -= fsz; 1432 } 1433 1434 return (1); 1435 } 1436 1437 static int 1438 _libelf_cvt_DYN64_tom(unsigned char *dst, size_t dsz, unsigned char *src, 1439 size_t count, int byteswap) 1440 { 1441 Elf64_Dyn t, *d; 1442 unsigned char *s,*s0; 1443 size_t fsz; 1444 1445 fsz = elf64_fsize(ELF_T_DYN, (size_t) 1, EV_CURRENT); 1446 d = ((Elf64_Dyn *) (uintptr_t) dst) + (count - 1); 1447 s0 = src + (count - 1) * fsz; 1448 1449 if (dsz < count * sizeof(Elf64_Dyn)) 1450 return (0); 1451 1452 while (count--) { 1453 s = s0; 1454 /* Read an Elf64_Dyn */ 1455 READ_SXWORD(s,t.d_tag); 1456 READ_XWORD(s,t.d_un.d_ptr); 1457 /**/ 1458 if (byteswap) { 1459 /* Swap an Elf64_Dyn */ 1460 SWAP_SXWORD(t.d_tag); 1461 SWAP_XWORD(t.d_un.d_ptr); 1462 /**/ 1463 } 1464 *d-- = t; s0 -= fsz; 1465 } 1466 1467 return (1); 1468 } 1469 1470 static int 1471 _libelf_cvt_EHDR64_tom(unsigned char *dst, size_t dsz, unsigned char *src, 1472 size_t count, int byteswap) 1473 { 1474 Elf64_Ehdr t, *d; 1475 unsigned char *s,*s0; 1476 size_t fsz; 1477 1478 fsz = elf64_fsize(ELF_T_EHDR, (size_t) 1, EV_CURRENT); 1479 d = ((Elf64_Ehdr *) (uintptr_t) dst) + (count - 1); 1480 s0 = src + (count - 1) * fsz; 1481 1482 if (dsz < count * sizeof(Elf64_Ehdr)) 1483 return (0); 1484 1485 while (count--) { 1486 s = s0; 1487 /* Read an Elf64_Ehdr */ 1488 READ_IDENT(s,t.e_ident); 1489 READ_HALF(s,t.e_type); 1490 READ_HALF(s,t.e_machine); 1491 READ_WORD(s,t.e_version); 1492 READ_ADDR64(s,t.e_entry); 1493 READ_OFF64(s,t.e_phoff); 1494 READ_OFF64(s,t.e_shoff); 1495 READ_WORD(s,t.e_flags); 1496 READ_HALF(s,t.e_ehsize); 1497 READ_HALF(s,t.e_phentsize); 1498 READ_HALF(s,t.e_phnum); 1499 READ_HALF(s,t.e_shentsize); 1500 READ_HALF(s,t.e_shnum); 1501 READ_HALF(s,t.e_shstrndx); 1502 /**/ 1503 if (byteswap) { 1504 /* Swap an Elf64_Ehdr */ 1505 SWAP_IDENT(t.e_ident); 1506 SWAP_HALF(t.e_type); 1507 SWAP_HALF(t.e_machine); 1508 SWAP_WORD(t.e_version); 1509 SWAP_ADDR64(t.e_entry); 1510 SWAP_OFF64(t.e_phoff); 1511 SWAP_OFF64(t.e_shoff); 1512 SWAP_WORD(t.e_flags); 1513 SWAP_HALF(t.e_ehsize); 1514 SWAP_HALF(t.e_phentsize); 1515 SWAP_HALF(t.e_phnum); 1516 SWAP_HALF(t.e_shentsize); 1517 SWAP_HALF(t.e_shnum); 1518 SWAP_HALF(t.e_shstrndx); 1519 /**/ 1520 } 1521 *d-- = t; s0 -= fsz; 1522 } 1523 1524 return (1); 1525 } 1526 1527 static int 1528 _libelf_cvt_HALF_tom(unsigned char *dst, size_t dsz, unsigned char *src, 1529 size_t count, int byteswap) 1530 { 1531 Elf64_Half t, *d = (Elf64_Half *) (uintptr_t) dst; 1532 size_t c; 1533 1534 if (dsz < count * sizeof(Elf64_Half)) 1535 return (0); 1536 1537 if (!byteswap) { 1538 (void) memcpy(dst, src, count * sizeof(*d)); 1539 return (1); 1540 } 1541 1542 for (c = 0; c < count; c++) { 1543 READ_HALF(src,t); 1544 SWAP_HALF(t); 1545 *d++ = t; 1546 } 1547 1548 return (1); 1549 } 1550 1551 static int 1552 _libelf_cvt_LWORD_tom(unsigned char *dst, size_t dsz, unsigned char *src, 1553 size_t count, int byteswap) 1554 { 1555 Elf64_Lword t, *d = (Elf64_Lword *) (uintptr_t) dst; 1556 size_t c; 1557 1558 if (dsz < count * sizeof(Elf64_Lword)) 1559 return (0); 1560 1561 if (!byteswap) { 1562 (void) memcpy(dst, src, count * sizeof(*d)); 1563 return (1); 1564 } 1565 1566 for (c = 0; c < count; c++) { 1567 READ_LWORD(src,t); 1568 SWAP_LWORD(t); 1569 *d++ = t; 1570 } 1571 1572 return (1); 1573 } 1574 1575 static int 1576 _libelf_cvt_MOVE64_tom(unsigned char *dst, size_t dsz, unsigned char *src, 1577 size_t count, int byteswap) 1578 { 1579 Elf64_Move t, *d; 1580 unsigned char *s,*s0; 1581 size_t fsz; 1582 1583 fsz = elf64_fsize(ELF_T_MOVE, (size_t) 1, EV_CURRENT); 1584 d = ((Elf64_Move *) (uintptr_t) dst) + (count - 1); 1585 s0 = src + (count - 1) * fsz; 1586 1587 if (dsz < count * sizeof(Elf64_Move)) 1588 return (0); 1589 1590 while (count--) { 1591 s = s0; 1592 /* Read an Elf64_Move */ 1593 READ_LWORD(s,t.m_value); 1594 READ_XWORD(s,t.m_info); 1595 READ_XWORD(s,t.m_poffset); 1596 READ_HALF(s,t.m_repeat); 1597 READ_HALF(s,t.m_stride); 1598 /**/ 1599 if (byteswap) { 1600 /* Swap an Elf64_Move */ 1601 SWAP_LWORD(t.m_value); 1602 SWAP_XWORD(t.m_info); 1603 SWAP_XWORD(t.m_poffset); 1604 SWAP_HALF(t.m_repeat); 1605 SWAP_HALF(t.m_stride); 1606 /**/ 1607 } 1608 *d-- = t; s0 -= fsz; 1609 } 1610 1611 return (1); 1612 } 1613 1614 static int 1615 _libelf_cvt_OFF64_tom(unsigned char *dst, size_t dsz, unsigned char *src, 1616 size_t count, int byteswap) 1617 { 1618 Elf64_Off t, *d = (Elf64_Off *) (uintptr_t) dst; 1619 size_t c; 1620 1621 if (dsz < count * sizeof(Elf64_Off)) 1622 return (0); 1623 1624 if (!byteswap) { 1625 (void) memcpy(dst, src, count * sizeof(*d)); 1626 return (1); 1627 } 1628 1629 for (c = 0; c < count; c++) { 1630 READ_OFF64(src,t); 1631 SWAP_OFF64(t); 1632 *d++ = t; 1633 } 1634 1635 return (1); 1636 } 1637 1638 static int 1639 _libelf_cvt_PHDR64_tom(unsigned char *dst, size_t dsz, unsigned char *src, 1640 size_t count, int byteswap) 1641 { 1642 Elf64_Phdr t, *d; 1643 unsigned char *s,*s0; 1644 size_t fsz; 1645 1646 fsz = elf64_fsize(ELF_T_PHDR, (size_t) 1, EV_CURRENT); 1647 d = ((Elf64_Phdr *) (uintptr_t) dst) + (count - 1); 1648 s0 = src + (count - 1) * fsz; 1649 1650 if (dsz < count * sizeof(Elf64_Phdr)) 1651 return (0); 1652 1653 while (count--) { 1654 s = s0; 1655 /* Read an Elf64_Phdr */ 1656 READ_WORD(s,t.p_type); 1657 READ_WORD(s,t.p_flags); 1658 READ_OFF64(s,t.p_offset); 1659 READ_ADDR64(s,t.p_vaddr); 1660 READ_ADDR64(s,t.p_paddr); 1661 READ_XWORD(s,t.p_filesz); 1662 READ_XWORD(s,t.p_memsz); 1663 READ_XWORD(s,t.p_align); 1664 /**/ 1665 if (byteswap) { 1666 /* Swap an Elf64_Phdr */ 1667 SWAP_WORD(t.p_type); 1668 SWAP_WORD(t.p_flags); 1669 SWAP_OFF64(t.p_offset); 1670 SWAP_ADDR64(t.p_vaddr); 1671 SWAP_ADDR64(t.p_paddr); 1672 SWAP_XWORD(t.p_filesz); 1673 SWAP_XWORD(t.p_memsz); 1674 SWAP_XWORD(t.p_align); 1675 /**/ 1676 } 1677 *d-- = t; s0 -= fsz; 1678 } 1679 1680 return (1); 1681 } 1682 1683 static int 1684 _libelf_cvt_REL64_tom(unsigned char *dst, size_t dsz, unsigned char *src, 1685 size_t count, int byteswap) 1686 { 1687 Elf64_Rel t, *d; 1688 unsigned char *s,*s0; 1689 size_t fsz; 1690 1691 fsz = elf64_fsize(ELF_T_REL, (size_t) 1, EV_CURRENT); 1692 d = ((Elf64_Rel *) (uintptr_t) dst) + (count - 1); 1693 s0 = src + (count - 1) * fsz; 1694 1695 if (dsz < count * sizeof(Elf64_Rel)) 1696 return (0); 1697 1698 while (count--) { 1699 s = s0; 1700 /* Read an Elf64_Rel */ 1701 READ_ADDR64(s,t.r_offset); 1702 READ_XWORD(s,t.r_info); 1703 /**/ 1704 if (byteswap) { 1705 /* Swap an Elf64_Rel */ 1706 SWAP_ADDR64(t.r_offset); 1707 SWAP_XWORD(t.r_info); 1708 /**/ 1709 } 1710 *d-- = t; s0 -= fsz; 1711 } 1712 1713 return (1); 1714 } 1715 1716 static int 1717 _libelf_cvt_RELA64_tom(unsigned char *dst, size_t dsz, unsigned char *src, 1718 size_t count, int byteswap) 1719 { 1720 Elf64_Rela t, *d; 1721 unsigned char *s,*s0; 1722 size_t fsz; 1723 1724 fsz = elf64_fsize(ELF_T_RELA, (size_t) 1, EV_CURRENT); 1725 d = ((Elf64_Rela *) (uintptr_t) dst) + (count - 1); 1726 s0 = src + (count - 1) * fsz; 1727 1728 if (dsz < count * sizeof(Elf64_Rela)) 1729 return (0); 1730 1731 while (count--) { 1732 s = s0; 1733 /* Read an Elf64_Rela */ 1734 READ_ADDR64(s,t.r_offset); 1735 READ_XWORD(s,t.r_info); 1736 READ_SXWORD(s,t.r_addend); 1737 /**/ 1738 if (byteswap) { 1739 /* Swap an Elf64_Rela */ 1740 SWAP_ADDR64(t.r_offset); 1741 SWAP_XWORD(t.r_info); 1742 SWAP_SXWORD(t.r_addend); 1743 /**/ 1744 } 1745 *d-- = t; s0 -= fsz; 1746 } 1747 1748 return (1); 1749 } 1750 1751 static int 1752 _libelf_cvt_SHDR64_tom(unsigned char *dst, size_t dsz, unsigned char *src, 1753 size_t count, int byteswap) 1754 { 1755 Elf64_Shdr t, *d; 1756 unsigned char *s,*s0; 1757 size_t fsz; 1758 1759 fsz = elf64_fsize(ELF_T_SHDR, (size_t) 1, EV_CURRENT); 1760 d = ((Elf64_Shdr *) (uintptr_t) dst) + (count - 1); 1761 s0 = src + (count - 1) * fsz; 1762 1763 if (dsz < count * sizeof(Elf64_Shdr)) 1764 return (0); 1765 1766 while (count--) { 1767 s = s0; 1768 /* Read an Elf64_Shdr */ 1769 READ_WORD(s,t.sh_name); 1770 READ_WORD(s,t.sh_type); 1771 READ_XWORD(s,t.sh_flags); 1772 READ_ADDR64(s,t.sh_addr); 1773 READ_OFF64(s,t.sh_offset); 1774 READ_XWORD(s,t.sh_size); 1775 READ_WORD(s,t.sh_link); 1776 READ_WORD(s,t.sh_info); 1777 READ_XWORD(s,t.sh_addralign); 1778 READ_XWORD(s,t.sh_entsize); 1779 /**/ 1780 if (byteswap) { 1781 /* Swap an Elf64_Shdr */ 1782 SWAP_WORD(t.sh_name); 1783 SWAP_WORD(t.sh_type); 1784 SWAP_XWORD(t.sh_flags); 1785 SWAP_ADDR64(t.sh_addr); 1786 SWAP_OFF64(t.sh_offset); 1787 SWAP_XWORD(t.sh_size); 1788 SWAP_WORD(t.sh_link); 1789 SWAP_WORD(t.sh_info); 1790 SWAP_XWORD(t.sh_addralign); 1791 SWAP_XWORD(t.sh_entsize); 1792 /**/ 1793 } 1794 *d-- = t; s0 -= fsz; 1795 } 1796 1797 return (1); 1798 } 1799 1800 static int 1801 _libelf_cvt_SWORD_tom(unsigned char *dst, size_t dsz, unsigned char *src, 1802 size_t count, int byteswap) 1803 { 1804 Elf64_Sword t, *d = (Elf64_Sword *) (uintptr_t) dst; 1805 size_t c; 1806 1807 if (dsz < count * sizeof(Elf64_Sword)) 1808 return (0); 1809 1810 if (!byteswap) { 1811 (void) memcpy(dst, src, count * sizeof(*d)); 1812 return (1); 1813 } 1814 1815 for (c = 0; c < count; c++) { 1816 READ_SWORD(src,t); 1817 SWAP_SWORD(t); 1818 *d++ = t; 1819 } 1820 1821 return (1); 1822 } 1823 1824 static int 1825 _libelf_cvt_SXWORD_tom(unsigned char *dst, size_t dsz, unsigned char *src, 1826 size_t count, int byteswap) 1827 { 1828 Elf64_Sxword t, *d = (Elf64_Sxword *) (uintptr_t) dst; 1829 size_t c; 1830 1831 if (dsz < count * sizeof(Elf64_Sxword)) 1832 return (0); 1833 1834 if (!byteswap) { 1835 (void) memcpy(dst, src, count * sizeof(*d)); 1836 return (1); 1837 } 1838 1839 for (c = 0; c < count; c++) { 1840 READ_SXWORD(src,t); 1841 SWAP_SXWORD(t); 1842 *d++ = t; 1843 } 1844 1845 return (1); 1846 } 1847 1848 static int 1849 _libelf_cvt_SYMINFO64_tom(unsigned char *dst, size_t dsz, unsigned char *src, 1850 size_t count, int byteswap) 1851 { 1852 Elf64_Syminfo t, *d; 1853 unsigned char *s,*s0; 1854 size_t fsz; 1855 1856 fsz = elf64_fsize(ELF_T_SYMINFO, (size_t) 1, EV_CURRENT); 1857 d = ((Elf64_Syminfo *) (uintptr_t) dst) + (count - 1); 1858 s0 = src + (count - 1) * fsz; 1859 1860 if (dsz < count * sizeof(Elf64_Syminfo)) 1861 return (0); 1862 1863 while (count--) { 1864 s = s0; 1865 /* Read an Elf64_Syminfo */ 1866 READ_HALF(s,t.si_boundto); 1867 READ_HALF(s,t.si_flags); 1868 /**/ 1869 if (byteswap) { 1870 /* Swap an Elf64_Syminfo */ 1871 SWAP_HALF(t.si_boundto); 1872 SWAP_HALF(t.si_flags); 1873 /**/ 1874 } 1875 *d-- = t; s0 -= fsz; 1876 } 1877 1878 return (1); 1879 } 1880 1881 static int 1882 _libelf_cvt_SYM64_tom(unsigned char *dst, size_t dsz, unsigned char *src, 1883 size_t count, int byteswap) 1884 { 1885 Elf64_Sym t, *d; 1886 unsigned char *s,*s0; 1887 size_t fsz; 1888 1889 fsz = elf64_fsize(ELF_T_SYM, (size_t) 1, EV_CURRENT); 1890 d = ((Elf64_Sym *) (uintptr_t) dst) + (count - 1); 1891 s0 = src + (count - 1) * fsz; 1892 1893 if (dsz < count * sizeof(Elf64_Sym)) 1894 return (0); 1895 1896 while (count--) { 1897 s = s0; 1898 /* Read an Elf64_Sym */ 1899 READ_WORD(s,t.st_name); 1900 READ_BYTE(s,t.st_info); 1901 READ_BYTE(s,t.st_other); 1902 READ_HALF(s,t.st_shndx); 1903 READ_ADDR64(s,t.st_value); 1904 READ_XWORD(s,t.st_size); 1905 /**/ 1906 if (byteswap) { 1907 /* Swap an Elf64_Sym */ 1908 SWAP_WORD(t.st_name); 1909 SWAP_BYTE(t.st_info); 1910 SWAP_BYTE(t.st_other); 1911 SWAP_HALF(t.st_shndx); 1912 SWAP_ADDR64(t.st_value); 1913 SWAP_XWORD(t.st_size); 1914 /**/ 1915 } 1916 *d-- = t; s0 -= fsz; 1917 } 1918 1919 return (1); 1920 } 1921 1922 static int 1923 _libelf_cvt_WORD_tom(unsigned char *dst, size_t dsz, unsigned char *src, 1924 size_t count, int byteswap) 1925 { 1926 Elf64_Word t, *d = (Elf64_Word *) (uintptr_t) dst; 1927 size_t c; 1928 1929 if (dsz < count * sizeof(Elf64_Word)) 1930 return (0); 1931 1932 if (!byteswap) { 1933 (void) memcpy(dst, src, count * sizeof(*d)); 1934 return (1); 1935 } 1936 1937 for (c = 0; c < count; c++) { 1938 READ_WORD(src,t); 1939 SWAP_WORD(t); 1940 *d++ = t; 1941 } 1942 1943 return (1); 1944 } 1945 1946 static int 1947 _libelf_cvt_XWORD_tom(unsigned char *dst, size_t dsz, unsigned char *src, 1948 size_t count, int byteswap) 1949 { 1950 Elf64_Xword t, *d = (Elf64_Xword *) (uintptr_t) dst; 1951 size_t c; 1952 1953 if (dsz < count * sizeof(Elf64_Xword)) 1954 return (0); 1955 1956 if (!byteswap) { 1957 (void) memcpy(dst, src, count * sizeof(*d)); 1958 return (1); 1959 } 1960 1961 for (c = 0; c < count; c++) { 1962 READ_XWORD(src,t); 1963 SWAP_XWORD(t); 1964 *d++ = t; 1965 } 1966 1967 return (1); 1968 } 1969 1970 static int 1971 _libelf_cvt_VDEF64_tom(unsigned char *dst, size_t dsz, unsigned char *src, 1972 size_t count, int byteswap) 1973 { 1974 Elf64_Verdef t, *dp; 1975 Elf64_Verdaux a, *ap; 1976 const size_t verfsz = 20; 1977 const size_t auxfsz = 8; 1978 const size_t vermsz = sizeof(Elf64_Verdef); 1979 const size_t auxmsz = sizeof(Elf64_Verdaux); 1980 unsigned char * const dstend = dst + dsz; 1981 unsigned char * const srcend = src + count; 1982 unsigned char *dstaux, *s, *srcaux, *stmp; 1983 Elf64_Word aux, anext, cnt, vnext; 1984 1985 for (stmp = src, vnext = ~0U; 1986 vnext != 0 && stmp + verfsz <= srcend && dst + vermsz <= dstend; 1987 stmp += vnext, dst += vnext) { 1988 1989 /* Read in a VDEF structure. */ 1990 s = stmp; 1991 /* Read an Elf64_Verdef */ 1992 READ_HALF(s,t.vd_version); 1993 READ_HALF(s,t.vd_flags); 1994 READ_HALF(s,t.vd_ndx); 1995 READ_HALF(s,t.vd_cnt); 1996 READ_WORD(s,t.vd_hash); 1997 READ_WORD(s,t.vd_aux); 1998 READ_WORD(s,t.vd_next); 1999 /**/ 2000 if (byteswap) { 2001 /* Swap an Elf64_Verdef */ 2002 SWAP_HALF(t.vd_version); 2003 SWAP_HALF(t.vd_flags); 2004 SWAP_HALF(t.vd_ndx); 2005 SWAP_HALF(t.vd_cnt); 2006 SWAP_WORD(t.vd_hash); 2007 SWAP_WORD(t.vd_aux); 2008 SWAP_WORD(t.vd_next); 2009 /**/ 2010 } 2011 2012 dp = (Elf64_Verdef *) (uintptr_t) dst; 2013 *dp = t; 2014 2015 aux = t.vd_aux; 2016 cnt = t.vd_cnt; 2017 vnext = t.vd_next; 2018 2019 if (aux < vermsz) 2020 return (0); 2021 2022 /* Process AUX entries. */ 2023 for (anext = ~0U, dstaux = dst + aux, srcaux = stmp + aux; 2024 cnt != 0 && anext != 0 && dstaux + auxmsz <= dstend && 2025 srcaux + auxfsz <= srcend; 2026 dstaux += anext, srcaux += anext, cnt--) { 2027 2028 s = srcaux; 2029 /* Read an Elf64_Verdaux */ 2030 READ_WORD(s,a.vda_name); 2031 READ_WORD(s,a.vda_next); 2032 /**/ 2033 2034 if (byteswap) { 2035 /* Swap an Elf64_Verdaux */ 2036 SWAP_WORD(a.vda_name); 2037 SWAP_WORD(a.vda_next); 2038 /**/ 2039 } 2040 2041 anext = a.vda_next; 2042 2043 ap = ((Elf64_Verdaux *) (uintptr_t) dstaux); 2044 *ap = a; 2045 } 2046 2047 if (anext || cnt) 2048 return (0); 2049 } 2050 2051 if (vnext) 2052 return (0); 2053 2054 return (1); 2055 } 2056 2057 static int 2058 _libelf_cvt_VNEED64_tom(unsigned char *dst, size_t dsz, unsigned char *src, 2059 size_t count, int byteswap) 2060 { 2061 Elf64_Verneed t, *dp; 2062 Elf64_Vernaux a, *ap; 2063 const size_t verfsz = 16; 2064 const size_t auxfsz = 16; 2065 const size_t vermsz = sizeof(Elf64_Verneed); 2066 const size_t auxmsz = sizeof(Elf64_Vernaux); 2067 unsigned char * const dstend = dst + dsz; 2068 unsigned char * const srcend = src + count; 2069 unsigned char *dstaux, *s, *srcaux, *stmp; 2070 Elf64_Word aux, anext, cnt, vnext; 2071 2072 for (stmp = src, vnext = ~0U; 2073 vnext != 0 && stmp + verfsz <= srcend && dst + vermsz <= dstend; 2074 stmp += vnext, dst += vnext) { 2075 2076 /* Read in a VNEED structure. */ 2077 s = stmp; 2078 /* Read an Elf64_Verneed */ 2079 READ_HALF(s,t.vn_version); 2080 READ_HALF(s,t.vn_cnt); 2081 READ_WORD(s,t.vn_file); 2082 READ_WORD(s,t.vn_aux); 2083 READ_WORD(s,t.vn_next); 2084 /**/ 2085 if (byteswap) { 2086 /* Swap an Elf64_Verneed */ 2087 SWAP_HALF(t.vn_version); 2088 SWAP_HALF(t.vn_cnt); 2089 SWAP_WORD(t.vn_file); 2090 SWAP_WORD(t.vn_aux); 2091 SWAP_WORD(t.vn_next); 2092 /**/ 2093 } 2094 2095 dp = (Elf64_Verneed *) (uintptr_t) dst; 2096 *dp = t; 2097 2098 aux = t.vn_aux; 2099 cnt = t.vn_cnt; 2100 vnext = t.vn_next; 2101 2102 if (aux < vermsz) 2103 return (0); 2104 2105 /* Process AUX entries. */ 2106 for (anext = ~0U, dstaux = dst + aux, srcaux = stmp + aux; 2107 cnt != 0 && anext != 0 && dstaux + auxmsz <= dstend && 2108 srcaux + auxfsz <= srcend; 2109 dstaux += anext, srcaux += anext, cnt--) { 2110 2111 s = srcaux; 2112 /* Read an Elf64_Vernaux */ 2113 READ_WORD(s,a.vna_hash); 2114 READ_HALF(s,a.vna_flags); 2115 READ_HALF(s,a.vna_other); 2116 READ_WORD(s,a.vna_name); 2117 READ_WORD(s,a.vna_next); 2118 /**/ 2119 2120 if (byteswap) { 2121 /* Swap an Elf64_Vernaux */ 2122 SWAP_WORD(a.vna_hash); 2123 SWAP_HALF(a.vna_flags); 2124 SWAP_HALF(a.vna_other); 2125 SWAP_WORD(a.vna_name); 2126 SWAP_WORD(a.vna_next); 2127 /**/ 2128 } 2129 2130 anext = a.vna_next; 2131 2132 ap = ((Elf64_Vernaux *) (uintptr_t) dstaux); 2133 *ap = a; 2134 } 2135 2136 if (anext || cnt) 2137 return (0); 2138 } 2139 2140 if (vnext) 2141 return (0); 2142 2143 return (1); 2144 } 2145 2146 static int 2147 _libelf_cvt_BYTE_tox(unsigned char *dst, size_t dsz, unsigned char *src, 2148 size_t count, int byteswap) 2149 { 2150 (void) byteswap; 2151 if (dsz < count) 2152 return (0); 2153 if (dst != src) 2154 (void) memcpy(dst, src, count); 2155 return (1); 2156 } 2157 2158 static int 2159 _libelf_cvt_GNUHASH64_tom(unsigned char *dst, size_t dsz, unsigned char *src, 2160 size_t srcsz, int byteswap) 2161 { 2162 size_t sz; 2163 uint64_t t64, *bloom64; 2164 Elf_GNU_Hash_Header *gh; 2165 uint32_t n, nbuckets, nchains, maskwords, shift2, symndx, t32; 2166 uint32_t *buckets, *chains; 2167 2168 sz = 4 * sizeof(uint32_t); /* File header is 4 words long. */ 2169 if (dsz < sizeof(Elf_GNU_Hash_Header) || srcsz < sz) 2170 return (0); 2171 2172 /* Read in the section header and byteswap if needed. */ 2173 READ_WORD(src, nbuckets); 2174 READ_WORD(src, symndx); 2175 READ_WORD(src, maskwords); 2176 READ_WORD(src, shift2); 2177 2178 srcsz -= sz; 2179 2180 if (byteswap) { 2181 SWAP_WORD(nbuckets); 2182 SWAP_WORD(symndx); 2183 SWAP_WORD(maskwords); 2184 SWAP_WORD(shift2); 2185 } 2186 2187 /* Check source buffer and destination buffer sizes. */ 2188 sz = nbuckets * sizeof(uint32_t) + maskwords * sizeof(uint64_t); 2189 if (srcsz < sz || dsz < sz + sizeof(Elf_GNU_Hash_Header)) 2190 return (0); 2191 2192 gh = (Elf_GNU_Hash_Header *) (uintptr_t) dst; 2193 gh->gh_nbuckets = nbuckets; 2194 gh->gh_symndx = symndx; 2195 gh->gh_maskwords = maskwords; 2196 gh->gh_shift2 = shift2; 2197 2198 dsz -= sizeof(Elf_GNU_Hash_Header); 2199 dst += sizeof(Elf_GNU_Hash_Header); 2200 2201 bloom64 = (uint64_t *) (uintptr_t) dst; 2202 2203 /* Copy bloom filter data. */ 2204 for (n = 0; n < maskwords; n++) { 2205 READ_XWORD(src, t64); 2206 if (byteswap) 2207 SWAP_XWORD(t64); 2208 bloom64[n] = t64; 2209 } 2210 2211 /* The hash buckets follows the bloom filter. */ 2212 dst += maskwords * sizeof(uint64_t); 2213 buckets = (uint32_t *) (uintptr_t) dst; 2214 2215 for (n = 0; n < nbuckets; n++) { 2216 READ_WORD(src, t32); 2217 if (byteswap) 2218 SWAP_WORD(t32); 2219 buckets[n] = t32; 2220 } 2221 2222 dst += nbuckets * sizeof(uint32_t); 2223 2224 /* The hash chain follows the hash buckets. */ 2225 dsz -= sz; 2226 srcsz -= sz; 2227 2228 if (dsz < srcsz) /* Destination lacks space. */ 2229 return (0); 2230 2231 nchains = srcsz / sizeof(uint32_t); 2232 chains = (uint32_t *) (uintptr_t) dst; 2233 2234 for (n = 0; n < nchains; n++) { 2235 READ_WORD(src, t32); 2236 if (byteswap) 2237 SWAP_WORD(t32); 2238 *chains++ = t32; 2239 } 2240 2241 return (1); 2242 } 2243 2244 static int 2245 _libelf_cvt_NOTE_tom(unsigned char *dst, size_t dsz, unsigned char *src, 2246 size_t count, int byteswap) 2247 { 2248 uint32_t namesz, descsz, type; 2249 Elf_Note *en; 2250 size_t sz, hdrsz; 2251 2252 if (dsz < count) /* Destination buffer is too small. */ 2253 return (0); 2254 2255 hdrsz = 3 * sizeof(uint32_t); 2256 if (count < hdrsz) /* Source too small. */ 2257 return (0); 2258 2259 if (!byteswap) { 2260 (void) memcpy(dst, src, count); 2261 return (1); 2262 } 2263 2264 /* Process all notes in the section. */ 2265 while (count > hdrsz) { 2266 /* Read the note header. */ 2267 READ_WORD(src, namesz); 2268 READ_WORD(src, descsz); 2269 READ_WORD(src, type); 2270 2271 /* Translate. */ 2272 SWAP_WORD(namesz); 2273 SWAP_WORD(descsz); 2274 SWAP_WORD(type); 2275 2276 /* Copy out the translated note header. */ 2277 en = (Elf_Note *) (uintptr_t) dst; 2278 en->n_namesz = namesz; 2279 en->n_descsz = descsz; 2280 en->n_type = type; 2281 2282 dsz -= sizeof(Elf_Note); 2283 dst += sizeof(Elf_Note); 2284 count -= hdrsz; 2285 2286 ROUNDUP2(namesz, 4U); 2287 ROUNDUP2(descsz, 4U); 2288 2289 sz = namesz + descsz; 2290 2291 if (count < sz || dsz < sz) /* Buffers are too small. */ 2292 return (0); 2293 2294 (void) memcpy(dst, src, sz); 2295 2296 src += sz; 2297 dst += sz; 2298 2299 count -= sz; 2300 dsz -= sz; 2301 } 2302 2303 return (1); 2304 } 2305 2306 struct converters { 2307 int (*tof32)(unsigned char *dst, size_t dsz, unsigned char *src, 2308 size_t cnt, int byteswap); 2309 int (*tom32)(unsigned char *dst, size_t dsz, unsigned char *src, 2310 size_t cnt, int byteswap); 2311 int (*tof64)(unsigned char *dst, size_t dsz, unsigned char *src, 2312 size_t cnt, int byteswap); 2313 int (*tom64)(unsigned char *dst, size_t dsz, unsigned char *src, 2314 size_t cnt, int byteswap); 2315 }; 2316 2317 static struct converters cvt[ELF_T_NUM] = { 2318 /*[*/ 2319 [ELF_T_ADDR] = { .tof32 = NULL, .tom32 = NULL, .tof64 = NULL, 2320 .tom64 = _libelf_cvt_ADDR64_tom }, 2321 [ELF_T_CAP] = { .tof32 = NULL, .tom32 = NULL, .tof64 = NULL, 2322 .tom64 = _libelf_cvt_CAP64_tom }, 2323 [ELF_T_DYN] = { .tof32 = NULL, .tom32 = NULL, .tof64 = NULL, 2324 .tom64 = _libelf_cvt_DYN64_tom }, 2325 [ELF_T_EHDR] = { .tof32 = NULL, .tom32 = NULL, .tof64 = NULL, 2326 .tom64 = _libelf_cvt_EHDR64_tom }, 2327 [ELF_T_GNUHASH] = { .tof32 = NULL, .tom32 = NULL, .tof64 = NULL, 2328 .tom64 = _libelf_cvt_GNUHASH64_tom }, 2329 [ELF_T_HALF] = { .tof32 = NULL, .tom32 = NULL, .tof64 = NULL, 2330 .tom64 = _libelf_cvt_HALF_tom }, 2331 [ELF_T_LWORD] = { .tof32 = NULL, .tom32 = NULL, .tof64 = NULL, 2332 .tom64 = _libelf_cvt_LWORD_tom }, 2333 [ELF_T_MOVE] = { .tof32 = NULL, .tom32 = NULL, .tof64 = NULL, 2334 .tom64 = _libelf_cvt_MOVE64_tom }, 2335 [ELF_T_OFF] = { .tof32 = NULL, .tom32 = NULL, .tof64 = NULL, 2336 .tom64 = _libelf_cvt_OFF64_tom }, 2337 [ELF_T_PHDR] = { .tof32 = NULL, .tom32 = NULL, .tof64 = NULL, 2338 .tom64 = _libelf_cvt_PHDR64_tom }, 2339 [ELF_T_REL] = { .tof32 = NULL, .tom32 = NULL, .tof64 = NULL, 2340 .tom64 = _libelf_cvt_REL64_tom }, 2341 [ELF_T_RELA] = { .tof32 = NULL, .tom32 = NULL, .tof64 = NULL, 2342 .tom64 = _libelf_cvt_RELA64_tom }, 2343 [ELF_T_SHDR] = { .tof32 = NULL, .tom32 = NULL, .tof64 = NULL, 2344 .tom64 = _libelf_cvt_SHDR64_tom }, 2345 [ELF_T_SWORD] = { .tof32 = NULL, .tom32 = NULL, .tof64 = NULL, 2346 .tom64 = _libelf_cvt_SWORD_tom }, 2347 [ELF_T_SXWORD] = { .tof32 = NULL, .tom32 = NULL, .tof64 = NULL, 2348 .tom64 = _libelf_cvt_SXWORD_tom }, 2349 [ELF_T_SYMINFO] = { .tof32 = NULL, .tom32 = NULL, .tof64 = NULL, 2350 .tom64 = _libelf_cvt_SYMINFO64_tom }, 2351 [ELF_T_SYM] = { .tof32 = NULL, .tom32 = NULL, .tof64 = NULL, 2352 .tom64 = _libelf_cvt_SYM64_tom }, 2353 [ELF_T_VDEF] = { .tof32 = NULL, .tom32 = NULL, .tof64 = NULL, 2354 .tom64 = _libelf_cvt_VDEF64_tom }, 2355 [ELF_T_VNEED] = { .tof32 = NULL, .tom32 = NULL, .tof64 = NULL, 2356 .tom64 = _libelf_cvt_VNEED64_tom }, 2357 [ELF_T_WORD] = { .tof32 = NULL, .tom32 = NULL, .tof64 = NULL, 2358 .tom64 = _libelf_cvt_WORD_tom }, 2359 [ELF_T_XWORD] = { .tof32 = NULL, .tom32 = NULL, .tof64 = NULL, 2360 .tom64 = _libelf_cvt_XWORD_tom }, 2361 /*]*/ 2362 /* 2363 * Types that need hand-coded converters follow. 2364 */ 2365 [ELF_T_BYTE] = { .tof32 = NULL, .tom32 = NULL, .tof64 = NULL, 2366 .tom64 = _libelf_cvt_BYTE_tox }, 2367 [ELF_T_NOTE] = { .tof32 = NULL, .tom32 = NULL, .tof64 = NULL, 2368 .tom64 = _libelf_cvt_NOTE_tom } 2369 }; 2370 2371 static int (*_libelf_get_translator(Elf_Type t, int direction, int elfclass)) 2372 (unsigned char *_dst, size_t dsz, unsigned char *_src, size_t _cnt, 2373 int _byteswap) 2374 { 2375 assert(/* elfclass == ELFCLASS32 || */ elfclass == ELFCLASS64); 2376 assert(/* direction == ELF_TOFILE || */ direction == ELF_TOMEMORY); 2377 2378 if (t >= ELF_T_NUM || 2379 (/* elfclass != ELFCLASS32 && */ elfclass != ELFCLASS64) || 2380 (/* direction != ELF_TOFILE && */ direction != ELF_TOMEMORY)) 2381 return (NULL); 2382 2383 #if 1 2384 return cvt[t].tom64; 2385 #else 2386 return ((elfclass == ELFCLASS32) ? 2387 (direction == ELF_TOFILE ? cvt[t].tof32 : cvt[t].tom32) : 2388 (direction == ELF_TOFILE ? cvt[t].tof64 : cvt[t].tom64)); 2389 #endif 2390 } 2391 2392 /* libelf_ehdr.h */ 2393 /* 2394 * Retrieve counts for sections, phdrs and the section string table index 2395 * from section header #0 of the ELF object. 2396 */ 2397 static int 2398 _libelf_load_extended(Elf *e, int ec, uint64_t shoff, uint16_t phnum, 2399 uint16_t strndx) 2400 { 2401 Elf_Scn *scn; 2402 size_t fsz; 2403 int (*xlator)(unsigned char *_d, size_t _dsz, unsigned char *_s, 2404 size_t _c, int _swap); 2405 uint32_t shtype; 2406 2407 assert(STAILQ_EMPTY(&e->e_u.e_elf.e_scn)); 2408 2409 fsz = _libelf_fsize(ELF_T_SHDR, ec, e->e_version, 1); 2410 assert(fsz > 0); 2411 2412 if (e->e_rawsize < shoff + fsz) { /* raw file too small */ 2413 LIBELF_SET_ERROR(HEADER, 0); 2414 return (0); 2415 } 2416 2417 if ((scn = _libelf_allocate_scn(e, (size_t) 0)) == NULL) 2418 return (0); 2419 2420 xlator = _libelf_get_translator(ELF_T_SHDR, ELF_TOMEMORY, ec); 2421 (*xlator)((unsigned char *) &scn->s_shdr, sizeof(scn->s_shdr), 2422 (unsigned char *) e->e_rawfile + shoff, (size_t) 1, 2423 e->e_byteorder != LIBELF_PRIVATE(byteorder)); 2424 2425 #define GET_SHDR_MEMBER(M) (/* (ec == ELFCLASS32) ? scn->s_shdr.s_shdr32.M :*/ \ 2426 scn->s_shdr.s_shdr64.M) 2427 2428 if ((shtype = GET_SHDR_MEMBER(sh_type)) != SHT_NULL) { 2429 LIBELF_SET_ERROR(SECTION, 0); 2430 return (0); 2431 } 2432 2433 e->e_u.e_elf.e_nscn = (size_t) GET_SHDR_MEMBER(sh_size); 2434 e->e_u.e_elf.e_nphdr = (phnum != PN_XNUM) ? phnum : 2435 GET_SHDR_MEMBER(sh_info); 2436 e->e_u.e_elf.e_strndx = (strndx != SHN_XINDEX) ? strndx : 2437 GET_SHDR_MEMBER(sh_link); 2438 #undef GET_SHDR_MEMBER 2439 2440 return (1); 2441 } 2442 2443 #define EHDR_INIT(E,SZ) do { \ 2444 Elf##SZ##_Ehdr *eh = (E); \ 2445 eh->e_ident[EI_MAG0] = ELFMAG0; \ 2446 eh->e_ident[EI_MAG1] = ELFMAG1; \ 2447 eh->e_ident[EI_MAG2] = ELFMAG2; \ 2448 eh->e_ident[EI_MAG3] = ELFMAG3; \ 2449 eh->e_ident[EI_CLASS] = ELFCLASS##SZ; \ 2450 eh->e_ident[EI_DATA] = ELFDATANONE; \ 2451 eh->e_ident[EI_VERSION] = LIBELF_PRIVATE(version) & 0xFFU; \ 2452 eh->e_machine = EM_NONE; \ 2453 eh->e_type = ELF_K_NONE; \ 2454 eh->e_version = LIBELF_PRIVATE(version); \ 2455 } while (0) 2456 2457 static void * 2458 _libelf_ehdr(Elf *e, int ec, int allocate) 2459 { 2460 void *ehdr; 2461 size_t fsz, msz; 2462 uint16_t phnum, shnum, strndx; 2463 uint64_t shoff; 2464 int (*xlator)(unsigned char *_d, size_t _dsz, unsigned char *_s, 2465 size_t _c, int _swap); 2466 2467 assert(ec == ELFCLASS32 || ec == ELFCLASS64); 2468 2469 if (e == NULL || e->e_kind != ELF_K_ELF) { 2470 LIBELF_SET_ERROR(ARGUMENT, 0); 2471 return (NULL); 2472 } 2473 2474 if (e->e_class != ELFCLASSNONE && e->e_class != ec) { 2475 LIBELF_SET_ERROR(CLASS, 0); 2476 return (NULL); 2477 } 2478 2479 if (e->e_version != EV_CURRENT) { 2480 LIBELF_SET_ERROR(VERSION, 0); 2481 return (NULL); 2482 } 2483 2484 if (e->e_class == ELFCLASSNONE) 2485 e->e_class = ec; 2486 2487 #if 0 2488 if (ec == ELFCLASS32) 2489 ehdr = (void *) e->e_u.e_elf.e_ehdr.e_ehdr32; 2490 else 2491 #endif 2492 ehdr = (void *) e->e_u.e_elf.e_ehdr.e_ehdr64; 2493 2494 if (ehdr != NULL) /* already have a translated ehdr */ 2495 return (ehdr); 2496 2497 fsz = _libelf_fsize(ELF_T_EHDR, ec, e->e_version, (size_t) 1); 2498 assert(fsz > 0); 2499 2500 if (e->e_cmd != ELF_C_WRITE && e->e_rawsize < fsz) { 2501 LIBELF_SET_ERROR(HEADER, 0); 2502 return (NULL); 2503 } 2504 2505 msz = _libelf_msize(ELF_T_EHDR, ec, EV_CURRENT); 2506 2507 assert(msz > 0); 2508 2509 if ((ehdr = calloc((size_t) 1, msz)) == NULL) { 2510 LIBELF_SET_ERROR(RESOURCE, 0); 2511 return (NULL); 2512 } 2513 2514 #if 0 2515 if (ec == ELFCLASS32) { 2516 e->e_u.e_elf.e_ehdr.e_ehdr32 = ehdr; 2517 EHDR_INIT(ehdr,32); 2518 } else 2519 #endif 2520 { 2521 e->e_u.e_elf.e_ehdr.e_ehdr64 = ehdr; 2522 EHDR_INIT(ehdr,64); 2523 } 2524 2525 if (allocate) 2526 e->e_flags |= ELF_F_DIRTY; 2527 2528 if (e->e_cmd == ELF_C_WRITE) 2529 return (ehdr); 2530 2531 xlator = _libelf_get_translator(ELF_T_EHDR, ELF_TOMEMORY, ec); 2532 (*xlator)((unsigned char*) ehdr, msz, e->e_rawfile, (size_t) 1, 2533 e->e_byteorder != LIBELF_PRIVATE(byteorder)); 2534 2535 /* 2536 * If extended numbering is being used, read the correct 2537 * number of sections and program header entries. 2538 */ 2539 #if 0 2540 if (ec == ELFCLASS32) { 2541 phnum = ((Elf32_Ehdr *) ehdr)->e_phnum; 2542 shnum = ((Elf32_Ehdr *) ehdr)->e_shnum; 2543 shoff = ((Elf32_Ehdr *) ehdr)->e_shoff; 2544 strndx = ((Elf32_Ehdr *) ehdr)->e_shstrndx; 2545 } else 2546 #endif 2547 { 2548 phnum = ((Elf64_Ehdr *) ehdr)->e_phnum; 2549 shnum = ((Elf64_Ehdr *) ehdr)->e_shnum; 2550 shoff = ((Elf64_Ehdr *) ehdr)->e_shoff; 2551 strndx = ((Elf64_Ehdr *) ehdr)->e_shstrndx; 2552 } 2553 2554 if (shnum >= SHN_LORESERVE || 2555 (shoff == 0LL && (shnum != 0 || phnum == PN_XNUM || 2556 strndx == SHN_XINDEX))) { 2557 LIBELF_SET_ERROR(HEADER, 0); 2558 return (NULL); 2559 } 2560 2561 if (shnum != 0 || shoff == 0LL) { /* not using extended numbering */ 2562 e->e_u.e_elf.e_nphdr = phnum; 2563 e->e_u.e_elf.e_nscn = shnum; 2564 e->e_u.e_elf.e_strndx = strndx; 2565 } else if (_libelf_load_extended(e, ec, shoff, phnum, strndx) == 0) 2566 return (NULL); 2567 2568 return (ehdr); 2569 } 2570 2571 /* libelf_shdr.c */ 2572 static void * 2573 _libelf_getshdr(Elf_Scn *s, int ec) 2574 { 2575 Elf *e; 2576 2577 if (s == NULL || (e = s->s_elf) == NULL || 2578 e->e_kind != ELF_K_ELF) { 2579 LIBELF_SET_ERROR(ARGUMENT, 0); 2580 return (NULL); 2581 } 2582 2583 if (ec == ELFCLASSNONE) 2584 ec = e->e_class; 2585 2586 if (ec != e->e_class) { 2587 LIBELF_SET_ERROR(CLASS, 0); 2588 return (NULL); 2589 } 2590 2591 return ((void *) &s->s_shdr); 2592 } 2593 2594 /* elf_scn.c */ 2595 static int 2596 _libelf_load_section_headers(Elf *e, void *ehdr) 2597 { 2598 Elf_Scn *scn; 2599 uint64_t shoff; 2600 #if 0 2601 Elf32_Ehdr *eh32; 2602 #endif 2603 Elf64_Ehdr *eh64; 2604 int ec, swapbytes; 2605 unsigned char *src; 2606 size_t fsz, i, shnum; 2607 int (*xlator)(unsigned char *_d, size_t _dsz, unsigned char *_s, 2608 size_t _c, int _swap); 2609 2610 assert(e != NULL); 2611 assert(ehdr != NULL); 2612 assert((e->e_flags & LIBELF_F_SHDRS_LOADED) == 0); 2613 2614 #define CHECK_EHDR(E,EH) do { \ 2615 if (shoff > e->e_rawsize || \ 2616 fsz != (EH)->e_shentsize || \ 2617 shnum > SIZE_MAX / fsz || \ 2618 fsz * shnum > e->e_rawsize - shoff) { \ 2619 LIBELF_SET_ERROR(HEADER, 0); \ 2620 return (0); \ 2621 } \ 2622 } while (0) 2623 2624 ec = e->e_class; 2625 fsz = _libelf_fsize(ELF_T_SHDR, ec, e->e_version, (size_t) 1); 2626 assert(fsz > 0); 2627 2628 shnum = e->e_u.e_elf.e_nscn; 2629 2630 #if 0 2631 if (ec == ELFCLASS32) { 2632 eh32 = (Elf32_Ehdr *) ehdr; 2633 shoff = (uint64_t) eh32->e_shoff; 2634 CHECK_EHDR(e, eh32); 2635 } else 2636 #endif 2637 { 2638 eh64 = (Elf64_Ehdr *) ehdr; 2639 shoff = eh64->e_shoff; 2640 CHECK_EHDR(e, eh64); 2641 } 2642 2643 xlator = _libelf_get_translator(ELF_T_SHDR, ELF_TOMEMORY, ec); 2644 2645 swapbytes = e->e_byteorder != LIBELF_PRIVATE(byteorder); 2646 src = e->e_rawfile + shoff; 2647 2648 /* 2649 * If the file is using extended numbering then section #0 2650 * would have already been read in. 2651 */ 2652 2653 i = 0; 2654 if (!STAILQ_EMPTY(&e->e_u.e_elf.e_scn)) { 2655 assert(STAILQ_FIRST(&e->e_u.e_elf.e_scn) == 2656 STAILQ_LAST(&e->e_u.e_elf.e_scn, _Elf_Scn, s_next)); 2657 2658 i = 1; 2659 src += fsz; 2660 } 2661 2662 for (; i < shnum; i++, src += fsz) { 2663 if ((scn = _libelf_allocate_scn(e, i)) == NULL) 2664 return (0); 2665 2666 (*xlator)((unsigned char *) &scn->s_shdr, sizeof(scn->s_shdr), 2667 src, (size_t) 1, swapbytes); 2668 2669 #if 0 2670 if (ec == ELFCLASS32) { 2671 scn->s_offset = scn->s_rawoff = 2672 scn->s_shdr.s_shdr32.sh_offset; 2673 scn->s_size = scn->s_shdr.s_shdr32.sh_size; 2674 } else 2675 #endif 2676 { 2677 scn->s_offset = scn->s_rawoff = 2678 scn->s_shdr.s_shdr64.sh_offset; 2679 scn->s_size = scn->s_shdr.s_shdr64.sh_size; 2680 } 2681 } 2682 2683 e->e_flags |= LIBELF_F_SHDRS_LOADED; 2684 2685 return (1); 2686 } 2687 2688 static Elf_Scn * 2689 elf_getscn(Elf *e, size_t index) 2690 { 2691 int ec; 2692 void *ehdr; 2693 Elf_Scn *s; 2694 2695 if (e == NULL || e->e_kind != ELF_K_ELF || 2696 ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { 2697 LIBELF_SET_ERROR(ARGUMENT, 0); 2698 return (NULL); 2699 } 2700 2701 if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL) 2702 return (NULL); 2703 2704 if (e->e_cmd != ELF_C_WRITE && 2705 (e->e_flags & LIBELF_F_SHDRS_LOADED) == 0 && 2706 _libelf_load_section_headers(e, ehdr) == 0) 2707 return (NULL); 2708 2709 STAILQ_FOREACH(s, &e->e_u.e_elf.e_scn, s_next) 2710 if (s->s_ndx == index) 2711 return (s); 2712 2713 LIBELF_SET_ERROR(ARGUMENT, 0); 2714 return (NULL); 2715 } 2716 2717 /* libelf_memory.c */ 2718 static Elf * 2719 _libelf_memory(unsigned char *image, size_t sz, int reporterror) 2720 { 2721 Elf *e; 2722 int e_class; 2723 enum Elf_Error error; 2724 unsigned int e_byteorder, e_version; 2725 2726 assert(image != NULL); 2727 assert(sz > 0); 2728 2729 if ((e = _libelf_allocate_elf()) == NULL) 2730 return (NULL); 2731 2732 e->e_cmd = ELF_C_READ; 2733 e->e_rawfile = image; 2734 e->e_rawsize = sz; 2735 2736 #undef LIBELF_IS_ELF 2737 #define LIBELF_IS_ELF(P) ((P)[EI_MAG0] == ELFMAG0 && \ 2738 (P)[EI_MAG1] == ELFMAG1 && (P)[EI_MAG2] == ELFMAG2 && \ 2739 (P)[EI_MAG3] == ELFMAG3) 2740 2741 if (sz > EI_NIDENT && LIBELF_IS_ELF(image)) { 2742 e_byteorder = image[EI_DATA]; 2743 e_class = image[EI_CLASS]; 2744 e_version = image[EI_VERSION]; 2745 2746 error = ELF_E_NONE; 2747 2748 if (e_version > EV_CURRENT) 2749 error = ELF_E_VERSION; 2750 else if ((e_byteorder != ELFDATA2LSB && e_byteorder != 2751 ELFDATA2MSB) || (e_class != ELFCLASS32 && e_class != 2752 ELFCLASS64)) 2753 error = ELF_E_HEADER; 2754 2755 if (error != ELF_E_NONE) { 2756 if (reporterror) { 2757 LIBELF_PRIVATE(error) = LIBELF_ERROR(error, 0); 2758 (void) _libelf_release_elf(e); 2759 return (NULL); 2760 } 2761 } else { 2762 _libelf_init_elf(e, ELF_K_ELF); 2763 2764 e->e_byteorder = e_byteorder; 2765 e->e_class = e_class; 2766 e->e_version = e_version; 2767 } 2768 } 2769 #if 0 2770 else if (sz >= SARMAG && 2771 strncmp((const char *) image, ARMAG, (size_t) SARMAG) == 0) 2772 return (_libelf_ar_open(e, reporterror)); 2773 #endif 2774 2775 return (e); 2776 } 2777 2778 /* libelf_open.c */ 2779 #define _LIBELF_INITSIZE (64*1024) 2780 2781 static void * 2782 _libelf_read_special_file(int fd, size_t *fsz) 2783 { 2784 ssize_t readsz; 2785 size_t bufsz, datasz; 2786 unsigned char *buf, *t; 2787 2788 datasz = 0; 2789 readsz = 0; 2790 bufsz = _LIBELF_INITSIZE; 2791 if ((buf = malloc(bufsz)) == NULL) 2792 goto resourceerror; 2793 2794 /* 2795 * Read data from the file descriptor till we reach EOF, or 2796 * till an error is encountered. 2797 */ 2798 do { 2799 /* Check if we need to expand the data buffer. */ 2800 if (datasz == bufsz) { 2801 bufsz *= 2; 2802 if ((t = realloc(buf, bufsz)) == NULL) 2803 goto resourceerror; 2804 buf = t; 2805 } 2806 2807 do { 2808 assert(bufsz - datasz > 0); 2809 t = buf + datasz; 2810 if ((readsz = read(fd, t, bufsz - datasz)) <= 0) 2811 break; 2812 datasz += (size_t) readsz; 2813 } while (datasz < bufsz); 2814 2815 } while (readsz > 0); 2816 2817 if (readsz < 0) { 2818 LIBELF_SET_ERROR(IO, errno); 2819 goto error; 2820 } 2821 2822 assert(readsz == 0); 2823 2824 /* 2825 * Free up extra buffer space. 2826 */ 2827 if (bufsz > datasz) { 2828 if (datasz > 0) { 2829 if ((t = realloc(buf, datasz)) == NULL) 2830 goto resourceerror; 2831 buf = t; 2832 } else { /* Zero bytes read. */ 2833 LIBELF_SET_ERROR(ARGUMENT, 0); 2834 free(buf); 2835 buf = NULL; 2836 } 2837 } 2838 2839 *fsz = datasz; 2840 return (buf); 2841 2842 resourceerror: 2843 LIBELF_SET_ERROR(RESOURCE, 0); 2844 error: 2845 if (buf != NULL) 2846 free(buf); 2847 return (NULL); 2848 } 2849 2850 static Elf * 2851 _libelf_open_object(int fd, Elf_Cmd c, int reporterror) 2852 { 2853 Elf *e; 2854 void *m; 2855 mode_t mode; 2856 size_t fsize; 2857 struct stat sb; 2858 unsigned int flags; 2859 2860 assert(c == ELF_C_READ || c == ELF_C_RDWR || c == ELF_C_WRITE); 2861 2862 if (fstat(fd, &sb) < 0) { 2863 LIBELF_SET_ERROR(IO, errno); 2864 return (NULL); 2865 } 2866 2867 mode = sb.st_mode; 2868 fsize = (size_t) sb.st_size; 2869 2870 /* 2871 * Reject unsupported file types. 2872 */ 2873 if (!S_ISREG(mode) && !S_ISCHR(mode) && !S_ISFIFO(mode) && 2874 !S_ISSOCK(mode)) { 2875 LIBELF_SET_ERROR(ARGUMENT, 0); 2876 return (NULL); 2877 } 2878 2879 /* 2880 * For ELF_C_WRITE mode, allocate and return a descriptor. 2881 */ 2882 if (c == ELF_C_WRITE) { 2883 if ((e = _libelf_allocate_elf()) != NULL) { 2884 _libelf_init_elf(e, ELF_K_ELF); 2885 e->e_byteorder = LIBELF_PRIVATE(byteorder); 2886 e->e_fd = fd; 2887 e->e_cmd = c; 2888 if (!S_ISREG(mode)) 2889 e->e_flags |= LIBELF_F_SPECIAL_FILE; 2890 } 2891 2892 return (e); 2893 } 2894 2895 2896 /* 2897 * ELF_C_READ and ELF_C_RDWR mode. 2898 */ 2899 m = NULL; 2900 flags = 0; 2901 if (S_ISREG(mode)) { 2902 2903 /* 2904 * Reject zero length files. 2905 */ 2906 if (fsize == 0) { 2907 LIBELF_SET_ERROR(ARGUMENT, 0); 2908 return (NULL); 2909 } 2910 2911 #if ELFTC_HAVE_MMAP 2912 /* 2913 * Always map regular files in with 'PROT_READ' 2914 * permissions. 2915 * 2916 * For objects opened in ELF_C_RDWR mode, when 2917 * elf_update(3) is called, we remove this mapping, 2918 * write file data out using write(2), and map the new 2919 * contents back. 2920 */ 2921 m = mmap(NULL, fsize, PROT_READ, MAP_PRIVATE, fd, (off_t) 0); 2922 2923 if (m == MAP_FAILED) 2924 m = NULL; 2925 else 2926 flags = LIBELF_F_RAWFILE_MMAP; 2927 #endif 2928 2929 /* 2930 * Fallback to a read() if the call to mmap() failed, 2931 * or if mmap() is not available. 2932 */ 2933 if (m == NULL) { 2934 if ((m = malloc(fsize)) == NULL) { 2935 LIBELF_SET_ERROR(RESOURCE, 0); 2936 return (NULL); 2937 } 2938 2939 if (read(fd, m, fsize) != (ssize_t) fsize) { 2940 LIBELF_SET_ERROR(IO, errno); 2941 free(m); 2942 return (NULL); 2943 } 2944 2945 flags = LIBELF_F_RAWFILE_MALLOC; 2946 } 2947 } else if ((m = _libelf_read_special_file(fd, &fsize)) != NULL) 2948 flags = LIBELF_F_RAWFILE_MALLOC | LIBELF_F_SPECIAL_FILE; 2949 else 2950 return (NULL); 2951 2952 if ((e = _libelf_memory(m, fsize, reporterror)) == NULL) { 2953 assert((flags & LIBELF_F_RAWFILE_MALLOC) || 2954 (flags & LIBELF_F_RAWFILE_MMAP)); 2955 if (flags & LIBELF_F_RAWFILE_MALLOC) 2956 free(m); 2957 #if ELFTC_HAVE_MMAP 2958 else 2959 (void) munmap(m, fsize); 2960 #endif 2961 return (NULL); 2962 } 2963 2964 /* ar(1) archives aren't supported in RDWR mode. */ 2965 #if 0 2966 if (c == ELF_C_RDWR && e->e_kind == ELF_K_AR) { 2967 (void) elf_end(e); 2968 LIBELF_SET_ERROR(ARGUMENT, 0); 2969 return (NULL); 2970 } 2971 #endif 2972 2973 e->e_flags |= flags; 2974 e->e_fd = fd; 2975 e->e_cmd = c; 2976 2977 return (e); 2978 } 2979 2980 static const char *_libelf_errors[] = { 2981 #define DEFINE_ERROR(N,S) [ELF_E_##N] = S 2982 DEFINE_ERROR(NONE, "No Error"), 2983 DEFINE_ERROR(ARCHIVE, "Malformed ar(1) archive"), 2984 DEFINE_ERROR(ARGUMENT, "Invalid argument"), 2985 DEFINE_ERROR(CLASS, "ELF class mismatch"), 2986 DEFINE_ERROR(DATA, "Invalid data buffer descriptor"), 2987 DEFINE_ERROR(HEADER, "Missing or malformed ELF header"), 2988 DEFINE_ERROR(IO, "I/O error"), 2989 DEFINE_ERROR(LAYOUT, "Layout constraint violation"), 2990 DEFINE_ERROR(MODE, "Incorrect ELF descriptor mode"), 2991 DEFINE_ERROR(RANGE, "Value out of range of target"), 2992 DEFINE_ERROR(RESOURCE, "Resource exhaustion"), 2993 DEFINE_ERROR(SECTION, "Invalid section descriptor"), 2994 DEFINE_ERROR(SEQUENCE, "API calls out of sequence"), 2995 DEFINE_ERROR(UNIMPL, "Unimplemented feature"), 2996 DEFINE_ERROR(VERSION, "Unknown ELF API version"), 2997 DEFINE_ERROR(NUM, "Unknown error") 2998 #undef DEFINE_ERROR 2999 }; 3000 3001 /* PUBLIC */ 3002 3003 /* elf_errmsg.c */ 3004 static const char * 3005 elf_errmsg(int error) 3006 { 3007 int oserr; 3008 3009 if (error == ELF_E_NONE && 3010 (error = LIBELF_PRIVATE(error)) == 0) 3011 return NULL; 3012 else if (error == -1) 3013 error = LIBELF_PRIVATE(error); 3014 3015 oserr = error >> LIBELF_OS_ERROR_SHIFT; 3016 error &= LIBELF_ELF_ERROR_MASK; 3017 3018 if (error < ELF_E_NONE || error >= ELF_E_NUM) 3019 return _libelf_errors[ELF_E_NUM]; 3020 if (oserr) { 3021 (void) snprintf((char *) LIBELF_PRIVATE(msg), 3022 sizeof(LIBELF_PRIVATE(msg)), "%s: %s", 3023 _libelf_errors[error], strerror(oserr)); 3024 return (const char *)&LIBELF_PRIVATE(msg); 3025 } 3026 return _libelf_errors[error]; 3027 } 3028 3029 /* elf_errno.c */ 3030 static int 3031 elf_errno(void) 3032 { 3033 int old; 3034 3035 old = LIBELF_PRIVATE(error); 3036 LIBELF_PRIVATE(error) = 0; 3037 return (old & LIBELF_ELF_ERROR_MASK); 3038 } 3039 3040 /* elf_version.c */ 3041 static unsigned int 3042 elf_version(unsigned int v) 3043 { 3044 unsigned int old; 3045 3046 if ((old = LIBELF_PRIVATE(version)) == EV_NONE) 3047 old = EV_CURRENT; 3048 3049 if (v == EV_NONE) 3050 return old; 3051 if (v > EV_CURRENT) { 3052 LIBELF_SET_ERROR(VERSION, 0); 3053 return EV_NONE; 3054 } 3055 3056 LIBELF_PRIVATE(version) = v; 3057 return (old); 3058 } 3059 3060 /* elf_begin.c */ 3061 static Elf * 3062 elf_begin(int fd, Elf_Cmd c, Elf *a) 3063 { 3064 Elf *e; 3065 3066 e = NULL; 3067 3068 if (LIBELF_PRIVATE(version) == EV_NONE) { 3069 LIBELF_SET_ERROR(SEQUENCE, 0); 3070 return (NULL); 3071 } 3072 3073 switch (c) { 3074 case ELF_C_NULL: 3075 return (NULL); 3076 3077 case ELF_C_WRITE: 3078 /* 3079 * The ELF_C_WRITE command is required to ignore the 3080 * descriptor passed in. 3081 */ 3082 a = NULL; 3083 break; 3084 3085 case ELF_C_RDWR: 3086 if (a != NULL) { /* not allowed for ar(1) archives. */ 3087 LIBELF_SET_ERROR(ARGUMENT, 0); 3088 return (NULL); 3089 } 3090 /*FALLTHROUGH*/ 3091 case ELF_C_READ: 3092 /* 3093 * Descriptor `a' could be for a regular ELF file, or 3094 * for an ar(1) archive. If descriptor `a' was opened 3095 * using a valid file descriptor, we need to check if 3096 * the passed in `fd' value matches the original one. 3097 */ 3098 if (a && 3099 ((a->e_fd != -1 && a->e_fd != fd) || c != a->e_cmd)) { 3100 LIBELF_SET_ERROR(ARGUMENT, 0); 3101 return (NULL); 3102 } 3103 break; 3104 3105 default: 3106 LIBELF_SET_ERROR(ARGUMENT, 0); 3107 return (NULL); 3108 3109 } 3110 3111 if (a == NULL) 3112 e = _libelf_open_object(fd, c, 1); 3113 #if 0 3114 else if (a->e_kind == ELF_K_AR) 3115 e = _libelf_ar_open_member(a->e_fd, c, a); 3116 #endif 3117 else 3118 (e = a)->e_activations++; 3119 3120 return (e); 3121 } 3122 3123 /* elf_end.c */ 3124 static int 3125 elf_end(Elf *e) 3126 { 3127 Elf *sv; 3128 Elf_Scn *scn, *tscn; 3129 3130 if (e == NULL || e->e_activations == 0) 3131 return (0); 3132 3133 if (--e->e_activations > 0) 3134 return (e->e_activations); 3135 3136 assert(e->e_activations == 0); 3137 3138 while (e && e->e_activations == 0) { 3139 switch (e->e_kind) { 3140 case ELF_K_AR: 3141 /* 3142 * If we still have open child descriptors, we 3143 * need to defer reclaiming resources till all 3144 * the child descriptors for the archive are 3145 * closed. 3146 */ 3147 if (e->e_u.e_ar.e_nchildren > 0) 3148 return (0); 3149 break; 3150 case ELF_K_ELF: 3151 /* 3152 * Reclaim all section descriptors. 3153 */ 3154 STAILQ_FOREACH_SAFE(scn, &e->e_u.e_elf.e_scn, s_next, 3155 tscn) 3156 scn = _libelf_release_scn(scn); 3157 break; 3158 case ELF_K_NUM: 3159 assert(0); 3160 default: 3161 break; 3162 } 3163 3164 if (e->e_rawfile) { 3165 if (e->e_flags & LIBELF_F_RAWFILE_MALLOC) 3166 free(e->e_rawfile); 3167 #if ELFTC_HAVE_MMAP 3168 else if (e->e_flags & LIBELF_F_RAWFILE_MMAP) 3169 (void) munmap(e->e_rawfile, e->e_rawsize); 3170 #endif 3171 } 3172 3173 sv = e; 3174 if ((e = e->e_parent) != NULL) 3175 e->e_u.e_ar.e_nchildren--; 3176 sv = _libelf_release_elf(sv); 3177 } 3178 3179 return (0); 3180 } 3181 3182 /* gelf_shdr.c */ 3183 static GElf_Shdr * 3184 gelf_getshdr(Elf_Scn *s, GElf_Shdr *d) 3185 { 3186 int ec; 3187 void *sh; 3188 #if 0 3189 Elf32_Shdr *sh32; 3190 #endif 3191 Elf64_Shdr *sh64; 3192 3193 if (d == NULL) { 3194 LIBELF_SET_ERROR(ARGUMENT, 0); 3195 return (NULL); 3196 } 3197 3198 if ((sh = _libelf_getshdr(s, ELFCLASSNONE)) == NULL) 3199 return (NULL); 3200 3201 ec = s->s_elf->e_class; 3202 assert(/* ec == ELFCLASS32 || */ ec == ELFCLASS64); 3203 3204 #if 0 3205 if (ec == ELFCLASS32) { 3206 sh32 = (Elf32_Shdr *) sh; 3207 3208 d->sh_name = sh32->sh_name; 3209 d->sh_type = sh32->sh_type; 3210 d->sh_flags = (Elf64_Xword) sh32->sh_flags; 3211 d->sh_addr = (Elf64_Addr) sh32->sh_addr; 3212 d->sh_offset = (Elf64_Off) sh32->sh_offset; 3213 d->sh_size = (Elf64_Xword) sh32->sh_size; 3214 d->sh_link = sh32->sh_link; 3215 d->sh_info = sh32->sh_info; 3216 d->sh_addralign = (Elf64_Xword) sh32->sh_addralign; 3217 d->sh_entsize = (Elf64_Xword) sh32->sh_entsize; 3218 } else 3219 #endif 3220 { 3221 sh64 = (Elf64_Shdr *) sh; 3222 *d = *sh64; 3223 } 3224 3225 return (d); 3226 } 3227 3228 /* gelf_sym.c */ 3229 static GElf_Sym * 3230 gelf_getsym(Elf_Data *ed, int ndx, GElf_Sym *dst) 3231 { 3232 int ec; 3233 Elf *e; 3234 size_t msz; 3235 Elf_Scn *scn; 3236 uint32_t sh_type; 3237 #if 0 3238 Elf32_Sym *sym32; 3239 #endif 3240 Elf64_Sym *sym64; 3241 struct _Libelf_Data *d; 3242 3243 d = (struct _Libelf_Data *) ed; 3244 3245 if (d == NULL || ndx < 0 || dst == NULL || 3246 (scn = d->d_scn) == NULL || 3247 (e = scn->s_elf) == NULL) { 3248 LIBELF_SET_ERROR(ARGUMENT, 0); 3249 return (NULL); 3250 } 3251 3252 ec = e->e_class; 3253 assert(/* ec == ELFCLASS32 || */ ec == ELFCLASS64); 3254 3255 #if 0 3256 if (ec == ELFCLASS32) 3257 sh_type = scn->s_shdr.s_shdr32.sh_type; 3258 else 3259 #endif 3260 sh_type = scn->s_shdr.s_shdr64.sh_type; 3261 3262 if (_libelf_xlate_shtype(sh_type) != ELF_T_SYM) { 3263 LIBELF_SET_ERROR(ARGUMENT, 0); 3264 return (NULL); 3265 } 3266 3267 msz = _libelf_msize(ELF_T_SYM, ec, e->e_version); 3268 3269 assert(msz > 0); 3270 assert(ndx >= 0); 3271 3272 if (msz * (size_t) ndx >= d->d_data.d_size) { 3273 LIBELF_SET_ERROR(ARGUMENT, 0); 3274 return (NULL); 3275 } 3276 3277 #if 0 3278 if (ec == ELFCLASS32) { 3279 sym32 = (Elf32_Sym *) d->d_data.d_buf + ndx; 3280 3281 dst->st_name = sym32->st_name; 3282 dst->st_value = (Elf64_Addr) sym32->st_value; 3283 dst->st_size = (Elf64_Xword) sym32->st_size; 3284 dst->st_info = sym32->st_info; 3285 dst->st_other = sym32->st_other; 3286 dst->st_shndx = sym32->st_shndx; 3287 } else 3288 #endif 3289 { 3290 sym64 = (Elf64_Sym *) d->d_data.d_buf + ndx; 3291 3292 *dst = *sym64; 3293 } 3294 3295 return (dst); 3296 } 3297 3298 /* elf_scn.c */ 3299 static Elf_Scn * 3300 elf_nextscn(Elf *e, Elf_Scn *s) 3301 { 3302 if (e == NULL || (e->e_kind != ELF_K_ELF) || 3303 (s && s->s_elf != e)) { 3304 LIBELF_SET_ERROR(ARGUMENT, 0); 3305 return (NULL); 3306 } 3307 3308 return (s == NULL ? elf_getscn(e, (size_t) 1) : 3309 STAILQ_NEXT(s, s_next)); 3310 } 3311 3312 /* elf_strptr.c */ 3313 static char * 3314 elf_strptr(Elf *e, size_t scndx, size_t offset) 3315 { 3316 Elf_Scn *s; 3317 Elf_Data *d; 3318 GElf_Shdr shdr; 3319 uint64_t alignment, count; 3320 3321 if (e == NULL || e->e_kind != ELF_K_ELF) { 3322 LIBELF_SET_ERROR(ARGUMENT, 0); 3323 return (NULL); 3324 } 3325 3326 if ((s = elf_getscn(e, scndx)) == NULL || 3327 gelf_getshdr(s, &shdr) == NULL) 3328 return (NULL); 3329 3330 if (shdr.sh_type != SHT_STRTAB || 3331 offset >= shdr.sh_size) { 3332 LIBELF_SET_ERROR(ARGUMENT, 0); 3333 return (NULL); 3334 } 3335 3336 d = NULL; 3337 if (e->e_flags & ELF_F_LAYOUT) { 3338 3339 /* 3340 * The application is taking responsibility for the 3341 * ELF object's layout, so we can directly translate 3342 * an offset to a `char *' address using the `d_off' 3343 * members of Elf_Data descriptors. 3344 */ 3345 while ((d = elf_getdata(s, d)) != NULL) { 3346 3347 if (d->d_buf == 0 || d->d_size == 0) 3348 continue; 3349 3350 if (d->d_type != ELF_T_BYTE) { 3351 LIBELF_SET_ERROR(DATA, 0); 3352 return (NULL); 3353 } 3354 3355 if (offset >= d->d_off && 3356 offset < d->d_off + d->d_size) 3357 return ((char *) d->d_buf + offset - d->d_off); 3358 } 3359 } else { 3360 /* 3361 * Otherwise, the `d_off' members are not useable and 3362 * we need to compute offsets ourselves, taking into 3363 * account 'holes' in coverage of the section introduced 3364 * by alignment requirements. 3365 */ 3366 count = (uint64_t) 0; /* cumulative count of bytes seen */ 3367 while ((d = elf_getdata(s, d)) != NULL && count <= offset) { 3368 3369 if (d->d_buf == NULL || d->d_size == 0) 3370 continue; 3371 3372 if (d->d_type != ELF_T_BYTE) { 3373 LIBELF_SET_ERROR(DATA, 0); 3374 return (NULL); 3375 } 3376 3377 if ((alignment = d->d_align) > 1) { 3378 if ((alignment & (alignment - 1)) != 0) { 3379 LIBELF_SET_ERROR(DATA, 0); 3380 return (NULL); 3381 } 3382 count = roundup2(count, alignment); 3383 } 3384 3385 if (offset < count) { 3386 /* offset starts in the 'hole' */ 3387 LIBELF_SET_ERROR(ARGUMENT, 0); 3388 return (NULL); 3389 } 3390 3391 if (offset < count + d->d_size) { 3392 if (d->d_buf != NULL) 3393 return ((char *) d->d_buf + 3394 offset - count); 3395 LIBELF_SET_ERROR(DATA, 0); 3396 return (NULL); 3397 } 3398 3399 count += d->d_size; 3400 } 3401 } 3402 3403 LIBELF_SET_ERROR(ARGUMENT, 0); 3404 return (NULL); 3405 } 3406 3407 /* elf_data.c */ 3408 static Elf_Data * 3409 elf_getdata(Elf_Scn *s, Elf_Data *ed) 3410 { 3411 Elf *e; 3412 unsigned int sh_type; 3413 int elfclass, elftype; 3414 size_t count, fsz, msz; 3415 struct _Libelf_Data *d; 3416 uint64_t sh_align, sh_offset, sh_size; 3417 int (*xlate)(unsigned char *_d, size_t _dsz, unsigned char *_s, 3418 size_t _c, int _swap); 3419 3420 d = (struct _Libelf_Data *) ed; 3421 3422 if (s == NULL || (e = s->s_elf) == NULL || 3423 (d != NULL && s != d->d_scn)) { 3424 LIBELF_SET_ERROR(ARGUMENT, 0); 3425 return (NULL); 3426 } 3427 3428 assert(e->e_kind == ELF_K_ELF); 3429 3430 if (d == NULL && (d = STAILQ_FIRST(&s->s_data)) != NULL) 3431 return (&d->d_data); 3432 3433 if (d != NULL) 3434 return (&STAILQ_NEXT(d, d_next)->d_data); 3435 3436 if (e->e_rawfile == NULL) { 3437 /* 3438 * In the ELF_C_WRITE case, there is no source that 3439 * can provide data for the section. 3440 */ 3441 LIBELF_SET_ERROR(ARGUMENT, 0); 3442 return (NULL); 3443 } 3444 3445 elfclass = e->e_class; 3446 3447 assert(/* elfclass == ELFCLASS32 || */ elfclass == ELFCLASS64); 3448 3449 #if 0 3450 if (elfclass == ELFCLASS32) { 3451 sh_type = s->s_shdr.s_shdr32.sh_type; 3452 sh_offset = (uint64_t) s->s_shdr.s_shdr32.sh_offset; 3453 sh_size = (uint64_t) s->s_shdr.s_shdr32.sh_size; 3454 sh_align = (uint64_t) s->s_shdr.s_shdr32.sh_addralign; 3455 } else 3456 #endif 3457 { 3458 sh_type = s->s_shdr.s_shdr64.sh_type; 3459 sh_offset = s->s_shdr.s_shdr64.sh_offset; 3460 sh_size = s->s_shdr.s_shdr64.sh_size; 3461 sh_align = s->s_shdr.s_shdr64.sh_addralign; 3462 } 3463 3464 if (sh_type == SHT_NULL) { 3465 LIBELF_SET_ERROR(SECTION, 0); 3466 return (NULL); 3467 } 3468 3469 if ((elftype = _libelf_xlate_shtype(sh_type)) < ELF_T_FIRST || 3470 elftype > ELF_T_LAST || (sh_type != SHT_NOBITS && 3471 sh_offset + sh_size > (uint64_t) e->e_rawsize)) { 3472 LIBELF_SET_ERROR(SECTION, 0); 3473 return (NULL); 3474 } 3475 3476 if ((fsz = (/* elfclass == ELFCLASS32 ? elf32_fsize :*/ elf64_fsize) 3477 (elftype, (size_t) 1, e->e_version)) == 0) { 3478 LIBELF_SET_ERROR(UNIMPL, 0); 3479 return (NULL); 3480 } 3481 3482 if (sh_size % fsz) { 3483 LIBELF_SET_ERROR(SECTION, 0); 3484 return (NULL); 3485 } 3486 3487 if (sh_size / fsz > SIZE_MAX) { 3488 LIBELF_SET_ERROR(RANGE, 0); 3489 return (NULL); 3490 } 3491 3492 count = (size_t) (sh_size / fsz); 3493 3494 msz = _libelf_msize(elftype, elfclass, e->e_version); 3495 3496 if (count > 0 && msz > SIZE_MAX / count) { 3497 LIBELF_SET_ERROR(RANGE, 0); 3498 return (NULL); 3499 } 3500 3501 assert(msz > 0); 3502 assert(count <= SIZE_MAX); 3503 assert(msz * count <= SIZE_MAX); 3504 3505 if ((d = _libelf_allocate_data(s)) == NULL) 3506 return (NULL); 3507 3508 d->d_data.d_buf = NULL; 3509 d->d_data.d_off = 0; 3510 d->d_data.d_align = sh_align; 3511 d->d_data.d_size = msz * count; 3512 d->d_data.d_type = elftype; 3513 d->d_data.d_version = e->e_version; 3514 3515 if (sh_type == SHT_NOBITS || sh_size == 0) { 3516 STAILQ_INSERT_TAIL(&s->s_data, d, d_next); 3517 return (&d->d_data); 3518 } 3519 3520 if ((d->d_data.d_buf = malloc(msz * count)) == NULL) { 3521 (void) _libelf_release_data(d); 3522 LIBELF_SET_ERROR(RESOURCE, 0); 3523 return (NULL); 3524 } 3525 3526 d->d_flags |= LIBELF_F_DATA_MALLOCED; 3527 3528 xlate = _libelf_get_translator(elftype, ELF_TOMEMORY, elfclass); 3529 if (!(*xlate)(d->d_data.d_buf, (size_t) d->d_data.d_size, 3530 e->e_rawfile + sh_offset, count, 3531 e->e_byteorder != LIBELF_PRIVATE(byteorder))) { 3532 _libelf_release_data(d); 3533 LIBELF_SET_ERROR(DATA, 0); 3534 return (NULL); 3535 } 3536 3537 STAILQ_INSERT_TAIL(&s->s_data, d, d_next); 3538 3539 return (&d->d_data); 3540 } 3541 3542 #endif /* !_PRIVATE_LIBELF_H_ */ 3543