Bumping manifests a=b2g-bump
[gecko.git] / tools / jprof / elf.cpp
blob1de1d2dcc55948300a50f5cc92499b4a2db2e870
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #include "leaky.h"
7 #ifdef USE_ELF
9 #include "leaky.h"
10 #include <stdio.h>
11 #include <malloc.h>
12 #include <libelf/libelf.h>
13 #include <unistd.h>
14 #include <fcntl.h>
15 #include <string.h>
17 void leaky::readSymbols(const char *fileName)
19 int fd = ::open(fileName, O_RDONLY);
20 if (fd < 0) {
21 fprintf(stderr, "%s: unable to open \"%s\"\n", applicationName,
22 fileName);
23 exit(-1);
26 elf_version(EV_CURRENT);
27 Elf *elf = elf_begin(fd, ELF_C_READ, 0);
28 if (!elf) {
29 fprintf(stderr, "%s: \"%s\": has no symbol table\n", applicationName,
30 fileName);
31 exit(-1);
34 long alloced = 10000;
35 Symbol* syms = (Symbol*) malloc(sizeof(Symbol) * 10000);
36 Symbol* sp = syms;
37 Symbol* last = syms + alloced;
39 // Get each of the relevant sections and add them to the list of
40 // symbols.
41 Elf32_Ehdr *ehdr = elf32_getehdr(elf);
42 if (!ehdr) {
43 fprintf(stderr, "%s: elf library lossage\n", applicationName);
44 exit(-1);
46 #if 0
47 Elf32_Half ndx = ehdr->e_shstrndx;
48 #endif
50 Elf_Scn *scn = 0;
51 int strtabndx = -1;
52 for (int i = 1; (scn = elf_nextscn(elf, scn)) != 0; i++) {
53 Elf32_Shdr *shdr = elf32_getshdr(scn);
54 #if 0
55 char *name = elf_strptr(elf, ndx, (size_t) shdr->sh_name);
56 printf("Section %s (%d 0x%x)\n", name ? name : "(null)",
57 shdr->sh_type, shdr->sh_type);
58 #endif
59 if (shdr->sh_type == SHT_STRTAB) {
60 /* We assume here that string tables preceed symbol tables... */
61 strtabndx = i;
62 continue;
64 #if 0
65 if (shdr->sh_type == SHT_DYNAMIC) {
66 /* Dynamic */
67 Elf_Data *data = elf_getdata(scn, 0);
68 if (!data || !data->d_size) {
69 printf("No data...");
70 continue;
73 Elf32_Dyn *dyn = (Elf32_Dyn*) data->d_buf;
74 Elf32_Dyn *lastdyn =
75 (Elf32_Dyn*) ((char*) data->d_buf + data->d_size);
76 for (; dyn < lastdyn; dyn++) {
77 printf("tag=%d value=0x%x\n", dyn->d_tag, dyn->d_un.d_val);
79 } else
80 #endif
81 if ((shdr->sh_type == SHT_SYMTAB) ||
82 (shdr->sh_type == SHT_DYNSYM)) {
83 /* Symbol table */
84 Elf_Data *data = elf_getdata(scn, 0);
85 if (!data || !data->d_size) {
86 printf("No data...");
87 continue;
90 /* In theory we now have the symbols... */
91 Elf32_Sym *esym = (Elf32_Sym*) data->d_buf;
92 Elf32_Sym *lastsym =
93 (Elf32_Sym*) ((char*) data->d_buf + data->d_size);
94 for (; esym < lastsym; esym++) {
95 #if 0
96 char *nm = elf_strptr(elf, strtabndx, (size_t)esym->st_name);
97 printf("%20s 0x%08x %02x %02x\n",
98 nm, esym->st_value, ELF32_ST_BIND(esym->st_info),
99 ELF32_ST_TYPE(esym->st_info));
100 #endif
101 if ((esym->st_value == 0) ||
102 (ELF32_ST_BIND(esym->st_info) == STB_WEAK) ||
103 (ELF32_ST_BIND(esym->st_info) == STB_NUM) ||
104 (ELF32_ST_TYPE(esym->st_info) != STT_FUNC)) {
105 continue;
107 #if 1
108 char *nm = elf_strptr(elf, strtabndx, (size_t)esym->st_name);
109 #endif
110 sp->name = nm ? strdup(nm) : "(no name)";
111 sp->address = esym->st_value;
112 sp++;
113 if (sp >= last) {
114 long n = alloced + 10000;
115 syms = (Symbol*)
116 realloc(syms, (size_t) (sizeof(Symbol) * n));
117 last = syms + n;
118 sp = syms + alloced;
119 alloced = n;
125 int interesting = sp - syms;
126 if (!quiet) {
127 printf("Total of %d symbols\n", interesting);
129 usefulSymbols = interesting;
130 externalSymbols = syms;
133 #endif /* USE_ELF */