4 * Created on: Aug 25, 2008
11 #include <aros/libcall.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
)
25 while (!(inw(0xf0002004) & 0x400));
26 outb(chr
, 0xf0002080);
27 while (!(inw(0xf0002004) & 0x400));
32 AROS_LHA(const char *, format
, A0
),
33 AROS_LHA(va_list, args
, A1
),
34 struct KernelBase
*, KernelBase
, 11, Kernel
)
41 result
= __vcformat(NULL
, __putc
, format
, args
);
55 #define SHT_PROGBITS 1
61 #define SHT_SYMTAB_SHNDX 18
69 #define EM_X86_64 62 /* AMD x86-64 */
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 */
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
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)
116 #define ELFDATA2LSB 1
117 #define ELFDATA2MSB 2
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))
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
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 ? */
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 */
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 */
199 ((n) < SHN_LORESERVE ? (n) : ((n) <= SHN_HIRESERVE ? 0 : (n) - (SHN_HIRESERVE + 1 - SHN_LORESERVE)))
201 /* convert section header array index to section number */
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
)
213 struct ExecBase
*SysBase
= getSysBase();
215 if (name
&& sections
&& eh
)
217 module_t
*mod
= AllocVec(sizeof(module_t
), MEMF_PUBLIC
| MEMF_CLEAR
);
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;
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));
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
)
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
);
288 // D(bug("[KRN] address range %08x - %08x\n", mod->m_lowest, mod->m_highest-1));
292 AddHead(&KernelBase
->kb_Modules
, mod
);
299 AROS_LH1(void, KrnUnregisterModule
,
300 AROS_LHA(void *, address
, A0
),
301 struct KernelBase
*, KernelBase
, 11, Kernel
)
305 struct ExecBase
*SysBase
= getSysBase();
307 intptr_t addr
= (intptr_t)address
;
309 ForeachNode(&KernelBase
->kb_Modules
, mod
)
311 if (mod
->m_lowest
<= addr
&& mod
->m_highest
> addr
)
320 FreeVec(mod
->m_name
);
322 while(sym
= RemHead(&mod
->m_symbols
))
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();
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
;
371 /* module unset? then look through the kernel list */
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
;