OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Mar 28, 2024 3:54 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 8 posts ] 
Author Message
 Post subject: Module loading
PostPosted: Thu Nov 03, 2022 7:27 am 
Offline
Member
Member

Joined: Thu Jul 14, 2022 9:45 am
Posts: 91
Hello! I have problem with the kernel module loading.
So after the module loaded, i got #UD and the problem is: the kernel symbols not resolving(address of functions didn't setted)
What i am doing wrong?
There are function for module symbols resolving:
Code:
bool module_resolve_symbols(module_t *mod,Elf32_Ehdr *e) {
   unsigned i;
   Elf32_Shdr *s;
   Elf32_Sym *sym;
   const char *str;
   Elf32_Word size,entsize;
   for (i = 0, s = (Elf32_Shdr *)((char *)e + e->e_shoff); i < e->e_shnum;
      i++,s = (Elf32_Shdr *)((char *)s + e->e_shentsize)) {
      if (s->sh_type == SHT_SYMTAB) break;
   }
   if (i == e->e_shnum) {
      printf("%s: failed to find symbol table in module!\n");
      return false;
   }
   mod->symtab = (Elf32_Sym *)((char *)e + s->sh_offset);
   sym = mod->symtab;
   size = s->sh_size;
   entsize = s->sh_entsize;
   s = (Elf32_Shdr *)((char *)e + e->e_shoff + e->e_shentsize * s->sh_link);
   str = (char *)e+ s->sh_offset;
   for (i = 0; i < size/entsize; i++,sym = (Elf32_Sym *)((char *)sym + entsize)) {
      uint8_t type = ELF32_ST_TYPE(sym->st_info);
      uint8_t bind = ELF32_ST_BIND(sym->st_info);
      const char *name = str + sym->st_name;
      switch (type) {
         case STT_NOTYPE:
         case STT_OBJECT:
         if (sym->st_name != 0 && sym->st_shndx == 0) {
            sym->st_value = (Elf32_Addr)symbols_findValue(name);
            printf("Symbol %s founded in kernel: %x\n",name,sym->st_value);
            if (!sym->st_value) {
               printf("Cannot find symbol %s in kernel, abort\n",name);
               return false;
            }
         } else {
            sym->st_value += (Elf32_Addr) module_get_section_addr(mod,sym->st_shndx);
            if (bind != STB_LOCAL) {
               printf("TODO: add this to global symbol table: %s\n",name);
            }
         } break;
         case STT_FUNC:
         sym->st_value += (Elf32_Addr) module_get_section_addr(mod,sym->st_shndx);
         if (bind != STB_LOCAL) {
            printf("TODO: This function %s also need to be added to global symbols table\n",name);
         }
         if (strcmp(name,"module_main")) {
            printf("Module init found\n");
            mod->init = (void (*)(module_t *))sym->st_value;
         }
         break;
         case STT_SECTION:
         sym->st_value += (Elf32_Addr) module_get_section_addr(mod,sym->st_shndx);
         break;
         case STT_FILE:
         sym->st_value = 0;
         break;
         default:
         printf("Unknown symbol type: %d,%s\n",type,name);
         return false;
         break;
      }
   }
   return true;
}


Top
 Profile  
 
 Post subject: Re: Module loading
PostPosted: Thu Nov 03, 2022 9:45 am 
Offline
Member
Member

Joined: Wed Aug 30, 2017 8:24 am
Posts: 1593
OK, yes, that does resolve the symbols. But do you at any point process the relocations? After assigning values to all the symbols, you must look through all the section headers again, looking for all sections of type SHT_REL and SHT_RELA. Each of those says in the section header's link field what symbol table they are referring to (the section index of that), and in the info field, what section they are relocations for. The offsets in the relocation structures are relative to the start of the referred-to section. And then you only have to actually process the relocations by type.

_________________
Carpe diem!


Top
 Profile  
 
 Post subject: Re: Module loading
PostPosted: Thu Nov 03, 2022 10:32 am 
Offline
Member
Member

Joined: Thu Jul 14, 2022 9:45 am
Posts: 91
nullplan wrote:
But do you at any point process the relocations?

