Solaris compatibility and proc map parsing #183, thanks BlueZeniX!

This commit is contained in:
Christian Kamm 2009-01-22 18:53:32 +01:00
parent f4f5c58a44
commit ab9b9cc2e9
4 changed files with 98 additions and 9 deletions

View file

@ -190,7 +190,7 @@ Codegen control:\n\
-m<arch> emit code specific to <arch> being one of:\n\ -m<arch> emit code specific to <arch> being one of:\n\
x86 x86-64 ppc32 ppc64 arm thumb\n\ x86 x86-64 ppc32 ppc64 arm thumb\n\
-t<os> emit code specific to <os> being one of:\n\ -t<os> emit code specific to <os> being one of:\n\
Linux, Windows, MacOSX, FreeBSD\n\ Linux, Windows, MacOSX, FreeBSD, Solaris\n\
\n\ \n\
-g, -gc add symbolic debug info\n\ -g, -gc add symbolic debug info\n\
\n\ \n\

View file

@ -45,8 +45,10 @@ static double zero = 0;
static double zero = 0; static double zero = 0;
#elif __GNUC__ #elif __GNUC__
#include <math.h> #include <math.h>
#if !(defined (__SVR4) && defined (__sun))
#include <bits/nan.h> #include <bits/nan.h>
#include <bits/mathdef.h> #include <bits/mathdef.h>
#endif
static double zero = 0; static double zero = 0;
#endif #endif

View file

@ -289,11 +289,18 @@ int linkObjToExecutable(const char* argv0)
case OSLinux: case OSLinux:
case OSMacOSX: case OSMacOSX:
args.push_back("-ldl"); args.push_back("-ldl");
// fallthrough
case OSFreeBSD: case OSFreeBSD:
args.push_back("-lpthread"); args.push_back("-lpthread");
args.push_back("-lm"); args.push_back("-lm");
break; break;
case OSSolaris:
args.push_back("-lm");
args.push_back("-lumem");
// solaris TODO
break;
case OSWindows: case OSWindows:
// FIXME: I'd assume kernel32 etc // FIXME: I'd assume kernel32 etc
break; break;

View file

@ -27,11 +27,14 @@ module memory;
version = GC_Use_Dynamic_Ranges; version = GC_Use_Dynamic_Ranges;
// does Posix suffice?
version(Posix) version(Posix)
{ {
version = GC_Use_Data_Proc_Maps; version = GC_Use_Data_Proc_Maps;
} }
version(solaris)
{
version = GC_Use_Data_Proc_Maps;
}
version(GC_Use_Data_Proc_Maps) version(GC_Use_Data_Proc_Maps)
{ {
@ -167,11 +170,11 @@ private
{ {
extern int _data_start__; extern int _data_start__;
extern int _bss_end__; extern int _bss_end__;
}
alias _data_start__ Data_Start; alias _data_start__ Data_Start;
alias _bss_end__ Data_End; alias _bss_end__ Data_End;
} }
}
else version( linux ) else version( linux )
{ {
extern (C) extern (C)
@ -189,6 +192,17 @@ private
alias __data_start Data_Start; alias __data_start Data_Start;
alias _end Data_End; 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 ) version( GC_Use_Dynamic_Ranges )
{ {
@ -280,13 +294,78 @@ void initStaticDataPtrs()
dataStart = adjust_up( &Data_Start ); dataStart = adjust_up( &Data_Start );
dataEnd = adjust_down( &Data_End ); dataEnd = adjust_down( &Data_End );
} }
else version(solaris)
{
dataStart = adjust_up( &Data_Start );
dataEnd = adjust_down( &Data_End );
}
else else
{ {
static assert( false, "Operating system not supported." ); static assert( false, "Operating system not supported." );
} }
//TODO: This could use cleanup!
version( GC_Use_Data_Proc_Maps ) 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/<pid>/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 // TODO: Exclude zero-mapped regions
@ -415,3 +494,4 @@ void initStaticDataPtrs()
} }
} }
} }
}