tools/jprof/elf.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

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

mercurial