|
From: Jeremy F. <je...@go...> - 2005-01-18 21:29:50
|
CVS commit by fitzhardinge:
Make the use of the skiplist find functions a bit clearer, which extends
to the segment-finding functions.
M +4 -5 coregrind/core.h 1.69
M +6 -4 coregrind/vg_main.c 1.238
M +29 -20 coregrind/vg_memory.c 1.86
M +3 -2 coregrind/vg_scheduler.c 1.213
M +3 -16 coregrind/vg_signals.c 1.112
M +26 -1 coregrind/vg_skiplist.c 1.8
M +7 -7 coregrind/vg_symtab2.c 1.99
M +8 -7 coregrind/vg_syscalls.c 1.236
M +2 -5 coregrind/vg_translate.c 1.95
M +12 -3 coregrind/linux/syscalls.c 1.7
M +2 -3 coregrind/x86/signal.c 1.11
M +2 -2 coregrind/x86-linux/syscalls.c 1.17
M +7 -3 include/tool.h.base 1.20
M +1 -0 include/x86-linux/vki_arch.h 1.12
--- valgrind/coregrind/vg_skiplist.c #1.7:1.8
@@ -340,5 +340,6 @@ static SkipNode *SkipList__Find(const Sk
}
-void *VG_(SkipList_Find)(const SkipList *l, void *k)
+/* Return list element which is <= k, or NULL if there is none. */
+void *VG_(SkipList_Find_Before)(const SkipList *l, void *k)
{
SkipNode *n = SkipList__Find(l, k, NULL);
@@ -349,4 +350,28 @@ void *VG_(SkipList_Find)(const SkipList
}
+/* Return the list element which == k, or NULL if none */
+void *VG_(SkipList_Find_Exact)(const SkipList *l, void *k)
+{
+ SkipNode *n = SkipList__Find(l, k, NULL);
+
+ if (n != NULL && (l->cmp)(key_of_node(l, n), k) == 0)
+ return data_of_node(l, n);
+ return NULL;
+}
+
+/* Return the list element which is >= k, or NULL if none */
+void *VG_(SkipList_Find_After)(const SkipList *l, void *k)
+{
+ SkipNode *n = SkipList__Find(l, k, NULL);
+
+ if (n != NULL && (l->cmp)(key_of_node(l, n), k) < 0)
+ n = n->next[0];
+
+ if (n != NULL)
+ return data_of_node(l, n);
+
+ return NULL;
+}
+
void VG_(SkipList_Insert)(SkipList *l, void *data)
{
--- valgrind/coregrind/core.h #1.68:1.69
@@ -1235,13 +1235,12 @@ extern void VG_(mprotect_range)(Addr add
extern Addr VG_(find_map_space)(Addr base, SizeT len, Bool for_client);
-/* Find the segment containing or before 'a', or NULL if there isn't
- one. Would be better named "find_segment_before". */
-extern Segment *VG_(find_segment)(Addr a);
+/* Find the segment containing or before 'a', or NULL if there isn't one. */
+extern Segment *VG_(find_segment_before)(Addr a);
/* Find the segment containing or after 'a', or NULL if there isn't one. */
extern Segment *VG_(find_segment_after)(Addr a);
-/* Find the segment returning exactly 'a'. */
-extern Segment *VG_(find_segment_exact)(Addr a);
+/* Find the segment containing 'a', or NULL if there isn't one. */
+extern Segment *VG_(find_segment_containing)(Addr a);
extern Segment *VG_(first_segment)(void);
--- valgrind/coregrind/vg_memory.c #1.85:1.86
@@ -126,5 +126,5 @@ static inline Segment *allocseg()
Segment *VG_(split_segment)(Addr a)
{
- Segment *s = VG_(SkipList_Find)(&sk_segments, &a);
+ Segment *s = VG_(SkipList_Find_Before)(&sk_segments, &a);
Segment *ns;
Int delta;
@@ -191,5 +191,5 @@ void VG_(unmap_range)(Addr addr, SizeT l
vg_assert((len & (VKI_PAGE_SIZE-1)) == 0);
- for(s = VG_(SkipList_Find)(&sk_segments, &addr);
+ for(s = VG_(SkipList_Find_Before)(&sk_segments, &addr);
s != NULL && s->addr < (addr+len);
s = next) {
@@ -312,5 +312,5 @@ static void merge_segments(Addr a, SizeT
len += VKI_PAGE_SIZE;
- for(s = VG_(SkipList_Find)(&sk_segments, &a);
+ for(s = VG_(SkipList_Find_Before)(&sk_segments, &a);
s != NULL && s->addr < (a+len);) {
next = VG_(SkipNode_Next)(&sk_segments, s);
@@ -353,5 +353,5 @@ void VG_(map_file_segment)(Addr addr, Si
/* First look to see what already exists around here */
- s = VG_(SkipList_Find)(&sk_segments, &addr);
+ s = VG_(find_segment_containing)(addr);
if (s != NULL && s->addr == addr && s->len == len) {
@@ -500,5 +500,5 @@ void VG_(mprotect_range)(Addr a, SizeT l
if (debug) {
- s = VG_(find_segment)(a);
+ s = VG_(find_segment_before)(a);
VG_(printf)(" split: s1=%p-%p s2=%p-%p s(%p)=%p-%p\n",
s1 ? s1->addr : 0, s1 ? (s1->addr+s1->len) : 0,
@@ -508,5 +508,5 @@ void VG_(mprotect_range)(Addr a, SizeT l
}
- for(s = VG_(find_segment)(a);
+ for(s = VG_(find_segment_before)(a);
s != NULL && s->addr < a+len;
s = next)
@@ -553,5 +553,5 @@ Addr VG_(find_map_space)(Addr addr, Size
ret, ret+len, for_client);
- s = VG_(SkipList_Find)(&sk_segments, &ret);
+ s = VG_(SkipList_Find_Before)(&sk_segments, &ret);
if (s == NULL)
s = VG_(SkipNode_First)(&sk_segments);
@@ -601,5 +601,5 @@ Addr VG_(find_map_space)(Addr addr, Size
void VG_(pad_address_space)(Addr start)
{
- Addr addr = start == 0 ? VG_(client_base) : start;
+ Addr addr = (start == 0) ? VG_(client_base) : start;
Segment *s = VG_(find_segment_after)(addr);
Addr ret;
@@ -608,5 +608,6 @@ void VG_(pad_address_space)(Addr start)
if (addr < s->addr) {
PLATFORM_DO_MMAP(ret, addr, s->addr - addr, 0,
- VKI_MAP_FIXED | VKI_MAP_PRIVATE | VKI_MAP_ANONYMOUS,
+ VKI_MAP_FIXED | VKI_MAP_PRIVATE |
+ VKI_MAP_ANONYMOUS | VKI_MAP_NORESERVE,
-1, 0);
}
@@ -629,6 +630,6 @@ void VG_(pad_address_space)(Addr start)
void VG_(unpad_address_space)(Addr start)
{
- Addr addr = start == 0 ? VG_(client_base) : start;
- Segment *s = VG_(find_segment)(addr);
+ Addr addr = (start == 0) ? VG_(client_base) : start;
+ Segment *s = VG_(find_segment_after)(addr);
Int ret;
@@ -649,16 +650,17 @@ void VG_(unpad_address_space)(Addr start
}
-Segment *VG_(find_segment)(Addr a)
+Segment *VG_(find_segment_before)(Addr a)
{
- return VG_(SkipList_Find)(&sk_segments, &a);
+ return VG_(SkipList_Find_Before)(&sk_segments, &a);
}
/* Return the segment starting at exactly address 'a' */
-Segment *VG_(find_segment_exact)(Addr a)
+Segment *VG_(find_segment_containing)(Addr a)
{
- Segment *seg = VG_(find_segment)(a);
- if (seg && seg->addr != a)
+ Segment *seg = VG_(find_segment_before)(a);
+
+ if (seg && ((a < seg->addr) || (seg->addr + seg->len) <= a))
seg = NULL;
- return NULL;
+ return seg;
}
@@ -666,5 +668,12 @@ Segment *VG_(find_segment_exact)(Addr a)
Segment *VG_(find_segment_after)(Addr a)
{
- Segment *seg = VG_(find_segment)(a);
+ Segment *seg = VG_(find_segment_before)(a);
+
+ if (seg == NULL) {
+ // If there's nothing before the address, then the next segment
+ // is the first
+ seg = VG_(first_segment)();
+ }
+
while (seg && a >= (seg->addr+seg->len))
seg = VG_(next_segment)(seg);
@@ -764,5 +773,5 @@ Bool VG_(is_addressable)(Addr p, SizeT s
return False;
- for(seg = VG_(find_segment)(p);
+ for(seg = VG_(find_segment_containing)(p);
size > 0 &&
seg &&
@@ -807,5 +816,5 @@ Addr VG_(client_alloc)(Addr addr, SizeT
void VG_(client_free)(Addr addr)
{
- Segment *s = VG_(find_segment)(addr);
+ Segment *s = VG_(find_segment_containing)(addr);
if (s == NULL || s->addr != addr || !(s->flags & SF_CORE)) {
--- valgrind/coregrind/vg_scheduler.c #1.212:1.213
@@ -383,5 +383,6 @@ void VG_(exit_thread)(ThreadId tid)
the stack after thread death... */
if (0 && VG_(threads)[tid].stack_base) {
- Segment *seg = VG_(find_segment)( VG_(threads)[tid].stack_base );
+ Segment *seg = VG_(find_segment_containing)( VG_(threads)[tid].stack_base );
+ if (seg)
VG_TRACK( die_mem_stack, seg->addr, seg->len );
}
--- valgrind/coregrind/vg_main.c #1.237:1.238
@@ -2325,4 +2325,7 @@ static void build_valgrind_map_callback
SF_MMAP|SF_NOSYMS|SF_VALGRIND,
dev, ino, foffset, filename);
+ /* update VG_(valgrind_last) if it looks wrong */
+ if (start+size > VG_(valgrind_last))
+ VG_(valgrind_last) = start+size-1;
}
}
@@ -2365,5 +2368,5 @@ static void build_segment_map_callback (
if (start >= VG_(client_end) && start < VG_(valgrind_last)) {
- Segment *s = VG_(find_segment)(start);
+ Segment *s = VG_(find_segment_before)(start);
/* We have to be a bit careful about inserting new mappings into
@@ -2745,7 +2748,6 @@ int main(int argc, char **argv, char **e
/* Make sure this segment isn't treated as stack */
- seg = VG_(find_segment)(VG_(client_trampoline_code));
- if (seg && VG_(seg_contains)(seg, VG_(client_trampoline_code),
- VG_(trampoline_code_length)))
+ seg = VG_(find_segment_containing)(VG_(client_trampoline_code));
+ if (seg)
seg->flags &= ~(SF_STACK | SF_GROWDOWN);
}
--- valgrind/coregrind/vg_signals.c #1.111:1.112
@@ -1594,11 +1594,7 @@ Bool VG_(extend_stack)(Addr addr, UInt m
/* Find the next Segment above addr */
- seg = VG_(find_segment)(addr);
- if (seg == NULL)
- seg = VG_(first_segment)();
- else if (VG_(seg_contains)(seg, addr, sizeof(void *)))
+ seg = VG_(find_segment_after)(addr);
+ if (seg && VG_(seg_contains)(seg, addr, sizeof(void *)))
return True;
- else
- seg = VG_(next_segment)(seg);
/* If there isn't one, or it isn't growable, fail */
@@ -1675,16 +1671,7 @@ void vg_sync_signalhandler ( Int sigNo,
? VG_(baseBlock)[VGOFF_STACK_PTR]
: ARCH_STACK_PTR(VG_(threads)[tid].arch);
- Segment *seg;
-
- /* If the fault happened between segments, find the segment
- after the fault. This is because we want to see if we can
- grow this segment down to cover the fault address. */
- seg = VG_(find_segment)(fault);
- if (seg == NULL)
- seg = VG_(first_segment)();
- else if (seg->addr+seg->len <= fault)
- seg = VG_(next_segment)(seg);
if (VG_(clo_trace_signals)) {
+ Segment *seg = VG_(find_segment_containing)(fault);
if (seg == NULL)
VG_(message)(Vg_DebugMsg,
--- valgrind/coregrind/vg_symtab2.c #1.98:1.99
@@ -1323,5 +1323,5 @@ Bool vg_read_lib_symbols ( SegInfo* si )
si->start+newsz, newsz);
- for(seg = VG_(find_segment)(si->start);
+ for(seg = VG_(find_segment_containing)(si->start);
seg != NULL && VG_(seg_overlaps)(seg, si->start, si->size);
seg = VG_(next_segment)(seg)) {
@@ -1723,7 +1723,7 @@ static void search_all_symtabs ( Addr pt
VGP_PUSHCC(VgpSearchSyms);
- s = VG_(find_segment)(ptr);
+ s = VG_(find_segment_containing)(ptr);
- if (s == NULL || !VG_(seg_overlaps)(s, ptr, 0) || s->symtab == NULL)
+ if (s == NULL || s->symtab == NULL)
goto not_found;
@@ -2393,7 +2393,7 @@ static Bool resolve_redir(CodeRedirect *
{
- CodeRedirect *r = VG_(SkipList_Find)(&sk_resolved_redir, &redir->from_addr);
+ CodeRedirect *r = VG_(SkipList_Find_Exact)(&sk_resolved_redir, &redir->from_addr);
- if (r == NULL || r->from_addr != redir->from_addr)
+ if (r == NULL)
VG_(SkipList_Insert)(&sk_resolved_redir, redir);
else if (verbose_redir)
@@ -2493,7 +2493,7 @@ static void add_redirect_addr(const Char
Addr VG_(code_redirect)(Addr a)
{
- CodeRedirect *r = VG_(SkipList_Find)(&sk_resolved_redir, &a);
+ CodeRedirect *r = VG_(SkipList_Find_Exact)(&sk_resolved_redir, &a);
- if (r == NULL || r->from_addr != a)
+ if (r == NULL)
return a;
--- valgrind/coregrind/vg_syscalls.c #1.235:1.236
@@ -236,8 +236,8 @@ Addr mremap_segment ( Addr old_addr, Siz
return old_addr;
- seg = VG_(find_segment)(old_addr);
+ seg = VG_(find_segment_containing)(old_addr);
/* range must be contained within segment */
- if (seg == NULL || !VG_(seg_contains)(seg, old_addr, old_size))
+ if (seg == NULL)
return -VKI_EINVAL;
@@ -906,7 +906,8 @@ static Addr do_brk(Addr newbrk)
/* brk isn't allowed to grow over anything else */
- seg = VG_(find_segment)(VG_(brk_limit));
+ seg = VG_(find_segment_before)(VG_(brk_limit));
- vg_assert(seg != NULL);
+ if (seg == NULL)
+ return VG_(brk_limit); /* brk unmapped - no change */
if (0)
@@ -916,5 +917,5 @@ static Addr do_brk(Addr newbrk)
seg = VG_(next_segment)(seg);
- if (seg != NULL && newbrk > seg->addr)
+ if (seg != NULL && newbrk > seg->addr) /* brk crashes into next segment - no change */
return VG_(brk_limit);
@@ -2766,7 +2767,7 @@ POST(sys_ipc)
case 22: /* IPCOP_shmdt */
{
- Segment *s = VG_(find_segment)(arg5);
+ Segment *s = VG_(find_segment_containing)(arg5);
- if (s != NULL && (s->flags & SF_SHM) && VG_(seg_contains)(s, arg5, 1)) {
+ if (s != NULL && (s->flags & SF_SHM)) {
VG_TRACK( die_mem_munmap, s->addr, s->len );
VG_(unmap_range)(s->addr, s->len);
--- valgrind/coregrind/vg_translate.c #1.94:1.95
@@ -2468,5 +2468,5 @@ Bool VG_(translate) ( ThreadId tid, Addr
notrace_until_done = VG_(get_bbs_translated)() >= notrace_until_limit;
- seg = VG_(find_segment)(orig_addr);
+ seg = VG_(find_segment_containing)(orig_addr);
if (!debugging_translation)
@@ -2474,10 +2474,7 @@ Bool VG_(translate) ( ThreadId tid, Addr
if (seg == NULL ||
- !VG_(seg_contains)(seg, orig_addr, 1) ||
(seg->prot & (VKI_PROT_READ|VKI_PROT_EXEC)) == 0) {
/* Code address is bad - deliver a signal instead */
- vg_assert(!VG_(is_addressable)(orig_addr, 1, VKI_PROT_EXEC));
-
- if (seg != NULL && VG_(seg_contains)(seg, orig_addr, 1)) {
+ if (seg != NULL) {
vg_assert((seg->prot & VKI_PROT_EXEC) == 0);
VG_(synth_fault_perms)(tid, orig_addr);
--- valgrind/include/tool.h.base #1.19:1.20
@@ -1686,6 +1686,8 @@
/* List operations:
- SkipList_Find searchs a list. If it can't find an exact match, it either
- returns NULL or a pointer to the element before where k would go
+ SkipList_Find_* search a list. The 3 variants are:
+ Before: returns a node which is <= key, or NULL if none
+ Exact: returns a node which is == key, or NULL if none
+ After: returns a node which is >= key, or NULL if none
SkipList_Insert inserts a new element into the list. Duplicates are
forbidden. The element must have been created with SkipList_Alloc!
@@ -1693,5 +1695,7 @@
doesn't free the memory.
*/
-extern void *VG_(SkipList_Find) (const SkipList *l, void *key);
+extern void *VG_(SkipList_Find_Before) (const SkipList *l, void *key);
+extern void *VG_(SkipList_Find_Exact) (const SkipList *l, void *key);
+extern void *VG_(SkipList_Find_After) (const SkipList *l, void *key);
extern void VG_(SkipList_Insert)( SkipList *l, void *data);
extern void *VG_(SkipList_Remove)( SkipList *l, void *key);
--- valgrind/coregrind/x86/signal.c #1.10:1.11
@@ -356,5 +356,5 @@ static Bool extend(ThreadState *tst, Add
if (VG_(extend_stack)(addr, tst->stack_size)) {
- stackseg = VG_(find_segment)(addr);
+ stackseg = VG_(find_segment_containing)(addr);
if (0 && stackseg)
VG_(printf)("frame=%p seg=%p-%p\n",
@@ -362,6 +362,5 @@ static Bool extend(ThreadState *tst, Add
}
- if (stackseg == NULL ||
- !VG_(is_addressable)(addr, size, VKI_PROT_READ|VKI_PROT_WRITE)) {
+ if (stackseg == NULL || (stackseg->prot & (VKI_PROT_READ|VKI_PROT_WRITE)) == 0) {
VG_(message)(Vg_UserMsg,
"Can't extend stack to %p during signal delivery for thread %d:",
--- valgrind/coregrind/x86-linux/syscalls.c #1.16:1.17
@@ -323,6 +323,6 @@ static Int do_clone(ThreadId ptid,
assume that esp starts near its highest possible value, and can
only go down to the start of the mmaped segment. */
- seg = VG_(find_segment)((Addr)esp);
- if (VG_(seg_contains)(seg, (Addr)esp, sizeof(UInt))) {
+ seg = VG_(find_segment_containing)((Addr)esp);
+ if (seg) {
ctst->stack_base = seg->addr;
ctst->stack_size = (Addr)PGROUNDUP(esp) - seg->addr;
--- valgrind/coregrind/linux/syscalls.c #1.6:1.7
@@ -500,5 +500,11 @@ PRE(sys_io_setup, Special)
arg1*sizeof(struct vki_io_event));
addr = VG_(find_map_space)(0, size, True);
- VG_(map_segment)(addr, size, VKI_PROT_READ|VKI_PROT_EXEC, SF_FIXED);
+
+ if (addr == 0) {
+ set_result( -VKI_ENOMEM );
+ return;
+ }
+
+ VG_(map_segment)(addr, size, VKI_PROT_READ|VKI_PROT_WRITE, SF_FIXED);
VG_(pad_address_space)(0);
@@ -525,7 +531,10 @@ PRE(sys_io_setup, Special)
// know that we must look at the aio_ring structure because Tom inspected the
// kernel and glibc sources to see what they do, yuk.)
+//
+// XXX This segment can be implicitly unmapped when aio
+// file-descriptors are closed...
PRE(sys_io_destroy, Special)
{
- Segment *s = VG_(find_segment)(arg1);
+ Segment *s = VG_(find_segment_containing)(arg1);
struct vki_aio_ring *r;
SizeT size;
@@ -542,5 +551,5 @@ PRE(sys_io_destroy, Special)
set_result( VG_(do_syscall)(SYSNO, arg1) );
- if (res == 0 && s != NULL && VG_(seg_contains)(s, arg1, size)) {
+ if (res == 0 && s != NULL) {
VG_TRACK( die_mem_munmap, arg1, size );
VG_(unmap_range)(arg1, size);
--- valgrind/include/x86-linux/vki_arch.h #1.11:1.12
@@ -262,4 +262,5 @@ struct vki_sigcontext {
#define VKI_MAP_FIXED 0x10 /* Interpret addr exactly */
#define VKI_MAP_ANONYMOUS 0x20 /* don't use a file */
+#define VKI_MAP_NORESERVE 0x4000 /* don't check for reservations */
//----------------------------------------------------------------------
|