build/ccw_gen: stat the file in C instead of shelling out
[hvf.git] / cp / nucleus / symtab.c
blob8440f69b12f808cfa39face0da8fa55def46a778
1 /*
2 * (C) Copyright 2007-2011 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
4 * This file is released under the GPLv2. See the COPYING file for more
5 * details.
6 */
8 #include <symtab.h>
10 Elf64_Ehdr *symtab;
12 static Elf64_Shdr *__get_section(int i)
14 return ((void*)symtab) + symtab->e_shoff + symtab->e_shentsize * i;
17 static void *get_section(int type, int *entsize, int *size)
19 Elf64_Shdr *cur;
20 int getstr = 0;
21 int i;
23 /* we want the string table associated with the symbol table */
24 if (type == SHT_STRTAB) {
25 getstr = 1;
26 type = SHT_SYMTAB;
29 for(i=0; i<symtab->e_shnum; i++) {
30 cur = __get_section(i);
32 if (cur->sh_type == type)
33 goto found;
36 return NULL;
38 found:
40 if (getstr)
41 cur = __get_section(cur->sh_link);
43 *entsize = cur->sh_entsize;
44 *size = cur->sh_size;
45 return ((void*)symtab) + cur->sh_offset;
48 void symtab_find_text_range(u64 *start, u64 *end)
50 u64 s, e;
51 Elf64_Sym *cur, *tab;
52 int entsize, size;
53 int bind, type;
55 s = -1;
56 e = 0;
58 tab = get_section(SHT_SYMTAB, &entsize, &size);
59 if (!tab)
60 return;
62 cur=tab;
64 while(((void*)cur)-((void*)tab)<size) {
65 cur = ((void*)cur) + entsize;
67 bind = cur->st_info >> 4;
68 type = cur->st_info & 0xf;
70 if ((bind != STB_LOCAL) && (bind != STB_GLOBAL))
71 continue;
73 if ((type != STT_OBJECT) && (type != STT_FUNC))
74 continue;
76 if (s > cur->st_value)
77 s = cur->st_value;
78 if (e < (cur->st_value + cur->st_size))
79 e = cur->st_value + cur->st_size;
82 *start = s;
83 *end = e;
86 char *symtab_lookup(u64 addr, char *buf, int buflen)
88 Elf64_Sym *cur, *tab;
89 char *strtab;
90 int entsize, size;
91 int strsize, dummy;
92 int bind, type;
94 tab = get_section(SHT_SYMTAB, &entsize, &size);
95 if (!tab)
96 goto fail;
98 strtab = get_section(SHT_STRTAB, &dummy, &strsize);
99 if (!strtab)
100 goto fail;
102 cur=tab;
104 while(((void*)cur)-((void*)tab)<size) {
105 cur = ((void*)cur) + entsize;
107 bind = cur->st_info >> 4;
108 type = cur->st_info & 0xf;
110 if ((bind != STB_LOCAL) && (bind != STB_GLOBAL))
111 continue;
113 if ((type != STT_OBJECT) && (type != STT_FUNC))
114 continue;
116 if (addr < cur->st_value)
117 continue;
118 if (addr >= (cur->st_value + cur->st_size))
119 continue;
121 /* ok, found the symbol */
122 if (cur->st_name > strsize)
123 goto fail;
125 snprintf(buf, buflen, "%s+%#llx",
126 strtab + cur->st_name, addr - cur->st_value);
127 return buf;
130 fail:
131 return "???";