cynix

x86 UNIX-like OS
git clone git://git.2f30.org/cynix
Log | Files | Refs | README | LICENSE

elf.c (1121B)


      1 /*
      2  *  core/elf.c
      3  *
      4  *  Copyright (C) 2010 stateless
      5  */
      6 
      7 #include <elf.h>
      8 #include <multiboot.h>
      9 #include <common.h>
     10 #include <string.h>
     11 #include <serial.h>
     12 
     13 extern multiboot_info_t *info_boot;
     14 
     15 Elf32_Shdr *symtab = NULL, *strtab = NULL;
     16 
     17 int
     18 prepare_elf(void)
     19 {
     20 	elf_section_header_table_t *header;
     21 	Elf32_Shdr *sh, *tmp;
     22 	unsigned long i;
     23 
     24 	header = &info_boot->u.elf_sec;
     25 	sh = (Elf32_Shdr *)(header->addr + header->shndx * header->size);
     26 	for (i = 0; i < header->num; ++i) {
     27 		tmp = (Elf32_Shdr *)(header->addr + i * header->size);
     28 		if (tmp->sh_type == SHT_SYMTAB)
     29 			symtab = tmp;
     30 		else if (tmp->sh_type == SHT_STRTAB)
     31 			if (!strcmp((const char *)sh->sh_addr + tmp->sh_name, ".strtab"))
     32 				strtab = tmp;
     33 	}
     34 	return (!symtab || !strtab) ? -1 : 0;
     35 }
     36 
     37 const char *
     38 find_symbol(uint32_t addr)
     39 {
     40 	Elf32_Sym *sym;
     41 	size_t i;
     42 
     43 	if (!symtab || !strtab)
     44 		return NULL;
     45 
     46 	sym = (Elf32_Sym *)symtab->sh_addr;
     47 	for (i = 0; i < symtab->sh_size / sizeof(*sym); ++i) {
     48 		if (addr >= sym->st_value && addr < sym->st_value + sym->st_size)
     49 			return (const char *)(strtab->sh_addr + sym->st_name);
     50 		++sym;
     51 	}
     52 
     53 	return NULL;
     54 }
     55