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
|
2
|
3
(1) |
4
(1) |
5
|
6
(1) |
7
|
|
8
|
9
(1) |
10
(4) |
11
(3) |
12
(6) |
13
(13) |
14
(1) |
|
15
(1) |
16
(3) |
17
|
18
(1) |
19
(3) |
20
(7) |
21
(5) |
|
22
|
23
(1) |
24
|
25
(3) |
26
|
27
(3) |
28
|
|
29
(1) |
30
(1) |
31
(5) |
|
|
|
|
|
From: Philippe W. <phi...@sk...> - 2017-01-12 19:36:18
|
On Thu, 2017-01-12 at 13:37 +0100, Roland Mainz wrote: > On Thu, Jan 12, 2017 at 1:31 PM, Petar Jovanovic <mip...@gm...> wrote: > > On Wed, Jan 4, 2017 at 3:21 PM, Philippe Waroquiers > > <phi...@sk...> wrote: > >> No sign of any tilegx user or developer activity since something like > >> one year. > >> No reply received for question in > >> https://sourceforge.net/p/valgrind/mailman/message/35566192/ > >> > >> Is there any tilegx user or developer still active ? > >> Should we consider this platform as dead ? > >> > > I have exchanged a few emails with Tilera/Mellanox compiler enigneers, > > and they say they cannot take care of TileGx port in Valgrind for the > > time being. > > Is there any emulator or other way we can use to test changes ? I > don't like seeing such a port just disappear... Well, if there is no known users, and no (original) developer doing maintenance and no reply from (original) developers to simple questions and no access to a system to test/compile and no nightly build and no tests in SVN and no emulator then IMO, this platform is a candidate to remove. as just keeping this compiling forever for no reason will at the end cost more than just removing it. I will at least put this question as one of the things to discuss in FOSDEM 2017 Valgrind BoF. Also, IMO, for the future, we also have to put some mandatory requirements before accepting new platforms such as e.g. provide an access to a development system, at least for some time ensure a minimum of effort for maintenance/questions, provide tests, ... Philippe |
|
From: <sv...@va...> - 2017-01-12 14:38:05
|
Author: sewardj
Date: Thu Jan 12 14:37:58 2017
New Revision: 3291
Log:
Implement VRINT{A,N,P,M}.F64 d_d, VRINT{A,N,P,M}.F32 s_s.
Modified:
trunk/priv/guest_arm_toIR.c
trunk/priv/host_arm_defs.c
trunk/priv/host_arm_defs.h
trunk/priv/host_arm_isel.c
Modified: trunk/priv/guest_arm_toIR.c
==============================================================================
--- trunk/priv/guest_arm_toIR.c (original)
+++ trunk/priv/guest_arm_toIR.c Thu Jan 12 14:37:58 2017
@@ -13510,6 +13510,59 @@
}
/* fall through */
+ /* -------- VRINT{A,N,P,M}.F64 d_d, VRINT{A,N,P,M}.F32 s_s -------- */
+ /* 31 22 21 17 15 11 8 7 5 4 3
+ T1/A1: 111111101 D 1110 rm Vd 101 1 01 M 0 Vm VRINT{A,N,P,M}.F64 Dd, Dm
+ T1/A1: 111111101 D 1110 rm Vd 101 0 01 M 0 Vm VRINT{A,N,P,M}.F32 Sd, Sm
+
+ ARM encoding is in NV space.
+ In Thumb mode, we must not be in an IT block.
+ */
+ if (INSN(31,23) == BITS9(1,1,1,1,1,1,1,0,1)
+ && INSN(21,18) == BITS4(1,1,1,0) && INSN(11,9) == BITS3(1,0,1)
+ && INSN(7,6) == BITS2(0,1) && INSN(4,4) == 0) {
+ UInt bit_D = INSN(22,22);
+ UInt fld_rm = INSN(17,16);
+ UInt fld_d = INSN(15,12);
+ Bool isF64 = INSN(8,8) == 1;
+ UInt bit_M = INSN(5,5);
+ UInt fld_m = INSN(3,0);
+
+ UInt dd = isF64 ? ((bit_D << 4) | fld_d) : ((fld_d << 1) | bit_D);
+ UInt mm = isF64 ? ((bit_M << 4) | fld_m) : ((fld_m << 1) | bit_M);
+
+ if (isT) {
+ gen_SIGILL_T_if_in_ITBlock(old_itstate, new_itstate);
+ }
+ /* In ARM mode, this is statically unconditional. In Thumb mode,
+ this must be dynamically unconditional, and we've SIGILLd if not.
+ In either case we can create unconditional IR. */
+
+ UChar c = '?';
+ IRRoundingMode rm = Irrm_NEAREST;
+ switch (fld_rm) {
+ /* The use of NEAREST for both the 'a' and 'n' cases is a bit of a
+ kludge since it doesn't take into account the nearest-even vs
+ nearest-away semantics. */
+ case BITS2(0,0): c = 'a'; rm = Irrm_NEAREST; break;
+ case BITS2(0,1): c = 'n'; rm = Irrm_NEAREST; break;
+ case BITS2(1,0): c = 'p'; rm = Irrm_PosINF; break;
+ case BITS2(1,1): c = 'm'; rm = Irrm_NegINF; break;
+ default: vassert(0);
+ }
+
+ IRExpr* srcM = (isF64 ? llGetDReg : llGetFReg)(mm);
+ IRExpr* res = binop(isF64 ? Iop_RoundF64toInt : Iop_RoundF32toInt,
+ mkU32((UInt)rm), srcM);
+ (isF64 ? llPutDReg : llPutFReg)(dd, res);
+
+ UChar rch = isF64 ? 'd' : 'f';
+ DIP("vrint%c.%s %c%u, %c%u\n",
+ c, isF64 ? "f64" : "f32", rch, dd, rch, mm);
+ return True;
+ }
+ /* fall through */
+
/* ---------- Doesn't match anything. ---------- */
return False;
Modified: trunk/priv/host_arm_defs.c
==============================================================================
--- trunk/priv/host_arm_defs.c (original)
+++ trunk/priv/host_arm_defs.c Thu Jan 12 14:37:58 2017
@@ -1365,6 +1365,15 @@
i->ARMin.VCvtID.src = src;
return i;
}
+ARMInstr* ARMInstr_VRIntR ( Bool isF64, HReg dst, HReg src )
+{
+ ARMInstr* i = LibVEX_Alloc_inline(sizeof(ARMInstr));
+ i->tag = ARMin_VRIntR;
+ i->ARMin.VRIntR.isF64 = isF64;
+ i->ARMin.VRIntR.dst = dst ;
+ i->ARMin.VRIntR.src = src;
+ return i;
+}
ARMInstr* ARMInstr_FPSCR ( Bool toFPSCR, HReg iReg ) {
ARMInstr* i = LibVEX_Alloc_inline(sizeof(ARMInstr));
i->tag = ARMin_FPSCR;
@@ -1873,6 +1882,14 @@
ppHRegARM(i->ARMin.VCvtID.src);
return;
}
+ case ARMin_VRIntR: {
+ const HChar* sz = i->ARMin.VRIntR.isF64 ? "f64" : "f32";
+ vex_printf("vrintr.%s.%s ", sz, sz);
+ ppHRegARM(i->ARMin.VRIntR.dst);
+ vex_printf(", ");
+ ppHRegARM(i->ARMin.VRIntR.src);
+ return;
+ }
case ARMin_FPSCR:
if (i->ARMin.FPSCR.toFPSCR) {
vex_printf("fmxr fpscr, ");
@@ -2268,6 +2285,10 @@
addHRegUse(u, HRmWrite, i->ARMin.VCvtID.dst);
addHRegUse(u, HRmRead, i->ARMin.VCvtID.src);
return;
+ case ARMin_VRIntR:
+ addHRegUse(u, HRmWrite, i->ARMin.VRIntR.dst);
+ addHRegUse(u, HRmRead, i->ARMin.VRIntR.src);
+ return;
case ARMin_FPSCR:
if (i->ARMin.FPSCR.toFPSCR)
addHRegUse(u, HRmRead, i->ARMin.FPSCR.iReg);
@@ -2483,6 +2504,10 @@
i->ARMin.VCvtID.dst = lookupHRegRemap(m, i->ARMin.VCvtID.dst);
i->ARMin.VCvtID.src = lookupHRegRemap(m, i->ARMin.VCvtID.src);
return;
+ case ARMin_VRIntR:
+ i->ARMin.VRIntR.dst = lookupHRegRemap(m, i->ARMin.VRIntR.dst);
+ i->ARMin.VRIntR.src = lookupHRegRemap(m, i->ARMin.VRIntR.src);
+ return;
case ARMin_FPSCR:
i->ARMin.FPSCR.iReg = lookupHRegRemap(m, i->ARMin.FPSCR.iReg);
return;
@@ -3852,6 +3877,29 @@
/*UNREACHED*/
vassert(0);
}
+ case ARMin_VRIntR: { /* NB: ARM v8 and above only */
+ Bool isF64 = i->ARMin.VRIntR.isF64;
+ UInt rDst = (isF64 ? dregEnc : fregEnc)(i->ARMin.VRIntR.dst);
+ UInt rSrc = (isF64 ? dregEnc : fregEnc)(i->ARMin.VRIntR.src);
+ /* The encoding of registers here differs strangely for the
+ F32 and F64 cases. */
+ UInt D, Vd, M, Vm;
+ if (isF64) {
+ D = (rDst >> 4) & 1;
+ Vd = rDst & 0xF;
+ M = (rSrc >> 4) & 1;
+ Vm = rSrc & 0xF;
+ } else {
+ Vd = (rDst >> 1) & 0xF;
+ D = rDst & 1;
+ Vm = (rSrc >> 1) & 0xF;
+ M = rSrc & 1;
+ }
+ vassert(D <= 1 && Vd <= 15 && M <= 1 && Vm <= 15);
+ *p++ = XXXXXXXX(0xE, X1110, X1011 | (D << 2), X0110, Vd,
+ isF64 ? X1011 : X1010, X0100 | (M << 1), Vm);
+ goto done;
+ }
case ARMin_FPSCR: {
Bool toFPSCR = i->ARMin.FPSCR.toFPSCR;
UInt iReg = iregEnc(i->ARMin.FPSCR.iReg);
Modified: trunk/priv/host_arm_defs.h
==============================================================================
--- trunk/priv/host_arm_defs.h (original)
+++ trunk/priv/host_arm_defs.h Thu Jan 12 14:37:58 2017
@@ -595,6 +595,7 @@
ARMin_VXferD,
ARMin_VXferS,
ARMin_VCvtID,
+ ARMin_VRIntR,
ARMin_FPSCR,
ARMin_MFence,
ARMin_CLREX,
@@ -853,6 +854,13 @@
HReg dst;
HReg src;
} VCvtID;
+ /* Round a F32 or F64 value to the nearest integral value,
+ according to the FPSCR.RM. For ARM >= V8 hosts only. */
+ struct {
+ Bool isF64;
+ HReg dst;
+ HReg src;
+ } VRIntR;
/* Move a 32-bit value to/from the FPSCR (FMXR, FMRX) */
struct {
Bool toFPSCR;
@@ -1007,6 +1015,7 @@
extern ARMInstr* ARMInstr_VXferS ( Bool toS, HReg fD, HReg rLo );
extern ARMInstr* ARMInstr_VCvtID ( Bool iToD, Bool syned,
HReg dst, HReg src );
+extern ARMInstr* ARMInstr_VRIntR ( Bool isF64, HReg dst, HReg src );
extern ARMInstr* ARMInstr_FPSCR ( Bool toFPSCR, HReg iReg );
extern ARMInstr* ARMInstr_MFence ( void );
extern ARMInstr* ARMInstr_CLREX ( void );
Modified: trunk/priv/host_arm_isel.c
==============================================================================
--- trunk/priv/host_arm_isel.c (original)
+++ trunk/priv/host_arm_isel.c Thu Jan 12 14:37:58 2017
@@ -5603,6 +5603,21 @@
addInstr(env, ARMInstr_VUnaryD(ARMvfpu_SQRT, dst, src));
return dst;
}
+ case Iop_RoundF64toInt: {
+ /* We can only generate this on a >= V8 capable target. But
+ that's OK since we should only be asked to generate for V8
+ capable guests, and we assume here that host == guest. */
+ if (VEX_ARM_ARCHLEVEL(env->hwcaps) >= 8) {
+ HReg src = iselDblExpr(env, e->Iex.Binop.arg2);
+ HReg dst = newVRegD(env);
+ set_VFP_rounding_mode(env, e->Iex.Binop.arg1);
+ addInstr(env, ARMInstr_VRIntR(True/*isF64*/, dst, src));
+ set_VFP_rounding_default(env);
+ return dst;
+ }
+ /* not a V8 target, so we can't select insns for this. */
+ break;
+ }
default:
break;
}
@@ -5745,6 +5760,21 @@
set_VFP_rounding_default(env);
return valS;
}
+ case Iop_RoundF32toInt: {
+ /* We can only generate this on a >= V8 capable target. But
+ that's OK since we should only be asked to generate for V8
+ capable guests, and we assume here that host == guest. */
+ if (VEX_ARM_ARCHLEVEL(env->hwcaps) >= 8) {
+ HReg src = iselFltExpr(env, e->Iex.Binop.arg2);
+ HReg dst = newVRegF(env);
+ set_VFP_rounding_mode(env, e->Iex.Binop.arg1);
+ addInstr(env, ARMInstr_VRIntR(False/*!isF64*/, dst, src));
+ set_VFP_rounding_default(env);
+ return dst;
+ }
+ /* not a V8 target, so we can't select insns for this. */
+ break;
+ }
default:
break;
}
|
|
From: Roland M. <rol...@nr...> - 2017-01-12 12:37:11
|
On Thu, Jan 12, 2017 at 1:31 PM, Petar Jovanovic <mip...@gm...> wrote: > On Wed, Jan 4, 2017 at 3:21 PM, Philippe Waroquiers > <phi...@sk...> wrote: >> No sign of any tilegx user or developer activity since something like >> one year. >> No reply received for question in >> https://sourceforge.net/p/valgrind/mailman/message/35566192/ >> >> Is there any tilegx user or developer still active ? >> Should we consider this platform as dead ? >> > I have exchanged a few emails with Tilera/Mellanox compiler enigneers, > and they say they cannot take care of TileGx port in Valgrind for the > time being. Is there any emulator or other way we can use to test changes ? I don't like seeing such a port just disappear... ---- Bye, Roland -- __ . . __ (o.\ \/ /.o) rol...@nr... \__\/\/__/ MPEG specialist, C&&JAVA&&Sun&&Unix programmer /O /==\ O\ TEL +49 641 3992797 (;O/ \/ \O;) |
|
From: Petar J. <mip...@gm...> - 2017-01-12 12:32:04
|
On Wed, Jan 4, 2017 at 3:21 PM, Philippe Waroquiers <phi...@sk...> wrote: > No sign of any tilegx user or developer activity since something like > one year. > No reply received for question in > https://sourceforge.net/p/valgrind/mailman/message/35566192/ > > Is there any tilegx user or developer still active ? > Should we consider this platform as dead ? > I have exchanged a few emails with Tilera/Mellanox compiler enigneers, and they say they cannot take care of TileGx port in Valgrind for the time being. Petar |
|
From: <sv...@va...> - 2017-01-12 11:28:30
|
Author: iraisr
Date: Thu Jan 12 11:28:20 2017
New Revision: 16200
Log:
Fix a bug when --log-file output isn't split when a program forks.
Patch loosely based on idea by Timur Iskhodzhanov <tim...@go...>.
Fixes BZ#162848
Modified:
trunk/NEWS
trunk/coregrind/m_coredump/coredump-elf.c
trunk/coregrind/m_coredump/coredump-solaris.c
trunk/coregrind/m_libcprint.c
trunk/coregrind/m_main.c
trunk/coregrind/m_options.c
trunk/coregrind/m_syswrap/syswrap-generic.c
trunk/coregrind/m_syswrap/syswrap-linux.c
trunk/coregrind/m_syswrap/syswrap-solaris.c
trunk/coregrind/pub_core_libcprint.h
trunk/coregrind/pub_core_options.h
Modified: trunk/NEWS
==============================================================================
--- trunk/NEWS (original)
+++ trunk/NEWS Thu Jan 12 11:28:20 2017
@@ -81,6 +81,7 @@
https://bugs.kde.org/show_bug.cgi?id=XXXXXX
where XXXXXX is the bug number as listed below.
+162848 --log-file output isn't split when a program forks
342040 Valgrind mishandles clone with CLONE_VFORK | CLONE_VM that clones
to a different stack.
348616 Wine/valgrind: noted but unhandled ioctl 0x5390 [..] (DVD_READ_STRUCT)
Modified: trunk/coregrind/m_coredump/coredump-elf.c
==============================================================================
--- trunk/coregrind/m_coredump/coredump-elf.c (original)
+++ trunk/coregrind/m_coredump/coredump-elf.c Thu Jan 12 11:28:20 2017
@@ -597,10 +597,10 @@
Addr *seg_starts;
Int n_seg_starts;
- if (VG_(clo_log_fname_expanded) != NULL) {
+ if (VG_(clo_log_fname_unexpanded) != NULL) {
coreext = ".core";
basename = VG_(expand_file_name)("--log-file",
- VG_(clo_log_fname_expanded));
+ VG_(clo_log_fname_unexpanded));
}
vg_assert(coreext);
Modified: trunk/coregrind/m_coredump/coredump-solaris.c
==============================================================================
--- trunk/coregrind/m_coredump/coredump-solaris.c (original)
+++ trunk/coregrind/m_coredump/coredump-solaris.c Thu Jan 12 11:28:20 2017
@@ -866,10 +866,10 @@
const HChar *coreext = "";
Int core_fd;
- if (VG_(clo_log_fname_expanded) != NULL) {
+ if (VG_(clo_log_fname_unexpanded) != NULL) {
coreext = ".core";
basename = VG_(expand_file_name)("--log-file",
- VG_(clo_log_fname_expanded));
+ VG_(clo_log_fname_unexpanded));
}
vg_assert(coreext != NULL);
Modified: trunk/coregrind/m_libcprint.c
==============================================================================
--- trunk/coregrind/m_libcprint.c (original)
+++ trunk/coregrind/m_libcprint.c Thu Jan 12 11:28:20 2017
@@ -31,6 +31,7 @@
#include "pub_core_basics.h"
#include "pub_core_vki.h"
+#include "pub_core_vkiscnums.h"
#include "pub_core_debuglog.h"
#include "pub_core_gdbserver.h" // VG_(gdb_printf)
#include "pub_core_libcbase.h"
@@ -39,9 +40,275 @@
#include "pub_core_libcprint.h"
#include "pub_core_libcproc.h" // VG_(getpid)(), VG_(read_millisecond_timer()
#include "pub_core_mallocfree.h" // VG_(malloc)
+#include "pub_core_machine.h" // VG_(machine_get_VexArchInfo)
#include "pub_core_options.h"
#include "pub_core_clreq.h" // For RUNNING_ON_VALGRIND
+#include "pub_core_clientstate.h"
+#include "pub_core_syscall.h" // VG_(strerror)
+#include "pub_core_tooliface.h" // VG_(details)
+
+
+/*====================================================================*/
+/*=== Printing the preamble ===*/
+/*====================================================================*/
+
+// Print the argument, escaping any chars that require it.
+static void umsg_arg(const HChar *arg)
+{
+ SizeT len = VG_(strlen)(arg);
+ const HChar *special = " \\<>";
+ for (UInt i = 0; i < len; i++) {
+ if (VG_(strchr)(special, arg[i])) {
+ VG_(umsg)("\\"); // escape with a backslash if necessary
+ }
+ VG_(umsg)("%c", arg[i]);
+ }
+}
+// Send output to the XML-stream and escape any XML meta-characters.
+static void xml_arg(const HChar *arg)
+{
+ VG_(printf_xml)("%pS", arg);
+}
+
+// Write the name and value of log file qualifiers to the xml file.
+// We can safely assume here that the format string is well-formed.
+// It has been checked earlier in VG_(expand_file_name) when processing
+// command line options.
+static void print_file_vars(const HChar *format)
+{
+ UInt i = 0;
+
+ while (format[i]) {
+ if (format[i] == '%') {
+ // We saw a '%'. What's next...
+ i++;
+ if ('q' == format[i]) {
+ i++;
+ if ('{' == format[i]) {
+ // Get the env var name, print its contents.
+ UInt begin_qualname = ++i;
+ while (True) {
+ if ('}' == format[i]) {
+ UInt qualname_len = i - begin_qualname;
+ HChar qualname[qualname_len + 1];
+ VG_(strncpy)(qualname, format + begin_qualname,
+ qualname_len);
+ qualname[qualname_len] = '\0';
+ HChar *qual = VG_(getenv)(qualname);
+ i++;
+ VG_(printf_xml)("<logfilequalifier> <var>%pS</var> "
+ "<value>%pS</value> </logfilequalifier>\n",
+ qualname, qual);
+ break;
+ }
+ i++;
+ }
+ }
+ }
+ } else {
+ i++;
+ }
+ }
+}
+
+/* Ok, the logging sink is running now. Print a suitable preamble.
+ If logging to file or a socket, write details of parent PID and
+ command line args, to help people trying to interpret the
+ results of a run which encompasses multiple processes. */
+void VG_(print_preamble)(Bool logging_to_fd)
+{
+ const HChar *xpre = VG_(clo_xml) ? " <line>" : "";
+ const HChar *xpost = VG_(clo_xml) ? "</line>" : "";
+ UInt (*umsg_or_xml)( const HChar *, ... )
+ = VG_(clo_xml) ? VG_(printf_xml) : VG_(umsg);
+ void (*umsg_or_xml_arg)( const HChar *) = VG_(clo_xml) ? xml_arg : umsg_arg;
+
+ vg_assert( VG_(args_for_client) );
+ vg_assert( VG_(args_for_valgrind) );
+ vg_assert( VG_(clo_toolname) );
+
+ if (VG_(clo_xml)) {
+ VG_(printf_xml)("<?xml version=\"1.0\"?>\n");
+ VG_(printf_xml)("\n");
+ VG_(printf_xml)("<valgrindoutput>\n");
+ VG_(printf_xml)("\n");
+ VG_(printf_xml)("<protocolversion>4</protocolversion>\n");
+ VG_(printf_xml)("<protocoltool>%s</protocoltool>\n", VG_(clo_toolname));
+ VG_(printf_xml)("\n");
+ }
+
+ if (VG_(clo_xml) || VG_(clo_verbosity) > 0) {
+
+ if (VG_(clo_xml))
+ VG_(printf_xml)("<preamble>\n");
+
+ /* Tool details */
+ umsg_or_xml(VG_(clo_xml) ? "%s%pS%pS%pS, %pS%s\n" : "%s%s%s%s, %s%s\n",
+ xpre,
+ VG_(details).name,
+ NULL == VG_(details).version ? "" : "-",
+ NULL == VG_(details).version ? "" : VG_(details).version,
+ VG_(details).description,
+ xpost);
+
+ if (VG_(strlen)(VG_(clo_toolname)) >= 4 &&
+ VG_STREQN(4, VG_(clo_toolname), "exp-")) {
+ umsg_or_xml("%sNOTE: This is an Experimental-Class Valgrind Tool%s\n",
+ xpre, xpost);
+ }
+
+ umsg_or_xml(VG_(clo_xml) ? "%s%pS%s\n" : "%s%s%s\n",
+ xpre, VG_(details).copyright_author, xpost);
+
+ /* Core details */
+ umsg_or_xml(
+ "%sUsing Valgrind-%s and LibVEX; rerun with -h for copyright info%s\n",
+ xpre, VERSION, xpost);
+
+ // Print the command line. At one point we wrapped at 80 chars and
+ // printed a '\' as a line joiner, but that makes it hard to cut and
+ // paste the command line (because of the "==pid==" prefixes), so we now
+ // favour utility and simplicity over aesthetics.
+ umsg_or_xml("%sCommand: ", xpre);
+ umsg_or_xml_arg(VG_(args_the_exename));
+
+ for (UInt i = 0; i < VG_(sizeXA)( VG_(args_for_client)); i++) {
+ HChar *s = *(HChar **)VG_(indexXA)( VG_(args_for_client), i);
+ umsg_or_xml(" ");
+ umsg_or_xml_arg(s);
+ }
+ umsg_or_xml("%s\n", xpost);
+
+ if (VG_(clo_xml))
+ VG_(printf_xml)("</preamble>\n");
+ }
+
+ // Print the parent PID, and other stuff, if necessary.
+ if (!VG_(clo_xml) && VG_(clo_verbosity) > 0 && !logging_to_fd) {
+ VG_(umsg)("Parent PID: %d\n", VG_(getppid)());
+ } else if (VG_(clo_xml)) {
+ VG_(printf_xml)("\n");
+ VG_(printf_xml)("<pid>%d</pid>\n", VG_(getpid)());
+ VG_(printf_xml)("<ppid>%d</ppid>\n", VG_(getppid)());
+ VG_(printf_xml)("<tool>%pS</tool>\n", VG_(clo_toolname));
+ if (VG_(clo_xml_fname_unexpanded) != NULL)
+ print_file_vars(VG_(clo_xml_fname_unexpanded));
+ if (VG_(clo_xml_user_comment)) {
+ /* Note: the user comment itself is XML and is therefore to
+ be passed through verbatim (%s) rather than escaped (%pS). */
+ VG_(printf_xml)("<usercomment>%s</usercomment>\n",
+ VG_(clo_xml_user_comment));
+ }
+ VG_(printf_xml)("\n");
+ VG_(printf_xml)("<args>\n");
+
+ VG_(printf_xml)(" <vargv>\n");
+ if (VG_(name_of_launcher))
+ VG_(printf_xml)(" <exe>%pS</exe>\n", VG_(name_of_launcher));
+ else
+ VG_(printf_xml)(" <exe>%pS</exe>\n", "(launcher name unknown)");
+ for (UInt i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
+ VG_(printf_xml)(
+ " <arg>%pS</arg>\n",
+ *(HChar **) VG_(indexXA)( VG_(args_for_valgrind), i));
+ }
+ VG_(printf_xml)(" </vargv>\n");
+
+ VG_(printf_xml)(" <argv>\n");
+ VG_(printf_xml)(" <exe>%pS</exe>\n", VG_(args_the_exename));
+ for (UInt i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++) {
+ VG_(printf_xml)(
+ " <arg>%pS</arg>\n",
+ *(HChar **) VG_(indexXA)( VG_(args_for_client), i));
+ }
+ VG_(printf_xml)(" </argv>\n");
+
+ VG_(printf_xml)("</args>\n");
+ }
+
+ // Last thing in the preamble is a blank line.
+ if (VG_(clo_xml))
+ VG_(printf_xml)("\n");
+ else if (VG_(clo_verbosity) > 0)
+ VG_(umsg)("\n");
+
+ if (VG_(clo_verbosity) > 1) {
+# if defined(VGO_linux)
+ SysRes fd;
+# endif
+ VexArch vex_arch;
+ VexArchInfo vex_archinfo;
+ if (!logging_to_fd)
+ VG_(message)(Vg_DebugMsg, "\n");
+ VG_(message)(Vg_DebugMsg, "Valgrind options:\n");
+ for (UInt i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
+ VG_(message)(Vg_DebugMsg,
+ " %s\n",
+ *(HChar **) VG_(indexXA)( VG_(args_for_valgrind), i));
+ }
+
+# if defined(VGO_linux)
+ VG_(message)(Vg_DebugMsg, "Contents of /proc/version:\n");
+ fd = VG_(open)("/proc/version", VKI_O_RDONLY, 0);
+ if (sr_isError(fd)) {
+ VG_(message)(Vg_DebugMsg, " can't open /proc/version\n");
+ } else {
+ const SizeT bufsiz = 255;
+ HChar version_buf[bufsiz+1];
+ VG_(message)(Vg_DebugMsg, " ");
+ Int n, fdno = sr_Res(fd);
+ do {
+ n = VG_(read)(fdno, version_buf, bufsiz);
+ if (n < 0) {
+ VG_(message)(Vg_DebugMsg, " error reading /proc/version\n");
+ break;
+ }
+ version_buf[n] = '\0';
+ VG_(message)(Vg_DebugMsg, "%s", version_buf);
+ } while (n == bufsiz);
+ VG_(message)(Vg_DebugMsg, "\n");
+ VG_(close)(fdno);
+ }
+# elif defined(VGO_darwin)
+ VG_(message)(Vg_DebugMsg, "Output from sysctl({CTL_KERN,KERN_VERSION}):\n");
+ /* Note: preferable to use sysctlbyname("kern.version", kernelVersion, &len, NULL, 0)
+ however that syscall is OS X 10.10+ only. */
+ Int mib[] = {CTL_KERN, KERN_VERSION};
+ SizeT len;
+ VG_(sysctl)(mib, sizeof(mib)/sizeof(Int), NULL, &len, NULL, 0);
+ HChar *kernelVersion = VG_(malloc)("main.pp.1", len);
+ VG_(sysctl)(mib, sizeof(mib)/sizeof(Int), kernelVersion, &len, NULL, 0);
+ VG_(message)(Vg_DebugMsg, " %s\n", kernelVersion);
+ VG_(free)( kernelVersion );
+# elif defined(VGO_solaris)
+ /* There is no /proc/version file on Solaris so we try to get some
+ system information using the uname(2) syscall. */
+ struct vki_utsname uts;
+ VG_(message)(Vg_DebugMsg, "System information:\n");
+ SysRes res = VG_(do_syscall1)(__NR_uname, (UWord)&uts);
+ if (sr_isError(res))
+ VG_(message)(Vg_DebugMsg, " uname() failed\n");
+ else
+ VG_(message)(Vg_DebugMsg, " %s %s %s %s\n",
+ uts.sysname, uts.release, uts.version, uts.machine);
+# endif
+
+ VG_(machine_get_VexArchInfo)(&vex_arch, &vex_archinfo);
+ VG_(message)(
+ Vg_DebugMsg,
+ "Arch and hwcaps: %s, %s, %s\n",
+ LibVEX_ppVexArch ( vex_arch ),
+ LibVEX_ppVexEndness ( vex_archinfo.endness ),
+ LibVEX_ppVexHwCaps ( vex_arch, vex_archinfo.hwcaps )
+ );
+ VG_(message)(Vg_DebugMsg,
+ "Page sizes: currently %u, max supported %u\n",
+ (UInt) VKI_PAGE_SIZE, (UInt) VKI_MAX_PAGE_SIZE);
+ VG_(message)(Vg_DebugMsg,
+ "Valgrind library directory: %s\n", VG_(libdir));
+ }
+}
/* ---------------------------------------------------------------------
Writing to file or a socket
@@ -54,19 +321,260 @@
After startup, the gdbserver monitor command might temporarily
set the fd of log_output_sink to -2 to indicate that output is
to be given to gdb rather than output to the startup fd */
-OutputSink VG_(log_output_sink) = { 2, False }; /* 2 = stderr */
-OutputSink VG_(xml_output_sink) = { -1, False }; /* disabled */
-
+OutputSink VG_(log_output_sink) = { 2, VgLogTo_Fd, NULL }; /* 2 = stderr */
+OutputSink VG_(xml_output_sink) = { -1, VgLogTo_Fd, NULL }; /* disabled */
+
+static void revert_sink_to_stderr ( OutputSink *sink )
+{
+ sink->fd = 2; /* stderr */
+ sink->type = VgLogTo_Fd;
+ VG_(free)(sink->fsname_expanded);
+ sink->fsname_expanded = NULL;
+}
+
+static Int prepare_sink_fd(const HChar *clo_fname_unexpanded, OutputSink *sink,
+ Bool is_xml)
+{
+ vg_assert(clo_fname_unexpanded != NULL);
+ vg_assert(VG_(strlen)(clo_fname_unexpanded) <= 900); /* paranoia */
+
+ // Nb: we overwrite an existing file of this name without asking
+ // any questions.
+ HChar *logfilename = VG_(expand_file_name)(
+ (is_xml) ? "--xml-file" : "--log-file",
+ clo_fname_unexpanded);
+ SysRes sres = VG_(open)(logfilename,
+ VKI_O_CREAT|VKI_O_WRONLY|VKI_O_TRUNC,
+ VKI_S_IRUSR|VKI_S_IWUSR|VKI_S_IRGRP|VKI_S_IROTH);
+ if (!sr_isError(sres)) {
+ Int fd = sr_Res(sres);
+ sink->fsname_expanded = logfilename;
+ sink->type = VgLogTo_File;
+ return fd;
+ } else {
+ VG_(fmsg)("Cannot create %s file '%s': %s\n",
+ (is_xml) ? "XML" : "log", logfilename,
+ VG_(strerror)(sr_Err(sres)));
+ VG_(exit)(1);
+ /*NOTREACHED*/
+ }
+}
+
+static Int prepare_sink_socket(const HChar *clo_fname_unexpanded,
+ OutputSink *sink, Bool is_xml)
+{
+ vg_assert(clo_fname_unexpanded != NULL);
+ vg_assert(VG_(strlen)(clo_fname_unexpanded) <= 900); /* paranoia */
+
+ Int fd = VG_(connect_via_socket)(clo_fname_unexpanded);
+ if (fd == -1) {
+ VG_(fmsg)("Invalid %s spec of '%s'\n",
+ (is_xml) ? "--xml-socket" : "--log-socket",
+ clo_fname_unexpanded);
+ VG_(exit)(1);
+ /*NOTREACHED*/
+ }
+ if (fd == -2) {
+ VG_(umsg)("Failed to connect to %slogging server '%s'.\n"
+ "%s will be sent to stderr instead.\n",
+ (is_xml) ? "XML " : "",
+ (is_xml) ? "XML output" : "Logging messages",
+ clo_fname_unexpanded);
+ /* We don't change anything here. */
+ vg_assert(sink->fd == 2);
+ vg_assert(sink->type == VgLogTo_Fd);
+ return 2;
+ } else {
+ vg_assert(fd > 0);
+ sink->type = VgLogTo_Socket;
+ return fd;
+ }
+}
+
+static void finalize_sink_fd(OutputSink *sink, Int new_fd, Bool is_xml)
+{
+ // Move new_fd into the safe range, so it doesn't conflict with any app fds.
+ Int safe_fd = VG_(fcntl)(new_fd, VKI_F_DUPFD, VG_(fd_hard_limit));
+ if (safe_fd < 0) {
+ VG_(message)(Vg_UserMsg, "Valgrind: failed to move %s file descriptor "
+ "into safe range, using stderr\n",
+ (is_xml) ? "XML" : "log");
+ revert_sink_to_stderr(sink);
+ } else {
+ VG_(fcntl)(safe_fd, VKI_F_SETFD, VKI_FD_CLOEXEC);
+ sink->fd = safe_fd;
+ }
+}
+
+/* Re-opens an output file sink when exanded file name differs from what we
+ have now. Returns 'True' if the sink was reopened */
+static Bool reopen_sink_if_needed(const HChar *clo_fname_unexpanded,
+ OutputSink *sink, Bool is_xml)
+{
+ if (sink->type == VgLogTo_File) {
+ /* Try to expand --log|xml-file again and see if it differs from what
+ we have now. */
+ HChar *logfilename = VG_(expand_file_name)(
+ (is_xml) ? "--xml-file" : "--log-file",
+ clo_fname_unexpanded);
+ if (VG_(strcmp)(logfilename, sink->fsname_expanded) != 0) {
+ Int fd = prepare_sink_fd(clo_fname_unexpanded, sink, is_xml);
+ finalize_sink_fd(sink, fd, is_xml);
+ return True;
+ }
+ VG_(free)(logfilename);
+ }
+
+ return False;
+}
+
+void VG_(logging_atfork_child)(ThreadId tid)
+{
+ /* If --child-silent-after-fork=yes was specified, set the output file
+ descriptors to 'impossible' values. This is noticed by
+ send_bytes_to_logging_sink(), which duly stops writing any further
+ output. */
+ if (VG_(clo_child_silent_after_fork)) {
+ if (VG_(log_output_sink).type != VgLogTo_Socket) {
+ VG_(log_output_sink).fd = -1;
+ VG_(log_output_sink).type = VgLogTo_Fd;
+ }
+ if (VG_(xml_output_sink).type != VgLogTo_Socket) {
+ VG_(xml_output_sink).fd = -1;
+ VG_(xml_output_sink).type = VgLogTo_Fd;
+ }
+ } else {
+ if (reopen_sink_if_needed(VG_(clo_log_fname_unexpanded),
+ &VG_(log_output_sink), False) ||
+ reopen_sink_if_needed(VG_(clo_xml_fname_unexpanded),
+ &VG_(xml_output_sink), True)) {
+ VG_(print_preamble)(VG_(log_output_sink).type != VgLogTo_File);
+ }
+ }
+}
+
+/* Initializes normal log and xml sinks (of type fd, file, or socket).
+ Any problem encountered is considered a hard error and causes V. to exit.
+
+ Comments on how the logging options are handled:
+
+ User can specify:
+ --log-fd= for a fd to write to (default setting, fd = 2)
+ --log-file= for a file name to write to
+ --log-socket= for a socket to write to
+
+ As a result of examining these and doing relevant socket/file
+ opening, a final fd is established. This is stored in
+ VG_(log_output_sink) in m_libcprint. Also, if --log-file=STR was
+ specified, then it is stored in VG_(clo_log_fname_unexpanded), in m_options.
+ And then STR, after expansion of %p and %q templates within
+ it, is stored in VG_(log_output_sink), just in case anybody wants to know
+ what it is.
+
+ When printing, VG_(log_output_sink) is consulted to find the
+ fd to send output to.
+
+ Exactly analogous actions are undertaken for the XML output
+ channel, with the one difference that the default fd is -1, meaning
+ the channel is disabled by default. */
+void VG_(init_log_xml_sinks)(VgLogTo log_to, VgLogTo xml_to,
+ Int /*initial*/log_fd, Int /*initial*/xml_fd)
+{
+ // VG_(clo_log_fd) is used by all the messaging. It starts as 2 (stderr)
+ // and we cannot change it until we know what we are changing it to is ok.
+
+ /* Start setting up logging now. After this is done, VG_(log_output_sink)
+ and (if relevant) VG_(xml_output_sink) should be connected to whatever
+ sink has been selected, and we indiscriminately chuck stuff into it
+ without worrying what the nature of it is.
+ Oh the wonder of Unix streams. */
+
+ vg_assert(VG_(log_output_sink).fd == 2 /* stderr */);
+ vg_assert(VG_(log_output_sink).type == VgLogTo_Fd);
+ vg_assert(VG_(log_output_sink).fsname_expanded == NULL);
+
+ vg_assert(VG_(xml_output_sink).fd == -1 /* disabled */);
+ vg_assert(VG_(xml_output_sink).type == VgLogTo_Fd);
+ vg_assert(VG_(xml_output_sink).fsname_expanded == NULL);
+
+ /* --- set up the normal text output channel --- */
+ switch (log_to) {
+ case VgLogTo_Fd:
+ vg_assert(VG_(clo_log_fname_unexpanded) == NULL);
+ break;
+
+ case VgLogTo_File:
+ log_fd = prepare_sink_fd(VG_(clo_log_fname_unexpanded),
+ &VG_(log_output_sink), False);
+ break;
+
+ case VgLogTo_Socket:
+ log_fd = prepare_sink_socket(VG_(clo_log_fname_unexpanded),
+ &VG_(log_output_sink), False);
+ break;
+ }
+
+ /* --- set up the XML output channel --- */
+ switch (xml_to) {
+ case VgLogTo_Fd:
+ vg_assert(VG_(clo_xml_fname_unexpanded) == NULL);
+ break;
+
+ case VgLogTo_File:
+ xml_fd = prepare_sink_fd(VG_(clo_xml_fname_unexpanded),
+ &VG_(xml_output_sink), True);
+ break;
+
+ case VgLogTo_Socket:
+ log_fd = prepare_sink_socket(VG_(clo_xml_fname_unexpanded),
+ &VG_(xml_output_sink), True);
+ break;
+ }
+
+ /* If we've got this far, and XML mode was requested, but no XML
+ output channel appears to have been specified, just stop. We
+ could continue, and XML output will simply vanish into nowhere,
+ but that is likely to confuse the hell out of users, which is
+ distinctly Ungood. */
+ if (VG_(clo_xml) && xml_fd == -1) {
+ VG_(fmsg_bad_option)(
+ "--xml=yes, but no XML destination specified",
+ "--xml=yes has been specified, but there is no XML output\n"
+ "destination. You must specify an XML output destination\n"
+ "using --xml-fd, --xml-file or --xml-socket.\n"
+ );
+ }
+
+ // Finalise the output fds: the log fd ..
+ if (log_fd >= 0) {
+ finalize_sink_fd(&VG_(log_output_sink), log_fd, False);
+ } else {
+ // If they said --log-fd=-1, don't print anything. Plausible for use in
+ // regression testing suites that use client requests to count errors.
+ VG_(log_output_sink).fd = -1;
+ VG_(log_output_sink).type = VgLogTo_Fd;
+ }
+
+ // Finalise the output fds: and the XML fd ..
+ if (xml_fd >= 0) {
+ finalize_sink_fd(&VG_(xml_output_sink), xml_fd, True);
+ } else {
+ // If they said --xml-fd=-1, don't print anything. Plausible for use in
+ // regression testing suites that use client requests to count errors.
+ VG_(xml_output_sink).fd = -1;
+ VG_(xml_output_sink).type = VgLogTo_Fd;
+ }
+}
+
/* Do the low-level send of a message to the logging sink. */
static
void send_bytes_to_logging_sink ( OutputSink* sink, const HChar* msg, Int nbytes )
{
- if (sink->is_socket) {
+ if (sink->type == VgLogTo_Socket) {
Int rc = VG_(write_socket)( sink->fd, msg, nbytes );
if (rc == -1) {
// For example, the listener process died. Switch back to stderr.
- sink->is_socket = False;
- sink->fd = 2;
+ revert_sink_to_stderr(sink);
VG_(write)( sink->fd, msg, nbytes );
}
} else {
@@ -557,8 +1065,7 @@
static void revert_to_stderr ( void )
{
- VG_(log_output_sink).fd = 2; /* stderr */
- VG_(log_output_sink).is_socket = False;
+ revert_sink_to_stderr(&VG_(log_output_sink));
}
/* VG_(message) variants with hardwired first argument. */
Modified: trunk/coregrind/m_main.c
==============================================================================
--- trunk/coregrind/m_main.c (original)
+++ trunk/coregrind/m_main.c Thu Jan 12 11:28:20 2017
@@ -31,7 +31,6 @@
#include "vgversion.h"
#include "pub_core_basics.h"
#include "pub_core_vki.h"
-#include "pub_core_vkiscnums.h"
#include "pub_core_threadstate.h"
#include "pub_core_xarray.h"
#include "pub_core_clientstate.h"
@@ -51,7 +50,6 @@
#include "pub_core_libcproc.h"
#include "pub_core_libcsignal.h"
#include "pub_core_sbprofile.h"
-#include "pub_core_syscall.h" // VG_(strerror)
#include "pub_core_mach.h"
#include "pub_core_machine.h"
#include "pub_core_mallocfree.h"
@@ -314,7 +312,7 @@
// Ensure the message goes to stdout
VG_(log_output_sink).fd = 1;
- VG_(log_output_sink).is_socket = False;
+ VG_(log_output_sink).type = VgLogTo_Fd;
if (VG_(needs).malloc_replacement) {
VG_(sprintf)(default_alignment, "%d", VG_MIN_MALLOC_SZB);
@@ -363,7 +361,7 @@
- show the version string, if requested (-v)
- extract any request for help (--help, -h, --help-debug)
- - get the toolname (--tool=)
+ - set VG_(toolname) (--tool=)
- set VG_(clo_max_stackframe) (--max-stackframe=)
- set VG_(clo_main_stacksize) (--main-stacksize=)
- set VG_(clo_sim_hints) (--sim-hints=)
@@ -374,8 +372,7 @@
main_process_cmd_line_options has to handle but ignore the ones we
have handled here.
*/
-static void early_process_cmd_line_options ( /*OUT*/Int* need_help,
- /*OUT*/const HChar** tool )
+static void early_process_cmd_line_options ( /*OUT*/Int* need_help )
{
UInt i;
HChar* str;
@@ -403,7 +400,7 @@
// The tool has already been determined, but we need to know the name
// here.
- else if VG_STR_CLO(str, "--tool", *tool) {}
+ else if VG_STR_CLO(str, "--tool", VG_(clo_toolname)) {}
// Set up VG_(clo_max_stackframe) and VG_(clo_main_stacksize).
// These are needed by VG_(ii_create_image), which happens
@@ -427,7 +424,7 @@
if (need_version) {
// Nb: the version string goes to stdout.
VG_(log_output_sink).fd = 1;
- VG_(log_output_sink).is_socket = False;
+ VG_(log_output_sink).type = VgLogTo_Fd;
if (VG_(clo_verbosity) <= 1)
VG_(printf)("valgrind-" VERSION "\n");
else
@@ -440,53 +437,13 @@
}
/* The main processing for command line options. See comments above
- on early_process_cmd_line_options.
-
- Comments on how the logging options are handled:
-
- User can specify:
- --log-fd= for a fd to write to (default setting, fd = 2)
- --log-file= for a file name to write to
- --log-socket= for a socket to write to
-
- As a result of examining these and doing relevant socket/file
- opening, a final fd is established. This is stored in
- VG_(log_output_sink) in m_libcprint. Also, if --log-file=STR was
- specified, then STR, after expansion of %p and %q templates within
- it, is stored in VG_(clo_log_fname_expanded), in m_options, just in
- case anybody wants to know what it is.
-
- When printing, VG_(log_output_sink) is consulted to find the
- fd to send output to.
-
- Exactly analogous actions are undertaken for the XML output
- channel, with the one difference that the default fd is -1, meaning
- the channel is disabled by default.
-*/
+ on early_process_cmd_line_options. */
static
-void main_process_cmd_line_options ( /*OUT*/Bool* logging_to_fd,
- /*OUT*/const HChar** xml_fname_unexpanded,
- const HChar* toolname )
-{
- // VG_(clo_log_fd) is used by all the messaging. It starts as 2 (stderr)
- // and we cannot change it until we know what we are changing it to is
- // ok. So we have tmp_log_fd to hold the tmp fd prior to that point.
- SysRes sres;
- Int i, tmp_log_fd, tmp_xml_fd;
- Int toolname_len = VG_(strlen)(toolname);
+void main_process_cmd_line_options( void )
+{
+ Int i;
+ Int toolname_len = VG_(strlen)(VG_(clo_toolname));
const HChar* tmp_str; // Used in a couple of places.
- enum {
- VgLogTo_Fd,
- VgLogTo_File,
- VgLogTo_Socket
- } log_to = VgLogTo_Fd, // Where is logging output to be sent?
- xml_to = VgLogTo_Fd; // Where is XML output to be sent?
-
- /* Temporarily holds the string STR specified with
- --{log,xml}-{name,socket}=STR. 'fs' stands for
- file-or-socket. */
- const HChar* log_fsname_unexpanded = NULL;
- const HChar* xml_fsname_unexpanded = NULL;
/* Whether the user has explicitly provided --sigill-diagnostics.
If not explicitly given depends on general verbosity setting. */
@@ -494,9 +451,11 @@
/* Log to stderr by default, but usage message goes to stdout. XML
output is initially disabled. */
- tmp_log_fd = 2;
- tmp_xml_fd = -1;
-
+ VgLogTo log_to = VgLogTo_Fd; // Where is logging output to be sent?
+ VgLogTo xml_to = VgLogTo_Fd; // Where is XML output to be sent?
+ Int tmp_log_fd = 2;
+ Int tmp_xml_fd = -1;
+
/* Check for sane path in ./configure --prefix=... */
if (VG_LIBDIR[0] != '/')
VG_(err_config_error)("Please use absolute paths in "
@@ -536,7 +495,7 @@
// eg. "--memcheck:verbose".
if (*colon == ':') {
if (VG_STREQN(2, arg, "--") &&
- VG_STREQN(toolname_len, arg+2, toolname) &&
+ VG_STREQN(toolname_len, arg+2, VG_(clo_toolname)) &&
VG_STREQN(1, arg+2+toolname_len, ":"))
{
// Prefix matches, convert "--toolname:foo" to "--foo".
@@ -780,24 +739,24 @@
else if VG_INT_CLO(arg, "--log-fd", tmp_log_fd) {
log_to = VgLogTo_Fd;
- log_fsname_unexpanded = NULL;
+ VG_(clo_log_fname_unexpanded) = NULL;
}
else if VG_INT_CLO(arg, "--xml-fd", tmp_xml_fd) {
xml_to = VgLogTo_Fd;
- xml_fsname_unexpanded = NULL;
+ VG_(clo_xml_fname_unexpanded) = NULL;
}
- else if VG_STR_CLO(arg, "--log-file", log_fsname_unexpanded) {
+ else if VG_STR_CLO(arg, "--log-file", VG_(clo_log_fname_unexpanded)) {
log_to = VgLogTo_File;
}
- else if VG_STR_CLO(arg, "--xml-file", xml_fsname_unexpanded) {
+ else if VG_STR_CLO(arg, "--xml-file", VG_(clo_xml_fname_unexpanded)) {
xml_to = VgLogTo_File;
}
- else if VG_STR_CLO(arg, "--log-socket", log_fsname_unexpanded) {
+ else if VG_STR_CLO(arg, "--log-socket", VG_(clo_log_fname_unexpanded)) {
log_to = VgLogTo_Socket;
}
- else if VG_STR_CLO(arg, "--xml-socket", xml_fsname_unexpanded) {
+ else if VG_STR_CLO(arg, "--xml-socket", VG_(clo_xml_fname_unexpanded)) {
xml_to = VgLogTo_Socket;
}
@@ -1031,197 +990,13 @@
have to generate any other command-line-related error messages.
(So far we should be still attached to stderr, so we can show on
the terminal any problems to do with processing command line
- opts.)
-
- So set up logging now. After this is done, VG_(log_output_sink)
- and (if relevant) VG_(xml_output_sink) should be connected to
- whatever sink has been selected, and we indiscriminately chuck
- stuff into it without worrying what the nature of it is. Oh the
- wonder of Unix streams. */
-
- vg_assert(VG_(log_output_sink).fd == 2 /* stderr */);
- vg_assert(VG_(log_output_sink).is_socket == False);
- vg_assert(VG_(clo_log_fname_expanded) == NULL);
-
- vg_assert(VG_(xml_output_sink).fd == -1 /* disabled */);
- vg_assert(VG_(xml_output_sink).is_socket == False);
- vg_assert(VG_(clo_xml_fname_expanded) == NULL);
-
- /* --- set up the normal text output channel --- */
+ opts.) */
+ VG_(init_log_xml_sinks)(log_to, xml_to, tmp_log_fd, tmp_xml_fd);
- switch (log_to) {
-
- case VgLogTo_Fd:
- vg_assert(log_fsname_unexpanded == NULL);
- break;
-
- case VgLogTo_File: {
- HChar* logfilename;
-
- vg_assert(log_fsname_unexpanded != NULL);
- vg_assert(VG_(strlen)(log_fsname_unexpanded) <= 900); /* paranoia */
-
- // Nb: we overwrite an existing file of this name without asking
- // any questions.
- logfilename = VG_(expand_file_name)("--log-file",
- log_fsname_unexpanded);
- sres = VG_(open)(logfilename,
- VKI_O_CREAT|VKI_O_WRONLY|VKI_O_TRUNC,
- VKI_S_IRUSR|VKI_S_IWUSR|VKI_S_IRGRP|VKI_S_IROTH);
- if (!sr_isError(sres)) {
- tmp_log_fd = sr_Res(sres);
- VG_(clo_log_fname_expanded) = logfilename;
- } else {
- VG_(fmsg)("can't create log file '%s': %s\n",
- logfilename, VG_(strerror)(sr_Err(sres)));
- VG_(exit)(1);
- /*NOTREACHED*/
- }
- break;
- }
-
- case VgLogTo_Socket: {
- vg_assert(log_fsname_unexpanded != NULL);
- vg_assert(VG_(strlen)(log_fsname_unexpanded) <= 900); /* paranoia */
- tmp_log_fd = VG_(connect_via_socket)( log_fsname_unexpanded );
- if (tmp_log_fd == -1) {
- VG_(fmsg)("Invalid --log-socket spec of '%s'\n",
- log_fsname_unexpanded);
- VG_(exit)(1);
- /*NOTREACHED*/
- }
- if (tmp_log_fd == -2) {
- VG_(umsg)("failed to connect to logging server '%s'.\n"
- "Log messages will sent to stderr instead.\n",
- log_fsname_unexpanded );
-
- /* We don't change anything here. */
- vg_assert(VG_(log_output_sink).fd == 2);
- tmp_log_fd = 2;
- } else {
- vg_assert(tmp_log_fd > 0);
- VG_(log_output_sink).is_socket = True;
- }
- break;
- }
- }
-
- /* --- set up the XML output channel --- */
-
- switch (xml_to) {
-
- case VgLogTo_Fd:
- vg_assert(xml_fsname_unexpanded == NULL);
- break;
-
- case VgLogTo_File: {
- HChar* xmlfilename;
-
- vg_assert(xml_fsname_unexpanded != NULL);
- vg_assert(VG_(strlen)(xml_fsname_unexpanded) <= 900); /* paranoia */
-
- // Nb: we overwrite an existing file of this name without asking
- // any questions.
- xmlfilename = VG_(expand_file_name)("--xml-file",
- xml_fsname_unexpanded);
- sres = VG_(open)(xmlfilename,
- VKI_O_CREAT|VKI_O_WRONLY|VKI_O_TRUNC,
- VKI_S_IRUSR|VKI_S_IWUSR|VKI_S_IRGRP|VKI_S_IROTH);
- if (!sr_isError(sres)) {
- tmp_xml_fd = sr_Res(sres);
- VG_(clo_xml_fname_expanded) = xmlfilename;
- *xml_fname_unexpanded = xml_fsname_unexpanded;
- } else {
- VG_(fmsg)("can't create XML file '%s': %s\n",
- xmlfilename, VG_(strerror)(sr_Err(sres)));
- VG_(exit)(1);
- /*NOTREACHED*/
- }
- break;
- }
-
- case VgLogTo_Socket: {
- vg_assert(xml_fsname_unexpanded != NULL);
- vg_assert(VG_(strlen)(xml_fsname_unexpanded) <= 900); /* paranoia */
- tmp_xml_fd = VG_(connect_via_socket)( xml_fsname_unexpanded );
- if (tmp_xml_fd == -1) {
- VG_(fmsg)("Invalid --xml-socket spec of '%s'\n",
- xml_fsname_unexpanded );
- VG_(exit)(1);
- /*NOTREACHED*/
- }
- if (tmp_xml_fd == -2) {
- VG_(umsg)("failed to connect to XML logging server '%s'.\n"
- "XML output will sent to stderr instead.\n",
- xml_fsname_unexpanded);
- /* We don't change anything here. */
- vg_assert(VG_(xml_output_sink).fd == 2);
- tmp_xml_fd = 2;
- } else {
- vg_assert(tmp_xml_fd > 0);
- VG_(xml_output_sink).is_socket = True;
- }
- break;
- }
- }
-
- /* If we've got this far, and XML mode was requested, but no XML
- output channel appears to have been specified, just stop. We
- could continue, and XML output will simply vanish into nowhere,
- but that is likely to confuse the hell out of users, which is
- distinctly Ungood. */
- if (VG_(clo_xml) && tmp_xml_fd == -1) {
- VG_(fmsg_bad_option)(
- "--xml=yes, but no XML destination specified",
- "--xml=yes has been specified, but there is no XML output\n"
- "destination. You must specify an XML output destination\n"
- "using --xml-fd, --xml-file or --xml-socket.\n"
- );
- }
-
- // Finalise the output fds: the log fd ..
-
- if (tmp_log_fd >= 0) {
- // Move log_fd into the safe range, so it doesn't conflict with
- // any app fds.
- tmp_log_fd = VG_(fcntl)(tmp_log_fd, VKI_F_DUPFD, VG_(fd_hard_limit));
- if (tmp_log_fd < 0) {
- VG_(message)(Vg_UserMsg, "valgrind: failed to move logfile fd "
- "into safe range, using stderr\n");
- VG_(log_output_sink).fd = 2; // stderr
- VG_(log_output_sink).is_socket = False;
- } else {
- VG_(log_output_sink).fd = tmp_log_fd;
- VG_(fcntl)(VG_(log_output_sink).fd, VKI_F_SETFD, VKI_FD_CLOEXEC);
- }
- } else {
- // If they said --log-fd=-1, don't print anything. Plausible for use in
- // regression testing suites that use client requests to count errors.
- VG_(log_output_sink).fd = -1;
- VG_(log_output_sink).is_socket = False;
- }
-
- // Finalise the output fds: and the XML fd ..
-
- if (tmp_xml_fd >= 0) {
- // Move xml_fd into the safe range, so it doesn't conflict with
- // any app fds.
- tmp_xml_fd = VG_(fcntl)(tmp_xml_fd, VKI_F_DUPFD, VG_(fd_hard_limit));
- if (tmp_xml_fd < 0) {
- VG_(message)(Vg_UserMsg, "valgrind: failed to move XML file fd "
- "into safe range, using stderr\n");
- VG_(xml_output_sink).fd = 2; // stderr
- VG_(xml_output_sink).is_socket = False;
- } else {
- VG_(xml_output_sink).fd = tmp_xml_fd;
- VG_(fcntl)(VG_(xml_output_sink).fd, VKI_F_SETFD, VKI_FD_CLOEXEC);
- }
- } else {
- // If they said --xml-fd=-1, don't print anything. Plausible for use in
- // regression testing suites that use client requests to count errors.
- VG_(xml_output_sink).fd = -1;
- VG_(xml_output_sink).is_socket = False;
- }
+ /* Register child at-fork handler which will take care of handling
+ --child-silent-after-fork clo and also reopening output sinks for forked
+ children, if requested via --log|xml-file= options. */
+ VG_(atfork)(NULL, NULL, VG_(logging_atfork_child));
// Suppressions related stuff
@@ -1235,294 +1010,6 @@
VG_(sprintf)(buf, "%s/%s", VG_(libdir), default_supp);
VG_(addToXA)(VG_(clo_suppressions), &buf);
}
-
- *logging_to_fd = log_to == VgLogTo_Fd || log_to == VgLogTo_Socket;
-}
-
-// Write the name and value of log file qualifiers to the xml file.
-// We can safely assume here that the format string is well-formed.
-// It has been checked earlier in VG_(expand_file_name) when processing
-// command line options.
-static void print_file_vars(const HChar* format)
-{
- Int i = 0;
-
- while (format[i]) {
- if (format[i] == '%') {
- // We saw a '%'. What's next...
- i++;
- if ('q' == format[i]) {
- i++;
- if ('{' == format[i]) {
- // Get the env var name, print its contents.
- HChar* qual;
- Int begin_qualname = ++i;
- while (True) {
- if ('}' == format[i]) {
- Int qualname_len = i - begin_qualname;
- HChar qualname[qualname_len + 1];
- VG_(strncpy)(qualname, format + begin_qualname,
- qualname_len);
- qualname[qualname_len] = '\0';
- qual = VG_(getenv)(qualname);
- i++;
- VG_(printf_xml)("<logfilequalifier> <var>%pS</var> "
- "<value>%pS</value> </logfilequalifier>\n",
- qualname, qual);
- break;
- }
- i++;
- }
- }
- }
- } else {
- i++;
- }
- }
-}
-
-
-/*====================================================================*/
-/*=== Printing the preamble ===*/
-/*====================================================================*/
-
-// Print the argument, escaping any chars that require it.
-static void umsg_arg(const HChar* arg)
-{
- SizeT len = VG_(strlen)(arg);
- const HChar* special = " \\<>";
- Int i;
- for (i = 0; i < len; i++) {
- if (VG_(strchr)(special, arg[i])) {
- VG_(umsg)("\\"); // escape with a backslash if necessary
- }
- VG_(umsg)("%c", arg[i]);
- }
-}
-
-// Send output to the XML-stream and escape any XML meta-characters.
-static void xml_arg(const HChar* arg)
-{
- VG_(printf_xml)("%pS", arg);
-}
-
-/* Ok, the logging sink is running now. Print a suitable preamble.
- If logging to file or a socket, write details of parent PID and
- command line args, to help people trying to interpret the
- results of a run which encompasses multiple processes. */
-static void print_preamble ( Bool logging_to_fd,
- const HChar* xml_fname_unexpanded,
- const HChar* toolname )
-{
- Int i;
- const HChar* xpre = VG_(clo_xml) ? " <line>" : "";
- const HChar* xpost = VG_(clo_xml) ? "</line>" : "";
- UInt (*umsg_or_xml)( const HChar*, ... )
- = VG_(clo_xml) ? VG_(printf_xml) : VG_(umsg);
-
- void (*umsg_or_xml_arg)( const HChar* )
- = VG_(clo_xml) ? xml_arg : umsg_arg;
-
- vg_assert( VG_(args_for_client) );
- vg_assert( VG_(args_for_valgrind) );
- vg_assert( toolname );
-
- if (VG_(clo_xml)) {
- VG_(printf_xml)("<?xml version=\"1.0\"?>\n");
- VG_(printf_xml)("\n");
- VG_(printf_xml)("<valgrindoutput>\n");
- VG_(printf_xml)("\n");
- VG_(printf_xml)("<protocolversion>4</protocolversion>\n");
- VG_(printf_xml)("<protocoltool>%s</protocoltool>\n", toolname);
- VG_(printf_xml)("\n");
- }
-
- if (VG_(clo_xml) || VG_(clo_verbosity) > 0) {
-
- if (VG_(clo_xml))
- VG_(printf_xml)("<preamble>\n");
-
- /* Tool details */
- umsg_or_xml( VG_(clo_xml) ? "%s%pS%pS%pS, %pS%s\n" : "%s%s%s%s, %s%s\n",
- xpre,
- VG_(details).name,
- NULL == VG_(details).version ? "" : "-",
- NULL == VG_(details).version
- ? "" : VG_(details).version,
- VG_(details).description,
- xpost );
-
- if (VG_(strlen)(toolname) >= 4 && VG_STREQN(4, toolname, "exp-")) {
- umsg_or_xml(
- "%sNOTE: This is an Experimental-Class Valgrind Tool%s\n",
- xpre, xpost
- );
- }
-
- umsg_or_xml( VG_(clo_xml) ? "%s%pS%s\n" : "%s%s%s\n",
- xpre, VG_(details).copyright_author, xpost );
-
- /* Core details */
- umsg_or_xml(
- "%sUsing Valgrind-%s and LibVEX; rerun with -h for copyright info%s\n",
- xpre, VERSION, xpost
- );
-
- // Print the command line. At one point we wrapped at 80 chars and
- // printed a '\' as a line joiner, but that makes it hard to cut and
- // paste the command line (because of the "==pid==" prefixes), so we now
- // favour utility and simplicity over aesthetics.
- umsg_or_xml("%sCommand: ", xpre);
- umsg_or_xml_arg(VG_(args_the_exename));
-
- for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++) {
- HChar* s = *(HChar**)VG_(indexXA)( VG_(args_for_client), i );
- umsg_or_xml(" ");
- umsg_or_xml_arg(s);
- }
- umsg_or_xml("%s\n", xpost);
-
- if (VG_(clo_xml))
- VG_(printf_xml)("</preamble>\n");
- }
-
- // Print the parent PID, and other stuff, if necessary.
- if (!VG_(clo_xml) && VG_(clo_verbosity) > 0 && !logging_to_fd) {
- VG_(umsg)("Parent PID: %d\n", VG_(getppid)());
- }
- else
- if (VG_(clo_xml)) {
- VG_(printf_xml)("\n");
- VG_(printf_xml)("<pid>%d</pid>\n", VG_(getpid)());
- VG_(printf_xml)("<ppid>%d</ppid>\n", VG_(getppid)());
- VG_(printf_xml)("<tool>%pS</tool>\n", toolname);
- if (xml_fname_unexpanded)
- print_file_vars(xml_fname_unexpanded);
- if (VG_(clo_xml_user_comment)) {
- /* Note: the user comment itself is XML and is therefore to
- be passed through verbatim (%s) rather than escaped
- (%pS). */
- VG_(printf_xml)("<usercomment>%s</usercomment>\n",
- VG_(clo_xml_user_comment));
- }
- VG_(printf_xml)("\n");
- VG_(printf_xml)("<args>\n");
-
- VG_(printf_xml)(" <vargv>\n");
- if (VG_(name_of_launcher))
- VG_(printf_xml)(" <exe>%pS</exe>\n",
- VG_(name_of_launcher));
- else
- VG_(printf_xml)(" <exe>%pS</exe>\n",
- "(launcher name unknown)");
- for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
- VG_(printf_xml)(
- " <arg>%pS</arg>\n",
- * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i )
- );
- }
- VG_(printf_xml)(" </vargv>\n");
-
- VG_(printf_xml)(" <argv>\n");
- VG_(printf_xml)(" <exe>%pS</exe>\n",
- VG_(args_the_exename));
- for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++) {
- VG_(printf_xml)(
- " <arg>%pS</arg>\n",
- * (HChar**) VG_(indexXA)( VG_(args_for_client), i )
- );
- }
- VG_(printf_xml)(" </argv>\n");
-
- VG_(printf_xml)("</args>\n");
- }
-
- // Last thing in the preamble is a blank line.
- if (VG_(clo_xml))
- VG_(printf_xml)("\n");
- else if (VG_(clo_verbosity) > 0)
- VG_(umsg)("\n");
-
- if (VG_(clo_verbosity) > 1) {
-# if defined(VGO_linux)
- SysRes fd;
-# endif
- VexArch vex_arch;
- VexArchInfo vex_archinfo;
- if (!logging_to_fd)
- VG_(message)(Vg_DebugMsg, "\n");
- VG_(message)(Vg_DebugMsg, "Valgrind options:\n");
- for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
- VG_(message)(Vg_DebugMsg,
- " %s\n",
- * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i ));
- }
-
-# if defined(VGO_linux)
- VG_(message)(Vg_DebugMsg, "Contents of /proc/version:\n");
- fd = VG_(open) ( "/proc/version", VKI_O_RDONLY, 0 );
- if (sr_isError(fd)) {
- VG_(message)(Vg_DebugMsg, " can't open /proc/version\n");
- } else {
- const SizeT bufsiz = 255;
- HChar version_buf[bufsiz+1];
- VG_(message)(Vg_DebugMsg, " ");
- Int n, fdno = sr_Res(fd);
- do {
- n = VG_(read)(fdno, version_buf, bufsiz);
- if (n < 0) {
- VG_(message)(Vg_DebugMsg, " error reading /proc/version\n");
- break;
- }
- version_buf[n] = '\0';
- VG_(message)(Vg_DebugMsg, "%s", version_buf);
- } while (n == bufsiz);
- VG_(message)(Vg_DebugMsg, "\n");
- VG_(close)(fdno);
- }
-# elif defined(VGO_darwin)
- VG_(message)(Vg_DebugMsg, "Output from sysctl({CTL_KERN,KERN_VERSION}):\n");
- /* Note: preferable to use sysctlbyname("kern.version", kernelVersion, &len, NULL, 0)
- however that syscall is OS X 10.10+ only. */
- Int mib[] = {CTL_KERN, KERN_VERSION};
- SizeT len;
- VG_(sysctl)(mib, sizeof(mib)/sizeof(Int), NULL, &len, NULL, 0);
- HChar *kernelVersion = VG_(malloc)("main.pp.1", len);
- VG_(sysctl)(mib, sizeof(mib)/sizeof(Int), kernelVersion, &len, NULL, 0);
- VG_(message)(Vg_DebugMsg, " %s\n", kernelVersion);
- VG_(free)( kernelVersion );
-# elif defined(VGO_solaris)
- /* There is no /proc/version file on Solaris so we try to get some
- system information using the uname(2) syscall. */
- {
- struct vki_utsname uts;
-
- VG_(message)(Vg_DebugMsg, "System information:\n");
- SysRes res = VG_(do_syscall1)(__NR_uname, (UWord)&uts);
- if (sr_isError(res))
- VG_(message)(Vg_DebugMsg, " uname() failed\n");
- else
- VG_(message)(Vg_DebugMsg, " %s %s %s %s\n",
- uts.sysname, uts.release, uts.version, uts.machine);
- }
-# endif
-
- VG_(machine_get_VexArchInfo)( &vex_arch, &vex_archinfo );
- VG_(message)(
- Vg_DebugMsg,
- "Arch and hwcaps: %s, %s, %s\n",
- LibVEX_ppVexArch ( vex_arch ),
- LibVEX_ppVexEndness ( vex_archinfo.endness ),
- LibVEX_ppVexHwCaps ( vex_arch, vex_archinfo.hwcaps )
- );
- VG_(message)(
- Vg_DebugMsg,
- "Page sizes: currently %d, max supported %d\n",
- (Int)VKI_PAGE_SIZE, (Int)VKI_MAX_PAGE_SIZE
- );
- VG_(message)(Vg_DebugMsg,
- "Valgrind library directory: %s\n", VG_(libdir));
- }
}
@@ -1643,11 +1130,8 @@
static
Int valgrind_main ( Int argc, HChar **argv, HChar **envp )
{
- const HChar* toolname = "memcheck"; // default to Memcheck
Int need_help = 0; // 0 = no, 1 = --help, 2 = --help-debug
ThreadId tid_main = VG_INVALID_THREADID;
- Bool logging_to_fd = False;
- const HChar* xml_fname_unexpanded = NULL;
Int loglevel, i;
XArray* addr2dihandle = NULL;
@@ -1914,15 +1398,15 @@
//--------------------------------------------------------------
VG_(debugLog)(1, "main",
"(early_) Process Valgrind's command line options\n");
- early_process_cmd_line_options(&need_help, &toolname);
+ early_process_cmd_line_options(&need_help);
// BEGIN HACK
- vg_assert(toolname != NULL);
+ vg_assert(VG_(clo_toolname) != NULL);
vg_assert(VG_(clo_read_inline_info) == False);
# if !defined(VGO_darwin)
- if (0 == VG_(strcmp)(toolname, "memcheck")
- || 0 == VG_(strcmp)(toolname, "helgrind")
- || 0 == VG_(strcmp)(toolname, "drd")) {
+ if (0 == VG_(strcmp)(VG_(clo_toolname), "memcheck")
+ || 0 == VG_(strcmp)(VG_(clo_toolname), "helgrind")
+ || 0 == VG_(strcmp)(VG_(clo_toolname), "drd")) {
/* Change the default setting. Later on (just below)
main_process_cmd_line_options should pick up any
user-supplied setting for it and will override the default
@@ -1944,7 +1428,7 @@
//
// Set up client's environment
// p: set-libdir [for VG_(libdir)]
- // p: early_process_cmd_line_options [for toolname]
+ // p: early_process_cmd_line_options [for VG_(clo_toolname)]
//
// Setup client stack, eip, and VG_(client_arg[cv])
// p: load_client() [for 'info']
@@ -1963,7 +1447,7 @@
# if defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_solaris)
the_iicii.argv = argv;
the_iicii.envp = envp;
- the_iicii.toolname = toolname;
+ the_iicii.toolname = VG_(clo_toolname);
# else
# error "Unknown platform"
# endif
@@ -2120,8 +1604,7 @@
VG_(debugLog)(1, "main",
"(main_) Process Valgrind's command line options, "
"setup logging\n");
- main_process_cmd_line_options ( &logging_to_fd, &xml_fname_unexpanded,
- toolname );
+ main_process_cmd_line_options();
//--------------------------------------------------------------
// Zeroise the millisecond counter by doing a first read of it.
@@ -2133,11 +1616,10 @@
// Print the preamble
// p: tl_pre_clo_init [for 'VG_(details).name' and friends]
// p: main_process_cmd_line_options()
- // [for VG_(clo_verbosity), VG_(clo_xml),
- // logging_to_fd, xml_fname_unexpanded]
+ // [for VG_(clo_verbosity), VG_(clo_xml)]
//--------------------------------------------------------------
VG_(debugLog)(1, "main", "Print the preamble...\n");
- print_preamble(logging_to_fd, xml_fname_unexpanded, toolname);
+ VG_(print_preamble)(VG_(log_output_sink).type != VgLogTo_File);
VG_(debugLog)(1, "main", "...finished the preamble\n");
//--------------------------------------------------------------
Modified: trunk/coregrind/m_options.c
==============================================================================
--- trunk/coregrind/m_options.c (original)
+++ trunk/coregrind/m_options.c Thu Jan 12 11:28:20 2017
@@ -45,6 +45,7 @@
/* Define, and set defaults. */
+const HChar *VG_(clo_toolname) = "memcheck"; // default to Memcheck
VexControl VG_(clo_vex_control);
VexRegisterUpdates VG_(clo_px_file_backed) = VexRegUpd_INVALID;
@@ -79,8 +80,8 @@
const HChar* VG_(clo_trace_children_skip) = NULL;
const HChar* VG_(clo_trace_children_skip_by_arg) = NULL;
Bool VG_(clo_child_silent_after_fork) = False;
-const HChar* VG_(clo_log_fname_expanded) = NULL;
-const HChar* VG_(clo_xml_fname_expanded) = NULL;
+const HChar *VG_(clo_log_fname_unexpanded) = NULL;
+const HChar *VG_(clo_xml_fname_unexpanded) = NULL;
Bool VG_(clo_time_stamp) = False;
Int VG_(clo_input_fd) = 0; /* stdin */
Bool VG_(clo_default_supp) = True;
Modified: trunk/coregrind/m_syswrap/syswrap-generic.c
==============================================================================
--- trunk/coregrind/m_syswrap/syswrap-generic.c (original)
+++ trunk/coregrind/m_syswrap/syswrap-generic.c Thu Jan 12 11:28:20 2017
@@ -3301,18 +3301,6 @@
/* restore signal mask */
VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
-
- /* If --child-silent-after-fork=yes was specified, set the
- output file descriptors to 'impossible' values. This is
- noticed by send_bytes_to_logging_sink in m_libcprint.c, which
- duly stops writing any further output. */
- if (VG_(clo_child_silent_after_fork)) {
- if (!VG_(log_output_sink).is_socket)
- VG_(log_output_sink).fd = -1;
- if (!VG_(xml_output_sink).is_socket)
- VG_(xml_output_sink).fd = -1;
- }
-
} else {
VG_(do_atfork_parent)(tid);
Modified: trunk/coregrind/m_syswrap/syswrap-linux.c
==============================================================================
--- trunk/coregrind/m_syswrap/syswrap-linux.c (original)
+++ trunk/coregrind/m_syswrap/syswrap-linux.c Thu Jan 12 11:28:20 2017
@@ -788,17 +788,6 @@
/* restore signal mask */
VG_(sigprocmask)(VKI_SIG_SETMASK, &fork_saved_mask, NULL);
-
- /* If --child-silent-after-fork=yes was specified, set the
- output file descriptors to 'impossible' values. This is
- noticed by send_bytes_to_logging_sink in m_libcprint.c, which
- duly stops writing any further output. */
- if (VG_(clo_child_silent_after_fork)) {
- if (!VG_(log_output_sink).is_socket)
- VG_(log_output_sink).fd = -1;
- if (!VG_(xml_output_sink).is_socket)
- VG_(xml_output_sink).fd = -1;
- }
}
else
if (!sr_isError(res) && sr_Res(res) > 0) {
Modified: trunk/coregrind/m_syswrap/syswrap-solaris.c
==============================================================================
--- trunk/coregrind/m_syswrap/syswrap-solaris.c (original)
+++ trunk/coregrind/m_syswrap/syswrap-solaris.c Thu Jan 12 11:28:20 2017
@@ -6624,17 +6624,6 @@
if (RESHI) {
VG_(do_atfork_child)(tid);
- /* If --child-silent-after-fork=yes was specified, set the output file
- descriptors to 'impossible' values. This is noticed by
- send_bytes_to_logging_sink() in m_libcprint.c, which duly stops
- writing any further output. */
- if (VG_(clo_child_silent_after_fork)) {
- if (!VG_(log_output_sink).is_socket)
- VG_(log_output_sink).fd = -1;
- if (!VG_(xml_output_sink).is_socket)
- VG_(xml_output_sink).fd = -1;
- }
-
/* vfork */
if (ARG1 == 2)
VG_(close)(fds[1]);
Modified: trunk/coregrind/pub_core_libcprint.h
==============================================================================
--- trunk/coregrind/pub_core_libcprint.h (original)
+++ trunk/coregrind/pub_core_libcprint.h Thu Jan 12 11:28:20 2017
@@ -38,16 +38,36 @@
#include "pub_tool_libcprint.h"
-/* An output file descriptor wrapped up with a Bool indicating whether
- or not the fd is a socket. */
typedef
- struct { Int fd; Bool is_socket; }
+ enum {
+ VgLogTo_Fd,
+ VgLogTo_File,
+ VgLogTo_Socket
+ }
+ VgLogTo;
+
+/* An output file descriptor wrapped up with its type and expanded name. */
+typedef
+ struct {
+ Int fd;
+ VgLogTo type;
+ HChar *fsname_expanded; // 'fs' stands for file or socket
+ }
OutputSink;
/* And the destinations for normal and XML output. */
extern OutputSink VG_(log_output_sink);
extern OutputSink VG_(xml_output_sink);
+/* Initializes normal log and xml sinks (of type fd, file, or socket).
+ Any problem encountered is considered a hard error and causes V. to exit. */
+extern void VG_(init_log_xml_sinks)(VgLogTo log_to, VgLogTo xml_to,
+ Int /*initial*/log_fd, Int /*initial*/xml_fd);
+
+extern void VG_(print_preamble)(Bool logging_to_fd);
+
+extern void VG_(logging_atfork_child)(ThreadId tid);
+
/* Get the elapsed wallclock time since startup into buf which has size
bufsize. The function will assert if bufsize is not large enough.
Upon return, buf will contain the zero-terminated wallclock time as
Modified: trunk/coregrind/pub_core_options.h
==============================================================================
--- trunk/coregrind/pub_core_options.h (original)
+++ trunk/coregrind/pub_core_options.h Thu Jan 12 11:28:20 2017
@@ -39,6 +39,9 @@
#include "pub_tool_options.h"
#include "pub_core_xarray.h"
+/* Valgrind tool name. Defaults to "memcheck". */
+extern const HChar *VG_(clo_toolname);
+
/* Should we stop collecting errors if too many appear? default: YES */
extern Bool VG_(clo_error_limit);
/* Alternative exit code to hand to parent if errors were found.
@@ -117,9 +120,9 @@
extern Bool VG_(clo_child_silent_after_fork);
/* If the user specified --log-file=STR and/or --xml-file=STR, these
- hold STR after expansion of the %p and %q templates. */
-extern const HChar* VG_(clo_log_fname_expanded);
-extern const HChar* VG_(clo_xml_fname_expanded);
+ hold STR before expansion. */
+extern const HChar *VG_(clo_log_fname_unexpanded);
+extern const HChar *VG_(clo_xml_fname_unexpanded);
/* Add timestamps to log messages? default: NO */
extern Bool VG_(clo_time_stamp);
|
|
From: <sv...@va...> - 2017-01-12 11:21:16
|
Author: sewardj
Date: Thu Jan 12 11:21:08 2017
New Revision: 3290
Log:
Implement ARMv8 VSEL<c>.F64 d_d_d, VSEL<c>.F32 s_s_s.
Modified:
trunk/priv/guest_arm_toIR.c
Modified: trunk/priv/guest_arm_toIR.c
==============================================================================
--- trunk/priv/guest_arm_toIR.c (original)
+++ trunk/priv/guest_arm_toIR.c Thu Jan 12 11:21:08 2017
@@ -13462,6 +13462,54 @@
/* else fall through */
}
+ /* ----------- VSEL<c>.F64 d_d_d, VSEL<c>.F32 s_s_s ----------- */
+ /* 31 27 22 21 19 15 11 8 7 6 5 4 3
+ T1/A1: 1111 11100 D cc n d 101 1 N 0 M 0 m VSEL<c>.F64 Dd, Dn, Dm
+ T1/A1: 1111 11100 D cc n d 101 0 N 0 M 0 m VSEL<c>.F32 Sd, Sn, Sm
+
+ ARM encoding is in NV space.
+ In Thumb mode, we must not be in an IT block.
+ */
+ if (INSN(31,23) == BITS9(1,1,1,1,1,1,1,0,0) && INSN(11,9) == BITS3(1,0,1)
+ && INSN(6,6) == 0 && INSN(4,4) == 0) {
+ UInt bit_D = INSN(22,22);
+ UInt fld_cc = INSN(21,20);
+ UInt fld_n = INSN(19,16);
+ UInt fld_d = INSN(15,12);
+ Bool isF64 = INSN(8,8) == 1;
+ UInt bit_N = INSN(7,7);
+ UInt bit_M = INSN(5,5);
+ UInt fld_m = INSN(3,0);
+
+ UInt dd = isF64 ? ((bit_D << 4) | fld_d) : ((fld_d << 1) | bit_D);
+ UInt nn = isF64 ? ((bit_N << 4) | fld_n) : ((fld_n << 1) | bit_N);
+ UInt mm = isF64 ? ((bit_M << 4) | fld_m) : ((fld_m << 1) | bit_M);
+
+ UInt cc_1 = (fld_cc >> 1) & 1;
+ UInt cc_0 = (fld_cc >> 0) & 1;
+ UInt cond = (fld_cc << 2) | ((cc_1 ^ cc_0) << 1) | 0;
+
+ if (isT) {
+ gen_SIGILL_T_if_in_ITBlock(old_itstate, new_itstate);
+ }
+ /* In ARM mode, this is statically unconditional. In Thumb mode,
+ this must be dynamically unconditional, and we've SIGILLd if not.
+ In either case we can create unconditional IR. */
+
+ IRTemp guard = newTemp(Ity_I32);
+ assign(guard, mk_armg_calculate_condition(cond));
+ IRExpr* srcN = (isF64 ? llGetDReg : llGetFReg)(nn);
+ IRExpr* srcM = (isF64 ? llGetDReg : llGetFReg)(mm);
+ IRExpr* res = IRExpr_ITE(unop(Iop_32to1, mkexpr(guard)), srcN, srcM);
+ (isF64 ? llPutDReg : llPutFReg)(dd, res);
+
+ UChar rch = isF64 ? 'd' : 'f';
+ DIP("vsel%s.%s %c%u, %c%u, %c%u\n",
+ nCC(cond), isF64 ? "f64" : "f32", rch, dd, rch, nn, rch, mm);
+ return True;
+ }
+ /* fall through */
+
/* ---------- Doesn't match anything. ---------- */
return False;
|