Bug 453312 - Building accessible without MOZ_XUL fails. r=surkov
[mozilla-central.git] / tools / leaky / elf.cpp
blob98fc0bf0e2fa706076472b5f6daf6c9fa030cc1c
1 /* ***** BEGIN LICENSE BLOCK *****
2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 * The contents of this file are subject to the Mozilla Public License Version
5 * 1.1 (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 * http://www.mozilla.org/MPL/
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
12 * License.
14 * The Original Code is mozilla.org code.
16 * The Initial Developer of the Original Code is
17 * Kipp E.B. Hickman.
18 * Portions created by the Initial Developer are Copyright (C) 1999
19 * the Initial Developer. All Rights Reserved.
21 * Contributor(s):
23 * Alternatively, the contents of this file may be used under the terms of
24 * either the GNU General Public License Version 2 or later (the "GPL"), or
25 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
26 * in which case the provisions of the GPL or the LGPL are applicable instead
27 * of those above. If you wish to allow use of your version of this file only
28 * under the terms of either the GPL or the LGPL, and not to allow others to
29 * use your version of this file under the terms of the MPL, indicate your
30 * decision by deleting the provisions above and replace them with the notice
31 * and other provisions required by the GPL or the LGPL. If you do not delete
32 * the provisions above, a recipient may use your version of this file under
33 * the terms of any one of the MPL, the GPL or the LGPL.
35 * ***** END LICENSE BLOCK ***** */
37 #include "leaky.h"
39 #ifdef USE_ELF
41 #include "leaky.h"
42 #include <stdio.h>
43 #include <malloc.h>
44 #include <libelf/libelf.h>
45 #include <unistd.h>
46 #include <fcntl.h>
47 #include <string.h>
49 void leaky::readSymbols(const char *fileName)
51 int fd = ::open(fileName, O_RDONLY);
52 if (fd < 0) {
53 fprintf(stderr, "%s: unable to open \"%s\"\n", applicationName,
54 fileName);
55 exit(-1);
58 elf_version(EV_CURRENT);
59 Elf *elf = elf_begin(fd, ELF_C_READ, 0);
60 if (!elf) {
61 fprintf(stderr, "%s: \"%s\": has no symbol table\n", applicationName,
62 fileName);
63 exit(-1);
66 long alloced = 10000;
67 Symbol* syms = (Symbol*) malloc(sizeof(Symbol) * 10000);
68 Symbol* sp = syms;
69 Symbol* last = syms + alloced;
71 // Get each of the relevant sections and add them to the list of
72 // symbols.
73 Elf32_Ehdr *ehdr = elf32_getehdr(elf);
74 if (!ehdr) {
75 fprintf(stderr, "%s: elf library lossage\n", applicationName);
76 exit(-1);
78 #if 0
79 Elf32_Half ndx = ehdr->e_shstrndx;
80 #endif
82 Elf_Scn *scn = 0;
83 int strtabndx = -1;
84 for (int i = 1; (scn = elf_nextscn(elf, scn)) != 0; i++) {
85 Elf32_Shdr *shdr = elf32_getshdr(scn);
86 #if 0
87 char *name = elf_strptr(elf, ndx, (size_t) shdr->sh_name);
88 printf("Section %s (%d 0x%x)\n", name ? name : "(null)",
89 shdr->sh_type, shdr->sh_type);
90 #endif
91 if (shdr->sh_type == SHT_STRTAB) {
92 /* We assume here that string tables preceed symbol tables... */
93 strtabndx = i;
94 continue;
96 #if 0
97 if (shdr->sh_type == SHT_DYNAMIC) {
98 /* Dynamic */
99 Elf_Data *data = elf_getdata(scn, 0);
100 if (!data || !data->d_size) {
101 printf("No data...");
102 continue;
105 Elf32_Dyn *dyn = (Elf32_Dyn*) data->d_buf;
106 Elf32_Dyn *lastdyn =
107 (Elf32_Dyn*) ((char*) data->d_buf + data->d_size);
108 for (; dyn < lastdyn; dyn++) {
109 printf("tag=%d value=0x%x\n", dyn->d_tag, dyn->d_un.d_val);
111 } else
112 #endif
113 if ((shdr->sh_type == SHT_SYMTAB) ||
114 (shdr->sh_type == SHT_DYNSYM)) {
115 /* Symbol table */
116 Elf_Data *data = elf_getdata(scn, 0);
117 if (!data || !data->d_size) {
118 printf("No data...");
119 continue;
122 /* In theory we now have the symbols... */
123 Elf32_Sym *esym = (Elf32_Sym*) data->d_buf;
124 Elf32_Sym *lastsym =
125 (Elf32_Sym*) ((char*) data->d_buf + data->d_size);
126 for (; esym < lastsym; esym++) {
127 #if 0
128 char *nm = elf_strptr(elf, strtabndx, (size_t)esym->st_name);
129 printf("%20s 0x%08x %02x %02x\n",
130 nm, esym->st_value, ELF32_ST_BIND(esym->st_info),
131 ELF32_ST_TYPE(esym->st_info));
132 #endif
133 if ((esym->st_value == 0) ||
134 (ELF32_ST_BIND(esym->st_info) == STB_WEAK) ||
135 (ELF32_ST_BIND(esym->st_info) == STB_NUM) ||
136 (ELF32_ST_TYPE(esym->st_info) != STT_FUNC)) {
137 continue;
139 #if 1
140 char *nm = elf_strptr(elf, strtabndx, (size_t)esym->st_name);
141 #endif
142 sp->name = nm ? strdup(nm) : "(no name)";
143 sp->address = esym->st_value;
144 sp++;
145 if (sp >= last) {
146 long n = alloced + 10000;
147 syms = (Symbol*)
148 realloc(syms, (size_t) (sizeof(Symbol) * n));
149 last = syms + n;
150 sp = syms + alloced;
151 alloced = n;
157 int interesting = sp - syms;
158 if (!quiet) {
159 printf("Total of %d symbols\n", interesting);
161 usefulSymbols = interesting;
162 externalSymbols = syms;
165 #endif /* USE_ELF */