bool assertvalidmemory(int ptr, int structure) {
return memmap->assertvalidmemory((void *)ptr, structure);
}
+
+void initializestack(void *high) {
+ memmap->initializestack(high);
+}
void resettypemap();
bool assertvalidtype(int ptr, int structure);
bool assertvalidmemory(int ptr, int structure);
-
+void initializestack(void *);
extern typemap * memmap;
#endif
+#include "ex_aux.h"
class typeobject {
- public:
- typeobject();
- int getfield(int type, int fieldindex); //returns type
- int isArray(int type, int fieldindex); //returns if array
- int numElements(int type, int fieldindex); //returns number of elements
- int size(int type);
- int getnumfields(int type);
- bool issubtype(int subtype, int type);
- void reset();
+public:
+typeobject();
+int getfield(int type, int fieldindex);
+int isArray(int type, int fieldindex);
+int isPtr(int type, int fieldindex);
+int numElements(int type, int fieldindex);
+int size(int type);
+int sizeBytes(int type);
+int getnumfields(int type);
+bool issubtype(int subtype, int type);
+void computesizes(foo_state *);
};
--- /dev/null
+/*
+Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers
+Copyright (c) 1991-1995 by Xerox Corporation. All rights reserved.
+Copyright (c) 1996-1999 by Silicon Graphics. All rights reserved.
+Copyright (c) 1999-2001 by Hewlett-Packard. All rights reserved.
+
+THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
+OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
+
+Permission is hereby granted to use or copy this program
+for any purpose, provided the above notices are retained on all copies.
+Permission to modify the code and to distribute modified code is granted,
+provided the above notices are retained, and a notice that the code was
+modified is included with the above copyright notice.
+ */
+
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <ctype.h>
+#define ptr_t void *
+#pragma weak __libc_stack_end
+extern ptr_t __libc_stack_end;
+#define word unsigned int
+# define STAT_SKIP 27 /* Number of fields preceding startstack */
+ /* field in /proc/self/stat */
+#define ABORT printf
+
+ ptr_t GC_linux_stack_base(void)
+ {
+ /* We read the stack base value from /proc/self/stat. We do this */
+ /* using direct I/O system calls in order to avoid calling malloc */
+ /* in case REDIRECT_MALLOC is defined. */
+# define STAT_BUF_SIZE 4096
+# define STAT_READ read
+ /* Should probably call the real read, if read is wrapped. */
+ char stat_buf[STAT_BUF_SIZE];
+ int f;
+ char c;
+ word result = 0;
+ size_t i, buf_offset = 0;
+
+ /* First try the easy way. This should work for glibc 2.2 */
+ if (0 != &__libc_stack_end) {
+# ifdef IA64
+ /* Some versions of glibc set the address 16 bytes too */
+ /* low while the initialization code is running. */
+ if (((word)__libc_stack_end & 0xfff) + 0x10 < 0x1000) {
+ return __libc_stack_end + 0x10;
+ } /* Otherwise it's not safe to add 16 bytes and we fall */
+ /* back to using /proc. */
+# else
+ return __libc_stack_end;
+# endif
+ }
+ f = open("/proc/self/stat", O_RDONLY);
+ if (f < 0 || STAT_READ(f, stat_buf, STAT_BUF_SIZE) < 2 * STAT_SKIP) {
+ ABORT("Couldn't read /proc/self/stat");
+ }
+ c = stat_buf[buf_offset++];
+ /* Skip the required number of fields. This number is hopefully */
+ /* constant across all Linux implementations. */
+ for (i = 0; i < STAT_SKIP; ++i) {
+ while (isspace(c)) c = stat_buf[buf_offset++];
+ while (!isspace(c)) c = stat_buf[buf_offset++];
+ }
+ while (isspace(c)) c = stat_buf[buf_offset++];
+ while (isdigit(c)) {
+ result *= 10;
+ result += c - '0';
+ c = stat_buf[buf_offset++];
+ }
+ close(f);
+ if (result < 0x10000000) ABORT("Absurd stack bottom value");
+ return (ptr_t)result;
+ }
--- /dev/null
+void * GC_linux_stack_base(void);
#include "size.h"
extern "C" {
#include "redblack.h"
+#include "stack.h"
}
#define CHECKTYPE
alloctree=rbinit();
typetree=rbinit();
this->size=size;
+ this->low=GC_linux_stack_base();
}
void freefunction(void *ptr) {
void typemap::reset() {
rbdestroy(typetree,freefunction);
typetree=rbinit();
+ if (low<high)
+ rbdelete(low,alloctree);
+ else
+ rbdelete(high,alloctree);
+}
+
+void typemap::initializestack(void *high) {
+ this->high=high;
+ if (low<high)
+ rbinsert(low,high,NULL,alloctree);
+ else
+ rbinsert(high,low,NULL,alloctree);
}
structuremap::structuremap(int s) {
}
bool typemap::asserttype(void *ptr, int s) {
- int toadd=size->size(s);
- int inbytes=toadd>>3;
- if (toadd%8)
- inbytes++;
- return asserttype(ptr,((char *) ptr)+inbytes,s);
+ int toadd=size->sizeBytes(s);
+ return asserttype(ptr,((char *) ptr)+toadd,s);
}
bool typemap::asserttype(void *ptr, void *high, int s) {
}
bool typemap::assertvalidmemory(void* low, int s) {
- int toadd=size->size(s);
- int inbytes=toadd>>3;
- if (toadd%8)
- inbytes++;
- return assertvalidmemory(low,((char *)low)+inbytes);
+ int toadd=size->sizeBytes(s);
+ return assertvalidmemory(low,((char *)low)+toadd);
}
bool typemap::assertvalidmemory(void* low, void* high) {
printf("Error\n");
}
+inline int sizeinbytes(unsigned int bits) {
+ int bytes=bits>>3;
+ if (bits %8)
+ bytes++;
+ return bytes;
+}
+
int typemap::findoffsetstructure(int s, int offset) {
int count=0;
for(int i=0;i<size->getnumfields(s);i++) {
mult=size->numElements(s,i);
}
int increment=size->size(ttype);
- int delt=offset-count;
- if (delt<mult*increment) {
- if (delt%increment==0) {
- return ttype;
- } else
+ if (increment%8) {
+ int delt=offset-count;
+ int byteincrement=increment/8;
+ if (delt<mult*byteincrement) {
+ if (delt%byteincrement==0) {
+ return ttype;
+ } else
+ return -1;
+ }
+ } else {
+ if ((count+sizeinbytes(mult*increment))>offset)
return -1;
}
- count+=mult*increment;
+ count+=sizeinbytes(mult*increment);
}
return -1;
}
bool typemap::checktype(bool doaction,void *ptr, int structure) {
- int ssize=size->size(structure);
+ int ssize=size->sizeBytes(structure);
void *low=ptr;
void *high=((char *)low)+ssize;
struct pair allocp=rbfind(low,high,alloctree);
bool istype(void *ptr, void *high, int structure);
void reset();
typeobject *size;
+ void initializestack(void *high);
private:
+ void *low;
+ void *high;
bool checkmemory(void* low, void* high);
bool checktype(bool doaction,void *ptr, int structure);
bool checktype(bool doaction, void *low, void *high,int structure, struct rbtree *ttree);