home *** CD-ROM | disk | FTP | other *** search
/ PC Extra Super CD 1998 January / PCPLUS131.iso / DJGPP / V2 / DJLSR201.ZIP / src / dxe / dxegen.c next >
Encoding:
C/C++ Source or Header  |  1995-04-22  |  4.2 KB  |  181 lines

  1. /* Copyright (C) 1995 Charles Sandmann (sandmann@clio.rice.edu)
  2.    This software may be freely distributed with above copyright, no warranty.
  3.    Based on code by DJ Delorie, it's really his, enhanced, bugs fixed. */
  4.  
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <coff.h>
  9. #include <sys/dxe.h>
  10.  
  11. void exit_cleanup(void)
  12. {
  13.   remove("dxe__tmp.o");
  14. }
  15.  
  16. int main(int argc, char **argv)
  17. {
  18.   int errors = 0;
  19.   unsigned bss_start = 0;
  20.   FILHDR fh;
  21.   FILE *input_f, *output_f;
  22.   SCNHDR sc;
  23.   char *data, *strings;
  24.   SYMENT *sym;
  25.   RELOC *relocs;
  26.   int strsz, i;
  27.   dxe_header dh;
  28.  
  29.   if (argc < 4)
  30.   {
  31.     printf("Usage: dxegen output.dxe symbol input.o [input2.o ... -lgcc -lc]\n");
  32.     return 1;
  33.   }
  34.  
  35.   input_f = fopen(argv[3], "rb");
  36.   if (!input_f)
  37.   {
  38.     perror(argv[3]);
  39.     return 1;
  40.   }
  41.  
  42.   fread(&fh, 1, FILHSZ, input_f);
  43.   if (fh.f_nscns != 1 || argc > 4)
  44.   {
  45.     char command[1024];
  46.     fclose(input_f);
  47.  
  48.     strcpy(command,"ld -X -S -r -o dxe__tmp.o -L");
  49.     strcat(command,getenv("DJDIR"));
  50.     strcat(command,"/lib ");
  51.     for(i=3;argv[i];i++) {
  52.       strcat(command,argv[i]);
  53.       strcat(command," ");
  54.     }
  55.     strcat(command," -T dxe.ld ");
  56.       
  57.     printf("%s\n",command);
  58.     i = system(command);
  59.     if(i)
  60.       return i;
  61.  
  62.     input_f = fopen("dxe__tmp.o", "rb");
  63.     if (!input_f)
  64.     {
  65.       perror(argv[3]);
  66.       return 1;
  67.     } else
  68.       atexit(exit_cleanup);
  69.  
  70.     fread(&fh, 1, FILHSZ, input_f);
  71.     if (fh.f_nscns != 1) {
  72.       printf("Error: input file has more than one section; use -M for map\n");
  73.       return 1;
  74.     }
  75.   }
  76.  
  77.   fseek(input_f, fh.f_opthdr, 1);
  78.   fread(&sc, 1, SCNHSZ, input_f);
  79.  
  80.   dh.magic = DXE_MAGIC;
  81.   dh.symbol_offset = -1;
  82.   dh.element_size = sc.s_size;
  83.   dh.nrelocs = sc.s_nreloc;
  84.  
  85.   data = malloc(sc.s_size);
  86.   fseek(input_f, sc.s_scnptr, 0);
  87.   fread(data, 1, sc.s_size, input_f);
  88.  
  89.   sym = malloc(sizeof(SYMENT)*fh.f_nsyms);
  90.   fseek(input_f, fh.f_symptr, 0);
  91.   fread(sym, fh.f_nsyms, SYMESZ, input_f);
  92.   fread(&strsz, 1, 4, input_f);
  93.   strings = malloc(strsz);
  94.   fread(strings+4, 1, strsz-4, input_f);
  95.   strings[0] = 0;
  96.   for (i=0; i<fh.f_nsyms; i++)
  97.   {
  98.     char tmp[9], *name;
  99.     if (sym[i].e.e.e_zeroes)
  100.     {
  101.       memcpy(tmp, sym[i].e.e_name, 8);
  102.       tmp[8] = 0;
  103.       name = tmp;
  104.     }
  105.     else
  106.       name = strings + sym[i].e.e.e_offset;
  107. #if 0
  108.     printf("[%3d] 0x%08x 0x%04x 0x%04x %d %s\n",
  109.        i,
  110.        sym[i].e_value,
  111.        sym[i].e_scnum & 0xffff,
  112.        sym[i].e_sclass,
  113.        sym[i].e_numaux,
  114.        name
  115.        );
  116. #endif
  117.     if (sym[i].e_scnum == 0)
  118.     {
  119.       printf("Error: object contains unresolved external symbols (%s)\n", name);
  120.       errors ++;
  121.     }
  122.     if (strncmp(name, argv[2], strlen(argv[2])) == 0)
  123.     {
  124.       if (dh.symbol_offset != -1)
  125.       {
  126.     printf("Error: multiple symbols that start with %s (%s)!\n", argv[2], name);
  127.     errors++;
  128.       }
  129.       dh.symbol_offset = sym[i].e_value;
  130.     } else if (strcmp(name, ".bss") == 0 && !bss_start) {
  131.       bss_start = sym[i].e_value;
  132. /*      printf("bss_start 0x%x\n",bss_start); */
  133.       memset(data+bss_start, 0, sc.s_size - bss_start);
  134.     }
  135.     i += sym[i].e_numaux;
  136.   }
  137.  
  138.   if (dh.symbol_offset == -1)
  139.   {
  140.     printf("Error: symbol %s not found!\n", argv[2]);
  141.     errors++;
  142.   }
  143.  
  144.   relocs = malloc(sizeof(RELOC)*sc.s_nreloc);
  145.   fseek(input_f, sc.s_relptr, 0);
  146.   fread(relocs, sc.s_nreloc, RELSZ, input_f);
  147. #if 0
  148.   for (i=0; i<sc.s_nreloc; i++)
  149.     printf("0x%08x %3d 0x%04x - 0x%08x\n",
  150.        relocs[i].r_vaddr,
  151.        relocs[i].r_symndx,
  152.        relocs[i].r_type,
  153.        *(long *)(data + relocs[i].r_vaddr)
  154.        );
  155. #endif
  156.  
  157.   fclose(input_f);
  158.   if (errors)
  159.     return errors;
  160.  
  161.   output_f = fopen(argv[1], "wb");
  162.   if (!output_f)
  163.   {
  164.     perror(argv[1]);
  165.     return 1;
  166.   }
  167.  
  168.   for (i=0; i<sc.s_nreloc; i++)
  169.     if(relocs[i].r_type == 0x14)    /* Don't do these, they are relative */
  170.       dh.nrelocs--;
  171.  
  172.   fwrite(&dh, 1, sizeof(dh), output_f);
  173.   fwrite(data, 1, sc.s_size, output_f);
  174.   for (i=0; i<sc.s_nreloc; i++)
  175.     if(relocs[i].r_type != 0x14)    /* Don't do these, they are relative */
  176.       fwrite(&(relocs[i].r_vaddr), 1, sizeof(long), output_f);
  177.  
  178.   fclose(output_f);
  179.   return 0;
  180. }
  181.