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/. */
12 # include <libelf/libelf.h>
17 void leaky::readSymbols(const char* fileName
) {
18 int fd
= ::open(fileName
, O_RDONLY
);
20 fprintf(stderr
, "%s: unable to open \"%s\"\n", applicationName
, fileName
);
24 elf_version(EV_CURRENT
);
25 Elf
* elf
= elf_begin(fd
, ELF_C_READ
, 0);
27 fprintf(stderr
, "%s: \"%s\": has no symbol table\n", applicationName
,
33 Symbol
* syms
= (Symbol
*)malloc(sizeof(Symbol
) * 10000);
35 Symbol
* last
= syms
+ alloced
;
37 // Get each of the relevant sections and add them to the list of
39 Elf32_Ehdr
* ehdr
= elf32_getehdr(elf
);
41 fprintf(stderr
, "%s: elf library lossage\n", applicationName
);
45 Elf32_Half ndx
= ehdr
->e_shstrndx
;
50 for (int i
= 1; (scn
= elf_nextscn(elf
, scn
)) != 0; i
++) {
51 Elf32_Shdr
* shdr
= elf32_getshdr(scn
);
53 char *name
= elf_strptr(elf
, ndx
, (size_t) shdr
->sh_name
);
54 printf("Section %s (%d 0x%x)\n", name
? name
: "(null)",
55 shdr
->sh_type
, shdr
->sh_type
);
57 if (shdr
->sh_type
== SHT_STRTAB
) {
58 /* We assume here that string tables preceed symbol tables... */
63 if (shdr
->sh_type
== SHT_DYNAMIC
) {
65 Elf_Data
*data
= elf_getdata(scn
, 0);
66 if (!data
|| !data
->d_size
) {
71 Elf32_Dyn
*dyn
= (Elf32_Dyn
*) data
->d_buf
;
73 (Elf32_Dyn
*) ((char*) data
->d_buf
+ data
->d_size
);
74 for (; dyn
< lastdyn
; dyn
++) {
75 printf("tag=%d value=0x%x\n", dyn
->d_tag
, dyn
->d_un
.d_val
);
79 if ((shdr
->sh_type
== SHT_SYMTAB
) || (shdr
->sh_type
== SHT_DYNSYM
)) {
81 Elf_Data
* data
= elf_getdata(scn
, 0);
82 if (!data
|| !data
->d_size
) {
87 /* In theory we now have the symbols... */
88 Elf32_Sym
* esym
= (Elf32_Sym
*)data
->d_buf
;
89 Elf32_Sym
* lastsym
= (Elf32_Sym
*)((char*)data
->d_buf
+ data
->d_size
);
90 for (; esym
< lastsym
; esym
++) {
92 char *nm
= elf_strptr(elf
, strtabndx
, (size_t)esym
->st_name
);
93 printf("%20s 0x%08x %02x %02x\n",
94 nm
, esym
->st_value
, ELF32_ST_BIND(esym
->st_info
),
95 ELF32_ST_TYPE(esym
->st_info
));
97 if ((esym
->st_value
== 0) ||
98 (ELF32_ST_BIND(esym
->st_info
) == STB_WEAK
) ||
99 (ELF32_ST_BIND(esym
->st_info
) == STB_NUM
) ||
100 (ELF32_ST_TYPE(esym
->st_info
) != STT_FUNC
)) {
104 char* nm
= elf_strptr(elf
, strtabndx
, (size_t)esym
->st_name
);
106 sp
->name
= nm
? strdup(nm
) : "(no name)";
107 sp
->address
= esym
->st_value
;
110 long n
= alloced
+ 10000;
111 syms
= (Symbol
*)realloc(syms
, (size_t)(sizeof(Symbol
) * n
));
120 int interesting
= sp
- syms
;
122 printf("Total of %d symbols\n", interesting
);
124 usefulSymbols
= interesting
;
125 externalSymbols
= syms
;