Back to index

lightning-sunbird  0.9+nobinonly
elf.cpp
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is mozilla.org code.
00015  *
00016  * The Initial Developer of the Original Code is
00017  * Kipp E.B. Hickman.
00018  * Portions created by the Initial Developer are Copyright (C) 1999
00019  * the Initial Developer. All Rights Reserved.
00020  *
00021  * Contributor(s):
00022  *
00023  * Alternatively, the contents of this file may be used under the terms of
00024  * either the GNU General Public License Version 2 or later (the "GPL"), or
00025  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00026  * in which case the provisions of the GPL or the LGPL are applicable instead
00027  * of those above. If you wish to allow use of your version of this file only
00028  * under the terms of either the GPL or the LGPL, and not to allow others to
00029  * use your version of this file under the terms of the MPL, indicate your
00030  * decision by deleting the provisions above and replace them with the notice
00031  * and other provisions required by the GPL or the LGPL. If you do not delete
00032  * the provisions above, a recipient may use your version of this file under
00033  * the terms of any one of the MPL, the GPL or the LGPL.
00034  *
00035  * ***** END LICENSE BLOCK ***** */
00036 
00037 #include "leaky.h"
00038 
00039 #ifdef USE_ELF
00040 
00041 #include "leaky.h"
00042 #include <stdio.h>
00043 #include <malloc.h>
00044 #include <libelf/libelf.h>
00045 #include <unistd.h>
00046 #include <fcntl.h>
00047 #include <string.h>
00048 
00049 void leaky::readSymbols(const char *fileName)
00050 {
00051     int fd = ::open(fileName, O_RDONLY);
00052     if (fd < 0) {
00053        fprintf(stderr, "%s: unable to open \"%s\"\n", applicationName,
00054               fileName);
00055        exit(-1);
00056     }
00057 
00058     elf_version(EV_CURRENT);
00059     Elf *elf = elf_begin(fd, ELF_C_READ, 0);
00060     if (!elf) {
00061        fprintf(stderr, "%s: \"%s\": has no symbol table\n", applicationName,
00062               fileName);
00063        exit(-1);
00064     }
00065 
00066     long alloced = 10000;
00067     Symbol* syms = (Symbol*) malloc(sizeof(Symbol) * 10000);
00068     Symbol* sp = syms;
00069     Symbol* last = syms + alloced;
00070 
00071     // Get each of the relevant sections and add them to the list of
00072     // symbols.
00073     Elf32_Ehdr *ehdr = elf32_getehdr(elf);
00074     if (!ehdr) {
00075        fprintf(stderr, "%s: elf library lossage\n", applicationName);
00076        exit(-1);
00077     }
00078 #if 0
00079     Elf32_Half ndx = ehdr->e_shstrndx;
00080 #endif
00081 
00082     Elf_Scn *scn = 0;
00083     int strtabndx = -1;
00084     for (int i = 1; (scn = elf_nextscn(elf, scn)) != 0; i++) {
00085        Elf32_Shdr *shdr = elf32_getshdr(scn);
00086 #if 0
00087        char *name = elf_strptr(elf, ndx, (size_t) shdr->sh_name);
00088        printf("Section %s (%d 0x%x)\n", name ? name : "(null)",
00089               shdr->sh_type, shdr->sh_type);
00090 #endif
00091        if (shdr->sh_type == SHT_STRTAB) {
00092            /* We assume here that string tables preceed symbol tables... */
00093            strtabndx = i;
00094            continue;
00095        }
00096 #if 0
00097        if (shdr->sh_type == SHT_DYNAMIC) {
00098            /* Dynamic */
00099            Elf_Data *data = elf_getdata(scn, 0);
00100            if (!data || !data->d_size) {
00101               printf("No data...");
00102               continue;
00103            }
00104 
00105            Elf32_Dyn *dyn = (Elf32_Dyn*) data->d_buf;
00106            Elf32_Dyn *lastdyn =
00107               (Elf32_Dyn*) ((char*) data->d_buf + data->d_size);
00108            for (; dyn < lastdyn; dyn++) {
00109               printf("tag=%d value=0x%x\n", dyn->d_tag, dyn->d_un.d_val);
00110            }
00111        } else
00112 #endif
00113        if ((shdr->sh_type == SHT_SYMTAB) ||
00114            (shdr->sh_type == SHT_DYNSYM)) {
00115            /* Symbol table */
00116            Elf_Data *data = elf_getdata(scn, 0);
00117            if (!data || !data->d_size) {
00118               printf("No data...");
00119               continue;
00120            }
00121 
00122            /* In theory we now have the symbols... */
00123            Elf32_Sym *esym = (Elf32_Sym*) data->d_buf;
00124            Elf32_Sym *lastsym =
00125               (Elf32_Sym*) ((char*) data->d_buf + data->d_size);
00126            for (; esym < lastsym; esym++) {
00127 #if 0
00128               char *nm = elf_strptr(elf, strtabndx, (size_t)esym->st_name);
00129               printf("%20s 0x%08x %02x %02x\n",
00130                      nm, esym->st_value, ELF32_ST_BIND(esym->st_info),
00131                      ELF32_ST_TYPE(esym->st_info));
00132 #endif
00133               if ((esym->st_value == 0) ||
00134                   (ELF32_ST_BIND(esym->st_info) == STB_WEAK) ||
00135                   (ELF32_ST_BIND(esym->st_info) == STB_NUM) ||
00136                   (ELF32_ST_TYPE(esym->st_info) != STT_FUNC)) {
00137                   continue;
00138               }
00139 #if 1
00140               char *nm = elf_strptr(elf, strtabndx, (size_t)esym->st_name);
00141 #endif
00142               sp->name = nm ? strdup(nm) : "(no name)";
00143               sp->address = esym->st_value;
00144               sp++;
00145               if (sp >= last) {
00146                   long n = alloced + 10000;
00147                   syms = (Symbol*)
00148                      realloc(syms, (size_t) (sizeof(Symbol) * n));
00149                   last = syms + n;
00150                   sp = syms + alloced;
00151                   alloced = n;
00152               }
00153            }
00154        }
00155     }
00156 
00157     int interesting = sp - syms;
00158     if (!quiet) {
00159        printf("Total of %d symbols\n", interesting);
00160     }
00161     usefulSymbols = interesting;
00162     externalSymbols = syms;
00163 }
00164 
00165 #endif /* USE_ELF */