Fixed a few warnings.
[tangerine.git] / arch / ppc-chrp / efika / kernel / debug.c
blob3ff1e05624d74192b46fb7053cda8e2cb245e522
1 /*
2 * debug.c
4 * Created on: Aug 25, 2008
5 * Author: misc
6 */
8 #define PCIC0_IO 0
10 #include <asm/io.h>
11 #include <aros/libcall.h>
12 #include <stdarg.h>
13 #include <string.h>
14 #include <proto/exec.h>
15 #include <exec/lists.h>
16 #include <exec/nodes.h>
17 #include <exec/memory.h>
18 #include "kernel_intern.h"
20 void __putc(uint8_t chr)
22 if (chr == '\n')
23 __putc('\r');
25 while (!(inw(0xf0002004) & 0x400));
26 outb(chr, 0xf0002080);
27 while (!(inw(0xf0002004) & 0x400));
31 AROS_LH2(int, KrnBug,
32 AROS_LHA(const char *, format, A0),
33 AROS_LHA(va_list, args, A1),
34 struct KernelBase *, KernelBase, 11, Kernel)
36 AROS_LIBFUNC_INIT
38 #if 1
39 int result;
41 result = __vcformat(NULL, __putc, format, args);
43 return result;
44 #endif
46 AROS_LIBFUNC_EXIT
55 #define SHT_PROGBITS 1
56 #define SHT_SYMTAB 2
57 #define SHT_STRTAB 3
58 #define SHT_RELA 4
59 #define SHT_NOBITS 8
60 #define SHT_REL 9
61 #define SHT_SYMTAB_SHNDX 18
63 #define ET_REL 1
65 #define EM_386 3
66 #define EM_68K 4
67 #define EM_PPC 20
68 #define EM_ARM 40
69 #define EM_X86_64 62 /* AMD x86-64 */
71 #define R_386_NONE 0
72 #define R_386_32 1
73 #define R_386_PC32 2
75 /* AMD x86-64 relocations. */
76 #define R_X86_64_NONE 0 /* No reloc */
77 #define R_X86_64_64 1 /* Direct 64 bit */
78 #define R_X86_64_PC32 2 /* PC relative 32 bit signed */
80 #define R_68k_NONE 0
81 #define R_68K_32 1
82 #define R_68K_PC32 4
84 #define R_PPC_NONE 0
85 #define R_PPC_ADDR32 1
86 #define R_PPC_ADDR16_LO 4
87 #define R_PPC_ADDR16_HA 6
88 #define R_PPC_REL24 10
89 #define R_PPC_REL32 26
90 #define R_PPC_REL16_LO 250
91 #define R_PPC_REL16_HA 252
93 #define R_ARM_NONE 0
94 #define R_ARM_PC24 1
95 #define R_ARM_ABS32 2
97 #define STT_OBJECT 1
98 #define STT_FUNC 2
100 #define SHN_UNDEF 0
101 #define SHN_LORESERVE 0xff00
102 #define SHN_ABS 0xfff1
103 #define SHN_COMMON 0xfff2
104 #define SHN_XINDEX 0xffff
105 #define SHN_HIRESERVE 0xffff
107 #define SHF_ALLOC (1 << 1)
108 #define SHF_EXECINSTR (1 << 2)
110 #define ELF32_ST_TYPE(i) ((i) & 0x0F)
112 #define EI_VERSION 6
113 #define EV_CURRENT 1
115 #define EI_DATA 5
116 #define ELFDATA2LSB 1
117 #define ELFDATA2MSB 2
119 #define EI_CLASS 4
120 #define ELFCLASS32 1
121 #define ELFCLASS64 2 /* 64-bit objects */
123 #define ELF32_R_SYM(val) ((val) >> 8)
124 #define ELF32_R_TYPE(val) ((val) & 0xff)
125 #define ELF32_R_INFO(sym, type) (((sym) << 8) + ((type) & 0xff))
128 struct elfheader
130 UBYTE ident[16];
131 UWORD type;
132 UWORD machine;
133 ULONG version;
134 APTR entry;
135 ULONG phoff;
136 ULONG shoff;
137 ULONG flags;
138 UWORD ehsize;
139 UWORD phentsize;
140 UWORD phnum;
141 UWORD shentsize;
142 UWORD shnum;
143 UWORD shstrndx;
145 /* these are internal, and not part of the header proper. they are wider
146 * versions of shnum and shstrndx for when they don't fit in the header
147 * and we need to get them from the first section header. see
148 * load_header() for details
150 ULONG int_shnum;
151 ULONG int_shstrndx;
154 struct sheader
156 ULONG name;
157 ULONG type;
158 ULONG flags;
159 APTR addr;
160 ULONG offset;
161 ULONG size;
162 ULONG link;
163 ULONG info;
164 ULONG addralign;
165 ULONG entsize;
168 struct symbol
170 ULONG name; /* Offset of the name string in the string table */
171 ULONG value; /* Varies; eg. the offset of the symbol in its hunk */
172 ULONG size; /* How much memory does the symbol occupy */
173 UBYTE info; /* What kind of symbol is this ? (global, variable, etc) */
174 UBYTE other; /* undefined */
175 UWORD shindex; /* In which section is the symbol defined ? */
178 struct relo
180 ULONG offset; /* Address of the relocation relative to the section it refers to */
181 ULONG info; /* Type of the relocation */
182 #if defined(__mc68000__) || defined (__x86_64__) || defined (__ppc__) || defined (__powerpc__) || defined(__arm__)
183 LONG addend; /* Constant addend used to compute value */
184 #endif
187 struct hunk
189 ULONG size;
190 BPTR next;
191 char data[0];
192 } __attribute__((packed));
194 #define BPTR2HUNK(bptr) ((struct hunk *)((char *)BADDR(bptr) - offsetof(struct hunk, next)))
195 #define HUNK2BPTR(hunk) MKBADDR(&hunk->next)
197 /* convert section header number to array index */
198 #define SHINDEX(n) \
199 ((n) < SHN_LORESERVE ? (n) : ((n) <= SHN_HIRESERVE ? 0 : (n) - (SHN_HIRESERVE + 1 - SHN_LORESERVE)))
201 /* convert section header array index to section number */
202 #define SHNUM(i) \
203 ((i) < SHN_LORESERVE ? (i) : (i) + (SHN_HIRESERVE + 1 - SHN_LORESERVE))
205 AROS_LH3(void, KrnRegisterModule,
206 AROS_LHA(const char *, name, A0),
207 AROS_LHA(struct sheader *, sections, A1),
208 AROS_LHA(struct elfheader *,eh, A2),
209 struct KernelBase *, KernelBase, 11, Kernel)
211 AROS_LIBFUNC_INIT
213 struct ExecBase *SysBase = getSysBase();
215 if (name && sections && eh)
217 module_t *mod = AllocVec(sizeof(module_t), MEMF_PUBLIC | MEMF_CLEAR);
219 if (mod)
221 int i;
223 // D(bug("[KRN] KrnRegisterModule('%s', %08x, %d)\n", name, sections, eh->int_shnum));
225 mod->m_name = AllocVec(strlen(name)+1, MEMF_PUBLIC | MEMF_CLEAR);
226 strcpy(mod->m_name, name);
228 NEWLIST(&mod->m_symbols);
230 mod->m_lowest = 0xffffffff;
231 mod->m_highest = 0;
233 for (i=0; i < eh->int_shnum; i++)
235 /* If we have string table, copy it */
236 if (sections[i].type == SHT_STRTAB && i != SHINDEX(eh->int_shstrndx))
238 // D(bug("[KRN] symbol table of length %d in section %d\n", sections[i].size, i));
240 if (!mod->m_str)
242 mod->m_str = AllocVec(sections[i].size, MEMF_PUBLIC | MEMF_CLEAR);
243 CopyMem(sections[i].addr, mod->m_str, sections[i].size);
247 if ((sections[i].flags & (SHF_ALLOC | SHF_EXECINSTR)) == (SHF_ALLOC | SHF_EXECINSTR))
249 if (sections[i].addr)
251 if (sections[i].addr < mod->m_lowest)
252 mod->m_lowest = sections[i].addr;
253 if (sections[i].addr + sections[i].size > mod->m_highest)
254 mod->m_highest = sections[i].addr + sections[i].size;
259 for (i=0; i < eh->int_shnum; i++)
261 if (sections[i].addr && sections[i].type == SHT_SYMTAB)
263 int j;
264 struct symbol *st = (struct symbol *)sections[i].addr;
266 for (j=0; j < (sections[i].size / sizeof(struct symbol)); j++)
268 if (st[j].shindex != SHN_XINDEX)
270 if (sections[st[j].shindex].addr && (sections[st[j].shindex].flags & (SHF_ALLOC | SHF_EXECINSTR)) == (SHF_ALLOC | SHF_EXECINSTR))
272 symbol_t *sym = AllocVec(sizeof(symbol_t), MEMF_PUBLIC | MEMF_CLEAR);
273 sym->s_name = &mod->m_str[st[j].name];
274 sym->s_lowest = sections[st[j].shindex].addr + st[j].value;
275 sym->s_highest = sym->s_lowest + st[j].size;
277 // D(bug("[KRN] Adding symbol '%s' %08x-%08x\n", sym->s_name, sym->s_lowest, sym->s_highest-1));
279 AddHead(&mod->m_symbols, sym);
284 break;
288 // D(bug("[KRN] address range %08x - %08x\n", mod->m_lowest, mod->m_highest-1));
292 AddHead(&KernelBase->kb_Modules, mod);
296 AROS_LIBFUNC_EXIT
299 AROS_LH1(void, KrnUnregisterModule,
300 AROS_LHA(void *, address, A0),
301 struct KernelBase *, KernelBase, 11, Kernel)
303 AROS_LIBFUNC_INIT
305 struct ExecBase *SysBase = getSysBase();
306 module_t *mod;
307 intptr_t addr = (intptr_t)address;
309 ForeachNode(&KernelBase->kb_Modules, mod)
311 if (mod->m_lowest <= addr && mod->m_highest > addr)
313 symbol_t *sym;
315 Remove(mod);
317 if (mod->m_str)
318 FreeVec(mod->m_str);
319 if (mod->m_name)
320 FreeVec(mod->m_name);
322 while(sym = RemHead(&mod->m_symbols))
324 FreeVec(sym);
327 FreeVec(mod);
329 break;
333 AROS_LIBFUNC_EXIT
336 extern module_t *modlist;
337 extern uint32_t modlength;
339 uint32_t findNames(intptr_t addr, char **module, char **function)
341 struct KernelBase *KernelBase = getKernelBase();
342 module_t *mod;
343 symbol_t *sym;
344 uint32_t offset = 0;
346 *module = NULL;
347 *function = NULL;
349 ForeachNode(&KernelBase->kb_Modules, mod)
351 /* if address suits the module bounds, you got it */
352 if (mod->m_lowest <= addr && mod->m_highest > addr)
354 *module = mod->m_name;
355 offset = addr - mod->m_lowest;
357 ForeachNode(&mod->m_symbols, sym)
359 if (sym->s_lowest <= addr && sym->s_highest > addr)
361 offset = addr - sym->s_lowest;
362 *function = sym->s_name;
363 break;
367 break;
371 /* module unset? then look through the kernel list */
372 if (*module == NULL)
374 int i;
375 for (i=0; i < modlength; i++)
377 if (modlist[i].m_lowest <= addr && modlist[i].m_highest > addr)
379 *module = modlist[i].m_name;
380 offset = addr - modlist[i].m_lowest;
382 ForeachNode(&modlist[i].m_symbols, sym)
384 if (sym->s_lowest <= addr && sym->s_highest > addr)
386 offset = addr - sym->s_lowest;
387 *function = sym->s_name;
388 break;
392 break;
397 return offset;