[BACK]Return to elf.c CVS log [TXT][DIR] Up to [local] / prex-old / boot / common

Diff for /prex-old/boot/common/elf.c between version 1.1.1.1 and 1.1.1.1.2.1

version 1.1.1.1, 2008/06/03 10:38:40 version 1.1.1.1.2.1, 2008/08/13 17:12:20
Line 36 
Line 36 
 #include <sys/elf.h>  #include <sys/elf.h>
 #include <platform.h>  #include <platform.h>
   
   #ifdef DEBUG_ELF
   #define DPRINTF(a) printf a
   #else
   #define DPRINTF(a) do {} while (0)
   #endif
   
 extern int nr_img;              /* number of images */  extern int nr_img;              /* number of images */
   
 #define SHF_VALID       (SHF_ALLOC | SHF_EXECINSTR | SHF_ALLOC | SHF_WRITE)  #define SHF_VALID       (SHF_ALLOC | SHF_EXECINSTR | SHF_ALLOC | SHF_WRITE)
Line 47 
Line 53 
 {  {
         Elf32_Ehdr *ehdr;          Elf32_Ehdr *ehdr;
         Elf32_Phdr *phdr;          Elf32_Phdr *phdr;
         u_long phys_base;          paddr_t phys_base;
         int i;          int i;
   
         phys_base = load_base;          phys_base = load_base;
         ehdr = (Elf32_Ehdr *)img;          ehdr = (Elf32_Ehdr *)img;
         phdr = (Elf32_Phdr *)((u_long)ehdr + ehdr->e_phoff);          phdr = (Elf32_Phdr *)((paddr_t)ehdr + ehdr->e_phoff);
         m->phys = load_base;          m->phys = load_base;
         phys_base = load_base;          phys_base = load_base;
         elf_print("phys addr=%x\n", phys_base);          DPRINTF(("phys addr=%x\n", phys_base));
   
         for (i = 0; i < (int)ehdr->e_phnum; i++, phdr++) {          for (i = 0; i < (int)ehdr->e_phnum; i++, phdr++) {
                 if (phdr->p_type != PT_LOAD)                  if (phdr->p_type != PT_LOAD)
                         continue;                          continue;
   
                 elf_print("p_flags=%x\n", (int)phdr->p_flags);                  DPRINTF(("p_flags=%x\n", (int)phdr->p_flags));
                 elf_print("p_align=%x\n", (int)phdr->p_align);                  DPRINTF(("p_align=%x\n", (int)phdr->p_align));
                 elf_print("p_paddr=%x\n", (int)phdr->p_paddr);                  DPRINTF(("p_paddr=%x\n", (int)phdr->p_paddr));
   
                 if (i >= 2) {                  if (i >= 2) {
                         elf_print("skipping extra phdr\n");                          DPRINTF(("skipping extra phdr\n"));
                         continue;                          continue;
                 }                  }
                 if (phdr->p_flags & PF_X) {                  if (phdr->p_flags & PF_X) {
Line 84 
Line 90 
                 if (phdr->p_filesz > 0) {                  if (phdr->p_filesz > 0) {
                         memcpy((char *)load_base, img + phdr->p_offset,                          memcpy((char *)load_base, img + phdr->p_offset,
                                (size_t)phdr->p_filesz);                                 (size_t)phdr->p_filesz);
                         elf_print("load: offset=%x size=%x\n",                          DPRINTF(("load: offset=%x size=%x\n",
                                 load_base, (int)phdr->p_filesz);                                   load_base, (int)phdr->p_filesz));
                 }                  }
                 if (!(phdr->p_flags & PF_X)) {                  if (!(phdr->p_flags & PF_X)) {
                         if (m->bsssz > 0) {                          if (m->bsssz > 0) {
Line 103 
Line 109 
         load_base = PAGE_ALIGN(load_base);          load_base = PAGE_ALIGN(load_base);
         m->size = (size_t)(load_base - m->phys);          m->size = (size_t)(load_base - m->phys);
         m->entry = ehdr->e_entry;          m->entry = ehdr->e_entry;
         elf_print("module size=%x entry=%x\n", m->size, m->entry);          DPRINTF(("module size=%x entry=%x\n", m->size, m->entry));
         return 0;          return 0;
 }  }
   
Line 123 
Line 129 
                         if (relocate_rela(rela, sym_val, target_sect) != 0)                          if (relocate_rela(rela, sym_val, target_sect) != 0)
                                 return -1;                                  return -1;
                 } else if (ELF32_ST_BIND(sym->st_info) != STB_WEAK) {                  } else if (ELF32_ST_BIND(sym->st_info) != STB_WEAK) {
                         printk("Undefined symbol for rela[%x] sym=%x\n",                          DPRINTF(("Undefined symbol for rela[%x] sym=%x\n",
                                i, sym);                                   i, sym));
                         return -1;                          return -1;
                 } else {                  } else {
                         elf_print("Undefined weak symbol for rela[%x]\n", i);                          DPRINTF(("Undefined weak symbol for rela[%x]\n", i));
                 }                  }
                 rela++;                  rela++;
         }          }
Line 150 
Line 156 
                         if (relocate_rel(rel, sym_val, target_sect) != 0)                          if (relocate_rel(rel, sym_val, target_sect) != 0)
                                 return -1;                                  return -1;
                 } else if (ELF32_ST_BIND(sym->st_info) != STB_WEAK) {                  } else if (ELF32_ST_BIND(sym->st_info) != STB_WEAK) {
                         printk("Undefined symbol for rel[%x] sym=%x\n",                          DPRINTF(("Undefined symbol for rel[%x] sym=%x\n",
                                i, sym);                                   i, sym));
                         return -1;                          return -1;
                 } else {                  } else {
                         elf_print("Undefined weak symbol for rel[%x]\n", i);                          DPRINTF(("Undefined weak symbol for rel[%x]\n", i));
                 }                  }
                 rel++;                  rel++;
         }          }
