www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2002/11/29/00:50:01

From: sandmann AT clio DOT rice DOT edu (Charles Sandmann)
Message-Id: <10211290511.AA14332@clio.rice.edu>
Subject: DXE enhancements
To: djgpp-workers AT delorie DOT com (DJGPP developers)
Date: Thu, 28 Nov 2002 23:11:42 -0600 (CST)
X-Mailer: ELM [version 2.5 PL2]
Mime-Version: 1.0
Reply-To: djgpp-workers AT delorie DOT com

I've been hacking on DXEs.  In particular, I want to be able to call I/O
and other lib routines from DXEs; this will allow us to put big libraries
such as libiconv there.

Included below are my current working patches for comments.  There is a
new switch "-i" which enables the new behavior.  If you use it, it does
not complain about unresolved symbols, it assumes they will be fixed up
at _dxe_load time; it then puts the required fixups at the end of the image.

_dxe_load has a corresponding change to check for this new section and
fix up values.  It needs a fixup vector which is assumed to be set 
externally before calling _dxe_load in a wrapper.  This fixup vector 
is currently written to the screen by dxegen; it would be linked into
images loading the DXE (solves the strip issue).

This is all very lightweight - my example DXE which calls malloc and 
printf is less than 200 bytes in size; the new dxe_load is only 200
bytes or more in size.

I also plan to support multiple exports in a future hack, but that can
be done today manually (the num_exports code below gives hints where
it goes).

Comments?

*** dxegen.c_	Sun Dec  9 18:14:22 2001
--- dxegen4.c	Thu Nov 28 22:53:10 2002
*************** int main(int argc, char **argv)
*** 71,74 ****
--- 71,88 ----
    size_t i;
    dxe_header dh;
+   int num_import, num_export = 0;
+   long *import_symndx = NULL;
+   char **import_name = NULL;
+ 
+   if (argc >= 2 && strcmp(argv[1], "-i") == 0)
+   {
+     argv++;
+     argc--;
+     num_import = 0;	/* New option to allow imports */
+     import_symndx = malloc(sizeof(long));
+     import_name = malloc(sizeof(char *));
+   }
+   else
+     num_import = -1;	/* No imports allowed */
  
    if (argc < 4)
