Mail Archives: djgpp-workers/2002/11/29/00:50:01
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 -