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