tools/jprof/elf.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     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 {
    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);
    24     }
    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);
    32     }
    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);
    45     }
    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;
    63 	}
    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;
    71 	    }
    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);
    78 	    }
    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;
    88 	    }
    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;
   106 		}
   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;
   120 		}
   121 	    }
   122 	}
   123     }
   125     int interesting = sp - syms;
   126     if (!quiet) {
   127 	printf("Total of %d symbols\n", interesting);
   128     }
   129     usefulSymbols = interesting;
   130     externalSymbols = syms;
   131 }
   133 #endif /* USE_ELF */

mercurial