1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #include <string.h> 27 #include "_libelf.h" 28 #include "decl.h" 29 #include "msg.h" 30 31 32 /* 33 * Find elf or it's class from a pointer to an Elf_Data struct. 34 * Warning: this Assumes that the Elf_Data is part of a libelf 35 * Dnode structure, which is expected to be true for any Elf_Data 36 * passed into libelf *except* for the xlatetof() and xlatetom() functions. 37 */ 38 #define EDATA_CLASS(edata) \ 39 (((Dnode *)(edata))->db_scn->s_elf->ed_class) 40 41 #define EDATA_ELF(edata) \ 42 (((Dnode *)(edata))->db_scn->s_elf) 43 44 #define EDATA_SCN(edata) \ 45 (((Dnode *)(edata))->db_scn) 46 47 #define EDATA_READLOCKS(edata) \ 48 READLOCKS(EDATA_ELF((edata)), EDATA_SCN((edata))) 49 50 #define EDATA_READUNLOCKS(edata) \ 51 READUNLOCKS(EDATA_ELF((edata)), EDATA_SCN((edata))) 52 53 54 size_t 55 gelf_fsize(Elf * elf, Elf_Type type, size_t count, unsigned ver) 56 { 57 int class; 58 59 if (elf == NULL) 60 return (0); 61 62 class = gelf_getclass(elf); 63 if (class == ELFCLASS32) 64 return (elf32_fsize(type, count, ver)); 65 else if (class == ELFCLASS64) 66 return (elf64_fsize(type, count, ver)); 67 68 _elf_seterr(EREQ_CLASS, 0); 69 return (0); 70 } 71 72 73 int 74 gelf_getclass(Elf *elf) 75 { 76 if (elf == NULL) 77 return (0); 78 79 /* 80 * Don't rely on the idents, a new ehdr doesn't have it! 81 */ 82 return (elf->ed_class); 83 } 84 85 86 GElf_Ehdr * 87 gelf_getehdr(Elf *elf, GElf_Ehdr *dst) 88 { 89 int class; 90 91 if (elf == NULL) 92 return (NULL); 93 94 class = gelf_getclass(elf); 95 if (class == ELFCLASS32) { 96 Elf32_Ehdr * e = elf32_getehdr(elf); 97 98 if (e == NULL) 99 return (NULL); 100 101 ELFRLOCK(elf); 102 (void) memcpy(dst->e_ident, e->e_ident, EI_NIDENT); 103 dst->e_type = e->e_type; 104 dst->e_machine = e->e_machine; 105 dst->e_version = e->e_version; 106 dst->e_entry = (Elf64_Addr)e->e_entry; 107 dst->e_phoff = (Elf64_Off)e->e_phoff; 108 dst->e_shoff = (Elf64_Off)e->e_shoff; 109 dst->e_flags = e->e_flags; 110 dst->e_ehsize = e->e_ehsize; 111 dst->e_phentsize = e->e_phentsize; 112 dst->e_phnum = e->e_phnum; 113 dst->e_shentsize = e->e_shentsize; 114 dst->e_shnum = e->e_shnum; 115 dst->e_shstrndx = e->e_shstrndx; 116 ELFUNLOCK(elf); 117 118 return (dst); 119 } else if (class == ELFCLASS64) { 120 Elf64_Ehdr * e = elf64_getehdr(elf); 121 122 if (e == NULL) 123 return (NULL); 124 125 ELFRLOCK(elf); 126 *dst = *e; 127 ELFUNLOCK(elf); 128 129 return (dst); 130 } 131 132 _elf_seterr(EREQ_CLASS, 0); 133 return (NULL); 134 } 135 136 137 int 138 gelf_update_ehdr(Elf *elf, GElf_Ehdr *src) 139 { 140 int class; 141 142 if (elf == NULL) 143 return (0); 144 145 /* 146 * In case elf isn't cooked. 147 */ 148 class = gelf_getclass(elf); 149 if (class == ELFCLASSNONE) 150 class = src->e_ident[EI_CLASS]; 151 152 153 if (class == ELFCLASS32) { 154 Elf32_Ehdr * d = elf32_getehdr(elf); 155 156 if (d == NULL) 157 return (0); 158 159 ELFWLOCK(elf); 160 (void) memcpy(d->e_ident, src->e_ident, EI_NIDENT); 161 d->e_type = src->e_type; 162 d->e_machine = src->e_machine; 163 d->e_version = src->e_version; 164 /* LINTED */ 165 d->e_entry = (Elf32_Addr)src->e_entry; 166 /* LINTED */ 167 d->e_phoff = (Elf32_Off)src->e_phoff; 168 /* LINTED */ 169 d->e_shoff = (Elf32_Off)src->e_shoff; 170 /* could memcpy the rest of these... */ 171 d->e_flags = src->e_flags; 172 d->e_ehsize = src->e_ehsize; 173 d->e_phentsize = src->e_phentsize; 174 d->e_phnum = src->e_phnum; 175 d->e_shentsize = src->e_shentsize; 176 d->e_shnum = src->e_shnum; 177 d->e_shstrndx = src->e_shstrndx; 178 ELFUNLOCK(elf); 179 180 return (1); 181 } else if (class == ELFCLASS64) { 182 Elf64_Ehdr * d = elf64_getehdr(elf); 183 184 if (d == NULL) 185 return (0); 186 187 ELFWLOCK(elf); 188 *d = *(Elf64_Ehdr *)src; 189 ELFUNLOCK(elf); 190 191 return (1); 192 } 193 194 _elf_seterr(EREQ_CLASS, 0); 195 return (0); 196 } 197 198 199 unsigned long 200 gelf_newehdr(Elf *elf, int class) 201 { 202 if (elf == NULL) 203 return (0); 204 205 if (class == ELFCLASS32) 206 return ((unsigned long)elf32_newehdr(elf)); 207 else if (class == ELFCLASS64) 208 return ((unsigned long)elf64_newehdr(elf)); 209 210 _elf_seterr(EREQ_CLASS, 0); 211 return (0); 212 } 213 214 215 GElf_Phdr * 216 gelf_getphdr(Elf *elf, int ndx, GElf_Phdr *dst) 217 { 218 int class; 219 size_t phnum; 220 221 if (elf == NULL) 222 return (NULL); 223 224 if (elf_getphdrnum(elf, &phnum) == -1) 225 return (NULL); 226 227 if (phnum <= ndx) { 228 _elf_seterr(EREQ_RAND, 0); 229 return (NULL); 230 } 231 232 class = gelf_getclass(elf); 233 if ((class != ELFCLASS32) && (class != ELFCLASS64)) { 234 _elf_seterr(EREQ_CLASS, 0); 235 return (NULL); 236 } 237 238 if (class == ELFCLASS32) { 239 Elf32_Phdr *p = &((Elf32_Phdr *)elf32_getphdr(elf))[ndx]; 240 241 ELFRLOCK(elf); 242 dst->p_type = p->p_type; 243 dst->p_flags = p->p_flags; 244 dst->p_offset = (Elf64_Off)p->p_offset; 245 dst->p_vaddr = (Elf64_Addr)p->p_vaddr; 246 dst->p_paddr = (Elf64_Addr)p->p_paddr; 247 dst->p_filesz = (Elf64_Xword)p->p_filesz; 248 dst->p_memsz = (Elf64_Xword)p->p_memsz; 249 dst->p_align = (Elf64_Xword)p->p_align; 250 ELFUNLOCK(elf); 251 } else if (class == ELFCLASS64) { 252 Elf64_Phdr *phdrs = elf64_getphdr(elf); 253 ELFRLOCK(elf); 254 *dst = ((GElf_Phdr *)phdrs)[ndx]; 255 ELFUNLOCK(elf); 256 } 257 258 return (dst); 259 } 260 261 262 int 263 gelf_update_phdr(Elf *elf, int ndx, GElf_Phdr *src) 264 { 265 int class; 266 size_t phnum; 267 268 if (elf == NULL) 269 return (0); 270 271 if (elf_getphdrnum(elf, &phnum) == -1) 272 return (NULL); 273 274 if (phnum < ndx) { 275 _elf_seterr(EREQ_RAND, 0); 276 return (0); 277 } 278 279 class = gelf_getclass(elf); 280 if (class == ELFCLASS32) { 281 Elf32_Phdr *dst = &((Elf32_Phdr *)elf32_getphdr(elf))[ndx]; 282 ELFWLOCK(elf); 283 dst->p_type = src->p_type; 284 dst->p_flags = src->p_flags; 285 /* LINTED */ 286 dst->p_offset = (Elf32_Off)src->p_offset; 287 /* LINTED */ 288 dst->p_vaddr = (Elf32_Addr)src->p_vaddr; 289 /* LINTED */ 290 dst->p_paddr = (Elf32_Addr)src->p_paddr; 291 /* LINTED */ 292 dst->p_filesz = (Elf32_Word)src->p_filesz; 293 /* LINTED */ 294 dst->p_memsz = (Elf32_Word)src->p_memsz; 295 /* LINTED */ 296 dst->p_align = (Elf32_Word)src->p_align; 297 ELFUNLOCK(elf); 298 } else if (class == ELFCLASS64) { 299 Elf64_Phdr *dst = elf64_getphdr(elf); 300 ELFWLOCK(elf); 301 dst[ndx] = *(GElf_Phdr *)src; 302 ELFUNLOCK(elf); 303 } else { 304 _elf_seterr(EREQ_CLASS, 0); 305 return (0); 306 } 307 return (1); 308 } 309 310 311 unsigned long 312 gelf_newphdr(Elf *elf, size_t phnum) 313 { 314 int class; 315 316 if (elf == NULL) 317 return (0); 318 319 class = gelf_getclass(elf); 320 if (class == ELFCLASS32) 321 return ((unsigned long)elf32_newphdr(elf, phnum)); 322 else if (class == ELFCLASS64) 323 return ((unsigned long)elf64_newphdr(elf, phnum)); 324 325 _elf_seterr(EREQ_CLASS, 0); 326 return (0); 327 } 328 329 330 GElf_Shdr * 331 gelf_getshdr(Elf_Scn *scn, GElf_Shdr *dst) 332 { 333 if (scn == NULL) 334 return (NULL); 335 336 if (scn->s_elf->ed_class == ELFCLASS32) { 337 Elf32_Shdr *s = elf32_getshdr(scn); 338 339 if (s == NULL) 340 return (NULL); 341 342 READLOCKS(scn->s_elf, scn); 343 dst->sh_name = s->sh_name; 344 dst->sh_type = s->sh_type; 345 dst->sh_flags = (Elf64_Xword)s->sh_flags; 346 dst->sh_addr = (Elf64_Addr)s->sh_addr; 347 dst->sh_offset = (Elf64_Off)s->sh_offset; 348 dst->sh_size = (Elf64_Xword)s->sh_size; 349 dst->sh_link = s->sh_link; 350 dst->sh_info = s->sh_info; 351 dst->sh_addralign = (Elf64_Xword)s->sh_addralign; 352 dst->sh_entsize = (Elf64_Xword)s->sh_entsize; 353 READUNLOCKS(scn->s_elf, scn); 354 355 return (dst); 356 } else if (scn->s_elf->ed_class == ELFCLASS64) { 357 Elf64_Shdr *s = elf64_getshdr(scn); 358 359 if (s == NULL) 360 return (NULL); 361 362 READLOCKS(scn->s_elf, scn); 363 *dst = *(Elf64_Shdr *)s; 364 READUNLOCKS(scn->s_elf, scn); 365 366 return (dst); 367 } 368 369 _elf_seterr(EREQ_CLASS, 0); 370 return (NULL); 371 } 372 373 374 int 375 gelf_update_shdr(Elf_Scn *scn, GElf_Shdr *src) 376 { 377 if (scn == NULL) 378 return (0); 379 380 if (scn->s_elf->ed_class == ELFCLASS32) { 381 Elf32_Shdr *dst = elf32_getshdr(scn); 382 383 if (dst == NULL) 384 return (0); 385 386 ELFWLOCK(scn->s_elf); 387 dst->sh_name = src->sh_name; 388 dst->sh_type = src->sh_type; 389 /* LINTED */ 390 dst->sh_flags = (Elf32_Word)src->sh_flags; 391 /* LINTED */ 392 dst->sh_addr = (Elf32_Addr)src->sh_addr; 393 /* LINTED */ 394 dst->sh_offset = (Elf32_Off) src->sh_offset; 395 /* LINTED */ 396 dst->sh_size = (Elf32_Word)src->sh_size; 397 dst->sh_link = src->sh_link; 398 dst->sh_info = src->sh_info; 399 /* LINTED */ 400 dst->sh_addralign = (Elf32_Word)src->sh_addralign; 401 /* LINTED */ 402 dst->sh_entsize = (Elf32_Word)src->sh_entsize; 403 404 ELFUNLOCK(scn->s_elf); 405 return (1); 406 } else if (scn->s_elf->ed_class == ELFCLASS64) { 407 Elf64_Shdr * dst = elf64_getshdr(scn); 408 409 if (dst == NULL) 410 return (0); 411 412 ELFWLOCK(scn->s_elf); 413 *dst = *(Elf64_Shdr *)src; 414 ELFUNLOCK(scn->s_elf); 415 return (1); 416 } 417 418 _elf_seterr(EREQ_CLASS, 0); 419 return (0); 420 } 421 422 423 /* 424 * gelf_xlatetof/gelf_xlatetom use 'elf' to find the class 425 * because these are the odd case where the Elf_Data structs 426 * might not have been allocated by libelf (and therefore 427 * don't have Dnode's associated with them). 428 */ 429 Elf_Data * 430 gelf_xlatetof(Elf *elf, Elf_Data *dst, const Elf_Data *src, unsigned encode) 431 { 432 int class; 433 434 if ((elf == NULL) || (dst == NULL) || (src == NULL)) 435 return (NULL); 436 437 class = gelf_getclass(elf); 438 if (class == ELFCLASS32) 439 return (elf32_xlatetof(dst, src, encode)); 440 else if (class == ELFCLASS64) 441 return (elf64_xlatetof(dst, src, encode)); 442 443 _elf_seterr(EREQ_CLASS, 0); 444 return (NULL); 445 } 446 447 448 Elf_Data * 449 gelf_xlatetom(Elf *elf, Elf_Data *dst, const Elf_Data *src, unsigned encode) 450 { 451 int class; 452 453 if ((elf == NULL) || (dst == NULL) || (src == NULL)) 454 return (NULL); 455 456 class = gelf_getclass(elf); 457 if (class == ELFCLASS32) 458 return (elf32_xlatetom(dst, src, encode)); 459 else if (class == ELFCLASS64) 460 return (elf64_xlatetom(dst, src, encode)); 461 462 _elf_seterr(EREQ_CLASS, 0); 463 return (NULL); 464 } 465 466 467 GElf_Sym * 468 gelf_getsym(Elf_Data * data, int ndx, GElf_Sym * dst) 469 { 470 int class; 471 size_t entsize; 472 473 if (data == NULL) 474 return (NULL); 475 476 class = EDATA_CLASS(data); 477 if (class == ELFCLASS32) 478 entsize = sizeof (Elf32_Sym); 479 else if (class == ELFCLASS64) 480 entsize = sizeof (GElf_Sym); 481 else { 482 _elf_seterr(EREQ_CLASS, 0); 483 return (NULL); 484 } 485 486 EDATA_READLOCKS(data); 487 488 if ((entsize * ndx) >= data->d_size) { 489 _elf_seterr(EREQ_RAND, 0); 490 dst = NULL; 491 } else if (class == ELFCLASS32) { 492 Elf32_Sym *s; 493 s = &(((Elf32_Sym *)data->d_buf)[ndx]); 494 dst->st_name = s->st_name; 495 dst->st_value = (Elf64_Addr)s->st_value; 496 dst->st_size = (Elf64_Xword)s->st_size; 497 dst->st_info = ELF64_ST_INFO(ELF32_ST_BIND(s->st_info), 498 ELF32_ST_TYPE(s->st_info)); 499 dst->st_other = s->st_other; 500 dst->st_shndx = s->st_shndx; 501 } else 502 *dst = ((GElf_Sym *)data->d_buf)[ndx]; 503 504 EDATA_READUNLOCKS(data); 505 return (dst); 506 } 507 508 509 int 510 gelf_update_sym(Elf_Data *dst, int ndx, GElf_Sym *src) 511 { 512 int class, rc = 1; 513 size_t entsize; 514 515 if (dst == NULL) 516 return (0); 517 518 class = EDATA_CLASS(dst); 519 if (class == ELFCLASS32) 520 entsize = sizeof (Elf32_Sym); 521 else if (class == ELFCLASS64) 522 entsize = sizeof (GElf_Sym); 523 else { 524 _elf_seterr(EREQ_CLASS, 0); 525 return (0); 526 } 527 528 ELFWLOCK(EDATA_ELF(dst)); 529 530 if ((entsize * ndx) >= dst->d_size) { 531 _elf_seterr(EREQ_RAND, 0); 532 rc = 0; 533 } else if (class == ELFCLASS32) { 534 Elf32_Sym * d; 535 536 d = &(((Elf32_Sym *)dst->d_buf)[ndx]); 537 d->st_name = src->st_name; 538 /* LINTED */ 539 d->st_value = (Elf32_Addr)src->st_value; 540 /* LINTED */ 541 d->st_size = (Elf32_Word)src->st_size; 542 d->st_info = ELF32_ST_INFO(ELF64_ST_BIND(src->st_info), 543 ELF64_ST_TYPE(src->st_info)); 544 d->st_other = src->st_other; 545 d->st_shndx = src->st_shndx; 546 } else 547 ((Elf64_Sym *)dst->d_buf)[ndx] = *((Elf64_Sym *)src); 548 549 ELFUNLOCK(EDATA_ELF(dst)); 550 return (rc); 551 } 552 553 554 GElf_Syminfo * 555 gelf_getsyminfo(Elf_Data *data, int ndx, GElf_Syminfo *dst) 556 { 557 int class; 558 size_t entsize; 559 560 if (data == NULL) 561 return (NULL); 562 563 class = EDATA_CLASS(data); 564 if (class == ELFCLASS32) 565 entsize = sizeof (Elf32_Syminfo); 566 else if (class == ELFCLASS64) 567 entsize = sizeof (GElf_Syminfo); 568 else { 569 _elf_seterr(EREQ_CLASS, 0); 570 return (NULL); 571 } 572 EDATA_READLOCKS(data); 573 574 if ((entsize * ndx) >= data->d_size) { 575 _elf_seterr(EREQ_RAND, 0); 576 dst = NULL; 577 } else if (class == ELFCLASS32) { 578 Elf32_Syminfo * si; 579 580 si = &(((Elf32_Syminfo *)data->d_buf)[ndx]); 581 dst->si_boundto = si->si_boundto; 582 dst->si_flags = si->si_flags; 583 } else 584 *dst = ((GElf_Syminfo *)data->d_buf)[ndx]; 585 586 EDATA_READUNLOCKS(data); 587 return (dst); 588 } 589 590 int 591 gelf_update_syminfo(Elf_Data *dst, int ndx, GElf_Syminfo *src) 592 { 593 int class, rc = 1; 594 size_t entsize; 595 596 if (dst == NULL) 597 return (0); 598 599 class = EDATA_CLASS(dst); 600 if (class == ELFCLASS32) 601 entsize = sizeof (Elf32_Syminfo); 602 else if (class == ELFCLASS64) 603 entsize = sizeof (GElf_Syminfo); 604 else { 605 _elf_seterr(EREQ_CLASS, 0); 606 return (0); 607 } 608 ELFWLOCK(EDATA_ELF(dst)); 609 610 if ((entsize * ndx) >= dst->d_size) { 611 _elf_seterr(EREQ_RAND, 0); 612 rc = 0; 613 } else if (class == ELFCLASS32) { 614 Elf32_Syminfo * d = &(((Elf32_Syminfo *)dst->d_buf)[ndx]); 615 d->si_boundto = src->si_boundto; 616 d->si_flags = src->si_flags; 617 } else 618 ((Elf64_Syminfo *)dst->d_buf)[ndx] = *((Elf64_Syminfo *)src); 619 620 ELFUNLOCK(EDATA_ELF(dst)); 621 return (rc); 622 } 623 624 GElf_Dyn * 625 gelf_getdyn(Elf_Data *data, int ndx, GElf_Dyn *dst) 626 { 627 int class; 628 size_t entsize; 629 630 if (data == NULL) 631 return (NULL); 632 633 class = EDATA_CLASS(data); 634 if (class == ELFCLASS32) 635 entsize = sizeof (Elf32_Dyn); 636 else if (class == ELFCLASS64) 637 entsize = sizeof (GElf_Dyn); 638 else { 639 _elf_seterr(EREQ_CLASS, 0); 640 return (NULL); 641 } 642 EDATA_READLOCKS(data); 643 644 if ((entsize * ndx) >= data->d_size) { 645 _elf_seterr(EREQ_RAND, 0); 646 dst = NULL; 647 } else if (class == ELFCLASS32) { 648 Elf32_Dyn * d = &((Elf32_Dyn *)data->d_buf)[ndx]; 649 650 dst->d_tag = (Elf32_Sword)d->d_tag; 651 dst->d_un.d_val = (Elf32_Word) d->d_un.d_val; 652 } else 653 *dst = ((Elf64_Dyn *)data->d_buf)[ndx]; 654 655 EDATA_READUNLOCKS(data); 656 return (dst); 657 } 658 659 660 int 661 gelf_update_dyn(Elf_Data *dst, int ndx, GElf_Dyn *src) 662 { 663 int class, rc = 1; 664 size_t entsize; 665 666 if (dst == NULL) 667 return (0); 668 669 class = EDATA_CLASS(dst); 670 if (class == ELFCLASS32) 671 entsize = sizeof (Elf32_Dyn); 672 else if (class == ELFCLASS64) 673 entsize = sizeof (GElf_Dyn); 674 else { 675 _elf_seterr(EREQ_CLASS, 0); 676 return (0); 677 } 678 ELFWLOCK(EDATA_ELF(dst)); 679 680 if ((entsize * ndx) >= dst->d_size) { 681 _elf_seterr(EREQ_RAND, 0); 682 rc = 0; 683 } else if (class == ELFCLASS32) { 684 Elf32_Dyn * d = &((Elf32_Dyn *)dst->d_buf)[ndx]; 685 686 /* LINTED */ 687 d->d_tag = (Elf32_Word)src->d_tag; 688 /* LINTED */ 689 d->d_un.d_val = (Elf32_Word)src->d_un.d_val; 690 } else 691 ((Elf64_Dyn *)dst->d_buf)[ndx] = *(Elf64_Dyn*)src; 692 693 ELFUNLOCK(EDATA_ELF(dst)); 694 return (rc); 695 } 696 697 698 699 GElf_Sym * 700 gelf_getsymshndx(Elf_Data *symdata, Elf_Data *shndxdata, 701 int ndx, GElf_Sym *symptr, Elf32_Word *xshndx) 702 { 703 if (gelf_getsym(symdata, ndx, symptr) == 0) 704 return (NULL); 705 if (shndxdata && xshndx) { 706 EDATA_READLOCKS(shndxdata); 707 if ((ndx * sizeof (Elf32_Word)) >= shndxdata->d_size) { 708 _elf_seterr(EREQ_RAND, 0); 709 EDATA_READUNLOCKS(shndxdata); 710 return (NULL); 711 } 712 *xshndx = (((Elf32_Word *)shndxdata->d_buf)[ndx]); 713 EDATA_READUNLOCKS(shndxdata); 714 } else { 715 *xshndx = 0; 716 } 717 return (symptr); 718 } 719 720 int 721 gelf_update_symshndx(Elf_Data *symdata, Elf_Data *shndxdata, 722 int ndx, GElf_Sym *symptr, Elf32_Word xshndx) 723 { 724 if (gelf_update_sym(symdata, ndx, symptr) == 0) 725 return (0); 726 if (shndxdata) { 727 ELFWLOCK(EDATA_ELF(shndxdata)); 728 if ((ndx * sizeof (Elf32_Word)) >= shndxdata->d_size) { 729 _elf_seterr(EREQ_RAND, 0); 730 ELFUNLOCK(EDATA_ELF(shndxdata)); 731 return (0); 732 } 733 ((Elf32_Word *)shndxdata->d_buf)[ndx] = xshndx; 734 ELFUNLOCK(EDATA_ELF(shndxdata)); 735 } 736 return (1); 737 } 738 739 740 GElf_Move * 741 gelf_getmove(Elf_Data *src, int ndx, GElf_Move *dst) 742 { 743 int class; 744 size_t entsize; 745 746 if (src == NULL) 747 return (NULL); 748 749 class = EDATA_CLASS(src); 750 if (class == ELFCLASS32) 751 entsize = sizeof (Elf32_Move); 752 else if (class == ELFCLASS64) 753 entsize = sizeof (GElf_Move); 754 else { 755 _elf_seterr(EREQ_CLASS, 0); 756 return (NULL); 757 } 758 EDATA_READLOCKS(src); 759 760 if ((entsize * ndx) >= src->d_size) { 761 _elf_seterr(EREQ_RAND, 0); 762 dst = NULL; 763 } else if (class == ELFCLASS32) { 764 Elf32_Move * m = &((Elf32_Move *)src->d_buf)[ndx]; 765 766 dst->m_poffset = (Elf64_Word)m->m_poffset; 767 dst->m_repeat = (Elf64_Xword)m->m_repeat; 768 dst->m_stride = (Elf64_Half)m->m_stride; 769 dst->m_value = (Elf64_Xword)m->m_value; 770 dst->m_info = ELF64_M_INFO(ELF32_M_SYM(m->m_info), 771 ELF32_M_SIZE(m->m_info)); 772 } else { 773 *dst = ((Elf64_Move *)src->d_buf)[ndx]; 774 } 775 776 EDATA_READUNLOCKS(src); 777 return (dst); 778 } 779 780 int 781 gelf_update_move(Elf_Data *dest, int ndx, GElf_Move *src) 782 { 783 int class, rc = 1; 784 size_t entsize; 785 786 if (dest == NULL) 787 return (0); 788 789 class = EDATA_CLASS(dest); 790 if (class == ELFCLASS32) 791 entsize = sizeof (Elf32_Move); 792 else if (class == ELFCLASS64) 793 entsize = sizeof (GElf_Move); 794 else { 795 _elf_seterr(EREQ_CLASS, 0); 796 return (0); 797 } 798 ELFWLOCK(EDATA_ELF(dest)); 799 800 if ((entsize * ndx) >= dest->d_size) { 801 _elf_seterr(EREQ_RAND, 0); 802 rc = 0; 803 } else if (class == ELFCLASS32) { 804 Elf32_Move * m = &((Elf32_Move *)dest->d_buf)[ndx]; 805 806 m->m_poffset = (Elf32_Word)src->m_poffset; 807 m->m_repeat = (Elf32_Half)src->m_repeat; 808 m->m_stride = (Elf32_Half)src->m_stride; 809 m->m_value = (Elf32_Lword)src->m_value; 810 m->m_info = (Elf32_Word)ELF32_M_INFO(ELF64_M_SYM(src->m_info), 811 ELF64_M_SIZE(src->m_info)); 812 } else { 813 ((Elf64_Move *)dest->d_buf)[ndx] = *(Elf64_Move *)src; 814 } 815 816 ELFUNLOCK(EDATA_ELF(dest)); 817 return (rc); 818 } 819 820 821 GElf_Rela * 822 gelf_getrela(Elf_Data *src, int ndx, GElf_Rela *dst) 823 { 824 int class; 825 size_t entsize; 826 827 if (src == NULL) 828 return (NULL); 829 830 class = EDATA_CLASS(src); 831 if (class == ELFCLASS32) 832 entsize = sizeof (Elf32_Rela); 833 else if (class == ELFCLASS64) 834 entsize = sizeof (GElf_Rela); 835 else { 836 _elf_seterr(EREQ_CLASS, 0); 837 return (NULL); 838 } 839 EDATA_READLOCKS(src); 840 841 if ((entsize * ndx) >= src->d_size) { 842 _elf_seterr(EREQ_RAND, 0); 843 dst = NULL; 844 } else if (class == ELFCLASS32) { 845 Elf32_Rela * r = &((Elf32_Rela *)src->d_buf)[ndx]; 846 847 dst->r_offset = (GElf_Addr)r->r_offset; 848 dst->r_addend = (GElf_Addr)r->r_addend; 849 850 /* 851 * Elf32 will never have the extra data field that 852 * Elf64's r_info field can have, so ignore it. 853 */ 854 /* LINTED */ 855 dst->r_info = ELF64_R_INFO( 856 ELF32_R_SYM(r->r_info), 857 ELF32_R_TYPE(r->r_info)); 858 } else 859 *dst = ((Elf64_Rela *)src->d_buf)[ndx]; 860 861 EDATA_READUNLOCKS(src); 862 return (dst); 863 } 864 865 866 int 867 gelf_update_rela(Elf_Data *dst, int ndx, GElf_Rela *src) 868 { 869 int class, rc = 1; 870 size_t entsize; 871 872 if (dst == NULL) 873 return (0); 874 875 class = EDATA_CLASS(dst); 876 if (class == ELFCLASS32) 877 entsize = sizeof (Elf32_Rela); 878 else if (class == ELFCLASS64) 879 entsize = sizeof (GElf_Rela); 880 else { 881 _elf_seterr(EREQ_CLASS, 0); 882 return (0); 883 } 884 ELFWLOCK(EDATA_ELF(dst)); 885 886 if ((entsize * ndx) >= dst->d_size) { 887 _elf_seterr(EREQ_RAND, 0); 888 rc = 0; 889 } else if (class == ELFCLASS32) { 890 Elf32_Rela * r = &((Elf32_Rela *)dst->d_buf)[ndx]; 891 892 /* LINTED */ 893 r->r_offset = (Elf32_Addr) src->r_offset; 894 /* LINTED */ 895 r->r_addend = (Elf32_Sword)src->r_addend; 896 897 /* 898 * Elf32 will never have the extra data field that 899 * Elf64's r_info field can have, so ignore it. 900 */ 901 /* LINTED */ 902 r->r_info = ELF32_R_INFO(ELF64_R_SYM(src->r_info), 903 ELF64_R_TYPE(src->r_info)); 904 } else { 905 ((Elf64_Rela *)dst->d_buf)[ndx] = *(Elf64_Rela *)src; 906 } 907 908 ELFUNLOCK(EDATA_ELF(dst)); 909 910 return (rc); 911 } 912 913 914 GElf_Rel * 915 gelf_getrel(Elf_Data *src, int ndx, GElf_Rel *dst) 916 { 917 int class; 918 size_t entsize; 919 920 if (src == NULL) 921 return (NULL); 922 923 class = EDATA_CLASS(src); 924 if (class == ELFCLASS32) 925 entsize = sizeof (Elf32_Rel); 926 else if (class == ELFCLASS64) 927 entsize = sizeof (GElf_Rel); 928 else { 929 _elf_seterr(EREQ_CLASS, 0); 930 return (NULL); 931 } 932 EDATA_READLOCKS(src); 933 934 if ((entsize * ndx) >= src->d_size) { 935 _elf_seterr(EREQ_RAND, 0); 936 dst = NULL; 937 } else if (class == ELFCLASS32) { 938 Elf32_Rel * r = &((Elf32_Rel *)src->d_buf)[ndx]; 939 940 dst->r_offset = (GElf_Addr)r->r_offset; 941 942 /* 943 * Elf32 will never have the extra data field that 944 * Elf64's r_info field can have, so ignore it. 945 */ 946 /* LINTED */ 947 dst->r_info = ELF64_R_INFO(ELF32_R_SYM(r->r_info), 948 ELF32_R_TYPE(r->r_info)); 949 } else 950 *dst = ((Elf64_Rel *)src->d_buf)[ndx]; 951 952 EDATA_READUNLOCKS(src); 953 return (dst); 954 } 955 956 957 int 958 gelf_update_rel(Elf_Data *dst, int ndx, GElf_Rel *src) 959 { 960 int class, rc = 1; 961 size_t entsize; 962 963 if (dst == NULL) 964 return (0); 965 966 class = EDATA_CLASS(dst); 967 if (class == ELFCLASS32) 968 entsize = sizeof (Elf32_Rel); 969 else if (class == ELFCLASS64) 970 entsize = sizeof (GElf_Rel); 971 else { 972 _elf_seterr(EREQ_CLASS, 0); 973 return (0); 974 } 975 ELFWLOCK(EDATA_ELF(dst)); 976 977 if ((entsize * ndx) >= dst->d_size) { 978 _elf_seterr(EREQ_RAND, 0); 979 rc = 0; 980 } else if (class == ELFCLASS32) { 981 Elf32_Rel * r = &((Elf32_Rel *)dst->d_buf)[ndx]; 982 983 /* LINTED */ 984 r->r_offset = (Elf32_Addr) src->r_offset; 985 986 /* 987 * Elf32 will never have the extra data field that 988 * Elf64's r_info field can have, so ignore it. 989 */ 990 /* LINTED */ 991 r->r_info = ELF32_R_INFO(ELF64_R_SYM(src->r_info), 992 ELF64_R_TYPE(src->r_info)); 993 994 } else { 995 ((Elf64_Rel *)dst->d_buf)[ndx] = *(Elf64_Rel *)src; 996 } 997 998 ELFUNLOCK(EDATA_ELF(dst)); 999 return (rc); 1000 } 1001 1002 long 1003 gelf_checksum(Elf *elf) 1004 { 1005 int class = gelf_getclass(elf); 1006 1007 if (class == ELFCLASS32) 1008 return (elf32_checksum(elf)); 1009 else if (class == ELFCLASS64) 1010 return (elf64_checksum(elf)); 1011 1012 _elf_seterr(EREQ_CLASS, 0); 1013 return (0); 1014 } 1015 1016 GElf_Cap * 1017 gelf_getcap(Elf_Data *data, int ndx, GElf_Cap *dst) 1018 { 1019 int class; 1020 size_t entsize; 1021 1022 if (data == NULL) 1023 return (NULL); 1024 1025 class = EDATA_CLASS(data); 1026 if (class == ELFCLASS32) 1027 entsize = sizeof (Elf32_Cap); 1028 else if (class == ELFCLASS64) 1029 entsize = sizeof (GElf_Cap); 1030 else { 1031 _elf_seterr(EREQ_CLASS, 0); 1032 return (NULL); 1033 } 1034 1035 EDATA_READLOCKS(data); 1036 1037 if ((entsize * ndx) >= data->d_size) { 1038 _elf_seterr(EREQ_RAND, 0); 1039 dst = NULL; 1040 } else if (class == ELFCLASS32) { 1041 Elf32_Cap *c = &(((Elf32_Cap *)data->d_buf)[ndx]); 1042 1043 dst->c_tag = (Elf64_Xword)c->c_tag; 1044 dst->c_un.c_val = (Elf64_Xword)c->c_un.c_val; 1045 } else 1046 *dst = ((GElf_Cap *)data->d_buf)[ndx]; 1047 1048 EDATA_READUNLOCKS(data); 1049 return (dst); 1050 } 1051 1052 int 1053 gelf_update_cap(Elf_Data *dst, int ndx, GElf_Cap *src) 1054 { 1055 int class, rc = 1; 1056 size_t entsize; 1057 1058 if (dst == NULL) 1059 return (0); 1060 1061 class = EDATA_CLASS(dst); 1062 if (class == ELFCLASS32) 1063 entsize = sizeof (Elf32_Cap); 1064 else if (class == ELFCLASS64) 1065 entsize = sizeof (GElf_Cap); 1066 else { 1067 _elf_seterr(EREQ_CLASS, 0); 1068 return (0); 1069 } 1070 1071 ELFWLOCK(EDATA_ELF(dst)); 1072 1073 if ((entsize * ndx) >= dst->d_size) { 1074 _elf_seterr(EREQ_RAND, 0); 1075 rc = 0; 1076 } else if (class == ELFCLASS32) { 1077 Elf32_Cap *c = &(((Elf32_Cap *)dst->d_buf)[ndx]); 1078 1079 c->c_tag = (Elf32_Word)src->c_tag; 1080 c->c_un.c_val = (Elf32_Word)src->c_un.c_val; 1081 } else 1082 ((Elf64_Cap *)dst->d_buf)[ndx] = *((Elf64_Cap *)src); 1083 1084 ELFUNLOCK(EDATA_ELF(dst)); 1085 return (rc); 1086 } 1087 1088 /* 1089 * If the specified object has a dynamic section, and that section 1090 * contains a DT_FLAGS_1 entry, then return the value of that entry. 1091 * Otherwise, return 0. 1092 */ 1093 GElf_Xword 1094 _gelf_getdyndtflags_1(Elf *elf) 1095 { 1096 Elf_Scn *scn = NULL; 1097 Elf_Data *data; 1098 GElf_Shdr shdr; 1099 GElf_Dyn dyn; 1100 int i, n; 1101 1102 while (scn = elf_nextscn(elf, scn)) { 1103 if (gelf_getshdr(scn, &shdr) == NULL) 1104 break; 1105 if (shdr.sh_type != SHT_DYNAMIC) 1106 continue; 1107 if (data = elf_getdata(scn, NULL)) { 1108 n = shdr.sh_size / shdr.sh_entsize; 1109 for (i = 0; i < n; i++) { 1110 (void) gelf_getdyn(data, i, &dyn); 1111 if (dyn.d_tag == DT_FLAGS_1) { 1112 return (dyn.d_un.d_val); 1113 } 1114 } 1115 } 1116 break; 1117 } 1118 return (0); 1119 }