diff --git a/NT/init_nt b/NT/init_nt index 849a2d195a754faacb64b019c727b4637da74058..b5d02d47b22f4cac453f3d08840180a5b9edfc74 100755 --- a/NT/init_nt +++ b/NT/init_nt @@ -64,6 +64,16 @@ path=$MSVC\\bin; include=$MSVC\\Include;$local\\include lib=$MSVC\\Lib;$local\\lib " + + # This variable is used by pntld to find + # the libraries (*.lib) on the UNIX system. + # + # If your library directory is not available on the unix system you + # will need to make a copy. -Hubbe + # + NTLD_LIBRARY_PATH='/net/cytocin/winshare/vc98/Lib:/net/cytocin/winshare/local/lib' + + export NTLD_LIBRARY_PATH export REMOTE_VARIABLES else echo "We are not Hubbe." diff --git a/NT/tools/pntld b/NT/tools/pntld index 11401612cc70ecfa032c83aad64b0f13033036a2..c81b65672e9f4567d205e0c82fca577dc748e1c7 100755 --- a/NT/tools/pntld +++ b/NT/tools/pntld @@ -1,6 +1,12 @@ #!/usr/local/bin/pike -/* Partial linker for COFF files, written by Fredrik Hubinette 2000 */ +// Partial linker for COFF files, written by Fredrik Hubinette 2000 +// +// Things left to do: +// Merge sections +// Test if resulting files work with cl.exe +// Support line number information +// Support 64 bit architechtures class Reloc { @@ -35,6 +41,8 @@ class Symbol mapping(string:Symbol) global_symbols=([]); array(Section) global_sections=({}); array(string) global_directives=({}); +array(string) libpath=({}); +array(string) libraries=({}); class Linker { @@ -637,29 +645,75 @@ class dumpfile void dumpArchive(int pos) { + string name; + int num; + int longnames; while(pos < strlen(data)) { - string name=range(pos,16); + num++; int size = (int) range(pos+48,10); - + name=range(pos,16); + if(name[0]=='/') + { + if(num == 3) + { + longnames=pos+60; + } + else if(longnames && sscanf(name,"/%d",int longnamenum)) + { + name=nulltermstring(longnames + longnamenum); + } + }else{ + if(sscanf(reverse(name),"%*s/%s",name)) + name=reverse(name); + } #ifdef DEBUG write("\n"); write("# name: %s\n",name); - write("# date: %s\n",ctime( (int) range(pos+16,12) ) ); + write("# date: %s",ctime( (int) range(pos+16,12) ) ); write("# uid : %s\n",range(pos+28,6)); write("# gid : %s\n",range(pos+34,6)); write("# mode: %s\n",range(pos+40,8)); write("# size: %s\n",range(pos+48,10)); #endif - if(name[0]!='/') - dumpfile(data, pos+60,0,name); - + { + dumpfile(data, pos+60, 0, name); + } pos+=60; pos+=(size+1)&~1; } } + void dumpImportLib() + { + string name= ( filename/"/" )[-1]; +#if 0 + sscanf(range(0,20), + "%-2c%-2c%-2c%-2c%-4c%-4c%-2c%-2c", + int sig1, + int sig2, + int version, + int machine, + int timestamp, + int size_of_data, + int ordinal, + int type); + write("Sig1 : %x\n",sig1); + write("Sig2 : %x\n",sig2); + write("version : %x\n",version); + write("Machine : %x\n", machine); + write("Time : %s",ctime(timestamp)); + write("Ordinal : %x\n",ordinal); + write("Type: : %x\n",type); + write("Name : %s\n",nulltermstring(20)); + + write("Importing library: %O\n",name); +#endif + + global_directives|=({ "-LIB:"+name }); + } + void create(string d, void|int p, void|int len, void|string f) { base=p; @@ -674,21 +728,24 @@ class dumpfile #endif dumpArchive(8); }else{ - if(len >=0x40 && !dumpPE(i4(0x3c))) + if(i2(0) == 0 && i2(2) == 0xffff) { + dumpImportLib(); + }else{ dumpCOFF(0); - } + } } } } int main(int argc, array(string) argv) { + int err; int strip=0; string output="a.out"; // werror("%O\n",argv); werror("Pike Win32 partial linker.\n" - "$Id: pntld,v 1.1 2000/12/23 07:19:49 hubbe Exp $\n" + "$Id: pntld,v 1.2 2000/12/27 07:55:09 hubbe Exp $\n" "Written by Fredrik Hubinette 2000\n"); foreach(Getopt.find_all_options(argv,aggregate( @@ -704,8 +761,11 @@ int main(int argc, array(string) argv) { case "S": strip++; break; - case "R": case "L": + libpath|=({opt[1]}); + break; + + case "R": global_directives|=({ "-?rpath:"+opt[1] }); break; @@ -714,11 +774,7 @@ int main(int argc, array(string) argv) { case "c": case "m": break; default: - /* FIXME: - * search for *.lib files and link them 'statically' - * if found. - */ - global_directives|=({ "-lib:"+opt[1] }); + libraries|=({opt[1]}); } break; @@ -728,6 +784,49 @@ int main(int argc, array(string) argv) } } + if(getenv("NTLD_LIBRARY_PATH")) + libpath|=getenv("NTLD_LIBRARY_PATH")/":"; + + if(getenv("NTLD_RUN_PATH")) + foreach(getenv("NTLD_RUN_PATH")/":",string p) + global_directives|=({"-?rpath:"+p}); + + libpath|=({"."}); + + foreach(libraries, string lib) + { + int found; + foreach(libpath, string path) + { + string filename=combine_path(path,lib+".lib"); +#ifdef DEBUG + werror("Looking for %s\n",filename); +#endif + if(string file=Stdio.read_file(filename)) + { + dumpfile(file, 0, 0, filename); + found=1; + break; + } + + filename=combine_path(path,upper_case(lib+".lib")); +#ifdef DEBUG + werror("Looking for %s\n",filename); +#endif + if(string file=Stdio.read_file(filename)) + { + dumpfile(file, 0, 0, filename); + found=1; + break; + } + } + if(!found) + { + werror("Failed to find library: %s\n",lib); + err++; + } + } + argv=Getopt.get_args(argv); foreach(argv[1..],string file) @@ -753,9 +852,10 @@ int main(int argc, array(string) argv) global_sections= ({s}) + global_sections; } + if(err) exit(err); rm(output); Stdio.write_file(output, Linker()->out(global_sections, values(global_symbols))); - exit(0); + exit(err); } diff --git a/src/dlopen.c b/src/dlopen.c index f5871faba3865bc646df148fe61cbcbdb6c4dfa2..25319fdac58c9b111e3a21b08657dcbf62442b21 100644 --- a/src/dlopen.c +++ b/src/dlopen.c @@ -20,13 +20,21 @@ #include <sys/stat.h> #include <assert.h> +/* Todo: + * Make image debugable if possible + * Support Win64 + * Separate RWX, RW and R memory sections. + */ -#define DLDEBUG 1 +/* #define DLDEBUG 1 */ #define DL_VERBOSE 1 + #ifdef DLDEBUG +#define FLUSH() do{ fflush(stderr); Sleep(500); }while(0) #define DO_IF_DLDEBUG(X) X #else +#define FLUSH() #define DO_IF_DLDEBUG(X) #endif @@ -67,7 +75,7 @@ size_t STRNLEN(char *s, size_t maxlen) #else /* PIKE_CONCAT */ -RCSID("$Id: dlopen.c,v 1.2 2000/12/23 16:18:14 grubba Exp $"); +RCSID("$Id: dlopen.c,v 1.3 2000/12/27 07:55:09 hubbe Exp $"); #endif @@ -94,6 +102,7 @@ static struct Htable *alloc_htable(size_t size) struct Htable *ret; #ifdef DLDEBUG fprintf(stderr,"alloc_htable(%d)\n",size); + FLUSH(); #endif ret=(struct Htable *)malloc(sizeof(struct Htable) + sizeof(void *)*(size-1)); @@ -248,6 +257,9 @@ static void htable_free(struct Htable *h, void(*hfree)(void *)) static int filesize(char *filename) { struct stat st; +#ifdef DLDEBUG + fprintf(stderr,"filesize(%s)\n",filename); +#endif if(stat(filename, &st)<0) return -1; return st.st_size; } @@ -291,6 +303,8 @@ static char *read_file(char *name, size_t *len) while(fd_close(fd) < 0 && errno==EINTR); #ifdef DLDEBUG fprintf(stderr,"Done reading\n"); + fflush(stderr); + Sleep(500); #endif return buffer; } @@ -347,12 +361,18 @@ static int append_dlllist(struct DLLList **l, char *name) { struct DLLList *n; - HINSTANCE tmp=LoadLibrary(name); + HINSTANCE tmp; +#ifdef DLDEBUG + fprintf(stderr,"append_dlllist(%s)\n",name); + FLUSH(); +#endif + tmp=LoadLibrary(name); if(!tmp) return 0; n=(struct DLLList *)malloc(sizeof(struct DLLList)); n->dll=tmp; #ifdef DLDEBUG fprintf(stderr,"append_dlllist(%s)->%p\n",name,n->dll); + FLUSH(); #endif n->next=0; while( *l ) l= & (*l)->next; @@ -506,7 +526,9 @@ static void *low_dlsym(struct DLHandle *handle, } #ifdef DL_VERBOSE if(!ptr) + { fprintf(stderr,"Failed to find identifier %s\n",tmp); + } #endif return ptr; } @@ -535,6 +557,7 @@ static parse_link_info(struct DLHandle *ret, fprintf(stderr,"DLINFO(%d): ",len); for(z=0;z<len;z++) fprintf(stderr,"%c",info[z]); fprintf(stderr,"\n"); + FLUSH(); } #endif @@ -545,6 +568,7 @@ static parse_link_info(struct DLHandle *ret, #ifdef DLDEBUG fprintf(stderr,"Parse link info ptr=%d\n",ptr,l); + FLUSH(); #endif end=MEMCHR(info+ptr,' ',len-ptr); @@ -554,7 +578,17 @@ static parse_link_info(struct DLHandle *ret, l=len-ptr; #ifdef DLDEBUG - fprintf(stderr,"Parse link info ptr=%d len=%d\n",ptr,l); + fprintf(stderr,"Parse link info ptr=%d len=%d '%c%c%c%c%c%c%c%c'\n", + ptr,l, + info[x], + info[x+1], + info[x+2], + info[x+3], + info[x+4], + info[x+5], + info[x+6], + info[x+7]); + FLUSH(); #endif if(info[x] == '-') @@ -564,13 +598,31 @@ static parse_link_info(struct DLHandle *ret, if(!memcmp(info+x,"lib:",4) || !memcmp(info+x,"LIB:",4)) { x+=4; - memcpy(buffer,info+x,l-x); - buffer[l-x]=0; +#ifdef DLDEBUG + fprintf(stderr,"Found lib: ptr=%d len=%d '%c%c%c%c%c%c%c%c'\n", + x, + l-(x-ptr), + info[x], + info[x+1], + info[x+2], + info[x+3], + info[x+4], + info[x+5], + info[x+6], + info[x+7]); + FLUSH(); +#endif + memcpy(buffer,info+x,l-(x-ptr)); + buffer[l-(x-ptr)]=0; append_dlllist(&ret->dlls, buffer); } } ptr+=l+1; } +#ifdef DLDEBUG + fprintf(stderr,"Parse link info done.\n"); + FLUSH(); +#endif } static int dl_load_coff_files(struct DLHandle *ret, @@ -586,6 +638,7 @@ static int dl_load_coff_files(struct DLHandle *ret, #ifdef DLDEBUG fprintf(stderr,"dl_load_coff_files(%p,%p,%d)\n",ret,tmp,num); + FLUSH(); #endif if(!num) return 0; @@ -689,6 +742,7 @@ static int dl_load_coff_files(struct DLHandle *ret, #ifdef DLDEBUG fprintf(stderr,"DL: moving code\n"); + FLUSH(); #endif /* Copy code into executable memory */ @@ -797,6 +851,7 @@ static int dl_load_coff_files(struct DLHandle *ret, #ifdef DLDEBUG fprintf(stderr,"DL: resolving\n"); + FLUSH(); #endif /* Do resolve and relocations */ @@ -893,21 +948,17 @@ static int dl_load_coff_files(struct DLHandle *ret, /* We may need to support more types here */ case COFFReloc_type_dir32: - if(SYMBOLS(sym).type >> 4 == 2) + if( (SYMBOLS(sym).type >> 4) == 2 && !SYMBOLS(sym).secnum) { - /* Indirect function pointer (#&$#*&#$ */ - ((char **)loc)[0]=(char *)(data->symbol_addresses + sym); #ifdef DLDEBUG - fprintf(stderr,"DL: reloc indirect: loc %p = %p, *%p = %p + %d\n", - loc,ptr, - *(char **)loc,data->symbol_addresses,sym); + fprintf(stderr,"DL: Indirect *%p = %d secnum=%d!!!\n", loc, *(INT32 *)loc,SYMBOLS(sym).secnum); #endif - }else{ - ((INT32 *)loc)[0]+=(INT32)ptr; + ptr=(char *)(data->symbol_addresses + sym); + } + ((INT32 *)loc)[0]+=(INT32)ptr; #ifdef DLDEBUG fprintf(stderr,"DL: reloc absolute: loc %p = %p\n", loc,ptr); #endif - } break; @@ -948,6 +999,7 @@ static int dl_loadarchive(struct DLHandle *ret, #ifdef DLDEBUG fprintf(stderr,"dl_loadarchive\n"); + FLUSH(); #endif /* Count how many object files there are in the loop */ @@ -991,6 +1043,7 @@ static int dl_loadcoff(struct DLHandle *ret, #ifdef DLDEBUG fprintf(stderr,"dl_loadcoff\n"); + FLUSH(); #endif tmp.buflen=data->buflen; @@ -1012,6 +1065,7 @@ static int dl_load_file(struct DLHandle *ret, INT32 tmp; #ifdef DLDEBUG fprintf(stderr,"dl_load_file\n"); + FLUSH(); #endif if(data->buflen > 8 && ! memcmp(data->buffer,"!<arch>\n",8)) @@ -1033,12 +1087,11 @@ struct DLHandle *dlopen(char *name, int flags) int retcode; tmpdata.flags=flags; - if(!global_symbols) init_dlopen(); - #ifdef DLDEBUG fprintf(stderr,"dlopen(%s,%d)\n",name,flags); #endif - abort(); + + if(!global_symbols) init_dlopen(); for(ret=first;ret;ret=ret->next) { @@ -1065,7 +1118,6 @@ struct DLHandle *dlopen(char *name, int flags) dlclose(ret); return 0; } - retcode=dl_load_file(ret, &tmpdata); free(tmpdata.buffer); @@ -1244,6 +1296,10 @@ static void init_dlopen(void) EXPORT(abort); EXPORT(rand); EXPORT(srand); + EXPORT(getc); + EXPORT(ungetc); + EXPORT(printf); + EXPORT(perror); } #ifdef DLDEBUG