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
gelf_fsize(Elf * elf,Elf_Type type,size_t count,unsigned ver)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
gelf_getclass(Elf * elf)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 *
gelf_getehdr(Elf * elf,GElf_Ehdr * dst)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
gelf_update_ehdr(Elf * elf,GElf_Ehdr * src)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
gelf_newehdr(Elf * elf,int class)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 *
gelf_getphdr(Elf * elf,int ndx,GElf_Phdr * dst)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
gelf_update_phdr(Elf * elf,int ndx,GElf_Phdr * src)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
gelf_newphdr(Elf * elf,size_t phnum)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 *
gelf_getshdr(Elf_Scn * scn,GElf_Shdr * dst)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
gelf_update_shdr(Elf_Scn * scn,GElf_Shdr * src)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 *
gelf_xlatetof(Elf * elf,Elf_Data * dst,const Elf_Data * src,unsigned encode)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 *
gelf_xlatetom(Elf * elf,Elf_Data * dst,const Elf_Data * src,unsigned encode)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 *
gelf_getsym(Elf_Data * data,int ndx,GElf_Sym * dst)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
gelf_update_sym(Elf_Data * dst,int ndx,GElf_Sym * src)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 *
gelf_getsyminfo(Elf_Data * data,int ndx,GElf_Syminfo * dst)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
gelf_update_syminfo(Elf_Data * dst,int ndx,GElf_Syminfo * src)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 *
gelf_getdyn(Elf_Data * data,int ndx,GElf_Dyn * dst)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
gelf_update_dyn(Elf_Data * dst,int ndx,GElf_Dyn * src)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 *
gelf_getsymshndx(Elf_Data * symdata,Elf_Data * shndxdata,int ndx,GElf_Sym * symptr,Elf32_Word * xshndx)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
gelf_update_symshndx(Elf_Data * symdata,Elf_Data * shndxdata,int ndx,GElf_Sym * symptr,Elf32_Word xshndx)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 *
gelf_getmove(Elf_Data * src,int ndx,GElf_Move * dst)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
gelf_update_move(Elf_Data * dest,int ndx,GElf_Move * src)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 *
gelf_getrela(Elf_Data * src,int ndx,GElf_Rela * dst)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
gelf_update_rela(Elf_Data * dst,int ndx,GElf_Rela * src)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 *
gelf_getrel(Elf_Data * src,int ndx,GElf_Rel * dst)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
gelf_update_rel(Elf_Data * dst,int ndx,GElf_Rel * src)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
gelf_checksum(Elf * elf)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 *
gelf_getcap(Elf_Data * data,int ndx,GElf_Cap * dst)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
gelf_update_cap(Elf_Data * dst,int ndx,GElf_Cap * src)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
_gelf_getdyndtflags_1(Elf * elf)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 }
1120