8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / cmd / sgs / libelf / common / gelf.c
blob9483826d90b0665ebc2910bed3faa6d3929e775b
1 /*
2 * CDDL HEADER START
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.
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.
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]
19 * CDDL HEADER END
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #include <string.h>
27 #include "_libelf.h"
28 #include "decl.h"
29 #include "msg.h"
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.
38 #define EDATA_CLASS(edata) \
39 (((Dnode *)(edata))->db_scn->s_elf->ed_class)
41 #define EDATA_ELF(edata) \
42 (((Dnode *)(edata))->db_scn->s_elf)
44 #define EDATA_SCN(edata) \
45 (((Dnode *)(edata))->db_scn)
47 #define EDATA_READLOCKS(edata) \
48 READLOCKS(EDATA_ELF((edata)), EDATA_SCN((edata)))
50 #define EDATA_READUNLOCKS(edata) \
51 READUNLOCKS(EDATA_ELF((edata)), EDATA_SCN((edata)))
54 size_t
55 gelf_fsize(Elf * elf, Elf_Type type, size_t count, unsigned ver)
57 int class;
59 if (elf == NULL)
60 return (0);
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));
68 _elf_seterr(EREQ_CLASS, 0);
69 return (0);
73 int
74 gelf_getclass(Elf *elf)
76 if (elf == NULL)
77 return (0);
80 * Don't rely on the idents, a new ehdr doesn't have it!
82 return (elf->ed_class);
86 GElf_Ehdr *
87 gelf_getehdr(Elf *elf, GElf_Ehdr *dst)
89 int class;
91 if (elf == NULL)
92 return (NULL);
94 class = gelf_getclass(elf);
95 if (class == ELFCLASS32) {
96 Elf32_Ehdr * e = elf32_getehdr(elf);
98 if (e == NULL)
99 return (NULL);
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);
118 return (dst);
119 } else if (class == ELFCLASS64) {
120 Elf64_Ehdr * e = elf64_getehdr(elf);
122 if (e == NULL)
123 return (NULL);
125 ELFRLOCK(elf);
126 *dst = *e;
127 ELFUNLOCK(elf);
129 return (dst);
132 _elf_seterr(EREQ_CLASS, 0);
133 return (NULL);
138 gelf_update_ehdr(Elf *elf, GElf_Ehdr *src)
140 int class;
142 if (elf == NULL)
143 return (0);
146 * In case elf isn't cooked.
148 class = gelf_getclass(elf);
149 if (class == ELFCLASSNONE)
150 class = src->e_ident[EI_CLASS];
153 if (class == ELFCLASS32) {
154 Elf32_Ehdr * d = elf32_getehdr(elf);
156 if (d == NULL)
157 return (0);
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);
180 return (1);
181 } else if (class == ELFCLASS64) {
182 Elf64_Ehdr * d = elf64_getehdr(elf);
184 if (d == NULL)
185 return (0);
187 ELFWLOCK(elf);
188 *d = *(Elf64_Ehdr *)src;
189 ELFUNLOCK(elf);
191 return (1);
194 _elf_seterr(EREQ_CLASS, 0);
195 return (0);
199 unsigned long
200 gelf_newehdr(Elf *elf, int class)
202 if (elf == NULL)
203 return (0);
205 if (class == ELFCLASS32)
206 return ((unsigned long)elf32_newehdr(elf));
207 else if (class == ELFCLASS64)
208 return ((unsigned long)elf64_newehdr(elf));
210 _elf_seterr(EREQ_CLASS, 0);
211 return (0);
215 GElf_Phdr *
216 gelf_getphdr(Elf *elf, int ndx, GElf_Phdr *dst)
218 int class;
219 size_t phnum;
221 if (elf == NULL)
222 return (NULL);
224 if (elf_getphdrnum(elf, &phnum) == -1)
225 return (NULL);
227 if (phnum <= ndx) {
228 _elf_seterr(EREQ_RAND, 0);
229 return (NULL);
232 class = gelf_getclass(elf);
233 if ((class != ELFCLASS32) && (class != ELFCLASS64)) {
234 _elf_seterr(EREQ_CLASS, 0);
235 return (NULL);
238 if (class == ELFCLASS32) {
239 Elf32_Phdr *p = &((Elf32_Phdr *)elf32_getphdr(elf))[ndx];
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);
258 return (dst);
263 gelf_update_phdr(Elf *elf, int ndx, GElf_Phdr *src)
265 int class;
266 size_t phnum;
268 if (elf == NULL)
269 return (0);
271 if (elf_getphdrnum(elf, &phnum) == -1)
272 return (NULL);
274 if (phnum < ndx) {
275 _elf_seterr(EREQ_RAND, 0);
276 return (0);
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);
307 return (1);
311 unsigned long
312 gelf_newphdr(Elf *elf, size_t phnum)
314 int class;
316 if (elf == NULL)
317 return (0);
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));
325 _elf_seterr(EREQ_CLASS, 0);
326 return (0);
330 GElf_Shdr *
331 gelf_getshdr(Elf_Scn *scn, GElf_Shdr *dst)
333 if (scn == NULL)
334 return (NULL);
336 if (scn->s_elf->ed_class == ELFCLASS32) {
337 Elf32_Shdr *s = elf32_getshdr(scn);
339 if (s == NULL)
340 return (NULL);
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);
355 return (dst);
356 } else if (scn->s_elf->ed_class == ELFCLASS64) {
357 Elf64_Shdr *s = elf64_getshdr(scn);
359 if (s == NULL)
360 return (NULL);
362 READLOCKS(scn->s_elf, scn);
363 *dst = *(Elf64_Shdr *)s;
364 READUNLOCKS(scn->s_elf, scn);
366 return (dst);
369 _elf_seterr(EREQ_CLASS, 0);
370 return (NULL);
375 gelf_update_shdr(Elf_Scn *scn, GElf_Shdr *src)
377 if (scn == NULL)
378 return (0);
380 if (scn->s_elf->ed_class == ELFCLASS32) {
381 Elf32_Shdr *dst = elf32_getshdr(scn);
383 if (dst == NULL)
384 return (0);
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;
404 ELFUNLOCK(scn->s_elf);
405 return (1);
406 } else if (scn->s_elf->ed_class == ELFCLASS64) {
407 Elf64_Shdr * dst = elf64_getshdr(scn);
409 if (dst == NULL)
410 return (0);
412 ELFWLOCK(scn->s_elf);
413 *dst = *(Elf64_Shdr *)src;
414 ELFUNLOCK(scn->s_elf);
415 return (1);
418 _elf_seterr(EREQ_CLASS, 0);
419 return (0);
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).
429 Elf_Data *
430 gelf_xlatetof(Elf *elf, Elf_Data *dst, const Elf_Data *src, unsigned encode)
432 int class;
434 if ((elf == NULL) || (dst == NULL) || (src == NULL))
435 return (NULL);
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));
443 _elf_seterr(EREQ_CLASS, 0);
444 return (NULL);
448 Elf_Data *
449 gelf_xlatetom(Elf *elf, Elf_Data *dst, const Elf_Data *src, unsigned encode)
451 int class;
453 if ((elf == NULL) || (dst == NULL) || (src == NULL))
454 return (NULL);
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));
462 _elf_seterr(EREQ_CLASS, 0);
463 return (NULL);
467 GElf_Sym *
468 gelf_getsym(Elf_Data * data, int ndx, GElf_Sym * dst)
470 int class;
471 size_t entsize;
473 if (data == NULL)
474 return (NULL);
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);
486 EDATA_READLOCKS(data);
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];
504 EDATA_READUNLOCKS(data);
505 return (dst);
510 gelf_update_sym(Elf_Data *dst, int ndx, GElf_Sym *src)
512 int class, rc = 1;
513 size_t entsize;
515 if (dst == NULL)
516 return (0);
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);
528 ELFWLOCK(EDATA_ELF(dst));
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;
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);
549 ELFUNLOCK(EDATA_ELF(dst));
550 return (rc);
554 GElf_Syminfo *
555 gelf_getsyminfo(Elf_Data *data, int ndx, GElf_Syminfo *dst)
557 int class;
558 size_t entsize;
560 if (data == NULL)
561 return (NULL);
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);
572 EDATA_READLOCKS(data);
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;
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];
586 EDATA_READUNLOCKS(data);
587 return (dst);
591 gelf_update_syminfo(Elf_Data *dst, int ndx, GElf_Syminfo *src)
593 int class, rc = 1;
594 size_t entsize;
596 if (dst == NULL)
597 return (0);
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);
608 ELFWLOCK(EDATA_ELF(dst));
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);
620 ELFUNLOCK(EDATA_ELF(dst));
621 return (rc);
624 GElf_Dyn *
625 gelf_getdyn(Elf_Data *data, int ndx, GElf_Dyn *dst)
627 int class;
628 size_t entsize;
630 if (data == NULL)
631 return (NULL);
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);
642 EDATA_READLOCKS(data);
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];
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];
655 EDATA_READUNLOCKS(data);
656 return (dst);
661 gelf_update_dyn(Elf_Data *dst, int ndx, GElf_Dyn *src)
663 int class, rc = 1;
664 size_t entsize;
666 if (dst == NULL)
667 return (0);
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);
678 ELFWLOCK(EDATA_ELF(dst));
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];
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;
693 ELFUNLOCK(EDATA_ELF(dst));
694 return (rc);
699 GElf_Sym *
700 gelf_getsymshndx(Elf_Data *symdata, Elf_Data *shndxdata,
701 int ndx, GElf_Sym *symptr, Elf32_Word *xshndx)
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);
712 *xshndx = (((Elf32_Word *)shndxdata->d_buf)[ndx]);
713 EDATA_READUNLOCKS(shndxdata);
714 } else {
715 *xshndx = 0;
717 return (symptr);
721 gelf_update_symshndx(Elf_Data *symdata, Elf_Data *shndxdata,
722 int ndx, GElf_Sym *symptr, Elf32_Word xshndx)
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);
733 ((Elf32_Word *)shndxdata->d_buf)[ndx] = xshndx;
734 ELFUNLOCK(EDATA_ELF(shndxdata));
736 return (1);
740 GElf_Move *
741 gelf_getmove(Elf_Data *src, int ndx, GElf_Move *dst)
743 int class;
744 size_t entsize;
746 if (src == NULL)
747 return (NULL);
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);
758 EDATA_READLOCKS(src);
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];
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];
776 EDATA_READUNLOCKS(src);
777 return (dst);
781 gelf_update_move(Elf_Data *dest, int ndx, GElf_Move *src)
783 int class, rc = 1;
784 size_t entsize;
786 if (dest == NULL)
787 return (0);
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);
798 ELFWLOCK(EDATA_ELF(dest));
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];
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;
816 ELFUNLOCK(EDATA_ELF(dest));
817 return (rc);
821 GElf_Rela *
822 gelf_getrela(Elf_Data *src, int ndx, GElf_Rela *dst)
824 int class;
825 size_t entsize;
827 if (src == NULL)
828 return (NULL);
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);
839 EDATA_READLOCKS(src);
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];
847 dst->r_offset = (GElf_Addr)r->r_offset;
848 dst->r_addend = (GElf_Addr)r->r_addend;
851 * Elf32 will never have the extra data field that
852 * Elf64's r_info field can have, so ignore it.
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];
861 EDATA_READUNLOCKS(src);
862 return (dst);
867 gelf_update_rela(Elf_Data *dst, int ndx, GElf_Rela *src)
869 int class, rc = 1;
870 size_t entsize;
872 if (dst == NULL)
873 return (0);
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);
884 ELFWLOCK(EDATA_ELF(dst));
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];
892 /* LINTED */
893 r->r_offset = (Elf32_Addr) src->r_offset;
894 /* LINTED */
895 r->r_addend = (Elf32_Sword)src->r_addend;
898 * Elf32 will never have the extra data field that
899 * Elf64's r_info field can have, so ignore it.
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;
908 ELFUNLOCK(EDATA_ELF(dst));
910 return (rc);
914 GElf_Rel *
915 gelf_getrel(Elf_Data *src, int ndx, GElf_Rel *dst)
917 int class;
918 size_t entsize;
920 if (src == NULL)
921 return (NULL);
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);
932 EDATA_READLOCKS(src);
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];
940 dst->r_offset = (GElf_Addr)r->r_offset;
943 * Elf32 will never have the extra data field that
944 * Elf64's r_info field can have, so ignore it.
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];
952 EDATA_READUNLOCKS(src);
953 return (dst);
958 gelf_update_rel(Elf_Data *dst, int ndx, GElf_Rel *src)
960 int class, rc = 1;
961 size_t entsize;
963 if (dst == NULL)
964 return (0);
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);
975 ELFWLOCK(EDATA_ELF(dst));
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];
983 /* LINTED */
984 r->r_offset = (Elf32_Addr) src->r_offset;
987 * Elf32 will never have the extra data field that
988 * Elf64's r_info field can have, so ignore it.
990 /* LINTED */
991 r->r_info = ELF32_R_INFO(ELF64_R_SYM(src->r_info),
992 ELF64_R_TYPE(src->r_info));
994 } else {
995 ((Elf64_Rel *)dst->d_buf)[ndx] = *(Elf64_Rel *)src;
998 ELFUNLOCK(EDATA_ELF(dst));
999 return (rc);
1002 long
1003 gelf_checksum(Elf *elf)
1005 int class = gelf_getclass(elf);
1007 if (class == ELFCLASS32)
1008 return (elf32_checksum(elf));
1009 else if (class == ELFCLASS64)
1010 return (elf64_checksum(elf));
1012 _elf_seterr(EREQ_CLASS, 0);
1013 return (0);
1016 GElf_Cap *
1017 gelf_getcap(Elf_Data *data, int ndx, GElf_Cap *dst)
1019 int class;
1020 size_t entsize;
1022 if (data == NULL)
1023 return (NULL);
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);
1035 EDATA_READLOCKS(data);
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]);
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];
1048 EDATA_READUNLOCKS(data);
1049 return (dst);
1053 gelf_update_cap(Elf_Data *dst, int ndx, GElf_Cap *src)
1055 int class, rc = 1;
1056 size_t entsize;
1058 if (dst == NULL)
1059 return (0);
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);
1071 ELFWLOCK(EDATA_ELF(dst));
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]);
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);
1084 ELFUNLOCK(EDATA_ELF(dst));
1085 return (rc);
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.
1093 GElf_Xword
1094 _gelf_getdyndtflags_1(Elf *elf)
1096 Elf_Scn *scn = NULL;
1097 Elf_Data *data;
1098 GElf_Shdr shdr;
1099 GElf_Dyn dyn;
1100 int i, n;
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);
1116 break;
1118 return (0);