libdwfl/
2008-09-29 Roland McGrath <roland@redhat.com>
* segment.c (insert): Must realloc DWFL->lookup_module here too.
(dwfl_report_segment): Clear DWFL->lookup_module before insert calls.
diff --git a/libdwfl/segment.c b/libdwfl/segment.c
index 78220e3..cb520e6 100644
--- a/libdwfl/segment.c
+++ b/libdwfl/segment.c
@@ -83,12 +83,26 @@
int *nsegndx = realloc (dwfl->lookup_segndx, sizeof nsegndx[0] * n);
if (unlikely (nsegndx == NULL))
{
- free (naddr);
+ if (naddr != dwfl->lookup_addr)
+ free (naddr);
return true;
}
dwfl->lookup_alloc = n;
dwfl->lookup_addr = naddr;
dwfl->lookup_segndx = nsegndx;
+
+ if (dwfl->lookup_module != NULL)
+ {
+ /* Make sure this array is big enough too. */
+ Dwfl_Module **old = dwfl->lookup_module;
+ dwfl->lookup_module = realloc (dwfl->lookup_module,
+ sizeof dwfl->lookup_module[0] * n);
+ if (unlikely (dwfl->lookup_module == NULL))
+ {
+ free (old);
+ return true;
+ }
+ }
}
if (unlikely (i < dwfl->lookup_elts))
@@ -175,9 +189,17 @@
return true;
++idx;
}
+ else if (dwfl->lookup_addr[idx] < start)
+ {
+ /* The module starts past the end of this segment.
+ Add a new one. */
+ if (unlikely (insert (dwfl, idx + 1, start, end, -1)))
+ return true;
+ ++idx;
+ }
- if (((size_t) idx + 1 == dwfl->lookup_elts
- || end < dwfl->lookup_addr[idx + 1])
+ if ((size_t) idx + 1 < dwfl->lookup_elts
+ && end < dwfl->lookup_addr[idx + 1]
/* The module ends in the middle of this segment. Split it. */
&& unlikely (insert (dwfl, idx + 1,
end, dwfl->lookup_addr[idx + 1], -1)))
@@ -261,6 +283,12 @@
phdr->p_align < dwfl->segment_align))
dwfl->segment_align = phdr->p_align;
+ if (unlikely (dwfl->lookup_module != NULL))
+ {
+ free (dwfl->lookup_module);
+ dwfl->lookup_module = NULL;
+ }
+
GElf_Addr start = segment_start (dwfl, bias + phdr->p_vaddr);
GElf_Addr end = segment_end (dwfl, bias + phdr->p_vaddr + phdr->p_memsz);
@@ -289,12 +317,6 @@
dwfl->lookup_tail_offset = end - bias - phdr->p_vaddr + phdr->p_offset;
dwfl->lookup_tail_ndx = ndx + 1;
- if (unlikely (dwfl->lookup_module != NULL))
- {
- free (dwfl->lookup_module);
- dwfl->lookup_module = NULL;
- }
-
return ndx;
}
INTDEF (dwfl_report_segment)