]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gprofng/src/Elf.cc
Update year range in copyright notice of binutils files
[thirdparty/binutils-gdb.git] / gprofng / src / Elf.cc
CommitLineData
fd67aa11 1/* Copyright (C) 2021-2024 Free Software Foundation, Inc.
bb368aad
VM
2 Contributed by Oracle.
3
4 This file is part of GNU Binutils.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
9 any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 51 Franklin Street - Fifth Floor, Boston,
19 MA 02110-1301, USA. */
20
21#include "config.h"
22#include <unistd.h>
23
24#include "util.h"
25#include "bfd.h"
26#include "elf-bfd.h"
27#include "Elf.h"
28#include "Map.h"
29#include "StringBuilder.h"
30#include "DbeFile.h"
31
32typedef uint32_t Elf32_Word;
33typedef uint32_t Elf64_Word;
34typedef uint32_t Elf32_Addr;
35typedef uint64_t Elf64_Addr;
36typedef uint64_t Elf64_Xword;
37typedef int32_t Elf32_Sword;
38typedef int64_t Elf64_Sxword;
39typedef uint16_t Elf32_Half;
40typedef uint16_t Elf64_Half;
41
42// Ancillary entry
43typedef struct
44{
45 Elf32_Word a_tag; /* how to interpret value */
46 union
47 {
48 Elf32_Word a_val;
49 Elf32_Addr a_ptr;
50 } a_un;
51} Elf32_Ancillary;
52
53struct S_Elf64_Ancillary
54{
55 Elf64_Xword a_tag; /* how to interpret value */
56 union
57 {
58 Elf64_Xword a_val;
59 Elf64_Addr a_ptr;
60 } a_un;
61};
62
63/* Dynamic section entry. */
64typedef struct
65{
66 Elf32_Sword d_tag; /* Dynamic entry type */
67
68 union
69 {
70 Elf32_Word d_val; /* Integer value */
71 Elf32_Addr d_ptr; /* Address value */
72 } d_un;
73} Elf32_Dyn;
74
75struct S_Elf64_Dyn
76{
77 Elf64_Sxword d_tag; /* Dynamic entry type */
78
79 union
80 {
81 Elf64_Xword d_val; /* Integer value */
82 Elf64_Addr d_ptr; /* Address value */
83 } d_un;
84};
85
86
87// Symbol table
88typedef struct
89{
90 Elf32_Word st_name;
91 Elf32_Addr st_value;
92 Elf32_Word st_size;
93 unsigned char st_info; /* bind, type: ELF_32_ST_... */
94 unsigned char st_other;
95 Elf32_Half st_shndx; /* SHN_... */
96} Elf32_Sym;
97
98typedef struct
99{
100 Elf64_Word st_name;
101 unsigned char st_info; /* bind, type: ELF_64_ST_... */
102 unsigned char st_other;
103 Elf64_Half st_shndx; /* SHN_... */
104 Elf64_Addr st_value;
105 Elf64_Xword st_size;
106} Elf64_Sym;
107
108
109// Relocation
110typedef struct
111{
112 Elf32_Addr r_offset;
113 Elf32_Word r_info; /* sym, type: ELF32_R_... */
114} Elf32_Rel;
115
116typedef struct
117{
118 Elf32_Addr r_offset;
119 Elf32_Word r_info; /* sym, type: ELF32_R_... */
120 Elf32_Sword r_addend;
121} Elf32_Rela;
122
123typedef struct
124{
125 Elf64_Addr r_offset;
126 Elf64_Xword r_info; /* sym, type: ELF64_R_... */
127} Elf64_Rel;
128
129typedef struct
130{
131 Elf64_Addr r_offset;
132 Elf64_Xword r_info; /* sym, type: ELF64_R_... */
133 Elf64_Sxword r_addend;
134} Elf64_Rela;
135
136int Elf::bfd_status = -1;
137
138void
139Elf::elf_init ()
140{
141 if (bfd_status == -1)
142 bfd_status = bfd_init ();
143}
144
145Elf::Elf (char *filename) : DbeMessages (), Data_window (filename)
146{
147 ehdrp = NULL;
148 data = NULL;
149 ancillary_files = NULL;
150 elfSymbols = NULL;
151 gnu_debug_file = NULL;
152 dbeFile = NULL;
153 abfd = NULL;
7434de7e
VM
154 bfd_symcnt = -1;
155 bfd_dynsymcnt = -1;
156 bfd_synthcnt = -1;
157 bfd_sym = NULL;
158 bfd_dynsym = NULL;
159 bfd_synthsym = NULL;
160 synthsym = NULL;
161
bb368aad
VM
162 if (bfd_status != BFD_INIT_MAGIC)
163 {
164 status = ELF_ERR_CANT_OPEN_FILE;
165 return;
166 }
167 abfd = bfd_openr (filename, NULL);
168 if (abfd == NULL)
169 {
170 status = ELF_ERR_CANT_OPEN_FILE;
171 return;
172 }
7434de7e 173 abfd->flags |= BFD_DECOMPRESS;
bb368aad
VM
174 if (!bfd_check_format (abfd, bfd_object))
175 {
176 bfd_close (abfd);
177 abfd = NULL;
178 status = ELF_ERR_CANT_OPEN_FILE;
179 return;
180 }
181 ehdrp = elf_getehdr ();
182 if (ehdrp == NULL)
183 {
184 bfd_close (abfd);
185 abfd = NULL;
186 status = ELF_ERR_BAD_ELF_FORMAT;
187 return;
188 }
189 elf_class = ehdrp->e_ident[EI_CLASS];
190 elf_datatype = ehdrp->e_ident[EI_DATA];
191
192 if (not_opened ())
193 {
194 status = ELF_ERR_CANT_OPEN_FILE;
195 return;
196 }
197 status = ELF_ERR_NONE;
198
199#if ARCH(SPARC)
200 need_swap_endian = is_Intel ();
201#else
202 need_swap_endian = !is_Intel ();
203#endif
204
205 analyzerInfo = 0;
206 SUNW_ldynsym = 0;
207 gnuLink = 0;
208 stab = 0;
209 stabStr = 0;
210 stabIndex = 0;
211 stabIndexStr = 0;
212 stabExcl = 0;
213 stabExclStr = 0;
214 symtab = 0;
215 dynsym = 0;
216 info = 0;
217 plt = 0;
218 dwarf = false;
219
220 for (unsigned int sec = 1; sec < elf_getehdr ()->e_shnum; sec++)
221 {
222 char *name = get_sec_name (sec);
223 if (name == NULL)
224 continue;
225 if (streq (name, NTXT (".stab")))
226 stab = sec;
227 else if (streq (name, NTXT (".stabstr")))
228 stabStr = sec;
229 else if (streq (name, NTXT (".stab.index")))
230 stabIndex = sec;
231 else if (streq (name, NTXT (".stab.indexstr")))
232 stabIndexStr = sec;
233 else if (streq (name, NTXT (".stab.excl")))
234 stabExcl = sec;
235 else if (streq (name, NTXT (".stab.exclstr")))
236 stabExclStr = sec;
237 else if (streq (name, NTXT (".gnu_debuglink")))
238 gnuLink = sec;
239 else if (streq (name, NTXT (".__analyzer_info")))
240 analyzerInfo = sec;
241 else if (streq (name, NTXT (".info")))
242 info = true;
243 else if (streq (name, NTXT (".plt")))
244 plt = sec;
245 else if (streq (name, NTXT (".SUNW_ldynsym")))
246 SUNW_ldynsym = sec;
247 else if (streq (name, NTXT (".dynsym")))
248 dynsym = sec;
249 else if (streq (name, NTXT (".symtab")))
250 symtab = sec;
251 else if (strncmp (name, NTXT (".debug"), 6) == 0)
252 dwarf = true;
253 }
254 if (fd != -1)
255 {
256 close (fd);
257 fd = -1;
258 }
259}
260
261Elf::~Elf ()
262{
263 if (data)
264 {
265 for (int i = 0; i < (int) ehdrp->e_shnum; i++)
266 {
267 Elf_Data *p = data[i];
268 if (p && !mmap_on_file && (p->d_flags & SHF_SUNW_ABSENT) == 0)
269 free (p->d_buf);
270 delete p;
271 }
272 free (data);
273 }
274 if (ancillary_files)
275 {
276 ancillary_files->destroy ();
277 delete ancillary_files;
278 }
279 delete elfSymbols;
280 delete gnu_debug_file;
281 delete dbeFile;
7434de7e
VM
282 delete synthsym;
283 free (bfd_sym);
284 free (bfd_dynsym);
285 free (bfd_synthsym);
bb368aad
VM
286 if (abfd)
287 bfd_close (abfd);
288}
289
290Elf_Internal_Ehdr *
291Elf::elf_getehdr ()
292{
293 if (ehdrp == NULL && abfd)
294 ehdrp = elf_elfheader (abfd);
295 return ehdrp;
296}
297
298Elf_Internal_Phdr *
299Elf::get_phdr (unsigned int ndx)
300{
301 if (ehdrp == NULL || ndx >= ehdrp->e_phnum)
302 return NULL;
303 return &(elf_tdata (abfd)->phdr[ndx]);
304}
305
306Elf_Internal_Shdr *
307Elf::get_shdr (unsigned int ndx)
308{
309 if (ehdrp == NULL || ndx >= ehdrp->e_shnum)
310 return NULL;
311 return elf_elfsections (abfd)[ndx];
312}
313
314Elf64_Dyn *
315Elf::elf_getdyn (Elf_Internal_Phdr *phdr, unsigned int ndx, Elf64_Dyn *pdyn)
316{
317 if (elf_getclass () == ELFCLASS32)
318 {
319 if (ndx * sizeof (Elf32_Dyn) >= phdr->p_filesz)
320 return NULL;
321 Elf32_Dyn *hdr = (Elf32_Dyn*) bind (phdr->p_offset + ndx * sizeof (Elf32_Dyn),
322 sizeof (Elf32_Dyn));
323 if (hdr == NULL)
324 return NULL;
325 pdyn->d_tag = decode (hdr->d_tag);
326 pdyn->d_un.d_val = decode (hdr->d_un.d_val);
327 }
328 else
329 {
330 if (ndx * sizeof (Elf64_Dyn) >= phdr->p_filesz)
331 return NULL;
332 Elf64_Dyn *hdr = (Elf64_Dyn*) bind (phdr->p_offset + ndx * sizeof (Elf64_Dyn),
333 sizeof (Elf64_Dyn));
334 if (hdr == NULL)
335 return NULL;
336 pdyn->d_tag = decode (hdr->d_tag);
337 pdyn->d_un.d_val = decode (hdr->d_un.d_val);
338 }
339 return pdyn;
340}
341
342unsigned
343Elf::elf_version (unsigned ver)
344{
345 // We compile locally, no need to check the version
346 return ver;
347}
348
349Elf *
350Elf::elf_begin (char *fname, Elf_status *stp)
351{
352 if (fname == NULL)
353 {
354 if (stp)
355 *stp = ELF_ERR_CANT_OPEN_FILE;
356 return NULL;
357 }
358 Elf *elf = new Elf (fname);
359 if (stp)
360 *stp = elf->status;
361 if (elf->status != ELF_ERR_NONE)
362 {
363 delete elf;
364 return NULL;
365 }
366#if DEBUG
367 if (DUMP_ELF_SEC)
368 {
369 char *str = elf->dump ();
370 fprintf (stderr, NTXT ("%s\n\n"), str);
371 free (str);
372 }
373#endif /* DEBUG */
374 return elf;
375}
376
377unsigned int
378Elf::elf_get_sec_num (const char *name)
379{
380 if (name == NULL || ehdrp == NULL)
381 return 0;
382 for (unsigned int sec = 1; sec < ehdrp->e_shnum; sec++)
383 {
384 Elf_Internal_Shdr *shdr = get_shdr (sec);
385 if (shdr == NULL)
386 continue;
387 char *sname = elf_strptr (ehdrp->e_shstrndx, shdr->sh_name);
388 if (sname != NULL && strcmp (name, sname) == 0)
389 return sec;
390 }
391 return 0;
392}
393
394char *
395Elf::get_sec_name (unsigned int sec)
396{
397 Elf_Internal_Shdr *shdr = get_shdr (sec);
398 if (ehdrp == NULL || shdr == NULL)
399 return NULL;
400 return elf_strptr (ehdrp->e_shstrndx, shdr->sh_name);
401}
402
403Elf_Data *
404Elf::elf_getdata (unsigned int sec)
405{
406 if (data == NULL)
407 {
408 data = (Elf_Data **) malloc (ehdrp->e_shnum * sizeof (Elf_Data *));
409 for (int i = 0; i < (int) ehdrp->e_shnum; i++)
410 data[i] = NULL;
411 }
412 Elf_Data *edta = data[sec];
413 if (edta == NULL)
414 {
415 Elf_Internal_Shdr *shdr = get_shdr (sec);
416 if (shdr == NULL)
417 return NULL;
418 edta = new Elf_Data;
419 data[sec] = edta;
420 if ((shdr->sh_flags & SHF_SUNW_ABSENT) != 0)
421 {
422 char *sname = get_sec_name (sec);
423 for (int i = 0, sz = VecSize(ancillary_files); i < sz; i++)
424 {
425 Elf *ancElf = ancillary_files->fetch (i);
426 int secNum = sec;
427 if (dbe_strcmp (sname, ancElf->get_sec_name (sec)) != 0)
428 {
429 append_msg (CMSG_WARN,
430 "Warning: the section #%d (%s) is mismatch in ancillary file '%s')\n",
431 sec, STR (sname), STR (ancElf->fname));
432 secNum = ancElf->elf_get_sec_num (sname);
433 }
434 if (secNum > 0)
435 {
436 Elf_Data *ed = ancElf->elf_getdata (secNum);
437 if (ed && ed->d_buf)
438 {
439 *edta = *ed;
440 edta->d_flags |= SHF_SUNW_ABSENT;
441 return edta;
442 }
443 }
444 }
445 }
446 edta->d_buf = get_data (shdr->sh_offset, (size_t) shdr->sh_size, NULL);
447 edta->d_flags = shdr->sh_flags;
448 edta->d_size = ((edta->d_buf == NULL) || (shdr->sh_type == SHT_NOBITS)) ? 0 : shdr->sh_size;
449 edta->d_off = shdr->sh_offset;
450 edta->d_align = shdr->sh_addralign;
451 }
452 return edta;
453}
454
455int64_t
456Elf::elf_checksum ()
457{
458 if (ehdrp == NULL)
459 return 0;
460 int64_t chk = 0;
461 for (unsigned int ndx = 0; ndx < ehdrp->e_phnum; ndx++)
462 {
463 Elf_Internal_Phdr *phdr = get_phdr (ndx);
464 if (phdr == NULL)
465 continue;
466 if (phdr->p_type == PT_DYNAMIC)
467 {
468 Elf64_Dyn edyn;
469 for (unsigned int i = 0; elf_getdyn (phdr, i, &edyn) != NULL; i++)
470 {
471 if (!edyn.d_tag)
472 break;
473 if (edyn.d_tag == DT_CHECKSUM)
474 {
475 chk = edyn.d_un.d_val;
476 break;
477 }
478 }
479 }
480 }
481 return normalize_checksum (chk);
482}
483
484uint64_t
485Elf::get_baseAddr ()
486{
487 uint64_t addr = 0;
488 for (unsigned int pnum = 0; pnum < elf_getehdr ()->e_phnum; pnum++)
489 {
490 Elf_Internal_Phdr *phdr = get_phdr (pnum);
491 if (phdr->p_type == PT_LOAD && phdr->p_flags == (PF_R | PF_X))
492 {
493 if (addr == 0)
494 addr = phdr->p_vaddr;
495 else
496 {
497 addr = 0;
498 break;
499 }
500 }
501 }
502 return addr;
503}
504
505char *
506Elf::elf_strptr (unsigned int sec, uint64_t off)
507{
508 Elf_Data *edta = elf_getdata (sec);
509 if (edta && edta->d_buf && edta->d_size > off)
510 return ((char *) edta->d_buf) + off;
511 return NULL;
512}
513
514Elf_Internal_Sym *
515Elf::elf_getsym (Elf_Data *edta, unsigned int ndx, Elf_Internal_Sym *dst)
516{
517 if (dst == NULL || edta == NULL)
518 return NULL;
519 if (elf_getclass () == ELFCLASS32)
520 {
521 if (edta->d_size <= ndx * sizeof (Elf32_Sym))
522 return NULL;
523 Elf32_Sym *hdr = (Elf32_Sym*) bind (edta->d_off + ndx * sizeof (Elf32_Sym), sizeof (Elf32_Sym));
524 if (hdr == NULL)
525 return NULL;
526 dst->st_name = decode (hdr->st_name);
527 dst->st_value = decode (hdr->st_value);
528 dst->st_size = decode (hdr->st_size);
529 dst->st_info = ELF64_ST_INFO (ELF32_ST_BIND (decode (hdr->st_info)),
530 ELF32_ST_TYPE (decode (hdr->st_info)));
531 dst->st_other = decode (hdr->st_other);
532 dst->st_shndx = decode (hdr->st_shndx);
533 }
534 else
535 {
536 if (edta->d_size <= ndx * sizeof (Elf64_Sym))
537 return NULL;
538 Elf64_Sym *hdr = (Elf64_Sym*) bind (edta->d_off + ndx * sizeof (Elf64_Sym),
539 sizeof (Elf64_Sym));
540 if (hdr == NULL)
541 return NULL;
542 dst->st_name = decode (hdr->st_name);
543 dst->st_value = decode (hdr->st_value);
544 dst->st_size = decode (hdr->st_size);
545 dst->st_info = decode (hdr->st_info);
546 dst->st_other = decode (hdr->st_other);
547 dst->st_shndx = decode (hdr->st_shndx);
548 }
549 return dst;
550}
551
552Elf_Internal_Rela *
553Elf::elf_getrel (Elf_Data *edta, unsigned int ndx, Elf_Internal_Rela *dst)
554{
555 if (dst == NULL || edta == NULL || edta->d_buf == NULL)
556 return NULL;
557 if (elf_getclass () == ELFCLASS32)
558 {
559 Elf32_Rel *rel = ((Elf32_Rel *) edta->d_buf) + ndx;
560 dst->r_offset = decode (rel->r_offset);
561 dst->r_info = ELF64_R_INFO (ELF32_R_SYM (decode (rel->r_info)),
562 ELF32_R_TYPE (decode (rel->r_info)));
563 }
564 else
565 {
566 Elf64_Rel *rel = ((Elf64_Rel *) edta->d_buf) + ndx;
567 dst->r_offset = decode (rel->r_offset);
568 dst->r_info = decode (rel->r_info);
569 }
570 return dst;
571}
572
573Elf_Internal_Rela *
574Elf::elf_getrela (Elf_Data *edta, unsigned int ndx, Elf_Internal_Rela *dst)
575{
576 if (dst == NULL || edta == NULL || edta->d_buf == NULL)
577 return NULL;
578 if (elf_getclass () == ELFCLASS32)
579 {
580 Elf32_Rela *rela = ((Elf32_Rela *) edta->d_buf) + ndx;
581 dst->r_offset = decode (rela->r_offset);
582 dst->r_addend = decode (rela->r_addend);
583 dst->r_info = ELF64_R_INFO (ELF32_R_SYM (decode (rela->r_info)),
584 ELF32_R_TYPE (decode (rela->r_info)));
585 }
586 else
587 {
588 Elf64_Rela *rela = ((Elf64_Rela *) edta->d_buf) + ndx;
589 dst->r_offset = decode (rela->r_offset);
590 dst->r_addend = decode (rela->r_addend);
591 dst->r_info = decode (rela->r_info);
592 }
593 return dst;
594}
595
596Elf64_Ancillary *
597Elf::elf_getancillary (Elf_Data *edta, unsigned int ndx, Elf64_Ancillary *dst)
598{
599 if (dst == NULL || edta == NULL || edta->d_buf == NULL)
600 return NULL;
601 if (elf_getclass () == ELFCLASS32)
602 {
603 Elf32_Ancillary *p = ((Elf32_Ancillary *) edta->d_buf) + ndx;
604 dst->a_tag = decode (p->a_tag);
605 dst->a_un.a_val = decode (p->a_un.a_val);
606 }
607 else
608 {
609 Elf64_Ancillary *p = ((Elf64_Ancillary *) edta->d_buf) + ndx;
610 dst->a_tag = decode (p->a_tag);
611 dst->a_un.a_val = decode (p->a_un.a_val);
612 }
613 return dst;
614}
615
616Elf *
617Elf::get_related_file (const char *lo_name, const char *nm)
618{
619 DbeFile *df;
620 if (*nm == '/')
621 {
622 df = new DbeFile (nm);
623 df->filetype |= (DbeFile::F_FILE | DbeFile::F_DEBUG_FILE);
624 }
625 else
626 {
627 char *bname = get_basename (lo_name);
628 char *fnm = dbe_sprintf ("%.*s/%s", (int) (bname - lo_name), lo_name, nm);
629 df = new DbeFile (fnm);
630 df->filetype |= (DbeFile::F_FILE | DbeFile::F_DEBUG_FILE);
631 free (fnm);
632 }
633 Dprintf (DEBUG_STABS, "get_related_file: %s -> '%s'\n", nm, df->get_name ());
634 Elf_status st = ELF_ERR_CANT_OPEN_FILE;
635 Elf *elf = elf_begin (df->get_location (), &st);
636 if (elf)
637 {
638 elf->dbeFile = df;
639 return elf;
640 }
641 switch (st)
642 {
643 case ELF_ERR_CANT_OPEN_FILE:
644 append_msg (CMSG_ERROR, GTXT ("Cannot open file `%s'"), df->get_name ());
645 break;
646 case ELF_ERR_BAD_ELF_FORMAT:
647 default:
648 append_msg (CMSG_ERROR, GTXT ("Cannot read ELF header of `%s'"),
649 df->get_name ());
650 break;
651 }
652 delete df;
653 return NULL;
654}
655
656Elf *
657Elf::find_ancillary_files (char *lo_name)
658{
659 // read the .gnu_debuglink and .SUNW_ancillary seections
660 if (gnu_debug_file)
661 return gnu_debug_file;
662 unsigned int sec = elf_get_sec_num (NTXT (".gnu_debuglink"));
663 if (sec > 0)
664 {
665 Elf_Data *dp = elf_getdata (sec);
666 if (dp)
667 {
668 gnu_debug_file = get_related_file (lo_name, (char *) (dp->d_buf));
669 if (gnu_debug_file)
670 return gnu_debug_file;
671 }
672 }
673
674 sec = elf_get_sec_num (NTXT (".SUNW_ancillary"));
675 if (sec > 0)
676 {
677 Elf_Internal_Shdr *shdr = get_shdr (sec);
678 uint64_t check_sum = 0;
679 char *ancName = NULL;
680 if (shdr)
681 {
682 Elf_Data *dp = elf_getdata (sec);
683 for (int i = 0, sz = (int) (shdr->sh_size / shdr->sh_entsize);
684 i < sz; i++)
685 {
686 Elf64_Ancillary anc;
687 if (elf_getancillary (dp, i, &anc) == NULL
688 || anc.a_tag == ANC_SUNW_NULL)
689 break;
690 if (anc.a_tag == ANC_SUNW_MEMBER)
691 ancName = elf_strptr (shdr->sh_link, anc.a_un.a_ptr);
692 else if (anc.a_tag == ANC_SUNW_CHECKSUM)
693 {
694 if (i == 0)
695 {
696 check_sum = anc.a_un.a_val;
697 continue;
698 }
699 if (check_sum == anc.a_un.a_val)
700 ancName = NULL;
701 if (ancName)
702 {
703 Elf *ancElf = get_related_file (lo_name, ancName);
704 if (ancElf == NULL)
705 continue;
706 int ancSec = ancElf->elf_get_sec_num (".SUNW_ancillary");
707 if (ancSec > 0)
708 {
709 Elf_Internal_Shdr *ancHdr = ancElf->get_shdr (ancSec);
710 if (ancHdr)
711 {
712 Elf_Data *anc_dp = ancElf->elf_getdata (ancSec);
713 Elf64_Ancillary anc1;
714 if (ancElf->elf_getancillary (anc_dp, 0, &anc1)
715 && (anc1.a_tag == ANC_SUNW_CHECKSUM) &&
716 anc1.a_un.a_val == anc.a_un.a_val)
717 {
718 if (ancillary_files == NULL)
719 ancillary_files = new Vector<Elf*>(2);
720 ancillary_files->append (ancElf);
721 }
722 else
723 append_msg (CMSG_WARN, GTXT ("Load Object: '%s' (checksum Ox%lld). The .anc file '%s' has checksum Ox%llx"),
724 STR (fname), (long long) check_sum,
725 STR (ancElf->dbeFile->get_location ()),
726 (long long) anc1.a_un.a_val);
727 }
728 }
729 ancName = NULL;
730 }
731 }
732 }
733 }
734 }
735 return NULL;
736}
737
7434de7e
VM
738void
739Elf::get_bfd_symbols()
740{
741 if (bfd_symcnt < 0)
742 {
743 if ((bfd_get_file_flags (abfd) & HAS_SYMS) != 0)
744 bfd_symcnt = bfd_get_symtab_upper_bound (abfd);
745 if (bfd_symcnt > 0)
746 {
747 bfd_sym = (asymbol **) malloc (bfd_symcnt);
748 bfd_symcnt = bfd_canonicalize_symtab (abfd, bfd_sym);
749 if (bfd_symcnt < 0)
750 {
751 free (bfd_sym);
752 bfd_sym = NULL;
753 }
754 }
755 else
756 bfd_symcnt = 0;
757 }
758
759 if (bfd_dynsymcnt < 0)
760 {
761 bfd_dynsymcnt = bfd_get_dynamic_symtab_upper_bound (abfd);
762 if (bfd_dynsymcnt > 0)
763 {
764 bfd_dynsym = (asymbol **) malloc (bfd_dynsymcnt);
765 bfd_dynsymcnt = bfd_canonicalize_dynamic_symtab (abfd, bfd_dynsym);
766 if (bfd_dynsymcnt < 0)
767 {
768 free (bfd_dynsym);
769 bfd_dynsym = NULL;
770 }
771 }
772 else
773 bfd_dynsymcnt = 0;
774 }
775 if (bfd_synthcnt < 0)
776 {
777 bfd_synthcnt = bfd_get_synthetic_symtab (abfd, bfd_symcnt, bfd_sym,
778 bfd_dynsymcnt, bfd_dynsym, &bfd_synthsym);
779 if (bfd_synthcnt < 0)
780 bfd_synthcnt = 0;
781 }
782}
783
784static int
785cmp_sym_addr (const void *a, const void *b)
786{
787 asymbol *sym1 = *((asymbol **) a);
788 asymbol *sym2 = *((asymbol **) b);
789 uint64_t a1 = sym1->value;
790 uint64_t a2 = sym2->value;
791 if (sym1->section)
792 a1 += sym1->section->vma;
793 if (sym2->section)
794 a2 += sym2->section->vma;
795 return a1 < a2 ? -1 : (a1 == a2 ? 0 : 1);
796}
797
798const char *
799Elf::get_funcname_in_plt (uint64_t pc)
800{
801 if (synthsym == NULL)
802 {
803 get_bfd_symbols();
804 synthsym = new Vector<asymbol *> (bfd_synthcnt + 1);
805 for (long i = 0; i < bfd_synthcnt; i++)
806 synthsym->append (bfd_synthsym + i);
807 synthsym->sort (cmp_sym_addr);
808 }
809
810 asymbol sym, *symp = &sym;
811 sym.section = NULL;
812 sym.value = pc;
813 long ind = synthsym->bisearch (0, -1, &symp, cmp_sym_addr);
814 if (ind >= 0)
815 return synthsym->get (ind)->name;
816 return NULL;
817}
818
bb368aad
VM
819char*
820Elf::get_location ()
821{
822 return dbeFile ? dbeFile->get_location () : fname;
823}
824
825#define RET_S(x) if (t == x) return (char *) #x
826
827static char *
828get_elf_class_name (int t)
829{
830 RET_S (ELFCLASSNONE);
831 RET_S (ELFCLASS32);
832 RET_S (ELFCLASS64);
833 return NTXT ("ELFCLASS_UNKNOWN");
834}
835
836static char *
837get_elf_data_name (int t)
838{
839 RET_S (ELFDATANONE);
840 RET_S (ELFDATA2LSB);
841 RET_S (ELFDATA2MSB);
842 return NTXT ("ELFDATA_UNKNOWN");
843}
844
845static char *
846get_elf_osabi_name (int t)
847{
848 RET_S (ELFOSABI_NONE);
849 RET_S (ELFOSABI_HPUX);
850 RET_S (ELFOSABI_NETBSD);
851 RET_S (ELFOSABI_LINUX);
852 RET_S (ELFOSABI_SOLARIS);
853 RET_S (ELFOSABI_AIX);
854 RET_S (ELFOSABI_IRIX);
855 RET_S (ELFOSABI_FREEBSD);
856 RET_S (ELFOSABI_TRU64);
857 RET_S (ELFOSABI_MODESTO);
858 RET_S (ELFOSABI_OPENBSD);
859 return NTXT ("ELFOSABI_UNKNOWN");
860}
861
862static char *
863get_elf_etype_name (int t)
864{
865 RET_S (ET_NONE);
866 RET_S (ET_REL);
867 RET_S (ET_EXEC);
868 RET_S (ET_DYN);
869 RET_S (ET_CORE);
870 RET_S (ET_LOPROC);
871 RET_S (ET_HIPROC);
872 return NTXT ("ETYPE_UNKNOWN");
873}
874
875static char *
876get_elf_ptype_name (int t)
877{
878 RET_S (PT_NULL);
879 RET_S (PT_LOAD);
880 RET_S (PT_DYNAMIC);
881 RET_S (PT_INTERP);
882 RET_S (PT_NOTE);
883 RET_S (PT_SHLIB);
884 RET_S (PT_PHDR);
885 RET_S (PT_TLS);
886 RET_S (PT_LOOS);
887 RET_S (PT_GNU_EH_FRAME);
888 RET_S (PT_GNU_EH_FRAME);
889 RET_S (PT_HIOS);
890 RET_S (PT_LOPROC);
891 RET_S (PT_HIPROC);
892 return NTXT ("PTYPE_UNKNOWN");
893}
894
895static char *
896get_elf_shtype_name (unsigned int t)
897{
898 RET_S (SHT_NULL);
899 RET_S (SHT_PROGBITS);
900 RET_S (SHT_SYMTAB);
901 RET_S (SHT_STRTAB);
902 RET_S (SHT_RELA);
903 RET_S (SHT_HASH);
904 RET_S (SHT_DYNAMIC);
905 RET_S (SHT_NOTE);
906 RET_S (SHT_NOBITS);
907 RET_S (SHT_REL);
908 RET_S (SHT_SHLIB);
909 RET_S (SHT_DYNSYM);
910 RET_S (SHT_INIT_ARRAY);
911 RET_S (SHT_FINI_ARRAY);
912 RET_S (SHT_PREINIT_ARRAY);
913 RET_S (SHT_GROUP);
914 RET_S (SHT_SYMTAB_SHNDX);
915 RET_S (SHT_LOOS);
916 RET_S (SHT_SUNW_verdef);
917 RET_S (SHT_SUNW_verneed);
918 RET_S (SHT_HIOS);
919 RET_S (SHT_LOPROC);
920 RET_S (SHT_HIPROC);
921 RET_S (SHT_LOUSER);
922 RET_S (SHT_HIUSER);
923 return NTXT ("SHTYPE_UNKNOWN");
924}
925
926static char *
927get_elf_machine_name (int t)
928{
929 RET_S (EM_NONE);
930 RET_S (EM_M32);
931 RET_S (EM_SPARC);
932 RET_S (EM_386);
933 RET_S (EM_68K);
934 RET_S (EM_88K);
935 RET_S (EM_860);
936 RET_S (EM_MIPS);
937 RET_S (EM_S370);
938 RET_S (EM_MIPS_RS3_LE);
939 RET_S (EM_SPARC32PLUS);
940 RET_S (EM_960);
941 RET_S (EM_PPC);
942 RET_S (EM_PPC64);
943 RET_S (EM_V800);
944 RET_S (EM_FR20);
945 RET_S (EM_RH32);
946 RET_S (EM_RCE);
947 RET_S (EM_ARM);
948 RET_S (EM_ALPHA);
949 RET_S (EM_SH);
950 RET_S (EM_SPARCV9);
951 RET_S (EM_TRICORE);
952 RET_S (EM_ARC);
953 RET_S (EM_H8_300);
954 RET_S (EM_H8_300H);
955 RET_S (EM_H8S);
956 RET_S (EM_H8_500);
957 RET_S (EM_IA_64);
958 RET_S (EM_MIPS_X);
959 RET_S (EM_COLDFIRE);
960 RET_S (EM_68HC12);
961 RET_S (EM_MMA);
962 RET_S (EM_PCP);
963 RET_S (EM_NCPU);
964 RET_S (EM_NDR1);
965 RET_S (EM_STARCORE);
966 RET_S (EM_ME16);
967 RET_S (EM_ST100);
968 RET_S (EM_TINYJ);
969 RET_S (EM_X86_64);
970 RET_S (EM_PDSP);
971 RET_S (EM_FX66);
972 RET_S (EM_ST9PLUS);
973 RET_S (EM_ST7);
974 RET_S (EM_68HC16);
975 RET_S (EM_68HC11);
976 RET_S (EM_68HC08);
977 RET_S (EM_68HC05);
978 RET_S (EM_SVX);
979 RET_S (EM_ST19);
980 RET_S (EM_VAX);
981 RET_S (EM_CRIS);
982 RET_S (EM_JAVELIN);
983 RET_S (EM_FIREPATH);
984 RET_S (EM_ZSP);
985 RET_S (EM_MMIX);
986 RET_S (EM_HUANY);
987 RET_S (EM_PRISM);
988 RET_S (EM_AVR);
989 RET_S (EM_FR30);
990 RET_S (EM_D10V);
991 RET_S (EM_D30V);
992 RET_S (EM_V850);
993 RET_S (EM_M32R);
994 RET_S (EM_MN10300);
995 RET_S (EM_MN10200);
996 RET_S (EM_PJ);
997 RET_S (EM_OPENRISC);
998 RET_S (EM_XTENSA);
999 return NTXT ("ELFMACHINE_UNKNOWN");
1000}
1001
1002static char *
1003get_elf_version_name (int t)
1004{
1005 RET_S (EV_NONE);
1006 RET_S (EV_CURRENT);
1007 return NTXT ("VERSION_UNKNOWN");
1008}
1009
1010static char *
1011get_elf_ancillary_tag (int t)
1012{
1013 RET_S (ANC_SUNW_NULL);
1014 RET_S (ANC_SUNW_CHECKSUM);
1015 RET_S (ANC_SUNW_MEMBER);
1016 RET_S (ANC_SUNW_NUM);
1017 return NTXT ("ANCILLARY_TAG_UNKNOWN");
1018}
1019
1020#define ADD_S(x) if ((f & (x)) == (x)) { sb->append(' '); sb->append(#x); f &= ~(x); }
1021
1022static void
1023dump_sh_flags (StringBuilder *sb, long long flags)
1024{
1025 long long f = flags;
1026 if (f != 0)
1027 {
1028 sb->append (NTXT (" ["));
1029 ADD_S (SHF_WRITE)
1030 ADD_S (SHF_ALLOC)
1031 ADD_S (SHF_EXECINSTR)
1032 ADD_S (SHF_MERGE)
1033 ADD_S (SHF_STRINGS)
1034 ADD_S (SHF_INFO_LINK)
1035 ADD_S (SHF_LINK_ORDER)
1036 ADD_S (SHF_OS_NONCONFORMING)
1037 ADD_S (SHF_GROUP)
1038 ADD_S (SHF_TLS)
1039 ADD_S (SHF_SUNW_ABSENT)
1040 ADD_S (SHF_EXCLUDE)
1041 if (f != 0 && f != flags)
1042 sb->appendf (NTXT (" 0x%llx"), (long long) f);
1043 sb->append (NTXT (" ]"));
1044 }
1045 sb->append (NTXT ("\n"));
1046}
1047
1048static void
1049dump_p_flags (StringBuilder *sb, long long flags)
1050{
1051 long long f = flags;
1052 if (f != 0)
1053 {
1054 sb->append (NTXT (" ["));
1055 ADD_S (PF_X)
1056 ADD_S (PF_W)
1057 ADD_S (PF_R)
1058 ADD_S (PF_MASKPROC)
1059 if (f != 0 && f != flags)
1060 sb->appendf (NTXT (" 0x%llx"), (long long) f);
1061 sb->append (NTXT (" ]"));
1062 }
1063 sb->append (NTXT ("\n"));
1064}
1065
1066char *
1067Elf::dump ()
1068{
1069 StringBuilder sb;
1070 sb.sprintf (NTXT ("ELF Header: %s\n"), fname ? fname : GTXT ("(unknown)"));
1071 if (ehdrp == NULL)
1072 {
1073 sb.appendf (GTXT ("\n\n Cannot read Elf header\n"));
1074 return sb.toString ();
1075 }
1076 sb.appendf (NTXT (" %-15s "), NTXT ("e_ident"));
1077 for (int i = 0; i < EI_NIDENT; i++)
1078 sb.appendf (NTXT ("%x"), ehdrp->e_ident[i]);
1079 sb.append (NTXT ("\n"));
1080 char *fmt0 = NTXT (" %-15s %10lld ( %s )\n");
1081 char *fmt1 = NTXT (" %-15s 0x%08llx ( %lld )\n");
1082 char *fmt2 = NTXT (" %-15s 0x%08llx");
1083 sb.appendf (fmt0, NTXT ("EI_CLASS"), (long long) ehdrp->e_ident[EI_CLASS],
1084 get_elf_class_name (ehdrp->e_ident[EI_CLASS]));
1085 sb.appendf (fmt0, NTXT ("EI_DATA"), (long long) ehdrp->e_ident[EI_DATA],
1086 get_elf_data_name (ehdrp->e_ident[EI_DATA]));
1087 sb.appendf (fmt0, NTXT ("EI_OSABI"), (long long) ehdrp->e_ident[EI_OSABI],
1088 get_elf_osabi_name (ehdrp->e_ident[EI_OSABI]));
1089 sb.appendf (fmt0, NTXT ("e_type"), (long long) ehdrp->e_type,
1090 get_elf_etype_name (ehdrp->e_type));
1091 sb.appendf (fmt0, NTXT ("e_machine"), (long long) ehdrp->e_machine,
1092 get_elf_machine_name (ehdrp->e_machine));
1093 sb.appendf (fmt0, NTXT ("e_version"), (long long) ehdrp->e_version,
1094 get_elf_version_name (ehdrp->e_version));
1095 sb.appendf (fmt1, NTXT ("e_entry"), (long long) ehdrp->e_entry,
1096 (long long) ehdrp->e_entry);
1097 sb.appendf (fmt1, NTXT ("e_phoff"), (long long) ehdrp->e_phoff,
1098 (long long) ehdrp->e_phoff);
1099 sb.appendf (fmt1, NTXT ("e_shoff"), (long long) ehdrp->e_shoff,
1100 (long long) ehdrp->e_shoff);
1101 sb.appendf (fmt1, NTXT ("e_flags"), (long long) ehdrp->e_flags,
1102 (long long) ehdrp->e_flags);
1103 sb.appendf (fmt1, NTXT ("e_ehsize"), (long long) ehdrp->e_ehsize,
1104 (long long) ehdrp->e_ehsize);
1105 sb.appendf (fmt1, NTXT ("e_phentsize"), (long long) ehdrp->e_phentsize,
1106 (long long) ehdrp->e_phentsize);
1107 sb.appendf (fmt1, NTXT ("e_phnum"), (long long) ehdrp->e_phnum,
1108 (long long) ehdrp->e_phnum);
1109 sb.appendf (fmt1, NTXT ("e_shentsize"), (long long) ehdrp->e_shentsize,
1110 (long long) ehdrp->e_shentsize);
1111 sb.appendf (fmt1, NTXT ("e_shnum"), (long long) ehdrp->e_shnum,
1112 (long long) ehdrp->e_shnum);
1113 sb.appendf (fmt1, NTXT ("e_shstrndx"), (long long) ehdrp->e_shstrndx,
1114 (long long) ehdrp->e_shstrndx);
1115
1116 for (unsigned int i = 0; i < ehdrp->e_phnum; i++)
1117 {
1118 sb.appendf (NTXT ("\nProgram Header[%d]:\n"), i);
1119 Elf_Internal_Phdr *phdr = get_phdr (i);
1120 if (phdr == NULL)
1121 {
1122 sb.appendf (NTXT (" ERROR: get_phdr(%d) failed\n"), i);
1123 continue;
1124 }
1125 sb.appendf (fmt0, "p_type", (long long) phdr->p_type,
1126 get_elf_ptype_name (phdr->p_type));
1127 sb.appendf (fmt2, "p_flags", (long long) phdr->p_flags);
1128 dump_p_flags (&sb, phdr->p_flags);
1129 sb.appendf (fmt1, "p_offset", (long long) phdr->p_offset,
1130 (long long) phdr->p_offset);
1131 sb.appendf (fmt1, "p_vaddr", (long long) phdr->p_vaddr,
1132 (long long) phdr->p_vaddr);
1133 sb.appendf (fmt1, "p_paddr", (long long) phdr->p_paddr,
1134 (long long) phdr->p_paddr);
1135 sb.appendf (fmt1, "p_filesz", (long long) phdr->p_filesz,
1136 (long long) phdr->p_filesz);
1137 sb.appendf (fmt1, "p_memsz", (long long) phdr->p_memsz,
1138 (long long) phdr->p_memsz);
1139 sb.appendf (fmt1, "p_align", (long long) phdr->p_align,
1140 (long long) phdr->p_align);
1141 }
1142
1143 for (unsigned int i = 1; i < ehdrp->e_shnum; i++)
1144 {
1145 sb.appendf (NTXT ("\nSection Header[%d]:\n"), i);
1146 Elf_Internal_Shdr *shdr = get_shdr (i);
1147 if (shdr == NULL)
1148 {
1149 sb.appendf (NTXT (" ERROR: get_shdr(%d) failed\n"), i);
1150 continue;
1151 }
1152 char *s = get_sec_name (i);
1153 sb.appendf (fmt0, "sh_name", (long long) shdr->sh_name,
1154 s ? s : NTXT ("NULL"));
1155 sb.appendf (fmt0, "sh_type", (long long) shdr->sh_type,
1156 get_elf_shtype_name (shdr->sh_type));
1157 sb.appendf (fmt2, "sh_flags", (long long) shdr->sh_flags);
1158 dump_sh_flags (&sb, shdr->sh_flags);
1159 sb.appendf (fmt1, "sh_addr", (long long) shdr->sh_addr,
1160 (long long) shdr->sh_addr);
1161 sb.appendf (fmt1, "sh_offset", (long long) shdr->sh_offset,
1162 (long long) shdr->sh_offset);
1163 sb.appendf (fmt1, "sh_size", (long long) shdr->sh_size,
1164 (long long) shdr->sh_size);
1165 sb.appendf (fmt1, "sh_link", (long long) shdr->sh_link,
1166 (long long) shdr->sh_link);
1167 sb.appendf (fmt1, "sh_info", (long long) shdr->sh_info,
1168 (long long) shdr->sh_info);
1169 sb.appendf (fmt1, "sh_addralign", (long long) shdr->sh_addralign,
1170 (long long) shdr->sh_addralign);
1171 sb.appendf (fmt1, "sh_entsize", (long long) shdr->sh_entsize,
1172 (long long) shdr->sh_entsize);
1173 }
1174
1175 for (unsigned int i = 1; i < ehdrp->e_shnum; i++)
1176 {
1177 Elf_Internal_Shdr *shdr = get_shdr (i);
1178 if (shdr == NULL)
1179 continue;
1180 char *secName = get_sec_name (i);
1181 if (secName == NULL)
1182 continue;
1183 if (strcmp (NTXT (".SUNW_ancillary"), secName) == 0)
1184 {
1185 sb.appendf (NTXT ("\nSection[%d]: %s\n"), i, secName);
1186 Elf_Data *dp = elf_getdata (i);
1187 for (int j = 0, cnt = (int) (shdr->sh_size / shdr->sh_entsize);
1188 j < cnt; j++)
1189 {
1190 Elf64_Ancillary anc;
1191 if (elf_getancillary (dp, j, &anc) == NULL)
1192 break;
1193 sb.appendf (NTXT ("%10d %-20s 0x%08llx %6lld"), j,
1194 get_elf_ancillary_tag ((int) anc.a_tag),
1195 (long long) anc.a_un.a_ptr, (long long) anc.a_un.a_ptr);
1196 if (anc.a_tag == ANC_SUNW_MEMBER)
1197 sb.appendf (NTXT (" %s\n"), STR (elf_strptr (shdr->sh_link, anc.a_un.a_ptr)));
1198 else
1199 sb.append (NTXT ("\n"));
1200 }
1201 }
1202 }
1203 return sb.toString ();
1204}
1205
1206void
1207Elf::dump_elf_sec ()
1208{
1209 if (!DUMP_ELF_SEC)
1210 return;
1211 if (ehdrp == NULL)
1212 return;
1213 Dprintf (DUMP_ELF_SEC, "======= DwarfLib::dump_elf_sec\n"
1214 " N |type|flags| sh_addr | sh_offset | sh_size | sh_link |"
1215 " sh_info | sh_addralign | sh_entsize | sh_name | name\n");
1216 for (unsigned int sec = 1; sec < ehdrp->e_shnum; sec++)
1217 {
1218 Elf_Internal_Shdr *shdr = get_shdr (sec);
1219 if (shdr == NULL)
1220 continue;
1221 char *name = elf_strptr (ehdrp->e_shstrndx, shdr->sh_name);
1222 Dprintf (DUMP_ELF_SEC, "%3d:%3d |%4d |%9lld | %9lld |%8lld |%8lld |"
1223 "%8lld |%14d |%11lld | %6lld %s\n",
1224 sec, (int) shdr->sh_type, (int) shdr->sh_flags,
1225 (long long) shdr->sh_addr, (long long) shdr->sh_offset,
1226 (long long) shdr->sh_size, (long long) shdr->sh_link,
1227 (long long) shdr->sh_info,
1228 (int) shdr->sh_addralign, (long long) shdr->sh_entsize,
1229 (long long) shdr->sh_name, name ? name : NTXT ("NULL"));
1230 }
1231 Dprintf (DUMP_ELF_SEC, NTXT ("\n"));
1232}