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
(14) |
|
2
(5) |
3
(15) |
4
(20) |
5
(2) |
6
(4) |
7
(16) |
8
(13) |
|
9
(3) |
10
(19) |
11
(13) |
12
(10) |
13
(16) |
14
|
15
|
|
16
|
17
(5) |
18
(14) |
19
(1) |
20
(12) |
21
(1) |
22
|
|
23
(1) |
24
(1) |
25
(1) |
26
(13) |
27
(2) |
28
(19) |
29
(15) |
|
30
(17) |
|
|
|
|
|
|
|
From: Tom H. <to...@co...> - 2013-06-28 01:51:08
|
valgrind revision: 13432 VEX revision: 2728 C compiler: gcc (GCC) 4.8.1 20130612 (Red Hat 4.8.1-2) GDB: GNU gdb (GDB) Fedora (7.6-32.fc20) Assembler: GNU assembler version 2.23.2 C library: GNU C Library (GNU libc) development release version 2.17.90 uname -mrs: Linux 3.9.4-200.fc18.x86_64 x86_64 Vendor version: Fedora release 20 (Rawhide) Nightly build on bristol ( x86_64, Fedora 20 ) Started at 2013-06-28 02:22:42 BST Ended at 2013-06-28 02:50:52 BST 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 == 655 tests, 5 stderr failures, 1 stdout failure, 0 stderrB failures, 0 stdoutB failures, 0 post failures == memcheck/tests/amd64/insn_basic (stderr) memcheck/tests/dw4 (stderr) memcheck/tests/origin5-bz2 (stderr) none/tests/amd64/insn_basic (stdout) none/tests/amd64/insn_basic (stderr) exp-sgcheck/tests/hackedbz2 (stderr) |
|
From: <sv...@va...> - 2013-06-27 20:31:47
|
sewardj 2013-06-27 21:31:36 +0100 (Thu, 27 Jun 2013)
New Revision: 13432
Log:
Exit a bit more gracefully if a request to get part of an image
exceeds the allowable range. With this change, it should be
essentially impossible to crash V by feeding it invalid ELF or Dwarf.
Modified files:
branches/DISRV/coregrind/m_debuginfo/image.c
branches/DISRV/coregrind/m_debuginfo/readelf.c
Modified: branches/DISRV/coregrind/m_debuginfo/image.c (+60 -16)
===================================================================
--- branches/DISRV/coregrind/m_debuginfo/image.c 2013-06-27 18:39:15 +01:00 (rev 13431)
+++ branches/DISRV/coregrind/m_debuginfo/image.c 2013-06-27 21:31:36 +01:00 (rev 13432)
@@ -67,6 +67,9 @@
Bool is_local;
// The fd for the local file, or sd for a remote server.
Int fd;
+ // The name. In ML_(dinfo_zalloc)'d space. Used only for printing
+ // error messages; hence it doesn't really matter what this contains.
+ HChar* name;
// The rest of these fields are only valid when using remote files
// (that is, using a debuginfo server; hence when is_local==False)
// Session ID allocated to us by the server. Cannot be zero.
@@ -181,17 +184,30 @@
/* If we lost communication with the remote server, just give up.
Recovering is too difficult. */
-static void give_up(void)
+static void give_up__comms_lost(void)
{
VG_(umsg)("\n");
- VG_(umsg)("Valgrind: Lost communication with the remote "
- "debuginfo server.\n");
- VG_(umsg)("Valgrind: I can't recover from that. Giving up. Sorry.\n");
+ VG_(umsg)(
+ "Valgrind: debuginfo reader: Lost communication with the remote\n");
+ VG_(umsg)(
+ "Valgrind: debuginfo server. I can't recover. Giving up. Sorry.\n");
VG_(umsg)("\n");
VG_(exit)(1);
/*NOTREACHED*/
}
+static void give_up__image_overrun(void)
+{
+ VG_(umsg)("\n");
+ VG_(umsg)(
+ "Valgrind: debuginfo reader: Possibly corrupted debuginfo file.\n");
+ VG_(umsg)(
+ "Valgrind: I can't recover. Giving up. Sorry.\n");
+ VG_(umsg)("\n");
+ VG_(exit)(1);
+ /*NOTREACHED*/
+}
+
/* "Do" a transaction: that is, send the given frame to the server and
return the frame it sends back. Caller owns the resulting frame
and must free it. A NULL return means the transaction failed for
@@ -502,7 +518,7 @@
VG_(umsg)("set_CEnt (reading data from DI server): fail: "
"server unexpectedly closed the connection\n");
}
- give_up();
+ give_up__comms_lost();
/* NOTREACHED */
vg_assert(0);
end_of_else_clause:
@@ -599,6 +615,7 @@
img->source.fd = sr_Res(fd);
img->size = size;
img->ces_used = 0;
+ img->source.name = ML_(dinfo_strdup)("di.image.ML_iflf.2", fullpath);
/* img->ces is already zeroed out */
vg_assert(img->source.fd >= 0);
@@ -684,6 +701,11 @@
img->source.session_id = session_id;
img->size = size;
img->ces_used = 0;
+ img->source.name = ML_(dinfo_zalloc)("di.image.ML_ifds.2",
+ 20 + VG_(strlen)(filename)
+ + VG_(strlen)(serverAddr));
+ VG_(sprintf)(img->source.name, "%s at %s", filename, serverAddr);
+
/* img->ces is already zeroed out */
vg_assert(img->source.fd >= 0);
@@ -740,6 +762,7 @@
for (i = i; i < img->ces_used; i++) {
vg_assert(img->ces[i] == NULL);
}
+ ML_(dinfo_free)(img->source.name);
ML_(dinfo_free)(img);
}
@@ -749,19 +772,40 @@
return img->size;
}
-Bool ML_(img_valid)(DiImage* img, DiOffT offset, SizeT size)
+inline Bool ML_(img_valid)(DiImage* img, DiOffT offset, SizeT size)
{
vg_assert(img);
vg_assert(offset != DiOffT_INVALID);
return img->size > 0 && offset + size <= (DiOffT)img->size;
}
+/* Check the given range is valid, and if not, shut down the system.
+ An invalid range would imply that we're trying to read outside the
+ image, which normally means the image is corrupted somehow, or the
+ caller is buggy. Recovering is too complex, and we have
+ probably-corrupt debuginfo, so just give up. */
+static void ensure_valid(DiImage* img, DiOffT offset, SizeT size,
+ const HChar* caller)
+{
+ if (LIKELY(ML_(img_valid)(img, offset, size)))
+ return;
+ VG_(umsg)("Valgrind: debuginfo reader: ensure_valid failed:\n");
+ VG_(umsg)("Valgrind: during call to %s\n", caller);
+ VG_(umsg)("Valgrind: request for range [%llu, +%llu) exceeds\n",
+ (ULong)offset, (ULong)size);
+ VG_(umsg)("Valgrind: valid image size of %llu for image:\n",
+ (ULong)img->size);
+ VG_(umsg)("Valgrind: \"%s\"\n", img->source.name);
+ give_up__image_overrun();
+}
+
+
void ML_(img_get)(/*OUT*/void* dst,
DiImage* img, DiOffT offset, SizeT size)
{
vg_assert(img);
vg_assert(size > 0);
- vg_assert(ML_(img_valid)(img, offset, size));
+ ensure_valid(img, offset, size, "ML_(img_get)");
SizeT i;
for (i = 0; i < size; i++) {
((UChar*)dst)[i] = get(img, offset + i);
@@ -773,7 +817,7 @@
{
vg_assert(img);
vg_assert(size > 0);
- vg_assert(ML_(img_valid)(img, offset, size));
+ ensure_valid(img, offset, size, "ML_(img_get_some)");
UChar* dstU = (UChar*)dst;
/* Use |get| in the normal way to get the first byte of the range.
This guarantees to put the cache entry containing |offset| in
@@ -795,7 +839,7 @@
SizeT ML_(img_strlen)(DiImage* img, DiOffT off)
{
- vg_assert(ML_(img_valid)(img, off, 1));
+ ensure_valid(img, off, 1, "ML_(img_strlen)");
SizeT i = 0;
while (get(img, off + i) != 0) i++;
return i;
@@ -803,7 +847,7 @@
HChar* ML_(img_strdup)(DiImage* img, const HChar* cc, DiOffT offset)
{
- vg_assert(ML_(img_valid)(img, offset, 1));
+ ensure_valid(img, offset, 1, "ML_(img_strdup)");
SizeT len = ML_(img_strlen)(img, offset);
HChar* res = ML_(dinfo_zalloc)(cc, len+1);
SizeT i;
@@ -816,8 +860,8 @@
Int ML_(img_strcmp)(DiImage* img, DiOffT off1, DiOffT off2)
{
- vg_assert(ML_(img_valid)(img, off1, 1));
- vg_assert(ML_(img_valid)(img, off2, 1));
+ ensure_valid(img, off1, 1, "ML_(img_strcmp)(first arg)");
+ ensure_valid(img, off2, 1, "ML_(img_strcmp)(second arg)");
while (True) {
UChar c1 = get(img, off1);
UChar c2 = get(img, off2);
@@ -830,7 +874,7 @@
Int ML_(img_strcmp_c)(DiImage* img, DiOffT off1, const HChar* str2)
{
- vg_assert(ML_(img_valid)(img, off1, 1));
+ ensure_valid(img, off1, 1, "ML_(img_strcmp_c)");
while (True) {
UChar c1 = get(img, off1);
UChar c2 = *(UChar*)str2;
@@ -843,7 +887,7 @@
UChar ML_(img_get_UChar)(DiImage* img, DiOffT offset)
{
- vg_assert(ML_(img_valid)(img, offset, 1));
+ ensure_valid(img, offset, 1, "ML_(img_get_UChar)");
return get(img, offset);
}
@@ -931,7 +975,7 @@
0x2d02ef8d
};
- vg_assert(img);
+ vg_assert(img);
/* If the image is local, calculate the CRC here directly. If it's
remote, forward the request to the server. */
@@ -985,7 +1029,7 @@
if (req) free_Frame(req);
if (res) free_Frame(res);
// FIXME: now what?
- give_up();
+ give_up__comms_lost();
/* NOTREACHED */
vg_assert(0);
}
Modified: branches/DISRV/coregrind/m_debuginfo/readelf.c (+4 -1)
===================================================================
--- branches/DISRV/coregrind/m_debuginfo/readelf.c 2013-06-27 18:39:15 +01:00 (rev 13431)
+++ branches/DISRV/coregrind/m_debuginfo/readelf.c 2013-06-27 21:31:36 +01:00 (rev 13432)
@@ -1662,7 +1662,10 @@
);
if (ok2 && strtab_mioff == DiOffT_INVALID) {
// Check for obviously bogus offsets.
- vg_assert(ML_(img_valid)(mimg, offset, 1));
+ if (!ML_(img_valid)(mimg, offset, 1)) {
+ ML_(symerr)(di, True, "Invalid DT_STRTAB offset");
+ goto out;
+ }
strtab_mioff = ehdr_mioff + offset;
vg_assert(ehdr_mioff == 0); // should always be
}
|
|
From: <sv...@va...> - 2013-06-27 17:39:30
|
sewardj 2013-06-27 18:39:15 +0100 (Thu, 27 Jun 2013)
New Revision: 13431
Log:
Minimal changes needed to make this suitable for trunk:
* add a new flag --allow-mismatched-debuginfo to override the
CRC32/build-id checks, if needed
* tidy up logic for finding files on the --extra-debuginfo-path
and at the --debuginfo-server
* don't assert if connection to the debuginfo server is lost;
instead print a reasonable message and quit.
Modified files:
branches/DISRV/auxprogs/valgrind-di-server.c
branches/DISRV/coregrind/m_debuginfo/image.c
branches/DISRV/coregrind/m_debuginfo/readelf.c
branches/DISRV/coregrind/m_main.c
branches/DISRV/coregrind/m_options.c
branches/DISRV/coregrind/pub_core_options.h
Modified: branches/DISRV/coregrind/m_main.c (+6 -0)
===================================================================
--- branches/DISRV/coregrind/m_main.c 2013-06-25 13:42:52 +01:00 (rev 13430)
+++ branches/DISRV/coregrind/m_main.c 2013-06-27 18:39:15 +01:00 (rev 13431)
@@ -178,6 +178,9 @@
" well known search paths.\n"
" --debuginfo-server=ipaddr:port also query this server\n"
" (valgrind-di-server) for debug symbols\n"
+" --allow-mismatched-debuginfo=no|yes [no]\n"
+" for the above two flags only, accept debuginfo\n"
+" objects that don't \"match\" the main object\n"
" --smc-check=none|stack|all|all-non-file [stack]\n"
" checks for self-modifying code: none, only for\n"
" code found in stacks, for all code, or for all\n"
@@ -681,6 +684,9 @@
else if VG_STR_CLO(arg, "--debuginfo-server",
VG_(clo_debuginfo_server)) {}
+ else if VG_BOOL_CLO(arg, "--allow-mismatched-debuginfo",
+ VG_(clo_allow_mismatched_debuginfo)) {}
+
else if VG_STR_CLO(arg, "--xml-user-comment",
VG_(clo_xml_user_comment)) {}
Modified: branches/DISRV/auxprogs/valgrind-di-server.c (+15 -0)
===================================================================
--- branches/DISRV/auxprogs/valgrind-di-server.c 2013-06-25 13:42:52 +01:00 (rev 13430)
+++ branches/DISRV/auxprogs/valgrind-di-server.c 2013-06-27 18:39:15 +01:00 (rev 13431)
@@ -4,6 +4,15 @@
/*--- valgrind-di-server.c ---*/
/*--------------------------------------------------------------------*/
+/* To build for an x86_64-linux host:
+ gcc -g -Wall -O -o valgrind-di-server \
+ auxprogs/valgrind-di-server.c -Icoregrind -Iinclude \
+ -IVEX/pub -DVGO_linux -DVGA_amd64
+
+ To build for an x86 (32-bit) host
+ The same, except change -DVGA_amd64 to -DVGA_x86
+*/
+
/*
This file is part of Valgrind, a dynamic binary instrumentation
framework.
@@ -33,6 +42,9 @@
/* This code works (just), but it's a mess. Cleanups (also for
coregrind/m_debuginfo/image.c):
+ * Build this file for the host arch, not the target. But how?
+ Even Tromey had difficulty figuring out how to do that.
+
* Change the use of pread w/ fd to FILE*, for the file we're
serving. Or, at least, put a loop around the pread uses
so that it works correctly in the case where pread reads more
@@ -627,6 +639,9 @@
*ok = False;
return 0;
}
+ /* this is a kludge .. we should loop around pread and deal
+ with short reads, for whatever reason */
+ assert(nRead == avail);
UInt i;
for (i = 0; i < (UInt)nRead; i++)
crc = crc32_table[(crc ^ buf[i]) & 0xff] ^ (crc >> 8);
Modified: branches/DISRV/coregrind/pub_core_options.h (+7 -0)
===================================================================
--- branches/DISRV/coregrind/pub_core_options.h 2013-06-25 13:42:52 +01:00 (rev 13430)
+++ branches/DISRV/coregrind/pub_core_options.h 2013-06-27 18:39:15 +01:00 (rev 13431)
@@ -134,6 +134,13 @@
"d.d.d.d:d", where d is one or more digits. */
extern const HChar* VG_(clo_debuginfo_server);
+/* Do we allow reading debuginfo from debuginfo objects that don't
+ match (in some sense) the main object? This is dangerous, so the
+ default is NO (False). In any case it applies only to objects
+ found either in _extra_debuginfo_path or via the
+ _debuginfo_server. */
+extern Bool VG_(clo_allow_mismatched_debuginfo);
+
/* DEBUG: print generated code? default: 00000000 ( == NO ) */
extern UChar VG_(clo_trace_flags);
Modified: branches/DISRV/coregrind/m_debuginfo/readelf.c (+110 -16)
===================================================================
--- branches/DISRV/coregrind/m_debuginfo/readelf.c 2013-06-25 13:42:52 +01:00 (rev 13430)
+++ branches/DISRV/coregrind/m_debuginfo/readelf.c 2013-06-27 18:39:15 +01:00 (rev 13431)
@@ -1131,7 +1131,12 @@
/* Try to find a separate debug file for a given object file. If
- found, return its DiImage, which should be freed by the caller. */
+ found, return its DiImage, which should be freed by the caller. If
+ |buildid| is non-NULL, then a debug object matching it is
+ acceptable. If |buildid| is NULL or doesn't specify a findable
+ debug object, then we look in various places to find a file with
+ the specified CRC. And if that doesn't work out then we give
+ up. */
static
DiImage* find_debug_file( struct _DebugInfo* di,
const HChar* objpath, const HChar* buildid,
@@ -1166,11 +1171,11 @@
debugpath = ML_(dinfo_zalloc)(
"di.fdf.3",
- VG_(strlen)(objdir) + VG_(strlen)(debugname) + 32 +
- (extrapath ? VG_(strlen)(extrapath) : 0));
+ VG_(strlen)(objdir) + VG_(strlen)(debugname) + 64
+ + (extrapath ? VG_(strlen)(extrapath) : 0)
+ + (serverpath ? VG_(strlen)(serverpath) : 0));
VG_(sprintf)(debugpath, "%s/%s", objdir, debugname);
-
dimg = open_debug_file(debugpath, NULL, crc, rel_ok, NULL);
if (dimg != NULL) goto dimg_ok;
@@ -1184,13 +1189,20 @@
if (extrapath) {
VG_(sprintf)(debugpath, "%s%s/%s", extrapath,
- objdir, debugname);
+ objdir, debugname);
dimg = open_debug_file(debugpath, NULL, crc, rel_ok, NULL);
if (dimg != NULL) goto dimg_ok;
}
if (serverpath) {
- dimg = open_debug_file(debugname, NULL, crc, rel_ok, serverpath);
+ /* When looking on the debuginfo server, always just pass the
+ basename. */
+ const HChar* basename = debugname;
+ if (VG_(strstr)(basename, "/") != NULL) {
+ basename = VG_(strrchr)(basename, '/') + 1;
+ }
+ VG_(sprintf)(debugpath, "%s on %s", basename, serverpath);
+ dimg = open_debug_file(basename, NULL, crc, rel_ok, serverpath);
if (dimg) goto dimg_ok;
}
@@ -1212,6 +1224,77 @@
}
+/* Try to find a separate debug file for a given object file, in a
+ hacky and dangerous way: check only the --extra-debuginfo-path and
+ the --debuginfo-server. And don't do a consistency check. */
+static
+DiImage* find_debug_file_ad_hoc( struct _DebugInfo* di,
+ const HChar* objpath )
+{
+ const HChar* extrapath = VG_(clo_extra_debuginfo_path);
+ const HChar* serverpath = VG_(clo_debuginfo_server);
+
+ DiImage* dimg = NULL; /* the img that we found */
+ HChar* debugpath = NULL; /* where we found it */
+
+ HChar *objdir = ML_(dinfo_strdup)("di.fdfah.1", objpath);
+ HChar *objdirptr;
+
+ if ((objdirptr = VG_(strrchr)(objdir, '/')) != NULL)
+ *objdirptr = '\0';
+
+ debugpath = ML_(dinfo_zalloc)(
+ "di.fdfah.3",
+ VG_(strlen)(objdir) + 64
+ + (extrapath ? VG_(strlen)(extrapath) : 0)
+ + (serverpath ? VG_(strlen)(serverpath) : 0));
+
+ if (extrapath) {
+ VG_(sprintf)(debugpath, "%s/%s", extrapath, objpath);
+ dimg = ML_(img_from_local_file)(debugpath);
+ if (dimg != NULL) {
+ if (VG_(clo_verbosity) > 1) {
+ VG_(message)(Vg_DebugMsg, " Using (POSSIBLY MISMATCHED) %s\n",
+ debugpath);
+ }
+ goto dimg_ok;
+ }
+ }
+ if (serverpath) {
+ /* When looking on the debuginfo server, always just pass the
+ basename. */
+ const HChar* basename = objpath;
+ if (VG_(strstr)(basename, "/") != NULL) {
+ basename = VG_(strrchr)(basename, '/') + 1;
+ }
+ VG_(sprintf)(debugpath, "%s on %s", basename, serverpath);
+ dimg = ML_(img_from_di_server)(basename, serverpath);
+ if (dimg != NULL) {
+ if (VG_(clo_verbosity) > 1) {
+ VG_(message)(Vg_DebugMsg, " Using (POSSIBLY MISMATCHED) %s\n",
+ debugpath);
+ }
+ goto dimg_ok;
+ }
+ }
+
+ dimg_ok:
+
+ ML_(dinfo_free)(objdir);
+
+ if (dimg != NULL) {
+ vg_assert(debugpath);
+ TRACE_SYMTAB("\n");
+ TRACE_SYMTAB("------ Found an ad_hoc debuginfo file: %s\n", debugpath);
+ }
+
+ if (debugpath)
+ ML_(dinfo_free)(debugpath);
+
+ return dimg;
+}
+
+
static DiOffT INDEX_BIS ( DiOffT base, UWord idx, UWord scale ) {
// This is a bit stupid. Really, idx and scale ought to be
// 64-bit quantities, always.
@@ -2218,7 +2301,12 @@
/* Look for a build-id */
HChar* buildid = find_buildid(mimg, False, False);
- /* Look for a debug image */
+ /* Look for a debug image that matches either the build-id or
+ the debuglink-CRC32 in the main image. If the main image
+ doesn't contain either of those then this won't even bother
+ to try looking. This looks in all known places, including
+ the --extra-debuginfo-path if specified and on the
+ --debuginfo-server if specified. */
if (buildid != NULL || debuglink_escn.img != NULL) {
/* Do have a debuglink section? */
if (debuglink_escn.img != NULL) {
@@ -2251,16 +2339,22 @@
buildid = NULL; /* paranoia */
}
-# if defined(VGPV_arm_linux_android)
- if (dimg == NULL && VG_(clo_debuginfo_server) != NULL) {
- HChar* basename = di->fsm.filename;
- if (VG_(strstr)(basename, "/") != NULL)
- basename = VG_(strrchr)(basename, '/') + 1;
- VG_(printf)("XXXXXXXXXXX trying ad-hoc %s\n", basename);
- dimg = ML_(img_from_di_server)(basename,
- VG_(clo_debuginfo_server));
+ /* As a last-ditch measure, try looking for in the
+ --extra-debuginfo-path and/or on the --debuginfo-server, but
+ only in the case where --allow-mismatched-debuginfo=yes.
+ This is dangerous in that (1) it gives no assurance that the
+ debuginfo object matches the main one, and hence (2) we will
+ very likely get an assertion in the code below, if indeed
+ there is a mismatch. Hence it is disabled by default
+ (--allow-mismatched-debuginfo=no). Nevertheless it's
+ sometimes a useful way of getting out of a tight spot.
+
+ Note that we're ignoring the name in the .gnu_debuglink
+ section here, and just looking for a file of the same name
+ either the extra-path or on the server. */
+ if (dimg == NULL && VG_(clo_allow_mismatched_debuginfo)) {
+ dimg = find_debug_file_ad_hoc( di, di->fsm.filename );
}
-# endif
/* TOPLEVEL */
/* If we were successful in finding a debug image, pull various
Modified: branches/DISRV/coregrind/m_options.c (+1 -0)
===================================================================
--- branches/DISRV/coregrind/m_options.c 2013-06-25 13:42:52 +01:00 (rev 13430)
+++ branches/DISRV/coregrind/m_options.c 2013-06-27 18:39:15 +01:00 (rev 13431)
@@ -81,6 +81,7 @@
const HChar* VG_(clo_fullpath_after)[VG_CLO_MAX_FULLPATH_AFTER];
const HChar* VG_(clo_extra_debuginfo_path) = NULL;
const HChar* VG_(clo_debuginfo_server) = NULL;
+Bool VG_(clo_allow_mismatched_debuginfo) = False;
UChar VG_(clo_trace_flags) = 0; // 00000000b
Bool VG_(clo_profyle_sbs) = False;
UChar VG_(clo_profyle_flags) = 0; // 00000000b
Modified: branches/DISRV/coregrind/m_debuginfo/image.c (+31 -12)
===================================================================
--- branches/DISRV/coregrind/m_debuginfo/image.c 2013-06-25 13:42:52 +01:00 (rev 13430)
+++ branches/DISRV/coregrind/m_debuginfo/image.c 2013-06-27 18:39:15 +01:00 (rev 13431)
@@ -179,6 +179,18 @@
}
}
+/* If we lost communication with the remote server, just give up.
+ Recovering is too difficult. */
+static void give_up(void)
+{
+ VG_(umsg)("\n");
+ VG_(umsg)("Valgrind: Lost communication with the remote "
+ "debuginfo server.\n");
+ VG_(umsg)("Valgrind: I can't recover from that. Giving up. Sorry.\n");
+ VG_(umsg)("\n");
+ VG_(exit)(1);
+ /*NOTREACHED*/
+}
/* "Do" a transaction: that is, send the given frame to the server and
return the frame it sends back. Caller owns the resulting frame
@@ -186,7 +198,9 @@
some reason. */
static Frame* do_transaction ( Int sd, Frame* req )
{
-if (0) VG_(printf)("CLIENT: send %c%c%c%c\n", req->data[0], req->data[1], req->data[2], req->data[3]);
+ if (0) VG_(printf)("CLIENT: send %c%c%c%c\n",
+ req->data[0], req->data[1], req->data[2], req->data[3]);
+
/* What goes on the wire is:
adler(le32) n_data(le32) data[0 .. n_data-1]
where the checksum covers n_data as well as data[].
@@ -224,7 +238,8 @@
r = my_read(sd, res->data, res->n_data);
if (r != rd_len) return NULL;
-if (0) VG_(printf)("CLIENT: recv %c%c%c%c\n", res->data[0], res->data[1], res->data[2], res->data[3]);
+ if (0) VG_(printf)("CLIENT: recv %c%c%c%c\n",
+ res->data[0], res->data[1], res->data[2], res->data[3]);
/* Compute the checksum for the received data, and check it. */
adler = VG_(adler32)(0, NULL, 0); // initial value
@@ -417,16 +432,16 @@
/* So, read off .. off+len-1 into the entry. */
CEnt* ce = img->ces[entNo];
-if (0) {
-static UInt t_last = 0;
-static ULong nread = 0;
-UInt now = VG_(read_millisecond_timer)();
-UInt delay = now - t_last;
-t_last = now;
-nread += len;
-VG_(printf)("XXXXXXXX (tot %lld) read %ld offset %lld %u\n",
- nread, len, off, delay);
-}
+ if (0) {
+ static UInt t_last = 0;
+ static ULong nread = 0;
+ UInt now = VG_(read_millisecond_timer)();
+ UInt delay = now - t_last;
+ t_last = now;
+ nread += len;
+ VG_(printf)("XXXXXXXX (tot %lld) read %ld offset %lld %u\n",
+ nread, len, off, delay);
+ }
if (img->source.is_local) {
// Simple: just read it
@@ -487,6 +502,8 @@
VG_(umsg)("set_CEnt (reading data from DI server): fail: "
"server unexpectedly closed the connection\n");
}
+ give_up();
+ /* NOTREACHED */
vg_assert(0);
end_of_else_clause:
{}
@@ -968,6 +985,8 @@
if (req) free_Frame(req);
if (res) free_Frame(res);
// FIXME: now what?
+ give_up();
+ /* NOTREACHED */
vg_assert(0);
}
/*NOTREACHED*/
|
|
From: Philippe W. <phi...@sk...> - 2013-06-26 03:34:45
|
valgrind revision: 13430 VEX revision: 2728 C compiler: gcc (GCC) 4.7.2 20121109 (Red Hat 4.7.2-8) GDB: GNU gdb (GDB) Fedora (7.5.1-37.fc18) Assembler: GNU assembler version 2.23.51.0.1-7.fc18 20120806 C library: GNU C Library stable release version 2.16 uname -mrs: Linux 3.7.2-204.fc18.ppc64 ppc64 Vendor version: Fedora release 18 (Spherical Cow) Nightly build on gcc110 ( Fedora release 18 (Spherical Cow), ppc64 ) Started at 2013-06-25 20:00:21 PDT Ended at 2013-06-25 20:34:20 PDT 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 == 557 tests, 31 stderr failures, 3 stdout failures, 0 stderrB failures, 0 stdoutB failures, 2 post failures == memcheck/tests/linux/getregset (stdout) memcheck/tests/linux/getregset (stderr) memcheck/tests/ppc64/power_ISA2_05 (stdout) memcheck/tests/supp_unknown (stderr) memcheck/tests/varinfo6 (stderr) memcheck/tests/wrap8 (stdout) memcheck/tests/wrap8 (stderr) massif/tests/big-alloc (post) massif/tests/deep-D (post) helgrind/tests/annotate_rwlock (stderr) helgrind/tests/free_is_write (stderr) helgrind/tests/hg02_deadlock (stderr) helgrind/tests/hg03_inherit (stderr) helgrind/tests/hg04_race (stderr) helgrind/tests/hg05_race2 (stderr) helgrind/tests/locked_vs_unlocked1_fwd (stderr) helgrind/tests/locked_vs_unlocked1_rev (stderr) helgrind/tests/locked_vs_unlocked2 (stderr) helgrind/tests/locked_vs_unlocked3 (stderr) helgrind/tests/pth_barrier1 (stderr) helgrind/tests/pth_barrier2 (stderr) helgrind/tests/pth_barrier3 (stderr) helgrind/tests/pth_destroy_cond (stderr) helgrind/tests/rwlock_race (stderr) helgrind/tests/tc01_simple_race (stderr) helgrind/tests/tc05_simple_race (stderr) helgrind/tests/tc06_two_races (stderr) helgrind/tests/tc06_two_races_xml (stderr) helgrind/tests/tc09_bad_unlock (stderr) helgrind/tests/tc14_laog_dinphils (stderr) helgrind/tests/tc16_byterace (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) |
|
From: Tom H. <to...@co...> - 2013-06-26 03:19:56
|
valgrind revision: 13430 VEX revision: 2728 C compiler: gcc (GCC) 4.3.0 20080428 (Red Hat 4.3.0-8) GDB: Assembler: GNU assembler version 2.18.50.0.6-2 20080403 C library: GNU C Library stable release version 2.8 uname -mrs: Linux 3.9.4-200.fc18.x86_64 x86_64 Vendor version: Fedora release 9 (Sulphur) Nightly build on bristol ( x86_64, Fedora 9 ) Started at 2013-06-26 03:51:48 BST Ended at 2013-06-26 04:19:37 BST 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 == 632 tests, 1 stderr failure, 1 stdout failure, 0 stderrB failures, 0 stdoutB failures, 0 post failures == memcheck/tests/amd64/insn-pcmpistri (stderr) none/tests/amd64/sse4-64 (stdout) |
|
From: Tom H. <to...@co...> - 2013-06-26 03:08:55
|
valgrind revision: 13430 VEX revision: 2728 C compiler: gcc (GCC) 4.4.1 20090725 (Red Hat 4.4.1-2) GDB: Assembler: GNU assembler version 2.19.51.0.14-3.fc11 20090722 C library: GNU C Library stable release version 2.10.2 uname -mrs: Linux 3.9.4-200.fc18.x86_64 x86_64 Vendor version: Fedora release 11 (Leonidas) Nightly build on bristol ( x86_64, Fedora 11 ) Started at 2013-06-26 03:41:42 BST Ended at 2013-06-26 04:08:40 BST 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 == 634 tests, 1 stderr failure, 1 stdout failure, 0 stderrB failures, 0 stdoutB failures, 0 post failures == memcheck/tests/long_namespace_xml (stderr) none/tests/amd64/sse4-64 (stdout) |
|
From: Tom H. <to...@co...> - 2013-06-26 03:02:09
|
valgrind revision: 13430 VEX revision: 2728 C compiler: gcc (GCC) 4.4.5 20101112 (Red Hat 4.4.5-2) GDB: Assembler: GNU assembler version 2.20.51.0.2-20.fc13 20091009 C library: GNU C Library stable release version 2.12.2 uname -mrs: Linux 3.9.4-200.fc18.x86_64 x86_64 Vendor version: Fedora release 13 (Goddard) Nightly build on bristol ( x86_64, Fedora 13 ) Started at 2013-06-26 03:32:07 BST Ended at 2013-06-26 04:01:57 BST 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 == 634 tests, 1 stderr failure, 0 stdout failures, 0 stderrB failures, 0 stdoutB failures, 0 post failures == helgrind/tests/pth_barrier3 (stderr) |
|
From: Tom H. <to...@co...> - 2013-06-26 02:55:15
|
valgrind revision: 13430 VEX revision: 2728 C compiler: gcc (GCC) 4.5.1 20100924 (Red Hat 4.5.1-4) GDB: GNU gdb (GDB) Fedora (7.2-52.fc14) Assembler: GNU assembler version 2.20.51.0.7-8.fc14 20100318 C library: GNU C Library stable release version 2.13 uname -mrs: Linux 3.9.4-200.fc18.x86_64 x86_64 Vendor version: Fedora release 14 (Laughlin) Nightly build on bristol ( x86_64, Fedora 14 ) Started at 2013-06-26 03:22:40 BST Ended at 2013-06-26 03:55:01 BST 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 == 653 tests, 1 stderr failure, 0 stdout failures, 0 stderrB failures, 0 stdoutB failures, 0 post failures == memcheck/tests/origin5-bz2 (stderr) |
|
From: Tom H. <to...@co...> - 2013-06-26 02:49:02
|
valgrind revision: 13430 VEX revision: 2728 C compiler: gcc (GCC) 4.6.3 20120306 (Red Hat 4.6.3-2) GDB: GNU gdb (GDB) Fedora (7.3.1-48.fc15) Assembler: GNU assembler version 2.21.51.0.6-6.fc15 20110118 C library: GNU C Library stable release version 2.14.1 uname -mrs: Linux 3.9.4-200.fc18.x86_64 x86_64 Vendor version: Fedora release 15 (Lovelock) Nightly build on bristol ( x86_64, Fedora 15 ) Started at 2013-06-26 03:15:43 BST Ended at 2013-06-26 03:48:49 BST 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 == 655 tests, 1 stderr failure, 0 stdout failures, 0 stderrB failures, 0 stdoutB failures, 0 post failures == memcheck/tests/origin5-bz2 (stderr) |
|
From: Tom H. <to...@co...> - 2013-06-26 02:39:43
|
valgrind revision: 13430 VEX revision: 2728 C compiler: gcc (GCC) 4.6.3 20120306 (Red Hat 4.6.3-2) GDB: GNU gdb (GDB) Fedora (7.3.50.20110722-16.fc16) Assembler: GNU assembler version 2.21.53.0.1-6.fc16 20110716 C library: GNU C Library development release version 2.14.90 uname -mrs: Linux 3.9.4-200.fc18.x86_64 x86_64 Vendor version: Fedora release 16 (Verne) Nightly build on bristol ( x86_64, Fedora 16 ) Started at 2013-06-26 03:02:49 BST Ended at 2013-06-26 03:39:28 BST 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 == 655 tests, 1 stderr failure, 0 stdout failures, 0 stderrB failures, 0 stdoutB failures, 0 post failures == memcheck/tests/origin5-bz2 (stderr) |
|
From: Tom H. <to...@co...> - 2013-06-26 02:26:18
|
valgrind revision: 13430 VEX revision: 2728 C compiler: gcc (GCC) 4.7.2 20120921 (Red Hat 4.7.2-2) GDB: GNU gdb (GDB) Fedora (7.4.50.20120120-54.fc17) Assembler: GNU assembler version 2.22.52.0.1-10.fc17 20120131 C library: GNU C Library stable release version 2.15 uname -mrs: Linux 3.9.4-200.fc18.x86_64 x86_64 Vendor version: Fedora release 17 (Beefy Miracle) Nightly build on bristol ( x86_64, Fedora 17 (Beefy Miracle) ) Started at 2013-06-26 02:51:48 BST Ended at 2013-06-26 03:26:03 BST 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 == 655 tests, 5 stderr failures, 1 stdout failure, 0 stderrB failures, 0 stdoutB failures, 0 post failures == gdbserver_tests/mcinfcallRU (stderr) gdbserver_tests/mcinfcallWSRU (stderr) gdbserver_tests/mcmain_pic (stderr) memcheck/tests/origin5-bz2 (stderr) exp-sgcheck/tests/preen_invars (stdout) exp-sgcheck/tests/preen_invars (stderr) |
|
From: Christian B. <bor...@de...> - 2013-06-26 02:14:51
|
valgrind revision: 13430 VEX revision: 2728 C compiler: gcc (SUSE Linux) 4.3.4 [gcc-4_3-branch revision 152973] GDB: GNU gdb (GDB) SUSE (7.3-0.6.1) Assembler: GNU assembler (GNU Binutils; SUSE Linux Enterprise 11) 2.21.1 C library: GNU C Library stable release version 2.11.3 (20110527) uname -mrs: Linux 3.0.74-0.6.10-default s390x Vendor version: Welcome to SUSE Linux Enterprise Server 11 SP2 (s390x) - Kernel %r (%t). Nightly build on sless390 ( SUSE Linux Enterprise Server 11 SP1 gcc 4.3.4 on z196 (s390x) ) Started at 2013-06-26 03:45:01 CEST Ended at 2013-06-26 04:14:41 CEST Results unchanged from 24 hours ago Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... done Regression test results follow == 635 tests, 0 stderr failures, 0 stdout failures, 0 stderrB failures, 0 stdoutB failures, 0 post failures == |
|
From: Christian B. <bor...@de...> - 2013-06-26 02:14:37
|
valgrind revision: 13430 VEX revision: 2728 C compiler: gcc (GCC) 4.6.1 20110908 (Red Hat 4.6.1-9bb4) GDB: GNU gdb (GDB) Fedora (7.5-1bb1.fc15) Assembler: GNU assembler version 2.21.51.0.6-6bb6.fc15 20110118 C library: GNU C Library stable release version 2.14.1 uname -mrs: Linux 3.8.6-60.x.20130412-s390xperformance s390x Vendor version: unknown Nightly build on fedora390 ( Fedora 15 with devel libc/toolchain on z196 (s390x) ) Started at 2013-06-26 03:45:01 CEST Ended at 2013-06-26 04:14:43 CEST 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 == 636 tests, 2 stderr failures, 0 stdout failures, 0 stderrB failures, 0 stdoutB failures, 0 post failures == helgrind/tests/tc18_semabuse (stderr) helgrind/tests/tc20_verifywrap (stderr) |
|
From: Tom H. <to...@co...> - 2013-06-26 02:14:29
|
valgrind revision: 13430 VEX revision: 2728 C compiler: gcc (GCC) 4.7.2 20121109 (Red Hat 4.7.2-8) GDB: GNU gdb (GDB) Fedora (7.5.1-38.fc18) Assembler: GNU assembler version 2.23.51.0.1-6.fc18 20120806 C library: GNU C Library stable release version 2.16 uname -mrs: Linux 3.9.4-200.fc18.x86_64 x86_64 Vendor version: Fedora release 18 (Spherical Cow) Nightly build on bristol ( x86_64, Fedora 18 (Spherical Cow) ) Started at 2013-06-26 02:41:56 BST Ended at 2013-06-26 03:14:12 BST 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 == 655 tests, 2 stderr failures, 1 stdout failure, 0 stderrB failures, 0 stdoutB failures, 0 post failures == memcheck/tests/origin5-bz2 (stderr) exp-sgcheck/tests/preen_invars (stdout) exp-sgcheck/tests/preen_invars (stderr) |
|
From: Tom H. <to...@co...> - 2013-06-26 02:04:02
|
valgrind revision: 13430 VEX revision: 2728 C compiler: gcc (GCC) 4.8.1 20130603 (Red Hat 4.8.1-1) GDB: GNU gdb (GDB) Fedora (7.6-30.fc19) Assembler: GNU assembler version 2.23.52.0.1-8.fc19 20130226 C library: GNU C Library (GNU libc) stable release version 2.17 uname -mrs: Linux 3.9.4-200.fc18.x86_64 x86_64 Vendor version: Fedora release 19 (Schrödingerâs Cat) Nightly build on bristol ( x86_64, Fedora 19 (Schrödingerâs Cat) ) Started at 2013-06-26 02:31:25 BST Ended at 2013-06-26 03:03:47 BST 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 == 655 tests, 3 stderr failures, 0 stdout failures, 0 stderrB failures, 0 stdoutB failures, 0 post failures == memcheck/tests/dw4 (stderr) memcheck/tests/origin5-bz2 (stderr) exp-sgcheck/tests/hackedbz2 (stderr) |
|
From: Tom H. <to...@co...> - 2013-06-26 01:49:30
|
valgrind revision: 13430 VEX revision: 2728 C compiler: gcc (GCC) 4.8.1 20130612 (Red Hat 4.8.1-2) GDB: GNU gdb (GDB) Fedora (7.6-32.fc20) Assembler: GNU assembler version 2.23.2 C library: GNU C Library (GNU libc) development release version 2.17.90 uname -mrs: Linux 3.9.4-200.fc18.x86_64 x86_64 Vendor version: Fedora release 20 (Rawhide) Nightly build on bristol ( x86_64, Fedora 20 ) Started at 2013-06-26 02:22:10 BST Ended at 2013-06-26 02:49:16 BST 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 == 655 tests, 5 stderr failures, 1 stdout failure, 0 stderrB failures, 0 stdoutB failures, 0 post failures == memcheck/tests/amd64/insn_basic (stderr) memcheck/tests/dw4 (stderr) memcheck/tests/origin5-bz2 (stderr) none/tests/amd64/insn_basic (stdout) none/tests/amd64/insn_basic (stderr) exp-sgcheck/tests/hackedbz2 (stderr) |
|
From: <sv...@va...> - 2013-06-25 12:43:11
|
sewardj 2013-06-25 13:42:52 +0100 (Tue, 25 Jun 2013)
New Revision: 13430
Log:
Connect up the Mach-O reader to the new DiImage abstractions.
Modified files:
branches/DISRV/coregrind/m_debuginfo/priv_image.h
branches/DISRV/coregrind/m_debuginfo/readmacho.c
branches/DISRV/coregrind/m_main.c
branches/DISRV/include/vki/vki-darwin.h
Modified: branches/DISRV/coregrind/m_main.c (+2 -2)
===================================================================
--- branches/DISRV/coregrind/m_main.c 2013-06-17 22:04:25 +01:00 (rev 13429)
+++ branches/DISRV/coregrind/m_main.c 2013-06-25 13:42:52 +01:00 (rev 13430)
@@ -176,7 +176,7 @@
" --extra-debuginfo-path=path absolute path to search for additional\n"
" debug symbols, in addition to existing default\n"
" well known search paths.\n"
-" --debuginfo-server=ipaddr:port\n also query this server"
+" --debuginfo-server=ipaddr:port also query this server\n"
" (valgrind-di-server) for debug symbols\n"
" --smc-check=none|stack|all|all-non-file [stack]\n"
" checks for self-modifying code: none, only for\n"
@@ -259,7 +259,7 @@
" 0000 0010 show after reg-alloc\n"
" 0000 0001 show final assembly\n"
" 0000 0000 show summary profile only\n"
-" (Nb: you need --trace-notbelow and/or --trace-notabove "
+" (Nb: you need --trace-notbelow and/or --trace-notabove\n"
" with --trace-flags for full details)\n"
"\n"
" debugging options for Valgrind tools that report errors\n"
Modified: branches/DISRV/coregrind/m_debuginfo/readmacho.c (+398 -365)
===================================================================
--- branches/DISRV/coregrind/m_debuginfo/readmacho.c 2013-06-17 22:04:25 +01:00 (rev 13429)
+++ branches/DISRV/coregrind/m_debuginfo/readmacho.c 2013-06-25 13:42:52 +01:00 (rev 13430)
@@ -47,8 +47,9 @@
#include "pub_core_clientstate.h"
#include "pub_core_debuginfo.h"
+#include "priv_misc.h"
+#include "priv_image.h"
#include "priv_d3basics.h"
-#include "priv_misc.h"
#include "priv_tytypes.h"
#include "priv_storage.h"
#include "priv_readmacho.h"
@@ -85,24 +86,16 @@
/*--- ---*/
/*------------------------------------------------------------*/
-typedef
- struct {
- /* These two describe the entire mapped-in ("primary") image,
- fat headers, kitchen sink, whatnot: the entire file. The
- image is mapped into img[0 .. img_szB-1]. */
- UChar* img;
- SizeT img_szB;
- /* These two describe the Mach-O object of interest, which is
- presumably somewhere inside the primary image.
- map_image_aboard() below, which generates this info, will
- carefully check that the macho_ fields denote a section of
- memory that falls entirely inside img[0 .. img_szB-1]. */
- UChar* macho_img;
- SizeT macho_img_szB;
- }
- ImageInfo;
+/* A DiSlice is used to handle the thin/fat distinction for MachO images.
+ (1) the entire mapped-in ("primary") image, fat headers, kitchen sink,
+ whatnot: the entire file. This is the DiImage* that is the backing
+ for the DiSlice.
+ (2) the Mach-O object of interest, which is presumably somewhere inside
+ the primary image. map_image_aboard() below, which generates this
+ info, will carefully check that the macho_ fields denote a section of
+ memory that falls entirely inside the primary image.
+*/
-
Bool ML_(is_macho_object_file)( const void* buf, SizeT szB )
{
/* (JRS: the Mach-O headers might not be in this mapped data,
@@ -137,174 +130,158 @@
/* Unmap an image mapped in by map_image_aboard. */
-static void unmap_image ( /*MOD*/ImageInfo* ii )
+static void unmap_image ( /*MOD*/DiSlice* sli )
{
- SysRes sres;
- vg_assert(ii->img);
- vg_assert(ii->img_szB > 0);
- sres = VG_(am_munmap_valgrind)( (Addr)ii->img, ii->img_szB );
- /* Do we care if this fails? I suppose so; it would indicate
- some fairly serious snafu with the mapping of the file. */
- vg_assert( !sr_isError(sres) );
- VG_(memset)(ii, 0, sizeof(*ii));
+ vg_assert(sli);
+ if (ML_(sli_is_valid)(*sli)) {
+ ML_(img_done)(sli->img);
+ *sli = DiSlice_INVALID;
+ }
}
-/* Map a given fat or thin object aboard, find the thin part if
- necessary, do some checks, and write details of both the fat and
- thin parts into *ii. Returns False (and leaves the file unmapped)
- on failure. Guarantees to return pointers to a valid(ish) Mach-O
- image if it succeeds. */
-static Bool map_image_aboard ( DebugInfo* di, /* only for err msgs */
- /*OUT*/ImageInfo* ii, UChar* filename )
+/* Open the given file, find the thin part if necessary, do some
+ checks, and return a DiSlice containing details of both the thin
+ part and (implicitly, via the contained DiImage*) the fat part.
+ returns DiSlice_INVALID if it fails. If it succeeds, the returned
+ slice is guaranteed to refer to a valid(ish) Mach-O image. */
+static DiSlice map_image_aboard ( DebugInfo* di, /* only for err msgs */
+ const HChar* filename )
{
- VG_(memset)(ii, 0, sizeof(*ii));
+ DiSlice sli = DiSlice_INVALID;
/* First off, try to map the thing in. */
- { SizeT size;
- SysRes fd, sres;
- struct vg_stat stat_buf;
-
- fd = VG_(stat)(filename, &stat_buf);
- if (sr_isError(fd)) {
- ML_(symerr)(di, True, "Can't stat image (to determine its size)?!");
- return False;
- }
- size = stat_buf.size;
-
- fd = VG_(open)(filename, VKI_O_RDONLY, 0);
- if (sr_isError(fd)) {
- ML_(symerr)(di, True, "Can't open image to read symbols?!");
- return False;
- }
-
- sres = VG_(am_mmap_file_float_valgrind)
- ( size, VKI_PROT_READ, sr_Res(fd), 0 );
- if (sr_isError(sres)) {
- ML_(symerr)(di, True, "Can't mmap image to read symbols?!");
- return False;
- }
-
- VG_(close)(sr_Res(fd));
-
- ii->img = (UChar*)sr_Res(sres);
- ii->img_szB = size;
+ DiImage* mimg = ML_(img_from_local_file)(filename);
+ if (mimg == NULL) {
+ VG_(message)(Vg_UserMsg, "warning: connection to image %s failed\n",
+ filename );
+ VG_(message)(Vg_UserMsg, " no symbols or debug info loaded\n" );
+ return DiSlice_INVALID;
}
- /* Now it's mapped in and we have .img and .img_szB set. Look for
- the embedded Mach-O object. If not findable, unmap and fail. */
- { struct fat_header* fh_be;
- struct fat_header fh;
- struct MACH_HEADER* mh;
+ /* Now we have a viable DiImage* for it. Look for the embedded
+ Mach-O object. If not findable, close the image and fail. */
+ DiOffT fh_be_ioff = 0;
+ struct fat_header fh_be;
+ struct fat_header fh;
- // Assume initially that we have a thin image, and update
- // these if it turns out to be fat.
- ii->macho_img = ii->img;
- ii->macho_img_szB = ii->img_szB;
+ // Assume initially that we have a thin image, and narrow
+ // the bounds if it turns out to be fat. This stores |mimg| as
+ // |sli.img|, so NULL out |mimg| after this point, for the sake of
+ // clarity.
+ sli = ML_(sli_from_img)(mimg);
+ mimg = NULL;
- // Check for fat header.
- if (ii->img_szB < sizeof(struct fat_header)) {
- ML_(symerr)(di, True, "Invalid Mach-O file (0 too small).");
- goto unmap_and_fail;
- }
+ // Check for fat header.
+ if (ML_(img_size)(sli.img) < sizeof(struct fat_header)) {
+ ML_(symerr)(di, True, "Invalid Mach-O file (0 too small).");
+ goto close_and_fail;
+ }
- // Fat header is always BIG-ENDIAN
- fh_be = (struct fat_header *)ii->img;
- fh.magic = VG_(ntohl)(fh_be->magic);
- fh.nfat_arch = VG_(ntohl)(fh_be->nfat_arch);
- if (fh.magic == FAT_MAGIC) {
- // Look for a good architecture.
- struct fat_arch *arch_be;
- struct fat_arch arch;
- Int f;
- if (ii->img_szB < sizeof(struct fat_header)
- + fh.nfat_arch * sizeof(struct fat_arch)) {
- ML_(symerr)(di, True, "Invalid Mach-O file (1 too small).");
- goto unmap_and_fail;
- }
- for (f = 0, arch_be = (struct fat_arch *)(fh_be+1);
- f < fh.nfat_arch;
- f++, arch_be++) {
- Int cputype;
-# if defined(VGA_ppc)
- cputype = CPU_TYPE_POWERPC;
-# elif defined(VGA_ppc64)
- cputype = CPU_TYPE_POWERPC64;
-# elif defined(VGA_x86)
- cputype = CPU_TYPE_X86;
-# elif defined(VGA_amd64)
- cputype = CPU_TYPE_X86_64;
-# else
-# error "unknown architecture"
-# endif
- arch.cputype = VG_(ntohl)(arch_be->cputype);
- arch.cpusubtype = VG_(ntohl)(arch_be->cpusubtype);
- arch.offset = VG_(ntohl)(arch_be->offset);
- arch.size = VG_(ntohl)(arch_be->size);
- if (arch.cputype == cputype) {
- if (ii->img_szB < arch.offset + arch.size) {
- ML_(symerr)(di, True, "Invalid Mach-O file (2 too small).");
- goto unmap_and_fail;
- }
- ii->macho_img = ii->img + arch.offset;
- ii->macho_img_szB = arch.size;
- break;
- }
- }
- if (f == fh.nfat_arch) {
- ML_(symerr)(di, True,
- "No acceptable architecture found in fat file.");
- goto unmap_and_fail;
- }
- }
+ // Fat header is always BIG-ENDIAN
+ ML_(img_get)(&fh_be, sli.img, fh_be_ioff, sizeof(fh_be));
+ VG_(memset)(&fh, 0, sizeof(fh));
+ fh.magic = VG_(ntohl)(fh_be.magic);
+ fh.nfat_arch = VG_(ntohl)(fh_be.nfat_arch);
+ if (fh.magic == FAT_MAGIC) {
+ // Look for a good architecture.
+ if (ML_(img_size)(sli.img) < sizeof(struct fat_header)
+ + fh.nfat_arch * sizeof(struct fat_arch)) {
+ ML_(symerr)(di, True, "Invalid Mach-O file (1 too small).");
+ goto close_and_fail;
+ }
+ DiOffT arch_be_ioff;
+ Int f;
+ for (f = 0, arch_be_ioff = sizeof(struct fat_header);
+ f < fh.nfat_arch;
+ f++, arch_be_ioff += sizeof(struct fat_arch)) {
+# if defined(VGA_ppc)
+ Int cputype = CPU_TYPE_POWERPC;
+# elif defined(VGA_ppc64)
+ Int cputype = CPU_TYPE_POWERPC64;
+# elif defined(VGA_x86)
+ Int cputype = CPU_TYPE_X86;
+# elif defined(VGA_amd64)
+ Int cputype = CPU_TYPE_X86_64;
+# else
+# error "unknown architecture"
+# endif
+ struct fat_arch arch_be;
+ struct fat_arch arch;
+ ML_(img_get)(&arch_be, sli.img, arch_be_ioff, sizeof(arch_be));
+ VG_(memset)(&arch, 0, sizeof(arch));
+ arch.cputype = VG_(ntohl)(arch_be.cputype);
+ arch.cpusubtype = VG_(ntohl)(arch_be.cpusubtype);
+ arch.offset = VG_(ntohl)(arch_be.offset);
+ arch.size = VG_(ntohl)(arch_be.size);
+ if (arch.cputype == cputype) {
+ if (ML_(img_size)(sli.img) < arch.offset + arch.size) {
+ ML_(symerr)(di, True, "Invalid Mach-O file (2 too small).");
+ goto close_and_fail;
+ }
+ /* Found a suitable arch. Narrow down the slice accordingly. */
+ sli.ioff = arch.offset;
+ sli.szB = arch.size;
+ break;
+ }
+ }
+ if (f == fh.nfat_arch) {
+ ML_(symerr)(di, True,
+ "No acceptable architecture found in fat file.");
+ goto close_and_fail;
+ }
+ }
- /* Sanity check what we found. */
+ /* Sanity check what we found. */
- /* assured by logic above */
- vg_assert(ii->img_szB >= sizeof(struct fat_header));
+ /* assured by logic above */
+ vg_assert(ML_(img_size)(sli.img) >= sizeof(struct fat_header));
- if (ii->macho_img_szB < sizeof(struct MACH_HEADER)) {
- ML_(symerr)(di, True, "Invalid Mach-O file (3 too small).");
- goto unmap_and_fail;
- }
+ if (sli.szB < sizeof(struct MACH_HEADER)) {
+ ML_(symerr)(di, True, "Invalid Mach-O file (3 too small).");
+ goto close_and_fail;
+ }
- if (ii->macho_img_szB > ii->img_szB) {
- ML_(symerr)(di, True, "Invalid Mach-O file (thin bigger than fat).");
- goto unmap_and_fail;
- }
+ if (sli.szB > ML_(img_size)(sli.img)) {
+ ML_(symerr)(di, True, "Invalid Mach-O file (thin bigger than fat).");
+ goto close_and_fail;
+ }
- if (ii->macho_img >= ii->img
- && ii->macho_img + ii->macho_img_szB <= ii->img + ii->img_szB) {
- /* thin entirely within fat, as expected */
- } else {
- ML_(symerr)(di, True, "Invalid Mach-O file (thin not inside fat).");
- goto unmap_and_fail;
- }
+ if (sli.ioff >= 0 && sli.ioff + sli.szB <= ML_(img_size)(sli.img)) {
+ /* thin entirely within fat, as expected */
+ } else {
+ ML_(symerr)(di, True, "Invalid Mach-O file (thin not inside fat).");
+ goto close_and_fail;
+ }
- mh = (struct MACH_HEADER *)ii->macho_img;
- if (mh->magic != MAGIC) {
- ML_(symerr)(di, True, "Invalid Mach-O file (bad magic).");
- goto unmap_and_fail;
- }
+ /* Peer at the Mach header for the thin object, starting at the
+ beginning of the slice, to check it's at least marginally
+ sane. */
+ struct MACH_HEADER mh;
+ ML_(cur_read_get)(&mh, ML_(cur_from_sli)(sli), sizeof(mh));
+ if (mh.magic != MAGIC) {
+ ML_(symerr)(di, True, "Invalid Mach-O file (bad magic).");
+ goto close_and_fail;
+ }
- if (ii->macho_img_szB < sizeof(struct MACH_HEADER) + mh->sizeofcmds) {
- ML_(symerr)(di, True, "Invalid Mach-O file (4 too small).");
- goto unmap_and_fail;
- }
+ if (sli.szB < sizeof(struct MACH_HEADER) + mh.sizeofcmds) {
+ ML_(symerr)(di, True, "Invalid Mach-O file (4 too small).");
+ goto close_and_fail;
}
- vg_assert(ii->img);
- vg_assert(ii->macho_img);
- vg_assert(ii->img_szB > 0);
- vg_assert(ii->macho_img_szB > 0);
- vg_assert(ii->macho_img >= ii->img);
- vg_assert(ii->macho_img + ii->macho_img_szB <= ii->img + ii->img_szB);
- return True; /* success */
+ /* "main image is plausible" */
+ vg_assert(sli.img);
+ vg_assert(ML_(img_size)(sli.img) > 0);
+ /* "thin image exists and is a sub-part (or all) of main image" */
+ vg_assert(sli.ioff >= 0);
+ vg_assert(sli.szB > 0);
+ vg_assert(sli.ioff + sli.szB <= ML_(img_size)(sli.img));
+ return sli; /* success */
/*NOTREACHED*/
- unmap_and_fail:
- unmap_image(ii);
- return False; /* bah! */
+ close_and_fail:
+ unmap_image(&sli);
+ return DiSlice_INVALID; /* bah! */
}
@@ -320,30 +297,38 @@
static
void read_symtab( /*OUT*/XArray* /* DiSym */ syms,
struct _DebugInfo* di,
- struct NLIST* o_symtab, UInt o_symtab_count,
- UChar* o_strtab, UInt o_strtab_sz )
+ DiCursor symtab_cur, UInt symtab_count,
+ DiCursor strtab_cur, UInt strtab_sz )
{
Int i;
- Addr sym_addr;
DiSym disym;
- UChar* name;
- static UChar* s_a_t_v = NULL; /* do not make non-static */
+ // "start_according_to_valgrind"
+ static HChar* s_a_t_v = NULL; /* do not make non-static */
- for (i = 0; i < o_symtab_count; i++) {
- struct NLIST *nl = o_symtab+i;
- if ((nl->n_type & N_TYPE) == N_SECT) {
- sym_addr = di->text_bias + nl->n_value;
- /*} else if ((nl->n_type & N_TYPE) == N_ABS) {
+ for (i = 0; i < symtab_count; i++) {
+ struct NLIST nl;
+ ML_(cur_read_get)(&nl,
+ ML_(cur_plus)(symtab_cur, i * sizeof(struct NLIST)),
+ sizeof(nl));
+
+ Addr sym_addr = 0;
+ if ((nl.n_type & N_TYPE) == N_SECT) {
+ sym_addr = di->text_bias + nl.n_value;
+ /*} else if ((nl.n_type & N_TYPE) == N_ABS) {
GrP fixme don't ignore absolute symbols?
- sym_addr = nl->n_value; */
+ sym_addr = nl.n_value; */
} else {
continue;
}
- if (di->trace_symtab)
- VG_(printf)("nlist raw: avma %010lx %s\n",
- sym_addr, o_strtab + nl->n_un.n_strx );
+ if (di->trace_symtab) {
+ HChar* str = ML_(cur_read_strdup)(
+ ML_(cur_plus)(strtab_cur, nl.n_un.n_strx),
+ "di.read_symtab.1");
+ VG_(printf)("nlist raw: avma %010lx %s\n", sym_addr, str );
+ ML_(dinfo_free)(str);
+ }
/* If no part of the symbol falls within the mapped range,
ignore it. */
@@ -354,14 +339,20 @@
/* skip names which point outside the string table;
following these risks segfaulting Valgrind */
- name = o_strtab + nl->n_un.n_strx;
- if (name < o_strtab || name >= o_strtab + o_strtab_sz)
+ if (nl.n_un.n_strx < 0 || nl.n_un.n_strx >= strtab_sz) {
continue;
+ }
+ HChar* name
+ = ML_(cur_read_strdup)( ML_(cur_plus)(strtab_cur, nl.n_un.n_strx),
+ "di.read_symtab.2");
+
/* skip nameless symbols; these appear to be common, but
useless */
- if (*name == 0)
+ if (*name == 0) {
+ ML_(dinfo_free)(name);
continue;
+ }
disym.addr = sym_addr;
disym.tocptr = 0;
@@ -389,6 +380,7 @@
vg_assert(disym.pri_name);
VG_(addToXA)( syms, &disym );
+ ML_(dinfo_free)(name);
}
}
@@ -496,7 +488,7 @@
#endif
-static Bool file_exists_p(const Char *path)
+static Bool file_exists_p(const HChar *path)
{
struct vg_stat sbuf;
SysRes res = VG_(stat)(path, &sbuf);
@@ -506,13 +498,13 @@
/* Search for an existing dSYM file as a possible separate debug file.
Adapted from gdb. */
-static Char *
-find_separate_debug_file (const Char *executable_name)
+static HChar *
+find_separate_debug_file (const HChar *executable_name)
{
- const Char *basename_str;
- Char *dot_ptr;
- Char *slash_ptr;
- Char *dsymfile;
+ const HChar *basename_str;
+ HChar *dot_ptr;
+ HChar *slash_ptr;
+ HChar *dsymfile;
/* Make sure the object file name itself doesn't contain ".dSYM" in it or we
will end up with an infinite loop where after we add a dSYM symbol file,
@@ -593,53 +585,85 @@
}
-static UChar *getsectdata(UChar* base, SizeT size,
- const Char *segname, const Char *sectname,
- /*OUT*/Word *sect_size)
+/* Given a DiSlice covering the entire Mach-O thin image, find the
+ DiSlice for the specified (segname, sectname) pairing, if
+ possible. */
+static DiSlice getsectdata ( DiSlice img,
+ const HChar *segname, const HChar *sectname )
{
- struct MACH_HEADER *mh = (struct MACH_HEADER *)base;
- struct load_command *cmd;
+ DiCursor cur = ML_(cur_from_sli)(img);
+
+ struct MACH_HEADER mh;
+ ML_(cur_step_get)(&mh, &cur, sizeof(mh));
+
Int c;
-
- for (c = 0, cmd = (struct load_command *)(mh+1);
- c < mh->ncmds;
- c++, cmd = (struct load_command *)(cmd->cmdsize + (Addr)cmd))
- {
- if (cmd->cmd == LC_SEGMENT_CMD) {
- struct SEGMENT_COMMAND *seg = (struct SEGMENT_COMMAND *)cmd;
- if (0 == VG_(strncmp(seg->segname, segname, sizeof(seg->segname)))) {
- struct SECTION *sects = (struct SECTION *)(seg+1);
+ for (c = 0; c < mh.ncmds; c++) {
+ struct load_command cmd;
+ ML_(cur_read_get)(&cmd, cur, sizeof(cmd));
+ if (cmd.cmd == LC_SEGMENT_CMD) {
+ struct SEGMENT_COMMAND seg;
+ ML_(cur_read_get)(&seg, cur, sizeof(seg));
+ if (0 == VG_(strncmp(&seg.segname[0],
+ segname, sizeof(seg.segname)))) {
+ DiCursor sects_cur = ML_(cur_plus)(cur, sizeof(seg));
Int s;
- for (s = 0; s < seg->nsects; s++) {
- if (0 == VG_(strncmp(sects[s].sectname, sectname,
- sizeof(sects[s].sectname))))
- {
- if (sect_size) *sect_size = sects[s].size;
- return (UChar *)(base + sects[s].offset);
+ for (s = 0; s < seg.nsects; s++) {
+ struct SECTION sect;
+ ML_(cur_step_get)(§, §s_cur, sizeof(sect));
+ if (0 == VG_(strncmp(sect.sectname, sectname,
+ sizeof(sect.sectname)))) {
+ DiSlice res = img;
+ res.ioff = sect.offset;
+ res.szB = sect.size;
+ return res;
}
}
+
}
}
+ cur = ML_(cur_plus)(cur, cmd.cmdsize);
}
- if (sect_size) *sect_size = 0;
- return 0;
+ return DiSlice_INVALID;
}
-/* Brute force just simply search for uuid[0..15] in img[0..n_img-1] */
-static Bool check_uuid_matches ( Addr imgA, Word n_img, UChar* uuid )
+/* Brute force just simply search for uuid[0..15] in |sli| */
+static Bool check_uuid_matches ( DiSlice sli, UChar* uuid )
{
- Word i;
- UChar* img = (UChar*)imgA;
- UChar first = uuid[0];
- if (n_img < 16)
+ if (sli.szB < 16)
return False;
- for (i = 0; i < n_img-16; i++) {
- if (img[i] != first)
- continue;
- if (0 == VG_(memcmp)( &img[i], &uuid[0], 16 ))
- return True;
+
+ /* Work through the slice in 1 KB chunks. */
+ UChar first = uuid[0];
+ DiOffT min_off = sli.ioff;
+ DiOffT max1_off = sli.ioff + sli.szB;
+ DiOffT curr_off = min_off;
+ vg_assert(min_off < max1_off);
+ while (1) {
+ vg_assert(curr_off >= min_off && curr_off <= max1_off);
+ if (curr_off == max1_off) break;
+ DiOffT avail = max1_off - curr_off;
+ vg_assert(avail > 0 && avail <= max1_off);
+ if (avail > 1024) avail = 1024;
+ UChar buf[1024];
+ SizeT nGot = ML_(img_get_some)(buf, sli.img, curr_off, avail);
+ vg_assert(nGot >= 1 && nGot <= avail);
+ UInt i;
+ /* Scan through the 1K chunk we got, looking for the start char. */
+ for (i = 0; i < (UInt)nGot; i++) {
+ if (buf[i] != first)
+ continue;
+ /* first char matches. See if we can get 16 bytes at this
+ offset, and compare. */
+ if (curr_off + i < max1_off && max1_off - (curr_off + i) >= 16) {
+ UChar buff16[16];
+ ML_(img_get)(&buff16[0], sli.img, curr_off + i, 16);
+ if (0 == VG_(memcmp)(&buff16[0], &uuid[0], 16))
+ return True;
+ }
+ curr_off += nGot;
+ }
}
return False;
}
@@ -648,7 +672,7 @@
/* Heuristic kludge: return True if this looks like an installed
standard library; hence we shouldn't consider automagically running
dsymutil on it. */
-static Bool is_systemish_library_name ( UChar* name )
+static Bool is_systemish_library_name ( HChar* name )
{
vg_assert(name);
if (0 == VG_(strncasecmp)(name, "/usr/", 5)
@@ -668,15 +692,14 @@
Bool ML_(read_macho_debug_info)( struct _DebugInfo* di )
{
- struct symtab_command *symcmd = NULL;
- struct dysymtab_command *dysymcmd = NULL;
- HChar* dsymfilename = NULL;
- Bool have_uuid = False;
- UChar uuid[16];
- ImageInfo ii; /* main file */
- ImageInfo iid; /* auxiliary .dSYM file */
- Bool ok;
- Word i;
+ DiSlice msli = DiSlice_INVALID; // the main image
+ DiSlice dsli = DiSlice_INVALID; // the debuginfo image
+ DiCursor sym_cur = DiCursor_INVALID;
+ DiCursor dysym_cur = DiCursor_INVALID;
+ HChar* dsymfilename = NULL;
+ Bool have_uuid = False;
+ UChar uuid[16];
+ Word i;
struct _DebugInfoMapping* rx_map = NULL;
struct _DebugInfoMapping* rw_map = NULL;
@@ -705,14 +728,15 @@
"%s (rx at %#lx, rw at %#lx)\n", di->fsm.filename,
rx_map->avma, rw_map->avma );
- VG_(memset)(&ii, 0, sizeof(ii));
- VG_(memset)(&iid, 0, sizeof(iid));
VG_(memset)(&uuid, 0, sizeof(uuid));
- ok = map_image_aboard( di, &ii, di->fsm.filename );
- if (!ok) goto fail;
+ msli = map_image_aboard( di, di->fsm.filename );
+ if (!ML_(sli_is_valid)(msli)) {
+ ML_(symerr)(di, False, "Connect to main image failed.");
+ goto fail;
+ }
- vg_assert(ii.macho_img != NULL && ii.macho_img_szB > 0);
+ vg_assert(msli.img != NULL && msli.szB > 0);
/* Poke around in the Mach-O header, to find some important
stuff. */
@@ -725,38 +749,55 @@
di->text_bias = 0;
- { struct MACH_HEADER *mh = (struct MACH_HEADER *)ii.macho_img;
- struct load_command *cmd;
+ {
+ DiCursor cmd_cur = ML_(cur_from_sli)(msli);
+
+ struct MACH_HEADER mh;
+ ML_(cur_step_get)(&mh, &cmd_cur, sizeof(mh));
+
+ /* Now cur_cmd points just after the Mach header, right at the
+ start of the load commands, which is where we need it to start
+ the following loop. */
+
Int c;
-
- for (c = 0, cmd = (struct load_command *)(mh+1);
- c < mh->ncmds;
- c++, cmd = (struct load_command *)(cmd->cmdsize
- + (unsigned long)cmd)) {
- if (cmd->cmd == LC_SYMTAB) {
- symcmd = (struct symtab_command *)cmd;
+ for (c = 0; c < mh.ncmds; c++) {
+ struct load_command cmd;
+ ML_(cur_read_get)(&cmd, cmd_cur, sizeof(cmd));
+
+ if (cmd.cmd == LC_SYMTAB) {
+ sym_cur = cmd_cur;
}
- else if (cmd->cmd == LC_DYSYMTAB) {
- dysymcmd = (struct dysymtab_command *)cmd;
+ else if (cmd.cmd == LC_DYSYMTAB) {
+ dysym_cur = cmd_cur;
}
- else if (cmd->cmd == LC_ID_DYLIB && mh->filetype == MH_DYLIB) {
+ else if (cmd.cmd == LC_ID_DYLIB && mh.filetype == MH_DYLIB) {
// GrP fixme bundle?
- struct dylib_command *dcmd = (struct dylib_command *)cmd;
- UChar *dylibname = dcmd->dylib.name.offset + (UChar *)dcmd;
- UChar *soname = VG_(strrchr)(dylibname, '/');
+ struct dylib_command dcmd;
+ ML_(cur_read_get)(&dcmd, cmd_cur, sizeof(dcmd));
+ DiCursor dylibname_cur
+ = ML_(cur_plus)(cmd_cur, dcmd.dylib.name.offset);
+ HChar* dylibname
+ = ML_(cur_read_strdup)(dylibname_cur, "di.rmdi.1");
+ HChar* soname = VG_(strrchr)(dylibname, '/');
if (!soname) soname = dylibname;
else soname++;
di->soname = ML_(dinfo_strdup)("di.readmacho.dylibname",
soname);
+ ML_(dinfo_free)(dylibname);
}
- else if (cmd->cmd==LC_ID_DYLINKER && mh->filetype==MH_DYLINKER) {
- struct dylinker_command *dcmd = (struct dylinker_command *)cmd;
- UChar *dylinkername = dcmd->name.offset + (UChar *)dcmd;
- UChar *soname = VG_(strrchr)(dylinkername, '/');
+ else if (cmd.cmd==LC_ID_DYLINKER && mh.filetype==MH_DYLINKER) {
+ struct dylinker_command dcmd;
+ ML_(cur_read_get)(&dcmd, cmd_cur, sizeof(dcmd));
+ DiCursor dylinkername_cur
+ = ML_(cur_plus)(cmd_cur, dcmd.name.offset);
+ HChar* dylinkername
+ = ML_(cur_read_strdup)(dylinkername_cur, "di.rmdi.2");
+ HChar* soname = VG_(strrchr)(dylinkername, '/');
if (!soname) soname = dylinkername;
else soname++;
di->soname = ML_(dinfo_strdup)("di.readmacho.dylinkername",
soname);
+ ML_(dinfo_free)(dylinkername);
}
// A comment from Julian about why varinfo[35] fail:
@@ -786,17 +827,18 @@
// {text,data,bss}_{avma,svma}, from which the _bias numbers are
// then trivially derived. Then I think the debuginfo reader should
// work pretty well.
- else if (cmd->cmd == LC_SEGMENT_CMD) {
- struct SEGMENT_COMMAND *seg = (struct SEGMENT_COMMAND *)cmd;
+ else if (cmd.cmd == LC_SEGMENT_CMD) {
+ struct SEGMENT_COMMAND seg;
+ ML_(cur_read_get)(&seg, cmd_cur, sizeof(seg));
/* Try for __TEXT */
if (!di->text_present
- && 0 == VG_(strcmp)(seg->segname, "__TEXT")
+ && 0 == VG_(strcmp)(&seg.segname[0], "__TEXT")
/* DDD: is the next line a kludge? -- JRS */
- && seg->fileoff == 0 && seg->filesize != 0) {
+ && seg.fileoff == 0 && seg.filesize != 0) {
di->text_present = True;
- di->text_svma = (Addr)seg->vmaddr;
+ di->text_svma = (Addr)seg.vmaddr;
di->text_avma = rx_map->avma;
- di->text_size = seg->vmsize;
+ di->text_size = seg.vmsize;
di->text_bias = di->text_avma - di->text_svma;
/* Make the _debug_ values be the same as the
svma/bias for the primary object, since there is
@@ -808,22 +850,23 @@
}
/* Try for __DATA */
if (!di->data_present
- && 0 == VG_(strcmp)(seg->segname, "__DATA")
- /* && DDD:seg->fileoff == 0 */ && seg->filesize != 0) {
+ && 0 == VG_(strcmp)(&seg.segname[0], "__DATA")
+ /* && DDD:seg->fileoff == 0 */ && seg.filesize != 0) {
di->data_present = True;
- di->data_svma = (Addr)seg->vmaddr;
+ di->data_svma = (Addr)seg.vmaddr;
di->data_avma = rw_map->avma;
- di->data_size = seg->vmsize;
+ di->data_size = seg.vmsize;
di->data_bias = di->data_avma - di->data_svma;
di->data_debug_svma = di->data_svma;
di->data_debug_bias = di->data_bias;
}
}
- else if (cmd->cmd == LC_UUID) {
- struct uuid_command *uuid_cmd = (struct uuid_command *)cmd;
- VG_(memcpy)(uuid, uuid_cmd->uuid, sizeof(uuid));
+ else if (cmd.cmd == LC_UUID) {
+ ML_(cur_read_get)(&uuid, cmd_cur, sizeof(uuid));
have_uuid = True;
}
+ // Move the cursor along
+ cmd_cur = ML_(cur_plus)(cmd_cur, cmd.cmdsize);
}
}
@@ -839,33 +882,42 @@
/* Now we have the base object to hand. Read symbols from it. */
- if (ii.macho_img && ii.macho_img_szB > 0 && symcmd && dysymcmd) {
+ // We already asserted that ..
+ vg_assert(msli.img != NULL && msli.szB > 0);
+ if (ML_(cur_is_valid)(sym_cur) && ML_(cur_is_valid)(dysym_cur)) {
+
+ struct symtab_command symcmd;
+ struct dysymtab_command dysymcmd;
+
+ ML_(cur_read_get)(&symcmd, sym_cur, sizeof(symcmd));
+ ML_(cur_read_get)(&dysymcmd, dysym_cur, sizeof(dysymcmd));
+
/* Read nlist symbol table */
- struct NLIST *syms;
- UChar *strs;
+ DiCursor syms = DiCursor_INVALID;
+ DiCursor strs = DiCursor_INVALID;
XArray* /* DiSym */ candSyms = NULL;
Word nCandSyms;
- if (ii.macho_img_szB < symcmd->stroff + symcmd->strsize
- || ii.macho_img_szB < symcmd->symoff + symcmd->nsyms
- * sizeof(struct NLIST)) {
+ if (msli.szB < symcmd.stroff + symcmd.strsize
+ || msli.szB < symcmd.symoff + symcmd.nsyms
+ * sizeof(struct NLIST)) {
ML_(symerr)(di, False, "Invalid Mach-O file (5 too small).");
goto fail;
}
- if (dysymcmd->ilocalsym + dysymcmd->nlocalsym > symcmd->nsyms
- || dysymcmd->iextdefsym + dysymcmd->nextdefsym > symcmd->nsyms) {
+ if (dysymcmd.ilocalsym + dysymcmd.nlocalsym > symcmd.nsyms
+ || dysymcmd.iextdefsym + dysymcmd.nextdefsym > symcmd.nsyms) {
ML_(symerr)(di, False, "Invalid Mach-O file (bad symbol table).");
goto fail;
}
+
+ syms = ML_(cur_plus)(ML_(cur_from_sli)(msli), symcmd.symoff);
+ strs = ML_(cur_plus)(ML_(cur_from_sli)(msli), symcmd.stroff);
- syms = (struct NLIST *)(ii.macho_img + symcmd->symoff);
- strs = (UChar *)(ii.macho_img + symcmd->stroff);
-
if (VG_(clo_verbosity) > 1)
VG_(message)(Vg_DebugMsg,
" reading syms from primary file (%d %d)\n",
- dysymcmd->nextdefsym, dysymcmd->nlocalsym );
+ dysymcmd.nextdefsym, dysymcmd.nlocalsym );
/* Read candidate symbols into 'candSyms', so we can truncate
overlapping ends and generally tidy up, before presenting
@@ -878,14 +930,16 @@
// extern symbols
read_symtab(candSyms,
- di,
- syms + dysymcmd->iextdefsym, dysymcmd->nextdefsym,
- strs, symcmd->strsize);
+ di,
+ ML_(cur_plus)(syms,
+ dysymcmd.iextdefsym * sizeof(struct NLIST)),
+ dysymcmd.nextdefsym, strs, symcmd.strsize);
// static and private_extern symbols
read_symtab(candSyms,
- di,
- syms + dysymcmd->ilocalsym, dysymcmd->nlocalsym,
- strs, symcmd->strsize);
+ di,
+ ML_(cur_plus)(syms,
+ dysymcmd.ilocalsym * sizeof(struct NLIST)),
+ dysymcmd.nlocalsym, strs, symcmd.strsize);
/* tidy up the cand syms -- trim overlapping ends. May resize
candSyms. */
@@ -918,7 +972,7 @@
goto success;
/* mmap the dSYM file to look for DWARF debug info. If successful,
- use the .macho_img and .macho_img_szB in iid. */
+ use the .macho_img and .macho_img_szB in dsli. */
dsymfilename = find_separate_debug_file( di->fsm.filename );
@@ -929,14 +983,16 @@
if (VG_(clo_verbosity) > 1)
VG_(message)(Vg_DebugMsg, " dSYM= %s\n", dsymfilename);
- ok = map_image_aboard( di, &iid, dsymfilename );
- if (!ok) goto fail;
+ dsli = map_image_aboard( di, dsymfilename );
+ if (!ML_(sli_is_valid)(dsli)) {
+ ML_(symerr)(di, False, "Connect to debuginfo image failed "
+ "(first attempt).");
+ goto fail;
+ }
/* check it has the right uuid. */
vg_assert(have_uuid);
- valid = iid.macho_img && iid.macho_img_szB > 0
- && check_uuid_matches( (Addr)iid.macho_img,
- iid.macho_img_szB, uuid );
+ valid = dsli.img && dsli.szB > 0 && check_uuid_matches( dsli, uuid );
if (valid)
goto read_the_dwarf;
@@ -997,14 +1053,17 @@
if (VG_(clo_verbosity) > 1)
VG_(message)(Vg_DebugMsg, " dsyms= %s\n", dsymfilename);
- ok = map_image_aboard( di, &iid, dsymfilename );
- if (!ok) goto fail;
+ dsli = map_image_aboard( di, dsymfilename );
+ if (!ML_(sli_is_valid)(dsli)) {
+ ML_(symerr)(di, False, "Connect to debuginfo image failed "
+ "(second attempt).");
+ goto fail;
+ }
/* check it has the right uuid. */
vg_assert(have_uuid);
- valid = iid.macho_img && iid.macho_img_szB > 0
- && check_uuid_matches( (Addr)iid.macho_img,
- iid.macho_img_szB, uuid );
+ vg_assert(have_uuid);
+ valid = dsli.img && dsli.szB > 0 && check_uuid_matches( dsli, uuid );
if (!valid) {
if (VG_(clo_verbosity) > 0) {
VG_(message)(Vg_DebugMsg,
@@ -1019,9 +1078,9 @@
VG_(message)(Vg_DebugMsg,
"WARNING: for %s\n", di->fsm.filename);
}
- unmap_image( &iid );
- /* unmap_image zeroes the fields, so the following test makes
- sense. */
+ unmap_image( &dsli );
+ /* unmap_image zeroes out dsli, so it's safe for "fail:" to
+ re-try unmap_image. */
goto fail;
}
}
@@ -1030,65 +1089,43 @@
on to reading stuff out of it. */
read_the_dwarf:
- if (iid.macho_img && iid.macho_img_szB > 0) {
- UChar* debug_info_img = NULL;
- Word debug_info_sz;
- UChar* debug_abbv_img;
- Word debug_abbv_sz;
- UChar* debug_line_img;
- Word debug_line_sz;
- UChar* debug_str_img;
- Word debug_str_sz;
- UChar* debug_ranges_img;
- Word debug_ranges_sz;
- UChar* debug_loc_img;
- Word debug_loc_sz;
- UChar* debug_name_img;
- Word debug_name_sz;
-
- debug_info_img =
- getsectdata(iid.macho_img, iid.macho_img_szB,
- "__DWARF", "__debug_info", &debug_info_sz);
- debug_abbv_img =
- getsectdata(iid.macho_img, iid.macho_img_szB,
- "__DWARF", "__debug_abbrev", &debug_abbv_sz);
- debug_line_img =
- getsectdata(iid.macho_img, iid.macho_img_szB,
- "__DWARF", "__debug_line", &debug_line_sz);
- debug_str_img =
- getsectdata(iid.macho_img, iid.macho_img_szB,
- "__DWARF", "__debug_str", &debug_str_sz);
- debug_ranges_img =
- getsectdata(iid.macho_img, iid.macho_img_szB,
- "__DWARF", "__debug_ranges", &debug_ranges_sz);
- debug_loc_img =
- getsectdata(iid.macho_img, iid.macho_img_szB,
- "__DWARF", "__debug_loc", &debug_loc_sz);
- debug_name_img =
- getsectdata(iid.macho_img, iid.macho_img_szB,
- "__DWARF", "__debug_pubnames", &debug_name_sz);
+ if (ML_(sli_is_valid)(msli) && msli.szB > 0) {
+ // "_mscn" is "mach-o section"
+ DiSlice debug_info_mscn
+ = getsectdata(dsli, "__DWARF", "__debug_info");
+ DiSlice debug_abbv_mscn
+ = getsectdata(dsli, "__DWARF", "__debug_abbrev");
+ DiSlice debug_line_mscn
+ = getsectdata(dsli, "__DWARF", "__debug_line");
+ DiSlice debug_str_mscn
+ = getsectdata(dsli, "__DWARF", "__debug_str");
+ DiSlice debug_ranges_mscn
+ = getsectdata(dsli, "__DWARF", "__debug_ranges");
+ DiSlice debug_loc_mscn
+ = getsectdata(dsli, "__DWARF", "__debug_loc");
- if (debug_info_img) {
+ if (ML_(sli_is_valid)(debug_info_mscn)) {
if (VG_(clo_verbosity) > 1) {
if (0)
VG_(message)(Vg_DebugMsg,
"Reading dwarf3 for %s (%#lx) from %s"
- " (%ld %ld %ld %ld %ld %ld)\n",
+ " (%lld %lld %lld %lld %lld %lld)\n",
di->fsm.filename, di->text_avma, dsymfilename,
- debug_info_sz, debug_abbv_sz, debug_line_sz,
- debug_str_sz, debug_ranges_sz, debug_loc_sz
+ debug_info_mscn.szB, debug_abbv_mscn.szB,
+ debug_line_mscn.szB, debug_str_mscn.szB,
+ debug_ranges_mscn.szB, debug_loc_mscn.szB
);
VG_(message)(Vg_DebugMsg,
" reading dwarf3 from dsyms file\n");
}
/* The old reader: line numbers and unwind info only */
ML_(read_debuginfo_dwarf3) ( di,
- debug_info_img, debug_info_sz,
- NULL, 0,
- debug_abbv_img, debug_abbv_sz,
- debug_line_img, debug_line_sz,
- debug_str_img, debug_str_sz,
- NULL, 0 /* ALT .debug_str */ );
+ debug_info_mscn,
+ DiSlice_INVALID, /* .debug_types */
+ debug_abbv_mscn,
+ debug_line_mscn,
+ debug_str_mscn,
+ DiSlice_INVALID /* ALT .debug_str */ );
/* The new reader: read the DIEs in .debug_info to acquire
information on variable types and locations. But only if
@@ -1097,17 +1134,17 @@
if (VG_(needs).var_info /* the tool requires it */
|| VG_(clo_read_var_info) /* the user asked for it */) {
ML_(new_dwarf3_reader)(
- di, debug_info_img, debug_info_sz,
- NULL, 0,
- debug_abbv_img, debug_abbv_sz,
- debug_line_img, debug_line_sz,
- debug_str_img, debug_str_sz,
- debug_ranges_img, debug_ranges_sz,
- debug_loc_img, debug_loc_sz,
- NULL, 0, /* ALT .debug_info */
- NULL, 0, /* ALT .debug_abbv */
- NULL, 0, /* ALT .debug_line */
- NULL, 0 /* ALT .debug_str */
+ di, debug_info_mscn,
+ DiSlice_INVALID, /* .debug_types */
+ debug_abbv_mscn,
+ debug_line_mscn,
+ debug_str_mscn,
+ debug_ranges_mscn,
+ debug_loc_mscn,
+ DiSlice_INVALID, /* ALT .debug_info */
+ DiSlice_INVALID, /* ALT .debug_abbv */
+ DiSlice_INVALID, /* ALT .debug_line */
+ DiSlice_INVALID /* ALT .debug_str */
);
}
}
@@ -1116,20 +1153,16 @@
if (dsymfilename) ML_(dinfo_free)(dsymfilename);
success:
- if (ii.img)
- unmap_image(&ii);
- if (iid.img)
- unmap_image(&iid);
+ unmap_image(&msli);
+ unmap_image(&dsli);
return True;
/* NOTREACHED */
fail:
ML_(symerr)(di, True, "Error reading Mach-O object.");
- if (ii.img)
- unmap_image(&ii);
- if (iid.img)
- unmap_image(&iid);
+ unmap_image(&msli);
+ unmap_image(&dsli);
return False;
}
Modified: branches/DISRV/include/vki/vki-darwin.h (+10 -0)
===================================================================
--- branches/DISRV/include/vki/vki-darwin.h 2013-06-17 22:04:25 +01:00 (rev 13429)
+++ branches/DISRV/include/vki/vki-darwin.h 2013-06-25 13:42:52 +01:00 (rev 13430)
@@ -1041,6 +1041,16 @@
#define vki_aiocb aiocb
+#include <netinet/tcp.h>
+
+#define VKI_TCP_NODELAY TCP_NODELAY
+
+
+#include <netinet/in.h>
+
+#define VKI_IPPROTO_TCP IPPROTO_TCP
+
+
// XXX: for some reason when I #include <sys/kernel_types.h> I get a syntax
// error. Hmm. So just define things ourselves.
//#include <sys/kernel_types.h>
Modified: branches/DISRV/coregrind/m_debuginfo/priv_image.h (+16 -0)
===================================================================
--- branches/DISRV/coregrind/m_debuginfo/priv_image.h 2013-06-17 22:04:25 +01:00 (rev 13429)
+++ branches/DISRV/coregrind/m_debuginfo/priv_image.h 2013-06-25 13:42:52 +01:00 (rev 13430)
@@ -184,7 +184,16 @@
}
}
+/* Create a slice which exactly covers the given image. */
+static inline DiSlice ML_(sli_from_img)( DiImage* img ) {
+ if (img) {
+ return mk_DiSlice(img, 0, ML_(img_size)(img));
+ } else {
+ return DiSlice_INVALID;
+ }
+}
+
/*------------------------------------------------------------*/
/*--- Functions that operate on DiCursors ---*/
/*------------------------------------------------------------*/
@@ -253,6 +262,13 @@
ML_(img_get)(dst, c.img, c.ioff, size);
}
+// Fetch an arbitrary number of bytes from the cursor, and advance it.
+static inline void ML_(cur_step_get) ( /*OUT*/void* dst,
+ DiCursor* c, SizeT size) {
+ ML_(img_get)(dst, c->img, c->ioff, size);
+ c->ioff += size;
+}
+
// memdup from the given cursor. Caller must ML_(dinfo_free) the
// resulting block.
static inline UChar* ML_(cur_read_memdup)( DiCursor c, SizeT size,
|
|
From: Stephen M. <sm...@al...> - 2013-06-24 17:47:00
|
>>>>> "SP" == securitypotato <sec...@gm...> writes:
SP> Hi !
SP> Is anyone know what is the meaning of x86_calculate_condition
SP> expression
In x86 hardware, every time an (e.g.) "add" instruction occurs, the
processor computes flags that tell whether the result was zero,
whether it was negative, whether it overflowed, and a few
others. Sometimes these flags are later used in a conditional jump
like "jne", though most of the time most of the flags are just
ignored. In hardware this a cheap capability to provide because the
flag computations can happen in parallel. But in software simulation
if you did a straightforward translation that recomputed all the flags
after every instruction, it would be expensive.
Instead, Valgrind uses a lazy translation of the EFLAGS side effects
of x86 instructions (and similar condition-code flags on other
architectures). When an add instruction happens, Valgrind's
translation doesn't compute the flags, it just stores enough
information (basically the identity of the operation and its operands)
so that it can recompute the flag value if it later turns out to be
needed. An academic reference for this idea is section 6.3 of the tech
report on Shade:
@techreport{CK:93,
author={Robert F. Cmelik and David Keppel},
title={Shade: A Fast Instruction-Set Simulator for Execution
Profiling},
number={SMLI 93-12, UWCSE 93-06-06},
year={1993}
}
http://www.cs.washington.edu/research/compiler/papers.d/shade.html
There's also a brief mention in section 3.7 of the PLDI 2007 Valgrind
paper.
In Valgrind's translation, x86g_calculate_condition is the clean
helper routine that does the computation of a flag-based condition
value for an x86 guest. A typical call will look like:
x86g_calculate_condition(0x4:I32,GET:I32(32),GET:I32(36)
GET:I32(40),GET:I32(44))
The exact encoding of the arguments is explained in a long comment
that starts "%EFLAGS thunk descriptors" in VEX/priv/guest_x86_defs.h.
At the hardware level, there are two steps: the operation sets some of
the six flags in EFLAGS, and then later the branch condition is
computed as some combination of those. But x86g_calculate_condition
does both steps in one helper. The first argument is the kind of
condition to compute; in this example 4 means X86CondZ, for instance
from a jz (jump if zero) instruction. The four remaining arguments are
the saved information about the flag-setting operation, stored in the
guest state as CC_OP, CC_DEP1, CC_DEP2, and CC_NDEP.
Hope this helps,
-- Stephen
|
|
From: securitypotato <sec...@gm...> - 2013-06-23 07:09:27
|
Hi ! Is anyone know what is the meaning of x86_calculate_condition expression |
|
From: Maran P. <ma...@li...> - 2013-06-21 10:13:20
|
On 06/20/2013 07:09 PM, Julian Seward wrote: > >> And doing a rollback + failure path >> is slower than doing the failure path from the beginning. So (1) may >> not be a bad option at all. > OK, worth a try. At least it gives us an ultra-simple baseline > implementation. I expect to have a Haswell box to try with, soon. > > That's Intel-specific, though. The question of whether we can fit > Power/s390 into the same framework is also important. > With s390, there are 2 modes of transaction execution. 1) Non-constrained transaction 2) Constrained transaction Constrained-transaction as stated in PoP is "a constrained transaction will eventually complete, thus an abort-handler routine is not required." (Refer to: Principles of operations: "Constrained Transaction", pg. no: 5-105) So, a failure (fallback) path need not be present for all the transactions. So, on encountering a transaction, directly jumping to fallback path may not be a viable option atleast with constrained transactions. As far as I know, constrained transaction seem to be specific to s390. (These seem to be no equivalent for this type of transaction in ppc). Even with non-constrained transaction, the s390 architecture does not enforce an abort handler to be specified for a transaction. Also, it is possible to specify a set of (general) registers to be restored to the original value on a transaction abort whereas the remaining registers will retain the value updated in the transaction. And this kind of partial register set restoration seems to be specific to s390. Similary, it is possible to do a non-transactional store within a transaction - that is, the store operation designated as non-transactional store will be retained on a transaction abort while all the other data stores within a transaction are discarded. This feature also seems to be specific to s390. --Maran |
|
From: Niall D. <ndo...@bl...> - 2013-06-20 18:22:00
|
> https://groups.google.com/a/isocpp.org/d/msg/tm/zfRyY_XfxSU/47esUzUcHX > > 0J > > > > In short, I think you should simulate TM directly as effectively a > > "super longjmp" which preserves memory as well as registers. > > I skimmed the (very long) thread but am none the wiser. Can you summarise > what actions the simulator should take in response to XBEGIN and XEND ? 1. All writes by valgrind on behalf of a program being executed need a new trans_ctx pointer. 2. xbegin starts a new memory transaction context such that subsequent writes occur in that context instead. Other threads can't see anything accumulated there. 3. xend commits that context's changes as visible to all other threads and throws away the context. 4. Any thread reading or writing any cache line straddling a memory transaction context causes that context to abort next timeslice. Any syscall or context switch also aborts. The API I have in that thread is a very reasonable starting prototype for an internal API implementing the above. Quite separately, one might wish to use Transactional GCC to implement TM in valgrind's implementation right now. Niall --- Opinions expressed here are my own and do not necessarily represent those of BlackBerry Inc. |
|
From: Eliot M. <mo...@cs...> - 2013-06-20 16:52:44
|
On 6/20/2013 12:19 PM, John Reiser wrote: > On 06/20/2013 08:59 AM, Julian Seward wrote: >> On 06/20/2013 05:33 PM, John Reiser wrote: > The lock might guarantee that P(failure) < (1.0 - delta) for non-infinitesimal > delta > 0. For instance, the lock might guarantee no [other] memory accesses > to the relevant memory region, no context switching, no other XBEGIN (in the > strongest case: no other process, and no other thread), etc. Thus progress > will occur unless VG forces perpetual failure. Furthermore, I know that at least some people at IBM are very interested in an HTM definition that *guarantees* that certain transactions will succeed in the absence of conflicting accesses. The existing IBM spec may even make such a guarantee. As one of the originators of TM ( :-) ), my personal opinion is that it would be interesting to simulate TM in Valgrind, which basically means to build a software TM facility. When run on a platform that supports HTM, one could take a Hybrid TM approach, where some transactions may succeed directly in the target hardware while others will proceed in software (e.g., if the hardware version fails enough times or the transaction is too complex for the hardware). In terms of interaction with tools, one can try weaving in the tool rewrites directly -- which may tend to make transactions bigger, and thus more likely to fail in the underlying hardware. To get the proper semantics, we may need an STM emulation of logical success of the hardware transaction (as opposed to throwing the original code down its failure path). *Perhaps* we can "buffer" the actions of the original transaction, and if it commits, do the work that a tool wants to do. This may be too complex, but it's a thought. It has the virtue of not doing tool work on the actions of failing transactions -- actions that logically disappear anyway. ... Which suggests that we need additional clarity as to what should happen w.r.t. tool actions for a failing transaction. If you run it as a hardware txn and it *fails*, then the tool actions disappear -- which might, or might not, be what you want. Regards -- Eliot Moss |
|
From: Carl E. L. <ce...@li...> - 2013-06-20 16:20:17
|
On Thu, 2013-06-20 at 11:27 +0200, Julian Seward wrote: > Transactional memory support in hardware is about to hit mainstream > cpus, with the arrival of Intel's Haswell family. It also exists or > is about to exist (I don't know which) in the s390 and POWER architectures. > > So we need to have a Plan for dealing with it. I looked at the Intel > (Haswell) instructions a bit, but don't know about the s390 or POWER > ones. The IBM ISA 2.07 published May 10th at https://www.power.org contains the documentation on the IBM TM instructions. The TM instructions in the IBM ISA 2.07 are described in book 2, chapter 5. There are about 15 TM instructions. I have not studied them in any detail as of yet. > > IIRC, the Intel scheme requires two instructions: > > XBEGIN fail-addr > XEND > > XBEGIN starts a transaction and registers fail-addr as the fallback > address. If the transaction fails for whatever reason (there are many > reasons why it might fail) then the processor rolls back register/memory > state to how it was at the XBEGIN, and executes code at fail-addr > instead. > > XEND finishes the transaction. > > Transactions can be nested. > > We can't hope to emulate the conflict checking done by the real CPU > in any sane (performance or complexity) way. So I see two remaining > options: > > (1) translate "XBEGIN fail-addr" as "goto fail-addr"; that is: push > simulated execution directly onto the failure path. This is simple > but will have poor performance, if (as is likely) the failure path > uses normal locking and is not tuned for speed. > > (2) translate "XBEGIN fail-addr" by handing it through to the real CPU, > in the same kind of way we handle CPUID, RDTSC, etc. Of course we will > have to put our own failure-handler address so we don't lose control > of execution if the transaction is aborted, but that's not difficult. > > --- > > (1) is simple but likely to work. (2) is probably preferable but I don't > know if there will be hidden problems in it. > > This also assumes that the s390 and POWER instructions can be mapped to > this same structure: TRANSACTION-START(fail-addr) and TRANSACTION-END. > That's probably the first thing that we should investigate. > > J > |
|
From: John R. <jr...@bi...> - 2013-06-20 16:18:37
|
On 06/20/2013 08:59 AM, Julian Seward wrote: > On 06/20/2013 05:33 PM, John Reiser wrote: >>> (1) translate "XBEGIN fail-addr" as "goto fail-addr"; that is: push >>> simulated execution directly onto the failure path. This is simple >>> but will have poor performance, if (as is likely) the failure path >>> uses normal locking and is not tuned for speed. >> >> That strategy might induce a deadlock, infinite loop, or application failure >> in some cases. For example, one fallback strategy for the application when >> the transaction fails is: grab a larger lock (more powerful) which >> logically guarantees that the transaction will succeed, then re-run >> the transaction while holding that lock. > > Are you sure about that? The transaction might fail for entirely arbitrary > reasons, such as resource exhaustion (for conflict tracking) in the hardware > or due to a context switch whilst inside the transaction, so the fallback > path must always be usable. Hence not providing a usable fallback path is > a straight-out application bug. The lock might guarantee that P(failure) < (1.0 - delta) for non-infinitesimal delta > 0. For instance, the lock might guarantee no [other] memory accesses to the relevant memory region, no context switching, no other XBEGIN (in the strongest case: no other process, and no other thread), etc. Thus progress will occur unless VG forces perpetual failure. -- |
|
From: Julian S. <js...@ac...> - 2013-06-20 16:04:12
|
On 06/20/2013 04:53 PM, Niall Douglas wrote: > https://groups.google.com/a/isocpp.org/d/msg/tm/zfRyY_XfxSU/47esUzUcHX0J > > In short, I think you should simulate TM directly as effectively a "super > longjmp" which preserves memory as well as registers. I skimmed the (very long) thread but am none the wiser. Can you summarise what actions the simulator should take in response to XBEGIN and XEND ? J |