comparison dmd/Library.d @ 178:e3afd1303184

Many small bugs fixed Made all classes derive from TObject to detect memory leaks (functionality is disabled for now) Began work on overriding backend memory allocations (to avoid memory leaks)
author korDen
date Sun, 17 Oct 2010 07:42:00 +0400
parents e7769d53e750
children 190ba98276b3
comparison
equal deleted inserted replaced
177:1475fd394c9e 178:e3afd1303184
128 } 128 }
129 129
130 memcpy(name, p, len); 130 memcpy(name, p, len);
131 name[len] = 0; 131 name[len] = 0;
132 *pp = p + len; 132 *pp = p + len;
133 133
134 return len; 134 return len;
135 } 135 }
136 136
137 static ushort parseIdx(ubyte** pp) 137 static ushort parseIdx(ubyte** pp)
138 { 138 {
146 146
147 extern (C) int D_NameCompare(const(void*) a, const(void*) b) 147 extern (C) int D_NameCompare(const(void*) a, const(void*) b)
148 { 148 {
149 ObjSymbol** p1 = cast(ObjSymbol**)a; 149 ObjSymbol** p1 = cast(ObjSymbol**)a;
150 ObjSymbol** p2 = cast(ObjSymbol**)b; 150 ObjSymbol** p2 = cast(ObjSymbol**)b;
151 151
152 return cmp((*p1).name, (*p2).name); 152 return cmp((*p1).name, (*p2).name);
153 } 153 }
154 version (Windows) 154 version (Windows)
155 { 155 {
156 /******************************************* 156 /*******************************************
157 * Write a single entry into dictionary. 157 * Write a single entry into dictionary.
158 * Returns: 158 * Returns:
159 * 0 failure 159 * 0 failure
160 */ 160 */
161 161
162 extern (C) extern uint _rotl(uint value, int shift); 162 extern (C) extern uint _rotl(uint value, int shift);
163 extern (C) extern uint _rotr(uint value, int shift); 163 extern (C) extern uint _rotr(uint value, int shift);
164 164
165 static int EnterDict(ubyte* bucketsP, ushort ndicpages, ubyte* entry, uint entrylen) 165 static int EnterDict(ubyte* bucketsP, ushort ndicpages, ubyte* entry, uint entrylen)
166 { 166 {
252 } 252 }
253 253
254 return 0; 254 return 0;
255 } 255 }
256 256
257 class Library 257 import dmd.TObject;
258
259 class Library : TObject
258 { 260 {
259 File libfile; 261 File libfile;
260 Array objmodules; // ObjModule[] 262 Array objmodules; // ObjModule[]
261 Array objsymbols; // ObjSymbol[] 263 Array objsymbols; // ObjSymbol[]
262 264
263 StringTable tab; 265 StringTable tab;
264 266
265 this() 267 this()
266 { 268 {
269 register();
267 libfile = null; 270 libfile = null;
268 271
269 objmodules = new Array(); 272 objmodules = new Array();
270 objsymbols = new Array(); 273 objsymbols = new Array();
271 tab = new StringTable();
272 } 274 }
273 275
274 /*********************************** 276 /***********************************
275 * Set the library file name based on the output directory 277 * Set the library file name based on the output directory
276 * and the filename. 278 * and the filename.
278 */ 280 */
279 void setFilename(string dir, string filename) 281 void setFilename(string dir, string filename)
280 { 282 {
281 string arg = filename; 283 string arg = filename;
282 if (arg.length == 0) 284 if (arg.length == 0)
283 { 285 {
284 // Generate lib file name from first obj name 286 // Generate lib file name from first obj name
285 string n = (cast(String)global.params.objfiles.data[0]).str; 287 string n = (cast(String)global.params.objfiles.data[0]).str;
286 288
287 n = FileName.name(n); 289 n = FileName.name(n);
288 FileName fn = FileName.forceExt(n, global.lib_ext); 290 FileName fn = FileName.forceExt(n, global.lib_ext);
350 { 352 {
351 error("COFF libraries not supported"); 353 error("COFF libraries not supported");
352 return; 354 return;
353 } 355 }
354 else 356 else
355 { 357 {
356 // Not a library, assume OMF object module 358 // Not a library, assume OMF object module
357 g_page_size = 16; 359 g_page_size = 16;
358 } 360 }
359 361
360 /* Split up the buffer buf[0..buflen] into multiple object modules, 362 /* Split up the buffer buf[0..buflen] into multiple object modules,
381 switch (recTyp) 383 switch (recTyp)
382 { 384 {
383 case LHEADR : 385 case LHEADR :
384 case THEADR : 386 case THEADR :
385 if (!om) 387 if (!om)
386 { 388 {
387 char name[LIBIDMAX + 1]; 389 char name[LIBIDMAX + 1];
388 om = new ObjModule(); 390 om = new ObjModule();
389 om.flags = 0; 391 om.flags = 0;
390 om.base = p; 392 om.base = p;
391 p += 3; 393 p += 3;
392 parseName(&p, name.ptr); 394 parseName(&p, name.ptr);
393 if (first_module && module_name && !islibrary) 395 if (first_module && module_name && !islibrary)
394 { 396 {
395 // Remove path and extension 397 // Remove path and extension
396 string fname = FileName.name(module_name); 398 string fname = FileName.name(module_name);
397 string ext = FileName.ext(fname); 399 string ext = FileName.ext(fname);
398 if (ext.length != 0) { 400 if (ext.length != 0) {
399 fname = fname[0..$-ext.length-1]; 401 fname = fname[0..$-ext.length-1];
400 } 402 }
401 403
402 om.name = fname; 404 om.name = fname;
403 } 405 }
404 else 406 else
405 { 407 {
406 /* Use THEADR name as module name, 408 /* Use THEADR name as module name,
407 * removing path and extension. 409 * removing path and extension.
408 */ 410 */
409 string fname = FileName.name(fromStringz(name.ptr)); 411 string fname = FileName.name(fromStringz(name.ptr));
410 string ext = FileName.ext(fname); 412 string ext = FileName.ext(fname);
411 if (ext.length != 0) { 413 if (ext.length != 0) {
412 fname = fname[0..$-ext.length-1]; 414 fname = fname[0..$-ext.length-1];
413 } 415 }
414 416
415 om.name = fname; 417 om.name = fname;
416 om.flags |= MFtheadr; 418 om.flags |= MFtheadr;
417 } 419 }
418 if (strcmp(name.ptr, "C".ptr) == 0) // old C compilers did this 420 if (strcmp(name.ptr, "C".ptr) == 0) // old C compilers did this
419 { 421 {
420 om.flags |= MFgentheadr; // generate our own THEADR 422 om.flags |= MFgentheadr; // generate our own THEADR
421 om.base = pnext; // skip past THEADR 423 om.base = pnext; // skip past THEADR
422 } 424 }
423 objmodules.push(cast(void*)om); 425 objmodules.push(cast(void*)om);
424 first_module = 0; 426 first_module = 0;
426 break; 428 break;
427 429
428 case MODEND : 430 case MODEND :
429 case M386END: 431 case M386END:
430 if (om) 432 if (om)
431 { 433 {
432 om.page = cast(ushort)((om.base - pstart) / g_page_size); 434 om.page = cast(ushort)((om.base - pstart) / g_page_size);
433 om.length = pnext - om.base; 435 om.length = pnext - om.base;
434 om = null; 436 om = null;
435 } 437 }
436 // Round up to next page 438 // Round up to next page
437 uint t = pnext - pstart; 439 uint t = pnext - pstart;
438 t = (t + g_page_size - 1) & ~cast(uint)(g_page_size - 1); 440 t = (t + g_page_size - 1) & ~cast(uint)(g_page_size - 1);
439 pnext = pstart + t; 441 pnext = pstart + t;
440 break; 442 break;
441 443
442 default: 444 default:
443 // ignore 445 // ignore
444 ; 446 ;
445 } 447 }
446 } 448 }
447 449
448 if (om) 450 if (om)
476 void addSymbol(ObjModule* om, string name, int pickAny = 0) 478 void addSymbol(ObjModule* om, string name, int pickAny = 0)
477 { 479 {
478 version (LOG) { 480 version (LOG) {
479 printf("Library.addSymbol(%s, %s, %d)\n", om.name, name, pickAny); 481 printf("Library.addSymbol(%s, %s, %d)\n", om.name, name, pickAny);
480 } 482 }
481 StringValue* s = tab.insert(name); 483 Object* s = tab.insert(name);
482 if (!s) 484 if (!s)
483 { 485 {
484 // already in table 486 // already in table
485 if (!pickAny) 487 if (!pickAny)
486 { 488 {
487 s = tab.lookup(name); 489 s = tab.lookup(name);
488 assert(s); 490 assert(s);
489 ObjSymbol* os = cast(ObjSymbol*)s.ptrvalue; 491 ObjSymbol* os = *cast(ObjSymbol**)s;
490 error("multiple definition of %s: %s and %s: %s", 492 error("multiple definition of %s: %s and %s: %s",
491 om.name, name, os.om.name, os.name); 493 om.name, name, os.om.name, os.name);
492 } 494 }
493 } 495 }
494 else 496 else
495 { 497 {
496 ObjSymbol* os = new ObjSymbol(); 498 ObjSymbol* os = new ObjSymbol();
497 os.name = name; 499 os.name = name;
498 os.om = om; 500 os.om = om;
499 s.ptrvalue = cast(void*)os; 501 *s = cast(Object)cast(void*)os; /// !!!!
500 502
501 objsymbols.push(os); 503 objsymbols.push(os);
502 } 504 }
503 } 505 }
504 506
505 void scanObjModule(ObjModule* om) 507 void scanObjModule(ObjModule* om)
506 { 508 {
507 int easyomf; 509 int easyomf;
508 uint u; 510 uint u;
509 ubyte result = 0; 511 ubyte result = 0;
603 result = 1; 605 result = 1;
604 goto Ret; 606 goto Ret;
605 607
606 case COMENT: 608 case COMENT:
607 // Recognize Phar Lap EASY-OMF format 609 // Recognize Phar Lap EASY-OMF format
608 { 610 {
609 enum ubyte[7] omfstr = [0x80,0xAA,'8','0','3','8','6']; 611 enum ubyte[7] omfstr = [0x80,0xAA,'8','0','3','8','6'];
610 612
611 if (recLen == omfstr.sizeof) 613 if (recLen == omfstr.sizeof)
612 { 614 {
613 for (uint i = 0; i < omfstr.sizeof; i++) 615 for (uint i = 0; i < omfstr.sizeof; i++)
617 break; 619 break;
618 L1: ; 620 L1: ;
619 } 621 }
620 } 622 }
621 // Recognize .IMPDEF Import Definition Records 623 // Recognize .IMPDEF Import Definition Records
622 { 624 {
623 enum ubyte[3] omfstr = [0, 0xA0, 1]; 625 enum ubyte[3] omfstr = [0, 0xA0, 1];
624 626
625 if (recLen >= 7) 627 if (recLen >= 7)
626 { 628 {
627 p++; 629 p++;
636 } 638 }
637 } 639 }
638 break; 640 break;
639 641
640 default: 642 default:
641 // ignore 643 // ignore
642 ; 644 ;
643 } 645 }
644 } 646 }
645 647
646 Ret: 648 Ret:
647 ; 649 ;
648 ///for (u = 1; u < names.dim; u++) 650 ///for (u = 1; u < names.dim; u++)
649 /// free(names.data[u]); 651 /// free(names.data[u]);
650 } 652 }
651 653
652 /*********************************** 654 /***********************************
653 * Calculates number of pages needed for dictionary 655 * Calculates number of pages needed for dictionary
654 * Returns: 656 * Returns:
655 * number of pages 657 * number of pages
656 */ 658 */
660 ushort bucksForHash; 662 ushort bucksForHash;
661 ushort bucksForSize; 663 ushort bucksForSize;
662 uint symSize = 0; 664 uint symSize = 0;
663 665
664 for (int i = 0; i < objsymbols.dim; i++) 666 for (int i = 0; i < objsymbols.dim; i++)
665 { 667 {
666 ObjSymbol* s = cast(ObjSymbol*)objsymbols.data[i]; 668 ObjSymbol* s = cast(ObjSymbol*)objsymbols.data[i];
667 symSize += ( s.name.length + 4 ) & ~1; 669 symSize += ( s.name.length + 4 ) & ~1;
668 } 670 }
669 671
670 for (int i = 0; i < objmodules.dim; i++) 672 for (int i = 0; i < objmodules.dim; i++)
671 { 673 {
672 ObjModule* om = cast(ObjModule*)objmodules.data[i]; 674 ObjModule* om = cast(ObjModule*)objmodules.data[i];
673 675
674 size_t len = om.name.length; 676 size_t len = om.name.length;
675 if (len > 0xFF) 677 if (len > 0xFF)
676 len += 2; // Digital Mars long name extension 678 len += 2; // Digital Mars long name extension
699 ]; 701 ];
700 702
701 for (int i = 0; 1; i++) 703 for (int i = 0; 1; i++)
702 { 704 {
703 if ( primes[i] == 0 ) 705 if ( primes[i] == 0 )
704 { 706 {
705 // Quick and easy way is out. 707 // Quick and easy way is out.
706 // Now try and find first prime number > ndicpages 708 // Now try and find first prime number > ndicpages
707 uint prime; 709 uint prime;
708 710
709 for (prime = (ndicpages + 1) | 1; 1; prime += 2) 711 for (prime = (ndicpages + 1) | 1; 1; prime += 2)
728 } 730 }
729 } 731 }
730 732
731 return ndicpages; 733 return ndicpages;
732 } 734 }
733 735
734 /******************************************* 736 /*******************************************
735 * Write the module and symbol names to the dictionary. 737 * Write the module and symbol names to the dictionary.
736 * Returns: 738 * Returns:
737 * 0 failure 739 * 0 failure
738 */ 740 */
742 744
743 //printf("FillDict()\n"); 745 //printf("FillDict()\n");
744 746
745 // Add each of the module names 747 // Add each of the module names
746 for (int i = 0; i < objmodules.dim; i++) 748 for (int i = 0; i < objmodules.dim; i++)
747 { 749 {
748 ObjModule* om = cast(ObjModule*)objmodules.data[i]; 750 ObjModule* om = cast(ObjModule*)objmodules.data[i];
749 751
750 ushort n = cast(ushort)om.name.length; 752 ushort n = cast(ushort)om.name.length;
751 if (n > 255) 753 if (n > 255)
752 { 754 {
753 entry[0] = 0xFF; 755 entry[0] = 0xFF;
754 entry[1] = 0; 756 entry[1] = 0;
755 *cast(ushort*)(entry.ptr + 2) = cast(ushort)(n + 1); 757 *cast(ushort*)(entry.ptr + 2) = cast(ushort)(n + 1);
756 memcpy(entry.ptr + 4, om.name.ptr, n); 758 memcpy(entry.ptr + 4, om.name.ptr, n);
757 n += 3; 759 n += 3;
758 } 760 }
759 else 761 else
760 { 762 {
761 entry[ 0 ] = cast(ubyte)(1 + n); 763 entry[ 0 ] = cast(ubyte)(1 + n);
762 memcpy(entry.ptr + 1, om.name.ptr, n ); 764 memcpy(entry.ptr + 1, om.name.ptr, n );
763 } 765 }
764 entry[ n + 1 ] = '!'; 766 entry[ n + 1 ] = '!';
765 *(cast(ushort*)( n + 2 + entry.ptr )) = om.page; 767 *(cast(ushort*)( n + 2 + entry.ptr )) = om.page;
772 // Sort the symbols 774 // Sort the symbols
773 qsort( objsymbols.data, objsymbols.dim, 4, /*(cmpfunc_t)*/&D_NameCompare ); 775 qsort( objsymbols.data, objsymbols.dim, 4, /*(cmpfunc_t)*/&D_NameCompare );
774 776
775 // Add each of the symbols 777 // Add each of the symbols
776 for (int i = 0; i < objsymbols.dim; i++) 778 for (int i = 0; i < objsymbols.dim; i++)
777 { 779 {
778 ObjSymbol* os = cast(ObjSymbol*)objsymbols.data[i]; 780 ObjSymbol* os = cast(ObjSymbol*)objsymbols.data[i];
779 781
780 ushort n = cast(ushort)os.name.length; 782 ushort n = cast(ushort)os.name.length;
781 if (n > 255) 783 if (n > 255)
782 { 784 {
783 entry[0] = 0xFF; 785 entry[0] = 0xFF;
784 entry[1] = 0; 786 entry[1] = 0;
785 *cast(ushort*)(entry.ptr + 2) = n; 787 *cast(ushort*)(entry.ptr + 2) = n;
786 memcpy(entry.ptr + 4, os.name.ptr, n); 788 memcpy(entry.ptr + 4, os.name.ptr, n);
787 n += 3; 789 n += 3;
788 } 790 }
789 else 791 else
790 { 792 {
791 entry[ 0 ] = cast(ubyte)n; 793 entry[ 0 ] = cast(ubyte)n;
792 memcpy( entry.ptr + 1, os.name.ptr, n ); 794 memcpy( entry.ptr + 1, os.name.ptr, n );
793 } 795 }
794 *(cast(ushort*)( n + 1 + entry.ptr )) = os.om.page; 796 *(cast(ushort*)( n + 1 + entry.ptr )) = os.om.page;
795 if ( (n & 1) == 0 ) 797 if ( (n & 1) == 0 )
800 } 802 }
801 } 803 }
802 804
803 return 1; 805 return 1;
804 } 806 }
805 807
806 /********************************************** 808 /**********************************************
807 * Create and write library to libbuf. 809 * Create and write library to libbuf.
808 * The library consists of: 810 * The library consists of:
809 * library header 811 * library header
810 * object modules... 812 * object modules...
815 { 817 {
816 /* Scan each of the object modules for symbols 818 /* Scan each of the object modules for symbols
817 * to go into the dictionary 819 * to go into the dictionary
818 */ 820 */
819 for (int i = 0; i < objmodules.dim; i++) 821 for (int i = 0; i < objmodules.dim; i++)
820 { 822 {
821 ObjModule* om = cast(ObjModule*)objmodules.data[i]; 823 ObjModule* om = cast(ObjModule*)objmodules.data[i];
822 scanObjModule(om); 824 scanObjModule(om);
823 } 825 }
824 826
825 uint g_page_size = 16; 827 uint g_page_size = 16;
835 printf("g_page_size = %d\n", g_page_size); 837 printf("g_page_size = %d\n", g_page_size);
836 } 838 }
837 uint offset = g_page_size; 839 uint offset = g_page_size;
838 840
839 for (int i = 0; i < objmodules.dim; i++) 841 for (int i = 0; i < objmodules.dim; i++)
840 { 842 {
841 ObjModule* om = cast(ObjModule*)objmodules.data[i]; 843 ObjModule* om = cast(ObjModule*)objmodules.data[i];
842 844
843 uint page = offset / g_page_size; 845 uint page = offset / g_page_size;
844 if (page > 0xFFFF) 846 if (page > 0xFFFF)
845 { 847 {
877 libbuf.fill0(g_page_size); 879 libbuf.fill0(g_page_size);
878 880
879 /* Write each object module into the library 881 /* Write each object module into the library
880 */ 882 */
881 for (int i = 0; i < objmodules.dim; i++) 883 for (int i = 0; i < objmodules.dim; i++)
882 { 884 {
883 ObjModule* om = cast(ObjModule*)objmodules.data[i]; 885 ObjModule* om = cast(ObjModule*)objmodules.data[i];
884 886
885 uint page = libbuf.offset / g_page_size; 887 uint page = libbuf.offset / g_page_size;
886 assert(page <= 0xFFFF); 888 assert(page <= 0xFFFF);
887 om.page = cast(ushort)page; 889 om.page = cast(ushort)page;
903 // Compute and store record checksum 905 // Compute and store record checksum
904 uint n = size + 4; 906 uint n = size + 4;
905 ubyte checksum = 0; 907 ubyte checksum = 0;
906 ubyte* p = header.ptr; 908 ubyte* p = header.ptr;
907 while (n--) 909 while (n--)
908 { 910 {
909 checksum -= *p; 911 checksum -= *p;
910 p++; 912 p++;
911 } 913 }
912 *p = checksum; 914 *p = checksum;
913 915
956 { 958 {
957 // 'next available' slot 959 // 'next available' slot
958 bucketsP[u * BUCKETPAGE + HASHMOD] = (HASHMOD + 1) >> 1; 960 bucketsP[u * BUCKETPAGE + HASHMOD] = (HASHMOD + 1) >> 1;
959 } 961 }
960 962
961 if (FillDict(bucketsP, ndicpages)) 963 if (FillDict(bucketsP, ndicpages))
962 break; 964 break;
963 padding += 16; // try again with more margins 965 padding += 16; // try again with more margins
964 } 966 }
965 967
966 // Write dictionary 968 // Write dictionary
983 } 985 }
984 } 986 }
985 } // version (Windows) 987 } // version (Windows)
986 else version(TARGET_LINUX) 988 else version(TARGET_LINUX)
987 { 989 {
988 class Library 990
991 import dmd.TObject;
992
993 class Library : TObject
989 { 994 {
990 void setFilename(string dir, string filename) 995 void setFilename(string dir, string filename)
991 { 996 {
992 assert(0); 997 assert(0);
993 } 998 }
994 999
995 void addObject(string module_name, void *buf, size_t buflen) 1000 void addObject(string module_name, void *buf, size_t buflen)
996 { 1001 {
997 assert(0); 1002 assert(0);
998 } 1003 }
999 1004
1000 void write() 1005 void write()
1001 { 1006 {
1002 assert(0); 1007 assert(0);
1003 } 1008 }
1004 1009
1005 } 1010 }
1006 } 1011 }