PageRenderTime 53ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/src/mswin/windll/dll.cpp

https://bitbucket.org/nrnhines/nrn
C++ | 737 lines | 659 code | 56 blank | 22 comment | 115 complexity | ab6949bd1eb5863a0c0b887acbf9e316 MD5 | raw file
Possible License(s): BSD-3-Clause, GPL-2.0
  1. #include <../../nrnconf.h>
  2. #if defined(CYGWIN)
  3. #define nrnCYGWIN
  4. #endif
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <errno.h>
  9. #include <setjmp.h>
  10. #include <math.h>
  11. #include <io.h>
  12. #include <assert.h>
  13. #define __attribute__(arg) /**/
  14. #include "coff.h"
  15. #undef CYGWIN
  16. #define CYGWIN 1
  17. #if defined(__MWERKS__)|| defined(_MSC_VER)
  18. #undef SYMESZ
  19. #define SYMESZ 18
  20. #undef RELSZ
  21. #define RELSZ 10
  22. #endif
  23. #include "limits.h"
  24. #include "dll.h"
  25. #if defined(nrnCYGWIN)
  26. extern "C" {
  27. extern FILE __files[]; // declared in mswinprt.c. FILE* __files does not work here.
  28. int _flsbuf(unsigned i, FILE* f) {
  29. printf("\n_flsbuf i=%d\n", i);
  30. return i;
  31. }
  32. }
  33. #endif
  34. char* dllstrdup(const char* s) {
  35. char* p = new char[strlen(s) + 1];
  36. strcpy(p, s);
  37. return p;
  38. }
  39. #if defined(__MWERKS__) && !defined(_MSC_VER)
  40. extern "C" {
  41. #if __MWERKS__ >= 7
  42. FILE __files[]; // would be from file_struc.h except for RC_INVOKED
  43. #endif
  44. extern int flsbuf(unsigned, FILE*);
  45. int _flsbuf(unsigned i, FILE* f) {
  46. printf("\n_flsbuf i=%d\n", i);
  47. return i;
  48. }
  49. }
  50. #endif
  51. #define PRINT 0
  52. #define PRDEBUG printf(
  53. //#define PRDEBUGFILE "c:/temp.tmp"
  54. #if defined(PRDEBUGFILE)
  55. #undef PRDEBUG
  56. #define PRDEBUG fprintf(prdebug_,
  57. static FILE* prdebug_;
  58. #endif
  59. typedef void (*CDTOR)();
  60. struct Symtab {
  61. Symtab *next, *prev;
  62. static Symtab *symtabs;
  63. char **name;
  64. void **value;
  65. int num;
  66. int max;
  67. Symtab();
  68. ~Symtab();
  69. void add(char *name, void *value);
  70. void *get(char *name);
  71. static void *lookup(char *name);
  72. };
  73. struct dll_s {
  74. dll_s *next, *prev;
  75. char *loadpath;
  76. int valid;
  77. static dll_s *top;
  78. int load_count;
  79. int num_sections;
  80. char *bytes;
  81. char *dtor_section;
  82. int dtor_count;
  83. Symtab symtab;
  84. CDTOR uninit_func;
  85. };
  86. dll_s *dll_s::top = 0;
  87. Symtab *Symtab::symtabs = 0;
  88. Symtab::Symtab()
  89. {
  90. next = symtabs;
  91. prev = 0;
  92. symtabs = this;
  93. num = 0;
  94. max = 10;
  95. name = (char **)malloc(max*sizeof(char *));
  96. value = (void **)malloc(max*sizeof(void *));
  97. }
  98. Symtab::~Symtab()
  99. {
  100. int i;
  101. for (i=0; i<num; i++)
  102. free(name[i]);
  103. free(name);
  104. free(value);
  105. if (next)
  106. next->prev = prev;
  107. if (prev)
  108. prev->next = next;
  109. else
  110. symtabs = next;
  111. }
  112. void Symtab::add(char *Pname, void *Pvalue)
  113. {
  114. if (num >= max)
  115. {
  116. max += 10;
  117. name = (char **)realloc(name, max * sizeof(char *));
  118. value = (void **)realloc(value, max * sizeof(void *));
  119. }
  120. name[num] = dllstrdup(Pname);
  121. value[num] = Pvalue;
  122. num++;
  123. }
  124. void *Symtab::get(char *Pname)
  125. {
  126. int i;
  127. for (i=0; i<num; i++)
  128. if (strcmp(Pname, name[i]) == 0)
  129. return value[i];
  130. return 0;
  131. }
  132. void *Symtab::lookup(char *Pname)
  133. {
  134. Symtab *s;
  135. for (s=symtabs; s; s=s->next)
  136. {
  137. void *v = s->get(Pname);
  138. if (v)
  139. {
  140. return v;
  141. }
  142. }
  143. return 0;
  144. }
  145. static struct {
  146. int val;
  147. char *name;
  148. } flags[] = {
  149. F_RELFLG, "REL",
  150. F_EXEC, "EXEC",
  151. F_LNNO, "LNNO",
  152. F_LSYMS, "LSYMS",
  153. 0, 0
  154. };
  155. static struct {
  156. int val;
  157. char *name;
  158. } sflags[] = {
  159. STYP_TEXT, "text",
  160. STYP_DATA, "data",
  161. STYP_BSS, "bss",
  162. 0, 0
  163. };
  164. static char *dll_argv0 = 0;
  165. static Symtab *local_symtab = 0;
  166. static Symtab *common_symtab = 0;
  167. static void dll_exitfunc(void)
  168. {
  169. while (dll_s::top)
  170. dll_unload((struct DLL *)dll_s::top);
  171. }
  172. void dll_register(char *Psymbol, void *Paddress)
  173. {
  174. if (local_symtab == 0)
  175. local_symtab = new Symtab;
  176. if (common_symtab == 0)
  177. common_symtab = new Symtab;
  178. local_symtab->add(Psymbol, Paddress);
  179. local_symtab->get(Psymbol);
  180. }
  181. // following works around the c++ overloading of math functions
  182. // eg. want sin(double) not sin(float)
  183. static void dll_registerdf1(char* Psymbol, double(*Paddress)(double)) {
  184. dll_register(Psymbol, (void*)Paddress);
  185. }
  186. static void dll_registerdf2(char* Psymbol, double(*Paddress)(double, double)) {
  187. dll_register(Psymbol, (void*)Paddress);
  188. }
  189. #define MKDLL(a,b) extern void b();
  190. #define DFMKDLL(a,b) extern double b();
  191. #define DFMKDLL1(a,b) /**/
  192. #define DFMKDLL2(a,b) /**/
  193. #define DMKDLL(a,b) extern double b;
  194. #define IMKDLL(a,b) extern int b;
  195. #define MKDLLdec(a,b) /**/
  196. #define MKDLLvpf(a,b) extern void* b();
  197. #define MKDLLvp(a,b) extern void* b;
  198. #define MKDLLif(a,b) extern int b();
  199. extern "C" {
  200. #include "nrnmath.h"
  201. #include "nrnmech.h"
  202. #if OCMATRIX
  203. #include "ocmatdll.h"
  204. #endif
  205. }
  206. #undef MKDLL
  207. #undef DFMKDLL
  208. #undef DFMKDLL1
  209. #undef DFMKDLL2
  210. #undef DMKDLL
  211. #undef IMKDLL
  212. #undef MKDLLdec
  213. #undef MKDLLvpf
  214. #undef MKDLLvp
  215. #undef MKDLLif
  216. void dll_init(char *argv0)
  217. {
  218. // this was causing an unhandled exception on
  219. // exit on one machine. I don't believe, but
  220. // am not certain, that it is any longer necessary
  221. //atexit(dll_exitfunc);
  222. if (dll_argv0)
  223. free(dll_argv0);
  224. else
  225. {
  226. dll_register("_dll_load", (void*)dll_load);
  227. dll_register("_dll_unload", (void*)dll_unload);
  228. dll_register("_dll_lookup", (void*)dll_lookup);
  229. #define MKDLL(a,b) dll_register(a, (void*)b);
  230. #define DFMKDLL(a,b) dll_register(a, (void*)b);
  231. #define DFMKDLL1(a,b) dll_registerdf1(a, b);
  232. #define DFMKDLL2(a,b) dll_registerdf2(a, b);
  233. #define DMKDLL(a,b) dll_register(a, (void*)(&b));
  234. #define IMKDLL(a,b) DMKDLL(a,b)
  235. #define MKDLLdec(a,b) MKDLL(a, b)
  236. #define MKDLLvpf(a,b) MKDLL(a,b)
  237. #define MKDLLif(a,b) MKDLL(a,b)
  238. #define MKDLLvp(a,b) DMKDLL(a,b)
  239. #include "nrnmath.h"
  240. #include "nrnmech.h"
  241. #if OCMATRIX
  242. #include "ocmatdll.h"
  243. #endif
  244. #undef MKDLL
  245. #undef DFMKDLL
  246. #undef DMKDLL
  247. #undef IMKDLL
  248. #undef MKDLLdec
  249. #undef MKDLLvpf
  250. #undef MKDLLif
  251. }
  252. dll_argv0 = dllstrdup(argv0);
  253. }
  254. char *find_file(char *fn)
  255. {
  256. #if 0
  257. char *bp, *ep, *pp;
  258. static char buf[PATH_MAX];
  259. if (strpbrk(fn, ":\\/"))
  260. return fn;
  261. // printf("find: try `%s'\n", fn);
  262. if (access(fn,0) == 0)
  263. return fn;
  264. if (dll_argv0)
  265. {
  266. strcpy(buf, dll_argv0);
  267. ep = buf;
  268. for (bp=buf; *bp; bp++)
  269. if (strchr(":\\/", *bp))
  270. ep = bp+1;
  271. strcpy(ep, fn);
  272. // printf("find: try `%s'\n", buf);
  273. if (access(buf, 0) == 0)
  274. return buf;
  275. }
  276. bp = getenv("PATH");
  277. while (*bp)
  278. {
  279. pp = buf;
  280. while (*bp && *bp != ';')
  281. *pp++ = *bp++;
  282. *pp++ = '/';
  283. strcpy(pp, fn);
  284. // printf("find: try `%s'\n", buf);
  285. if (access(buf, 0) == 0)
  286. return buf;
  287. if (*bp == 0)
  288. break;
  289. bp++;
  290. }
  291. // printf("find: default `%s'\n", fn);
  292. #endif
  293. return fn;
  294. }
  295. struct DLL *dll_load(char *filename)
  296. {
  297. #if defined(PRDEBUGFILE)
  298. prdebug_ = fopen(PRDEBUGFILE, "wb");
  299. #endif
  300. if (dll_argv0 == 0)
  301. dll_init("");
  302. dll_s *dll;
  303. for (dll=dll_s::top; dll; dll=dll->next)
  304. if (strcmp(dll->loadpath, filename) == 0)
  305. {
  306. dll->load_count ++;
  307. return (DLL *)dll;
  308. }
  309. DLL* d = dll_force_load(filename);
  310. #if defined(PRDEBUGFILE)
  311. fclose(prdebug_);
  312. #endif
  313. return d;
  314. }
  315. struct DLL *dll_force_load(char *filename)
  316. {
  317. int i, s;
  318. int error = 0;
  319. int max_bytes = 0;
  320. dll_s *dll;
  321. char *loadpath = find_file(filename);
  322. #if PRINT
  323. PRDEBUG "load: `%s'\n", loadpath);
  324. #endif
  325. FILE *file = fopen(loadpath, "rb");
  326. if (file == 0)
  327. {
  328. printf("Error: unable to load %s\n", filename);
  329. perror("The error was");
  330. return 0;
  331. }
  332. dll = new dll_s;
  333. dll->valid = 0;
  334. dll->loadpath = dllstrdup(filename);
  335. dll->num_sections = 0;
  336. dll->next = dll_s::top;
  337. if (dll->next)
  338. dll->next->prev = dll;
  339. dll_s::top = dll;
  340. dll->prev = 0;
  341. dll->load_count = 1;
  342. dll->dtor_count = 0;
  343. dll->uninit_func = 0;
  344. CDTOR init_func = 0;
  345. FILHDR filhdr;
  346. fread(&filhdr, 1, FILHSZ, file);
  347. #if PRINT
  348. PRDEBUG "file: %s, magic=%#x\n", filename, filhdr.f_magic);
  349. #endif
  350. if (filhdr.f_magic != 0x14c)
  351. {
  352. fprintf(stderr, "Not a COFF file\n");
  353. return 0;
  354. }
  355. #if PRINT
  356. PRDEBUG "nscns=%d, nsyms=%d, symptr=%#x\n", filhdr.f_nscns, filhdr.f_nsyms,
  357. filhdr.f_symptr);
  358. PRDEBUG "flags: ");
  359. for (i=0; flags[i].val; i++)
  360. if (filhdr.f_flags & flags[i].val)
  361. PRDEBUG " %s", flags[i].name);
  362. PRDEBUG "\n");
  363. #endif
  364. if (filhdr.f_opthdr)
  365. fseek(file, filhdr.f_opthdr, 1);
  366. SCNHDR *section;
  367. section = new SCNHDR[filhdr.f_nscns];
  368. dll->num_sections = filhdr.f_nscns;
  369. #if defined(__MWERKS__) || defined(nrnCYGWIN)
  370. for (i=0; i < filhdr.f_nscns; ++i) {
  371. fread(section+i, 1, SCNHSZ, file);
  372. #if PRINT == 2
  373. PRDEBUG "%8s paddr %x vaddr %x size %x scnptr %x relptr %x lnnoptr %x nreloc %x nlnno %x flags %x\n",
  374. section[i].s_name, section[i].s_paddr, section[i].s_vaddr, section[i].s_size,
  375. section[i].s_scnptr, section[i].s_relptr, section[i].s_lnnoptr,
  376. section[i].s_nreloc, section[i].s_nlnno, section[i].s_flags);
  377. #endif
  378. }
  379. #else
  380. fread(section, sizeof(SCNHDR), filhdr.f_nscns, file);
  381. #endif
  382. max_bytes = 0;
  383. for (s=0; s<filhdr.f_nscns; s++) {
  384. #if CYGWIN
  385. if (max_bytes < section[s].s_vaddr + section[s].s_size + section[s].s_paddr)
  386. max_bytes = section[s].s_vaddr + section[s].s_size + section[s].s_paddr;
  387. #else
  388. if (max_bytes < section[s].s_vaddr + section[s].s_size)
  389. max_bytes = section[s].s_vaddr + section[s].s_size;
  390. #endif
  391. }
  392. dll->bytes = new char[max_bytes];
  393. // there was a problem with the hoc_scdoub and hoc_vdoub terminator 0's not
  394. // being set to 0 in all cases. Perhaps cygwin has changed its section zeroing
  395. // policy and s_size is back in favor at s_paddr expense. Anyway, the
  396. // following at least starts us out with a zero array and the segmentation
  397. // violation seen occasionally with NEURONMainMenu/File/WorkingDir
  398. // no longer occurs. See the next #if CYGWIN for my earlier hack which
  399. // may be obsolete.
  400. for (i=0; i < max_bytes; ++i) {dll->bytes[i] = 0;}
  401. for (s=0; s<filhdr.f_nscns; s++)
  402. {
  403. if (section[s].s_scnptr)
  404. {
  405. #if PRINT
  406. PRDEBUG "section %d from file at 0x%x size 0x%x\n",
  407. s, dll->bytes + section[s].s_vaddr, section[s].s_size);
  408. #endif
  409. if (section[s].s_size)
  410. {
  411. fseek(file, section[s].s_scnptr, 0);
  412. fread(dll->bytes+section[s].s_vaddr, 1, section[s].s_size, file);
  413. }
  414. }
  415. else
  416. {
  417. #if CYGWIN
  418. #if PRINT
  419. PRDEBUG "section %d zeroed 0x%x bytes at 0x%x\n", s, section[s].s_paddr, dll->bytes+section[s].s_vaddr);
  420. PRDEBUG "if not CYGWIN then we would\n");
  421. PRDEBUG "section %d zeroed %d bytes at 0x%x\n", s, section[s].s_size, dll->bytes+section[s].s_vaddr);
  422. #endif
  423. if (section[s].s_paddr)
  424. memset(dll->bytes+section[s].s_vaddr, 0, section[s].s_paddr);
  425. }
  426. #else
  427. #if PRINT
  428. PRDEBUG "section %d zeroed %d bytes at 0x%x\n", s, section[s].s_size, dll->bytes+section[s].s_vaddr);
  429. #endif
  430. if (section[s].s_size)
  431. memset(dll->bytes+section[s].s_vaddr, 0, section[s].s_size);
  432. }
  433. #endif
  434. }
  435. SYMENT *syment = new SYMENT[filhdr.f_nsyms];
  436. unsigned long *symaddr = new unsigned long [filhdr.f_nsyms];
  437. fseek(file, filhdr.f_symptr, 0);
  438. //printf("SYMESZ=%d\n", SYMESZ);
  439. #if defined(__MWERKS__) || defined(nrnCYGWIN)
  440. for (i=0; i < filhdr.f_nsyms; ++i) {
  441. fread(syment+i, 1, SYMESZ, file);
  442. }
  443. #else
  444. fread(syment, filhdr.f_nsyms, SYMESZ, file);
  445. #endif
  446. unsigned long strsize = 4;
  447. fread(&strsize, 1, sizeof(unsigned long), file);
  448. //printf("strsize=%ld\n", strsize);
  449. char *strings = new char[strsize];
  450. strings[0] = 0;
  451. if (strsize > 4)
  452. fread(strings+4, strsize-4, 1, file);
  453. for (i=0; i<filhdr.f_nsyms; i++)
  454. {
  455. char snameb[9], *sname, *scname;
  456. #if PRINT
  457. PRDEBUG "[0x%08x] ", syment[i].e_value);
  458. #endif
  459. if (syment[i].e.e.e_zeroes)
  460. {
  461. sprintf(snameb, "%.8s", syment[i].e.e_name);
  462. sname = snameb;
  463. }
  464. else
  465. sname = strings + syment[i].e.e.e_offset;
  466. if (syment[i].e_scnum > 0)
  467. {
  468. symaddr[i] = syment[i].e_value + (long)(dll->bytes);
  469. #if CYGWIN
  470. symaddr[i] += section[syment[i].e_scnum-1].s_vaddr;
  471. #endif
  472. if (syment[i].e_sclass == 2)
  473. dll->symtab.add(sname, (void *)symaddr[i]);
  474. if (strcmp(sname, "_dll_unloadfunc") == 0)
  475. dll->uninit_func = (CDTOR)symaddr[i];
  476. if (strcmp(sname, "_dll_loadfunc") == 0)
  477. init_func = (CDTOR)symaddr[i];
  478. }
  479. else if (syment[i].e_scnum == N_UNDEF)
  480. {
  481. if (syment[i].e_value)
  482. {
  483. void *stv = common_symtab->get(sname);
  484. if (stv)
  485. symaddr[i] = (long)stv;
  486. else
  487. {
  488. stv = calloc(syment[i].e_value,1);
  489. common_symtab->add(sname, stv);
  490. symaddr[i] = (long)stv;
  491. }
  492. }
  493. else
  494. {
  495. symaddr[i] = (long)Symtab::lookup(sname);
  496. if (symaddr[i] == 0)
  497. {
  498. fprintf(stderr, "Undefined symbol %s referenced from %s\n",
  499. sname, filename);
  500. error = 1;
  501. }
  502. }
  503. }
  504. #if PRINT
  505. if (syment[i].e_scnum >= 1)
  506. scname = section[syment[i].e_scnum-1].s_name;
  507. else
  508. scname = "N/A";
  509. PRDEBUG "[%2d] 0x%08x %2d %-8.8s %04x %02x %d %s\n", i,
  510. symaddr[i],
  511. syment[i].e_scnum,
  512. scname,
  513. syment[i].e_type,
  514. syment[i].e_sclass,
  515. syment[i].e_numaux,
  516. sname);
  517. for (int a=0; a<syment[i].e_numaux; a++)
  518. {
  519. i++;
  520. #if 0
  521. unsigned char *ap = (unsigned char *)(syment+i);
  522. printf("\033[0m");
  523. for (int b=0; b<SYMESZ; b++)
  524. printf(" %02x\033[32m%c\033[37m", ap[b], ap[b]>' '?ap[b]:' ');
  525. printf("\033[1m\n");
  526. #endif
  527. }
  528. #else
  529. i += syment[i].e_numaux;
  530. #endif
  531. }
  532. for (s=0; s<filhdr.f_nscns; s++)
  533. {
  534. #if PRINT
  535. PRDEBUG "\nS[%d] `%-8s' pa=%#x va=%#x s=%#x ptr=%#x\n",
  536. s, section[s].s_name, section[s].s_paddr,section[s].s_vaddr,
  537. section[s].s_size, section[s].s_scnptr);
  538. PRDEBUG " rel=%#x nrel=%#x flags: ",
  539. section[s].s_relptr, section[s].s_nreloc);
  540. for (i=0; sflags[i].val; i++)
  541. if (section[s].s_flags & sflags[i].val)
  542. PRDEBUG " %s", sflags[i].name);
  543. PRDEBUG "\n");
  544. #endif
  545. if (section[s].s_nreloc)
  546. {
  547. fseek(file, section[s].s_relptr, 0);
  548. //printf("RELSZ=%d\n", RELSZ);
  549. RELOC *r = new RELOC[section[s].s_nreloc];
  550. #if defined(__MWERKS__) || defined(nrnCYGWIN)
  551. for (i=0; i < section[s].s_nreloc; ++i) {
  552. fread(r+i, 1, RELSZ, file);
  553. }
  554. #else
  555. fread(r, RELSZ, section[s].s_nreloc, file);
  556. #endif
  557. for (i=0; i<section[s].s_nreloc; i++)
  558. {
  559. long *ptr = (long *)(dll->bytes + r[i].r_vaddr);
  560. long old_value = *ptr;
  561. #if PRINT
  562. PRDEBUG " [%02d] 0x%08x(0x%08x) %2d 0x%04x 0%02o (was 0x%08x",
  563. i, r[i].r_vaddr, ptr, r[i].r_symndx, r[i].r_type, r[i].r_type, old_value);
  564. #endif
  565. switch (r[i].r_type)
  566. {
  567. case 0x06:
  568. #if !CYGWIN
  569. old_value -= syment[r[i].r_symndx].e_value;
  570. #endif
  571. old_value += symaddr[r[i].r_symndx];
  572. break;
  573. case 0x14:
  574. if (syment[r[i].r_symndx].e_scnum == 0 || 1)
  575. {
  576. #if !CYGWIN // old coff format from gcc2.7.2 days
  577. old_value -= (long)(dll->bytes);
  578. #else // new pe-coff format from gcc2.95.2
  579. old_value = -(long)ptr - 4;
  580. #endif
  581. old_value += symaddr[r[i].r_symndx];
  582. }
  583. break;
  584. default:
  585. fprintf(stderr, "Error: unexpected relocation type %#x\n",
  586. r[i].r_type);
  587. error = 1;
  588. }
  589. *ptr = old_value;
  590. #if PRINT
  591. PRDEBUG ", now 0x%08x)\n", old_value);
  592. if (r[i].r_type == 0x14) {
  593. PRDEBUG "pc(0x%08x) + 4 + offset(0x%08x) = external address(0x%08x)\n", (long)ptr, (long)*ptr,
  594. (long)*ptr+(long)ptr+4);
  595. PRDEBUG "index %2d address 0x%08x\n", r[i].r_symndx, symaddr[r[i].r_symndx]);
  596. }
  597. if (r[i].r_type == 0x06) {
  598. PRDEBUG "e_value=0x%08x\n", syment[r[i].r_symndx].e_value);
  599. }
  600. #endif
  601. }
  602. delete [] r;
  603. }
  604. }
  605. for (s=0; s<filhdr.f_nscns; s++)
  606. {
  607. if (strcmp(section[s].s_name, ".ctor") == 0)
  608. {
  609. for (i=0; i<section[s].s_size/4; i++)
  610. {
  611. CDTOR f;
  612. void **fv = (void **)(dll->bytes+section[s].s_vaddr);
  613. f = (CDTOR)(fv[i]);
  614. f();
  615. }
  616. }
  617. if (strcmp(section[s].s_name, ".dtor") == 0)
  618. {
  619. dll->dtor_section = dll->bytes + section[s].s_vaddr;
  620. dll->dtor_count = section[s].s_size/4;
  621. }
  622. }
  623. if (init_func)
  624. init_func();
  625. dll->valid = 1;
  626. fclose(file);
  627. delete [] syment;
  628. delete [] symaddr;
  629. delete [] strings;
  630. delete [] section;
  631. #if (PRINT == 2)
  632. for (i=0; i < max_bytes; ++i) {
  633. if ((long)(dll->bytes + i)%8 == 0) {
  634. PRDEBUG "\n%08x ", (long)(dll->bytes + i));
  635. }
  636. PRDEBUG " %02x", dll->bytes[i]&0xff);
  637. }
  638. PRDEBUG "\n");
  639. PRDEBUG "printf=%08x *printf=%02x\n", (long)printf, *((char*)printf)&0xff);
  640. #endif
  641. if (error)
  642. return 0;
  643. return (struct DLL *)dll;
  644. }
  645. void dll_unload(struct DLL *Pdll)
  646. {
  647. int i, s;
  648. CDTOR f;
  649. if (Pdll == 0)
  650. return;
  651. dll_s *dll = (dll_s *)Pdll;
  652. if (--dll->load_count)
  653. return;
  654. // printf("unload: `%s'\n", dll->loadpath);
  655. if (dll->valid)
  656. {
  657. if (dll->uninit_func)
  658. dll->uninit_func();
  659. for (i=0; i<dll->dtor_count; i++)
  660. {
  661. void **fv = (void **)(dll->dtor_section);
  662. f = (CDTOR)(fv[i]);
  663. f();
  664. }
  665. }
  666. if (dll->next)
  667. dll->next->prev = dll->prev;
  668. if (dll->prev)
  669. dll->prev->next = dll->next;
  670. else
  671. dll_s::top = dll->next;
  672. if (dll->bytes)
  673. delete dll->bytes;
  674. dll->valid = 0;
  675. delete dll;
  676. }
  677. void *dll_lookup(struct DLL *Pdll, char *name)
  678. {
  679. dll_s *dll = (dll_s *)Pdll;
  680. return dll->symtab.get(name);
  681. }