# HG changeset patch # User Christian Kamm # Date 1232646812 -3600 # Node ID 177afbf5297be3c1851dd35389af108cfc32dee9 # Parent 23d36edea021b3a8ed8c6b8d04c0bf110dd03854 Solaris compatibility and proc map parsing #183, thanks BlueZeniX! diff -r 23d36edea021 -r 177afbf5297b dmd/mars.c --- a/dmd/mars.c Thu Jan 22 18:23:30 2009 +0100 +++ b/dmd/mars.c Thu Jan 22 18:53:32 2009 +0100 @@ -190,7 +190,7 @@ -m emit code specific to being one of:\n\ x86 x86-64 ppc32 ppc64 arm thumb\n\ -t emit code specific to being one of:\n\ - Linux, Windows, MacOSX, FreeBSD\n\ + Linux, Windows, MacOSX, FreeBSD, Solaris\n\ \n\ -g, -gc add symbolic debug info\n\ \n\ diff -r 23d36edea021 -r 177afbf5297b dmd/mtype.c --- a/dmd/mtype.c Thu Jan 22 18:23:30 2009 +0100 +++ b/dmd/mtype.c Thu Jan 22 18:53:32 2009 +0100 @@ -45,8 +45,10 @@ static double zero = 0; #elif __GNUC__ #include +#if !(defined (__SVR4) && defined (__sun)) #include #include +#endif static double zero = 0; #endif diff -r 23d36edea021 -r 177afbf5297b gen/linker.cpp --- a/gen/linker.cpp Thu Jan 22 18:23:30 2009 +0100 +++ b/gen/linker.cpp Thu Jan 22 18:53:32 2009 +0100 @@ -286,14 +286,21 @@ // default libs switch(global.params.os) { - case OSLinux: + case OSLinux: case OSMacOSX: args.push_back("-ldl"); + // fallthrough case OSFreeBSD: args.push_back("-lpthread"); args.push_back("-lm"); break; + case OSSolaris: + args.push_back("-lm"); + args.push_back("-lumem"); + // solaris TODO + break; + case OSWindows: // FIXME: I'd assume kernel32 etc break; diff -r 23d36edea021 -r 177afbf5297b runtime/internal/memory.d --- a/runtime/internal/memory.d Thu Jan 22 18:23:30 2009 +0100 +++ b/runtime/internal/memory.d Thu Jan 22 18:53:32 2009 +0100 @@ -27,11 +27,14 @@ version = GC_Use_Dynamic_Ranges; -// does Posix suffice? version(Posix) { version = GC_Use_Data_Proc_Maps; } +version(solaris) +{ + version = GC_Use_Data_Proc_Maps; +} version(GC_Use_Data_Proc_Maps) { @@ -167,10 +170,10 @@ { extern int _data_start__; extern int _bss_end__; + } - alias _data_start__ Data_Start; - alias _bss_end__ Data_End; - } + alias _data_start__ Data_Start; + alias _bss_end__ Data_End; } else version( linux ) { @@ -186,8 +189,19 @@ extern int __fini_array_end; } - alias __data_start Data_Start; - alias _end Data_End; + alias __data_start Data_Start; + alias _end Data_End; + } + else version( solaris ) + { + extern(C) + { + extern int _edata; + extern int _end; + } + + alias _edata Data_Start; + alias _end Data_End; } version( GC_Use_Dynamic_Ranges ) @@ -280,14 +294,79 @@ dataStart = adjust_up( &Data_Start ); dataEnd = adjust_down( &Data_End ); } + else version(solaris) + { + dataStart = adjust_up( &Data_Start ); + dataEnd = adjust_down( &Data_End ); + } else { static assert( false, "Operating system not supported." ); } - //TODO: This could use cleanup! version( GC_Use_Data_Proc_Maps ) { + parseDataProcMaps(); + } +} + +version( GC_Use_Data_Proc_Maps ) +{ +version(solaris) +{ + typedef long offset_t; + enum : uint { PRMAPSZ = 64, MA_WRITE = 0x02 } + extern(C) + { + struct prmap { + uintptr_t pr_vaddr; /* virtual address of mapping */ + size_t pr_size; /* size of mapping in bytes */ + char[PRMAPSZ] pr_mapname; /* name in /proc//object */ + private offset_t pr_offset; /* offset into mapped object, if any */ + int pr_mflags; /* protection and attribute flags (see below) */ + int pr_pagesize; /* pagesize (bytes) for this mapping */ + int pr_shmid; /* SysV shmid, -1 if not SysV shared memory */ + + private int[1] pr_filler; + } + } + + void parseDataProcMaps() + { + debug (ProcMaps) printf("initStaticDataPtrs()\n"); + // http://docs.sun.com/app/docs/doc/816-5174/proc-4 + prmap pr; + + int fd = open("/proc/self/map", O_RDONLY); + scope (exit) close(fd); + + while (prmap.sizeof == read(fd, &pr, prmap.sizeof)) + if (pr.pr_mflags & MA_WRITE) + { + void* start = cast(void*) pr.pr_vaddr; + void* end = cast(void*)(pr.pr_vaddr + pr.pr_size); + debug (ProcMaps) printf(" vmem at %p - %p with size %d bytes\n", start, end, pr.pr_size); + + // Exclude stack and dataStart..dataEnd + if ( ( !dataEnd || + !( dataStart >= start && dataEnd <= end ) ) && + !( &pr >= start && &pr < end ) ) + { + // we already have static data from this region. anything else + // is heap (%% check) + debug (ProcMaps) printf(" Adding map range %p - %p\n", start, end); + _d_gc_add_range(start, end); + } + } + } +} +else +{ + const int S = (void*).sizeof; + + // TODO: This could use cleanup! + void parseDataProcMaps() + { // TODO: Exclude zero-mapped regions int fd = open("/proc/self/maps", O_RDONLY); @@ -415,3 +494,4 @@ } } } +} \ No newline at end of file