tools/jprof/elf.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/tools/jprof/elf.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,133 @@
     1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.7 +
     1.8 +#include "leaky.h"
     1.9 +
    1.10 +#ifdef USE_ELF
    1.11 +
    1.12 +#include "leaky.h"
    1.13 +#include <stdio.h>
    1.14 +#include <malloc.h>
    1.15 +#include <libelf/libelf.h>
    1.16 +#include <unistd.h>
    1.17 +#include <fcntl.h>
    1.18 +#include <string.h>
    1.19 +
    1.20 +void leaky::readSymbols(const char *fileName)
    1.21 +{
    1.22 +    int fd = ::open(fileName, O_RDONLY);
    1.23 +    if (fd < 0) {
    1.24 +	fprintf(stderr, "%s: unable to open \"%s\"\n", applicationName,
    1.25 +		fileName);
    1.26 +	exit(-1);
    1.27 +    }
    1.28 +
    1.29 +    elf_version(EV_CURRENT);
    1.30 +    Elf *elf = elf_begin(fd, ELF_C_READ, 0);
    1.31 +    if (!elf) {
    1.32 +	fprintf(stderr, "%s: \"%s\": has no symbol table\n", applicationName,
    1.33 +		fileName);
    1.34 +	exit(-1);
    1.35 +    }
    1.36 +
    1.37 +    long alloced = 10000;
    1.38 +    Symbol* syms = (Symbol*) malloc(sizeof(Symbol) * 10000);
    1.39 +    Symbol* sp = syms;
    1.40 +    Symbol* last = syms + alloced;
    1.41 +
    1.42 +    // Get each of the relevant sections and add them to the list of
    1.43 +    // symbols.
    1.44 +    Elf32_Ehdr *ehdr = elf32_getehdr(elf);
    1.45 +    if (!ehdr) {
    1.46 +	fprintf(stderr, "%s: elf library lossage\n", applicationName);
    1.47 +	exit(-1);
    1.48 +    }
    1.49 +#if 0
    1.50 +    Elf32_Half ndx = ehdr->e_shstrndx;
    1.51 +#endif
    1.52 +
    1.53 +    Elf_Scn *scn = 0;
    1.54 +    int strtabndx = -1;
    1.55 +    for (int i = 1; (scn = elf_nextscn(elf, scn)) != 0; i++) {
    1.56 +	Elf32_Shdr *shdr = elf32_getshdr(scn);
    1.57 +#if 0
    1.58 +	char *name = elf_strptr(elf, ndx, (size_t) shdr->sh_name);
    1.59 +	printf("Section %s (%d 0x%x)\n", name ? name : "(null)",
    1.60 +	       shdr->sh_type, shdr->sh_type);
    1.61 +#endif
    1.62 +	if (shdr->sh_type == SHT_STRTAB) {
    1.63 +	    /* We assume here that string tables preceed symbol tables... */
    1.64 +	    strtabndx = i;
    1.65 +	    continue;
    1.66 +	}
    1.67 +#if 0
    1.68 +	if (shdr->sh_type == SHT_DYNAMIC) {
    1.69 +	    /* Dynamic */
    1.70 +	    Elf_Data *data = elf_getdata(scn, 0);
    1.71 +	    if (!data || !data->d_size) {
    1.72 +		printf("No data...");
    1.73 +		continue;
    1.74 +	    }
    1.75 +
    1.76 +	    Elf32_Dyn *dyn = (Elf32_Dyn*) data->d_buf;
    1.77 +	    Elf32_Dyn *lastdyn =
    1.78 +		(Elf32_Dyn*) ((char*) data->d_buf + data->d_size);
    1.79 +	    for (; dyn < lastdyn; dyn++) {
    1.80 +		printf("tag=%d value=0x%x\n", dyn->d_tag, dyn->d_un.d_val);
    1.81 +	    }
    1.82 +	} else
    1.83 +#endif
    1.84 +	if ((shdr->sh_type == SHT_SYMTAB) ||
    1.85 +	    (shdr->sh_type == SHT_DYNSYM)) {
    1.86 +	    /* Symbol table */
    1.87 +	    Elf_Data *data = elf_getdata(scn, 0);
    1.88 +	    if (!data || !data->d_size) {
    1.89 +		printf("No data...");
    1.90 +		continue;
    1.91 +	    }
    1.92 +
    1.93 +	    /* In theory we now have the symbols... */
    1.94 +	    Elf32_Sym *esym = (Elf32_Sym*) data->d_buf;
    1.95 +	    Elf32_Sym *lastsym =
    1.96 +		(Elf32_Sym*) ((char*) data->d_buf + data->d_size);
    1.97 +	    for (; esym < lastsym; esym++) {
    1.98 +#if 0
    1.99 +		char *nm = elf_strptr(elf, strtabndx, (size_t)esym->st_name);
   1.100 +		printf("%20s 0x%08x %02x %02x\n",
   1.101 +		       nm, esym->st_value, ELF32_ST_BIND(esym->st_info),
   1.102 +		       ELF32_ST_TYPE(esym->st_info));
   1.103 +#endif
   1.104 +		if ((esym->st_value == 0) ||
   1.105 +		    (ELF32_ST_BIND(esym->st_info) == STB_WEAK) ||
   1.106 +		    (ELF32_ST_BIND(esym->st_info) == STB_NUM) ||
   1.107 +		    (ELF32_ST_TYPE(esym->st_info) != STT_FUNC)) {
   1.108 +		    continue;
   1.109 +		}
   1.110 +#if 1
   1.111 +		char *nm = elf_strptr(elf, strtabndx, (size_t)esym->st_name);
   1.112 +#endif
   1.113 +		sp->name = nm ? strdup(nm) : "(no name)";
   1.114 +		sp->address = esym->st_value;
   1.115 +		sp++;
   1.116 +		if (sp >= last) {
   1.117 +		    long n = alloced + 10000;
   1.118 +		    syms = (Symbol*)
   1.119 +			realloc(syms, (size_t) (sizeof(Symbol) * n));
   1.120 +		    last = syms + n;
   1.121 +		    sp = syms + alloced;
   1.122 +		    alloced = n;
   1.123 +		}
   1.124 +	    }
   1.125 +	}
   1.126 +    }
   1.127 +
   1.128 +    int interesting = sp - syms;
   1.129 +    if (!quiet) {
   1.130 +	printf("Total of %d symbols\n", interesting);
   1.131 +    }
   1.132 +    usefulSymbols = interesting;
   1.133 +    externalSymbols = syms;
   1.134 +}
   1.135 +
   1.136 +#endif /* USE_ELF */

mercurial