*************** int main(int argc, char **argv)
*** 89,93 ****
    if (fh.f_nscns != 1 || argc > 4)
    {
!     char command[1024], *libdir;
      fclose(input_f);
  
--- 103,110 ----
    if (fh.f_nscns != 1 || argc > 4)
    {
!     char *command, *libdir;
!     unsigned cmdmax = 1024;
!     command = (char *)malloc(cmdmax);
! 
      fclose(input_f);
  
*************** int main(int argc, char **argv)
*** 115,127 ****
      for(i=3;argv[i];i++)
      {
        strcat(command, argv[i]);
        strcat(command, " ");
      }
      strcat(command," -T dxe.ld ");
!       
      printf("%s\n",command);
      i = system(command);
      if(i)
        return i;
  
      input_f = fopen("dxe__tmp.o", "rb");
--- 132,154 ----
      for(i=3;argv[i];i++)
      {
+       if(strlen(command) + strlen(argv[i]) + 2 > cmdmax) {
+         cmdmax += 1024;
+         command = realloc(command, cmdmax);
+       }
        strcat(command, argv[i]);
        strcat(command, " ");
      }
+ 
+     if(strlen(command) + 12 > cmdmax) {
+       cmdmax += 12;
+       command = realloc(command, cmdmax);
+     }
      strcat(command," -T dxe.ld ");
! 
      printf("%s\n",command);
      i = system(command);
      if(i)
        return i;
+     free(command);
  
      input_f = fopen("dxe__tmp.o", "rb");
*************** int main(int argc, char **argv)
*** 161,164 ****
--- 188,203 ----
    strings = malloc(strsz);
    fread(strings+4, 1, strsz-4, input_f);
+ 
+   relocs = malloc(sizeof(RELOC)*sc.s_nreloc);
+   fseek(input_f, sc.s_relptr, 0);
+   fread(relocs, sc.s_nreloc, RELSZ, input_f);
+ #if 0
+   /* Don't swap - it's in i386 order already */
+   for (i=0; i<sc.s_nreloc; i++)
+     dosswap(relocs+i, "lls");
+ #endif
+ 
+   fclose(input_f);
+ 
    strings[0] = 0;
    for (i=0; i<fh.f_nsyms; i++)
*************** int main(int argc, char **argv)
*** 178,185 ****
      }
  #if 0
!     printf("[%3d] 0x%08x 0x%04x 0x%04x %d %s\n",
  	   i,
  	   sym[i].e_value,
  	   sym[i].e_scnum & 0xffff,
  	   sym[i].e_sclass,
  	   sym[i].e_numaux,
--- 217,225 ----
      }
  #if 0
!     printf("[%3ld] 0x%08lx 0x%04x 0x%04x 0x%02x %d %s\n",
  	   i,
  	   sym[i].e_value,
  	   sym[i].e_scnum & 0xffff,
+ 	   sym[i].e_type,
  	   sym[i].e_sclass,
  	   sym[i].e_numaux,
*************** int main(int argc, char **argv)
*** 189,194 ****
      if (sym[i].e_scnum == 0)
      {
!       printf("Error: object contains unresolved external symbols (%s)\n", name);
!       errors ++;
      }
      if (strncmp(name, argv[2], strlen(argv[2])) == 0)
--- 229,275 ----
      if (sym[i].e_scnum == 0)
      {
!       if(num_import < 0)
!       {
!         printf("Error: object contains unresolved external symbols (%s)\n", name);
!         errors ++;
!       }
!       else
!       {
!         int j;
!         for (j=0; j<sc.s_nreloc; j++)
!           if(relocs[j].r_symndx == i)
!           {
!             num_import++;
!             import_symndx = realloc(import_symndx, num_import * sizeof(long));
!             import_name = realloc(import_name, num_import * sizeof(char *));
!             import_symndx[num_import - 1] = i;
!             import_name[num_import - 1] = strdup(name);
! #if 0
!             printf("import %s [%ld]", name, i);
!             if(relocs[j].r_type == 0x14)
!               printf("relative\n");
!             else
!               printf("absolulte\n");
!             break;
! #endif
!           }
!       }
!     }
!     else if (sym[i].e_sclass == 2)
!     {
! #if 0
!       int j;
!       for (j=0; j<sc.s_nreloc; j++)
!         if(relocs[j].r_symndx == i)
!         {
!           printf("export %s ",name);
!           if(relocs[j].r_type == 0x14)
!             printf("relative\n");
!           else
!             printf("absolulte\n");
!           break;
!         }
! #endif
!       num_export++;
      }
      if (strncmp(name, argv[2], strlen(argv[2])) == 0)
*************** int main(int argc, char **argv)
*** 214,229 ****
    }
  
-   relocs = malloc(sizeof(RELOC)*sc.s_nreloc);
-   fseek(input_f, sc.s_relptr, 0);
-   fread(relocs, sc.s_nreloc, RELSZ, input_f);
- #if 0
-   /* Don't swap - it's in i386 order already */
-   for (i=0; i<sc.s_nreloc; i++)
-     dosswap(relocs+i, "lls");
- #endif
  #if 0
    /* Thus, this won't work except on PCs */
    for (i=0; i<sc.s_nreloc; i++)
!     printf("0x%08x %3d 0x%04x - 0x%08x\n",
  	   relocs[i].r_vaddr,
  	   relocs[i].r_symndx,
--- 295,302 ----
    }
  
  #if 0
    /* Thus, this won't work except on PCs */
    for (i=0; i<sc.s_nreloc; i++)
!     printf("0x%08lx %3ld 0x%04x - 0x%08lx\n",
  	   relocs[i].r_vaddr,
  	   relocs[i].r_symndx,
*************** int main(int argc, char **argv)
*** 233,237 ****
  #endif
  
-   fclose(input_f);
    if (errors)
      return errors;
--- 306,309 ----
*************** int main(int argc, char **argv)
*** 245,249 ****
  
    for (i=0; i<sc.s_nreloc; i++)
!     if(*(char *)(&relocs[i].r_type) == 0x14)	/* Don't do these, they are relative */
        dh.nrelocs--;
  
--- 317,322 ----
  
    for (i=0; i<sc.s_nreloc; i++)
!     if(sym[relocs[i].r_symndx].e_scnum == 0 ||  /* Imports */
!      *(char *)(&relocs[i].r_type) == 0x14)      /* Don't do these, they are relative */
        dh.nrelocs--;
  
*************** int main(int argc, char **argv)
*** 252,258 ****
    fwrite(data, 1, sc.s_size, output_f);
    for (i=0; i<sc.s_nreloc; i++)
!     if(*(char *)(&relocs[i].r_type) != 0x14)	/* Don't do these, they are relative */
        fwrite(&(relocs[i].r_vaddr), 1, sizeof(long), output_f);
  
    fclose(output_f);
    return 0;
--- 325,359 ----
    fwrite(data, 1, sc.s_size, output_f);
    for (i=0; i<sc.s_nreloc; i++)
!     if(sym[relocs[i].r_symndx].e_scnum != 0 &&  /* Imports */
!      *(char *)(&relocs[i].r_type) != 0x14)      /* Don't do these, they are relative */
        fwrite(&(relocs[i].r_vaddr), 1, sizeof(long), output_f);
  
+   /* New Imports Section */
+   if (num_import > 0)
+   {
+     for (i=0; i<sc.s_nreloc; i++)
+       if (sym[relocs[i].r_symndx].e_scnum == 0)
+       {
+         int j;
+         long windx = relocs[i].r_symndx;
+         for (j=0; j<num_import; j++)		/* Find the mapped value */
+           if (windx == import_symndx[j]) {
+             windx = j + 1;			/* One based, can negate */
+             break;
+           }
+         if(*(char *)(&relocs[i].r_type) != 0x14)
+           windx = -windx;
+         /* printf("imprec: %ld 0x%lx\n", windx, relocs[i].r_vaddr); */
+         fwrite(&windx, 1, sizeof(long), output_f);
+         fwrite(&(relocs[i].r_vaddr), 1, sizeof(long), output_f);
+       }
+ 
+     /* This needs to go into an include file, like dxesub.h */
+     printf("static long dxefixup[] = {\n");
+     for (i=0; i<num_import; i++)
+       printf("(long)&%s,\n", import_name[i]+1);
+     printf("0 };\n");
+   }
+ 
    fclose(output_f);
    return 0;





*** dxeload.c_	Fri Apr 26 12:52:54 1996
--- dxeload.c	Mon Jan 21 21:30:28 2002
***************
*** 8,11 ****
--- 8,14 ----
  #include <sys/dxe.h>
  
+ char *_dxe_data;
+ long *_dxe_fixup;
+ 
  void *_dxe_load(char *name)
  {
*************** void *_dxe_load(char *name)
*** 39,43 ****
      int i;
      _read(h, relocs, sizeof(long)*dh.nrelocs);
-     _close(h);
  
      for (i=0; i<dh.nrelocs; i++)
--- 42,45 ----
*************** void *_dxe_load(char *name)
*** 45,48 ****
--- 47,69 ----
    }
  
+   {
+     long relocs[2];
+     int i,j;
+ 
+     while( sizeof(relocs) == _read(h, relocs, sizeof(relocs)) ) {
+       i = relocs[0];
+       if (i == 0)
+         break;
+       else if (i < 0) 
+         j = _dxe_fixup[-i-1];				/* Absolute - data */
+       else
+         j = _dxe_fixup[i-1] - (int)data;		/* Relative - code */
+ 
+       *(long *)(data + relocs[1]) += j;
+     }
+     _close(h);
+   }
+ 
+   _dxe_data = data;
    return (void *)(data + dh.symbol_offset);
  }

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019