2 Copyright © 1995-2014, The AROS Development Team. All rights reserved.
9 #include <aros/libcall.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
)
23 while (!(inw(0xf0002004) & 0x400));
24 outb(chr
, 0xf0002080);
25 while (!(inw(0xf0002004) & 0x400));
30 AROS_LHA(const char *, format
, A0
),
31 AROS_LHA(va_list, args
, A1
),
32 struct KernelBase
*, KernelBase
, 12, Kernel
)
39 result
= __vcformat(NULL
, __putc
, format
, args
);
53 #define SHT_PROGBITS 1
59 #define SHT_SYMTAB_SHNDX 18
67 #define EM_X86_64 62 /* AMD x86-64 */
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 */
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
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)
114 #define ELFDATA2LSB 1
115 #define ELFDATA2MSB 2
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))
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
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 ? */
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 */
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
)
203 struct ExecBase
*SysBase
= getSysBase();
205 if (name
&& sections
&& eh
)
207 module_t
*mod
= AllocVec(sizeof(module_t
), MEMF_PUBLIC
| MEMF_CLEAR
);
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;
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));
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
)
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
);
278 // D(bug("[KRN] address range %08x - %08x\n", mod->m_lowest, mod->m_highest-1));
282 AddHead(&KernelBase
->kb_Modules
, mod
);
289 AROS_LH1(void, KrnUnregisterModule
,
290 AROS_LHA(void *, address
, A0
),
291 struct KernelBase
*, KernelBase
, 23, Kernel
)
295 struct ExecBase
*SysBase
= getSysBase();
297 intptr_t addr
= (intptr_t)address
;
299 ForeachNode(&KernelBase
->kb_Modules
, mod
)
301 if (mod
->m_lowest
<= addr
&& mod
->m_highest
> addr
)
308 FreeVec(mod
->m_name
);
310 while(sym
= RemHead(&mod
->m_symbols
))
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();
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
;
359 /* module unset? then look through the kernel list */
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
;