diff --git a/dmd/mars.c b/dmd/mars.c index 92c082c0..b641ee92 100644 --- a/dmd/mars.c +++ b/dmd/mars.c @@ -190,7 +190,7 @@ Codegen control:\n\ -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 --git a/dmd/mtype.c b/dmd/mtype.c index 3dcd9071..3660348f 100644 --- a/dmd/mtype.c +++ b/dmd/mtype.c @@ -45,8 +45,10 @@ static double zero = 0; static double zero = 0; #elif __GNUC__ #include +#if !(defined (__SVR4) && defined (__sun)) #include #include +#endif static double zero = 0; #endif diff --git a/gen/linker.cpp b/gen/linker.cpp index 12ec1bb6..d63d7060 100644 --- a/gen/linker.cpp +++ b/gen/linker.cpp @@ -286,14 +286,21 @@ int linkObjToExecutable(const char* argv0) // 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 --git a/runtime/internal/memory.d b/runtime/internal/memory.d index 513058c4..53d3ce9f 100644 --- a/runtime/internal/memory.d +++ b/runtime/internal/memory.d @@ -27,11 +27,14 @@ module memory; 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 @@ private { 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 @@ private 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,13 +294,78 @@ void initStaticDataPtrs() 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 @@ -415,3 +494,4 @@ void initStaticDataPtrs() } } } +} \ No newline at end of file