home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 August - Disc 3 / chip_20018103_hu.iso / amiga / chiputil / gg / loadelfwos.lha / LoadElfWOS.lzx / src / loadelf.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-12-01  |  4.4 KB  |  192 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <powerpc/powerpc.h>
  5. #include <proto/powerpc.h>
  6. #include "loadelf.h"
  7. #include "relocelf.h"
  8. #include "error.h"
  9. #include "symbols.h"
  10. #include "elf/common.h"
  11. #include "elf/external.h"
  12.  
  13. int filelength (FILE *f);
  14.  
  15. int alloc_prog_sect(unsigned long);
  16. int alloc_bss_sect(unsigned long);
  17.  
  18. PElfObject *obj=0L;
  19.  
  20. PElfObject *alloc_elfobject(void *elfptr)
  21. {
  22.     Elf32_External_Ehdr *elfhdr;
  23.     Elf32_External_Shdr *shdrs;
  24.     char *shstrtab;
  25.     int i;
  26.  
  27.     if(!(obj=malloc(sizeof(PElfObject))))
  28.         return 0L;
  29.  
  30.     obj->sectcnt=0L;
  31.     obj->elfptr=0L;
  32.     for(i=0;i<MAX_SECTIONS;i++)
  33.         obj->sections[i].virtadr=0L;
  34.     obj->symbolscnt=0L;
  35.     obj->symbols=0L;
  36.  
  37.     obj->elfptr=elfptr;
  38.  
  39.     elfhdr=(Elf32_External_Ehdr *)obj->elfptr;
  40.  
  41.     if((elfhdr->e_ident[EI_MAG0]!=ELFMAG0)||
  42.        (elfhdr->e_ident[EI_MAG1]!=ELFMAG1)||
  43.        (elfhdr->e_ident[EI_MAG2]!=ELFMAG2)||
  44.        (elfhdr->e_ident[EI_MAG3]!=ELFMAG3))
  45.     {
  46.         error_printf("Wrong magic number in ELF-header !");
  47.         free_elfobject(obj);
  48.         return 0L;
  49.     }
  50.  
  51.     if(elfhdr->e_ident[EI_CLASS]!=ELFCLASS32)
  52.     {
  53.         error_printf("ELF-class is not 32-bit !");
  54.         free_elfobject(obj);
  55.         return 0L;
  56.     }
  57.  
  58.     if(elfhdr->e_ident[EI_DATA]!=ELFDATA2MSB)
  59.     {
  60.         error_printf("ELF-data encoding is not big endian !");
  61.         free_elfobject(obj);
  62.         return 0L;
  63.     }
  64.  
  65.     if(elfhdr->e_type!=ET_REL)
  66.     {
  67.         error_printf("ELF-file is not relocatable !");
  68.         free_elfobject(obj);
  69.         return 0L;
  70.     }
  71.  
  72.     if(elfhdr->e_machine!=EM_PPC)
  73.     {
  74.         error_printf("ELF-file is not for PowerPC !");
  75.         free_elfobject(obj);
  76.         return 0L;
  77.     }
  78.  
  79.     if(elfhdr->e_version!=EV_CURRENT)
  80.         info_printf("Warning: ELF-version is not EV_CURRENT !\n"); //Can this happen?
  81.  
  82.     if(elfhdr->e_entry!=0L)
  83.         info_printf("Warning: ELF-entry is not NULL !\n");//What does this mean?
  84.  
  85.     if(elfhdr->e_phoff!=0L)
  86.         info_printf("Warning: ELF-phoff is not NULL !\n");//Can this happen?
  87.  
  88.     shdrs=(Elf32_External_Shdr *)(obj->elfptr+elfhdr->e_shoff);
  89.  
  90.     if(elfhdr->e_ehsize!=sizeof(Elf32_External_Ehdr))
  91.     {
  92.         error_printf("ELF-header has unusual size !");
  93.         free_elfobject(obj);
  94.         return 0L;
  95.     }
  96.  
  97.     if(elfhdr->e_shentsize!=sizeof(Elf32_External_Shdr))
  98.     {
  99.         error_printf("Section-entrys have unusual size !");
  100.         free_elfobject(obj);
  101.         return 0L;
  102.     }
  103.  
  104.     obj->sectcnt=elfhdr->e_shnum;
  105.     info_printf("%li sections in file:\n",obj->sectcnt-1);
  106.  
  107.     shstrtab=obj->elfptr+shdrs[elfhdr->e_shstrndx].sh_offset;
  108.  
  109.     for(i=0;i<obj->sectcnt;i++)
  110.     {
  111.         obj->sections[i].virtadr=0L;
  112.         if(i!=0)        //Section 0 will be .common
  113.         {
  114.             obj->sections[i].name=&shstrtab[shdrs[i].sh_name];
  115.             obj->sections[i].size=shdrs[i].sh_size;
  116.             obj->sections[i].elfadr=obj->elfptr+shdrs[i].sh_offset;
  117.             obj->sections[i].type=shdrs[i].sh_type;
  118.             obj->sections[i].flags=shdrs[i].sh_flags;
  119.             obj->sections[i].link=shdrs[i].sh_link;
  120.             obj->sections[i].info=shdrs[i].sh_info;
  121.             obj->sections[i].entsize=shdrs[i].sh_entsize;
  122.         }
  123.     }
  124.  
  125.     for(i=1;i<obj->sectcnt;i++)        //Skip first shentry (hopefully unused)
  126.     {
  127.         info_printf("Section: %-15s ",obj->sections[i].name);
  128.         info_printf("Size: %7lu  ",obj->sections[i].size);
  129.  
  130.         if(obj->sections[i].flags&SHF_ALLOC)
  131.             if(!(obj->sections[i].virtadr=AllocVec32(obj->sections[i].size,0L)))        //Probably should use AllocMem32 here
  132.             {
  133.                 error_printf("No mem for section: %s",obj->sections[i].name);
  134.                 free_elfobject(obj);
  135.                 return 0L;
  136.             }
  137.             
  138.             
  139.         switch(obj->sections[i].type)
  140.         {
  141.             case SHT_PROGBITS :     info_printf("PROGRAM section\n");
  142.                         if(obj->sections[i].virtadr)
  143.                             memcpy(obj->sections[i].virtadr,obj->sections[i].elfadr,obj->sections[i].size);
  144.                         break;
  145.                         
  146.             case SHT_RELA :     info_printf("RELA section\n");
  147.                         break;
  148.                         
  149.             case SHT_SYMTAB :     info_printf("SYMBOL section\n");
  150.                         if(!add_symbol_sect(obj,i))
  151.                         {
  152.                             free_elfobject(obj);
  153.                             return 0L;
  154.                         }
  155.                         break;
  156.                         
  157.             case SHT_STRTAB :     info_printf("STRING section\n");
  158.                         break;
  159.                         
  160.             case SHT_NOBITS :     info_printf("BSS section\n");
  161.                         if(obj->sections[i].virtadr)
  162.                             memset(obj->sections[i].virtadr,0,obj->sections[i].size);
  163.                         break;
  164.                         
  165.             default:         error_printf("Unsupported Section-type!");
  166.                         free_elfobject(obj);
  167.                         return 0L;
  168.         }
  169.     }
  170.     if(!reloc_elfobj(obj))
  171.     {
  172.         free_elfobject(obj);
  173.         return 0L;
  174.     }
  175.  
  176.     return obj;
  177. }
  178.  
  179. void free_elfobject(PElfObject *elfobj)
  180. {
  181.     int i;
  182.     if(elfobj)
  183.     {
  184.         for(i=0;i<elfobj->sectcnt;i++)
  185.             if(elfobj->sections[i].virtadr)
  186.                 FreeVec32(elfobj->sections[i].virtadr);
  187.         if(elfobj->symbols)
  188.             free(elfobj->symbols);
  189.         free(elfobj);
  190.     }
  191. }
  192.