You can subscribe to this list here.
| 2002 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(1) |
Oct
(122) |
Nov
(152) |
Dec
(69) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2003 |
Jan
(6) |
Feb
(25) |
Mar
(73) |
Apr
(82) |
May
(24) |
Jun
(25) |
Jul
(10) |
Aug
(11) |
Sep
(10) |
Oct
(54) |
Nov
(203) |
Dec
(182) |
| 2004 |
Jan
(307) |
Feb
(305) |
Mar
(430) |
Apr
(312) |
May
(187) |
Jun
(342) |
Jul
(487) |
Aug
(637) |
Sep
(336) |
Oct
(373) |
Nov
(441) |
Dec
(210) |
| 2005 |
Jan
(385) |
Feb
(480) |
Mar
(636) |
Apr
(544) |
May
(679) |
Jun
(625) |
Jul
(810) |
Aug
(838) |
Sep
(634) |
Oct
(521) |
Nov
(965) |
Dec
(543) |
| 2006 |
Jan
(494) |
Feb
(431) |
Mar
(546) |
Apr
(411) |
May
(406) |
Jun
(322) |
Jul
(256) |
Aug
(401) |
Sep
(345) |
Oct
(542) |
Nov
(308) |
Dec
(481) |
| 2007 |
Jan
(427) |
Feb
(326) |
Mar
(367) |
Apr
(255) |
May
(244) |
Jun
(204) |
Jul
(223) |
Aug
(231) |
Sep
(354) |
Oct
(374) |
Nov
(497) |
Dec
(362) |
| 2008 |
Jan
(322) |
Feb
(482) |
Mar
(658) |
Apr
(422) |
May
(476) |
Jun
(396) |
Jul
(455) |
Aug
(267) |
Sep
(280) |
Oct
(253) |
Nov
(232) |
Dec
(304) |
| 2009 |
Jan
(486) |
Feb
(470) |
Mar
(458) |
Apr
(423) |
May
(696) |
Jun
(461) |
Jul
(551) |
Aug
(575) |
Sep
(134) |
Oct
(110) |
Nov
(157) |
Dec
(102) |
| 2010 |
Jan
(226) |
Feb
(86) |
Mar
(147) |
Apr
(117) |
May
(107) |
Jun
(203) |
Jul
(193) |
Aug
(238) |
Sep
(300) |
Oct
(246) |
Nov
(23) |
Dec
(75) |
| 2011 |
Jan
(133) |
Feb
(195) |
Mar
(315) |
Apr
(200) |
May
(267) |
Jun
(293) |
Jul
(353) |
Aug
(237) |
Sep
(278) |
Oct
(611) |
Nov
(274) |
Dec
(260) |
| 2012 |
Jan
(303) |
Feb
(391) |
Mar
(417) |
Apr
(441) |
May
(488) |
Jun
(655) |
Jul
(590) |
Aug
(610) |
Sep
(526) |
Oct
(478) |
Nov
(359) |
Dec
(372) |
| 2013 |
Jan
(467) |
Feb
(226) |
Mar
(391) |
Apr
(281) |
May
(299) |
Jun
(252) |
Jul
(311) |
Aug
(352) |
Sep
(481) |
Oct
(571) |
Nov
(222) |
Dec
(231) |
| 2014 |
Jan
(185) |
Feb
(329) |
Mar
(245) |
Apr
(238) |
May
(281) |
Jun
(399) |
Jul
(382) |
Aug
(500) |
Sep
(579) |
Oct
(435) |
Nov
(487) |
Dec
(256) |
| 2015 |
Jan
(338) |
Feb
(357) |
Mar
(330) |
Apr
(294) |
May
(191) |
Jun
(108) |
Jul
(142) |
Aug
(261) |
Sep
(190) |
Oct
(54) |
Nov
(83) |
Dec
(22) |
| 2016 |
Jan
(49) |
Feb
(89) |
Mar
(33) |
Apr
(50) |
May
(27) |
Jun
(34) |
Jul
(53) |
Aug
(53) |
Sep
(98) |
Oct
(206) |
Nov
(93) |
Dec
(53) |
| 2017 |
Jan
(65) |
Feb
(82) |
Mar
(102) |
Apr
(86) |
May
(187) |
Jun
(67) |
Jul
(23) |
Aug
(93) |
Sep
(65) |
Oct
(45) |
Nov
(35) |
Dec
(17) |
| 2018 |
Jan
(26) |
Feb
(35) |
Mar
(38) |
Apr
(32) |
May
(8) |
Jun
(43) |
Jul
(27) |
Aug
(30) |
Sep
(43) |
Oct
(42) |
Nov
(38) |
Dec
(67) |
| 2019 |
Jan
(32) |
Feb
(37) |
Mar
(53) |
Apr
(64) |
May
(49) |
Jun
(18) |
Jul
(14) |
Aug
(53) |
Sep
(25) |
Oct
(30) |
Nov
(49) |
Dec
(31) |
| 2020 |
Jan
(87) |
Feb
(45) |
Mar
(37) |
Apr
(51) |
May
(99) |
Jun
(36) |
Jul
(11) |
Aug
(14) |
Sep
(20) |
Oct
(24) |
Nov
(40) |
Dec
(23) |
| 2021 |
Jan
(14) |
Feb
(53) |
Mar
(85) |
Apr
(15) |
May
(19) |
Jun
(3) |
Jul
(14) |
Aug
(1) |
Sep
(57) |
Oct
(73) |
Nov
(56) |
Dec
(22) |
| 2022 |
Jan
(3) |
Feb
(22) |
Mar
(6) |
Apr
(55) |
May
(46) |
Jun
(39) |
Jul
(15) |
Aug
(9) |
Sep
(11) |
Oct
(34) |
Nov
(20) |
Dec
(36) |
| 2023 |
Jan
(79) |
Feb
(41) |
Mar
(99) |
Apr
(169) |
May
(48) |
Jun
(16) |
Jul
(16) |
Aug
(57) |
Sep
(19) |
Oct
|
Nov
|
Dec
|
| S | M | T | W | T | F | S |
|---|---|---|---|---|---|---|
|
|
|
1
(11) |
2
(9) |
3
(14) |
4
(18) |
5
(13) |
|
6
(4) |
7
(12) |
8
(16) |
9
(14) |
10
(8) |
11
(9) |
12
(7) |
|
13
(12) |
14
(6) |
15
(14) |
16
(5) |
17
(10) |
18
(8) |
19
(5) |
|
20
(10) |
21
(16) |
22
(5) |
23
(14) |
24
(10) |
25
(11) |
26
(6) |
|
27
(9) |
28
(8) |
29
(11) |
30
(9) |
31
(18) |
|
|
|
From: Bart V. A. <bar...@gm...> - 2008-01-07 20:52:31
|
On Dec 3, 2007 1:35 PM, Julian Seward <js...@ac...> wrote: > On Monday 03 December 2007 09:47, Tom Hughes wrote: > > In message <Pin...@mu...> > > > > Nicholas Nethercote <nj...@cs...> wrote: > > > I can either change the script to run 'make exp-regtest' -- which will > > > require Tom and Julian to update their copy of the script on those > > > machines -- or we can change 'make regtest' run all of them. I'm leaning > > > towards the latter, as an incentive to get the exp-tools' tests working > > > as well as possible. Julian, what do you think? > > I'd say, for now change the script to run make exp-regtest too. > Tom's machines will auto-update and I'll change mine to do whatever > Tom's are doing. After 3.3.0 is done we can merge make exp-regtest > into standard make regtest. Now that 3.3.0 has been released, can the aforementioned change please be implemented ? I recommend to run the exp-drd regression tests only on x86 and x86_64, and not on ppc or AIX. Bart. |
|
From: <sv...@va...> - 2008-01-07 19:24:26
|
Author: sewardj
Date: 2008-01-07 19:24:26 +0000 (Mon, 07 Jan 2008)
New Revision: 7319
Log:
Commit initial framework changes aimed at making data symbol reading
and .got/.plt identification work properly on Linux.
The basic observation is that until now, Valgrind has waited until an
ELF file is mapped r-x, then attempted to read both text and data
symbols for the file. That's reasonable for the text symbols but is
nonsense for the data symbols, since we have no idea where ld.so will
later map the file's data section.
The basic change is to cause debuginfo.c to wait to see both a r-x and
a rw- mapping for an ELF object file, before reading its symbols.
Only that way will we know where the data segment is mapped to, and
hence can we know what the data symbol actual VMAs are.
As well as revising the when-to-load-symbols logic, much accumulated
cruft in readelf.c is being tidied up.
Note this is work in progress and is majorly broken at the moment.
Modified:
branches/DATASYMS/coregrind/m_debuginfo/debuginfo.c
branches/DATASYMS/coregrind/m_debuginfo/priv_readelf.h
branches/DATASYMS/coregrind/m_debuginfo/priv_storage.h
branches/DATASYMS/coregrind/m_debuginfo/readelf.c
Modified: branches/DATASYMS/coregrind/m_debuginfo/debuginfo.c
===================================================================
--- branches/DATASYMS/coregrind/m_debuginfo/debuginfo.c 2008-01-05 00:12:45 UTC (rev 7318)
+++ branches/DATASYMS/coregrind/m_debuginfo/debuginfo.c 2008-01-07 19:24:26 UTC (rev 7319)
@@ -42,6 +42,7 @@
#include "pub_core_libcbase.h"
#include "pub_core_libcassert.h"
#include "pub_core_libcprint.h"
+#include "pub_core_libcfile.h"
#include "pub_core_mallocfree.h"
#include "pub_core_options.h"
#include "pub_core_redir.h" // VG_(redir_notify_{new,delete}_SegInfo)
@@ -237,7 +238,7 @@
}
}
-
+#if 0
/* Create a new SegInfo with the specific address/length/vma offset,
then snarf whatever info we can from the given filename into it. */
static
@@ -281,8 +282,116 @@
return si;
}
+#endif
+static Bool ranges_overlap (Addr s1, SizeT len1, Addr s2, SizeT len2 )
+{
+ Addr e1, e2;
+ if (len1 == 0 || len2 == 0)
+ return False;
+ e1 = s1 + len1 - 1;
+ e2 = s2 + len2 - 1;
+ /* Assert that we don't have wraparound. If we do it would imply
+ that file sections are getting mapped around the end of the
+ address space, which sounds unlikely. */
+ vg_assert(s1 <= e1);
+ vg_assert(s2 <= e2);
+ if (e1 < s2 || e2 < s1) return False;
+ return True;
+}
+static Bool do_SegInfos_overlap ( SegInfo* si1, SegInfo* si2 )
+{
+ vg_assert(si1);
+ vg_assert(si2);
+
+ if (si1->have_rx_map && si2->have_rx_map
+ && ranges_overlap(si1->rx_map_avma, si1->rx_map_size,
+ si2->rx_map_avma, si2->rx_map_size))
+ return True;
+
+ if (si1->have_rx_map && si2->have_rw_map
+ && ranges_overlap(si1->rx_map_avma, si1->rx_map_size,
+ si2->rw_map_avma, si2->rw_map_size))
+ return True;
+
+ if (si1->have_rw_map && si2->have_rx_map
+ && ranges_overlap(si1->rw_map_avma, si1->rw_map_size,
+ si2->rx_map_avma, si2->rx_map_size))
+ return True;
+
+ if (si1->have_rw_map && si2->have_rw_map
+ && ranges_overlap(si1->rw_map_avma, si1->rw_map_size,
+ si2->rw_map_avma, si2->rw_map_size))
+ return True;
+
+ return False;
+}
+
+static void discard_marked_SegInfos ( void )
+{
+ SegInfo* curr;
+
+ while (True) {
+
+ curr = segInfo_list;
+ while (True) {
+ if (curr == NULL)
+ break;
+ if (curr->mark)
+ break;
+ curr = curr->next;
+ }
+
+ if (!curr) break;
+ discard_SegInfo( curr );
+
+ }
+}
+
+static void discard_SegInfos_which_overlap_with ( SegInfo* siRef )
+{
+ SegInfo* si;
+ /* Mark all the SegInfos in segInfo_list that need to be deleted.
+ First, clear all the mark bits; then set them if they overlap
+ with siRef. Since siRef itself is in this list we at least
+ expect its own mark bit to be set. */
+ for (si = segInfo_list; si; si = si->next) {
+ si->mark = do_SegInfos_overlap( si, siRef );
+ if (si == siRef) {
+ vg_assert(si->mark);
+ si->mark = False;
+ }
+ }
+ discard_marked_SegInfos();
+}
+
+/* Find the existing SegInfo for (memname,filename) or if not found,
+ create one. In the latter case memname and filename are strdup'd
+ into VG_AR_DINFO, and the new SegInfo is added to segInfo_list. */
+static
+SegInfo* find_or_create_SegInfo_for ( UChar* filename, UChar* memname )
+{
+ SegInfo* si;
+ vg_assert(filename);
+ for (si = segInfo_list; si; si = si->next) {
+ vg_assert(si->filename);
+ if (0==VG_(strcmp)(si->filename, filename)
+ && ( (memname && si->memname)
+ ? 0==VG_(strcmp)(memname, si->memname)
+ : True ))
+ break;
+ }
+ if (!si) {
+ si = alloc_SegInfo(0,0,0, filename, memname);
+ vg_assert(si);
+ si->next = segInfo_list;
+ segInfo_list = si;
+ }
+ return si;
+}
+
+
/*--------------------------------------------------------------*/
/*--- ---*/
/*--- TOP LEVEL: NOTIFICATION (ACQUIRE/DISCARD INFO) (LINUX) ---*/
@@ -308,15 +417,73 @@
{
NSegment const * seg;
HChar* filename;
- Bool ok;
+ Bool ok, is_rx_map, is_rw_map;
+ SegInfo* si;
+ SysRes fd;
+ Int nread;
+ HChar buf1k[1024];
+ Bool debug = False;
- /* If this mapping is at the beginning of a file, isn't part of
- Valgrind, is at least readable and seems to contain an object
- file, then try reading symbols from it.
+ /* In short, figure out if this mapping is of interest to us, and
+ if so, try to guess what ld.so is doing and when/if we should
+ read debug info. */
+ seg = VG_(am_find_nsegment)(a);
+ vg_assert(seg);
- Getting this heuristic right is critical. On x86-linux, objects
- are typically mapped twice:
+ if (debug)
+ VG_(printf)("di_notify_mmap-1: %p-%p %c%c%c\n",
+ seg->start, seg->end,
+ seg->hasR ? 'r' : '-',
+ seg->hasW ? 'w' : '-',seg->hasX ? 'x' : '-' );
+ /* guaranteed by aspacemgr-linux.c, sane_NSegment() */
+ vg_assert(seg->end > seg->start);
+
+ /* Ignore non-file mappings */
+ if ( ! (seg->kind == SkFileC
+ || (seg->kind == SkFileV && allow_SkFileV)) )
+ return;
+
+ /* If the file doesn't have a name, we're hosed. Give up. */
+ filename = VG_(am_get_filename)( (NSegment*)seg );
+ if (!filename)
+ return;
+
+ if (debug)
+ VG_(printf)("di_notify_mmap-2: %s\n", filename);
+
+ /* Peer at the first few bytes of the file, to see if it is an ELF
+ object file. */
+ VG_(memset)(buf1k, 0, sizeof(buf1k));
+ fd = VG_(open)( filename, VKI_O_RDONLY, 0 );
+ if (fd.isError) {
+ ML_(symerr)("can't open file to inspect ELF header");
+ return;
+ }
+ nread = VG_(read)( fd.res, buf1k, sizeof(buf1k) );
+ VG_(close)( fd.res );
+
+ if (nread <= 0) {
+ ML_(symerr)("can't read file to inspect ELF header");
+ return;
+ }
+ vg_assert(nread > 0 && nread <= sizeof(buf1k) );
+
+ /* We're only interested in mappings of ELF object files. */
+ if (!ML_(is_elf_object_file)( buf1k, (SizeT)nread ))
+ return;
+
+ /* Now we have to guess if this is a text-like mapping, a data-like
+ mapping, neither or both. The rules are:
+
+ text if: x86-linux r and x
+ other-linux r and x and not w
+
+ data if: x86-linux r and w
+ other-linux r and w and not x
+
+ Background: On x86-linux, objects are typically mapped twice:
+
1b8fb000-1b8ff000 r-xp 00000000 08:02 4471477 vgpreload_memcheck.so
1b8ff000-1b900000 rw-p 00004000 08:02 4471477 vgpreload_memcheck.so
@@ -333,53 +500,87 @@
to redirect to addresses in that third segment, which is wrong
and causes crashes.
- ------
JRS 28 Dec 05: unfortunately icc 8.1 on x86 has been seen to
produce executables with a single rwx segment rather than a
(r-x,rw-) pair. That means the rules have to be modified thusly:
x86-linux: consider if r and x
- all others: consider if r and x and NOT w
+ all others: consider if r and x and not w
*/
+ is_rx_map = False;
+ is_rw_map = False;
# if defined(VGP_x86_linux)
- Bool require_no_W = False;
+ is_rx_map = seg->hasR && seg->hasX;
+ is_rw_map = seg->hasR && seg->hasW;
+# elif defined(VGP_amd64_linux) \
+ || defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
+ is_rx_map = seg->hasR && seg->hasX && !seg->hasW;
+ is_rw_map = seg->hasR && seg->hasW && !seg->hasX;
# else
- Bool require_no_W = True;
+# error "Unknown platform"
# endif
- seg = VG_(am_find_nsegment)(a);
- vg_assert(seg);
+ if (debug)
+ VG_(printf)("di_notify_mmap-3: is_rx_map %d, is_rw_map %d\n",
+ (Int)is_rx_map, (Int)is_rw_map);
- filename = VG_(am_get_filename)( (NSegment*)seg );
- if (!filename)
+ /* If it is neither text-ish nor data-ish, we're not interested. */
+ if (!(is_rx_map || is_rw_map))
return;
- filename = VG_(arena_strdup)( VG_AR_DINFO, filename );
+ /* See if we have a SegInfo for this filename. If not,
+ create one. */
+ si = find_or_create_SegInfo_for( filename, NULL/*membername*/ );
+ vg_assert(si);
- ok = (seg->kind == SkFileC || (seg->kind == SkFileV && allow_SkFileV))
- && seg->offset == 0
- && seg->fnIdx != -1
- && seg->hasR
- && seg->hasX
- && (require_no_W ? (!seg->hasW) : True)
- && ML_(is_elf_object_file)( (const void*)seg->start );
+ if (is_rx_map) {
+ /* We have a text-like mapping. Note the details. */
+ if (!si->have_rx_map) {
+ si->have_rx_map = True;
+ si->rx_map_avma = a;
+ si->rx_map_size = seg->end + 1 - seg->start;
+ si->rx_map_foff = seg->offset;
+ } else {
+ /* FIXME: complain about a second text-like mapping */
+ }
+ }
- if (!ok) {
- VG_(arena_free)(VG_AR_DINFO, filename);
- return;
+ if (is_rw_map) {
+ /* We have a data-like mapping. Note the details. */
+ if (!si->have_rw_map) {
+ si->have_rw_map = True;
+ si->rw_map_avma = a;
+ si->rw_map_size = seg->end + 1 - seg->start;
+ si->rw_map_foff = seg->offset;
+ } else {
+ /* FIXME: complain about a second data-like mapping */
+ }
}
- /* Dump any info previously associated with the range. */
- discard_syms_in_range( seg->start, seg->end + 1 - seg->start );
+ if (si->have_rx_map && si->have_rw_map && !si->have_dinfo) {
+ /* We're going to read symbols and debug info for the vma ranges
+ [rx_map_avma,+rx_map_size) and [rw_map_avma,+rw_map_size).
+ First get rid of any other SegInfos which overlap either of
+ those ranges (to avoid total confusion). */
+ discard_SegInfos_which_overlap_with( si );
- /* .. and acquire new info. */
- acquire_syms_for_range( seg->start, seg->end + 1 - seg->start,
- seg->offset, filename,
- /* XCOFF only */ NULL, 0, 0, False );
+ /* .. and acquire new info. */
+ ok = ML_(read_elf_debug_info)( si );
- /* acquire_syms_for_range makes its own copy of filename, so is
- safe to free it. */
- VG_(arena_free)(VG_AR_DINFO, filename);
+ if (ok) {
+ /* prepare read data for use */
+ ML_(canonicaliseTables) ( si );
+ /* notify m_redir about it */
+ VG_(redir_notify_new_SegInfo)( si );
+ /* Note that we succeeded */
+ si->have_dinfo = True;
+ } else {
+ /* Something went wrong (eg. bad ELF file). Should we delete
+ this SegInfo? No - it contains info on the rw/rx mappings,
+ at least. */
+ }
+
+ }
}
Modified: branches/DATASYMS/coregrind/m_debuginfo/priv_readelf.h
===================================================================
--- branches/DATASYMS/coregrind/m_debuginfo/priv_readelf.h 2008-01-05 00:12:45 UTC (rev 7318)
+++ branches/DATASYMS/coregrind/m_debuginfo/priv_readelf.h 2008-01-07 19:24:26 UTC (rev 7319)
@@ -40,7 +40,7 @@
/* Identify an ELF object file by peering at the first few bytes of
it. */
-extern Bool ML_(is_elf_object_file)( const void* buf );
+extern Bool ML_(is_elf_object_file)( void* image, SizeT n_image );
/* The central function for reading ELF debug info. For the
object/exe specified by the SegInfo, find ELF sections, then read
Modified: branches/DATASYMS/coregrind/m_debuginfo/priv_storage.h
===================================================================
--- branches/DATASYMS/coregrind/m_debuginfo/priv_storage.h 2008-01-05 00:12:45 UTC (rev 7318)
+++ branches/DATASYMS/coregrind/m_debuginfo/priv_storage.h 2008-01-07 19:24:26 UTC (rev 7319)
@@ -69,7 +69,7 @@
#define MAX_LOC_SIZE ((1 << LOC_SIZE_BITS) - 1)
/* Number used to detect line number overflows; if one line is
- 60000-odd smaller than the previous, is was probably an overflow.
+ 60000-odd smaller than the previous, it was probably an overflow.
*/
#define OVERFLOW_DIFFERENCE (LINENO_OVERFLOW - 5000)
@@ -218,6 +218,24 @@
struct _SegInfo {
struct _SegInfo* next; /* list of SegInfos */
+ /* begin NEW STUFF */
+ Bool have_rx_map;
+ Bool have_rw_map;
+
+ Addr rx_map_avma;
+ SizeT rx_map_size;
+ OffT rx_map_foff;
+ Addr rw_map_avma;
+ SizeT rw_map_size;
+ OffT rw_map_foff;
+
+ Bool mark; /* marked for deletion? */
+
+ /* If have_dinfo is False, then all fields except "*rx_map*" and "*rw_map*"
+ are invalid and should not be consulted. */
+ Bool have_dinfo;
+ /* end NEW STUFF */
+
/* Description of the mapped segment. */
Addr text_start_avma;
UInt text_size;
Modified: branches/DATASYMS/coregrind/m_debuginfo/readelf.c
===================================================================
--- branches/DATASYMS/coregrind/m_debuginfo/readelf.c 2008-01-05 00:12:45 UTC (rev 7318)
+++ branches/DATASYMS/coregrind/m_debuginfo/readelf.c 2008-01-07 19:24:26 UTC (rev 7319)
@@ -106,11 +106,14 @@
/* Identify an ELF object file by peering at the first few bytes of
it. */
-Bool ML_(is_elf_object_file)( const void* buf )
+Bool ML_(is_elf_object_file)( void* image, SizeT n_image )
{
- ElfXX_Ehdr* ehdr = (ElfXX_Ehdr*)buf;
+ ElfXX_Ehdr* ehdr = (ElfXX_Ehdr*)image;
Int ok = 1;
+ if (n_image < sizeof(ElfXX_Ehdr))
+ return False;
+
ok &= (ehdr->e_ident[EI_MAG0] == 0x7F
&& ehdr->e_ident[EI_MAG1] == 'E'
&& ehdr->e_ident[EI_MAG2] == 'L'
@@ -730,7 +733,7 @@
* not match the value from the main object file.
*/
static
-Addr open_debug_file( Char* name, UInt crc, UInt* size )
+Addr open_debug_file( Char* name, UInt crc, UWord* size )
{
SysRes fd, sres;
struct vki_stat stat_buf;
@@ -774,7 +777,7 @@
* Try to find a separate debug file for a given object file.
*/
static
-Addr find_debug_file( Char* objpath, Char* debugname, UInt crc, UInt* size )
+Addr find_debug_file( Char* objpath, Char* debugname, UInt crc, UWord* size )
{
Char *objdir = VG_(arena_strdup)(VG_AR_DINFO, objpath);
Char *objdirptr;
@@ -803,6 +806,22 @@
}
+static Bool contained_within ( Addr outer, UWord n_outer,
+ Addr inner, UWord n_inner )
+{
+ if (n_outer == 0 || n_inner == 0)
+ return False;
+ /* Simplistic .. assumes no wraparound (reasonably enough) */
+ if (inner >= outer && inner+n_inner <= outer+n_outer)
+ return True;
+ return False;
+}
+
+static void* INDEX_BIS ( void* base, Word index, Word scale ) {
+ return (void*)( ((UChar*)base) + index * scale );
+}
+
+
/* The central function for reading ELF debug info. For the
object/exe specified by the SegInfo, find ELF sections, then read
the symbols, line number info, file name info, CFA (stack-unwind
@@ -811,24 +830,64 @@
*/
Bool ML_(read_elf_debug_info) ( struct _SegInfo* si )
{
- Bool res;
- ElfXX_Ehdr* ehdr; /* The ELF header */
- ElfXX_Shdr* shdr; /* The section table */
- UChar* sh_strtab; /* The section table's string table */
+ Bool res, ok;
SysRes fd, sres;
- Int i;
- Bool ok;
- Addr oimage;
- UInt n_oimage;
+ Word i;
OffT offset_oimage = 0;
Addr dimage = 0;
- UInt n_dimage = 0;
+ UWord n_dimage = 0;
OffT offset_dimage = 0;
+ Bool debug = 1||False;
+ /* Image addresses for the ELF file we're working with. */
+ Addr oimage = 0;
+ UWord n_oimage = 0;
+
+ /* ELF header for the main file. Should == oimage since is at
+ start of file. */
+ ElfXX_Ehdr* ehdr_img = NULL;
+
+ /* Program header table image addr, # entries, entry size */
+ ElfXX_Phdr* phdr_img = NULL;
+ UWord phdr_nent = 0;
+ UWord phdr_ent_szB = 0;
+
+ /* Section header image addr, # entries, entry size. Also the
+ associated string table. */
+ ElfXX_Shdr* shdr_img = NULL;
+ UWord shdr_nent = 0;
+ UWord shdr_ent_szB = 0;
+ UChar* shdr_strtab_img = NULL;
+
+ vg_assert(si);
+ vg_assert(si->have_rx_map == True);
+ vg_assert(si->have_rw_map == True);
+ vg_assert(si->have_dinfo == False);
+ vg_assert(si->filename);
+ vg_assert(!si->memname);
+ vg_assert(!si->symtab);
+ vg_assert(!si->loctab);
+ vg_assert(!si->cfsi);
+ vg_assert(!si->cfsi_exprs);
+ vg_assert(!si->strchunks);
+ vg_assert(!si->soname);
+
+ /* ----------------------------------------------------------
+ Phase 1. At this point, there is very little information in
+ the SegInfo. We only know that something that looks like an
+ ELF file has been mapped rx-ishly as recorded with the
+ si->*rx_map* fields and has also been mapped rw-ishly as
+ recorded with the si->*rw_map* fields. In this phase we
+ examine the file's ELF Program Header, and, by comparing that
+ against the si->*r{w,x}_map* info, try to figure out the AVMAs
+ for the sections we care about, that should have been mapped:
+ text, data, got, plt, and toc.
+ ---------------------------------------------------------- */
+
oimage = (Addr)NULL;
if (VG_(clo_verbosity) > 1 || VG_(clo_trace_redir))
VG_(message)(Vg_DebugMsg, "Reading syms from %s (%p)",
- si->filename, si->text_start_avma );
+ si->filename, si->rx_map_avma );
/* mmap the object image aboard, so that we can read symbols and
line number info out of it. It will be munmapped immediately
@@ -841,7 +900,7 @@
}
n_oimage = VG_(fsize)(fd.res);
- if (n_oimage < 0) {
+ if (n_oimage <= 0) {
ML_(symerr)("Can't stat .so/.exe (to determine its size)?!");
VG_(close)(fd.res);
return False;
@@ -859,134 +918,270 @@
}
oimage = sres.res;
+ /* Check against wraparound. am_mmap_file_float_valgrind should
+ not produce a wrapped-around mapping. */
+ vg_assert(n_oimage > 0);
+ vg_assert(oimage + n_oimage > oimage);
if (0) {
VG_(printf)("read_elf_debug_info: OIMAGE = %p - %p\n",
(void*)oimage, (void*)(oimage + (UWord)n_oimage));
}
- /* Ok, the object image is safely in oimage[0 .. n_oimage-1].
- Now verify that it is a valid ELF .so or executable image.
- */
- res = False;
- ok = (n_oimage >= sizeof(ElfXX_Ehdr));
- ehdr = (ElfXX_Ehdr*)oimage;
+ /* Ok, the object image is safely in oimage[0 .. n_oimage-1]. Now
+ verify that it is a valid ELF .so or executable image. */
+ res = False;
+ ok = (n_oimage >= sizeof(ElfXX_Ehdr));
+ ehdr_img = (ElfXX_Ehdr*)oimage;
if (ok)
- ok &= ML_(is_elf_object_file)(ehdr);
+ ok &= ML_(is_elf_object_file)(ehdr_img, n_oimage);
if (!ok) {
- ML_(symerr)("Invalid ELF header, or missing stringtab/sectiontab.");
+ ML_(symerr)("Invalid ELF Header");
goto out;
}
- /* Walk the LOAD headers in the phdr and update the SegInfo to
- include them all, so that this segment also contains data and
- bss memory. Also computes correct symbol offset value for this
- ELF file. */
- if (ehdr->e_phoff + ehdr->e_phnum*sizeof(ElfXX_Phdr) > n_oimage) {
- ML_(symerr)("ELF program header is beyond image end?!");
+ /* Find where the program and section header tables are, and give
+ up if either is missing or outside the image (bogus). */
+ phdr_img = (ElfXX_Phdr*)( ((UChar*)ehdr_img) + ehdr_img->e_phoff );
+ phdr_nent = ehdr_img->e_phnum;
+ phdr_ent_szB = ehdr_img->e_phentsize;
+
+ shdr_img = (ElfXX_Shdr*)( ((UChar*)ehdr_img) + ehdr_img->e_shoff );
+ shdr_nent = ehdr_img->e_shnum;
+ shdr_ent_szB = ehdr_img->e_shentsize;
+
+ if (debug) {
+ VG_(printf)("object: img %p n_oimage %ld\n",
+ (void*)oimage, n_oimage);
+ VG_(printf)("phdr: img %p nent %ld ent_szB %ld\n",
+ phdr_img, phdr_nent, phdr_ent_szB);
+ VG_(printf)("shdr: img %p nent %ld ent_szB %ld\n",
+ shdr_img, shdr_nent, shdr_ent_szB);
+ }
+
+ if (phdr_nent == 0
+ || !contained_within(
+ oimage, n_oimage,
+ (Addr)phdr_img, phdr_nent * phdr_ent_szB)) {
+ ML_(symerr)("Missing or invalid ELF Program Header Table");
goto out;
}
+
+ if (shdr_nent == 0
+ || !contained_within(
+ oimage, n_oimage,
+ (Addr)shdr_img, shdr_nent * shdr_ent_szB)) {
+ ML_(symerr)("Missing or invalid ELF Section Header Table");
+ goto out;
+ }
+
+ /* Also find the section header's string table, and validate. */
+ /* checked previously by is_elf_object_file: */
+ vg_assert( ehdr_img->e_shstrndx != SHN_UNDEF );
+
+ shdr_strtab_img
+ = (UChar*)( ((UChar*)ehdr_img)
+ + shdr_img[ehdr_img->e_shstrndx].sh_offset);
+ if (!contained_within( oimage, n_oimage,
+ (Addr)shdr_strtab_img,
+ 1/*bogus, but we don't know the real size*/ )) {
+ ML_(symerr)("Invalid ELF Section Header String Table");
+ goto out;
+ }
+
+ if (debug) {
+ VG_(printf)("shdr: string table at %p\n", shdr_strtab_img );
+ }
+
+ /* Do another amazingly tedious thing: find out the .soname for
+ this object. Apparently requires looking through the program
+ header table. */
+ vg_assert(si->soname == NULL);
+
{
- Bool offset_set = False;
+//zz Bool offset_set = False;
ElfXX_Addr prev_addr = 0;
Addr baseaddr = 0;
- vg_assert(si->soname == NULL);
+ for (i = 0; i < phdr_nent; i++) {
+ ElfXX_Phdr* phdr = INDEX_BIS( phdr_img, i, phdr_ent_szB );
- for (i = 0; i < ehdr->e_phnum; i++) {
- ElfXX_Phdr *o_phdr;
- ElfXX_Addr mapped, mapped_end;
+ /* Make sure the PT_LOADable entries are in order */
+ if (phdr->p_type == PT_LOAD) {
+ if (debug)
+ VG_(printf)("Comparing %p %p\n", prev_addr, phdr->p_vaddr);
+ if (phdr->p_vaddr < prev_addr) {
+ ML_(symerr)("ELF Program Headers are not in ascending order");
+ goto out;
+ }
+ prev_addr = phdr->p_vaddr;
+ }
- o_phdr = &((ElfXX_Phdr *)(oimage + ehdr->e_phoff))[i];
-
/* Try to get the soname. If there isn't one, use "NONE".
The seginfo needs to have some kind of soname in order to
facilitate writing redirect functions, since all redirect
specifications require a soname (pattern). */
- if (o_phdr->p_type == PT_DYNAMIC && si->soname == NULL) {
- const ElfXX_Dyn *dyn = (const ElfXX_Dyn *)(oimage + o_phdr->p_offset);
- Int stroff = -1;
- Char *strtab = NULL;
- Int j;
-
- for(j = 0; dyn[j].d_tag != DT_NULL; j++) {
- switch(dyn[j].d_tag) {
+ if (phdr->p_type == PT_DYNAMIC && si->soname == NULL) {
+ ElfXX_Dyn* dyn_img = (ElfXX_Dyn*)( ((UChar*)ehdr_img)
+ + phdr->p_offset);
+ Word stroff = -1;
+ UChar* strtab = NULL;
+ Word j;
+
+ for (j = 0; dyn_img[j].d_tag != DT_NULL; j++) {
+ switch (dyn_img[j].d_tag) {
case DT_SONAME:
- stroff = dyn[j].d_un.d_val;
+ stroff = dyn_img[j].d_un.d_val;
break;
-
case DT_STRTAB:
- strtab = (Char *)oimage + dyn[j].d_un.d_ptr - baseaddr;
+ strtab = ((UChar*)ehdr_img)
+ + dyn_img[j].d_un.d_ptr - baseaddr;
break;
}
}
- if (stroff != -1 && strtab != 0) {
+ if (stroff != -1 && strtab != NULL) {
+ if (debug)
+ VG_(printf)("Got soname=%s\n", strtab+stroff);
TRACE_SYMTAB("soname=%s\n", strtab+stroff);
si->soname = VG_(arena_strdup)(VG_AR_DINFO, strtab+stroff);
}
}
- if (o_phdr->p_type != PT_LOAD)
- continue;
+//zz if (o_phdr->p_type != PT_LOAD)
+//zz continue;
+//zz
+//zz if (!offset_set) {
+//zz offset_set = True;
+//zz offset_oimage = si->text_start_avma - o_phdr->p_vaddr;
+//zz baseaddr = o_phdr->p_vaddr;
+//zz }
+//zz
+//zz // Get the data and bss start/size if appropriate
+//zz mapped = o_phdr->p_vaddr + offset_oimage;
+//zz mapped_end = mapped + o_phdr->p_memsz;
+//zz if (si->data_start_avma == 0 &&
+//zz (o_phdr->p_flags & (PF_R|PF_W|PF_X)) == (PF_R|PF_W)) {
+//zz si->data_start_avma = mapped;
+//zz si->data_size = o_phdr->p_filesz;
+//zz si->bss_start_avma = mapped + o_phdr->p_filesz;
+//zz if (o_phdr->p_memsz > o_phdr->p_filesz)
+//zz si->bss_size = o_phdr->p_memsz - o_phdr->p_filesz;
+//zz else
+//zz si->bss_size = 0;
+//zz }
+//zz
+//zz mapped = mapped & ~(VKI_PAGE_SIZE-1);
+//zz mapped_end = (mapped_end + VKI_PAGE_SIZE - 1) & ~(VKI_PAGE_SIZE-1);
+//zz
+//zz if (VG_(needs).data_syms
+//zz && mapped >= si->text_start_avma
+//zz && mapped <= (si->text_start_avma + si->text_size)
+//zz && mapped_end > (si->text_start_avma + si->text_size)) {
+//zz /* XXX jrs 2007 Jan 11: what's going on here? If data
+//zz syms are involved, surely we shouldn't be messing with
+//zz the segment's text_size unless there is an assumption
+//zz that the data segment has been mapped immediately after
+//zz the text segment. Which doesn't sound good to me. */
+//zz UInt newsz = mapped_end - si->text_start_avma;
+//zz if (newsz > si->text_size) {
+//zz if (0)
+//zz VG_(printf)("extending mapping %p..%p %d -> ..%p %d\n",
+//zz si->text_start_avma,
+//zz si->text_start_avma + si->text_size,
+//zz si->text_size,
+//zz si->text_start_avma + newsz, newsz);
+//zz
+//zz si->text_size = newsz;
+//zz }
+//zz }
+ }
+ }
- if (!offset_set) {
- offset_set = True;
- offset_oimage = si->text_start_avma - o_phdr->p_vaddr;
- baseaddr = o_phdr->p_vaddr;
- }
- // Make sure the Phdrs are in order
- if (o_phdr->p_vaddr < prev_addr) {
- ML_(symerr)("ELF Phdrs are out of order!?");
- goto out;
- }
- prev_addr = o_phdr->p_vaddr;
+ /* Now read the section table. */
+ if (debug) {
+ VG_(printf)("rx: foffsets %ld .. %ld\n",
+ si->rx_map_foff, si->rx_map_foff + si->rx_map_size - 1 );
+ VG_(printf)("rw: foffsets %ld .. %ld\n",
+ si->rw_map_foff, si->rw_map_foff + si->rw_map_size - 1 );
+ }
+ for (i = 0; i < shdr_nent; i++) {
+ ElfXX_Shdr* shdr = INDEX_BIS( shdr_img, i, shdr_ent_szB );
+ UChar* name = shdr_strtab_img + shdr->sh_name;
+ Addr svma = shdr->sh_addr;
+ OffT foff = shdr->sh_offset;
+ UWord size = shdr->sh_size;
+ Bool bits = !(shdr->sh_type == SHT_NOBITS);
+ Bool inrx = size > 0 && foff >= si->rx_map_foff
+ && foff < si->rx_map_foff + si->rx_map_size;
+ Bool inrw = size > 0 && foff >= si->rw_map_foff
+ && foff < si->rw_map_foff + si->rw_map_size;
- // Get the data and bss start/size if appropriate
- mapped = o_phdr->p_vaddr + offset_oimage;
- mapped_end = mapped + o_phdr->p_memsz;
- if (si->data_start_avma == 0 &&
- (o_phdr->p_flags & (PF_R|PF_W|PF_X)) == (PF_R|PF_W)) {
- si->data_start_avma = mapped;
- si->data_size = o_phdr->p_filesz;
- si->bss_start_avma = mapped + o_phdr->p_filesz;
- if (o_phdr->p_memsz > o_phdr->p_filesz)
- si->bss_size = o_phdr->p_memsz - o_phdr->p_filesz;
- else
- si->bss_size = 0;
- }
+ if (debug)
+ VG_(printf)("section %2ld %s %s foff %6ld .. %6ld "
+ " svma %p name \"%s\"\n",
+ i, inrx ? "rx" : " ", inrw ? "rw" : " ",
+ foff, foff+size-1, (void*)svma, name );
- mapped = mapped & ~(VKI_PAGE_SIZE-1);
- mapped_end = (mapped_end + VKI_PAGE_SIZE - 1) & ~(VKI_PAGE_SIZE-1);
+ /* Check for sane-sized segments. SHT_NOBITS sections have zero
+ size in the file. */
+ if ((foff >= n_oimage) || (foff + (bits ? size : 0) > n_oimage)) {
+ ML_(symerr)("ELF Section extends beyond image end");
+ goto out;
+ }
- if (VG_(needs).data_syms
- && mapped >= si->text_start_avma
- && mapped <= (si->text_start_avma + si->text_size)
- && mapped_end > (si->text_start_avma + si->text_size)) {
- /* XXX jrs 2007 Jan 11: what's going on here? If data
- syms are involved, surely we shouldn't be messing with
- the segment's text_size unless there is an assumption
- that the data segment has been mapped immediately after
- the text segment. Which doesn't sound good to me. */
- UInt newsz = mapped_end - si->text_start_avma;
- if (newsz > si->text_size) {
- if (0)
- VG_(printf)("extending mapping %p..%p %d -> ..%p %d\n",
- si->text_start_avma,
- si->text_start_avma + si->text_size,
- si->text_size,
- si->text_start_avma + newsz, newsz);
+# define BAD(_secname) \
+ do { ML_(symerr)("Can't make sense of " _secname \
+ " section mapping"); \
+ goto out; \
+ } while (0)
- si->text_size = newsz;
- }
- }
- }
+ /* Find avma-s for .text, .data, .opd */
+
+ /* Accept .text only when mapped as rx */
+ if (0 == VG_(strcmp)(name, ".text")) {
+ if (inrx /* && !inrw */ && size > 0 && si->text_size == 0) {
+ si->text_start_avma = si->rx_map_avma + foff - si->rx_map_foff;
+ si->text_size = size;
+ si->text_bias = si->text_start_avma - svma;
+ if (debug)
+ VG_(printf)("acquiring .text avma = %p\n", si->text_start_avma);
+ } else {
+ BAD(".text");
+ }
+ }
+
+ /* Accept .data only when mapped as rw */
+ if (0 == VG_(strcmp)(name, ".data")) {
+ if (/*!inrx && */ inrw && size > 0 && si->data_size == 0) {
+ si->data_start_avma = si->rw_map_avma + foff - si->rw_map_foff;
+ si->data_size = size;
+ if (debug)
+ VG_(printf)("acquiring .data avma = %p\n", si->data_start_avma);
+ } else {
+ BAD(".data");
+ }
+ }
+
+ /* Accept .opd only when mapped as rw */
+ if (0 == VG_(strcmp)(name, ".opd")) {
+ if (!inrx && inrw && size > 0 && si->opd_size == 0) {
+ si->opd_start_avma = si->rw_map_avma + foff - si->rw_map_foff;
+ si->opd_size = size;
+ if (debug)
+ VG_(printf)("acquiring .opd avma = %p\n", si->opd_start_avma);
+ } else {
+ BAD(".opd");
+ }
+ }
+
+# undef BAD
+
}
- si->text_bias = offset_oimage;
if (VG_(clo_verbosity) > 2 || VG_(clo_trace_redir))
VG_(message)(Vg_DebugMsg, " svma %010p, avma %010p",
@@ -1001,16 +1196,9 @@
}
TRACE_SYMTAB("shoff = %d, shnum = %d, size = %d, n_vg_oimage = %d\n",
- ehdr->e_shoff, ehdr->e_shnum, sizeof(ElfXX_Shdr), n_oimage );
+ ehdr_img->e_shoff, ehdr_img->e_shnum,
+ sizeof(ElfXX_Shdr), n_oimage );
- if (ehdr->e_shoff + ehdr->e_shnum*sizeof(ElfXX_Shdr) > n_oimage) {
- ML_(symerr)("ELF section header is beyond image end?!");
- goto out;
- }
-
- shdr = (ElfXX_Shdr*)(oimage + ehdr->e_shoff);
- sh_strtab = (UChar*)(oimage + shdr[ehdr->e_shstrndx].sh_offset);
-
/* Find interesting sections, read the symbol table(s), read any debug
information */
{
@@ -1055,7 +1243,6 @@
UInt ehframe_sz = 0;
/* Section actual virtual addresses */
- Addr dummy_avma = 0;
Addr ehframe_avma = 0;
/* Find all interesting sections */
@@ -1072,21 +1259,21 @@
transiently mapped aboard for inspection, it's always safe to
inspect that area. */
- for (i = 0; i < ehdr->e_shnum; i++) {
+ for (i = 0; i < ehdr_img->e_shnum; i++) {
-# define FIND(sec_name, sec_size, sec_filea, sec_vma) \
- if (0 == VG_(strcmp)(sec_name, sh_strtab + shdr[i].sh_name)) { \
+# define FIND(sec_name, sec_size, sec_filea) \
+ if (0 == VG_(strcmp)(sec_name, shdr_strtab_img \
+ + shdr_img[i].sh_name)) { \
Bool nobits; \
- sec_vma = (Addr)(offset_oimage + shdr[i].sh_addr); \
- sec_filea = (void*)(oimage + shdr[i].sh_offset); \
- sec_size = shdr[i].sh_size; \
- nobits = shdr[i].sh_type == SHT_NOBITS; \
+ sec_filea = (void*)(oimage + shdr_img[i].sh_offset); \
+ sec_size = shdr_img[i].sh_size; \
+ nobits = shdr_img[i].sh_type == SHT_NOBITS; \
TRACE_SYMTAB( "%18s: filea %p .. %p, vma %p .. %p\n", \
sec_name, (UChar*)sec_filea, \
- ((UChar*)sec_filea) + sec_size - 1, \
- sec_vma, sec_vma + sec_size - 1); \
+ ((UChar*)sec_filea) + sec_size - 1); \
/* SHT_NOBITS sections have zero size in the file. */ \
- if ( shdr[i].sh_offset + (nobits ? 0 : sec_size) > n_oimage ) { \
+ if ( shdr_img[i].sh_offset \
+ + (nobits ? 0 : sec_size) > n_oimage ) { \
ML_(symerr)(" section beyond image end?!"); \
goto out; \
} \
@@ -1094,29 +1281,29 @@
/* Nb: must find where .got and .plt sections will be in the
* executable image, not in the object image transiently loaded. */
- /* NAME SIZE IMAGE addr AVMA */
- FIND(".dynsym", dynsym_sz, dynsym_img, dummy_avma)
- FIND(".dynstr", dynstr_sz, dynstr_img, dummy_avma)
- FIND(".symtab", symtab_sz, symtab_img, dummy_avma)
- FIND(".strtab", strtab_sz, strtab_img, dummy_avma)
+ /* NAME SIZE IMAGE addr */
+ FIND(".dynsym", dynsym_sz, dynsym_img)
+ FIND(".dynstr", dynstr_sz, dynstr_img)
+ FIND(".symtab", symtab_sz, symtab_img)
+ FIND(".strtab", strtab_sz, strtab_img)
- FIND(".gnu_debuglink", debuglink_sz, debuglink_img, dummy_avma)
+ FIND(".gnu_debuglink", debuglink_sz, debuglink_img)
- FIND(".stab", stab_sz, stab_img, dummy_avma)
- FIND(".stabstr", stabstr_sz, stabstr_img, dummy_avma)
+ FIND(".stab", stab_sz, stab_img)
+ FIND(".stabstr", stabstr_sz, stabstr_img)
- FIND(".debug_line", debug_line_sz, debug_line_img, dummy_avma)
- FIND(".debug_info", debug_info_sz, debug_info_img, dummy_avma)
- FIND(".debug_abbrev", debug_abbv_sz, debug_abbv_img, dummy_avma)
- FIND(".debug_str", debug_str_sz, debug_str_img, dummy_avma)
+ FIND(".debug_line", debug_line_sz, debug_line_img)
+ FIND(".debug_info", debug_info_sz, debug_info_img)
+ FIND(".debug_abbrev", debug_abbv_sz, debug_abbv_img)
+ FIND(".debug_str", debug_str_sz, debug_str_img)
- FIND(".debug", dwarf1d_sz, dwarf1d_img, dummy_avma)
- FIND(".line", dwarf1l_sz, dwarf1l_img, dummy_avma)
- FIND(".eh_frame", ehframe_sz, ehframe_img, ehframe_avma)
+ FIND(".debug", dwarf1d_sz, dwarf1d_img)
+ FIND(".line", dwarf1l_sz, dwarf1l_img)
+ FIND(".eh_frame", ehframe_sz, ehframe_img)
- FIND(".got", si->got_size, dummy_filea_img, si->got_start_avma)
- FIND(".plt", si->plt_size, dummy_filea_img, si->plt_start_avma)
- FIND(".opd", si->opd_size, opd_filea_img, si->opd_start_avma)
+ FIND(".got", si->got_size, dummy_filea_img)
+ FIND(".plt", si->plt_size, dummy_filea_img)
+ FIND(".opd", si->opd_size, opd_filea_img)
# undef FIND
}
@@ -1134,20 +1321,22 @@
/* See if we can find a matching debug file */
dimage = find_debug_file(si->filename, debuglink_img, crc, &n_dimage);
if (dimage != 0) {
- ehdr = (ElfXX_Ehdr*)dimage;
+ ElfXX_Ehdr* ehdr_dimg = (ElfXX_Ehdr*)dimage;
if (n_dimage >= sizeof(ElfXX_Ehdr)
- && ML_(is_elf_object_file(ehdr))
- && ehdr->e_phoff + ehdr->e_phnum*sizeof(ElfXX_Phdr) <= n_dimage
- && ehdr->e_shoff + ehdr->e_shnum*sizeof(ElfXX_Shdr) <= n_dimage)
+ && ML_(is_elf_object_file(ehdr_dimg, n_dimage))
+ && ehdr_dimg->e_phoff + ehdr_dimg->e_phnum*sizeof(ElfXX_Phdr) <= n_dimage
+ && ehdr_dimg->e_shoff + ehdr_dimg->e_shnum*sizeof(ElfXX_Shdr) <= n_dimage)
{
Bool need_symtab = (NULL == symtab_img);
- Bool need_stabs = (NULL == stab_img);
+ Bool need_stabs = (NULL == stab_img);
Bool need_dwarf2 = (NULL == debug_info_img);
Bool need_dwarf1 = (NULL == dwarf1d_img);
+ ElfXX_Shdr* shdr;
+ UChar* sh_strtab;
- for (i = 0; i < ehdr->e_phnum; i++) {
- ElfXX_Phdr *o_phdr = &((ElfXX_Phdr *)(dimage + ehdr->e_phoff))[i];
+ for (i = 0; i < ehdr_dimg->e_phnum; i++) {
+ ElfXX_Phdr *o_phdr = &((ElfXX_Phdr *)(dimage + ehdr_dimg->e_phoff))[i];
if (o_phdr->p_type == PT_LOAD) {
offset_dimage = si->text_start_avma - o_phdr->p_vaddr;
break;
@@ -1158,14 +1347,14 @@
if (need_symtab)
symtab_offset = offset_dimage;
- shdr = (ElfXX_Shdr*)(dimage + ehdr->e_shoff);
- sh_strtab = (UChar*)(dimage + shdr[ehdr->e_shstrndx].sh_offset);
+ shdr = (ElfXX_Shdr*)(dimage + ehdr_dimg->e_shoff);
+ sh_strtab = (UChar*)(dimage + shdr[ehdr_dimg->e_shstrndx].sh_offset);
/* Same deal as previous FIND, except simpler - doesn't
look for avma, only oimage address. */
/* Find all interesting sections */
- for (i = 0; i < ehdr->e_shnum; i++) {
+ for (i = 0; i < ehdr_dimg->e_shnum; i++) {
# define FIND(condition, sec_name, sec_size, sec_filea) \
if (condition \
|
|
From: Russell S. <se...@cs...> - 2008-01-07 19:19:18
|
Tom Hughes wrote: > On 03/01/2008, Nicholas Nethercote <nj...@cs...> wrote: > >> If a kernel type isn't present, a vki_* version should be added. >> See the comment at the top of include/vki/vki-linux.h. >> >> But don't trust the man pages, they mostly describe glibc's wrappers for the >> syscalls. These mostly are the same as the kernel syscalls, but not always. >> Only trust the kernel code. Unfortunately, I can't remember where in the >> kernel code the syscall prototypes are defined. > > There isn't one place - each call will be in a place appropriate to > the systems it works on. In this case fs/sync.c is the file, and the > prototype is: > > asmlinkage long sys_sync_file_range(int fd, loff_t offset, loff_t > nbytes, unsigned int flags) > > So vki_loff_t is the thing to use. Fixed. Thanks! > > The wrapper should probably also validate the file descriptor like > other wrappers which have file descriptor arguments do. I couldn't find any wrappers that do anything special with their file descriptor arguments. (Look at sys_llseek in syswrap-linux.c, for example...) I've attached an updated patch. -Rusty > > Tom > |
|
From: Dan K. <da...@ke...> - 2008-01-07 19:00:00
|
On Jan 7, 2008 8:50 AM, Yossi Kreinin <yos...@gm...> wrote: > What I need is to support people using Windows as their development machine. Call me crazy, but I think the best way to do that is to get their windows development tools running 100% under Wine :-) - Dan |
|
From: John R.
|
Looking at the wine preloader's travails with reserving address space, including http://www.nabble.com/Valgrind-and-Wine-td14442642.html , here are some thoughts. Julian's comment about changing valt_load_address_normal certainly is part of the solution. Try 0x60000000 (1.6GB) as the value, to allow for some large Win32 programs. Regarding R.Walsh's comment about building the Wine preloader into Valgrind, there may be a shortcut. Create a new global variable minimum_mmap_address, default to 0 but use 0x60000000 (1.6GB) for wine, then do mmap(minimum_mmap_address, ...) instead of mmap(0, ...) . This causes the Linux kernel to start its ascending search for a suitable place in the address space at minimum_mmap_address instead of 0. Of course this is necessary for all non-tracked mmap, including calls from ld-linux and glibc internals used by the valgrind core and the tool. Mapping of a pre-linked .so also must use mmap(minimum_mmap_address, ...) instead of mmap(pre_linked_address, ...) According to the source wine/loader/preloader.c , the sacred ranges are: * 0x00000000 - 0x00110000 the DOS area * 0x80000000 - 0x81000000 the shared heap * ??? - ??? the PE binary load address (usually starting at 0x00400000) The DOS area and PE binary load address is covered by minimum_mmap_address. The preloader takes care of the shared heap area by reserving 0x02000000 bytes at 0x7f000000. So this would be a new global variable in ld-linux and glibc. The technical change would not be hard, and other "embedded" projects (in addition to wine) might applaud. But the existing maintainers of glibc probably would resist. -- John Reiser, jreiser@BitWagon.com |
|
From: Yossi K. <yos...@gm...> - 2008-01-07 16:50:02
|
On Jan 7, 2008 6:32 PM, Dan Kegel <da...@ke...> wrote: > > Y'know, it might be more productive for > you get simply use valgrind on wine. > > That solves the problem of instrumenting Windows binaries. What I need is to support people using Windows as their development machine. I'm mostly interested in running custom skins on Windows; people using Windows normally buy functionality similar to that of memcheck already. It sure is more practical to have wine deal with Windows syscalls and executable formats, when this works out. For starters, I was thinking about getting "text-only" programs to work (basically those only relying on the standard C library to talk to the OS). That would be very useful to me; I don't know whether it's very useful in general. -- Yossi |
|
From: Dan K. <da...@ke...> - 2008-01-07 16:32:09
|
On Jan 7, 2008 8:28 AM, Yossi Kreinin <yos...@gm...> wrote: > I think I want to try to port valgrind to Windows. Y'know, it might be more productive for you get simply use valgrind on wine. That's been working for a couple years, and is starting to be rather useful. How about you try that out on a few Windows apps and file bugs for what doesn't work? - Dan |
|
From: Yossi K. <yos...@gm...> - 2008-01-07 16:28:41
|
Hi! I think I want to try to port valgrind to Windows. My knowledge of the code base is pretty basic - enough to implement skins that are useful to me and I'd like them to run under Windows. Not enough to estimate how stupid the idea of trying such a port is though. The "Supported Platforms" page states that a Windows port would be almost a separate project. Naturally, if I get to the point where something materializes, I'd rather commit it to the main trunk than create a fork. If I go for the main trunk, I'll probably have to get some advice about organizing the Windows-specific parts at various points. If I go for a fork, I'll just get off the list... Which is better? :) -- Yossi |
|
From: Tom H. <th...@cy...> - 2008-01-07 04:00:49
|
Nightly build on alvis ( i686, Red Hat 7.3 ) started at 2008-01-07 03:15:04 GMT Results unchanged from 24 hours ago Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 323 tests, 66 stderr failures, 1 stdout failure, 28 post failures == memcheck/tests/addressable (stderr) memcheck/tests/badjump (stderr) memcheck/tests/describe-block (stderr) memcheck/tests/erringfds (stderr) memcheck/tests/leak-0 (stderr) memcheck/tests/leak-cycle (stderr) memcheck/tests/leak-pool-0 (stderr) memcheck/tests/leak-pool-1 (stderr) memcheck/tests/leak-pool-2 (stderr) memcheck/tests/leak-pool-3 (stderr) memcheck/tests/leak-pool-4 (stderr) memcheck/tests/leak-pool-5 (stderr) memcheck/tests/leak-regroot (stderr) memcheck/tests/leak-tree (stderr) memcheck/tests/long_namespace_xml (stderr) memcheck/tests/lsframe1 (stderr) memcheck/tests/lsframe2 (stderr) memcheck/tests/malloc_free_fill (stderr) memcheck/tests/match-overrun (stderr) memcheck/tests/noisy_child (stderr) memcheck/tests/partial_load_dflt (stderr) memcheck/tests/partial_load_ok (stderr) memcheck/tests/partiallydefinedeq (stderr) memcheck/tests/pointer-trace (stderr) memcheck/tests/sigkill (stderr) memcheck/tests/stack_changes (stderr) memcheck/tests/supp_unknown (stderr) memcheck/tests/x86/bug152022 (stderr) memcheck/tests/x86/scalar (stderr) memcheck/tests/x86/scalar_supp (stderr) memcheck/tests/x86/xor-undef-x86 (stderr) memcheck/tests/xml1 (stderr) massif/tests/alloc-fns-A (post) massif/tests/alloc-fns-B (post) massif/tests/basic (post) massif/tests/basic2 (post) massif/tests/big-alloc (post) massif/tests/culling1 (stderr) massif/tests/culling2 (stderr) massif/tests/custom_alloc (post) massif/tests/deep-A (post) massif/tests/deep-B (stderr) massif/tests/deep-B (post) massif/tests/deep-C (stderr) massif/tests/deep-C (post) massif/tests/deep-D (post) massif/tests/ignoring (post) massif/tests/insig (post) massif/tests/long-time (post) massif/tests/new-cpp (post) massif/tests/null (post) massif/tests/one (post) massif/tests/overloaded-new (post) massif/tests/peak (post) massif/tests/peak2 (stderr) massif/tests/peak2 (post) massif/tests/realloc (stderr) massif/tests/realloc (post) massif/tests/thresholds_0_0 (post) massif/tests/thresholds_0_10 (post) massif/tests/thresholds_10_0 (post) massif/tests/thresholds_10_10 (post) massif/tests/thresholds_5_0 (post) massif/tests/thresholds_5_10 (post) massif/tests/zero1 (post) massif/tests/zero2 (post) none/tests/blockfault (stderr) none/tests/mremap (stderr) none/tests/mremap2 (stdout) helgrind/tests/hg01_all_ok (stderr) helgrind/tests/hg02_deadlock (stderr) helgrind/tests/hg03_inherit (stderr) helgrind/tests/hg04_race (stderr) helgrind/tests/hg05_race2 (stderr) helgrind/tests/hg06_readshared (stderr) helgrind/tests/tc01_simple_race (stderr) helgrind/tests/tc02_simple_tls (stderr) helgrind/tests/tc03_re_excl (stderr) helgrind/tests/tc05_simple_race (stderr) helgrind/tests/tc06_two_races (stderr) helgrind/tests/tc07_hbl1 (stderr) helgrind/tests/tc08_hbl2 (stderr) helgrind/tests/tc09_bad_unlock (stderr) helgrind/tests/tc11_XCHG (stderr) helgrind/tests/tc12_rwl_trivial (stderr) helgrind/tests/tc14_laog_dinphils (stderr) helgrind/tests/tc16_byterace (stderr) helgrind/tests/tc17_sembar (stderr) helgrind/tests/tc18_semabuse (stderr) helgrind/tests/tc19_shadowmem (stderr) helgrind/tests/tc20_verifywrap (stderr) helgrind/tests/tc21_pthonce (stderr) helgrind/tests/tc22_exit_w_lock (stderr) helgrind/tests/tc23_bogus_condwait (stderr) helgrind/tests/tc24_nonzero_sem (stderr) |
|
From: Tom H. <th...@cy...> - 2008-01-07 03:37:36
|
Nightly build on lloyd ( x86_64, Fedora 7 ) started at 2008-01-07 03:05:15 GMT Results unchanged from 24 hours ago Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 357 tests, 7 stderr failures, 2 stdout failures, 0 post failures == memcheck/tests/malloc_free_fill (stderr) memcheck/tests/pointer-trace (stderr) memcheck/tests/vcpu_fnfns (stdout) memcheck/tests/x86/scalar (stderr) memcheck/tests/xml1 (stderr) none/tests/mremap (stderr) none/tests/mremap2 (stdout) helgrind/tests/tc20_verifywrap (stderr) helgrind/tests/tc22_exit_w_lock (stderr) |
|
From: Tom H. <th...@cy...> - 2008-01-07 03:28:03
|
Nightly build on dellow ( x86_64, Fedora 8 ) started at 2008-01-07 03:10:05 GMT Results differ from 24 hours ago Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 357 tests, 8 stderr failures, 4 stdout failures, 0 post failures == memcheck/tests/malloc_free_fill (stderr) memcheck/tests/pointer-trace (stderr) memcheck/tests/vcpu_fnfns (stdout) memcheck/tests/x86/scalar (stderr) memcheck/tests/xml1 (stderr) none/tests/mremap (stderr) none/tests/mremap2 (stdout) none/tests/pth_cvsimple (stdout) none/tests/pth_detached (stdout) helgrind/tests/tc18_semabuse (stderr) helgrind/tests/tc20_verifywrap (stderr) helgrind/tests/tc22_exit_w_lock (stderr) ================================================= == Results from 24 hours ago == ================================================= Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 357 tests, 8 stderr failures, 3 stdout failures, 0 post failures == memcheck/tests/malloc_free_fill (stderr) memcheck/tests/pointer-trace (stderr) memcheck/tests/vcpu_fnfns (stdout) memcheck/tests/x86/scalar (stderr) memcheck/tests/xml1 (stderr) none/tests/mremap (stderr) none/tests/mremap2 (stdout) none/tests/pth_detached (stdout) helgrind/tests/tc18_semabuse (stderr) helgrind/tests/tc20_verifywrap (stderr) helgrind/tests/tc22_exit_w_lock (stderr) ================================================= == Difference between 24 hours ago and now == ================================================= *** old.short Mon Jan 7 03:19:18 2008 --- new.short Mon Jan 7 03:28:05 2008 *************** *** 8,10 **** ! == 357 tests, 8 stderr failures, 3 stdout failures, 0 post failures == memcheck/tests/malloc_free_fill (stderr) --- 8,10 ---- ! == 357 tests, 8 stderr failures, 4 stdout failures, 0 post failures == memcheck/tests/malloc_free_fill (stderr) *************** *** 16,17 **** --- 16,18 ---- none/tests/mremap2 (stdout) + none/tests/pth_cvsimple (stdout) none/tests/pth_detached (stdout) |
|
From: Tom H. <th...@cy...> - 2008-01-07 03:15:07
|
Nightly build on gill ( x86_64, Fedora Core 2 ) started at 2008-01-07 03:00:02 GMT Results unchanged from 24 hours ago Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 359 tests, 30 stderr failures, 1 stdout failure, 0 post failures == memcheck/tests/addressable (stderr) memcheck/tests/badjump (stderr) memcheck/tests/describe-block (stderr) memcheck/tests/malloc_free_fill (stderr) memcheck/tests/match-overrun (stderr) memcheck/tests/pointer-trace (stderr) memcheck/tests/stack_switch (stderr) memcheck/tests/supp_unknown (stderr) memcheck/tests/x86/scalar (stderr) memcheck/tests/x86/scalar_supp (stderr) none/tests/blockfault (stderr) none/tests/fdleak_fcntl (stderr) none/tests/mremap (stderr) none/tests/mremap2 (stdout) helgrind/tests/hg01_all_ok (stderr) helgrind/tests/hg02_deadlock (stderr) helgrind/tests/hg03_inherit (stderr) helgrind/tests/hg04_race (stderr) helgrind/tests/hg05_race2 (stderr) helgrind/tests/tc01_simple_race (stderr) helgrind/tests/tc05_simple_race (stderr) helgrind/tests/tc06_two_races (stderr) helgrind/tests/tc09_bad_unlock (stderr) helgrind/tests/tc14_laog_dinphils (stderr) helgrind/tests/tc16_byterace (stderr) helgrind/tests/tc17_sembar (stderr) helgrind/tests/tc19_shadowmem (stderr) helgrind/tests/tc20_verifywrap (stderr) helgrind/tests/tc21_pthonce (stderr) helgrind/tests/tc22_exit_w_lock (stderr) helgrind/tests/tc23_bogus_condwait (stderr) |