60 |
# include <signal.h> |
# include <signal.h> |
61 |
# endif |
# endif |
62 |
|
|
63 |
|
#if defined(LINUX) || defined(LINUX_STACKBOTTOM) |
64 |
|
# include <ctype.h> |
65 |
|
#endif |
66 |
|
|
67 |
/* Blatantly OS dependent routines, except for those that are related */ |
/* Blatantly OS dependent routines, except for those that are related */ |
68 |
/* to dynamic loading. */ |
/* to dynamic loading. */ |
69 |
|
|
84 |
# define NEED_FIND_LIMIT |
# define NEED_FIND_LIMIT |
85 |
# endif |
# endif |
86 |
|
|
87 |
#if defined(FREEBSD) && defined(I386) |
#if defined(FREEBSD) && (defined(I386) || defined(powerpc) || defined(__powerpc__)) |
88 |
# include <machine/trap.h> |
# include <machine/trap.h> |
89 |
# if !defined(PCR) |
# if !defined(PCR) |
90 |
# define NEED_FIND_LIMIT |
# define NEED_FIND_LIMIT |
249 |
// XXXXXXXX-XXXXXXXX r-xp 00000000 30:05 260537 name of mapping...\n |
// XXXXXXXX-XXXXXXXX r-xp 00000000 30:05 260537 name of mapping...\n |
250 |
// ^^^^^^^^ ^^^^^^^^ ^^^^ ^^ |
// ^^^^^^^^ ^^^^^^^^ ^^^^ ^^ |
251 |
// start end prot maj_dev |
// start end prot maj_dev |
|
// 0 9 18 32 |
|
|
// |
|
|
// For 64 bit ABIs: |
|
|
// 0 17 34 56 |
|
252 |
// |
// |
253 |
// The parser is called with a pointer to the entry and the return value |
// Note that since about auguat 2003 kernels, the columns no longer have |
254 |
// is either NULL or is advanced to the next entry(the byte after the |
// fixed offsets on 64-bit kernels. Hence we no longer rely on fixed offsets |
255 |
// trailing '\n'.) |
// anywhere, which is safer anyway. |
256 |
// |
// |
|
#if CPP_WORDSZ == 32 |
|
|
# define OFFSET_MAP_START 0 |
|
|
# define OFFSET_MAP_END 9 |
|
|
# define OFFSET_MAP_PROT 18 |
|
|
# define OFFSET_MAP_MAJDEV 32 |
|
|
# define ADDR_WIDTH 8 |
|
|
#endif |
|
|
|
|
|
#if CPP_WORDSZ == 64 |
|
|
# define OFFSET_MAP_START 0 |
|
|
# define OFFSET_MAP_END 17 |
|
|
# define OFFSET_MAP_PROT 34 |
|
|
# define OFFSET_MAP_MAJDEV 56 |
|
|
# define ADDR_WIDTH 16 |
|
|
#endif |
|
257 |
|
|
258 |
/* |
/* |
259 |
* Assign various fields of the first line in buf_ptr to *start, *end, |
* Assign various fields of the first line in buf_ptr to *start, *end, |
262 |
char *GC_parse_map_entry(char *buf_ptr, word *start, word *end, |
char *GC_parse_map_entry(char *buf_ptr, word *start, word *end, |
263 |
char *prot_buf, unsigned int *maj_dev) |
char *prot_buf, unsigned int *maj_dev) |
264 |
{ |
{ |
265 |
char *tok; |
char *start_start, *end_start, *prot_start, *maj_dev_start; |
266 |
|
char *p; |
267 |
|
char *endp; |
268 |
|
|
269 |
if (buf_ptr == NULL || *buf_ptr == '\0') { |
if (buf_ptr == NULL || *buf_ptr == '\0') { |
270 |
return NULL; |
return NULL; |
271 |
} |
} |
272 |
|
|
273 |
memcpy(prot_buf, buf_ptr+OFFSET_MAP_PROT, 4); |
p = buf_ptr; |
274 |
/* do the protections first. */ |
while (isspace(*p)) ++p; |
275 |
|
start_start = p; |
276 |
|
GC_ASSERT(isxdigit(*start_start)); |
277 |
|
*start = strtoul(start_start, &endp, 16); p = endp; |
278 |
|
GC_ASSERT(*p=='-'); |
279 |
|
|
280 |
|
++p; |
281 |
|
end_start = p; |
282 |
|
GC_ASSERT(isxdigit(*end_start)); |
283 |
|
*end = strtoul(end_start, &endp, 16); p = endp; |
284 |
|
GC_ASSERT(isspace(*p)); |
285 |
|
|
286 |
|
while (isspace(*p)) ++p; |
287 |
|
prot_start = p; |
288 |
|
GC_ASSERT(*prot_start == 'r' || *prot_start == '-'); |
289 |
|
memcpy(prot_buf, prot_start, 4); |
290 |
prot_buf[4] = '\0'; |
prot_buf[4] = '\0'; |
291 |
|
if (prot_buf[1] == 'w') {/* we can skip the rest if it's not writable. */ |
292 |
if (prot_buf[1] == 'w') {/* we can skip all of this if it's not writable. */ |
/* Skip past protection field to offset field */ |
293 |
|
while (!isspace(*p)) ++p; while (isspace(*p)) ++p; |
294 |
tok = buf_ptr; |
GC_ASSERT(isxdigit(*p)); |
295 |
buf_ptr[OFFSET_MAP_START+ADDR_WIDTH] = '\0'; |
/* Skip past offset field, which we ignore */ |
296 |
*start = strtoul(tok, NULL, 16); |
while (!isspace(*p)) ++p; while (isspace(*p)) ++p; |
297 |
|
maj_dev_start = p; |
298 |
tok = buf_ptr+OFFSET_MAP_END; |
GC_ASSERT(isxdigit(*maj_dev_start)); |
299 |
buf_ptr[OFFSET_MAP_END+ADDR_WIDTH] = '\0'; |
*maj_dev = strtoul(maj_dev_start, NULL, 16); |
|
*end = strtoul(tok, NULL, 16); |
|
|
|
|
|
buf_ptr += OFFSET_MAP_MAJDEV; |
|
|
tok = buf_ptr; |
|
|
while (*buf_ptr != ':') buf_ptr++; |
|
|
*buf_ptr++ = '\0'; |
|
|
*maj_dev = strtoul(tok, NULL, 16); |
|
300 |
} |
} |
301 |
|
|
302 |
while (*buf_ptr && *buf_ptr++ != '\n'); |
while (*p && *p++ != '\n'); |
303 |
|
|
304 |
return buf_ptr; |
return p; |
305 |
} |
} |
306 |
|
|
307 |
#endif /* Need to parse /proc/self/maps. */ |
#endif /* Need to parse /proc/self/maps. */ |
850 |
|
|
851 |
#include <sys/types.h> |
#include <sys/types.h> |
852 |
#include <sys/stat.h> |
#include <sys/stat.h> |
|
#include <ctype.h> |
|
853 |
|
|
854 |
# define STAT_SKIP 27 /* Number of fields preceding startstack */ |
# define STAT_SKIP 27 /* Number of fields preceding startstack */ |
855 |
/* field in /proc/self/stat */ |
/* field in /proc/self/stat */ |
1389 |
} |
} |
1390 |
# endif |
# endif |
1391 |
|
|
1392 |
# if defined(FREEBSD) && defined(I386) && !defined(PCR) |
# if defined(FREEBSD) && (defined(I386) || defined(powerpc) || defined(__powerpc__)) && !defined(PCR) |
1393 |
/* Its unclear whether this should be identical to the above, or */ |
/* Its unclear whether this should be identical to the above, or */ |
1394 |
/* whether it should apply to non-X86 architectures. */ |
/* whether it should apply to non-X86 architectures. */ |
1395 |
/* For now we don't assume that there is always an empty page after */ |
/* For now we don't assume that there is always an empty page after */ |