revert between 56095 -> 55830 in arch
[AROS.git] / arch / ppc-chrp / efika / kernel / debug.c
blob0dfb230b6479b7f86489eb9499ee0271aff01f70
1 /*
2 Copyright © 1995-2014, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #define PCIC0_IO 0
8 #include <asm/io.h>
9 #include <aros/libcall.h>
10 #include <stdarg.h>
11 #include <string.h>
12 #include <proto/exec.h>
13 #include <exec/lists.h>
14 #include <exec/nodes.h>
15 #include <exec/memory.h>
16 #include "kernel_intern.h"
18 void __putc(uint8_t chr)
20 if (chr == '\n')
21 __putc('\r');
23 while (!(inw(0xf0002004) & 0x400));
24 outb(chr, 0xf0002080);
25 while (!(inw(0xf0002004) & 0x400));
29 AROS_LH2(int, KrnBug,
30 AROS_LHA(const char *, format, A0),
31 AROS_LHA(va_list, args, A1),
32 struct KernelBase *, KernelBase, 12, Kernel)
34 AROS_LIBFUNC_INIT
36 #if 1
37 int result;
39 result = __vcformat(NULL, __putc, format, args);
41 return result;
42 #endif
44 AROS_LIBFUNC_EXIT
53 #define SHT_PROGBITS 1
54 #define SHT_SYMTAB 2
55 #define SHT_STRTAB 3
56 #define SHT_RELA 4
57 #define SHT_NOBITS 8
58 #define SHT_REL 9
59 #define SHT_SYMTAB_SHNDX 18
61 #define ET_REL 1
63 #define EM_386 3
64 #define EM_68K 4
65 #define EM_PPC 20
66 #define EM_ARM 40
67 #define EM_X86_64 62 /* AMD x86-64 */
69 #define R_386_NONE 0
70 #define R_386_32 1
71 #define R_386_PC32 2
73 /* AMD x86-64 relocations. */
74 #define R_X86_64_NONE 0 /* No reloc */
75 #define R_X86_64_64 1 /* Direct 64 bit */
76 #define R_X86_64_PC32 2 /* PC relative 32 bit signed */
78 #define R_68k_NONE 0
79 #define R_68K_32 1
80 #define R_68K_PC32 4
82 #define R_PPC_NONE 0
83 #define R_PPC_ADDR32 1
84 #define R_PPC_ADDR16_LO 4
85 #define R_PPC_ADDR16_HA 6
86 #define R_PPC_REL24 10
87 #define R_PPC_REL32 26
88 #define R_PPC_REL16_LO 250
89 #define R_PPC_REL16_HA 252
91 #define R_ARM_NONE 0
92 #define R_ARM_PC24 1
93 #define R_ARM_ABS32 2
95 #define STT_OBJECT 1
96 #define STT_FUNC 2
98 #define SHN_UNDEF 0
99 #define SHN_LORESERVE 0xff00
100 #define SHN_ABS 0xfff1
101 #define SHN_COMMON 0xfff2
102 #define SHN_XINDEX 0xffff
103 #define SHN_HIRESERVE 0xffff
105 #define SHF_ALLOC (1 << 1)
106 #define SHF_EXECINSTR (1 << 2)
108 #define ELF32_ST_TYPE(i) ((i) & 0x0F)
110 #define EI_VERSION 6
111 #define EV_CURRENT 1
113 #define EI_DATA 5
114 #define ELFDATA2LSB 1
115 #define ELFDATA2MSB 2
117 #define EI_CLASS 4
118 #define ELFCLASS32 1
119 #define ELFCLASS64 2 /* 64-bit objects */
121 #define ELF32_R_SYM(val) ((val) >> 8)
122 #define ELF32_R_TYPE(val) ((val) & 0xff)
123 #define ELF32_R_INFO(sym, type) (((sym) << 8) + ((type) & 0xff))
126 struct elfheader
128 UBYTE ident[16];
129 UWORD type;
130 UWORD machine;
131 ULONG version;
132 APTR entry;
133 ULONG phoff;
134 ULONG shoff;
135 ULONG flags;
136 UWORD ehsize;
137 UWORD phentsize;
138 UWORD phnum;
139 UWORD shentsize;
140 UWORD shnum;
141 UWORD shstrndx;
143 /* these are internal, and not part of the header proper. they are wider
144 * versions of shnum and shstrndx for when they don't fit in the header
145 * and we need to get them from the first section header. see
146 * load_header() for details
148 ULONG int_shnum;
149 ULONG int_shstrndx;
152 struct sheader
154 ULONG name;
155 ULONG type;
156 ULONG flags;
157 APTR addr;
158 ULONG offset;
159 ULONG size;
160 ULONG link;
161 ULONG info;
162 ULONG addralign;
163 ULONG entsize;
166 struct symbol
168 ULONG name; /* Offset of the name string in the string table */
169 ULONG value; /* Varies; eg. the offset of the symbol in its hunk */
170 ULONG size; /* How much memory does the symbol occupy */
171 UBYTE info; /* What kind of symbol is this ? (global, variable, etc) */
172 UBYTE other; /* undefined */
173 UWORD shindex; /* In which section is the symbol defined ? */
176 struct relo
178 ULONG offset; /* Address of the relocation relative to the section it refers to */
179 ULONG info; /* Type of the relocation */
180 #if defined(__mc68000__) || defined (__x86_64__) || defined (__ppc__) || defined (__powerpc__) || defined(__arm__)
181 LONG addend; /* Constant addend used to compute value */
182 #endif
185 struct hunk
187 ULONG size;
188 BPTR next;
189 char data[0];
190 } __attribute__((packed));
192 #define BPTR2HUNK(bptr) ((struct hunk *)((char *)BADDR(bptr) - offsetof(struct hunk, next)))
193 #define HUNK2BPTR(hunk) MKBADDR(&hunk->next)
195 AROS_LH3(void, KrnRegisterModule,
196 AROS_LHA(const char *, name, A0),
197 AROS_LHA(struct sheader *, sections, A1),
198 AROS_LHA(struct elfheader *,eh, A2),
199 struct KernelBase *, KernelBase, 22, Kernel)
201 AROS_LIBFUNC_INIT
203 struct ExecBase *SysBase = getSysBase();
205 if (name && sections && eh)
207 module_t *mod = AllocVec(sizeof(module_t), MEMF_PUBLIC | MEMF_CLEAR);
209 if (mod)
211 int i;
213 // D(bug("[KRN] KrnRegisterModule('%s', %08x, %d)\n", name, sections, eh->int_shnum));
215 mod->m_name = AllocVec(strlen(name)+1, MEMF_PUBLIC | MEMF_CLEAR);
216 strcpy(mod->m_name, name);
218 NEWLIST(&mod->m_symbols);
220 mod->m_lowest = 0xffffffff;
221 mod->m_highest = 0;
223 for (i=0; i < eh->int_shnum; i++)
225 /* If we have string table, copy it */
226 if (sections[i].type == SHT_STRTAB && i != eh->int_shstrndx)
228 // D(bug("[KRN] symbol table of length %d in section %d\n", sections[i].size, i));
230 if (!mod->m_str)
232 mod->m_str = AllocVec(sections[i].size, MEMF_PUBLIC | MEMF_CLEAR);
233 CopyMem(sections[i].addr, mod->m_str, sections[i].size);
237 if ((sections[i].flags & (SHF_ALLOC | SHF_EXECINSTR)) == (SHF_ALLOC | SHF_EXECINSTR))
239 if (sections[i].addr)
241 if (sections[i].addr < mod->m_lowest)
242 mod->m_lowest = sections[i].addr;
243 if (sections[i].addr + sections[i].size > mod->m_highest)
244 mod->m_highest = sections[i].addr + sections[i].size;
249 for (i=0; i < eh->int_shnum; i++)
251 if (sections[i].addr && sections[i].type == SHT_SYMTAB)
253 int j;
254 struct symbol *st = (struct symbol *)sections[i].addr;
256 for (j=0; j < (sections[i].size / sizeof(struct symbol)); j++)
258 if (st[j].shindex != SHN_XINDEX)
260 if (sections[st[j].shindex].addr && (sections[st[j].shindex].flags & (SHF_ALLOC | SHF_EXECINSTR)) == (SHF_ALLOC | SHF_EXECINSTR))
262 symbol_t *sym = AllocVec(sizeof(symbol_t), MEMF_PUBLIC | MEMF_CLEAR);
263 sym->s_name = &mod->m_str[st[j].name];
264 sym->s_lowest = sections[st[j].shindex].addr + st[j].value;
265 sym->s_highest = sym->s_lowest + st[j].size;
267 // D(bug("[KRN] Adding symbol '%s' %08x-%08x\n", sym->s_name, sym->s_lowest, sym->s_highest-1));
269 AddHead(&mod->m_symbols, sym);
274 break;
278 // D(bug("[KRN] address range %08x - %08x\n", mod->m_lowest, mod->m_highest-1));
282 AddHead(&KernelBase->kb_Modules, mod);
286 AROS_LIBFUNC_EXIT
289 AROS_LH1(void, KrnUnregisterModule,
290 AROS_LHA(void *, address, A0),
291 struct KernelBase *, KernelBase, 23, Kernel)
293 AROS_LIBFUNC_INIT
295 struct ExecBase *SysBase = getSysBase();
296 module_t *mod;
297 intptr_t addr = (intptr_t)address;
299 ForeachNode(&KernelBase->kb_Modules, mod)
301 if (mod->m_lowest <= addr && mod->m_highest > addr)
303 symbol_t *sym;
305 Remove(mod);
307 FreeVec(mod->m_str);
308 FreeVec(mod->m_name);
310 while(sym = RemHead(&mod->m_symbols))
312 FreeVec(sym);
315 FreeVec(mod);
317 break;
321 AROS_LIBFUNC_EXIT
324 extern module_t *modlist;
325 extern uint32_t modlength;
327 uint32_t findNames(intptr_t addr, char **module, char **function)
329 struct KernelBase *KernelBase = getKernelBase();
330 module_t *mod;
331 symbol_t *sym;
332 uint32_t offset = 0;
334 *module = NULL;
335 *function = NULL;
337 ForeachNode(&KernelBase->kb_Modules, mod)
339 /* if address suits the module bounds, you got it */
340 if (mod->m_lowest <= addr && mod->m_highest > addr)
342 *module = mod->m_name;
343 offset = addr - mod->m_lowest;
345 ForeachNode(&mod->m_symbols, sym)
347 if (sym->s_lowest <= addr && sym->s_highest > addr)
349 offset = addr - sym->s_lowest;
350 *function = sym->s_name;
351 break;
355 break;
359 /* module unset? then look through the kernel list */
360 if (*module == NULL)
362 int i;
363 for (i=0; i < modlength; i++)
365 if (modlist[i].m_lowest <= addr && modlist[i].m_highest > addr)
367 *module = modlist[i].m_name;
368 offset = addr - modlist[i].m_lowest;
370 ForeachNode(&modlist[i].m_symbols, sym)
372 if (sym->s_lowest <= addr && sym->s_highest > addr)
374 offset = addr - sym->s_lowest;
375 *function = sym->s_name;
376 break;
380 break;
385 return offset;