Line 201 
Line 207 
 {  {
         Elf32_Ehdr *ehdr;          Elf32_Ehdr *ehdr;
         Elf32_Shdr *shdr;          Elf32_Shdr *shdr;
         u_long sect_base, bss_base;          paddr_t sect_base, bss_base;
         int i;          int i;
   
         ehdr = (Elf32_Ehdr *)img;          ehdr = (Elf32_Ehdr *)img;
         shdr = (Elf32_Shdr *)((u_long)ehdr + ehdr->e_shoff);          shdr = (Elf32_Shdr *)((paddr_t)ehdr + ehdr->e_shoff);
         bss_base = 0;          bss_base = 0;
         m->phys = load_base;          m->phys = load_base;
         elf_print("phys addr=%x\n", load_base);          DPRINTF(("phys addr=%x\n", load_base));
   
         /* Copy sections */          /* Copy sections */
         for (i = 0; i < (int)ehdr->e_shnum; i++, shdr++) {          for (i = 0; i < (int)ehdr->e_shnum; i++, shdr++) {
                 sect_addr[i] = 0;                  sect_addr[i] = 0;
                 if (shdr->sh_type == SHT_PROGBITS) {                  if (shdr->sh_type == SHT_PROGBITS) {
   
                         elf_print("sh_addr=%x\n", shdr->sh_addr);                          DPRINTF(("sh_addr=%x\n", shdr->sh_addr));
                         elf_print("sh_size=%x\n", shdr->sh_size);                          DPRINTF(("sh_size=%x\n", shdr->sh_size));
                         elf_print("sh_offset=%x\n", shdr->sh_offset);                          DPRINTF(("sh_offset=%x\n", shdr->sh_offset));
                         elf_print("sh_flags=%x\n", shdr->sh_flags);                          DPRINTF(("sh_flags=%x\n", shdr->sh_flags));
   
                         switch (shdr->sh_flags & SHF_VALID) {                          switch (shdr->sh_flags & SHF_VALID) {
                         case (SHF_ALLOC | SHF_EXECINSTR):                          case (SHF_ALLOC | SHF_EXECINSTR):
                                 /* Text */                                  /* Text */
                                 m->text = (u_long)phys_to_virt(load_base);                                  m->text = (vaddr_t)phys_to_virt(load_base);
                                 break;                                  break;
                         case (SHF_ALLOC | SHF_WRITE):                          case (SHF_ALLOC | SHF_WRITE):
                                 /* Data */                                  /* Data */
                                 if (m->data == 0)                                  if (m->data == 0)
                                         m->data =                                          m->data =
                                                 (u_long)phys_to_virt(load_base + shdr->sh_addr);                                                  (vaddr_t)phys_to_virt(load_base + shdr->sh_addr);
                                 break;                                  break;
                         case SHF_ALLOC:                          case SHF_ALLOC:
                                 /* rodata */                                  /* rodata */
Line 241 
Line 247 
                         sect_base = load_base + shdr->sh_addr;                          sect_base = load_base + shdr->sh_addr;
                         memcpy((char *)sect_base, img + shdr->sh_offset,                          memcpy((char *)sect_base, img + shdr->sh_offset,
                                (size_t)shdr->sh_size);                                 (size_t)shdr->sh_size);
                         elf_print("load: offset=%x size=%x\n",                          DPRINTF(("load: offset=%x size=%x\n",
                                 sect_base, (int)shdr->sh_size);                                   sect_base, (int)shdr->sh_size));
   
                         sect_addr[i] = (char *)sect_base;                          sect_addr[i] = (char *)sect_base;
                 } else if (shdr->sh_type == SHT_NOBITS) {                  } else if (shdr->sh_type == SHT_NOBITS) {
Line 266 
Line 272 
         load_base = bss_base + m->bsssz;          load_base = bss_base + m->bsssz;
         load_base = PAGE_ALIGN(load_base);          load_base = PAGE_ALIGN(load_base);
   
         elf_print("module load_base=%x text=%x\n", load_base, m->text);          DPRINTF(("module load_base=%x text=%x\n", load_base, m->text));
         m->size = (size_t)(load_base - (u_long)virt_to_phys(m->text));          m->size = (size_t)(load_base - (paddr_t)virt_to_phys(m->text));
         m->entry = (u_long)phys_to_virt(ehdr->e_entry + m->phys);          m->entry = (vaddr_t)phys_to_virt(ehdr->e_entry + m->phys);
         elf_print("module size=%x entry=%x\n", m->size, m->entry);          DPRINTF(("module size=%x entry=%x\n", m->size, m->entry));
   
         /* Process relocation */          /* Process relocation */
         shdr = (Elf32_Shdr *)((u_long)ehdr + ehdr->e_shoff);          shdr = (Elf32_Shdr *)((paddr_t)ehdr + ehdr->e_shoff);
         for (i = 0; i < (int)ehdr->e_shnum; i++, shdr++) {          for (i = 0; i < (int)ehdr->e_shnum; i++, shdr++) {
                 if (shdr->sh_type == SHT_REL || shdr->sh_type == SHT_RELA) {                  if (shdr->sh_type == SHT_REL || shdr->sh_type == SHT_RELA) {
                         if (relocate_section(img, shdr) != 0)                          if (relocate_section(img, shdr) != 0)
Line 292 
Line 298 
         Elf32_Ehdr *ehdr;          Elf32_Ehdr *ehdr;
         Elf32_Phdr *phdr;          Elf32_Phdr *phdr;
   
         elf_print("\nelf_load\n");          DPRINTF(("\nelf_load\n"));
   
         ehdr = (Elf32_Ehdr *)img;          ehdr = (Elf32_Ehdr *)img;
   
Line 303 
Line 309 
             (ehdr->e_ident[EI_MAG3] != ELFMAG3))              (ehdr->e_ident[EI_MAG3] != ELFMAG3))
                 return -1;                  return -1;
   
         phdr = (Elf32_Phdr *)((u_long)ehdr + ehdr->e_ehsize);          phdr = (Elf32_Phdr *)((paddr_t)ehdr + ehdr->e_ehsize);
   
         if (nr_img == 0) {          if (nr_img == 0) {
                 /*  Initialize the load address */                  /*  Initialize the load address */
                 load_base = (u_long)phys_to_virt(phdr->p_paddr);                  load_base = (vaddr_t)phys_to_virt(phdr->p_paddr);
                 if (load_base == 0)                  if (load_base == 0)
                         return -1;                          return -1;
                 elf_print("kernel base=%x\n", load_base);                  DPRINTF(("kernel base=%x\n", load_base));
                 load_start = load_base;                  load_start = load_base;
         }          }
         else if (nr_img == 1) {          else if (nr_img == 1) {
                 /*  Second image => Driver */                  /*  Second image => Driver */
                 elf_print("driver base=%x\n", load_base);                  DPRINTF(("driver base=%x\n", load_base));
         }          }
         else {          else {
                 /* Other images => Boot tasks */                  /* Other images => Boot tasks */
                 elf_print("task base=%x\n", load_base);                  DPRINTF(("task base=%x\n", load_base));
         }          }
   
         switch (ehdr->e_type) {          switch (ehdr->e_type) {
Line 332 
Line 338 
                         return -1;                          return -1;
                 break;                  break;
         default:          default:
                 elf_print("Unsupported file type\n");                  DPRINTF(("Unsupported file type\n"));
                 return -1;                  return -1;
         }          }
         nr_img++;          nr_img++;

Legend:
Removed from v.1.1.1.1  
changed lines
  Added in v.1.1.1.1.2.1

CVSweb