00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "src/common/shared.hpp"
00019 #include "src/common/qsort.hpp"
00020 #include "src/mboot.hpp"
00021 #include "src/arch/x86/interr.hpp"
00022 #include "src/arch/x86/except_c.hpp"
00023 #include "src/arch/x86/rtc.hpp"
00024 #include "src/memory/alloc4k.hpp"
00025 #include "src/memory/memset.hpp"
00026 #include "src/memory/align.hpp"
00027 #include "src/memory/heap.hpp"
00028 #include "src/module/elf.hpp"
00029 #include "src/module/coresyms.hpp"
00030
00031 namespace Syms {
00032
00033
00034
00035 struct Elf32_sym *core_syms=NULL;
00036 uint32 syms_count;
00037 uint32 syms_size;
00038 char *core_syms_str;
00039
00040
00041
00042 void init()
00043 {_Pf("Syms::init");
00044 Mboot::mboot_sht *syms;
00045 elf_t elf;
00046 Elf32_ehdr ehdr;
00047 uint32 i;
00048 Elf32_shdr *sect;
00049 size_t symtab_addr;
00050
00051 syms= Mboot::mboot_syms();
00052 if (syms==NULL)
00053 sysfail("failed to collect symbol info: mboot_sht not availlable");
00054
00055 create_ehdr(&ehdr, syms->num, (Elf32_shdr*) syms->addr,
00056 syms->entry_size, syms->shndx, ET_EXEC);
00057 elf.set_ehdr(&ehdr, mem_ksize);
00058
00059 for (i=0;i<syms->num;i++)
00060 { sect=elf.section(i); if (sect->sh_type == SHT_SYMTAB) break; }
00061
00062 if (sect->sh_type != SHT_SYMTAB)
00063 sysfail("failed to collect symbol info: no symtab found");
00064
00065 core_syms=(Elf32_sym*)Memory::Heap::heap0.malloc(sect->sh_size, NO_ALIGN, FAC_SYMS|FAC_SYMTAB, NULL);
00066 if (core_syms == NULL)
00067 sysfail("failed to collect symbol info: out of memory");
00068 symtab_addr=sect->sh_addr + mem_kernel_start - mem_physical;
00069 memmove(core_syms, (void*)symtab_addr, sect->sh_size);
00070 syms_size=sect->sh_entsize;
00071 syms_count=sect->sh_size / syms_size;
00072
00073 core_syms_str=(char*)elf.sect_addr(sect -> sh_link) + mem_kernel_start-mem_physical;
00074 if (core_syms_str==NULL)
00075 sysfail("failed to collect symbol info: no strtab found");
00076
00077
00078 qsort(core_syms, syms_count, syms_size, &symscompar, NULL);
00079
00080 Preturn();
00081 }
00082
00083
00084 int symscompar(const void *a, const void *b)
00085 { _Pf("Syms::symscompar");
00086 uint32 A, B;
00087 A= ((Elf32_sym*)a)-> st_value;
00088 B= ((Elf32_sym*)b)-> st_value;
00089
00090 if (A>B)
00091 preturn( 1);
00092 if (A<B)
00093 preturn( -1);
00094 preturn( 0);
00095 }
00096
00097
00098 char *sym_name(uint32 addr, int sym_type)
00099 {
00100 Elf32_sym *sym;
00101 Elf32_sym *guess=NULL;
00102 if (core_syms == NULL)
00103 return NULL;
00104 for (sym=core_syms;sym; sym=(Elf32_sym*)((uint32)sym + syms_size))
00105 {
00106 if (sym->st_value > addr)
00107 break;
00108
00109 if (ELF32_ST_TYPE(sym->st_info) == sym_type)
00110
00111 if (((uint32)ELF32_ST_BIND(sym->st_info) == STB_GLOBAL ) ||
00112 ((uint32)ELF32_ST_BIND(sym->st_info) == STB_WEAK ))
00113 guess=sym;
00114 }
00115 if (!guess)
00116 return NULL;
00117 return core_syms_str+guess->st_name;
00118 }
00119
00120
00121 char *sym_name(Elf32_sym *sym) {
00122 return core_syms_str+sym->st_name;
00123 }
00124
00125
00126
00127 };
00128
00129
00130
00131
00132
00133
00134