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