Mercurial > projects > ldc
comparison runtime/internal/memory.d @ 905:bd000a7fab18
Applied doob's patch to port GDC's Dyld data segment tracking for Mac.
author | Christian Kamm <kamm incasoftware de> |
---|---|
date | Sat, 24 Jan 2009 00:33:06 +0100 |
parents | 493d42562733 |
children | 3cf0066e6faf |
comparison
equal
deleted
inserted
replaced
904:01d9ece9982a | 905:bd000a7fab18 |
---|---|
25 */ | 25 */ |
26 module memory; | 26 module memory; |
27 | 27 |
28 version = GC_Use_Dynamic_Ranges; | 28 version = GC_Use_Dynamic_Ranges; |
29 | 29 |
30 version(Posix) | 30 version(darwin) |
31 { | |
32 version = GC_Use_Data_Dyld; | |
33 version = GC_Use_Dynamic_Ranges; | |
34 } | |
35 else version(Posix) | |
31 { | 36 { |
32 version = GC_Use_Data_Proc_Maps; | 37 version = GC_Use_Data_Proc_Maps; |
33 } | 38 } |
34 version(solaris) | 39 else version(solaris) |
35 { | 40 { |
36 version = GC_Use_Data_Proc_Maps; | 41 version = GC_Use_Data_Proc_Maps; |
37 } | 42 } |
38 | 43 |
39 version(GC_Use_Data_Proc_Maps) | 44 version(GC_Use_Data_Proc_Maps) |
296 } | 301 } |
297 else version(solaris) | 302 else version(solaris) |
298 { | 303 { |
299 dataStart = adjust_up( &Data_Start ); | 304 dataStart = adjust_up( &Data_Start ); |
300 dataEnd = adjust_down( &Data_End ); | 305 dataEnd = adjust_down( &Data_End ); |
306 } | |
307 else version(GC_Use_Data_Dyld) | |
308 { | |
309 _d_dyld_start(); | |
301 } | 310 } |
302 else | 311 else |
303 { | 312 { |
304 static assert( false, "Operating system not supported." ); | 313 static assert( false, "Operating system not supported." ); |
305 } | 314 } |
495 close(fd); | 504 close(fd); |
496 } | 505 } |
497 } | 506 } |
498 } | 507 } |
499 } | 508 } |
509 | |
510 /* | |
511 * GDC dyld memory module: | |
512 * http://www.dsource.org/projects/tango/browser/trunk/lib/compiler/gdc/memory_dyld.c | |
513 * Port to the D programming language: Jacob Carlborg | |
514 */ | |
515 version (GC_Use_Data_Dyld) | |
516 { | |
517 private | |
518 { | |
519 const char* SEG_DATA = "__DATA".ptr; | |
520 const char* SECT_DATA = "__data".ptr; | |
521 const char* SECT_BSS = "__bss".ptr; | |
522 const char* SECT_COMMON = "__common".ptr; | |
523 | |
524 struct SegmentSection | |
525 { | |
526 const char* segment; | |
527 const char* section; | |
528 } | |
529 | |
530 struct mach_header | |
531 { | |
532 uint magic; | |
533 int cputype; | |
534 int cpusubtype; | |
535 uint filetype; | |
536 uint ncmds; | |
537 uint sizeofcmds; | |
538 uint flags; | |
539 } | |
540 | |
541 struct section | |
542 { | |
543 char[16] sectname; | |
544 char[16] segname; | |
545 uint addr; | |
546 uint size; | |
547 uint offset; | |
548 uint align_; | |
549 uint reloff; | |
550 uint nreloc; | |
551 uint flags; | |
552 uint reserved1; | |
553 uint reserved2; | |
554 } | |
555 | |
556 alias extern (C) void function (mach_header* mh, ptrdiff_t vmaddr_slide) DyldFuncPointer; | |
557 | |
558 extern (C) /*const*/ section* getsectbynamefromheader(/*const*/ mach_header* mhp, /*const*/ char* segname, /*const*/ char* sectname); | |
559 extern (C) void _dyld_register_func_for_add_image(DyldFuncPointer func); | |
560 extern (C) void _dyld_register_func_for_remove_image(DyldFuncPointer func); | |
561 | |
562 const SegmentSection[3] GC_dyld_sections = [SegmentSection(SEG_DATA, SECT_DATA), SegmentSection(SEG_DATA, SECT_BSS), SegmentSection(SEG_DATA, SECT_COMMON)]; | |
563 | |
564 extern (C) void on_dyld_add_image (/*const*/ mach_header* hdr, ptrdiff_t slide) | |
565 { | |
566 void* start; | |
567 void* end; | |
568 /*const*/ section* sec; | |
569 | |
570 foreach (s ; GC_dyld_sections) | |
571 { | |
572 sec = getsectbynamefromheader(hdr, s.segment, s.section); | |
573 | |
574 if (sec == null || sec.size == 0) | |
575 continue; | |
576 | |
577 start = cast(void*) (sec.addr + slide); | |
578 end = cast(void*) (start + sec.size); | |
579 | |
580 _d_gc_add_range(start, end); | |
581 } | |
582 } | |
583 | |
584 extern (C) void on_dyld_remove_image (/*const*/ mach_header* hdr, ptrdiff_t slide) | |
585 { | |
586 void* start; | |
587 void* end; | |
588 /*const*/ section* sec; | |
589 | |
590 foreach (s ; GC_dyld_sections) | |
591 { | |
592 sec = getsectbynamefromheader(hdr, s.segment, s.section); | |
593 | |
594 if (sec == null || sec.size == 0) | |
595 continue; | |
596 | |
597 start = cast(void*) (sec.addr + slide); | |
598 end = cast(void*) (start + sec.size); | |
599 | |
600 _d_gc_remove_range(start); | |
601 } | |
602 } | |
603 | |
604 void _d_dyld_start () | |
605 { | |
606 static bool started; | |
607 | |
608 if (!started) | |
609 { | |
610 started = true; | |
611 | |
612 _dyld_register_func_for_add_image(&on_dyld_add_image); | |
613 _dyld_register_func_for_remove_image(&on_dyld_remove_image); | |
614 } | |
615 } | |
616 } | |
617 } | |
618 |