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\
x86 x86-64 ppc32 ppc64 arm thumb\n\
-t<os> emit code specific to <os> being one of:\n\
Linux, Windows, MacOSX, FreeBSD\n\
Linux, Windows, MacOSX, FreeBSD, Solaris\n\
\n\
-g, -gc add symbolic debug info\n\
\n\

View file

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

View file

@ -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;

View file

@ -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/<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
@ -415,3 +494,4 @@ void initStaticDataPtrs()
}
}
}
}