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