Bug 1883861 - Part 1: Move visitMemoryBarrier into the common CodeGenerator file...
[gecko.git] / tools / jprof / elf.cpp
blobc2e00f60dafd059b1d60a20018c81a11976c671e
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) {
18 int fd = ::open(fileName, O_RDONLY);
19 if (fd < 0) {
20 fprintf(stderr, "%s: unable to open \"%s\"\n", applicationName, fileName);
21 exit(-1);
24 elf_version(EV_CURRENT);
25 Elf* elf = elf_begin(fd, ELF_C_READ, 0);
26 if (!elf) {
27 fprintf(stderr, "%s: \"%s\": has no symbol table\n", applicationName,
28 fileName);
29 exit(-1);
32 long alloced = 10000;
33 Symbol* syms = (Symbol*)malloc(sizeof(Symbol) * 10000);
34 Symbol* sp = syms;
35 Symbol* last = syms + alloced;
37 // Get each of the relevant sections and add them to the list of
38 // symbols.
39 Elf32_Ehdr* ehdr = elf32_getehdr(elf);
40 if (!ehdr) {
41 fprintf(stderr, "%s: elf library lossage\n", applicationName);
42 exit(-1);
44 # if 0
45 Elf32_Half ndx = ehdr->e_shstrndx;
46 # endif
48 Elf_Scn* scn = 0;
49 int strtabndx = -1;
50 for (int i = 1; (scn = elf_nextscn(elf, scn)) != 0; i++) {
51 Elf32_Shdr* shdr = elf32_getshdr(scn);
52 # if 0
53 char *name = elf_strptr(elf, ndx, (size_t) shdr->sh_name);
54 printf("Section %s (%d 0x%x)\n", name ? name : "(null)",
55 shdr->sh_type, shdr->sh_type);
56 # endif
57 if (shdr->sh_type == SHT_STRTAB) {
58 /* We assume here that string tables preceed symbol tables... */
59 strtabndx = i;
60 continue;
62 # if 0
63 if (shdr->sh_type == SHT_DYNAMIC) {
64 /* Dynamic */
65 Elf_Data *data = elf_getdata(scn, 0);
66 if (!data || !data->d_size) {
67 printf("No data...");
68 continue;
71 Elf32_Dyn *dyn = (Elf32_Dyn*) data->d_buf;
72 Elf32_Dyn *lastdyn =
73 (Elf32_Dyn*) ((char*) data->d_buf + data->d_size);
74 for (; dyn < lastdyn; dyn++) {
75 printf("tag=%d value=0x%x\n", dyn->d_tag, dyn->d_un.d_val);
77 } else
78 # endif
79 if ((shdr->sh_type == SHT_SYMTAB) || (shdr->sh_type == SHT_DYNSYM)) {
80 /* Symbol table */
81 Elf_Data* data = elf_getdata(scn, 0);
82 if (!data || !data->d_size) {
83 printf("No data...");
84 continue;
87 /* In theory we now have the symbols... */
88 Elf32_Sym* esym = (Elf32_Sym*)data->d_buf;
89 Elf32_Sym* lastsym = (Elf32_Sym*)((char*)data->d_buf + data->d_size);
90 for (; esym < lastsym; esym++) {
91 # if 0
92 char *nm = elf_strptr(elf, strtabndx, (size_t)esym->st_name);
93 printf("%20s 0x%08x %02x %02x\n",
94 nm, esym->st_value, ELF32_ST_BIND(esym->st_info),
95 ELF32_ST_TYPE(esym->st_info));
96 # endif
97 if ((esym->st_value == 0) ||
98 (ELF32_ST_BIND(esym->st_info) == STB_WEAK) ||
99 (ELF32_ST_BIND(esym->st_info) == STB_NUM) ||
100 (ELF32_ST_TYPE(esym->st_info) != STT_FUNC)) {
101 continue;
103 # if 1
104 char* nm = elf_strptr(elf, strtabndx, (size_t)esym->st_name);
105 # endif
106 sp->name = nm ? strdup(nm) : "(no name)";
107 sp->address = esym->st_value;
108 sp++;
109 if (sp >= last) {
110 long n = alloced + 10000;
111 syms = (Symbol*)realloc(syms, (size_t)(sizeof(Symbol) * n));
112 last = syms + n;
113 sp = syms + alloced;
114 alloced = n;
120 int interesting = sp - syms;
121 if (!quiet) {
122 printf("Total of %d symbols\n", interesting);
124 usefulSymbols = interesting;
125 externalSymbols = syms;
128 #endif /* USE_ELF */