Yeah i do it here:
Code:
bool arch_relocSymbols(module_t *mod,void *ehdr) {
   Elf32_Ehdr *e = (Elf32_Ehdr *)ehdr;
   Elf32_Shdr *s;
   Elf32_Word entsize;
   unsigned i;
   // Find symbol table
   for (i = 0,s = (Elf32_Shdr *)((char *) e + e->e_shoff); i < e->e_shnum;
      i++,s = (Elf32_Shdr *)((char *) s + e->e_shentsize)) {
      if (s->sh_type == SHT_SYMTAB) {
         break;
      }
   }
   if (i == e->e_shnum) {
      printf("relloc: no symbol table to relocate!\n");
      return false;
   }
   entsize = s->sh_entsize;
   for (i = 0,s = (Elf32_Shdr *)((char *)e + e->e_shoff); i < e->e_shnum;
      i++,s = (Elf32_Shdr *)((char *)s + e->e_shentsize)) {
         if (s->sh_type == SHT_REL) {
            printf("Relocation segment\n");
            module_segment_t *seg;
            for (seg = mod->seg; seg; seg = seg->next) {
               if (seg->section == s->sh_info) break;
            }
            if (seg) {
               Elf32_Rel *rel,*max;
               for (rel = (Elf32_Rel *)((char *) e + s->sh_offset),
                  max = rel + s->sh_size / s->sh_entsize;
                  rel < max;
                  rel++) {
                  Elf32_Word *addr;
                  Elf32_Sym *sym;
                  if (seg->size < rel->r_offset) {
                     printf("Relloc offset is out of segment\n");
                     return false;
                  }
                  addr = (Elf32_Word *)((char *)seg->addr + rel->r_offset);
                  sym = (Elf32_Sym *)((char *)mod->symtab + entsize * ELF32_R_SYM(rel->r_info));
                  switch (ELF32_R_TYPE(rel->r_info)) {
                     case R_386_32:
                        *addr += sym->st_value;
                        break;
                     case R_386_PC32:
                        *addr += (sym->st_value - (Elf32_Word)seg->addr - rel->r_offset);
                        break;
                  }
               }
            }
         }
   }
   return true;
}

Does i do it wrong?


Top
 Profile  
 
 Post subject: Re: Module loading
PostPosted: Thu Nov 03, 2022 11:44 am 
Offline
Member
Member

Joined: Wed Aug 30, 2017 8:24 am
Posts: 1593
WinExperements wrote:
Does i do it wrong?
Well, you are looking up the symbol table in a weird way. As I said, the section index of the symbol table you need is given in the link field of the relocation table's section header. There might be multiple symbol tables. Also, you should give an error for unknown relocation types so you know if the compiler generated something you didn't handle. Other than that, looks good so far.

_________________
Carpe diem!


Top
 Profile  
 
 Post subject: Re: Module loading
PostPosted: Thu Nov 03, 2022 12:02 pm 
Offline
Member
Member

Joined: Thu Jul 14, 2022 9:45 am
Posts: 91
So why the address of kernel symbol didn't setted after loading the module, just i got #UD because the address invalid?


Top
 Profile  
 
 Post subject: Re: Module loading
PostPosted: Thu Nov 03, 2022 12:29 pm 
Offline
Member
Member
User avatar

Joined: Sat Mar 31, 2012 3:07 am
Posts: 4591
Location: Chichester, UK
It might help to single-step through the relevant code in a debugger. Once you see what’s actually happening you have a better chance of determining the cause.


Top
 Profile  
 
 Post subject: Re: Module loading
PostPosted: Sat Nov 05, 2022 3:08 am 
Offline
Member
Member

Joined: Thu Jul 14, 2022 9:45 am
Posts: 91
One thing that i found while i debug this: address of kernel symbols when loading it, setted correctly but the address didn't changed in the code(i disassemble the module entry point with GDB). Why?


Top
 Profile  
 
 Post subject: Re: Module loading
PostPosted: Sat Nov 05, 2022 10:51 am 
Offline
Member
Member

Joined: Fri Feb 11, 2022 4:55 am
Posts: 435
Location: behind the keyboard
That means that the address of kernel symbols isn't set correctly.


For my drivers, I create a buffer which contains the kernel mode address space (address space buffer), you should change the values in the address space buffer not in the file buffer, when you finish you just free the file buffer from memory.

The size of the virtual buffer is equal to the highest (relative) virtual address, then you copy the content of each section in that buffer using AddressSpaceBuffer + section.virtualaddress

for e.g. if RelocSection.virtualaddress = 0x5000, you should set the values in ProgramAddressSpace + 0x5000.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 8 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: Bing [Bot] and 65 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group