1 #include <../../nrnconf.h> 14 #define __attribute__(arg) 19 #if defined(__MWERKS__)|| defined(_MSC_VER) 29 #if defined(nrnCYGWIN) 31 extern FILE __files[];
32 int _flsbuf(
unsigned i, FILE* f) {
33 printf(
"\n_flsbuf i=%d\n", i);
40 char*
p =
new char[strlen(s) + 1];
45 #if defined(__MWERKS__) && !defined(_MSC_VER) 51 extern int flsbuf(
unsigned, FILE*);
52 int _flsbuf(
unsigned i, FILE* f) {
53 printf(
"\n_flsbuf i=%d\n", i);
61 #define PRDEBUG printf( 64 #if defined(PRDEBUGFILE) 66 #define PRDEBUG fprintf(prdebug_, 67 static FILE* prdebug_;
81 void add(
char *name,
void *value);
82 void *
get(
char *
name);
83 static void *
lookup(
char *name);
111 name = (
char **)malloc(
max*
sizeof(
char *));
112 value = (
void **)malloc(
max*
sizeof(
void *));
118 for (i=0; i<
num; i++)
135 name = (
char **)realloc(
name,
max *
sizeof(
char *));
146 for (i=0; i<
num; i++)
147 if (strcmp(Pname,
name[i]) == 0)
157 void *
v = s->
get(Pname);
199 if (local_symtab == 0)
200 local_symtab =
new Symtab;
201 if (common_symtab == 0)
202 common_symtab =
new Symtab;
203 local_symtab->
add(Psymbol, Paddress);
204 local_symtab->
get(Psymbol);
217 #define MKDLL(a,b) extern void b(); 218 #define DFMKDLL(a,b) extern double b(); 219 #define DFMKDLL1(a,b) 220 #define DFMKDLL2(a,b) 221 #define DMKDLL(a,b) extern double b; 222 #define IMKDLL(a,b) extern int b; 223 #define MKDLLdec(a,b) 224 #define MKDLLvpf(a,b) extern void* b(); 225 #define MKDLLvp(a,b) extern void* b; 226 #define MKDLLif(a,b) extern int b(); 258 #define MKDLL(a,b) dll_register(a, (void*)b); 259 #define DFMKDLL(a,b) dll_register(a, (void*)b); 260 #define DFMKDLL1(a,b) dll_registerdf1(a, b); 261 #define DFMKDLL2(a,b) dll_registerdf2(a, b); 262 #define DMKDLL(a,b) dll_register(a, (void*)(&b)); 263 #define IMKDLL(a,b) DMKDLL(a,b) 264 #define MKDLLdec(a,b) MKDLL(a, b) 265 #define MKDLLvpf(a,b) MKDLL(a,b) 266 #define MKDLLif(a,b) MKDLL(a,b) 267 #define MKDLLvp(a,b) DMKDLL(a,b) 290 if (strpbrk(fn,
":\\/"))
294 if (access(fn,0) == 0)
301 for (bp=buf; *bp; bp++)
302 if (strchr(
":\\/", *bp))
306 if (access(buf, 0) == 0)
314 while (*bp && *bp !=
';')
319 if (access(buf, 0) == 0)
332 #if defined(PRDEBUGFILE) 333 prdebug_ =
fopen(PRDEBUGFILE,
"wb");
339 for (dll=dll_s::top; dll; dll=dll->
next)
340 if (strcmp(dll->
loadpath, filename) == 0)
346 #if defined(PRDEBUGFILE) 362 PRDEBUG "load: `%s'\n", loadpath);
364 FILE *file =
fopen(loadpath,
"rb");
367 printf(
"Error: unable to load %s\n", filename);
368 perror(
"The error was");
387 fread(&filhdr, 1,
FILHSZ, file);
389 PRDEBUG "file: %s, magic=%#x\n", filename, filhdr.f_magic);
391 if (filhdr.f_magic != 0x14c)
393 fprintf(stderr,
"Not a COFF file\n");
397 PRDEBUG "nscns=%d, nsyms=%d, symptr=%#x\n", filhdr.f_nscns, filhdr.f_nsyms,
400 for (i=0;
flags[
i].val; i++)
401 if (filhdr.f_flags &
flags[i].val)
407 fseek(file, filhdr.f_opthdr, 1);
410 section =
new SCNHDR[filhdr.f_nscns];
412 #if defined(__MWERKS__) || defined(nrnCYGWIN) 413 for (i=0; i < filhdr.f_nscns; ++
i) {
414 fread(section+i, 1,
SCNHSZ, file);
416 PRDEBUG "%8s paddr %x vaddr %x size %x scnptr %x relptr %x lnnoptr %x nreloc %x nlnno %x flags %x\n",
417 section[
i].s_name, section[
i].s_paddr, section[
i].s_vaddr, section[
i].s_size,
418 section[
i].s_scnptr, section[
i].s_relptr, section[
i].s_lnnoptr,
419 section[
i].s_nreloc, section[
i].s_nlnno, section[
i].s_flags);
423 fread(section,
sizeof(
SCNHDR), filhdr.f_nscns, file);
426 for (s=0; s<filhdr.f_nscns; s++) {
428 if (max_bytes < section[s].s_vaddr + section[s].s_size + section[s].s_paddr)
429 max_bytes = section[
s].s_vaddr + section[
s].s_size + section[
s].s_paddr;
431 if (max_bytes < section[s].s_vaddr + section[s].s_size)
432 max_bytes = section[
s].s_vaddr + section[
s].s_size;
436 dll->
bytes =
new char[max_bytes];
444 for (i=0; i < max_bytes; ++
i) {dll->
bytes[
i] = 0;}
446 for (s=0; s<filhdr.f_nscns; s++)
448 if (section[s].s_scnptr)
451 PRDEBUG "section %d from file at 0x%x size 0x%x\n",
452 s, dll->
bytes + section[
s].s_vaddr, section[
s].s_size);
454 if (section[s].s_size)
456 fseek(file, section[s].s_scnptr, 0);
457 fread(dll->
bytes+section[s].s_vaddr, 1, section[s].s_size, file);
464 PRDEBUG "section %d zeroed 0x%x bytes at 0x%x\n",
s, section[
s].s_paddr, dll->
bytes+section[
s].s_vaddr);
465 PRDEBUG "if not CYGWIN then we would\n");
466 PRDEBUG "section %d zeroed %d bytes at 0x%x\n",
s, section[
s].s_size, dll->
bytes+section[
s].s_vaddr);
468 if (section[s].s_paddr)
469 memset(dll->
bytes+section[s].s_vaddr, 0, section[s].s_paddr);
473 PRDEBUG "section %d zeroed %d bytes at 0x%x\n",
s, section[
s].s_size, dll->
bytes+section[
s].s_vaddr);
475 if (section[s].s_size)
476 memset(dll->
bytes+section[s].s_vaddr, 0, section[s].s_size);
482 unsigned long *symaddr =
new unsigned long [filhdr.f_nsyms];
483 fseek(file, filhdr.f_symptr, 0);
485 #if defined(__MWERKS__) || defined(nrnCYGWIN) 486 for (
i=0;
i < filhdr.f_nsyms; ++
i) {
487 fread(syment+
i, 1,
SYMESZ, file);
490 fread(syment, filhdr.f_nsyms,
SYMESZ, file);
492 unsigned long strsize = 4;
493 fread(&strsize, 1,
sizeof(
unsigned long), file);
495 char *strings =
new char[strsize];
498 fread(strings+4, strsize-4, 1, file);
500 for (
i=0;
i<filhdr.f_nsyms;
i++)
502 char snameb[9], *sname, *scname;
504 PRDEBUG "[0x%08x] ", syment[
i].e_value);
506 if (syment[
i].
e.e.e_zeroes)
508 sprintf(snameb,
"%.8s", syment[i].
e.e_name);
512 sname = strings + syment[
i].e.e.e_offset;
514 if (syment[i].e_scnum > 0)
516 symaddr[
i] = syment[
i].e_value + (
long)(dll->bytes);
518 symaddr[
i] += section[syment[
i].e_scnum-1].s_vaddr;
520 if (syment[i].e_sclass == 2)
521 dll->symtab.add(sname, (
void *)symaddr[i]);
522 if (strcmp(sname,
"_dll_unloadfunc") == 0)
523 dll->uninit_func = (
CDTOR)symaddr[i];
524 if (strcmp(sname,
"_dll_loadfunc") == 0)
525 init_func = (
CDTOR)symaddr[
i];
527 else if (syment[i].e_scnum ==
N_UNDEF)
529 if (syment[i].e_value)
531 void *stv = common_symtab->
get(sname);
533 symaddr[
i] = (
long)stv;
536 stv = calloc(syment[i].e_value,1);
537 common_symtab->
add(sname, stv);
538 symaddr[
i] = (
long)stv;
546 fprintf(stderr,
"Undefined symbol %s referenced from %s\n",
554 if (syment[i].e_scnum >= 1)
555 scname = section[syment[
i].e_scnum-1].s_name;
558 PRDEBUG "[%2d] 0x%08x %2d %-8.8s %04x %02x %d %s\n",
i,
566 for (
int a=0; a<syment[
i].e_numaux; a++)
570 unsigned char *ap = (
unsigned char *)(syment+i);
572 for (
int b=0; b<
SYMESZ; b++)
573 printf(
" %02x\033[32m%c\033[37m", ap[b], ap[b]>
' '?ap[b]:
' ');
578 i += syment[
i].e_numaux;
582 for (
s=0;
s<filhdr.f_nscns;
s++)
585 PRDEBUG "\nS[%d] `%-8s' pa=%#x va=%#x s=%#x ptr=%#x\n",
586 s, section[
s].s_name, section[
s].s_paddr,section[
s].s_vaddr,
587 section[
s].s_size, section[
s].s_scnptr);
588 PRDEBUG " rel=%#x nrel=%#x flags: ",
589 section[
s].s_relptr, section[
s].s_nreloc);
596 if (section[s].s_nreloc)
598 fseek(file, section[s].s_relptr, 0);
601 #if defined(__MWERKS__) || defined(nrnCYGWIN) 602 for (
i=0;
i < section[
s].s_nreloc; ++
i) {
603 fread(r+
i, 1,
RELSZ, file);
606 fread(r,
RELSZ, section[s].s_nreloc, file);
608 for (
i=0;
i<section[
s].s_nreloc;
i++)
610 long *ptr = (
long *)(dll->bytes + r[
i].r_vaddr);
611 long old_value = *ptr;
613 PRDEBUG " [%02d] 0x%08x(0x%08x) %2d 0x%04x 0%02o (was 0x%08x",
614 i, r[
i].r_vaddr, ptr, r[
i].r_symndx, r[
i].r_type, r[
i].r_type, old_value);
620 old_value -= syment[r[
i].r_symndx].e_value;
622 old_value += symaddr[r[
i].r_symndx];
625 if (syment[r[i].r_symndx].e_scnum == 0 || 1)
627 #if !CYGWIN // old coff format from gcc2.7.2 days 628 old_value -= (
long)(dll->bytes);
629 #else // new pe-coff format from gcc2.95.2 630 old_value = -(
long)ptr - 4;
632 old_value += symaddr[r[
i].r_symndx];
636 fprintf(stderr,
"Error: unexpected relocation type %#x\n",
642 PRDEBUG ", now 0x%08x)\n", old_value);
643 if (r[i].r_type == 0x14) {
644 PRDEBUG "pc(0x%08x) + 4 + offset(0x%08x) = external address(0x%08x)\n", (
long)ptr, (
long)*ptr,
645 (
long)*ptr+(
long)ptr+4);
646 PRDEBUG "index %2d address 0x%08x\n", r[
i].r_symndx, symaddr[r[
i].r_symndx]);
648 if (r[i].r_type == 0x06) {
649 PRDEBUG "e_value=0x%08x\n", syment[r[
i].r_symndx].e_value);
656 for (
s=0;
s<filhdr.f_nscns;
s++)
658 if (strcmp(section[
s].s_name,
".ctor") == 0)
660 for (
i=0;
i<section[
s].s_size/4;
i++)
663 void **fv = (
void **)(dll->bytes+section[
s].s_vaddr);
668 if (strcmp(section[
s].s_name,
".dtor") == 0)
670 dll->dtor_section = dll->bytes + section[
s].s_vaddr;
671 dll->dtor_count = section[
s].s_size/4;
685 for (
i=0;
i < max_bytes; ++
i) {
686 if ((
long)(dll->bytes +
i)%8 == 0) {
689 PRDEBUG " %02x", dll->bytes[
i]&0xff);
697 return (
struct DLL *)dll;
726 dll_s::top = dll->
next;
struct DLL * dll_load(char *filename)
char * find_file(char *fn)
void dll_init(char *argv0)
static Symtab * common_symtab
static void dll_registerdf1(char *Psymbol, double(*Paddress)(double))
sprintf(buf," if (secondorder) {\ " int _i;\" " for(_i=0;_i< %d;++_i) {\" " _p[_slist%d[_i]]+=dt *_p[_dlist%d[_i]];\" " }}\", numeqn, listnum, listnum)
static Symtab * local_symtab
static struct @33 sflags[]
char * getenv(const char *s)
static void dll_registerdf2(char *Psymbol, double(*Paddress)(double, double))
fprintf(stderr, "Don't know the location of params at %p\, pp)
void * dll_lookup(struct DLL *Pdll, char *name)
void add(char *name, void *value)
static void dll_exitfunc(void)
struct DLL * dll_force_load(char *filename)
static void * lookup(char *name)
#define error(err_num, fn_name)
static struct @32 flags[]
char * dllstrdup(const char *s)
void dll_unload(struct DLL *Pdll)
void dll_register(char *Psymbol, void *Paddress)