test %al,%al // "if (return value of call is nonzero) { .."
je 7ed9e08 // "je after"
..
after:
That is, the && has been evaluated right-to-left. This is a correct
transformation if the compiler can prove that the call to |isRect| returns
|false| along any path on which it does not write its out-parameter
|&isClosed|.
In general, for the lazy-semantics (L->R) C-source-level && operator, we have
|A && B| == |B && A| if you can prove that |B| is |false| whenever A is
undefined. I assume that clang has some kind of interprocedural analysis that
tells it that. The compiler is further obliged to show that |B| won't trap,
since it is now being evaluated speculatively, but that's no big deal to
prove.
A similar result holds, per de Morgan, for transformations involving the C
language ||.
Memcheck correctly handles bitwise &&/|| in the presence of undefined inputs.
It has done so since the beginning. However, it assumes that every
conditional branch in the program is important -- any branch on uninitialised
data is an error. However, this idiom demonstrates otherwise. It defeats
Memcheck's existing &&/|| handling because the &&/|| is spread across two
basic blocks, rather than being bitwise.
This initial commit contains a complete initial implementation to fix that.
The basic idea is to detect the && condition spread across two blocks, and
transform it into a single block using bitwise &&. Then Memcheck's existing
accurate instrumentation of bitwise && will correctly handle it. The
transformation is
<contents of basic block A>
C1 = ...
if (!C1) goto after
.. falls through to ..
<contents of basic block B>
C2 = ...
if (!C2) goto after
.. falls through to ..
after:
===>
<contents of basic block A>
C1 = ...
<contents of basic block B, conditional on C1>
C2 = ...
if (!C1 && !C2) goto after
.. falls through to ..
after:
This assumes that <contents of basic block B> can be conditionalised, at the
IR level, so that the guest state is not modified if C1 is |false|. That's
not possible for all IRStmt kinds, but it is possible for a large enough
subset to make this transformation feasible.
There is no corresponding transformation that recovers an || condition,
because, per de Morgan, that merely corresponds to swapping the side exits vs
fallthoughs, and inverting the sense of the tests, and the pattern-recogniser
as implemented checks all possible combinations already.
The analysis and block-building is performed on the IR returned by the
architecture specific front ends. So they are almost not modified at all: in
fact they are simplified because all logic related to chasing through
unconditional and conditional branches has been removed from them, redone at
the IR level, and centralised.
The only file with big changes is the IRSB constructor logic,
guest_generic_bb_to_IR.c (a.k.a the "trace builder"). This is a complete
rewrite.
There is some additional work for the IR optimiser (ir_opt.c), since that
needs to do a quick initial simplification pass of the basic blocks, in order
to reduce the number of different IR variants that the trace-builder has to
pattern match on. An important followup task is to further reduce this cost.
There are two new IROps to support this: And1 and Or1, which both operate on
Ity_I1. They are regarded as evaluating both arguments, consistent with AndXX
and OrXX for all other sizes. It is possible to synthesise at the IR level by
widening the value to Ity_I8 or above, doing bitwise And/Or, and re-narrowing
it, but this gives inefficient code, so I chose to represent them directly.
The transformation appears to work for amd64-linux. In principle -- because
it operates entirely at the IR level -- it should work for all targets,
providing the initial pre-simplification pass can normalise the block ends
into the required form. That will no doubt require some tuning. And1 and Or1
will have to be implemented in all instruction selectors, but that's easy
enough.
Remaining FIXMEs in the code:
* Rename `expr_is_speculatable` et al to `expr_is_conditionalisable`. These
functions merely conditionalise code; the speculation has already been done
by gcc/clang.
* `expr_is_speculatable`: properly check that Iex_Unop/Binop don't contain
operatins that might trap (Div, Rem, etc).
* `analyse_block_end`: recognise all block ends, and abort on ones that can't
be recognised. Needed to ensure we don't miss any cases.
* maybe: guest_amd64_toIR.c: generate better code for And1/Or1
* ir_opt.c, do_iropt_BB: remove the initial flattening pass since presimp
will already have done it
* ir_opt.c, do_minimal_initial_iropt_BB (a.k.a. presimp). Make this as
cheap as possible. In particular, calling `cprop_BB_wrk` is total overkill
since we only need copy propagation.
* ir_opt.c: once the above is done, remove boolean parameter for `cprop_BB_wrk`.
sigprocmask should ignore HOW argument when SET is NULL.
Specific use case bug found in SysRes VG_(do_sys_sigprocmask).
Fix for case when ,,set,, parameter is NULL.
In this case ,,how,, parameter should be ignored because we are
only requesting from kernel to put current signal mask into ,,oldset,,.
But instead we determine the action based on ,,how,, parameter and
therefore make the system call fail when it should pass.
Taken from linux man pages (sigprocmask).
Andreas Arnez [Thu, 5 Dec 2019 17:22:43 +0000 (18:22 +0100)]
s390x: Fix offsets in comments to VexGuestS390XState
Each member of the structure declaration for `VexGuestS390XState' is
commented with its offset within the structure. But starting with
`guest_r0' and for all remaining members, these comments indicate the
wrong offsets, and the actual offsets are 8 bytes higher. Adjust the
comments accordingly.
Petar Jovanovic [Wed, 27 Nov 2019 12:22:46 +0000 (12:22 +0000)]
mips: enable sloppyXcheck for mips32 and mips64
Newer mips kernels (post 4.7.0) assign execute permissions to loadable
program segments which originally did not have them as per the
information provided in the elf file itself.
Include mips32/mips64 in the list of architectures for which the address
space manager should allow the kernel to report execute permissions in
sync_check_mapping_callback.
Petar Jovanovic [Thu, 14 Nov 2019 12:32:50 +0000 (12:32 +0000)]
mips64: upgrade parts of valgrind's fast cache for the n32 abi
Update the list of architectures to differentiate between the n32 and n64 abi
for mips64 when defining the fast cache macros in
coregrind/pub_core_transtab_asm.h.
Also amend the VG_(disp_cp_xindir) function in
coregrind/m_dispatch/dispatch-mips64-linux.S to use word-sized loads in case
of the n32 abi since the FastCacheSet structure members are now 4 bytes in
size for mips64 n32.
The estimate instructions (rcpss, rcpps, rsqrtps, rsqrtss) are, as the
name suggests, not expected to give a fully accurate result. They may
produce slighly different results on different CPU families because
their results are not defined by the IEEE standard. This is the
reason avx-1 test fails on amd now.
This patch assumes there are only two implementations, the intel and
amd one. It moves these estimate instructions out of avx-1 and into
their own testcase - avx_estimate_insn and creates two different .exp
files for intel and amd.
Repair --px-file-backed broken due to dynamic option change.
The commit 3a803036f7 (Allow the user to change a set of command line options
during execution) removed by mistake the code handling the option
--px-file-backed.
Add it back, and modify a trivialleak.vgtest to use the 'VEX registers'
options setting (and their synonym) to do a minimal verification that
the options and synonyms are accepted.
The options are specifying the default values, they should not influence
the result of the test.
Andreas Arnez [Wed, 23 Oct 2019 18:35:50 +0000 (20:35 +0200)]
callgrind_annotate, cg_annotate: don't truncate function names at '#'
C++ function names can contain substrings like "{lambda()#1}". But
callgrind_annotate and cg_annotate interpret the '#'-character as a
comment marker anywhere on each input line, and thus truncate such names
there.
On the other hand, the documentation in docs/cl-format.xml, states:
Everywhere, comments on own lines starting with '#' are allowed.
This seems to imply that a comment line must start with '#' in the first
column. Thus skip exactly such lines in the input file and don't handle
'#' as a comment marker anywhere else.
Signed-off-by: Philippe Waroquiers <philippe.waroquiers@skynet.be>
Have callgrind producing event: lines before events: line.
callgrind_annotate expects the 'events:' line to be the last line
of the header of a Part.
When event: lines are after the events: line, these event: lines are
handled by the calllgrind_annotate body line logic, that does not recognises
them and generates warnings such as:
WARNING: line 18 malformed, ignoring
line: 'event: sysTime : sysTime (elapsed ns)'
WARNING: line 19 malformed, ignoring
line: 'event: sysCpuTime : sysCpuTime (system cpu ns)'
- The command option --collect-systime has been enhanced to specify
the unit used to record the elapsed time spent during system calls.
The command option now accepts the values no|yes|msec|usec|nsec,
where yes is a synonym of msec. When giving the value nsec, the
system cpu time of system calls is also recorded.
Note that the nsec option is not supported on Darwin.
include/vki: fix vki_siginfo_t definition on amd64, arm64, and ppc64
As it turned out, the size of vki_siginfo_t is incorrect on these 64-bit
architectures:
(gdb) p sizeof(vki_siginfo_t)
$1 = 136
(gdb) ptype struct vki_siginfo
type = struct vki_siginfo {
int si_signo;
int si_errno;
int si_code;
union {
int _pad[29];
struct {...} _kill;
struct {...} _timer;
struct {...} _rt;
struct {...} _sigchld;
struct {...} _sigfault;
struct {...} _sigpoll;
} _sifields;
}
It looks like that for this architecture, __VKI_ARCH_SI_PREAMBLE_SIZE
hasn't been defined properly, which resulted in incorrect
VKI_SI_PAD_SIZE calculation (29 instead of 28).
This issue has been discovered with strace's "make check-valgrind-memcheck",
which produced false out-of-bounds writes on ptrace(PTRACE_GETSIGINFO) calls:
SYSCALL[24264,1](101) sys_ptrace ( 16898, 24283, 0x0, 0x606bd40 )
==24264== Syscall param ptrace(getsiginfo) points to unaddressable byte(s)
==24264== at 0x575C06E: ptrace (ptrace.c:45)
==24264== by 0x443244: next_event (strace.c:2431)
==24264== by 0x443D30: main (strace.c:2845)
==24264== Address 0x606bdc0 is 0 bytes after a block of size 144 alloc'd
(Note that the address passed is 0x606bd40 and the address reported is
0x606bdc0).
After the patch, no such errors observed.
* include/vki/vki-amd64-linux.h [__x86_64__ && __ILP32__]
(__vki_kernel_si_clock_t): New typedef.
[__x86_64__ && __ILP32__] (__VKI_ARCH_SI_CLOCK_T,
__VKI_ARCH_SI_ATTRIBUTES): New macros.
[__x86_64__ && !__ILP32__] (__VKI_ARCH_SI_PREAMBLE_SIZE): New macro,
define to 4 ints.
* include/vki/vki-arm64-linux.h (__VKI_ARCH_SI_PREAMBLE_SIZE): Likewise.
* include/vki/vki-ppc64-linux.h [__powerpc64__] (__VKI_ARCH_SI_PREAMBLE_SIZE):
Likewise.
* include/vki/vki-linux.h [!__VKI_ARCH_SI_CLOCK_T]
(__VKI_ARCH_SI_CLOCK_T): New macro, define to vki_clock_t.
[!__VKI_ARCH_SI_ATTRIBUTES] (__VKI_ARCH_SI_ATTRIBUTES): New macro,
define to nil.
(struct vki_siginfo): Use __VKI_ARCH_SI_CLOCK_T type for _utime and
_stime fields. Add __VKI_ARCH_SI_ATTRIBUTES.
Announce fix 411134 Allow the user to change a set of command line options during execution
Note that the fix for 411134 contains a bunch of white space only changes.
To see the diff without the white spaces, do:
git diff -w 3a803036^..3a803036
Allow the user to change a set of command line options during execution.
This patch changes the option parsing framework to allow a set of
core or tool (currently only memcheck) options to be changed dynamically.
Here is a summary of the new functionality (extracted from NEWS):
* It is now possible to dynamically change the value of many command
line options while your program (or its children) are running under
Valgrind.
To have the list of dynamically changeable options, run
valgrind --help-dyn-options
You can change the options from the shell by using vgdb to launch
the monitor command "v.clo <clo option>...".
The same monitor command can be used from a gdb connected
to the valgrind gdbserver.
Your program can also change the dynamically changeable options using
the client request VALGRIND_CLO_CHANGE(option).
Here is a brief description of the code changes.
* the command line options parsing macros are now checking a 'parsing' mode
to decide if the given option must be handled or not.
(more about the parsing mode below).
* the 'main' command option parsing code has been split in a function
'process_option' that can be called now by:
- early_process_cmd_line_options
(looping over args, calling process_option in mode "Early")
- main_process_cmd_line_options
(looping over args, calling process_option in mode "Processing")
- the new function VG_(process_dynamic_option) called from
gdbserver or from VALGRIND_CLO_CHANGE (calling
process_option in mode "Dynamic" or "Help")
* So, now, during startup, process_option is called twice for each arg:
- once during Early phase
- once during normal Processing
Then process_option can then be called again during execution.
So, the parsing mode is defined so that the option parsing code
behaves differently (e.g. allows or not to handle the option)
depending on the mode.
// Command line option parsing happens in the following modes:
// cloE : Early processing, used by coregrind m_main.c to parse the
// command line options that must be handled early on.
// cloP : Processing, used by coregrind and tools during startup, when
// doing command line options Processing.
// clodD : Dynamic, used to dynamically change options after startup.
// A subset of the command line options can be changed dynamically
// after startup.
// cloH : Help, special mode to produce the list of dynamically changeable
// options for --help-dyn-options.
typedef
enum {
cloE = 1,
cloP = 2,
cloD = 4,
cloH = 8
} Clo_Mode;
The option parsing macros in pub_tool_options.h have now all a new variant
*_CLOM with the mode(s) in which the given option is accepted.
The old variant is kept and calls the new variant with mode cloP.
The function VG_(check_clom) in the macro compares the current mode
with the modes allowed for the option, and returns True if qq_arg
should be further processed.
For example:
// String argument, eg. --foo=yes or --foo=no
(VG_(check_clom) \
(qq_mode, qq_arg, qq_option, \
VG_STREQN(VG_(strlen)(qq_option)+1, qq_arg, qq_option"=")) && \
({const HChar* val = &(qq_arg)[ VG_(strlen)(qq_option)+1 ]; \
if VG_STREQ(val, "yes") (qq_var) = True; \
else if VG_STREQ(val, "no") (qq_var) = False; \
else VG_(fmsg_bad_option)(qq_arg, "Invalid boolean value '%s'" \
" (should be 'yes' or 'no')\n", val); \
True; }))
VG_BOOL_CLOM(cloP, qq_arg, qq_option, qq_var)
To make an option dynamically excutable, it is typically enough to replace
VG_BOOL_CLO(...)
by
VG_BOOL_CLOM(cloPD, ...)
For example:
- else if VG_BOOL_CLO(arg, "--show-possibly-lost", tmp_show) {
+ else if VG_BOOL_CLOM(cloPD, arg, "--show-possibly-lost", tmp_show) {
cloPD means the option value is set/changed during the main command
Processing (P) and Dynamically during execution (D).
Note that the 'body/further processing' of a command is only executed when
the option is recognised and the current parsing mode is ok for this option.
Mark Wielaard [Fri, 23 Aug 2019 20:17:57 +0000 (22:17 +0200)]
arm64 fixup for statx support on older kernels
Turns out (older) arm64 linux kernels don't have statx, but also not
stat64 and no stat syscalls. It uses fstatat instead. The new statx
patch also added a check for stat. So That needs a special case for
arm64.
Petar Jovanovic [Wed, 21 Aug 2019 16:08:42 +0000 (16:08 +0000)]
mips: Add nanoMIPS support to Valgrind 1/4
Necessary changes to support nanoMIPS on Linux.
Part 1/4 - VEX changes
Patch by Aleksandar Rikalo, Dimitrije Nikolic, Tamara Vlahovic and
Aleksandra Karadzic.
nanoMIPS architecture in brief
Designed for embedded devices, nanoMIPS is a variable lengths instruction
set architecture (ISA) offering high performance in substantially reduced
code size.
The nanoMIPS ISA combines recoded and new 16-, 32-, and 48-bit instructions
to achieve an ideal balance of performance and code density.
It incorporates all MIPS32 instructions and architecture modules including
MIPS DSP and MIPS MT, as well as new instructions for advanced code size
reduction.
nanoMIPS is supported in release 6 of the MIPS architecture. It is first
implemented in the new MIPS I7200 multi-threaded multi-core processor
series. Compiler support is included in the MIPS GNU-based development
tools.
Fix compilation problem when __NR_preadv2 __NR_pwritev2 are undefined
check_preadv2_pwritev2.c: In function ‘main’:
check_preadv2_pwritev2.c:12:12: error: ‘__NR_preadv2’ undeclared (first use in this function)
syscall(__NR_preadv2, 0, NULL, 0, 0, 0);
^
check_preadv2_pwritev2.c:12:12: note: each undeclared identifier is reported only once for each function it appears in
check_preadv2_pwritev2.c:15:12: error: ‘__NR_pwritev2’ undeclared (first use in this function)
syscall(__NR_pwritev2, 0, NULL, 0, 0, 0);
Petar Jovanovic [Fri, 16 Aug 2019 15:57:50 +0000 (15:57 +0000)]
Use statx rather than other stat system calls
*STAT* system calls other than statx are becoming deprecated.
Coregrind should use statx as the first candidate in order to achieve
"stat" functionality.
There are also systems that do not even support older "stats".
Petar Jovanovic [Tue, 13 Aug 2019 14:51:37 +0000 (14:51 +0000)]
make pth_self_kill_15_other test deterministic
Modify the pth_self_kill_15_other test to make its behaviour deterministic
by introducing a pthread_join call. Do so by modifying the signal handler
for SIGTERM for the spawned thread which would issue the pthread_join call
prior to exiting.
Petar Jovanovic [Tue, 13 Aug 2019 12:19:30 +0000 (12:19 +0000)]
mips: pass 7th argument in syscalls
Only arg1 to arg6 have been passed down to kernel for syscalls.
This patch ensures that arg7 is also passed down for syscalls.
In addition to this, ensure that we have 16-byte aligned stack during
mips64 syscall.
Along with the change for sync_file_range, this will fix sync_file_range01
failure within LTP test suite.
Andreas Arnez [Tue, 6 Aug 2019 16:29:46 +0000 (18:29 +0200)]
s390x: Fix vector facility (vx) check in test suite
When checking the prereqisuites of running a vector test case, it is not
sufficient to check for the appropriate CPU facility bit. It must also be
verified that the kernel and hypervisor(s) have actually enabled the
vector facility. There are various ways of checking this. E.g., we could
try executing a vector instruction and handle any signals. Or we can
check the HWCAP for the appropriate bit. This patch does the latter.
Fix 409141 and 409367: valgrind hangs or loops when a process sends a signal to itself.
The loop scenario:
The main thread sends a signal 15 to another thread, and then calls the exit syscall.
The exit syscall done by thread 1 marks all threads as needing
to die using exitreason VgSrc_ExitProcess.
The main thread then gets all other threads out of their blocking syscall
to let them die, and then "busy polls" for all other threads to disappear.
However, when the second thread is out of its syscall, it gets the signal 15,
which is a fatal signal. This second thread then changes the exit reason
of all threads to VgSrc_FatalSig, and itself starts to busy poll for all
other threads to disappear.
This then loops forever.
The fix for this consists in not handling the fatal signal in the
second thread when the process is already busy dying. Effectively,
the exit syscall should be processed "atomically": either the process
is running, or it is dead once the syscall is done.
Under valgrind, when threads are marked as being ' VgSrc_ExitProcess',
the guest process should be considered as dead. Valgrind has still to do
the cleanup, the endof run report, etc but otherwise should not let
any more user code to run. So, signal should not be handled anymore
once the 'exit syscall' has marked all threads as VgSrc_ExitProcess.
The hang scenario:
The main thread sends a signal 9 (KILL) to itself.
When running natively, this directly kills the process,
without giving any opportunity to run some user code.
Valgrind intercepts the kill syscall, and detects that this is
a fatal signal. The main thread was then dying, but was
not getting the other threads out of their syscall (to let them die).
The fix for this is to have the 'handling' of the signal 9 sent to a
thread of the process to directly make the process die, by getting
all threads out of syscall.
Note that the previous code was trying to have this action done by
the thread to which the signal 9 was sent. This was too tricky to
keep (causing other race conditions between the main thread sending
the signal 9 e.g. exiting and the other thread supposed to die).
As it is not particularly critical to have the signal 9 'handled'
by a specific thread, the thread that is sending the signal 9 is
the one doing the work to cleanup and terminate the process.
Support for amd64, x86 - 64 and 32 bit, arm64, ppc64, ppc64le,
s390x, mips64. This should work identically on all
arches, tested on x86 32bit and 64bit one, but enabled on all.
Refactor the code to be reusable between old/new syscalls. Resolve TODO
items in the code. Add the testcase for the preadv2/pwritev2 and also
add the (similar) testcase for the older preadv/pwritev syscalls.
Trying to test handling an uninitialized flag argument for the v2 syscalls
does not work because the flag always comes out as defined zero.
Turns out glibc does this deliberately on 64bit architectures because
the kernel does actually have a low_offset and high_offset argument, but
ignores the high_offset/assumes it is zero.
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=601cc11d054ae4b5e9b5babec3d8e4667a2cb9b5
Introduce new header files for the system call numbers that are shared
across all Linux architectures and also for the system call numbers that
are shared across all 32-bit architectures.
Replace 'error' by 'warning' when a signal cannot be translated to the gdb nr.
As 'error' is supposed to be called only to go back at gdbserver toplevel,
and such signal translations can be called during tracing, when
gdbserver is not active : 'error' then tries to longjmp using a
not initialised longjmp buffer.
(reproduced by activating the trace with the test case attached in
bug 409141 - Valgrind hangs when SIGKILLed).
Andreas Arnez [Tue, 14 May 2019 15:19:34 +0000 (17:19 +0200)]
s390x: Clean up s390-check-opcodes.pl
Fix false positives when invoking s390-check-opcodes.pl. Also clean up
some code formatting issues in that script. Add the instructions TPEI and
IRBM to guest_s390_toIR.c and s390-opcodes.csv, so they are not longer
warned about.
Andreas Arnez [Tue, 2 Oct 2018 11:47:50 +0000 (13:47 +0200)]
s390x: Add models "z14" and "z14 ZR1"
Add IBM z14 and IBM z14 ZR1 to the list of known machine models. Add an
expected output variant for z14 to the s390x-specific "ecag" test case.
In README.s390, refer to a current version of the z/Architecture
Principles of Operation that describes the instructions introduced with
IBM z14.
Mark Wielaard [Wed, 29 May 2019 22:29:58 +0000 (00:29 +0200)]
linux x86 and amd64 memory protection key syscalls.
This implements minimal support for the pkey_alloc, pkey_free and
pkey_mprotect syscalls. pkey_alloc will simply indicate that pkeys
are not supported. pkey_free always fails. pkey_mprotect works just
like mprotect if the special pkey -1 is provided.