Subversion Repositories Kolibri OS

Rev

Rev 4973 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. #include"mcoff.h"
  2. #include<stdio.h>
  3. #include<stdlib.h>
  4. #include"string.h"
  5.  
  6. #undef MCOFF_MENUETOS
  7. #define MCOFF_MENUETOS  0
  8.  
  9. #if (MCOFF_MENUETOS==1)
  10. struct systree_blk {
  11.  unsigned long cmd,pos,blks;
  12.  void * data,* work;
  13.  char name[128];
  14. } __attribute__((packed));
  15.  
  16. static char systree_work[16384];
  17. static char temp_block[512];
  18.  
  19. static struct systree_blk sblk={
  20.  0,
  21.  0,
  22.  1,
  23.  NULL,
  24.  systree_work,
  25. };
  26.  
  27. static unsigned long open_on_path(char * pth,char * name)
  28. {
  29.  int l;
  30.  int d0,d1;
  31.  l=strlen(pth);
  32.  if(!pth)
  33.  {
  34.   sprintf(sblk.name,"%s",pth);
  35.  } else {
  36.   if(pth[l]!='/')
  37.    sprintf(sblk.name,"%s/%s",pth,name);
  38.   else
  39.    sprintf(sblk.name,"%s%s",pth,name);
  40.  }
  41.  sblk.data=&temp_block;
  42.  sblk.cmd=0;
  43.  sblk.pos=0;
  44.  sblk.blks=1;
  45.  sblk.work=systree_work;
  46.  __asm__ __volatile__("int $0x40":"=a"(d0),"=b"(d1):"0"(58),"1"((void *)&sblk));
  47.  if(d0!=0) return 0;
  48.  return d1;
  49. }
  50. #endif
  51.  
  52. coffobj_t * mcoff_load_file(char * fname)
  53. {
  54.  coffobj_t * obj;
  55.  int i;
  56. #if (MCOFF_MENUETOS==1)
  57.  unsigned long sz;
  58. #endif
  59.  obj=(coffobj_t *)malloc(sizeof(coffobj_t));
  60.  if(!obj)
  61.  {
  62.   dprintf("malloc error1\n");
  63.   return NULL;
  64.  }
  65. #if (MCOFF_MENUETOS==0)
  66.  FILE * f=fopen(fname,"rb");
  67.  if(!f)
  68.  {
  69.   dprintf("Unable to open file\n");
  70.   free(obj);
  71.   return NULL;
  72.  }
  73.  dprintf("File opened\n");
  74.  fseek(f,0,SEEK_END);
  75.  dprintf("After seek to end\n");
  76.  obj->co_filesize=ftell(f);
  77.  dprintf("After ftell\n");
  78.  fseek(f,0,SEEK_SET);
  79.  dprintf("After seek to start\n");
  80.  dprintf("File size is %u bytes\n",obj->co_filesize);
  81. #else
  82.  /* Special actions for MenuetOS, because it doesn't support relative paths */
  83.  /* We just search some paths if it is relative */
  84.  if(fname[0]!='/')
  85.  {
  86.   sz=open_on_path("/SYS",fname);
  87.   if(sz>64 && sz<0x1000000) goto OK; /* Max 16MB for DLL */
  88.   sz=open_on_path("/HD/1/MENUETOS",fname);
  89.   if(sz>64 && sz<0x1000000) goto OK; /* Max 16MB for DLL */
  90.   sz=open_on_path("/HD/1/MENUETOS/DLL",fname);
  91.   if(sz>64 && sz<0x1000000) goto OK; /* Max 16MB for DLL */
  92.  } else {
  93.   dprintf("Opening on std path\n");
  94.   sz=open_on_path("",fname);
  95.   if(sz>64 && sz<0x1000000) goto OK; /* Max 16MB for DLL */
  96.  }  
  97.  free(obj);
  98.  return NULL;
  99. OK:
  100.  obj->co_filesize=sz;
  101.  dprintf("File size is %u bytes\n",sz);
  102. #endif
  103.  obj->co_loadptr=(char *)malloc((obj->co_filesize+511)&~511);
  104.  if(!obj->co_loadptr)
  105.  {
  106.   dprintf("Unable to create file memory\n");
  107. #if (MCOFF_MENUETOS==0)
  108.   fclose(f);
  109. #endif
  110.   free(obj);
  111.   return NULL;
  112.  }
  113.  dprintf("Memory allocated\n");
  114. #if (MCOFF_MENUETOS==0)
  115.  dprintf("Before fread\n");
  116.  fread(obj->co_loadptr,1,obj->co_filesize,f);
  117.  dprintf("After fread\n");
  118.  fclose(f);
  119.  dprintf("After fclose\n");
  120. #else
  121.  sblk.cmd=0;
  122.  sblk.pos=0;
  123.  sblk.blks=((sz+511)&~511)/512;
  124.  sblk.data=obj->co_loadptr;
  125.  sblk.work=systree_work;
  126.  {
  127.   int d0,d1;
  128.   __asm__ __volatile__("int $0x40":"=a"(d0),"=b"(d1):"0"(58),"1"((void *)&sblk));
  129.  }
  130.  dprintf("Done reading file\n");
  131. #endif
  132.  dprintf("Checking file\n");
  133.  obj->co_loadaddr=(unsigned long)obj->co_loadptr;
  134.  obj->co_filehdr=(FILHDR *)obj->co_loadaddr;
  135.  /* Check if file is really COFF */
  136.  if(I386BADMAG(*obj->co_filehdr))
  137.  {
  138.   dprintf("bad magic\n");
  139. NOREL:
  140.   free(obj->co_loadptr);
  141.   free(obj);
  142.   return NULL;
  143.  }
  144.  /* We don't support files with relocations stripped */
  145. /* if(obj->co_filehdr->f_flags & F_RELFLG)
  146.  {
  147.   printf("No relocation info\n");
  148.   goto NOREL;
  149.  } */
  150.  /* Get into section table, symbol table and string table */
  151.  obj->co_sections=(SCNHDR *)(obj->co_loadaddr+FILHSZ+obj->co_filehdr->f_opthdr);
  152.  obj->co_symtab=(SYMENT *)(obj->co_loadaddr+obj->co_filehdr->f_symptr);
  153.  obj->co_strtab=(char *)(obj->co_loadaddr+obj->co_filehdr->f_symptr+
  154.   SYMESZ*obj->co_filehdr->f_nsyms);
  155.  /* Setup .bss section */
  156.  {
  157.   SCNHDR * h;
  158.   h=obj->co_sections;
  159.   dprintf("Looking for bss...\n");
  160.   for(i=0;i<obj->co_filehdr->f_nscns;i++,h++)
  161.   {
  162.    unsigned long r;
  163.    if((h->s_flags & 0xE0)!=0x80) continue;
  164.    r=h->s_size;
  165.    obj->co_bssptr=(char *)malloc(r);
  166.    obj->co_bsssize=r;
  167.    if(!obj->co_bssptr)
  168.    {
  169.     dprintf("Unable to alloc %u bytes for bss\n",r);
  170.     free(obj->co_loadptr);
  171.     free(obj);
  172.     return NULL;
  173.    }
  174.    obj->co_bssaddr=(unsigned long)obj->co_bssptr;
  175.    h->s_scnptr=obj->co_bssaddr-obj->co_loadaddr;
  176.    obj->co_bsssectnum=i+1; /* So we don't have to do it later */
  177.    dprintf("BSS size=%u bytes\n",obj->co_bsssize);
  178.   }
  179.  }
  180. NOBSS:
  181.  /* File is COFF. Just return obj */
  182.  return obj;
  183. }
  184.  
  185. void unload_coff_file(coffobj_t * obj)
  186. {
  187.  if(!obj) return;
  188.  free(obj->co_loadptr);
  189.  return;
  190. }
  191.