1 /* Determine the virtual memory area of a given address. FreeBSD version.
2 Copyright (C) 2002-2003, 2006, 2008 Bruno Haible <bruno@clisp.org>
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software Foundation,
16 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
21 #include "stackvma-simple.c"
22 #include "stackvma-rofile.c"
25 # define sigsegv_get_vma mincore_get_vma
26 # define STATIC static
27 # include "stackvma-mincore.c"
28 # undef sigsegv_get_vma
32 sigsegv_get_vma (unsigned long address
, struct vma_struct
*vma
)
36 /* The stack appears as multiple adjacents segments, therefore we
37 merge adjacent segments. */
38 unsigned long next_start
, next_end
, curr_start
, curr_end
;
39 #if STACK_DIRECTION < 0
40 unsigned long prev_end
;
43 /* Open the current process' maps file. It describes one VMA per line. */
44 if (rof_open (&rof
, "/proc/curproc/map") < 0)
47 #if STACK_DIRECTION < 0
50 for (curr_start
= curr_end
= 0; ;)
52 if (!(rof_getchar (&rof
) == '0'
53 && rof_getchar (&rof
) == 'x'
54 && rof_scanf_lx (&rof
, &next_start
) >= 0))
56 while (c
= rof_peekchar (&rof
), c
== ' ' || c
== '\t')
58 if (!(rof_getchar (&rof
) == '0'
59 && rof_getchar (&rof
) == 'x'
60 && rof_scanf_lx (&rof
, &next_end
) >= 0))
62 while (c
= rof_getchar (&rof
), c
!= -1 && c
!= '\n')
64 if (next_start
== curr_end
)
66 /* Merge adjacent segments. */
71 if (curr_start
< curr_end
72 && address
>= curr_start
&& address
<= curr_end
-1)
74 #if STACK_DIRECTION < 0
77 curr_start
= next_start
; curr_end
= next_end
;
80 if (address
>= curr_start
&& address
<= curr_end
-1)
83 vma
->start
= curr_start
;
85 #if STACK_DIRECTION < 0
86 vma
->prev_end
= prev_end
;
88 if (rof_getchar (&rof
) == '0'
89 && rof_getchar (&rof
) == 'x'
90 && rof_scanf_lx (&rof
, &vma
->next_start
) >= 0)
92 while (c
= rof_peekchar (&rof
), c
== ' ' || c
== '\t')
94 if (rof_getchar (&rof
) == '0'
95 && rof_getchar (&rof
) == 'x'
96 && rof_scanf_lx (&rof
, &next_end
) >= 0)
105 vma
->is_near_this
= simple_is_near_this
;
111 /* FreeBSD 6.[01] doesn't allow to distinguish unmapped pages from
112 mapped but swapped-out pages. See whether it's fixed. */
114 /* OK, mincore() appears to work as expected. */
115 return mincore_get_vma (address
, vma
);