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
(1) |
|
2
|
3
(6) |
4
(5) |
5
|
6
(2) |
7
(1) |
8
|
|
9
|
10
(4) |
11
(2) |
12
(2) |
13
(3) |
14
(1) |
15
|
|
16
(4) |
17
|
18
(3) |
19
(3) |
20
(3) |
21
|
22
|
|
23
(1) |
24
(10) |
25
(13) |
26
(6) |
27
(2) |
28
(3) |
29
(5) |
|
30
(6) |
|
|
|
|
|
|
|
From: zboom <net...@fo...> - 2017-04-19 01:50:51
|
Thanks for your reply! This problem occurred when I was running OpenSwitch (http://www.openswitch.net/) on my embedded system. As you know, the OpenSwitch use OVS (http://www.openvswitch.org/) as its control-plane. And It have much more configurations than OVS. For example, there are more than one hundred interfaces. When the ovsdb-client monitored this kind of messages, the ovsdb-server will return a huge JSON message (about 24KB). This huge message could cause the EAGAIN for several times, and then the ovsdb-server would be coredumped. Because there were two recursive functions, first I doubted the stack was overflowed. But I have confirmed with the ovs-dev group, and have counted the recursive depth. The result I got was safe for the stack size. The following are two typical call trace, and the ovsdb-server program coredumped at very different place every time. 1. Program terminated with signal SIGSEGV, Segmentation fault. #0 0x000000fff464a154 in hmap_remove (node=0xfff36e89c0, hmap=0xfff36313c0) at /usr/src/debug/ops-openvswitch/git999-r0/lib/hmap.h:245 245 /usr/src/debug/ops-openvswitch/git999-r0/lib/hmap.h: No such file or directory. (gdb) bt #0 0x000000fff464a154 in hmap_remove (node=0xfff36e89c0, hmap=0xfff36313c0) at /usr/src/debug/ops-openvswitch/git999-r0/lib/hmap.h:245 #1 shash_steal (sh=0xfff36313c0, node=0xfff36e89c0) at /usr/src/debug/ops-openvswitch/git999-r0/lib/shash.c:187 #2 0x000000fff464a1cc in shash_delete (sh=<optimized out>, node=<optimized out>) at /usr/src/debug/ops-openvswitch/git999-r0/lib/shash.c:176 #3 0x000000fff463ae34 in json_destroy_object (object=0xfff36313c0) at /usr/src/debug/ops-openvswitch/git999-r0/lib/json.c:386 #4 json_destroy (json=0xfff36313a0) at /usr/src/debug/ops-openvswitch/git999-r0/lib/json.c:352 #5 0x000000fff463ae24 in json_destroy_object (object=0xfff38e9420) at /usr/src/debug/ops-openvswitch/git999-r0/lib/json.c:385 #6 json_destroy (json=0xfff38e9400) at /usr/src/debug/ops-openvswitch/git999-r0/lib/json.c:352 #7 0x000000fff463ae24 in json_destroy_object (object=0xfff38cd600) at /usr/src/debug/ops-openvswitch/git999-r0/lib/json.c:385 #8 json_destroy (json=0xfff38cd620) at /usr/src/debug/ops-openvswitch/git999-r0/lib/json.c:352 #9 0x000000fff465e100 in jsonrpc_send (rpc=0xfff3832680, msg=<optimized out>) at /usr/src/debug/ops-openvswitch/git999-r0/lib/jsonrpc.c:261 #10 0x000000fff465ed30 in jsonrpc_session_send (s=<optimized out>, msg=<optimized out>) at /usr/src/debug/ops-openvswitch/git999-r0/lib/jsonrpc.c:1029 #11 0x000000fff43ee87c in ovsdb_jsonrpc_session_send (s=s@entry=0xfff3619e00, msg=0xfff36dd170) at /usr/src/debug/ops-openvswitch/git999-r0/ovsdb/jsonrpc-server.c:1290 #12 0x000000fff43f2ac4 in ovsdb_jsonrpc_session_got_request (request=0xfff381cbd0, s=<optimized out>) at /usr/src/debug/ops-openvswitch/git999-r0/ovsdb/jsonrpc-server.c:1256 #13 ovsdb_jsonrpc_session_run (s=<optimized out>) at /usr/src/debug/ops-openvswitch/git999-r0/ovsdb/jsonrpc-server.c:523 #14 ovsdb_jsonrpc_session_run_all (remote=<optimized out>) at /usr/src/debug/ops-openvswitch/git999-r0/ovsdb/jsonrpc-server.c:562 #15 ovsdb_jsonrpc_server_run (svr=0x0) at /usr/src/debug/ops-openvswitch/git999-r0/ovsdb/jsonrpc-server.c:366 #16 0x0000000120005d60 in main_loop (exiting=0xffdfaaf8d0, run_process=0x0, remotes=0xffdfaaf888, unixctl=0x12010e4a0, all_dbs=0xffdfaaf818, jsonrpc=0x0) at /usr/src/debug/ops-openvswitch/git999-r0/ovsdb/ovsdb-server.c:161 #17 main (argc=1, argv=0x12fc19e90) at /usr/src/debug/ops-openvswitch/git999-r0/ovsdb/ovsdb-server.c:357 (gdb) bt #0 json_serialize (json=0x3fd28f747, s=s@entry=0xffdfecf5a0) at /usr/src/debug/ops-openvswitch/git999-r0/lib/json.c:1499 #1 0x000000ffe999a024 in json_serialize_array (s=0xffdfecf5a0, array=0xffe8818ec8) at /usr/src/debug/ops-openvswitch/git999-r0/lib/json.c:1617 #2 json_serialize (json=0xffe8818ec0, s=s@entry=0xffdfecf5a0) at /usr/src/debug/ops-openvswitch/git999-r0/lib/json.c:1517 #3 0x000000ffe9999c80 in json_serialize_object_member (i=i@entry=0, node=node@entry=0xffe8818d60, s=s@entry=0xffdfecf5a0) at /usr/src/debug/ops-openvswitch/git999-r0/lib/json.c:1563 #4 0x000000ffe9999e60 in json_serialize_object (s=0xffdfecf5a0, object=0xffe8818de0) at /usr/src/debug/ops-openvswitch/git999-r0/lib/json.c:1592 #5 json_serialize (json=<optimized out>, s=s@entry=0xffdfecf5a0) at /usr/src/debug/ops-openvswitch/git999-r0/lib/json.c:1513 #6 0x000000ffe999d210 in json_to_ds (json=<optimized out>, flags=<optimized out>, ds=<optimized out>) at /usr/src/debug/ops-openvswitch/git999-r0/lib/json.c:1491 #7 0x000000ffe99bde70 in jsonrpc_send (rpc=0xffe8c32680, msg=<optimized out>) at /usr/src/debug/ops-openvswitch/git999-r0/lib/jsonrpc.c:252 #8 0x000000ffe99be9a8 in jsonrpc_session_send (s=<optimized out>, msg=<optimized out>) at /usr/src/debug/ops-openvswitch/git999-r0/lib/jsonrpc.c:1013 #9 0x000000ffe974e87c in ovsdb_jsonrpc_session_send (s=s@entry=0xffe89b8600, msg=0xffe8a85060) at /usr/src/debug/ops-openvswitch/git999-r0/ovsdb/jsonrpc-server.c:1290 #10 0x000000ffe9752ac4 in ovsdb_jsonrpc_session_got_request (request=0xffe8a85150, s=<optimized out>) at /usr/src/debug/ops-openvswitch/git999-r0/ovsdb/jsonrpc-server.c:1256 #11 ovsdb_jsonrpc_session_run (s=<optimized out>) at /usr/src/debug/ops-openvswitch/git999-r0/ovsdb/jsonrpc-server.c:523 #12 ovsdb_jsonrpc_session_run_all (remote=<optimized out>) at /usr/src/debug/ops-openvswitch/git999-r0/ovsdb/jsonrpc-server.c:562 #13 ovsdb_jsonrpc_server_run (svr=0x0) at /usr/src/debug/ops-openvswitch/git999-r0/ovsdb/jsonrpc-server.c:366 #14 0x0000000120005d3c in main_loop (exiting=0xffdfecf8b0, run_process=0x0, remotes=0xffdfecf868, unixctl=0x12010e4a0, all_dbs=0xffdfecf7f8, jsonrpc=0x0) at /usr/src/debug/ops-openvswitch/git999-r0/ovsdb/ovsdb-server.c:161 #15 main (argc=1, argv=0x12cf24060) at /usr/src/debug/ops-openvswitch/git999-r0/ovsdb/ovsdb-server.c:357 -- View this message in context: http://valgrind.10908.n7.nabble.com/Are-there-some-protective-mechanisms-of-valgrind-on-MIPS64-especially-on-Cavium-OCTEON3-tp57593p57596.html Sent from the Valgrind - Dev mailing list archive at Nabble.com. |
|
From: Petar J. <mip...@gm...> - 2017-04-18 15:53:06
|
On Sun, Apr 16, 2017 at 10:38 AM, Philippe Waroquiers <phi...@sk...> wrote: > On Fri, 2017-04-14 at 07:27 +0200, Ivo Raisr wrote: >> This revision seems to have caused regression on some of the supported >> architectures. >> I've seen it in all nightly test results so far. >> +No symbol "heuristic" in current context. > > Should be fixed with revision Committed revision 16305 > (but only tested on amd64. It should still work on mips platforms) > I was under (obviously very wrong) impression this GDB command is common for all targets. Thanks for the fix. Petar |
|
From: Petar J. <mip...@gm...> - 2017-04-18 11:00:42
|
On Tue, Apr 18, 2017 at 11:21 AM, 网络尖兵 <net...@fo...> wrote: > Hello everyone, > I am trying to use valgrind's memchek tool to find out a segment fault > problem. The user space program was coredumped every time when it was > running without valgrind. But when it was running with valgrind, very > strangely, it was not coredumped! Then I wrote a script to give some > pressure to the program, and it run smoothly for several hours. > > So I am confusing and writing this mail to find out if there are some > protective mechanisms of valgrind on MIPS64, especially on Cavium OCTEON3? > Can you share some information about the actual segfault (when running without Valgrind)? What is causing the failure? |
|
From: 网. <net...@fo...> - 2017-04-18 09:21:46
|
Hello everyone, I am trying to use valgrind's memchek tool to find out a segment fault problem. The user space program was coredumped every time when it was running without valgrind. But when it was running with valgrind, very strangely, it was not coredumped! Then I wrote a script to give some pressure to the program, and it run smoothly for several hours. So I am confusing and writing this mail to find out if there are some protective mechanisms of valgrind on MIPS64, especially on Cavium OCTEON3? |
|
From: <sv...@va...> - 2017-04-16 20:46:15
|
Author: iraisr
Date: Sun Apr 16 21:46:05 2017
New Revision: 3350
Log:
Refactor register allocator to work on HInstrVec.
At this point, 'none' and 'memcheck' tests pass as in the baseline.
Modified:
branches/VEX_JIT_HACKS/priv/host_generic_reg_alloc2.c
Modified: branches/VEX_JIT_HACKS/priv/host_generic_reg_alloc2.c
==============================================================================
--- branches/VEX_JIT_HACKS/priv/host_generic_reg_alloc2.c (original)
+++ branches/VEX_JIT_HACKS/priv/host_generic_reg_alloc2.c Sun Apr 16 21:46:05 2017
@@ -140,8 +140,8 @@
#define INVALID_RREG_NO ((Short)(-1))
-#define IS_VALID_VREGNO(_zz) ((_zz) >= 0 && (_zz) < n_vregs)
-#define IS_VALID_RREGNO(_zz) ((_zz) >= 0 && (_zz) < n_rregs)
+#define IS_VALID_VREGNO(_zz) ((_zz) >= 0 && (_zz) < state->n_vregs)
+#define IS_VALID_RREGNO(_zz) ((_zz) >= 0 && (_zz) < state->n_rregs)
/* Search forward from some given point in the incoming instruction
@@ -155,7 +155,7 @@
considered.
To do this we don't actually need to see the incoming instruction
- stream. Rather, what we need us the HRegUsage records for the
+ stream. Rather, what we need is the HRegUsage records for the
incoming instruction stream. Hence that is passed in.
Returns an index into the state array indicating the (v,r) pair to
@@ -205,21 +205,20 @@
/* Double the size of the real-reg live-range array, if needed. */
__attribute__((noinline))
-static void ensureRRLRspace_SLOW ( RRegLR** info, Int* size, Int used )
+static void ensureRRLRspace_SLOW(RRegLR** info, UInt* size, UInt used)
{
- Int k;
RRegLR* arr2;
if (0)
- vex_printf("ensureRRISpace: %d -> %d\n", *size, 2 * *size);
+ vex_printf("ensureRRLRspace: %u -> %u\n", *size, 2 * *size);
vassert(used == *size);
arr2 = LibVEX_Alloc_inline(2 * *size * sizeof(RRegLR));
- for (k = 0; k < *size; k++)
+ for (UInt k = 0; k < *size; k++)
arr2[k] = (*info)[k];
*size *= 2;
*info = arr2;
}
inline
-static void ensureRRLRspace ( RRegLR** info, Int* size, Int used )
+static void ensureRRLRspace(RRegLR** info, UInt* size, UInt used)
{
if (LIKELY(used < *size)) return;
ensureRRLRspace_SLOW(info, size, used);
@@ -229,7 +228,7 @@
/* Sort an array of RRegLR entries by either the .live_after or
.dead_before fields. This is performance-critical. */
static void sortRRLRarray ( RRegLR* arr,
- Int size, Bool by_live_after )
+ UInt size, Bool by_live_after )
{
Int incs[14] = { 1, 4, 13, 40, 121, 364, 1093, 3280,
9841, 29524, 88573, 265720,
@@ -336,203 +335,142 @@
# undef IS_4_ALIGNED
}
+#define N_SPILL64S (LibVEX_N_SPILL_BYTES / 8)
+STATIC_ASSERT((N_SPILL64S % 2) == 0);
-/* A target-independent register allocator. Requires various
- functions which it uses to deal abstractly with instructions and
- registers, since it cannot have any target-specific knowledge.
-
- Returns a new list of instructions, which, as a result of the
- behaviour of mapRegs, will be in-place modifications of the
- original instructions.
+/* Register allocator state. Keeps all vital information at one place. */
+typedef
+ struct {
+ /* The real-register universe to use. This contains facts about
+ real registers, one of which is the set of registers available
+ for allocation. */
+ const RRegUniverse* univ;
+
+ /* Info on vregs. Computed once and remains unchanged. */
+ UInt n_vregs;
+ VRegLR* vreg_lrs; /* [0 .. n_vregs-1] */
+
+ /* Used when constructing vreg_lrs (for allocating stack slots). */
+ Short ss_busy_until_before[N_SPILL64S];
+
+ /* We keep two copies of the real-reg live range info, one sorted
+ by .live_after and the other by .dead_before. First the unsorted info
+ is created in the _la variant is copied into the _db variant. Once
+ that's done both of them are sorted. We also need two integer cursors
+ which record the next location in the two arrays to consider. */
+ RRegLR* rreg_lrs_la;
+ RRegLR* rreg_lrs_db;
+ UInt rreg_lrs_size;
+ UInt rreg_lrs_used;
+ UInt rreg_lrs_la_next;
+ UInt rreg_lrs_db_next;
+
+ /* Info on register usage in the incoming HInstrVec.
+ Computed once and remains unchanged, more or less; updated
+ sometimes by the direct-reload optimisation. */
+ HRegUsage* reg_usage_arr; /* [0 .. instrs_in->insns_used-1] */
+
+ /* Used when constructing rreg_lrs. */
+ UInt* rreg_live_after;
+ UInt* rreg_dead_before;
+
+ /* Running state of the core allocation algorithm. */
+ RRegState* rreg_state; /* [0 .. n_rregs-1] */
+ UInt n_rregs;
+
+ /* .. and the redundant backward map */
+ /* Each value is 0 .. n_rregs-1 or is INVALID_RREG_NO.
+ This inplies n_rregs must be <= 32768. */
+ Short* vreg_state; /* [0 .. n_vregs-1] */
+
+ /* Return True iff the given insn is a reg-reg move, in which
+ case also return the src and dst regs. */
+ Bool (*isMove)(const HInstr*, HReg*, HReg*);
+
+ /* Get info about register usage in this insn. */
+ void (*getRegUsage)(HRegUsage*, const HInstr*, Bool);
+
+ /* Apply a reg-reg mapping to an insn. */
+ void (*mapRegs)(HRegRemap*, HInstr*, Bool);
+
+ /* Is this instruction actually HInstrIfThenElse? */
+ HInstrIfThenElse* (*isIfThenElse)(const HInstr*);
+
+ /* Return one, or, if we're unlucky, two insn(s) to spill/restore a
+ real reg to a spill slot byte offset. The two leading HInstr**
+ args are out parameters, through which the generated insns are
+ returned. Also (optionally) a 'directReload' function, which
+ attempts to replace a given instruction by one which reads
+ directly from a specified spill slot. May be NULL, in which
+ case the optimisation is not attempted. */
+ void (*genSpill)( HInstr**, HInstr**, HReg, Int, Bool);
+ void (*genReload)( HInstr**, HInstr**, HReg, Int, Bool);
+ HInstr* (*directReload)( HInstr*, HReg, Short);
+ UInt guest_sizeB;
+
+ /* For debug printing only. */
+ void (*ppInstr)(const HInstr*, Bool);
+ void (*ppReg)(HReg);
- Requires that the incoming code has been generated using
- vreg numbers 0, 1 .. n_vregs-1. Appearance of a vreg outside
- that range is a checked run-time error.
-
- Takes an expandable array of pointers to unallocated insns.
- Returns an expandable array of pointers to allocated insns.
-*/
-HInstrArray* doRegisterAllocation (
-
- /* Incoming virtual-registerised code. */
- HInstrArray* instrs_in,
-
- /* The real-register universe to use. This contains facts about
- real registers, one of which is the set of registers available
- for allocation. */
- const RRegUniverse* univ,
-
- /* Return True iff the given insn is a reg-reg move, in which
- case also return the src and dst regs. */
- Bool (*isMove) ( const HInstr*, HReg*, HReg* ),
-
- /* Get info about register usage in this insn. */
- void (*getRegUsage) ( HRegUsage*, const HInstr*, Bool ),
-
- /* Apply a reg-reg mapping to an insn. */
- void (*mapRegs) ( HRegRemap*, HInstr*, Bool ),
+ /* 32/64bit mode */
+ Bool mode64;
+ }
+ RegAllocState;
- /* Return one, or, if we're unlucky, two insn(s) to spill/restore a
- real reg to a spill slot byte offset. The two leading HInstr**
- args are out parameters, through which the generated insns are
- returned. Also (optionally) a 'directReload' function, which
- attempts to replace a given instruction by one which reads
- directly from a specified spill slot. May be NULL, in which
- case the optimisation is not attempted. */
- void (*genSpill) ( HInstr**, HInstr**, HReg, Int, Bool ),
- void (*genReload) ( HInstr**, HInstr**, HReg, Int, Bool ),
- HInstr* (*directReload) ( HInstr*, HReg, Short ),
- Int guest_sizeB,
+#define INVALID_INSTRNO (-2)
- /* For debug printing only. */
- void (*ppInstr) ( const HInstr*, Bool ),
- void (*ppReg) ( HReg ),
-
- /* 32/64bit mode */
- Bool mode64
-)
+static void initRegAllocState(RegAllocState* state, const RRegUniverse* univ,
+ Bool (*isMove)(const HInstr*, HReg*, HReg*),
+ void (*getRegUsage)(HRegUsage*, const HInstr*, Bool),
+ void (*mapRegs)(HRegRemap*, HInstr*, Bool),
+ HInstrIfThenElse* (*isIfThenElse)(const HInstr*),
+ void (*genSpill)( HInstr**, HInstr**, HReg, Int, Bool),
+ void (*genReload)( HInstr**, HInstr**, HReg, Int, Bool),
+ HInstr* (*directReload)( HInstr*, HReg, Short),
+ UInt guest_sizeB,
+ void (*ppInstr)(const HInstr*, Bool), void (*ppReg)(HReg),
+ Bool mode64, const HInstrVec* instrs_in, UInt n_vregs)
{
-# define N_SPILL64S (LibVEX_N_SPILL_BYTES / 8)
-
- const Bool eq_spill_opt = True;
-
- /* Info on vregs and rregs. Computed once and remains
- unchanged. */
- Int n_vregs;
- VRegLR* vreg_lrs; /* [0 .. n_vregs-1] */
-
- /* We keep two copies of the real-reg live range info, one sorted
- by .live_after and the other by .dead_before. First the
- unsorted info is created in the _la variant is copied into the
- _db variant. Once that's done both of them are sorted.
- We also need two integer cursors which record the next
- location in the two arrays to consider. */
- RRegLR* rreg_lrs_la;
- RRegLR* rreg_lrs_db;
- Int rreg_lrs_size;
- Int rreg_lrs_used;
- Int rreg_lrs_la_next;
- Int rreg_lrs_db_next;
-
- /* Info on register usage in the incoming instruction array.
- Computed once and remains unchanged, more or less; updated
- sometimes by the direct-reload optimisation. */
- HRegUsage* reg_usage_arr; /* [0 .. instrs_in->arr_used-1] */
-
- /* Used when constructing vreg_lrs (for allocating stack
- slots). */
- Short ss_busy_until_before[N_SPILL64S];
-
- /* Used when constructing rreg_lrs. */
- Int* rreg_live_after;
- Int* rreg_dead_before;
-
- /* Running state of the core allocation algorithm. */
- RRegState* rreg_state; /* [0 .. n_rregs-1] */
- Int n_rregs;
-
- /* .. and the redundant backward map */
- /* Each value is 0 .. n_rregs-1 or is INVALID_RREG_NO.
- This inplies n_rregs must be <= 32768. */
- Short* vreg_state; /* [0 .. n_vregs-1] */
-
- /* The vreg -> rreg map constructed and then applied to each
- instr. */
- HRegRemap remap;
-
- /* The output array of instructions. */
- HInstrArray* instrs_out;
-
- /* Sanity checks are expensive. They are only done periodically,
- not at each insn processed. */
- Bool do_sanity_check;
-
- vassert(0 == (guest_sizeB % LibVEX_GUEST_STATE_ALIGN));
- vassert(0 == (LibVEX_N_SPILL_BYTES % LibVEX_GUEST_STATE_ALIGN));
- vassert(0 == (N_SPILL64S % 2));
-
- /* The live range numbers are signed shorts, and so limiting the
- number of insns to 15000 comfortably guards against them
- overflowing 32k. */
- vassert(instrs_in->arr_used <= 15000);
-
-# define INVALID_INSTRNO (-2)
-
-# define EMIT_INSTR(_instr) \
- do { \
- HInstr* _tmp = (_instr); \
- if (DEBUG_REGALLOC) { \
- vex_printf("** "); \
- (*ppInstr)(_tmp, mode64); \
- vex_printf("\n\n"); \
- } \
- addHInstr ( instrs_out, _tmp ); \
- } while (0)
-
-# define PRINT_STATE \
- do { \
- Int z, q; \
- for (z = 0; z < n_rregs; z++) { \
- vex_printf(" rreg_state[%2d] = ", z); \
- (*ppReg)(univ->regs[z]); \
- vex_printf(" \t"); \
- switch (rreg_state[z].disp) { \
- case Free: vex_printf("Free\n"); break; \
- case Unavail: vex_printf("Unavail\n"); break; \
- case Bound: vex_printf("BoundTo "); \
- (*ppReg)(rreg_state[z].vreg); \
- vex_printf("\n"); break; \
- } \
- } \
- vex_printf("\n vreg_state[0 .. %d]:\n ", n_vregs-1); \
- q = 0; \
- for (z = 0; z < n_vregs; z++) { \
- if (vreg_state[z] == INVALID_RREG_NO) \
- continue; \
- vex_printf("[%d] -> %d ", z, vreg_state[z]); \
- q++; \
- if (q > 0 && (q % 6) == 0) \
- vex_printf("\n "); \
- } \
- vex_printf("\n"); \
- } while (0)
-
-
- /* --------- Stage 0: set up output array --------- */
- /* --------- and allocate/initialise running state. --------- */
+ /* Initialize Register Allocator state. */
+ state->univ = univ;
+ state->isMove = isMove;
+ state->getRegUsage = getRegUsage;
+ state->mapRegs = mapRegs;
+ state->isIfThenElse = isIfThenElse;
+ state->genSpill = genSpill;
+ state->genReload = genReload;
+ state->directReload = directReload;
+ state->guest_sizeB = guest_sizeB;
+ state->ppInstr = ppInstr;
+ state->ppReg = ppReg;
+ state->mode64 = mode64;
- instrs_out = newHInstrArray();
-
- /* ... and initialise running state. */
/* n_rregs is no more than a short name for n_available_real_regs. */
- n_rregs = univ->allocable;
- n_vregs = instrs_in->n_vregs;
+ state->n_rregs = univ->allocable;
+ state->n_vregs = n_vregs;
/* If this is not so, vreg_state entries will overflow. */
- vassert(n_vregs < 32767);
+ vassert(state->n_vregs < 32767);
/* If this is not so, the universe we have is nonsensical. */
- vassert(n_rregs > 0);
+ vassert(state->n_rregs > 0);
- rreg_state = LibVEX_Alloc_inline(n_rregs * sizeof(RRegState));
- vreg_state = LibVEX_Alloc_inline(n_vregs * sizeof(Short));
+ state->rreg_state = LibVEX_Alloc_inline(state->n_rregs * sizeof(RRegState));
+ state->vreg_state = LibVEX_Alloc_inline(state->n_vregs * sizeof(Short));
- for (Int j = 0; j < n_rregs; j++) {
- rreg_state[j].has_hlrs = False;
- rreg_state[j].disp = Free;
- rreg_state[j].vreg = INVALID_HREG;
- rreg_state[j].is_spill_cand = False;
- rreg_state[j].eq_spill_slot = False;
+ for (UInt i = 0; i < state->n_rregs; i++) {
+ state->rreg_state[i].has_hlrs = False;
+ state->rreg_state[i].disp = Free;
+ state->rreg_state[i].vreg = INVALID_HREG;
+ state->rreg_state[i].is_spill_cand = False;
+ state->rreg_state[i].eq_spill_slot = False;
}
- for (Int j = 0; j < n_vregs; j++)
- vreg_state[j] = INVALID_RREG_NO;
-
+ for (UInt i = 0; i < n_vregs; i++)
+ state->vreg_state[i] = INVALID_RREG_NO;
- /* --------- Stage 1: compute vreg live ranges. --------- */
- /* --------- Stage 2: compute rreg live ranges. --------- */
- /* ------ start of SET UP TO COMPUTE VREG LIVE RANGES ------ */
+ /* Initialize vreg live ranges. */
/* This is relatively simple, because (1) we only seek the complete
end-to-end live range of each vreg, and are not interested in
@@ -540,114 +478,185 @@
.. n_vregs-1, so we can just dump the results in a
pre-allocated array. */
- vreg_lrs = NULL;
- if (n_vregs > 0)
- vreg_lrs = LibVEX_Alloc_inline(sizeof(VRegLR) * n_vregs);
-
- for (Int j = 0; j < n_vregs; j++) {
- vreg_lrs[j].live_after = INVALID_INSTRNO;
- vreg_lrs[j].dead_before = INVALID_INSTRNO;
- vreg_lrs[j].spill_offset = 0;
- vreg_lrs[j].spill_size = 0;
- vreg_lrs[j].reg_class = HRcINVALID;
+ state->vreg_lrs = NULL;
+ if (state->n_vregs > 0)
+ state->vreg_lrs = LibVEX_Alloc_inline(sizeof(VRegLR) * state->n_vregs);
+
+ for (UInt i = 0; i < state->n_vregs; i++) {
+ state->vreg_lrs[i].live_after = INVALID_INSTRNO;
+ state->vreg_lrs[i].dead_before = INVALID_INSTRNO;
+ state->vreg_lrs[i].spill_offset = 0;
+ state->vreg_lrs[i].spill_size = 0;
+ state->vreg_lrs[i].reg_class = HRcINVALID;
}
- /* An array to hold the reg-usage info for the incoming
- instructions. */
- reg_usage_arr
- = LibVEX_Alloc_inline(sizeof(HRegUsage) * instrs_in->arr_used-1);
+ /* An array to hold the reg-usage info for the incoming instructions. */
+ state->reg_usage_arr
+ = LibVEX_Alloc_inline(sizeof(HRegUsage) * instrs_in->insns_used-1);
- /* ------ end of SET UP TO COMPUTE VREG LIVE RANGES ------ */
- /* ------ start of SET UP TO COMPUTE RREG LIVE RANGES ------ */
+ /* Initialize rreg live ranges. */
- /* This is more complex than Stage 1, because we need to compute
+ /* This is more complex than previous step, because we need to compute
exactly all the live ranges of all the allocatable real regs,
and we don't know in advance how many there will be. */
- rreg_lrs_used = 0;
- rreg_lrs_size = 4;
- rreg_lrs_la = LibVEX_Alloc_inline(rreg_lrs_size * sizeof(RRegLR));
- rreg_lrs_db = NULL; /* we'll create this later */
-
- /* We'll need to track live range start/end points seperately for
- each rreg. Sigh. */
- vassert(n_rregs > 0);
- rreg_live_after = LibVEX_Alloc_inline(n_rregs * sizeof(Int));
- rreg_dead_before = LibVEX_Alloc_inline(n_rregs * sizeof(Int));
-
- for (Int j = 0; j < n_rregs; j++) {
- rreg_live_after[j] =
- rreg_dead_before[j] = INVALID_INSTRNO;
+ state->rreg_lrs_used = 0;
+ state->rreg_lrs_size = 4;
+ state->rreg_lrs_la
+ = LibVEX_Alloc_inline(state->rreg_lrs_size * sizeof(RRegLR));
+ state->rreg_lrs_db = NULL; /* Will be created later. */
+
+ /* Track live range start/end points seperately for each rreg. Sigh. */
+ vassert(state->n_rregs > 0);
+ state->rreg_live_after = LibVEX_Alloc_inline(state->n_rregs * sizeof(UInt));
+ state->rreg_dead_before = LibVEX_Alloc_inline(state->n_rregs * sizeof(UInt));
+
+ for (UInt i = 0; i < state->n_rregs; i++) {
+ state->rreg_live_after[i] = state->rreg_dead_before[i] = INVALID_INSTRNO;
+ }
+
+ local_memset(state->ss_busy_until_before, 0,
+ sizeof(state->ss_busy_until_before));
+}
+
+static void print_state(const RegAllocState* state)
+{
+ for (UInt i = 0; i < state->n_rregs; i++) {
+ vex_printf(" rreg_state[%2d] = ", i);
+ state->ppReg(state->univ->regs[i]);
+ vex_printf(" \t");
+
+ switch (state->rreg_state[i].disp) {
+ case Free: vex_printf("Free\n"); break;
+ case Unavail: vex_printf("Unavail\n"); break;
+ case Bound: vex_printf("BoundTo ");
+ state->ppReg(state->rreg_state[i].vreg);
+ vex_printf("\n"); break;
+ }
+ }
+
+ vex_printf("\n vreg_state[0 .. %u]:\n ", state->n_vregs - 1);
+ UInt j = 0;
+ for (UInt i = 0; i < state->n_vregs; i++) {
+ if (state->vreg_state[i] == INVALID_RREG_NO)
+ continue;
+ vex_printf("[%u] -> %d ", i, state->vreg_state[i]);
+ j++;
+ if (j > 0 && (j % 6) == 0)
+ vex_printf("\n ");
}
- /* ------ end of SET UP TO COMPUTE RREG LIVE RANGES ------ */
+ vex_printf("\n");
+}
+
+/* A target-independent register allocator. Requires various
+ functions which it uses to deal abstractly with instructions and
+ registers, since it cannot have any target-specific knowledge.
+
+ Returns a new vector of instructions, which, as a result of the
+ behaviour of mapRegs, will be in-place modifications of the
+ original instructions.
+
+ Takes a vector of unallocated insns. Returns a vector of allocated insns.
+ Both vectors have the same structure, including any HInstrIfThenElse.
+*/
+static HInstrVec* regAlloc_HInstrVec(RegAllocState* state,
+ const HInstrVec* instrs_in)
+{
+ const Bool eq_spill_opt = True;
+
+ /* The live range numbers are signed shorts, and so limiting the
+ number of insns to 15000 comfortably guards against them
+ overflowing 32k. */
+ /* TODO-JIT: this is incorrect w.r.t. IfThenElse */
+ vassert(instrs_in->insns_used <= 15000);
+
+# define EMIT_INSTR(_instr) \
+ do { \
+ HInstr* _tmp = (_instr); \
+ if (DEBUG_REGALLOC) { \
+ vex_printf("** "); \
+ state->ppInstr(_tmp, state->mode64); \
+ vex_printf("\n\n"); \
+ } \
+ addHInstr(instrs_out, _tmp); \
+ } while (0)
+
+ /* --------- Stage 0: set up --------- */
+ HInstrVec* instrs_out = newHInstrVec();
+
+
+ /* --------- Stage 1: iterate over instructins --------- */
/* ------ start of ITERATE OVER INSNS ------ */
- for (Int ii = 0; ii < instrs_in->arr_used; ii++) {
+ for (UInt ii = 0; ii < instrs_in->insns_used; ii++) {
+ const HInstr* instr = instrs_in->insns[ii];
+
+ if (state->isIfThenElse(instr) != NULL) {
+ vpanic("IfThenElse unimplemented");
+ }
- (*getRegUsage)( ®_usage_arr[ii], instrs_in->arr[ii], mode64 );
+ state->getRegUsage(&state->reg_usage_arr[ii], instr, state->mode64);
if (0) {
- vex_printf("\n%d stage1: ", ii);
- (*ppInstr)(instrs_in->arr[ii], mode64);
+ vex_printf("\n%u stage1: ", ii);
+ state->ppInstr(instr, state->mode64);
vex_printf("\n");
- ppHRegUsage(univ, ®_usage_arr[ii]);
+ ppHRegUsage(state->univ, &state->reg_usage_arr[ii]);
}
/* ------ start of DEAL WITH VREG LIVE RANGES ------ */
/* for each virtual reg mentioned in the insn ... */
- for (Int j = 0; j < reg_usage_arr[ii].n_vRegs; j++) {
+ for (UInt j = 0; j < state->reg_usage_arr[ii].n_vRegs; j++) {
- HReg vreg = reg_usage_arr[ii].vRegs[j];
+ HReg vreg = state->reg_usage_arr[ii].vRegs[j];
vassert(hregIsVirtual(vreg));
Int k = hregIndex(vreg);
- if (k < 0 || k >= n_vregs) {
+ if (k < 0 || k >= state->n_vregs) {
vex_printf("\n");
- (*ppInstr)(instrs_in->arr[ii], mode64);
+ state->ppInstr(instr, state->mode64);
vex_printf("\n");
- vex_printf("vreg %d, n_vregs %d\n", k, n_vregs);
- vpanic("doRegisterAllocation: out-of-range vreg");
+ vex_printf("vreg %d, n_vregs %u\n", k, state->n_vregs);
+ vpanic("regAlloc_HInstrVec: out-of-range vreg");
}
/* Take the opportunity to note its regclass. We'll need
that when allocating spill slots. */
- if (vreg_lrs[k].reg_class == HRcINVALID) {
+ if (state->vreg_lrs[k].reg_class == HRcINVALID) {
/* First mention of this vreg. */
- vreg_lrs[k].reg_class = hregClass(vreg);
+ state->vreg_lrs[k].reg_class = hregClass(vreg);
} else {
/* Seen it before, so check for consistency. */
- vassert(vreg_lrs[k].reg_class == hregClass(vreg));
+ vassert(state->vreg_lrs[k].reg_class == hregClass(vreg));
}
/* Now consider live ranges. */
- switch (reg_usage_arr[ii].vMode[j]) {
+ switch (state->reg_usage_arr[ii].vMode[j]) {
case HRmRead:
- if (vreg_lrs[k].live_after == INVALID_INSTRNO) {
+ if (state->vreg_lrs[k].live_after == INVALID_INSTRNO) {
vex_printf("\n\nOFFENDING VREG = %d\n", k);
- vpanic("doRegisterAllocation: "
- "first event for vreg is Read");
+ vpanic("regAlloc_HInstrVec: first event for vreg is Read");
}
- vreg_lrs[k].dead_before = toShort(ii + 1);
+ state->vreg_lrs[k].dead_before = toShort(ii + 1);
break;
case HRmWrite:
- if (vreg_lrs[k].live_after == INVALID_INSTRNO)
- vreg_lrs[k].live_after = toShort(ii);
- vreg_lrs[k].dead_before = toShort(ii + 1);
+ if (state->vreg_lrs[k].live_after == INVALID_INSTRNO)
+ state->vreg_lrs[k].live_after = toShort(ii);
+ state->vreg_lrs[k].dead_before = toShort(ii + 1);
break;
case HRmModify:
- if (vreg_lrs[k].live_after == INVALID_INSTRNO) {
+ if (state->vreg_lrs[k].live_after == INVALID_INSTRNO) {
vex_printf("\n\nOFFENDING VREG = %d\n", k);
- vpanic("doRegisterAllocation: "
- "first event for vreg is Modify");
+ vpanic("regAlloc_HInstrVec: first event for vreg is Modify");
}
- vreg_lrs[k].dead_before = toShort(ii + 1);
+ state->vreg_lrs[k].dead_before = toShort(ii + 1);
break;
default:
- vpanic("doRegisterAllocation(1)");
+ vpanic("regAlloc_HInstrVec(1)");
} /* switch */
} /* iterate over virtual registers */
@@ -658,10 +667,10 @@
/* If this doesn't hold, the following iteration over real registers
will fail miserably. */
- vassert(N_RREGUNIVERSE_REGS == 64);
+ STATIC_ASSERT(N_RREGUNIVERSE_REGS == 64);
- const ULong rRead = reg_usage_arr[ii].rRead;
- const ULong rWritten = reg_usage_arr[ii].rWritten;
+ const ULong rRead = state->reg_usage_arr[ii].rRead;
+ const ULong rWritten = state->reg_usage_arr[ii].rWritten;
const ULong rMentioned = rRead | rWritten;
UInt rReg_minIndex;
@@ -678,8 +687,8 @@
/* Don't bother to look at registers which are not available
to the allocator. We asserted above that n_rregs > 0, so
n_rregs-1 is safe. */
- if (rReg_maxIndex >= n_rregs)
- rReg_maxIndex = n_rregs-1;
+ if (rReg_maxIndex >= state->n_rregs)
+ rReg_maxIndex = state->n_rregs-1;
}
/* for each allocator-available real reg mentioned in the insn ... */
@@ -703,49 +712,48 @@
Bool flush = False;
if (isW && !isR) {
- flush_la = rreg_live_after[j];
- flush_db = rreg_dead_before[j];
+ flush_la = state->rreg_live_after[j];
+ flush_db = state->rreg_dead_before[j];
if (flush_la != INVALID_INSTRNO && flush_db != INVALID_INSTRNO)
flush = True;
- rreg_live_after[j] = ii;
- rreg_dead_before[j] = ii+1;
+ state->rreg_live_after[j] = ii;
+ state->rreg_dead_before[j] = ii+1;
} else if (!isW && isR) {
- if (rreg_live_after[j] == INVALID_INSTRNO) {
+ if (state->rreg_live_after[j] == INVALID_INSTRNO) {
vex_printf("\nOFFENDING RREG = ");
- (*ppReg)(univ->regs[j]);
+ state->ppReg(state->univ->regs[j]);
vex_printf("\n");
vex_printf("\nOFFENDING instr = ");
- (*ppInstr)(instrs_in->arr[ii], mode64);
+ state->ppInstr(instr, state->mode64);
vex_printf("\n");
- vpanic("doRegisterAllocation: "
- "first event for rreg is Read");
+ vpanic("regAlloc_HInstrVec: first event for rreg is Read");
}
- rreg_dead_before[j] = ii+1;
+ state->rreg_dead_before[j] = ii+1;
} else {
vassert(isR && isW);
- if (rreg_live_after[j] == INVALID_INSTRNO) {
+ if (state->rreg_live_after[j] == INVALID_INSTRNO) {
vex_printf("\nOFFENDING RREG = ");
- (*ppReg)(univ->regs[j]);
+ state->ppReg(state->univ->regs[j]);
vex_printf("\n");
vex_printf("\nOFFENDING instr = ");
- (*ppInstr)(instrs_in->arr[ii], mode64);
+ state->ppInstr(instr, state->mode64);
vex_printf("\n");
- vpanic("doRegisterAllocation: "
- "first event for rreg is Modify");
+ vpanic("regAlloc_HInstrVec: first event for rreg is Modify");
}
- rreg_dead_before[j] = ii+1;
+ state->rreg_dead_before[j] = ii+1;
}
if (flush) {
vassert(flush_la != INVALID_INSTRNO);
vassert(flush_db != INVALID_INSTRNO);
- ensureRRLRspace(&rreg_lrs_la, &rreg_lrs_size, rreg_lrs_used);
+ UInt used = state->rreg_lrs_used;
+ ensureRRLRspace(&state->rreg_lrs_la, &state->rreg_lrs_size, used);
if (0)
vex_printf("FLUSH 1 (%d,%d)\n", flush_la, flush_db);
- rreg_lrs_la[rreg_lrs_used].rreg = univ->regs[j];
- rreg_lrs_la[rreg_lrs_used].live_after = toShort(flush_la);
- rreg_lrs_la[rreg_lrs_used].dead_before = toShort(flush_db);
- rreg_lrs_used++;
+ state->rreg_lrs_la[used].rreg = state->univ->regs[j];
+ state->rreg_lrs_la[used].live_after = toShort(flush_la);
+ state->rreg_lrs_la[used].dead_before = toShort(flush_db);
+ state->rreg_lrs_used++;
}
} /* iterate over rregs in the instr */
@@ -759,30 +767,32 @@
/* ------ start of FINALISE RREG LIVE RANGES ------ */
/* Now finish up any live ranges left over. */
- for (Int j = 0; j < n_rregs; j++) {
+ for (UInt j = 0; j < state->n_rregs; j++) {
if (0) {
- vex_printf("residual %d: %d %d\n", j, rreg_live_after[j],
- rreg_dead_before[j]);
+ vex_printf("residual %u: %u %u\n", j, state->rreg_live_after[j],
+ state->rreg_dead_before[j]);
}
- vassert( (rreg_live_after[j] == INVALID_INSTRNO
- && rreg_dead_before[j] == INVALID_INSTRNO)
+ vassert( (state->rreg_live_after[j] == INVALID_INSTRNO
+ && state->rreg_dead_before[j] == INVALID_INSTRNO)
||
- (rreg_live_after[j] != INVALID_INSTRNO
- && rreg_dead_before[j] != INVALID_INSTRNO)
+ (state->rreg_live_after[j] != INVALID_INSTRNO
+ && state->rreg_dead_before[j] != INVALID_INSTRNO)
);
- if (rreg_live_after[j] == INVALID_INSTRNO)
+ if (state->rreg_live_after[j] == INVALID_INSTRNO)
continue;
- ensureRRLRspace(&rreg_lrs_la, &rreg_lrs_size, rreg_lrs_used);
+ ensureRRLRspace(&state->rreg_lrs_la, &state->rreg_lrs_size,
+ state->rreg_lrs_used);
if (0)
vex_printf("FLUSH 2 (%d,%d)\n",
- rreg_live_after[j], rreg_dead_before[j]);
- rreg_lrs_la[rreg_lrs_used].rreg = univ->regs[j];
- rreg_lrs_la[rreg_lrs_used].live_after = toShort(rreg_live_after[j]);
- rreg_lrs_la[rreg_lrs_used].dead_before = toShort(rreg_dead_before[j]);
- rreg_lrs_used++;
+ state->rreg_live_after[j], state->rreg_dead_before[j]);
+ UInt used = state->rreg_lrs_used;
+ state->rreg_lrs_la[used].rreg = state->univ->regs[j];
+ state->rreg_lrs_la[used].live_after = toShort(state->rreg_live_after[j]);
+ state->rreg_lrs_la[used].dead_before = toShort(state->rreg_dead_before[j]);
+ state->rreg_lrs_used++;
}
/* Compute summary hints for choosing real regs. If a real reg is
@@ -793,65 +803,73 @@
their HLRs. Correctness of final assignment is unaffected by
this mechanism -- it is only an optimisation. */
- for (Int j = 0; j < rreg_lrs_used; j++) {
- HReg rreg = rreg_lrs_la[j].rreg;
+ for (UInt j = 0; j < state->rreg_lrs_used; j++) {
+ HReg rreg = state->rreg_lrs_la[j].rreg;
vassert(!hregIsVirtual(rreg));
/* rreg is involved in a HLR. Record this info in the array, if
there is space. */
UInt ix = hregIndex(rreg);
- vassert(ix < n_rregs);
- rreg_state[ix].has_hlrs = True;
+ vassert(ix < state->n_rregs);
+ state->rreg_state[ix].has_hlrs = True;
}
if (0) {
- for (Int j = 0; j < n_rregs; j++) {
- if (!rreg_state[j].has_hlrs)
+ for (UInt j = 0; j < state->n_rregs; j++) {
+ if (!state->rreg_state[j].has_hlrs)
continue;
- ppReg(univ->regs[j]);
+ state->ppReg(state->univ->regs[j]);
vex_printf(" hinted\n");
}
}
/* Finally, copy the _la variant into the _db variant and
sort both by their respective fields. */
- rreg_lrs_db = LibVEX_Alloc_inline(rreg_lrs_used * sizeof(RRegLR));
- for (Int j = 0; j < rreg_lrs_used; j++)
- rreg_lrs_db[j] = rreg_lrs_la[j];
-
- sortRRLRarray( rreg_lrs_la, rreg_lrs_used, True /* by .live_after*/ );
- sortRRLRarray( rreg_lrs_db, rreg_lrs_used, False/* by .dead_before*/ );
+ state->rreg_lrs_db
+ = LibVEX_Alloc_inline(state->rreg_lrs_used * sizeof(RRegLR));
+ for (UInt j = 0; j < state->rreg_lrs_used; j++)
+ state->rreg_lrs_db[j] = state->rreg_lrs_la[j];
+
+ sortRRLRarray(state->rreg_lrs_la, state->rreg_lrs_used,
+ True /* by .live_after*/ );
+ sortRRLRarray(state->rreg_lrs_db, state->rreg_lrs_used,
+ False/* by .dead_before*/ );
/* And set up the cursors. */
- rreg_lrs_la_next = 0;
- rreg_lrs_db_next = 0;
+ state->rreg_lrs_la_next = 0;
+ state->rreg_lrs_db_next = 0;
- for (Int j = 1; j < rreg_lrs_used; j++) {
- vassert(rreg_lrs_la[j-1].live_after <= rreg_lrs_la[j].live_after);
- vassert(rreg_lrs_db[j-1].dead_before <= rreg_lrs_db[j].dead_before);
+ const RRegLR* lrs_la = state->rreg_lrs_la;
+ const RRegLR* lrs_db = state->rreg_lrs_db;
+ for (UInt j = 1; j < state->rreg_lrs_used; j++) {
+ vassert(lrs_la[j-1].live_after <= lrs_la[j].live_after);
+ vassert(lrs_db[j-1].dead_before <= lrs_db[j].dead_before);
}
/* ------ end of FINALISE RREG LIVE RANGES ------ */
if (DEBUG_REGALLOC) {
- for (Int j = 0; j < n_vregs; j++) {
- vex_printf("vreg %d: la = %d, db = %d\n",
- j, vreg_lrs[j].live_after, vreg_lrs[j].dead_before );
+ for (UInt j = 0; j < state->n_vregs; j++) {
+ vex_printf("vreg %d: la = %d, db = %d\n", j,
+ state->vreg_lrs[j].live_after,
+ state->vreg_lrs[j].dead_before );
}
}
if (DEBUG_REGALLOC) {
vex_printf("RRegLRs by LA:\n");
- for (Int j = 0; j < rreg_lrs_used; j++) {
+ for (UInt j = 0; j < state->rreg_lrs_used; j++) {
vex_printf(" ");
- (*ppReg)(rreg_lrs_la[j].rreg);
+ state->ppReg(state->rreg_lrs_la[j].rreg);
vex_printf(" la = %d, db = %d\n",
- rreg_lrs_la[j].live_after, rreg_lrs_la[j].dead_before );
+ state->rreg_lrs_la[j].live_after,
+ state->rreg_lrs_la[j].dead_before );
}
vex_printf("RRegLRs by DB:\n");
- for (Int j = 0; j < rreg_lrs_used; j++) {
+ for (UInt j = 0; j < state->rreg_lrs_used; j++) {
vex_printf(" ");
- (*ppReg)(rreg_lrs_db[j].rreg);
+ state->ppReg(state->rreg_lrs_db[j].rreg);
vex_printf(" la = %d, db = %d\n",
- rreg_lrs_db[j].live_after, rreg_lrs_db[j].dead_before );
+ state->rreg_lrs_db[j].live_after,
+ state->rreg_lrs_db[j].dead_before );
}
}
@@ -883,14 +901,12 @@
*/
/* Int max_ss_no = -1; */
- local_memset(ss_busy_until_before, 0, sizeof(ss_busy_until_before));
-
- for (Int j = 0; j < n_vregs; j++) {
+ for (UInt j = 0; j < state->n_vregs; j++) {
/* True iff this vreg is unused. In which case we also expect
that the reg_class field for it has not been set. */
- if (vreg_lrs[j].live_after == INVALID_INSTRNO) {
- vassert(vreg_lrs[j].reg_class == HRcINVALID);
+ if (state->vreg_lrs[j].live_after == INVALID_INSTRNO) {
+ vassert(state->vreg_lrs[j].reg_class == HRcINVALID);
continue;
}
@@ -902,7 +918,7 @@
kept in sync with the size info on the definition of
HRegClass. */
Int ss_no = -1;
- switch (vreg_lrs[j].reg_class) {
+ switch (state->vreg_lrs[j].reg_class) {
case HRcVec128: case HRcFlt64:
/* Find two adjacent free slots in which between them
@@ -910,15 +926,19 @@
Since we are trying to find an even:odd pair, move
along in steps of 2 (slots). */
for (ss_no = 0; ss_no < N_SPILL64S-1; ss_no += 2)
- if (ss_busy_until_before[ss_no+0] <= vreg_lrs[j].live_after
- && ss_busy_until_before[ss_no+1] <= vreg_lrs[j].live_after)
+ if (state->ss_busy_until_before[ss_no+0]
+ <= state->vreg_lrs[j].live_after
+ && state->ss_busy_until_before[ss_no+1]
+ <= state->vreg_lrs[j].live_after)
break;
if (ss_no >= N_SPILL64S-1) {
vpanic("LibVEX_N_SPILL_BYTES is too low. "
"Increase and recompile.");
}
- ss_busy_until_before[ss_no+0] = vreg_lrs[j].dead_before;
- ss_busy_until_before[ss_no+1] = vreg_lrs[j].dead_before;
+ state->ss_busy_until_before[ss_no+0]
+ = state->vreg_lrs[j].dead_before;
+ state->ss_busy_until_before[ss_no+1]
+ = state->vreg_lrs[j].dead_before;
break;
default:
@@ -927,33 +947,35 @@
at the start point of this interval, and assign the
interval to it. */
for (ss_no = 0; ss_no < N_SPILL64S; ss_no++)
- if (ss_busy_until_before[ss_no] <= vreg_lrs[j].live_after)
+ if (state->ss_busy_until_before[ss_no]
+ <= state->vreg_lrs[j].live_after)
break;
if (ss_no == N_SPILL64S) {
vpanic("LibVEX_N_SPILL_BYTES is too low. "
"Increase and recompile.");
}
- ss_busy_until_before[ss_no] = vreg_lrs[j].dead_before;
+ state->ss_busy_until_before[ss_no] = state->vreg_lrs[j].dead_before;
break;
- } /* switch (vreg_lrs[j].reg_class) */
+ } /* switch (state->vreg_lrs[j].reg_class) */
- /* This reflects LibVEX's hard-wired knowledge of the baseBlock
+ /* This reflects LibVEX's hard-wired knowledge of the guest state
layout: the guest state, then two equal sized areas following
it for two sets of shadow state, and then the spill area. */
- vreg_lrs[j].spill_offset = toShort(guest_sizeB * 3 + ss_no * 8);
+ state->vreg_lrs[j].spill_offset
+ = toShort(state->guest_sizeB * 3 + ss_no * 8);
/* Independent check that we've made a sane choice of slot */
- sanity_check_spill_offset( &vreg_lrs[j] );
+ sanity_check_spill_offset(&state->vreg_lrs[j]);
/* if (j > max_ss_no) */
/* max_ss_no = j; */
}
if (0) {
vex_printf("\n\n");
- for (Int j = 0; j < n_vregs; j++)
+ for (UInt j = 0; j < state->n_vregs; j++)
vex_printf("vreg %d --> spill offset %d\n",
- j, vreg_lrs[j].spill_offset);
+ j, state->vreg_lrs[j].spill_offset);
}
/* --------- Stage 4: establish rreg preferences --------- */
@@ -979,14 +1001,16 @@
/* ------ BEGIN: Process each insn in turn. ------ */
- for (Int ii = 0; ii < instrs_in->arr_used; ii++) {
+ for (UInt ii = 0; ii < instrs_in->insns_used; ii++) {
+ HInstr* instr = instrs_in->insns[ii];
+ vassert(!state->isIfThenElse(instr));
if (DEBUG_REGALLOC) {
- vex_printf("\n====----====---- Insn %d ----====----====\n", ii);
+ vex_printf("\n====----====---- Insn %u ----====----====\n", ii);
vex_printf("---- ");
- (*ppInstr)(instrs_in->arr[ii], mode64);
+ state->ppInstr(instr, state->mode64);
vex_printf("\n\nInitial state:\n");
- PRINT_STATE;
+ print_state(state);
vex_printf("\n");
}
@@ -995,10 +1019,10 @@
/* Sanity checks are expensive. So they are done only once
every 17 instructions, and just before the last
instruction. */
- do_sanity_check
+ Bool do_sanity_check
= toBool(
False /* Set to True for sanity checking of all insns. */
- || ii == instrs_in->arr_used-1
+ || ii == instrs_in->insns_used-1
|| (ii > 0 && (ii % 17) == 0)
);
@@ -1007,25 +1031,25 @@
/* Sanity check 1: all rregs with a hard live range crossing
this insn must be marked as unavailable in the running
state. */
- for (Int j = 0; j < rreg_lrs_used; j++) {
- if (rreg_lrs_la[j].live_after < ii
- && ii < rreg_lrs_la[j].dead_before) {
+ for (UInt j = 0; j < state->rreg_lrs_used; j++) {
+ if (state->rreg_lrs_la[j].live_after < ii
+ && ii < state->rreg_lrs_la[j].dead_before) {
/* ii is the middle of a hard live range for some real
reg. Check it's marked as such in the running
state. */
- HReg reg = rreg_lrs_la[j].rreg;
+ HReg reg = state->rreg_lrs_la[j].rreg;
if (0) {
vex_printf("considering la %d .. db %d reg = ",
- rreg_lrs_la[j].live_after,
- rreg_lrs_la[j].dead_before);
- (*ppReg)(reg);
+ state->rreg_lrs_la[j].live_after,
+ state->rreg_lrs_la[j].dead_before);
+ state->ppReg(reg);
vex_printf("\n");
}
/* assert that this rreg is marked as unavailable */
vassert(!hregIsVirtual(reg));
- vassert(rreg_state[hregIndex(reg)].disp == Unavail);
+ vassert(state->rreg_state[hregIndex(reg)].disp == Unavail);
}
}
@@ -1033,36 +1057,36 @@
unavailable in the running rreg_state must have a
corresponding hard live range entry in the rreg_lrs
array. */
- for (Int j = 0; j < n_rregs; j++) {
- vassert(rreg_state[j].disp == Bound
- || rreg_state[j].disp == Free
- || rreg_state[j].disp == Unavail);
- if (rreg_state[j].disp != Unavail)
+ for (UInt j = 0; j < state->n_rregs; j++) {
+ vassert(state->rreg_state[j].disp == Bound
+ || state->rreg_state[j].disp == Free
+ || state->rreg_state[j].disp == Unavail);
+ if (state->rreg_state[j].disp != Unavail)
continue;
- Int k;
- for (k = 0; k < rreg_lrs_used; k++) {
- HReg reg = rreg_lrs_la[k].rreg;
+ UInt k;
+ for (k = 0; k < state->rreg_lrs_used; k++) {
+ HReg reg = state->rreg_lrs_la[k].rreg;
vassert(!hregIsVirtual(reg));
if (hregIndex(reg) == j
- && rreg_lrs_la[k].live_after < ii
- && ii < rreg_lrs_la[k].dead_before)
+ && state->rreg_lrs_la[k].live_after < ii
+ && ii < state->rreg_lrs_la[k].dead_before)
break;
}
/* If this vassertion fails, we couldn't find a
corresponding HLR. */
- vassert(k < rreg_lrs_used);
+ vassert(k < state->rreg_lrs_used);
}
/* Sanity check 3: all vreg-rreg bindings must bind registers
of the same class. */
- for (Int j = 0; j < n_rregs; j++) {
- if (rreg_state[j].disp != Bound) {
- vassert(rreg_state[j].eq_spill_slot == False);
+ for (UInt j = 0; j < state->n_rregs; j++) {
+ if (state->rreg_state[j].disp != Bound) {
+ vassert(state->rreg_state[j].eq_spill_slot == False);
continue;
}
- vassert(hregClass(univ->regs[j])
- == hregClass(rreg_state[j].vreg));
- vassert( hregIsVirtual(rreg_state[j].vreg));
+ vassert(hregClass(state->univ->regs[j])
+ == hregClass(state->rreg_state[j].vreg));
+ vassert(hregIsVirtual(state->rreg_state[j].vreg));
}
/* Sanity check 4: the vreg_state and rreg_state
@@ -1070,20 +1094,20 @@
rreg_state[j].vreg points at some vreg_state entry then
that vreg_state entry should point back at
rreg_state[j]. */
- for (Int j = 0; j < n_rregs; j++) {
- if (rreg_state[j].disp != Bound)
+ for (UInt j = 0; j < state->n_rregs; j++) {
+ if (state->rreg_state[j].disp != Bound)
continue;
- Int k = hregIndex(rreg_state[j].vreg);
+ Int k = hregIndex(state->rreg_state[j].vreg);
vassert(IS_VALID_VREGNO(k));
- vassert(vreg_state[k] == j);
+ vassert(state->vreg_state[k] == j);
}
- for (Int j = 0; j < n_vregs; j++) {
- Int k = vreg_state[j];
+ for (UInt j = 0; j < state->n_vregs; j++) {
+ Int k = state->vreg_state[j];
if (k == INVALID_RREG_NO)
continue;
vassert(IS_VALID_RREGNO(k));
- vassert(rreg_state[k].disp == Bound);
- vassert(hregIndex(rreg_state[k].vreg) == j);
+ vassert(state->rreg_state[k].disp == Bound);
+ vassert(hregIndex(state->rreg_state[k].vreg) == j);
}
} /* if (do_sanity_check) */
@@ -1100,7 +1124,7 @@
the dst to the src's rreg, and that's all. */
HReg vregS = INVALID_HREG;
HReg vregD = INVALID_HREG;
- if ( (*isMove)( instrs_in->arr[ii], &vregS, &vregD ) ) {
+ if (state->isMove(instr, &vregS, &vregD)) {
if (!hregIsVirtual(vregS)) goto cannot_coalesce;
if (!hregIsVirtual(vregD)) goto cannot_coalesce;
/* Check that *isMove is not telling us a bunch of lies ... */
@@ -1109,17 +1133,17 @@
Int m = hregIndex(vregD);
vassert(IS_VALID_VREGNO(k));
vassert(IS_VALID_VREGNO(m));
- if (vreg_lrs[k].dead_before != ii + 1) goto cannot_coalesce;
- if (vreg_lrs[m].live_after != ii) goto cannot_coalesce;
+ if (state->vreg_lrs[k].dead_before != ii + 1) goto cannot_coalesce;
+ if (state->vreg_lrs[m].live_after != ii) goto cannot_coalesce;
if (DEBUG_REGALLOC) {
vex_printf("COALESCE ");
- (*ppReg)(vregS);
+ state->ppReg(vregS);
vex_printf(" -> ");
- (*ppReg)(vregD);
+ state->ppReg(vregD);
vex_printf("\n\n");
}
/* Find the state entry for vregS. */
- Int n = vreg_state[k]; /* k is the index of vregS */
+ Int n = state->vreg_state[k]; /* k is the index of vregS */
if (n == INVALID_RREG_NO) {
/* vregS is not currently in a real register. So we can't
do the coalescing. Give up. */
@@ -1129,15 +1153,15 @@
/* Finally, we can do the coalescing. It's trivial -- merely
claim vregS's register for vregD. */
- rreg_state[n].vreg = vregD;
+ state->rreg_state[n].vreg = vregD;
vassert(IS_VALID_VREGNO(hregIndex(vregD)));
vassert(IS_VALID_VREGNO(hregIndex(vregS)));
- vreg_state[hregIndex(vregD)] = toShort(n);
- vreg_state[hregIndex(vregS)] = INVALID_RREG_NO;
+ state->vreg_state[hregIndex(vregD)] = toShort(n);
+ state->vreg_state[hregIndex(vregS)] = INVALID_RREG_NO;
/* This rreg has become associated with a different vreg and
hence with a different spill slot. Play safe. */
- rreg_state[n].eq_spill_slot = False;
+ state->rreg_state[n].eq_spill_slot = False;
/* Move on to the next insn. We skip the post-insn stuff for
fixed registers, since this move should not interact with
@@ -1151,20 +1175,20 @@
/* Look for vregs whose live range has just ended, and
mark the associated rreg as free. */
- for (Int j = 0; j < n_rregs; j++) {
- if (rreg_state[j].disp != Bound)
+ for (UInt j = 0; j < state->n_rregs; j++) {
+ if (state->rreg_state[j].disp != Bound)
continue;
- UInt vregno = hregIndex(rreg_state[j].vreg);
+ UInt vregno = hregIndex(state->rreg_state[j].vreg);
vassert(IS_VALID_VREGNO(vregno));
- if (vreg_lrs[vregno].dead_before <= ii) {
- rreg_state[j].disp = Free;
- rreg_state[j].eq_spill_slot = False;
- Int m = hregIndex(rreg_state[j].vreg);
+ if (state->vreg_lrs[vregno].dead_before <= ii) {
+ state->rreg_state[j].disp = Free;
+ state->rreg_state[j].eq_spill_slot = False;
+ Int m = hregIndex(state->rreg_state[j].vreg);
vassert(IS_VALID_VREGNO(m));
- vreg_state[m] = INVALID_RREG_NO;
+ state->vreg_state[m] = INVALID_RREG_NO;
if (DEBUG_REGALLOC) {
vex_printf("free up ");
- (*ppReg)(univ->regs[j]);
+ state->ppReg(state->univ->regs[j]);
vex_printf("\n");
}
}
@@ -1186,16 +1210,16 @@
(their .live_after field).
*/
while (True) {
- vassert(rreg_lrs_la_next >= 0);
- vassert(rreg_lrs_la_next <= rreg_lrs_used);
- if (rreg_lrs_la_next == rreg_lrs_used)
+ vassert(state->rreg_lrs_la_next >= 0);
+ vassert(state->rreg_lrs_la_next <= state->rreg_lrs_used);
+ if (state->rreg_lrs_la_next == state->rreg_lrs_used)
break; /* no more real reg live ranges to consider */
- if (ii < rreg_lrs_la[rreg_lrs_la_next].live_after)
+ if (ii < state->rreg_lrs_la[state->rreg_lrs_la_next].live_after)
break; /* next live range does not yet start */
- vassert(ii == rreg_lrs_la[rreg_lrs_la_next].live_after);
+ vassert(ii == state->rreg_lrs_la[state->rreg_lrs_la_next].live_after);
/* rreg_lrs_la[rreg_lrs_la_next].rreg needs to be freed up.
Find the associated rreg_state entry. */
- /* Note, re ii == rreg_lrs_la[rreg_lrs_la_next].live_after.
+ /* Note, re ii == state->rreg_lrs_la[rreg_lrs_la_next].live_after.
Real register live ranges are guaranteed to be well-formed
in that they start with a write to the register -- Stage 2
rejects any code not satisfying this. So the correct
@@ -1205,47 +1229,48 @@
than before it. */
if (DEBUG_REGALLOC) {
vex_printf("need to free up rreg: ");
- (*ppReg)(rreg_lrs_la[rreg_lrs_la_next].rreg);
+ state->ppReg(state->rreg_lrs_la[state->rreg_lrs_la_next].rreg);
vex_printf("\n\n");
}
- Int k = hregIndex(rreg_lrs_la[rreg_lrs_la_next].rreg);
+ Int k = hregIndex(state->rreg_lrs_la[state->rreg_lrs_la_next].rreg);
/* If this fails, we don't have an entry for this rreg.
Which we should. */
vassert(IS_VALID_RREGNO(k));
- Int m = hregIndex(rreg_state[k].vreg);
- if (rreg_state[k].disp == Bound) {
+ Int m = hregIndex(state->rreg_state[k].vreg);
+ if (state->rreg_state[k].disp == Bound) {
/* Yes, there is an associated vreg. Spill it if it's
still live. */
vassert(IS_VALID_VREGNO(m));
- vreg_state[m] = INVALID_RREG_NO;
- if (vreg_lrs[m].dead_before > ii) {
- vassert(vreg_lrs[m].reg_class != HRcINVALID);
- if ((!eq_spill_opt) || !rreg_state[k].eq_spill_slot) {
+ state->vreg_state[m] = INVALID_RREG_NO;
+ if (state->vreg_lrs[m].dead_before > ii) {
+ vassert(state->vreg_lrs[m].reg_class != HRcINVALID);
+ if ((!eq_spill_opt) || !state->rreg_state[k].eq_spill_slot) {
HInstr* spill1 = NULL;
HInstr* spill2 = NULL;
- (*genSpill)( &spill1, &spill2, univ->regs[k],
- vreg_lrs[m].spill_offset, mode64 );
+ state->genSpill(&spill1, &spill2, state->univ->regs[k],
+ state->vreg_lrs[m].spill_offset,
+ state->mode64);
vassert(spill1 || spill2); /* can't both be NULL */
if (spill1)
EMIT_INSTR(spill1);
if (spill2)
EMIT_INSTR(spill2);
}
- rreg_state[k].eq_spill_slot = True;
+ state->rreg_state[k].eq_spill_slot = True;
}
}
- rreg_state[k].disp = Unavail;
- rreg_state[k].vreg = INVALID_HREG;
- rreg_state[k].eq_spill_slot = False;
+ state->rreg_state[k].disp = Unavail;
+ state->rreg_state[k].vreg = INVALID_HREG;
+ state->rreg_state[k].eq_spill_slot = False;
/* check for further rregs entering HLRs at this point */
- rreg_lrs_la_next++;
+ state->rreg_lrs_la_next++;
}
if (DEBUG_REGALLOC) {
vex_printf("After pre-insn actions for fixed regs:\n");
- PRINT_STATE;
+ print_state(state);
vex_printf("\n");
}
@@ -1258,6 +1283,7 @@
We also build up the final vreg->rreg mapping to be applied
to the insn. */
+ HRegRemap remap;
initHRegRemap(&remap);
/* ------------ BEGIN directReload optimisation ----------- */
@@ -1272,28 +1298,29 @@
that the change is invisible to the standard-case handling
that follows. */
- if (directReload && reg_usage_arr[ii].n_vRegs <= 2) {
+ if (state->directReload != NULL
+ && state->reg_usage_arr[ii].n_vRegs <= 2) {
Bool debug_direct_reload = False;
HReg cand = INVALID_HREG;
Bool nreads = 0;
Short spilloff = 0;
- for (Int j = 0; j < reg_usage_arr[ii].n_vRegs; j++) {
+ for (UInt j = 0; j < state->reg_usage_arr[ii].n_vRegs; j++) {
- HReg vreg = reg_usage_arr[ii].vRegs[j];
+ HReg vreg = state->reg_usage_arr[ii].vRegs[j];
vassert(hregIsVirtual(vreg));
- if (reg_usage_arr[ii].vMode[j] == HRmRead) {
+ if (state->reg_usage_arr[ii].vMode[j] == HRmRead) {
nreads++;
Int m = hregIndex(vreg);
vassert(IS_VALID_VREGNO(m));
- Int k = vreg_state[m];
+ Int k = state->vreg_state[m];
if (!IS_VALID_RREGNO(k)) {
/* ok, it is spilled. Now, is this its last use? */
- vassert(vreg_lrs[m].dead_before >= ii+1);
- if (vreg_lrs[m].dead_before == ii+1
+ vassert(state->vreg_lrs[m].dead_before >= ii+1);
+ if (state->vreg_lrs[m].dead_before == ii+1
&& hregIsInvalid(cand)) {
- spilloff = vreg_lrs[m].spill_offset;
+ spilloff = state->vreg_lrs[m].spill_offset;
cand = vreg;
}
}
@@ -1301,24 +1328,25 @@
}
if (nreads == 1 && ! hregIsInvalid(cand)) {
- HInstr* reloaded;
- if (reg_usage_arr[ii].n_vRegs == 2)
- vassert(! sameHReg(reg_usage_arr[ii].vRegs[0],
- reg_usage_arr[ii].vRegs[1]));
+ if (state->reg_usage_arr[ii].n_vRegs == 2)
+ vassert(! sameHReg(state->reg_usage_arr[ii].vRegs[0],
+ state->reg_usage_arr[ii].vRegs[1]));
- reloaded = directReload ( instrs_in->arr[ii], cand, spilloff );
- if (debug_direct_reload && !reloaded) {
+ HInstr* reloaded = state->directReload(instr, cand, spilloff);
+ if (debug_direct_reload && reloaded == NULL) {
vex_printf("[%3d] ", spilloff); ppHReg(cand); vex_printf(" ");
- ppInstr(instrs_in->arr[ii], mode64);
+ state->ppInstr(instr, state->mode64);
}
- if (reloaded) {
+ if (reloaded != NULL) {
/* Update info about the insn, so it looks as if it had
been in this form all along. */
- instrs_in->arr[ii] = reloaded;
- (*getRegUsage)( ®_usage_arr[ii], instrs_in->arr[ii], mode64 );
- if (debug_direct_reload && !reloaded) {
+ instr = reloaded;
+ instrs_in->insns[ii] = reloaded;
+ state->getRegUsage(&state->reg_usage_arr[ii], instr,
+ state->mode64);
+ if (debug_direct_reload && reloaded == NULL) {
vex_printf(" --> ");
- ppInstr(reloaded, mode64);
+ state->ppInstr(reloaded, state->mode64);
}
}
@@ -1331,13 +1359,13 @@
/* ------------ END directReload optimisation ------------ */
/* for each virtual reg mentioned in the insn ... */
- for (Int j = 0; j < reg_usage_arr[ii].n_vRegs; j++) {
+ for (UInt j = 0; j < state->reg_usage_arr[ii].n_vRegs; j++) {
- HReg vreg = reg_usage_arr[ii].vRegs[j];
+ HReg vreg = state->reg_usage_arr[ii].vRegs[j];
vassert(hregIsVirtual(vreg));
if (0) {
- vex_printf("considering "); (*ppReg)(vreg); vex_printf("\n");
+ vex_printf("considering "); state->ppReg(vreg); vex_printf("\n");
}
/* Now we're trying to find a rreg for "vreg". First of all,
@@ -1345,14 +1373,14 @@
anything more. Inspect the current state to find out. */
Int m = hregIndex(vreg);
vassert(IS_VALID_VREGNO(m));
- Int n = vreg_state[m];
+ Short n = state->vreg_state[m];
if (IS_VALID_RREGNO(n)) {
- vassert(rreg_state[n].disp == Bound);
- addToHRegRemap(&remap, vreg, univ->regs[n]);
+ vassert(state->rreg_state[n].disp == Bound);
+ addToHRegRemap(&remap, vreg, state->univ->regs[n]);
/* If this rreg is written or modified, mark it as different
from any spill slot value. */
- if (reg_usage_arr[ii].vMode[j] != HRmRead)
- rreg_state[n].eq_spill_slot = False;
+ if (state->reg_usage_arr[ii].vMode[j] != HRmRead)
+ state->rreg_state[n].eq_spill_slot = False;
continue;
} else {
vassert(n == INVALID_RREG_NO);
@@ -1365,11 +1393,11 @@
as possible. */
Int k_suboptimal = -1;
Int k;
- for (k = 0; k < n_rregs; k++) {
- if (rreg_state[k].disp != Free
- || hregClass(univ->regs[k]) != hregClass(vreg))
+ for (k = 0; k < state->n_rregs; k++) {
+ if (state->rreg_state[k].disp != Free
+ || hregClass(state->univ->regs[k]) != hregClass(vreg))
continue;
- if (rreg_state[k].has_hlrs) {
+ if (state->rreg_state[k].has_hlrs) {
/* Well, at least we can use k_suboptimal if we really
have to. Keep on looking for a better candidate. */
k_suboptimal = k;
@@ -1382,25 +1410,25 @@
if (k_suboptimal >= 0)
k = k_suboptimal;
- if (k < n_rregs) {
- ...
[truncated message content] |
|
From: <sv...@va...> - 2017-04-16 20:36:57
|
Author: iraisr
Date: Sun Apr 16 21:36:48 2017
New Revision: 3349
Log:
Extend host instruction interface with HInstrSB, HInstrVec and HInstrIfThenElse.
Modified:
branches/VEX_JIT_HACKS/priv/host_amd64_defs.h
branches/VEX_JIT_HACKS/priv/host_arm64_defs.h
branches/VEX_JIT_HACKS/priv/host_arm_defs.h
branches/VEX_JIT_HACKS/priv/host_generic_regs.c
branches/VEX_JIT_HACKS/priv/host_generic_regs.h
branches/VEX_JIT_HACKS/priv/host_mips_defs.h
branches/VEX_JIT_HACKS/priv/host_ppc_defs.h
branches/VEX_JIT_HACKS/priv/host_s390_defs.h
branches/VEX_JIT_HACKS/priv/host_tilegx_defs.h
branches/VEX_JIT_HACKS/priv/host_x86_defs.c
branches/VEX_JIT_HACKS/priv/host_x86_defs.h
branches/VEX_JIT_HACKS/priv/host_x86_isel.c
branches/VEX_JIT_HACKS/priv/main_main.c
Modified: branches/VEX_JIT_HACKS/priv/host_amd64_defs.h
==============================================================================
--- branches/VEX_JIT_HACKS/priv/host_amd64_defs.h (original)
+++ branches/VEX_JIT_HACKS/priv/host_amd64_defs.h Sun Apr 16 21:36:48 2017
@@ -804,7 +804,7 @@
extern const RRegUniverse* getRRegUniverse_AMD64 ( void );
-extern HInstrArray* iselSB_AMD64 ( const IRSB*,
+extern HInstrSB* iselSB_AMD64 ( const IRSB*,
VexArch,
const VexArchInfo*,
const VexAbiInfo*,
Modified: branches/VEX_JIT_HACKS/priv/host_arm64_defs.h
==============================================================================
--- branches/VEX_JIT_HACKS/priv/host_arm64_defs.h (original)
+++ branches/VEX_JIT_HACKS/priv/host_arm64_defs.h Sun Apr 16 21:36:48 2017
@@ -982,7 +982,7 @@
extern const RRegUniverse* getRRegUniverse_ARM64 ( void );
-extern HInstrArray* iselSB_ARM64 ( const IRSB*,
+extern HInstrSB* iselSB_ARM64 ( const IRSB*,
VexArch,
const VexArchInfo*,
const VexAbiInfo*,
Modified: branches/VEX_JIT_HACKS/priv/host_arm_defs.h
==============================================================================
--- branches/VEX_JIT_HACKS/priv/host_arm_defs.h (original)
+++ branches/VEX_JIT_HACKS/priv/host_arm_defs.h Sun Apr 16 21:36:48 2017
@@ -1073,7 +1073,7 @@
extern const RRegUniverse* getRRegUniverse_ARM ( void );
-extern HInstrArray* iselSB_ARM ( const IRSB*,
+extern HInstrSB* iselSB_ARM ( const IRSB*,
VexArch,
const VexArchInfo*,
const VexAbiInfo*,
Modified: branches/VEX_JIT_HACKS/priv/host_generic_regs.c
==============================================================================
--- branches/VEX_JIT_HACKS/priv/host_generic_regs.c (original)
+++ branches/VEX_JIT_HACKS/priv/host_generic_regs.c Sun Apr 16 21:36:48 2017
@@ -282,28 +282,70 @@
/*--- Abstract instructions ---*/
/*---------------------------------------------------------*/
-HInstrArray* newHInstrArray ( void )
+HInstrVec* newHInstrVec(void)
{
- HInstrArray* ha = LibVEX_Alloc_inline(sizeof(HInstrArray));
- ha->arr_size = 4;
- ha->arr_used = 0;
- ha->arr = LibVEX_Alloc_inline(ha->arr_size * sizeof(HInstr*));
- ha->n_vregs = 0;
- return ha;
+ HInstrVec* hv = LibVEX_Alloc_inline(sizeof(HInstrVec));
+ hv->insns_size = 4;
+ hv->insns_used = 0;
+ hv->insns = LibVEX_Alloc_inline(hv->insns_size * sizeof(HInstr*));
+ return hv;
}
__attribute__((noinline))
-void addHInstr_SLOW ( HInstrArray* ha, HInstr* instr )
+void addHInstr_SLOW(HInstrVec* hv, HInstr* instr)
{
- vassert(ha->arr_used == ha->arr_size);
- Int i;
- HInstr** arr2 = LibVEX_Alloc_inline(ha->arr_size * 2 * sizeof(HInstr*));
- for (i = 0; i < ha->arr_size; i++) {
- arr2[i] = ha->arr[i];
+ vassert(hv->insns_used == hv->insns_size);
+ HInstr** insns2 = LibVEX_Alloc_inline(hv->insns_size * 2 * sizeof(HInstr*));
+ for (UInt i = 0; i < hv->insns_size; i++) {
+ insns2[i] = hv->insns[i];
}
- ha->arr_size *= 2;
- ha->arr = arr2;
- addHInstr(ha, instr);
+ hv->insns_size *= 2;
+ hv->insns = insns2;
+ addHInstr(hv, instr);
+}
+
+static void print_depth(UInt depth) {
+ for (UInt i = 0; i < depth; i++) {
+ vex_printf(" ");
+ }
+}
+
+static void ppHInstrVec(const HInstrVec* code,
+ HInstrIfThenElse* (*isIfThenElse)(const HInstr*),
+ void (*ppInstr)(const HInstr*, Bool),
+ Bool mode64, UInt depth, UInt *insn_num)
+{
+ for (UInt i = 0; i < code->insns_used; i++) {
+ const HInstr* instr = code->insns[i];
+ const HInstrIfThenElse* hite = isIfThenElse(instr);
+ if (UNLIKELY(hite != NULL)) {
+ ppHInstrVec(hite->fallThrough, isIfThenElse, ppInstr, mode64,
+ depth + 1, insn_num);
+ ppHInstrVec(hite->outOfLine, isIfThenElse, ppInstr, mode64,
+ depth + 1, insn_num);
+ } else {
+ vex_printf("%3u ", (*insn_num)++);
+ print_depth(depth);
+ ppInstr(instr, mode64);
+ vex_printf("\n");
+ }
+ }
+}
+
+HInstrSB* newHInstrSB(void)
+{
+ HInstrSB* hsb = LibVEX_Alloc_inline(sizeof(HInstrSB));
+ hsb->insns = newHInstrVec();
+ hsb->n_vregs = 0;
+ return hsb;
+}
+
+void ppHInstrSB(const HInstrSB* code,
+ HInstrIfThenElse* (*isIfThenElse)(const HInstr*),
+ void (*ppInstr)(const HInstr*, Bool), Bool mode64)
+{
+ UInt insn_num = 0;
+ ppHInstrVec(code->insns, isIfThenElse, ppInstr, mode64, 0, &insn_num);
}
Modified: branches/VEX_JIT_HACKS/priv/host_generic_regs.h
==============================================================================
--- branches/VEX_JIT_HACKS/priv/host_generic_regs.h (original)
+++ branches/VEX_JIT_HACKS/priv/host_generic_regs.h Sun Apr 16 21:36:48 2017
@@ -338,42 +338,66 @@
/* A type is needed to refer to pointers to instructions of any
target. Defining it like this means that HInstr* can stand in for
X86Instr*, ArmInstr*, etc. */
-
typedef void HInstr;
-/* An expandable array of HInstr*'s. Handy for insn selection and
- register allocation. n_vregs indicates the number of virtual
- registers mentioned in the code, something that reg-alloc needs to
- know. These are required to be numbered 0 .. n_vregs-1.
-*/
+/* An expandable vector of HInstr*'s. Handy for insn selection and
+ register allocation. */
typedef
struct {
- HInstr** arr;
- Int arr_size;
- Int arr_used;
- Int n_vregs;
+ HInstr** insns;
+ UInt insns_size;
+ UInt insns_used;
}
- HInstrArray;
+ HInstrVec;
-extern HInstrArray* newHInstrArray ( void );
+extern HInstrVec* newHInstrVec(void);
/* Never call this directly. It's the slow and incomplete path for
addHInstr. */
__attribute__((noinline))
-extern void addHInstr_SLOW ( HInstrArray*, HInstr* );
+extern void addHInstr_SLOW(HInstrVec*, HInstr*);
-static inline void addHInstr ( HInstrArray* ha, HInstr* instr )
+static inline void addHInstr(HInstrVec* ha, HInstr* instr)
{
- if (LIKELY(ha->arr_used < ha->arr_size)) {
- ha->arr[ha->arr_used] = instr;
- ha->arr_used++;
+ if (LIKELY(ha->insns_used < ha->insns_size)) {
+ ha->insns[ha->insns_used] = instr;
+ ha->insns_used++;
} else {
addHInstr_SLOW(ha, instr);
}
}
+/* Represents two alternative code paths:
+ - one more likely taken (hot path)
+ - one not so likely taken (cold path) */
+typedef
+ struct {
+ // HCondCode ccOOL; // TODO-JIT: condition code for the OOL branch
+ HInstrVec* fallThrough; // generated from the likely-taken IR
+ HInstrVec* outOfLine; // generated from likely-not-taken IR
+ }
+ HInstrIfThenElse;
+
+
+/* Code block of HInstr's.
+ n_vregs indicates the number of virtual registers mentioned in the code,
+ something that reg-alloc needs to know. These are required to be
+ numbered 0 .. n_vregs-1. */
+typedef
+ struct {
+ HInstrVec* insns;
+ UInt n_vregs;
+ }
+ HInstrSB;
+
+extern HInstrSB* newHInstrSB(void);
+extern void ppHInstrSB(const HInstrSB* code,
+ HInstrIfThenElse* (*isIfThenElse)(const HInstr*),
+ void (*ppInstr)(const HInstr*, Bool), Bool mode64);
+
+
/*---------------------------------------------------------*/
/*--- C-Call return-location descriptions ---*/
/*---------------------------------------------------------*/
@@ -443,10 +467,10 @@
/*---------------------------------------------------------*/
extern
-HInstrArray* doRegisterAllocation (
+HInstrSB* doRegisterAllocation (
/* Incoming virtual-registerised code. */
- HInstrArray* instrs_in,
+ HInstrSB* sb_in,
/* The real-register universe to use. This contains facts about
real registers, one of which is the set of registers available
@@ -463,6 +487,10 @@
/* Apply a reg-reg mapping to an insn. */
void (*mapRegs) (HRegRemap*, HInstr*, Bool),
+ /* Is this instruction actually HInstrIfThenElse? Returns pointer to
+ HInstrIfThenElse if yes, NULL otherwise. */
+ HInstrIfThenElse* (*isIfThenElse) (const HInstr*),
+
/* Return insn(s) to spill/restore a real reg to a spill slot
offset. And optionally a function to do direct reloads. */
void (*genSpill) ( HInstr**, HInstr**, HReg, Int, Bool ),
Modified: branches/VEX_JIT_HACKS/priv/host_mips_defs.h
==============================================================================
--- branches/VEX_JIT_HACKS/priv/host_mips_defs.h (original)
+++ branches/VEX_JIT_HACKS/priv/host_mips_defs.h Sun Apr 16 21:36:48 2017
@@ -703,7 +703,7 @@
extern const RRegUniverse* getRRegUniverse_MIPS ( Bool mode64 );
-extern HInstrArray *iselSB_MIPS ( const IRSB*,
+extern HInstrSB *iselSB_MIPS ( const IRSB*,
VexArch,
const VexArchInfo*,
const VexAbiInfo*,
Modified: branches/VEX_JIT_HACKS/priv/host_ppc_defs.h
==============================================================================
--- branches/VEX_JIT_HACKS/priv/host_ppc_defs.h (original)
+++ branches/VEX_JIT_HACKS/priv/host_ppc_defs.h Sun Apr 16 21:36:48 2017
@@ -1218,7 +1218,7 @@
extern const RRegUniverse* getRRegUniverse_PPC ( Bool mode64 );
-extern HInstrArray* iselSB_PPC ( const IRSB*,
+extern HInstrSB* iselSB_PPC ( const IRSB*,
VexArch,
const VexArchInfo*,
const VexAbiInfo*,
Modified: branches/VEX_JIT_HACKS/priv/host_s390_defs.h
==============================================================================
--- branches/VEX_JIT_HACKS/priv/host_s390_defs.h (original)
+++ branches/VEX_JIT_HACKS/priv/host_s390_defs.h Sun Apr 16 21:36:48 2017
@@ -749,7 +749,7 @@
const RRegUniverse *getRRegUniverse_S390( void );
void genSpill_S390 ( HInstr **, HInstr **, HReg , Int , Bool );
void genReload_S390 ( HInstr **, HInstr **, HReg , Int , Bool );
-HInstrArray *iselSB_S390 ( const IRSB *, VexArch, const VexArchInfo *,
+HInstrSB *iselSB_S390 ( const IRSB *, VexArch, const VexArchInfo *,
const VexAbiInfo *, Int, Int, Bool, Bool, Addr);
/* Return the number of bytes of code needed for an event check */
Modified: branches/VEX_JIT_HACKS/priv/host_tilegx_defs.h
==============================================================================
--- branches/VEX_JIT_HACKS/priv/host_tilegx_defs.h (original)
+++ branches/VEX_JIT_HACKS/priv/host_tilegx_defs.h Sun Apr 16 21:36:48 2017
@@ -532,10 +532,10 @@
extern const RRegUniverse* getRRegUniverse_TILEGX ( void );
-extern HInstrArray *iselSB_TILEGX ( const IRSB*, VexArch,
- const VexArchInfo*,
- const VexAbiInfo*,
- Int, Int, Bool, Bool, Addr);
+extern HInstrSB *iselSB_TILEGX ( const IRSB*, VexArch,
+ const VexArchInfo*,
+ const VexAbiInfo*,
+ Int, Int, Bool, Bool, Addr);
extern const HChar *showTILEGXCondCode ( TILEGXCondCode cond );
extern Int evCheckSzB_TILEGX (void);
extern VexInvalRange chainXDirect_TILEGX ( VexEndness endness_host,
Modified: branches/VEX_JIT_HACKS/priv/host_x86_defs.c
==============================================================================
--- branches/VEX_JIT_HACKS/priv/host_x86_defs.c (original)
+++ branches/VEX_JIT_HACKS/priv/host_x86_defs.c Sun Apr 16 21:36:48 2017
@@ -1697,6 +1697,13 @@
return False;
}
+extern HInstrIfThenElse* isIfThenElse_X86Instr(X86Instr* i)
+{
+ if (UNLIKELY(i->tag == Xin_IfThenElse)) {
+ return i->Xin.IfThenElse.hite;
+ }
+ return NULL;
+}
/* Generate x86 spill/reload instructions under the direction of the
register allocator. Note it's critical these don't write the
Modified: branches/VEX_JIT_HACKS/priv/host_x86_defs.h
==============================================================================
--- branches/VEX_JIT_HACKS/priv/host_x86_defs.h (original)
+++ branches/VEX_JIT_HACKS/priv/host_x86_defs.h Sun Apr 16 21:36:48 2017
@@ -388,7 +388,8 @@
Xin_SseCMov, /* SSE conditional move */
Xin_SseShuf, /* SSE2 shuffle (pshufd) */
Xin_EvCheck, /* Event check */
- Xin_ProfInc /* 64-bit profile counter increment */
+ Xin_ProfInc, /* 64-bit profile counter increment */
+ Xin_IfThenElse /* HInstrIfThenElse */
}
X86InstrTag;
@@ -652,6 +653,9 @@
installed later, post-translation, by patching it in,
as it is not known at translation time. */
} ProfInc;
+ struct {
+ HInstrIfThenElse* hite;
+ } IfThenElse;
} Xin;
}
@@ -717,6 +721,7 @@
extern void getRegUsage_X86Instr ( HRegUsage*, const X86Instr*, Bool );
extern void mapRegs_X86Instr ( HRegRemap*, X86Instr*, Bool );
extern Bool isMove_X86Instr ( const X86Instr*, HReg*, HReg* );
+extern HInstrIfThenElse* isIfThenElse_X86Instr(X86Instr*);
extern Int emit_X86Instr ( /*MB_MOD*/Bool* is_profInc,
UChar* buf, Int nbuf, const X86Instr* i,
Bool mode64,
@@ -735,7 +740,7 @@
extern const RRegUniverse* getRRegUniverse_X86 ( void );
-extern HInstrArray* iselSB_X86 ( const IRSB*,
+extern HInstrSB* iselSB_X86 ( const IRSB*,
VexArch,
const VexArchInfo*,
const VexAbiInfo*,
Modified: branches/VEX_JIT_HACKS/priv/host_x86_isel.c
==============================================================================
--- branches/VEX_JIT_HACKS/priv/host_x86_isel.c (original)
+++ branches/VEX_JIT_HACKS/priv/host_x86_isel.c Sun Apr 16 21:36:48 2017
@@ -185,7 +185,7 @@
Addr32 max_ga;
/* These are modified as we go along. */
- HInstrArray* code;
+ HInstrSB* code;
Int vreg_ctr;
}
ISelEnv;
@@ -209,7 +209,7 @@
static void addInstr ( ISelEnv* env, X86Instr* instr )
{
- addHInstr(env->code, instr);
+ addHInstr(env->code->insns, instr);
if (vex_traceflags & VEX_TRACE_VCODE) {
ppX86Instr(instr, False);
vex_printf("\n");
@@ -4420,7 +4420,7 @@
/* Translate an entire SB to x86 code. */
-HInstrArray* iselSB_X86 ( const IRSB* bb,
+HInstrSB* iselSB_X86 ( const IRSB* bb,
VexArch arch_host,
const VexArchInfo* archinfo_host,
const VexAbiInfo* vbi/*UNUSED*/,
@@ -4453,7 +4453,7 @@
env->vreg_ctr = 0;
/* Set up output code array. */
- env->code = newHInstrArray();
+ env->code = newHInstrSB();
/* Copy BB's type env. */
/* TODO-JIT: Currently works only with no if-then-else statements. */
Modified: branches/VEX_JIT_HACKS/priv/main_main.c
==============================================================================
--- branches/VEX_JIT_HACKS/priv/main_main.c (original)
+++ branches/VEX_JIT_HACKS/priv/main_main.c Sun Apr 16 21:36:48 2017
@@ -326,12 +326,13 @@
Bool (*isMove) ( const HInstr*, HReg*, HReg* );
void (*getRegUsage) ( HRegUsage*, const HInstr*, Bool );
void (*mapRegs) ( HRegRemap*, HInstr*, Bool );
+ HInstrIfThenElse* (*isIfThenElse)(const HInstr*);
void (*genSpill) ( HInstr**, HInstr**, HReg, Int, Bool );
void (*genReload) ( HInstr**, HInstr**, HReg, Int, Bool );
HInstr* (*directReload) ( HInstr*, HReg, Short );
void (*ppInstr) ( const HInstr*, Bool );
void (*ppReg) ( HReg );
- HInstrArray* (*iselSB) ( const IRSB*, VexArch, const VexArchInfo*,
+ HInstrSB* (*iselSB) ( const IRSB*, VexArch, const VexArchInfo*,
const VexAbiInfo*, Int, Int, Bool, Bool,
Addr );
Int (*emit) ( /*MB_MOD*/Bool*,
@@ -347,9 +348,9 @@
VexGuestLayout* guest_layout;
IRSB* irsb;
- HInstrArray* vcode;
- HInstrArray* rcode;
- Int i, j, k, out_used, guest_sizeB;
+ HInstrSB* vcode;
+ HInstrSB* rcode;
+ Int out_used, guest_sizeB;
Int offB_CMSTART, offB_CMLEN, offB_GUEST_IP, szB_GUEST_IP;
Int offB_HOST_EvC_COUNTER, offB_HOST_EvC_FAILADDR;
UChar insn_bytes[128];
@@ -413,6 +414,7 @@
getRegUsage
= (__typeof__(getRegUsage)) X86FN(getRegUsage_X86Instr);
mapRegs = (__typeof__(mapRegs)) X86FN(mapRegs_X86Instr);
+ isIfThenElse = (__typeof__(isIfThenElse)) X86FN(isIfThenElse_X86Instr);
genSpill = (__typeof__(genSpill)) X86FN(genSpill_X86);
genReload = (__typeof__(genReload)) X86FN(genReload_X86);
directReload = (__typeof__(directReload)) X86FN(directReload_X86);
@@ -878,7 +880,7 @@
vassert(vta->guest_extents->n_used >= 1 && vta->guest_extents->n_used <= 3);
vassert(vta->guest_extents->base[0] == vta->guest_bytes_addr);
- for (i = 0; i < vta->guest_extents->n_used; i++) {
+ for (UInt i = 0; i < vta->guest_extents->n_used; i++) {
vassert(vta->guest_extents->len[i] < 10000); /* sanity */
}
@@ -897,7 +899,7 @@
UInt guest_bytes_read = (UInt)vta->guest_extents->len[0];
vex_printf("GuestBytes %lx %u ", vta->guest_bytes_addr,
guest_bytes_read );
- for (i = 0; i < guest_bytes_read; i++) {
+ for (UInt i = 0; i < guest_bytes_read; i++) {
UInt b = (UInt)p[i];
vex_printf(" %02x", b );
sum = (sum << 1) ^ b;
@@ -1042,17 +1044,13 @@
vex_printf("\n");
if (vex_traceflags & VEX_TRACE_VCODE) {
- for (i = 0; i < vcode->arr_used; i++) {
- vex_printf("%3d ", i);
- ppInstr(vcode->arr[i], mode64);
- vex_printf("\n");
- }
+ ppHInstrSB(vcode, isIfThenElse, ppInstr, mode64);
vex_printf("\n");
}
/* Register allocate. */
rcode = doRegisterAllocation ( vcode, rRegUniv,
- isMove, getRegUsage, mapRegs,
+ isMove, getRegUsage, mapRegs, isIfThenElse,
genSpill, genReload, directReload,
guest_sizeB,
ppInstr, ppReg, mode64 );
@@ -1063,11 +1061,7 @@
vex_printf("\n------------------------"
" Register-allocated code "
"------------------------\n\n");
- for (i = 0; i < rcode->arr_used; i++) {
- vex_printf("%3d ", i);
- ppInstr(rcode->arr[i], mode64);
- vex_printf("\n");
- }
+ ppHInstrSB(rcode, isIfThenElse, ppInstr, mode64);
vex_printf("\n");
}
@@ -1086,22 +1080,25 @@
}
out_used = 0; /* tracks along the host_bytes array */
- for (i = 0; i < rcode->arr_used; i++) {
- HInstr* hi = rcode->arr[i];
+ /* TODO-JIT: This needs another interface when assembler/flattener
+ is given whole HInstrSB and also pointer to function
+ which prints emitted bytes. */
+ for (UInt i = 0; i < rcode->insns->insns_used; i++) {
+ HInstr* hi = rcode->insns->insns[i];
Bool hi_isProfInc = False;
if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
ppInstr(hi, mode64);
vex_printf("\n");
}
- j = emit( &hi_isProfInc,
- insn_bytes, sizeof insn_bytes, hi,
- mode64, vta->archinfo_host.endness,
- vta->disp_cp_chain_me_to_slowEP,
- vta->disp_cp_chain_me_to_fastEP,
- vta->disp_cp_xindir,
- vta->disp_cp_xassisted );
+ Int j = emit(&hi_isProfInc,
+ insn_bytes, sizeof insn_bytes, hi,
+ mode64, vta->archinfo_host.endness,
+ vta->disp_cp_chain_me_to_slowEP,
+ vta->disp_cp_chain_me_to_fastEP,
+ vta->disp_cp_xindir,
+ vta->disp_cp_xassisted);
if (UNLIKELY(vex_traceflags & VEX_TRACE_ASM)) {
- for (k = 0; k < j; k++)
+ for (Int k = 0; k < j; k++)
vex_printf("%02x ", (UInt)insn_bytes[k]);
vex_printf("\n\n");
}
@@ -1118,7 +1115,7 @@
res.offs_profInc = out_used;
}
{ UChar* dst = &vta->host_bytes[out_used];
- for (k = 0; k < j; k++) {
+ for (Int k = 0; k < j; k++) {
dst[k] = insn_bytes[k];
}
out_used += j;
@@ -1132,8 +1129,8 @@
if (vex_traceflags) {
/* Print the expansion ratio for this SB. */
- j = 0; /* total guest bytes */
- for (i = 0; i < vta->guest_extents->n_used; i++) {
+ UInt j = 0; /* total guest bytes */
+ for (UInt i = 0; i < vta->guest_extents->n_used; i++) {
j += vta->guest_extents->len[i];
}
if (1) vex_printf("VexExpansionRatio %d %d %d :10\n\n",
|
|
From: Philippe W. <phi...@sk...> - 2017-04-16 08:38:19
|
On Fri, 2017-04-14 at 07:27 +0200, Ivo Raisr wrote: > This revision seems to have caused regression on some of the supported > architectures. > I've seen it in all nightly test results so far. > +No symbol "heuristic" in current context. Should be fixed with revision Committed revision 16305 (but only tested on amd64. It should still work on mips platforms) Philippe |
|
From: <sv...@va...> - 2017-04-16 08:36:53
|
Author: philippe
Date: Sun Apr 16 09:36:43 2017
New Revision: 16305
Log:
Fix regression following r16303
Use 'set heuristic-fence-post 999999' only on mips platforms
Modified:
trunk/gdbserver_tests/mcmain_pic.stdinB.gdb
trunk/gdbserver_tests/mcmain_pic.vgtest
Modified: trunk/gdbserver_tests/mcmain_pic.stdinB.gdb
==============================================================================
--- trunk/gdbserver_tests/mcmain_pic.stdinB.gdb (original)
+++ trunk/gdbserver_tests/mcmain_pic.stdinB.gdb Sun Apr 16 09:36:43 2017
@@ -1,7 +1,7 @@
# connect gdb to Valgrind gdbserver:
target remote | ./vgdb --wait=60 --vgdb-prefix=./vgdb-prefix-mcmain_pic
echo vgdb launched process attached\n
-set heuristic-fence-post 999999
+source mcmain_pic.heur
monitor v.set vgdb-error 999999
#
# break
Modified: trunk/gdbserver_tests/mcmain_pic.vgtest
==============================================================================
--- trunk/gdbserver_tests/mcmain_pic.vgtest (original)
+++ trunk/gdbserver_tests/mcmain_pic.vgtest Sun Apr 16 09:36:43 2017
@@ -3,7 +3,7 @@
# information via the gdbserver protocol packet qXfer:auxv:read:
# The content of the auxv data can be shown by gdb using
# gdb command 'info auxv'
-prereq: test -e gdb.pic
+prereq: test -e gdb.pic && if ../tests/arch_test mips32 || ../tests/arch_test mips64 ; then echo "set heuristic-fence-post 999999" ; else echo '' ; fi > mcmain_pic.heur
prog: main_pic
vgopts: --tool=memcheck --vgdb=yes --vgdb-error=0 --vgdb-prefix=./vgdb-prefix-mcmain_pic
stdout_filter: filter_gdb
|
|
From: Ivo R. <iv...@iv...> - 2017-04-14 05:27:33
|
This revision seems to have caused regression on some of the supported
architectures.
I've seen it in all nightly test results so far.
+No symbol "heuristic" in current context.
Please could you investigate and fix?
Thank you,
I.
-----------------------------------------------
New Revision: 16303
Log:
increase heuristic-fence-post limit for gdbserver_tests/mcmain_pic
GDB reports to be "unable to find the start of the function" and suggests
increasing the range of the search using the 'set heuristic-fence-post'
command. So we did.
It fixes gdbserver_tests/mcmain_pic on some platforms.
Modified:
trunk/gdbserver_tests/mcmain_pic.stdinB.gdb
Modified: trunk/gdbserver_tests/mcmain_pic.stdinB.gdb
===========================================================================
--- trunk/gdbserver_tests/mcmain_pic.stdinB.gdb (original)
+++ trunk/gdbserver_tests/mcmain_pic.stdinB.gdb Thu Apr 13 17:11:54 2017
@@ -1,6 +1,7 @@
# connect gdb to Valgrind gdbserver:
target remote | ./vgdb --wait=60 --vgdb-prefix=./vgdb-prefix-mcmain_pic
echo vgdb launched process attached\n
+set heuristic-fence-post 999999
monitor v.set vgdb-error 999999
#
# break
|
|
From: <sv...@va...> - 2017-04-13 16:33:15
|
Author: petarj
Date: Thu Apr 13 17:33:06 2017
New Revision: 16304
Log:
add additional stderr.exp file for helgrind/tests/pth_destroy_cond
On some platforms, Helgrind detects valid additional data race over "cond".
Thread one is at pthread_cond_wait(&cond, &mutex).
Thread two is at pthread_cond_destroy(&cond).
This fixes helgrind/tests/pth_destroy_cond on different platforms.
Contributed by Aleksandra Karadzic.
Added:
trunk/helgrind/tests/pth_destroy_cond.stderr.exp2
Modified:
trunk/helgrind/tests/Makefile.am
Modified: trunk/helgrind/tests/Makefile.am
==============================================================================
--- trunk/helgrind/tests/Makefile.am (original)
+++ trunk/helgrind/tests/Makefile.am Thu Apr 13 17:33:06 2017
@@ -46,7 +46,8 @@
pth_barrier2.vgtest pth_barrier2.stdout.exp pth_barrier2.stderr.exp \
pth_barrier3.vgtest pth_barrier3.stdout.exp pth_barrier3.stderr.exp \
pth_destroy_cond.vgtest \
- pth_destroy_cond.stdout.exp pth_destroy_cond.stderr.exp \
+ pth_destroy_cond.stdout.exp \
+ pth_destroy_cond.stderr.exp pth_destroy_cond.stderr.exp2 \
pth_cond_destroy_busy.vgtest pth_cond_destroy_busy.stderr.exp \
pth_cond_destroy_busy.stderr.exp-ppc64 \
pth_cond_destroy_busy.stderr.exp-solaris \
Added: trunk/helgrind/tests/pth_destroy_cond.stderr.exp2
==============================================================================
--- trunk/helgrind/tests/pth_destroy_cond.stderr.exp2 (added)
+++ trunk/helgrind/tests/pth_destroy_cond.stderr.exp2 Thu Apr 13 17:33:06 2017
@@ -0,0 +1,44 @@
+---Thread-Announcement------------------------------------------
+
+Thread #x was created
+ ...
+ by 0x........: pthread_create@* (hg_intercepts.c:...)
+ by 0x........: main (pth_destroy_cond.c:29)
+
+---Thread-Announcement------------------------------------------
+
+Thread #x is the program's root thread
+
+----------------------------------------------------------------
+
+ Lock at 0x........ was first observed
+ at 0x........: pthread_mutex_init (hg_intercepts.c:...)
+ by 0x........: main (pth_destroy_cond.c:25)
+ Address 0x........ is 0 bytes inside data symbol "mutex"
+
+Possible data race during read of size 1 at 0x........ by thread #x
+Locks held: 1, at address 0x........
+ at 0x........: my_memcmp (hg_intercepts.c:...)
+ by 0x........: pthread_cond_destroy_WRK (hg_intercepts.c:...)
+ by 0x........: pthread_cond_destroy@* (hg_intercepts.c:...)
+ by 0x........: ThreadFunction (pth_destroy_cond.c:18)
+ by 0x........: mythread_wrapper (hg_intercepts.c:...)
+ ...
+
+This conflicts with a previous write of size 4 by thread #x
+Locks held: none
+ ...
+ by 0x........: pthread_cond_wait_WRK (hg_intercepts.c:...)
+ by 0x........: pthread_cond_wait@* (hg_intercepts.c:...)
+ by 0x........: main (pth_destroy_cond.c:31)
+ Address 0x........ is 4 bytes inside data symbol "cond"
+
+----------------------------------------------------------------
+
+Thread #x: pthread_cond_destroy: destruction of condition variable being waited upon
+ at 0x........: pthread_cond_destroy_WRK (hg_intercepts.c:...)
+ by 0x........: pthread_cond_destroy@* (hg_intercepts.c:...)
+ by 0x........: ThreadFunction (pth_destroy_cond.c:18)
+ by 0x........: mythread_wrapper (hg_intercepts.c:...)
+ ...
+
|
|
From: <sv...@va...> - 2017-04-13 16:12:02
|
Author: petarj
Date: Thu Apr 13 17:11:54 2017
New Revision: 16303
Log:
increase heuristic-fence-post limit for gdbserver_tests/mcmain_pic
GDB reports to be "unable to find the start of the function" and suggests
increasing the range of the search using the 'set heuristic-fence-post'
command. So we did.
It fixes gdbserver_tests/mcmain_pic on some platforms.
Modified:
trunk/gdbserver_tests/mcmain_pic.stdinB.gdb
Modified: trunk/gdbserver_tests/mcmain_pic.stdinB.gdb
==============================================================================
--- trunk/gdbserver_tests/mcmain_pic.stdinB.gdb (original)
+++ trunk/gdbserver_tests/mcmain_pic.stdinB.gdb Thu Apr 13 17:11:54 2017
@@ -1,6 +1,7 @@
# connect gdb to Valgrind gdbserver:
target remote | ./vgdb --wait=60 --vgdb-prefix=./vgdb-prefix-mcmain_pic
echo vgdb launched process attached\n
+set heuristic-fence-post 999999
monitor v.set vgdb-error 999999
#
# break
|
|
From: Ivo R. <iv...@iv...> - 2017-04-13 12:33:13
|
Hi folks, I just wanted to let you know about the upcoming event. I'll be there. I. ---------------------------------------------------------------------------------- From: Jan Hubicka <hu...@uc...> Subject: GNU Tools Cauldron 2017, Prague, September 8-10 Hi, we are very pleased to invite you all the GNU Tools Cauldron on 8-10 September 2017. This year we will meet again in Prague, at Charles University. Details are here: https://gcc.gnu.org/wiki/cauldron2017 As usual, please register (capacity is limited), send abstracts and ask administrivia questions to too...@go.... I plan to contact GCC, GDB, binutils, CGEN, DejaGnu, newlib and glibc mailing lists. Please feel free to share with any other groups that are appropriate. Looking forward to see you in Prague, Honza Hubicka |
|
From: <sv...@va...> - 2017-04-12 17:51:53
|
Author: petarj
Date: Wed Apr 12 18:51:45 2017
New Revision: 3348
Log:
fix early initialization of s390_host_hwcaps in LibVEX_FrontEnd
This is a follow-up to r3341 and r3344. r3341 split LibVEX_Translate into
LibVEX_FrontEnd and LibVEX_BackEnd. s390_host_hwcaps needs to be initialized
early when arch_host is VexArchS390X.
This also fixes none/tests/libvexmultiarch_test on MIPS64 BE platforms.
Modified:
trunk/priv/main_main.c
Modified: trunk/priv/main_main.c
==============================================================================
--- trunk/priv/main_main.c (original)
+++ trunk/priv/main_main.c Wed Apr 12 18:51:45 2017
@@ -362,6 +362,11 @@
vex_traceflags = vta->traceflags;
+ /* KLUDGE: export hwcaps. */
+ if (vta->arch_host == VexArchS390X) {
+ s390_host_hwcaps = vta->archinfo_host.hwcaps;
+ }
+
/* First off, check that the guest and host insn sets
are supported. */
@@ -438,9 +443,6 @@
break;
case VexArchS390X:
- /* KLUDGE: export hwcaps. */
- s390_host_hwcaps = vta->archinfo_host.hwcaps;
-
preciseMemExnsFn
= S390FN(guest_s390x_state_requires_precise_mem_exns);
disInstrFn = S390FN(disInstr_S390);
|
|
From: <sv...@va...> - 2017-04-12 13:01:45
|
Author: mjw
Date: Wed Apr 12 14:01:29 2017
New Revision: 16302
Log:
Update libiberty demangler.
Update the libiberty demangler using the auxprogs/update-demangler
script to the gcc svn r246502 revision. Replaces our rust demangling
with the upstream variant (which is basically the same code in a
separate file). Adds handling of inheriting constructor. Handle
noexcept and throw-spec. Demangle Dc as decltype(auto). And various
(crasher) bug fixes.
Bug 378673.
Added:
trunk/coregrind/m_demangle/rust-demangle.c
Modified:
trunk/NEWS
trunk/auxprogs/update-demangler
trunk/coregrind/Makefile.am
trunk/coregrind/m_demangle/ansidecl.h
trunk/coregrind/m_demangle/cp-demangle.c
trunk/coregrind/m_demangle/cp-demangle.h
trunk/coregrind/m_demangle/cplus-dem.c
trunk/coregrind/m_demangle/d-demangle.c
trunk/coregrind/m_demangle/demangle.c
trunk/coregrind/m_demangle/demangle.h
trunk/coregrind/m_demangle/dyn-string.c
trunk/coregrind/m_demangle/dyn-string.h
trunk/coregrind/m_demangle/safe-ctype.c
trunk/coregrind/m_demangle/safe-ctype.h
Modified: trunk/NEWS
==============================================================================
--- trunk/NEWS (original)
+++ trunk/NEWS Wed Apr 12 14:01:29 2017
@@ -155,6 +155,7 @@
377717 Fix massive space leak when reading compressed debuginfo sections
377930 fcntl syscall wrapper is missing flock structure check
378535 Valgrind reports INTERNAL ERROR in execve syscall wrapper
+378673 Update libiberty demangler
Release 3.12.0 (20 October 2016)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Modified: trunk/auxprogs/update-demangler
==============================================================================
--- trunk/auxprogs/update-demangler (original)
+++ trunk/auxprogs/update-demangler Wed Apr 12 14:01:29 2017
@@ -17,8 +17,8 @@
#---------------------------------------------------------------------
# You need to modify these revision numbers for your update.
-old_gcc_revision=r212125 # the revision of the previous update
-new_gcc_revision=r240068 # the revision for this update
+old_gcc_revision=r240068 # the revision of the previous update
+new_gcc_revision=r246502 # the revision for this update
# Unless the organization of demangler related files has changed, no
# changes below this line should be necessary.
@@ -56,6 +56,7 @@
cp ../gcc-$old_gcc_revision/libiberty/cplus-dem.c .
cp ../gcc-$old_gcc_revision/libiberty/dyn-string.c .
cp ../gcc-$old_gcc_revision/libiberty/d-demangle.c .
+cp ../gcc-$old_gcc_revision/libiberty/rust-demangle.c .
cp ../gcc-$old_gcc_revision/libiberty/safe-ctype.c .
cd ..
@@ -83,6 +84,7 @@
cp ../gcc-$new_gcc_revision/libiberty/cplus-dem.c .
cp ../gcc-$new_gcc_revision/libiberty/dyn-string.c .
cp ../gcc-$new_gcc_revision/libiberty/d-demangle.c .
+cp ../gcc-$new_gcc_revision/libiberty/rust-demangle.c .
cp ../gcc-$new_gcc_revision/libiberty/safe-ctype.c .
cd ..
Modified: trunk/coregrind/Makefile.am
==============================================================================
--- trunk/coregrind/Makefile.am (original)
+++ trunk/coregrind/Makefile.am Wed Apr 12 14:01:29 2017
@@ -362,6 +362,7 @@
m_demangle/demangle.c \
m_demangle/dyn-string.c \
m_demangle/d-demangle.c \
+ m_demangle/rust-demangle.c \
m_demangle/safe-ctype.c \
m_dispatch/dispatch-x86-linux.S \
m_dispatch/dispatch-amd64-linux.S \
Modified: trunk/coregrind/m_demangle/ansidecl.h
==============================================================================
--- trunk/coregrind/m_demangle/ansidecl.h (original)
+++ trunk/coregrind/m_demangle/ansidecl.h Wed Apr 12 14:01:29 2017
@@ -1,5 +1,5 @@
/* ANSI and traditional C compatability macros
- Copyright (C) 1991-2015 Free Software Foundation, Inc.
+ Copyright (C) 1991-2017 Free Software Foundation, Inc.
This file is part of the GNU C Library.
This program is free software; you can redistribute it and/or modify
@@ -313,13 +313,39 @@
#define ENUM_BITFIELD(TYPE) unsigned int
#endif
- /* This is used to mark a class or virtual function as final. */
-#if __cplusplus >= 201103L
-#define GCC_FINAL final
+/* C++11 adds the ability to add "override" after an implementation of a
+ virtual function in a subclass, to:
+ (A) document that this is an override of a virtual function
+ (B) allow the compiler to issue a warning if it isn't (e.g. a mismatch
+ of the type signature).
+
+ Similarly, it allows us to add a "final" to indicate that no subclass
+ may subsequently override the vfunc.
+
+ Provide OVERRIDE and FINAL as macros, allowing us to get these benefits
+ when compiling with C++11 support, but without requiring C++11.
+
+ For gcc, use "-std=c++11" to enable C++11 support; gcc 6 onwards enables
+ this by default (actually GNU++14). */
+
+#if __cplusplus >= 201103
+/* C++11 claims to be available: use it. final/override were only
+ implemented in 4.7, though. */
+# if GCC_VERSION < 4007
+# define OVERRIDE
+# define FINAL
+# else
+# define OVERRIDE override
+# define FINAL final
+# endif
#elif GCC_VERSION >= 4007
-#define GCC_FINAL __final
+/* G++ 4.7 supports __final in C++98. */
+# define OVERRIDE
+# define FINAL __final
#else
-#define GCC_FINAL
+/* No C++11 support; leave the macros empty: */
+# define OVERRIDE
+# define FINAL
#endif
#ifdef __cplusplus
Modified: trunk/coregrind/m_demangle/cp-demangle.c
==============================================================================
--- trunk/coregrind/m_demangle/cp-demangle.c (original)
+++ trunk/coregrind/m_demangle/cp-demangle.c Wed Apr 12 14:01:29 2017
@@ -1,6 +1,5 @@
/* Demangler for g++ V3 ABI.
- Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2014
- Free Software Foundation, Inc.
+ Copyright (C) 2003-2017 Free Software Foundation, Inc.
Written by Ian Lance Taylor <ia...@wa...>.
This file is part of the libiberty library, which is part of GCC.
@@ -190,10 +189,10 @@
static struct demangle_component *d_type (struct d_info *);
#define cplus_demangle_print d_print
-static char *d_print (int, const struct demangle_component *, int, size_t *);
+static char *d_print (int, struct demangle_component *, int, size_t *);
#define cplus_demangle_print_callback d_print_callback
-static int d_print_callback (int, const struct demangle_component *,
+static int d_print_callback (int, struct demangle_component *,
demangle_callbackref, void *);
#define cplus_demangle_init_info d_init_info
@@ -282,7 +281,7 @@
in which they appeared in the mangled string. */
struct d_print_mod *next;
/* The modifier. */
- const struct demangle_component *mod;
+ struct demangle_component *mod;
/* Whether this modifier was printed. */
int printed;
/* The list of templates which applies to this modifier. */
@@ -360,6 +359,9 @@
struct d_print_mod *modifiers;
/* Set to 1 if we saw a demangling error. */
int demangle_failure;
+ /* Non-zero if we're printing a lambda argument. A template
+ parameter reference actually means 'auto'. */
+ int is_lambda_arg;
/* The current index into any template argument packs we are using
for printing, or -1 to print the whole pack. */
int pack_index;
@@ -453,6 +455,8 @@
static struct demangle_component *d_special_name (struct d_info *);
+static struct demangle_component *d_parmlist (struct d_info *);
+
static int d_call_offset (struct d_info *, int);
static struct demangle_component *d_ctor_dtor_name (struct d_info *);
@@ -543,7 +547,7 @@
static inline char d_last_char (struct d_print_info *);
static void
-d_print_comp (struct d_print_info *, int, const struct demangle_component *);
+d_print_comp (struct d_print_info *, int, struct demangle_component *);
static void
d_print_java_identifier (struct d_print_info *, const char *, int);
@@ -552,30 +556,56 @@
d_print_mod_list (struct d_print_info *, int, struct d_print_mod *, int);
static void
-d_print_mod (struct d_print_info *, int, const struct demangle_component *);
+d_print_mod (struct d_print_info *, int, struct demangle_component *);
static void
d_print_function_type (struct d_print_info *, int,
- const struct demangle_component *,
+ struct demangle_component *,
struct d_print_mod *);
static void
d_print_array_type (struct d_print_info *, int,
- const struct demangle_component *,
+ struct demangle_component *,
struct d_print_mod *);
static void
-d_print_expr_op (struct d_print_info *, int, const struct demangle_component *);
+d_print_expr_op (struct d_print_info *, int, struct demangle_component *);
static void d_print_cast (struct d_print_info *, int,
- const struct demangle_component *);
+ struct demangle_component *);
static void d_print_conversion (struct d_print_info *, int,
- const struct demangle_component *);
+ struct demangle_component *);
static int d_demangle_callback (const char *, int,
demangle_callbackref, void *);
static char *d_demangle (const char *, int, size_t *);
+/* True iff TYPE is a demangling component representing a
+ function-type-qualifier. */
+
+static int
+is_fnqual_component_type (enum demangle_component_type type)
+{
+ return (type == DEMANGLE_COMPONENT_RESTRICT_THIS
+ || type == DEMANGLE_COMPONENT_VOLATILE_THIS
+ || type == DEMANGLE_COMPONENT_CONST_THIS
+ || type == DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS
+ || type == DEMANGLE_COMPONENT_TRANSACTION_SAFE
+ || type == DEMANGLE_COMPONENT_NOEXCEPT
+ || type == DEMANGLE_COMPONENT_THROW_SPEC
+ || type == DEMANGLE_COMPONENT_REFERENCE_THIS);
+}
+
+#define FNQUAL_COMPONENT_CASE \
+ case DEMANGLE_COMPONENT_RESTRICT_THIS: \
+ case DEMANGLE_COMPONENT_VOLATILE_THIS: \
+ case DEMANGLE_COMPONENT_CONST_THIS: \
+ case DEMANGLE_COMPONENT_REFERENCE_THIS: \
+ case DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS: \
+ case DEMANGLE_COMPONENT_TRANSACTION_SAFE: \
+ case DEMANGLE_COMPONENT_NOEXCEPT: \
+ case DEMANGLE_COMPONENT_THROW_SPEC
+
#ifdef CP_DEMANGLE_DEBUG
static void
@@ -841,6 +871,7 @@
{
if (p == NULL || s == NULL || len == 0)
return 0;
+ p->d_printing = 0;
p->type = DEMANGLE_COMPONENT_NAME;
p->u.s_name.s = s;
p->u.s_name.len = len;
@@ -856,6 +887,7 @@
{
if (p == NULL || args < 0 || name == NULL)
return 0;
+ p->d_printing = 0;
p->type = DEMANGLE_COMPONENT_EXTENDED_OPERATOR;
p->u.s_extended_operator.args = args;
p->u.s_extended_operator.name = name;
@@ -875,6 +907,7 @@
|| (int) kind < gnu_v3_complete_object_ctor
|| (int) kind > gnu_v3_object_ctor_group)
return 0;
+ p->d_printing = 0;
p->type = DEMANGLE_COMPONENT_CTOR;
p->u.s_ctor.kind = kind;
p->u.s_ctor.name = name;
@@ -894,6 +927,7 @@
|| (int) kind < gnu_v3_deleting_dtor
|| (int) kind > gnu_v3_object_dtor_group)
return 0;
+ p->d_printing = 0;
p->type = DEMANGLE_COMPONENT_DTOR;
p->u.s_dtor.kind = kind;
p->u.s_dtor.name = name;
@@ -910,6 +944,7 @@
if (di->next_comp >= di->num_comps)
return NULL;
p = &di->comps[di->next_comp];
+ p->d_printing = 0;
++di->next_comp;
return p;
}
@@ -1001,14 +1036,9 @@
case DEMANGLE_COMPONENT_RESTRICT:
case DEMANGLE_COMPONENT_VOLATILE:
case DEMANGLE_COMPONENT_CONST:
- case DEMANGLE_COMPONENT_RESTRICT_THIS:
- case DEMANGLE_COMPONENT_VOLATILE_THIS:
- case DEMANGLE_COMPONENT_CONST_THIS:
- case DEMANGLE_COMPONENT_TRANSACTION_SAFE:
- case DEMANGLE_COMPONENT_REFERENCE_THIS:
- case DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS:
case DEMANGLE_COMPONENT_ARGLIST:
case DEMANGLE_COMPONENT_TEMPLATE_ARGLIST:
+ FNQUAL_COMPONENT_CASE:
break;
/* Other types should not be seen here. */
@@ -1242,12 +1272,7 @@
return 0;
case DEMANGLE_COMPONENT_TEMPLATE:
return ! is_ctor_dtor_or_conversion (d_left (dc));
- case DEMANGLE_COMPONENT_RESTRICT_THIS:
- case DEMANGLE_COMPONENT_VOLATILE_THIS:
- case DEMANGLE_COMPONENT_CONST_THIS:
- case DEMANGLE_COMPONENT_REFERENCE_THIS:
- case DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS:
- case DEMANGLE_COMPONENT_TRANSACTION_SAFE:
+ FNQUAL_COMPONENT_CASE:
return has_return_type (d_left (dc));
}
}
@@ -1304,13 +1329,12 @@
while (dc->type == DEMANGLE_COMPONENT_RESTRICT_THIS
|| dc->type == DEMANGLE_COMPONENT_VOLATILE_THIS
|| dc->type == DEMANGLE_COMPONENT_CONST_THIS
- || dc->type == DEMANGLE_COMPONENT_TRANSACTION_SAFE
|| dc->type == DEMANGLE_COMPONENT_REFERENCE_THIS
|| dc->type == DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS)
dc = d_left (dc);
/* If the top level is a DEMANGLE_COMPONENT_LOCAL_NAME, then
- there may be CV-qualifiers on its right argument which
+ there may be function-qualifiers on its right argument which
really apply here; this happens when parsing a class
which is local to a function. */
if (dc->type == DEMANGLE_COMPONENT_LOCAL_NAME)
@@ -1318,12 +1342,7 @@
struct demangle_component *dcr;
dcr = d_right (dc);
- while (dcr->type == DEMANGLE_COMPONENT_RESTRICT_THIS
- || dcr->type == DEMANGLE_COMPONENT_VOLATILE_THIS
- || dcr->type == DEMANGLE_COMPONENT_CONST_THIS
- || dcr->type == DEMANGLE_COMPONENT_TRANSACTION_SAFE
- || dcr->type == DEMANGLE_COMPONENT_REFERENCE_THIS
- || dcr->type == DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS)
+ while (is_fnqual_component_type (dcr->type))
dcr = d_left (dcr);
dc->u.s_binary.right = dcr;
}
@@ -1597,6 +1616,8 @@
ret = d_source_name (di);
else if (IS_LOWER (peek))
{
+ if (peek == 'o' && d_peek_next_char (di) == 'n')
+ d_advance (di, 2);
ret = d_operator_name (di);
if (ret != NULL && ret->type == DEMANGLE_COMPONENT_OPERATOR)
{
@@ -2185,6 +2206,13 @@
case 'C':
{
enum gnu_v3_ctor_kinds kind;
+ int inheriting = 0;
+
+ if (d_peek_next_char (di) == 'I')
+ {
+ inheriting = 1;
+ d_advance (di, 1);
+ }
switch (d_peek_next_char (di))
{
@@ -2206,7 +2234,12 @@
default:
return NULL;
}
+
d_advance (di, 2);
+
+ if (inheriting)
+ cplus_demangle_type (di);
+
return d_make_ctor (di, kind, di->last_name);
}
@@ -2244,6 +2277,24 @@
}
}
+/* True iff we're looking at an order-insensitive type-qualifier, including
+ function-type-qualifiers. */
+
+static int
+next_is_type_qual (struct d_info *di)
+{
+ char peek = d_peek_char (di);
+ if (peek == 'r' || peek == 'V' || peek == 'K')
+ return 1;
+ if (peek == 'D')
+ {
+ peek = d_peek_next_char (di);
+ if (peek == 'x' || peek == 'o' || peek == 'O' || peek == 'w')
+ return 1;
+ }
+ return 0;
+}
+
/* <type> ::= <builtin-type>
::= <function-type>
::= <class-enum-type>
@@ -2329,9 +2380,7 @@
__vector, and it treats it as order-sensitive when mangling
names. */
- peek = d_peek_char (di);
- if (peek == 'r' || peek == 'V' || peek == 'K'
- || (peek == 'D' && d_peek_next_char (di) == 'x'))
+ if (next_is_type_qual (di))
{
struct demangle_component **pret;
@@ -2366,6 +2415,7 @@
can_subst = 1;
+ peek = d_peek_char (di);
switch (peek)
{
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g':
@@ -2566,7 +2616,11 @@
/* auto */
ret = d_make_name (di, "auto", 4);
break;
-
+ case 'c':
+ /* decltype(auto) */
+ ret = d_make_name (di, "decltype(auto)", 14);
+ break;
+
case 'f':
/* 32-bit decimal floating point */
ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[26]);
@@ -2653,10 +2707,10 @@
pstart = pret;
peek = d_peek_char (di);
- while (peek == 'r' || peek == 'V' || peek == 'K'
- || (peek == 'D' && d_peek_next_char (di) == 'x'))
+ while (next_is_type_qual (di))
{
enum demangle_component_type t;
+ struct demangle_component *right = NULL;
d_advance (di, 1);
if (peek == 'r')
@@ -2682,12 +2736,41 @@
}
else
{
- t = DEMANGLE_COMPONENT_TRANSACTION_SAFE;
- di->expansion += sizeof "transaction_safe";
- d_advance (di, 1);
+ peek = d_next_char (di);
+ if (peek == 'x')
+ {
+ t = DEMANGLE_COMPONENT_TRANSACTION_SAFE;
+ di->expansion += sizeof "transaction_safe";
+ }
+ else if (peek == 'o'
+ || peek == 'O')
+ {
+ t = DEMANGLE_COMPONENT_NOEXCEPT;
+ di->expansion += sizeof "noexcept";
+ if (peek == 'O')
+ {
+ right = d_expression (di);
+ if (right == NULL)
+ return NULL;
+ if (! d_check_char (di, 'E'))
+ return NULL;
+ }
+ }
+ else if (peek == 'w')
+ {
+ t = DEMANGLE_COMPONENT_THROW_SPEC;
+ di->expansion += sizeof "throw";
+ right = d_parmlist (di);
+ if (right == NULL)
+ return NULL;
+ if (! d_check_char (di, 'E'))
+ return NULL;
+ }
+ else
+ return NULL;
}
- *pret = d_make_comp (di, t, NULL, NULL);
+ *pret = d_make_comp (di, t, NULL, right);
if (*pret == NULL)
return NULL;
pret = &d_left (*pret);
@@ -3362,6 +3445,8 @@
first = d_expression_1 (di);
second = d_expression_1 (di);
third = d_expression_1 (di);
+ if (third == NULL)
+ return NULL;
}
else if (code[0] == 'f')
{
@@ -3369,6 +3454,8 @@
first = d_operator_name (di);
second = d_expression_1 (di);
third = d_expression_1 (di);
+ if (third == NULL)
+ return NULL;
}
else if (code[0] == 'n')
{
@@ -3546,7 +3633,11 @@
}
}
-/* <discriminator> ::= _ <(non-negative) number>
+/* <discriminator> ::= _ <number> # when number < 10
+ ::= __ <number> _ # when number >= 10
+
+ <discriminator> ::= _ <number> # when number >=10
+ is also accepted to support gcc versions that wrongly mangled that way.
We demangle the discriminator, but we don't print it out. FIXME:
We should print it out in verbose mode. */
@@ -3554,14 +3645,28 @@
static int
d_discriminator (struct d_info *di)
{
- int discrim;
+ int discrim, num_underscores = 1;
if (d_peek_char (di) != '_')
return 1;
d_advance (di, 1);
+ if (d_peek_char (di) == '_')
+ {
+ ++num_underscores;
+ d_advance (di, 1);
+ }
+
discrim = d_number (di);
if (discrim < 0)
return 0;
+ if (num_underscores > 1 && discrim >= 10)
+ {
+ if (d_peek_char (di) == '_')
+ d_advance (di, 1);
+ else
+ return 0;
+ }
+
return 1;
}
@@ -3978,6 +4083,8 @@
case DEMANGLE_COMPONENT_REFERENCE_THIS:
case DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS:
case DEMANGLE_COMPONENT_TRANSACTION_SAFE:
+ case DEMANGLE_COMPONENT_NOEXCEPT:
+ case DEMANGLE_COMPONENT_THROW_SPEC:
case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL:
case DEMANGLE_COMPONENT_POINTER:
case DEMANGLE_COMPONENT_COMPLEX:
@@ -4067,6 +4174,7 @@
dpi->opaque = opaque;
dpi->demangle_failure = 0;
+ dpi->is_lambda_arg = 0;
dpi->component_stack = NULL;
@@ -4163,7 +4271,7 @@
CP_STATIC_IF_GLIBCPP_V3
int
cplus_demangle_print_callback (int options,
- const struct demangle_component *dc,
+ struct demangle_component *dc,
demangle_callbackref callback, void *opaque)
{
struct d_print_info dpi;
@@ -4222,7 +4330,7 @@
CP_STATIC_IF_GLIBCPP_V3
char *
-cplus_demangle_print (int options, const struct demangle_component *dc,
+cplus_demangle_print (int options, struct demangle_component *dc,
int estimate, size_t *palc)
{
struct d_growable_string dgs;
@@ -4382,7 +4490,7 @@
static void
d_print_subexpr (struct d_print_info *dpi, int options,
- const struct demangle_component *dc)
+ struct demangle_component *dc)
{
int simple = 0;
if (dc->type == DEMANGLE_COMPONENT_NAME
@@ -4458,9 +4566,9 @@
static int
d_maybe_print_fold_expression (struct d_print_info *dpi, int options,
- const struct demangle_component *dc)
+ struct demangle_component *dc)
{
- const struct demangle_component *ops, *operator_, *op1, *op2;
+ struct demangle_component *ops, *operator_, *op1, *op2;
int save_idx;
const char *fold_code = d_left (dc)->u.s_operator.op->code;
@@ -4521,11 +4629,11 @@
static void
d_print_comp_inner (struct d_print_info *dpi, int options,
- const struct demangle_component *dc)
+ struct demangle_component *dc)
{
/* Magic variable to let reference smashing skip over the next modifier
without needing to modify *dc. */
- const struct demangle_component *mod_inner = NULL;
+ struct demangle_component *mod_inner = NULL;
/* Variable used to store the current templates while a previously
captured scope is used. */
@@ -4608,12 +4716,7 @@
adpm[i].templates = dpi->templates;
++i;
- if (typed_name->type != DEMANGLE_COMPONENT_RESTRICT_THIS
- && typed_name->type != DEMANGLE_COMPONENT_VOLATILE_THIS
- && typed_name->type != DEMANGLE_COMPONENT_CONST_THIS
- && typed_name->type != DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS
- && typed_name->type != DEMANGLE_COMPONENT_TRANSACTION_SAFE
- && typed_name->type != DEMANGLE_COMPONENT_REFERENCE_THIS)
+ if (!is_fnqual_component_type (typed_name->type))
break;
typed_name = d_left (typed_name);
@@ -4650,13 +4753,7 @@
d_print_error (dpi);
return;
}
- while (local_name->type == DEMANGLE_COMPONENT_RESTRICT_THIS
- || local_name->type == DEMANGLE_COMPONENT_VOLATILE_THIS
- || local_name->type == DEMANGLE_COMPONENT_CONST_THIS
- || local_name->type == DEMANGLE_COMPONENT_REFERENCE_THIS
- || local_name->type == DEMANGLE_COMPONENT_TRANSACTION_SAFE
- || (local_name->type
- == DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS))
+ while (is_fnqual_component_type (local_name->type))
{
if (i >= sizeof adpm / sizeof adpm[0])
{
@@ -4751,33 +4848,41 @@
}
case DEMANGLE_COMPONENT_TEMPLATE_PARAM:
- {
- struct d_print_template *hold_dpt;
- struct demangle_component *a = d_lookup_template_argument (dpi, dc);
-
- if (a && a->type == DEMANGLE_COMPONENT_TEMPLATE_ARGLIST)
- a = d_index_template_argument (a, dpi->pack_index);
+ if (dpi->is_lambda_arg)
+ {
+ /* Show the template parm index, as that's how g++ displays
+ these, and future proofs us against potential
+ '[]<typename T> (T *a, T *b) {...}'. */
+ d_append_buffer (dpi, "auto:", 5);
+ d_append_num (dpi, dc->u.s_number.number + 1);
+ }
+ else
+ {
+ struct d_print_template *hold_dpt;
+ struct demangle_component *a = d_lookup_template_argument (dpi, dc);
- if (a == NULL)
- {
- d_print_error (dpi);
- return;
- }
+ if (a && a->type == DEMANGLE_COMPONENT_TEMPLATE_ARGLIST)
+ a = d_index_template_argument (a, dpi->pack_index);
- /* While processing this parameter, we need to pop the list of
- templates. This is because the template parameter may
- itself be a reference to a parameter of an outer
- template. */
+ if (a == NULL)
+ {
+ d_print_error (dpi);
+ return;
+ }
- hold_dpt = dpi->templates;
- dpi->templates = hold_dpt->next;
+ /* While processing this parameter, we need to pop the list
+ of templates. This is because the template parameter may
+ itself be a reference to a parameter of an outer
+ template. */
- d_print_comp (dpi, options, a);
+ hold_dpt = dpi->templates;
+ dpi->templates = hold_dpt->next;
- dpi->templates = hold_dpt;
+ d_print_comp (dpi, options, a);
- return;
- }
+ dpi->templates = hold_dpt;
+ }
+ return;
case DEMANGLE_COMPONENT_CTOR:
d_print_comp (dpi, options, dc->u.s_ctor.name);
@@ -4913,8 +5018,9 @@
case DEMANGLE_COMPONENT_RVALUE_REFERENCE:
{
/* Handle reference smashing: & + && = &. */
- const struct demangle_component *sub = d_left (dc);
- if (sub->type == DEMANGLE_COMPONENT_TEMPLATE_PARAM)
+ struct demangle_component *sub = d_left (dc);
+ if (!dpi->is_lambda_arg
+ && sub->type == DEMANGLE_COMPONENT_TEMPLATE_PARAM)
{
struct d_saved_scope *scope = d_get_saved_scope (dpi, sub);
struct demangle_component *a;
@@ -4981,16 +5087,11 @@
}
/* Fall through. */
- case DEMANGLE_COMPONENT_RESTRICT_THIS:
- case DEMANGLE_COMPONENT_VOLATILE_THIS:
- case DEMANGLE_COMPONENT_CONST_THIS:
- case DEMANGLE_COMPONENT_REFERENCE_THIS:
- case DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS:
case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL:
case DEMANGLE_COMPONENT_POINTER:
case DEMANGLE_COMPONENT_COMPLEX:
case DEMANGLE_COMPONENT_IMAGINARY:
- case DEMANGLE_COMPONENT_TRANSACTION_SAFE:
+ FNQUAL_COMPONENT_CASE:
modifier:
{
/* We keep a list of modifiers on the stack. */
@@ -5589,7 +5690,11 @@
case DEMANGLE_COMPONENT_LAMBDA:
d_append_string (dpi, "{lambda(");
+ /* Generic lambda auto parms are mangled as the template type
+ parm they are. */
+ dpi->is_lambda_arg++;
d_print_comp (dpi, options, dc->u.s_unary_num.sub);
+ dpi->is_lambda_arg--;
d_append_string (dpi, ")#");
d_append_num (dpi, dc->u.s_unary_num.num + 1);
d_append_char (dpi, '}');
@@ -5616,9 +5721,16 @@
static void
d_print_comp (struct d_print_info *dpi, int options,
- const struct demangle_component *dc)
+ struct demangle_component *dc)
{
struct d_component_stack self;
+ if (dc == NULL || dc->d_printing > 1)
+ {
+ d_print_error (dpi);
+ return;
+ }
+ else
+ dc->d_printing++;
self.dc = dc;
self.parent = dpi->component_stack;
@@ -5627,6 +5739,7 @@
d_print_comp_inner (dpi, options, dc);
dpi->component_stack = self.parent;
+ dc->d_printing--;
}
/* Print a Java dentifier. For Java we try to handle encoded extended
@@ -5695,13 +5808,7 @@
if (mods->printed
|| (! suffix
- && (mods->mod->type == DEMANGLE_COMPONENT_RESTRICT_THIS
- || mods->mod->type == DEMANGLE_COMPONENT_VOLATILE_THIS
- || mods->mod->type == DEMANGLE_COMPONENT_CONST_THIS
- || mods->mod->type == DEMANGLE_COMPONENT_REFERENCE_THIS
- || mods->mod->type == DEMANGLE_COMPONENT_TRANSACTION_SAFE
- || (mods->mod->type
- == DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS))))
+ && (is_fnqual_component_type (mods->mod->type))))
{
d_print_mod_list (dpi, options, mods->next, suffix);
return;
@@ -5754,12 +5861,7 @@
dc = dc->u.s_unary_num.sub;
}
- while (dc->type == DEMANGLE_COMPONENT_RESTRICT_THIS
- || dc->type == DEMANGLE_COMPONENT_VOLATILE_THIS
- || dc->type == DEMANGLE_COMPONENT_CONST_THIS
- || dc->type == DEMANGLE_COMPONENT_REFERENCE_THIS
- || dc->type == DEMANGLE_COMPONENT_TRANSACTION_SAFE
- || dc->type == DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS)
+ while (is_fnqual_component_type (dc->type))
dc = d_left (dc);
d_print_comp (dpi, options, dc);
@@ -5779,7 +5881,7 @@
static void
d_print_mod (struct d_print_info *dpi, int options,
- const struct demangle_component *mod)
+ struct demangle_component *mod)
{
switch (mod->type)
{
@@ -5798,6 +5900,24 @@
case DEMANGLE_COMPONENT_TRANSACTION_SAFE:
d_append_string (dpi, " transaction_safe");
return;
+ case DEMANGLE_COMPONENT_NOEXCEPT:
+ d_append_string (dpi, " noexcept");
+ if (d_right (mod))
+ {
+ d_append_char (dpi, '(');
+ d_print_comp (dpi, options, d_right (mod));
+ d_append_char (dpi, ')');
+ }
+ return;
+ case DEMANGLE_COMPONENT_THROW_SPEC:
+ d_append_string (dpi, " throw");
+ if (d_right (mod))
+ {
+ d_append_char (dpi, '(');
+ d_print_comp (dpi, options, d_right (mod));
+ d_append_char (dpi, ')');
+ }
+ return;
case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL:
d_append_char (dpi, ' ');
d_print_comp (dpi, options, d_right (mod));
@@ -5853,7 +5973,7 @@
static void
d_print_function_type (struct d_print_info *dpi, int options,
- const struct demangle_component *dc,
+ struct demangle_component *dc,
struct d_print_mod *mods)
{
int need_paren;
@@ -5885,12 +6005,7 @@
need_space = 1;
need_paren = 1;
break;
- case DEMANGLE_COMPONENT_RESTRICT_THIS:
- case DEMANGLE_COMPONENT_VOLATILE_THIS:
- case DEMANGLE_COMPONENT_CONST_THIS:
- case DEMANGLE_COMPONENT_REFERENCE_THIS:
- case DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS:
- case DEMANGLE_COMPONENT_TRANSACTION_SAFE:
+ FNQUAL_COMPONENT_CASE:
break;
default:
break;
@@ -5936,7 +6051,7 @@
static void
d_print_array_type (struct d_print_info *dpi, int options,
- const struct demangle_component *dc,
+ struct demangle_component *dc,
struct d_print_mod *mods)
{
int need_space;
@@ -5990,7 +6105,7 @@
static void
d_print_expr_op (struct d_print_info *dpi, int options,
- const struct demangle_component *dc)
+ struct demangle_component *dc)
{
if (dc->type == DEMANGLE_COMPONENT_OPERATOR)
d_append_buffer (dpi, dc->u.s_operator.op->name,
@@ -6003,7 +6118,7 @@
static void
d_print_cast (struct d_print_info *dpi, int options,
- const struct demangle_component *dc)
+ struct demangle_component *dc)
{
d_print_comp (dpi, options, d_left (dc));
}
@@ -6012,7 +6127,7 @@
static void
d_print_conversion (struct d_print_info *dpi, int options,
- const struct demangle_component *dc)
+ struct demangle_component *dc)
{
struct d_print_template dpt;
@@ -6451,7 +6566,6 @@
case DEMANGLE_COMPONENT_CONST_THIS:
case DEMANGLE_COMPONENT_REFERENCE_THIS:
case DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS:
- case DEMANGLE_COMPONENT_TRANSACTION_SAFE:
default:
dc = NULL;
break;
Modified: trunk/coregrind/m_demangle/cp-demangle.h
==============================================================================
--- trunk/coregrind/m_demangle/cp-demangle.h (original)
+++ trunk/coregrind/m_demangle/cp-demangle.h Wed Apr 12 14:01:29 2017
@@ -1,6 +1,5 @@
/* Internal demangler interface for g++ V3 ABI.
- Copyright (C) 2003, 2004, 2005, 2006, 2007, 2010
- Free Software Foundation, Inc.
+ Copyright (C) 2003-2017 Free Software Foundation, Inc.
Written by Ian Lance Taylor <ia...@wa...>.
This file is part of the libiberty library, which is part of GCC.
Modified: trunk/coregrind/m_demangle/cplus-dem.c
==============================================================================
--- trunk/coregrind/m_demangle/cplus-dem.c (original)
+++ trunk/coregrind/m_demangle/cplus-dem.c Wed Apr 12 14:01:29 2017
@@ -1,6 +1,5 @@
/* Demangler for GNU C++
- Copyright 1989, 1991, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003, 2004, 2010 Free Software Foundation, Inc.
+ Copyright (C) 1989-2017 Free Software Foundation, Inc.
Written by James Clark (jjc@jclark.uucp)
Rewritten by Fred Fish (fn...@cy...) for ARM and Lucid demangling
Modified by Satish Pai (pa...@ap...) for HP demangling
@@ -343,6 +342,12 @@
}
,
{
+ RUST_DEMANGLING_STYLE_STRING,
+ rust_demangling,
+ "Rust style demangling"
+ }
+ ,
+ {
NULL, unknown_demangling, NULL
}
};
@@ -893,10 +898,26 @@
work->options |= (int) current_demangling_style & DMGL_STYLE_MASK;
/* The V3 ABI demangling is implemented elsewhere. */
- if (GNU_V3_DEMANGLING || AUTO_DEMANGLING)
+ if (GNU_V3_DEMANGLING || RUST_DEMANGLING || AUTO_DEMANGLING)
{
ret = cplus_demangle_v3 (mangled, work->options);
- if (ret || GNU_V3_DEMANGLING)
+ if (GNU_V3_DEMANGLING)
+ return ret;
+
+ if (ret)
+ {
+ /* Rust symbols are GNU_V3 mangled plus some extra subtitutions.
+ The subtitutions are always smaller, so do in place changes. */
+ if (rust_is_mangled (ret))
+ rust_demangle_sym (ret);
+ else if (RUST_DEMANGLING)
+ {
+ free (ret);
+ ret = NULL;
+ }
+ }
+
+ if (ret || RUST_DEMANGLING)
return ret;
}
@@ -922,6 +943,27 @@
return (ret);
}
+char *
+rust_demangle (const char *mangled, int options)
+{
+ /* Rust symbols are GNU_V3 mangled plus some extra subtitutions. */
+ char *ret = cplus_demangle_v3 (mangled, options);
+
+ /* The Rust subtitutions are always smaller, so do in place changes. */
+ if (ret != NULL)
+ {
+ if (rust_is_mangled (ret))
+ rust_demangle_sym (ret);
+ else
+ {
+ free (ret);
+ ret = NULL;
+ }
+ }
+
+ return ret;
+}
+
/* Demangle ada names. The encoding is documented in gcc/ada/exp_dbug.ads. */
char *
@@ -930,7 +972,7 @@
int len0;
const char* p;
char *d;
- char *demangled;
+ char *demangled = NULL;
/* Discard leading _ada_, which is used for library level subprograms. */
if (strncmp (mangled, "_ada_", 5) == 0)
@@ -1175,6 +1217,7 @@
return demangled;
unknown:
+ XDELETEVEC (demangled);
len0 = strlen (mangled);
demangled = XNEWVEC (char, len0 + 3);
@@ -1672,12 +1715,13 @@
0);
if (!(work->constructor & 1))
expect_return_type = 1;
- (*mangled)++;
+ if (!**mangled)
+ success = 0;
+ else
+ (*mangled)++;
break;
}
- else
- /* fall through */
- {;}
+ /* fall through */
default:
if (AUTO_DEMANGLING || GNU_DEMANGLING)
@@ -2153,6 +2197,8 @@
{
int idx;
(*mangled)++;
+ if (**mangled == '\0')
+ return (0);
(*mangled)++;
idx = consume_count_with_underscores (mangled);
@@ -2997,7 +3043,7 @@
int success = 1;
const char *p;
- if ((*mangled)[0] == '_'
+ if ((*mangled)[0] == '_' && (*mangled)[1] != '\0'
&& strchr (cplus_markers, (*mangled)[1]) != NULL
&& (*mangled)[2] == '_')
{
@@ -3011,7 +3057,7 @@
&& (*mangled)[3] == 't'
&& (*mangled)[4] == '_')
|| ((*mangled)[1] == 'v'
- && (*mangled)[2] == 't'
+ && (*mangled)[2] == 't' && (*mangled)[3] != '\0'
&& strchr (cplus_markers, (*mangled)[3]) != NULL)))
{
/* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
@@ -3781,11 +3827,12 @@
break;
}
- if (*(*mangled)++ != 'F')
+ if (*(*mangled) != 'F')
{
success = 0;
break;
}
+ (*mangled)++;
}
if ((member && !demangle_nested_args (work, mangled, &decl))
|| **mangled != '_')
@@ -4042,6 +4089,7 @@
success = 0;
break;
}
+ /* fall through */
case 'I':
(*mangled)++;
if (**mangled == '_')
Modified: trunk/coregrind/m_demangle/d-demangle.c
==============================================================================
--- trunk/coregrind/m_demangle/d-demangle.c (original)
+++ trunk/coregrind/m_demangle/d-demangle.c Wed Apr 12 14:01:29 2017
@@ -1,5 +1,5 @@
/* Demangler for the D programming language
- Copyright 2014, 2015, 2016 Free Software Foundation, Inc.
+ Copyright (C) 2014-2017 Free Software Foundation, Inc.
Written by Iain Buclaw (ib...@gd...)
This file is part of the libiberty library.
Modified: trunk/coregrind/m_demangle/demangle.c
==============================================================================
--- trunk/coregrind/m_demangle/demangle.c (original)
+++ trunk/coregrind/m_demangle/demangle.c Wed Apr 12 14:01:29 2017
@@ -43,10 +43,6 @@
#include "vg_libciface.h"
#include "demangle.h"
-/* fwds */
-static Bool rust_is_mangled ( const HChar* );
-static void rust_demangle_sym ( HChar* );
-
/*------------------------------------------------------------*/
/*--- ---*/
@@ -408,297 +404,6 @@
}
-/*------------------------------------------------------------*/
-/*--- DEMANGLE RUST NAMES ---*/
-/*------------------------------------------------------------*/
-
-/*
- * Mangled Rust symbols look like this:
- *
- * _$LT$std..sys..fd..FileDesc$u20$as$u20$core..ops..Drop$GT$::drop::hc68340e1baa4987a
- *
- * The original symbol is:
- *
- * <std::sys::fd::FileDesc as core::ops::Drop>::drop
- *
- * The last component of the path is a 64-bit hash in lowercase hex, prefixed
- * with "h". Rust does not have a global namespace between crates, an illusion
- * which Rust maintains by using the hash to distinguish things that would
- * otherwise have the same symbol.
- *
- * Any path component not starting with a XID_Start character is prefixed with
- * "_".
- *
- * The following escape sequences are used:
- *
- * "," => $C$
- * "@" => $SP$
- * "*" => $BP$
- * "&" => $RF$
- * "<" => $LT$
- * ">" => $GT$
- * "(" => $LP$
- * ")" => $RP$
- * " " => $u20$
- * "\"" => $u22$
- * "'" => $u27$
- * "+" => $u2b$
- * ";" => $u3b$
- * "[" => $u5b$
- * "]" => $u5d$
- * "{" => $u7b$
- * "}" => $u7d$
- * "~" => $u7e$
- *
- * A double ".." means "::" and a single "." means "-".
- *
- * The only characters allowed in the mangled symbol are a-zA-Z0-9 and _.:$
- */
-
-static const HChar *hash_prefix = "::h";
-static const SizeT hash_prefix_len = 3;
-static const SizeT hash_len = 16;
-
-static Bool is_prefixed_hash(const HChar *start);
-static Bool looks_like_rust(const HChar *sym, SizeT len);
-static Bool unescape(const HChar **in, HChar **out,
- const HChar *seq, HChar value);
-
-/*
- * INPUT:
- * sym: symbol that has been through BFD-demangling
- *
- * This function looks for the following indicators:
- *
- * 1. The hash must consist of "h" followed by 16 lowercase hex digits.
- *
- * 2. As a sanity check, the hash must use between 5 and 15 of the 16 possible
- * hex digits. This is true of 99.9998% of hashes so once in your life you
- * may see a false negative. The point is to notice path components that
- * could be Rust hashes but are probably not, like "haaaaaaaaaaaaaaaa". In
- * this case a false positive (non-Rust symbol has an important path
- * component removed because it looks like a Rust hash) is worse than a
- * false negative (the rare Rust symbol is not demangled) so this sets the
- * balance in favor of false negatives.
- *
- * 3. There must be no characters other than a-zA-Z0-9 and _.:$
- *
- * 4. There must be no unrecognized $-sign sequences.
- *
- * 5. There must be no sequence of three or more dots in a row ("...").
- */
-static Bool rust_is_mangled(const HChar *sym)
-{
- SizeT len, len_without_hash;
-
- if (!sym)
- return False;
-
- len = VG_(strlen)(sym);
- if (len <= hash_prefix_len + hash_len)
- /* Not long enough to contain "::h" + hash + something else */
- return False;
-
- len_without_hash = len - (hash_prefix_len + hash_len);
- if (!is_prefixed_hash(sym + len_without_hash))
- return False;
-
- return looks_like_rust(sym, len_without_hash);
-}
-
-/*
- * A hash is the prefix "::h" followed by 16 lowercase hex digits. The hex
- * digits must comprise between 5 and 15 (inclusive) distinct digits.
- */
-static Bool is_prefixed_hash(const HChar *str)
-{
- const HChar *end;
- Bool seen[16];
- SizeT i;
- Int count;
-
- if (VG_(strncmp)(str, hash_prefix, hash_prefix_len))
- return False;
- str += hash_prefix_len;
-
- VG_(memset)(seen, False, sizeof(seen));
- for (end = str + hash_len; str < end; str++)
- if (*str >= '0' && *str <= '9')
- seen[*str - '0'] = True;
- else if (*str >= 'a' && *str <= 'f')
- seen[*str - 'a' + 10] = True;
- else
- return False;
-
- /* Count how many distinct digits seen */
- count = 0;
- for (i = 0; i < 16; i++)
- if (seen[i])
- count++;
-
- return count >= 5 && count <= 15;
-}
-
-static Bool looks_like_rust(const HChar *str, SizeT len)
-{
- const HChar *end = str + len;
-
- while (str < end) {
- switch (*str) {
- case '$':
- if (!VG_(strncmp)(str, "$C$", 3))
- str += 3;
- else if (!VG_(strncmp)(str, "$SP$", 4)
- || !VG_(strncmp)(str, "$BP$", 4)
- || !VG_(strncmp)(str, "$RF$", 4)
- || !VG_(strncmp)(str, "$LT$", 4)
- || !VG_(strncmp)(str, "$GT$", 4)
- || !VG_(strncmp)(str, "$LP$", 4)
- || !VG_(strncmp)(str, "$RP$", 4))
- str += 4;
- else if (!VG_(strncmp)(str, "$u20$", 5)
- || !VG_(strncmp)(str, "$u22$", 5)
- || !VG_(strncmp)(str, "$u27$", 5)
- || !VG_(strncmp)(str, "$u2b$", 5)
- || !VG_(strncmp)(str, "$u3b$", 5)
- || !VG_(strncmp)(str, "$u5b$", 5)
- || !VG_(strncmp)(str, "$u5d$", 5)
- || !VG_(strncmp)(str, "$u7b$", 5)
- || !VG_(strncmp)(str, "$u7d$", 5)
- || !VG_(strncmp)(str, "$u7e$", 5))
- str += 5;
- else
- return False;
- break;
- case '.':
- /* Do not allow three or more consecutive dots */
- if (!VG_(strncmp)(str, "...", 3))
- return False;
- /* Fall through */
- case 'a' ... 'z':
- case 'A' ... 'Z':
- case '0' ... '9':
- case '_':
- case ':':
- str++;
- break;
- default:
- return False;
- }
- }
-
- return True;
-}
-
-/*
- * INPUT:
- * sym: symbol for which rust_is_mangled(sym) returns True
- *
- * The input is demangled in-place because the mangled name is always longer
- * than the demangled one.
- */
-static void rust_demangle_sym(HChar *sym)
-{
- const HChar *in;
- HChar *out;
- const HChar *end;
-
- if (!sym)
- return;
-
- const SizeT sym_len = VG_(strlen)(sym);
- const HChar* never_after = sym + sym_len;
-
- in = sym;
- out = sym;
- end = sym + sym_len - (hash_prefix_len + hash_len);
-
- while (in < end) {
- switch (*in) {
- case '$':
- if (!(unescape(&in, &out, "$C$", ',')
- || unescape(&in, &out, "$SP$", '@')
- || unescape(&in, &out, "$BP$", '*')
- || unescape(&in, &out, "$RF$", '&')
- || unescape(&in, &out, "$LT$", '<')
- || unescape(&in, &out, "$GT$", '>')
- || unescape(&in, &out, "$LP$", '(')
- || unescape(&in, &out, "$RP$", ')')
- || unescape(&in, &out, "$u20$", ' ')
- || unescape(&in, &out, "$u22$", '\"')
- || unescape(&in, &out, "$u27$", '\'')
- || unescape(&in, &out, "$u2b$", '+')
- || unescape(&in, &out, "$u3b$", ';')
- || unescape(&in, &out, "$u5b$", '[')
- || unescape(&in, &out, "$u5d$", ']')
- || unescape(&in, &out, "$u7b$", '{')
- || unescape(&in, &out, "$u7d$", '}')
- || unescape(&in, &out, "$u7e$", '~'))) {
- goto fail;
- }
- break;
- case '_':
- /*
- * If this is the start of a path component and the next
- * character is an escape sequence, ignore the
- * underscore. The mangler inserts an underscore to make
- * sure the path component begins with a XID_Start
- * character.
- */
- if ((in == sym || in[-1] == ':') && in[1] == '$')
- in++;
- else
- *out++ = *in++;
- break;
- case '.':
- if (in[1] == '.') {
- /* ".." becomes "::" */
- *out++ = ':';
- *out++ = ':';
- in += 2;
- } else {
- /* "." becomes "-" */
- *out++ = '-';
- in++;
- }
- break;
- case 'a' ... 'z':
- case 'A' ... 'Z':
- case '0' ... '9':
- case ':':
- *out++ = *in++;
- break;
- default:
- goto fail;
- }
- }
- goto done;
-
- fail:
- *out++ = '?'; /* This is pretty lame, but it's hard to do better. */
- done:
- *out++ = '\0';
-
- vg_assert(out <= never_after);
-}
-
-static Bool unescape(const HChar **in, HChar **out,
- const HChar *seq, HChar value)
-{
- SizeT len = VG_(strlen)(seq);
-
- if (VG_(strncmp)(*in, seq, len))
- return False;
-
- **out = value;
-
- *in += len;
- *out += 1;
-
- return True;
-}
-
-
/*--------------------------------------------------------------------*/
/*--- end ---*/
/*--------------------------------------------------------------------*/
Modified: trunk/coregrind/m_demangle/demangle.h
==============================================================================
--- trunk/coregrind/m_demangle/demangle.h (original)
+++ trunk/coregrind/m_demangle/demangle.h Wed Apr 12 14:01:29 2017
@@ -1,5 +1,5 @@
/* Defs for interface to demanglers.
- Copyright (C) 1992-2015 Free Software Foundation, Inc.
+ Copyright (C) 1992-2017 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License
@@ -65,9 +65,10 @@
#define DMGL_GNU_V3 (1 << 14)
#define DMGL_GNAT (1 << 15)
#define DMGL_DLANG (1 << 16)
+#define DMGL_RUST (1 << 17) /* Rust wraps GNU_V3 style mangling. */
/* If none of these are set, use 'current_demangling_style' as the default. */
-#define DMGL_STYLE_MASK (DMGL_AUTO|DMGL_GNU|DMGL_LUCID|DMGL_ARM|DMGL_HP|DMGL_EDG|DMGL_GNU_V3|DMGL_JAVA|DMGL_GNAT|DMGL_DLANG)
+#define DMGL_STYLE_MASK (DMGL_AUTO|DMGL_GNU|DMGL_LUCID|DMGL_ARM|DMGL_HP|DMGL_EDG|DMGL_GNU_V3|DMGL_JAVA|DMGL_GNAT|DMGL_DLANG|DMGL_RUST)
/* Enumeration of possible demangling styles.
@@ -90,7 +91,8 @@
gnu_v3_demangling = DMGL_GNU_V3,
java_demangling = DMGL_JAVA,
gnat_demangling = DMGL_GNAT,
- dlang_demangling = DMGL_DLANG
+ dlang_demangling = DMGL_DLANG,
+ rust_demangling = DMGL_RUST
} current_demangling_style;
/* Define string names for the various demangling styles. */
@@ -106,6 +108,7 @@
#define JAVA_DEMANGLING_STYLE_STRING "java"
#define GNAT_DEMANGLING_STYLE_STRING "gnat"
#define DLANG_DEMANGLING_STYLE_STRING "dlang"
+#define RUST_DEMANGLING_STYLE_STRING "rust"
/* Some macros to test what demangling style is active. */
@@ -120,6 +123,7 @@
#define JAVA_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_JAVA)
#define GNAT_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_GNAT)
#define DLANG_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_DLANG)
+#define RUST_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_RUST)
/* Provide information about the available demangle styles. This code is
pulled from gdb into libiberty because it is useful to binutils also. */
@@ -177,6 +181,27 @@
extern char *
dlang_demangle (const char *mangled, int options);
+/* Returns non-zero iff MANGLED is a rust mangled symbol. MANGLED must
+ already have been demangled through cplus_demangle_v3. If this function
+ returns non-zero then MANGLED can be demangled (in-place) using
+ RUST_DEMANGLE_SYM. */
+extern int
+rust_is_mangled (const char *mangled);
+
+/* Demangles SYM (in-place) if RUST_IS_MANGLED returned non-zero for SYM.
+ If RUST_IS_MANGLED returned zero for SYM then RUST_DEMANGLE_SYM might
+ replace characters that cannot be demangled with '?' and might truncate
+ SYM. After calling RUST_DEMANGLE_SYM SYM might be shorter, but never
+ larger. */
+extern void
+rust_demangle_sym (char *sym);
+
+/* Demangles MANGLED if it was GNU_V3 and then RUST mangled, otherwise
+ returns NULL. Uses CPLUS_DEMANGLE_V3, RUST_IS_MANGLED and
+ RUST_DEMANGLE_SYM. Returns a new string that is owned by the caller. */
+extern char *
+rust_demangle (const char *mangled, int options);
+
enum gnu_v3_ctor_kinds {
gnu_v3_complete_object_ctor = 1,
gnu_v3_base_object_ctor,
@@ -451,7 +476,9 @@
/* A transaction-safe function type. */
DEMANGLE_COMPONENT_TRANSACTION_SAFE,
/* A cloned function. */
- DEMANGLE_COMPONENT_CLONE
+ DEMANGLE_COMPONENT_CLONE,
+ DEMANGLE_COMPONENT_NOEXCEPT,
+ DEMANGLE_COMPONENT_THROW_SPEC
};
/* Types which are only used internally. */
@@ -469,6 +496,11 @@
/* The type of this component. */
enum demangle_component_type type;
+ /* Guard against recursive component printing.
+ Initialize to zero. Private to d_print_comp.
+ All other fields are final after initialization. */
+ int d_printing;
+
union
{
/* For DEMANGLE_COMPONENT_NAME. */
@@ -663,7 +695,7 @@
extern char *
cplus_demangle_print (int options,
- const struct demangle_component *tree,
+ struct demangle_component *tree,
int estimated_length,
size_t *p_allocated_size);
@@ -683,7 +715,7 @@
extern int
cplus_demangle_print_callback (int options,
- const struct demangle_component *tree,
+ struct demangle_component *tree,
demangle_callbackref callback, void *opaque);
#ifdef __cplusplus
Modified: trunk/coregrind/m_demangle/dyn-string.c
==============================================================================
--- trunk/coregrind/m_demangle/dyn-string.c (original)
+++ trunk/coregrind/m_demangle/dyn-string.c Wed Apr 12 14:01:29 2017
@@ -1,5 +1,5 @@
/* An abstract string datatype.
- Copyright (C) 1998, 1999, 2000, 2002, 2004 Free Software Foundation, Inc.
+ Copyright (C) 1998-2017 Free Software Foundation, Inc.
Contributed by Mark Mitchell (ma...@ma...).
This file is part of GNU CC.
Modified: trunk/coregrind/m_demangle/dyn-string.h
==============================================================================
--- trunk/coregrind/m_demangle/dyn-string.h (original)
+++ trunk/coregrind/m_demangle/dyn-string.h Wed Apr 12 14:01:29 2017
@@ -1,5 +1,5 @@
/* An abstract string datatype.
- Copyright (C) 1998-2015 Free Software Foundation, Inc.
+ Copyright (C) 1998-2017 Free Software Foundation, Inc.
Contributed by Mark Mitchell (ma...@ma...).
This file is part of GCC.
Added: trunk/coregrind/m_demangle/rust-demangle.c
==============================================================================
--- trunk/coregrind/m_demangle/rust-demangle.c (added)
+++ trunk/coregrind/m_demangle/rust-demangle.c Wed Apr 12 14:01:29 2017
@@ -0,0 +1,363 @@
+/* Demangler for the Rust programming language
+ Copyright (C) 2016-2017 Free Software Foundation, Inc.
+ Written by David Tolnay (dt...@gm...).
+
+This file is part of the libiberty library.
+Libiberty is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+In addition to the permissions in the GNU Library General Public
+License, the Free Software Foundation gives you unlimited permission
+to link the compiled version of this file into combinations with other
+programs, and to distribute those combinations without any restriction
+coming from the use of this file. (The Library Public License
+restrictions do apply in other respects; for example, they cover
+modification of the file, and distribution when not linked into a
+combined executable.)
+
+Libiberty is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with libiberty; see the file COPYING.LIB.
+If not, see <http://www.gnu.org/licenses/>. */
+
+
+#if 0 /* in valgrind */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#endif /* ! in valgrind */
+
+#if 0 /* in valgrind */
+#include "safe-ctype.h"
+#endif /* ! in valgrind */
+
+#if 0 /* in valgrind */
+#include <sys/types.h>
+#include <string.h>
+#include <stdio.h>
+#endif /* ! in valgrind */
+
+#if 0 /* in valgrind */
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+extern size_t strlen(const char *s);
+extern int strncmp(const char *s1, const char *s2, size_t n);
+extern void *memset(void *s, int c, size_t n);
+#endif
+#endif /* ! in valgrind */
+
+#if 0 /* in valgrind */
+#include <demangle.h>
+#include "libiberty.h"
+#endif /* ! in valgrind */
+
+#include "vg_libciface.h"
+
+#include "ansidecl.h"
+#include "demangle.h"
+#include "safe-ctype.h"
+
+/* Mangled Rust symbols look like this:
+ _$LT$std..sys..fd..FileDesc$u20$as$u20$core..ops..Drop$GT$::drop::hc68340e1baa4987a
+
+ The original symbol is:
+ <std::sys::fd::FileDesc as core::ops::Drop>::drop
+
+ The last component of the path is a 64-bit hash in lowercase hex,
+ prefixed with "h". Rust does not have a global namespace between
+ crates, an illusion which Rust maintains by using the hash to
+ distinguish things that would otherwise have the same symbol.
+
+ Any path component not starting with a XID_Start character is
+ prefixed with "_".
+
+ The following escape sequences are used:
+
+ "," => $C$
+ "@" => $SP$
+ "*" => $BP$
+ "&" => $RF$
+ "<" => $LT$
+ ">" => $GT$
+ "(" => $LP$
+ ")" => $RP$
+ " " => $u20$
+ "\"" => $u22$
+ "'" => $u27$
+ "+" => $u2b$
+ ";" => $u3b$
+ "[" => $u5b$
+ "]" => $u5d$
+ "{" => $u7b$
+ "}" => $u7d$
+ "~" => $u7e$
+
+ A double ".." means "::" and a single "." means "-".
+
+ The only characters allowed in the mangled symbol are a-zA-Z0-9 and _.:$ */
+
+static const char *hash_prefix = "::h";
+static const size_t hash_prefix_len = 3;
+static const size_t hash_len = 16;
+
+static int is_prefixed_hash (const char *start);
+static int looks_like_rust (const char *sym, size_t len);
+static int unescape (const char **in, char **out, const char *seq, char value);
+
+/* INPUT: sym: symbol that has been through C++ (gnu v3) demangling
+
+ This function looks for the following indicators:
+
+ 1. The hash must consist of "h" followed by 16 lowercase hex digits.
+
+ 2. As a sanity check, the hash must use between 5 and 15 of the 16
+ possible hex digits. This is true of 99.9998% of hashes so once
+ in your life you may see a false negative. The point is to
+ notice path components that could be Rust hashes but are
+ probably not, like "haaaaaaaaaaaaaaaa". In this case a false
+ positive (non-Rust symbol has an important path component
+ removed because it looks like a Rust hash) is worse than a false
+ negative (the rare Rust symbol is not demangled) so this sets
+ the balance in favor of false negatives.
+
+ 3. There must be no characters other than a-zA-Z0-9 and _.:$
+
+ 4. There must be no unrecognized $-sign sequences.
+
+ 5. There must be no sequence of three or more dots in a row ("..."). */
+
+int
+rust_is_mangled (const char *sym)
+{
+ size_t len, len_without_hash;
+
+ if (!sym)
+ return 0;
+
+ len = strlen (sym);
+ if (len <= hash_prefix_len + hash_len)
+ /* Not long enough to contain "::h" + hash + something else */
+ return 0;
+
+ len_without_hash = len - (hash_prefix_len + hash_len);
+ if (!is_prefixed_hash (sym + len_without_hash))
+ return 0;
+
+ return looks_like_rust (sym, len_without_hash);
+}
+
+/* A hash is the prefix "::h" followed by 16 lowercase hex digits. The
+ hex digits must comprise between 5 and 15 (inclusive) distinct
+ digits. */
+
+static int
+is_prefixed_hash (const char *str)
+{
+ const char *end;
+ char seen[16];
+ size_t i;
+ int count;
+
+ if (strncmp (str, hash_prefix, hash_prefix_len))
+ return 0;
+ str += hash_prefix_len;
+
+ memset (seen, 0, sizeof(seen));
+ for (end = str + hash_len; str < end; str++)
+ if (*str >= '0' && *str <= '9')
+ seen[*str - '0'] = 1;
+ else if (*str >= 'a' && *str <= 'f')
+ seen[*str - 'a' + 10] = 1;
+ else
+ return 0;
+
+ /* Count how many distinct digits seen */
+ count = 0;
+ for (i = 0; i < 16; i++)
+ if (seen[i])
+ count++;
+
+ return count >= 5 && count <= 15;
+}
+
+static int
+looks_like_rust (const char *str, size_t len)
+{
+ const char *end = str + len;
+
+ while (str < end)
+ switch (*str)
+ {
+ case '$':
+ if (!strncmp (str, "$C$", 3))
+ str += 3;
+ else if (!strncmp (str, "$SP$", 4)
+ || !strncmp (str, "$BP$", 4)
+ || !strncmp (str, "$RF$", 4)
+ || !strncmp (str, "$LT$", 4)
+ || !strncmp (str, "$GT$", 4)
+ || !strncmp (str, "$LP$", 4)
+ || !strncmp (str, "$RP$", 4))
+ str += 4;
+ else if (!strncmp (str, "$u20$", 5)
+ || !strncmp (str, "$u22$", 5)
+ || !strncmp (str, "$u27$", 5)
+ || !strncmp (str, "$u2b$", 5)
+ || !strncmp (str, "$u3b$", 5)
+ || !strncmp (str, "$u5b$", 5)
+ || !strncmp (str, "$u5d$", 5)
+ || !strncmp (str, "$u7b$", 5)
+ || !strncmp (str, "$u7d$", 5)
+ || !strncmp (str, "$u7e$", 5))
+ str += 5;
+ else
+ return 0;
+ break;
+ case '.':
+ /* Do not allow three or more consecutive dots */
+ if (!strncmp (str, "...", 3))
+ return 0;
+ /* Fall through */
+ case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
+ case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
+ case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
+ case 's': case 't': case 'u': case 'v': case 'w': case 'x':
+ case 'y': case 'z':
+ case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
+ case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
+ case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
+ case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
+ case 'Y': case 'Z':
+ case '0': case '1': case '2': case '3': case '4': case '5':
+ case '6': case '7': case '8': case '9':
+ case '_':
+ case ':':
+ str++;
+ break;
+ default:
+ return 0;
+ }
+
+ return 1;
+}
+
+/*
+ INPUT: sym: symbol for which rust_is_mangled(sym) returned 1.
+
+ The input is demangled in-place because the mangled name is always
+ longer than the demangled one. */
+
+void
+rust_demangle_sym (char *sym)
+{
+ const char *in;
+ char *out;
+ const char *end;
+
+ if (!sym)
+ return;
+
+ in = sym;
+ out = sym;
+ end = sym + strlen (sym) - (hash_prefix_len + hash_len);
+
+ while (in < end)
+ switch (*in)
+ {
+ case '$':
+ if (!(unescape (&in, &out, "$C$", ',')
+ || unescape (&in, &out, "$SP$", '@')
+ || unescape (&in, &out, "$BP$", '*')
+ || unescape (&in, &out, "$RF$", '&')
+ || unescape (&in, &out, "$LT$", '<')
+ || unescape (&in, &out, "$GT$", '>')
+ || unescape (&in, &out, "$LP$", '(')
+ || unescape (&in, &out, "$RP$", ')')
+ || unescape (&in, &out, "$u20$", ' ')
+ || unescape (&in, &out, "$u22$", '\"')
+ || unescape (&in, &out, "$u27$", '\'')
+ || unescape (&in, &out, "$u2b$", '+')
+ || unescape (&in, &out, "$u3b$", ';')
+ || unescape (&in, &out, "$u5b$", '[')
+ || unescape (&in, &out, "$u5d$", ']')
+ || unescape (&in, &out, "$u7b$", '{')
+ || unescape (&in, &out, "$u7d$", '}')
+ || unescape (&in, &out, "$u7e$", '~'))) {
+ /* unexpected escape sequence, not looks_like_rust. */
+ goto fail;
+ }
+ break;
+ case '_':
+ /* If this is the start of a path component and the next
+ character is an escape sequence, ignore the underscore. The
+ mangler inserts an underscore to make sure the path
+ component begins with a XID_Start character. */
+ if ((in == sym || in[-1] == ':') && in[1] == '$')
+ in++;
+ else
+ *out++ = *in++;
+ break;
+ case '.':
+ if (in[1] == '.')
+ {
+ /* ".." becomes "::" */
+ *out++ = ':';
+ *out++ = ':';
+ in += 2;
+ }
+ else
+ {
+ /* "." becomes "-" */
+ *out++ = '-';
+ in++;
+ }
+ break;
+ case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
+ case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
+ case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
+ case 's': case 't': case 'u': case 'v': case 'w': case 'x':
+ case 'y': case 'z':
+ case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
+ case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
+ case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
+ case 'S': case 'T': case 'U': case 'V': cas...
[truncated message content] |
|
From: <sv...@va...> - 2017-04-11 17:06:08
|
Author: petarj
Date: Tue Apr 11 18:06:02 2017
New Revision: 3347
Log:
mips: update code for Dis_Resteer for mode64
Even though Dis_Resteer is currently unused, the code for mode64 should
be different.
Nicely spotted by Florian K.
Modified:
trunk/priv/guest_mips_toIR.c
Modified: trunk/priv/guest_mips_toIR.c
==============================================================================
--- trunk/priv/guest_mips_toIR.c (original)
+++ trunk/priv/guest_mips_toIR.c Tue Apr 11 18:06:02 2017
@@ -17249,7 +17249,10 @@
break;
case Dis_ResteerU:
case Dis_ResteerC:
- putPC(mkU32(dres.continueAt));
+ if (mode64)
+ putPC(mkU64(dres.continueAt));
+ else
+ putPC(mkU32(dres.continueAt));
break;
case Dis_StopHere:
break;
|
|
From: <sv...@va...> - 2017-04-11 16:35:03
|
Author: sewardj Date: Tue Apr 11 17:34:53 2017 New Revision: 3346 Log: Mark VPMULHRSW ymm3/m256, ymm2, ymm1 as a "verbose instruction". This pertains to failures documented at https://bugs.kde.org/show_bug.cgi?id=375839 comments 10 to 18. Modified: trunk/priv/guest_amd64_toIR.c Modified: trunk/priv/guest_amd64_toIR.c ============================================================================== --- trunk/priv/guest_amd64_toIR.c (original) +++ trunk/priv/guest_amd64_toIR.c Tue Apr 11 17:34:53 2017 @@ -28152,6 +28152,7 @@ ) ); *uses_vvvv = True; + dres->hint = Dis_HintVerbose; goto decode_success; } break; |
Author: iraisr
Date: Mon Apr 10 21:36:00 2017
New Revision: 16301
Log:
Fix an INTERNAL ERROR problem in execve syscall wrapper.
Fixes BZ#378535.
Modified:
trunk/NEWS
trunk/coregrind/m_syswrap/syswrap-generic.c
trunk/coregrind/m_syswrap/syswrap-linux.c
trunk/memcheck/tests/x86-linux/scalar.c
trunk/memcheck/tests/x86-linux/scalar.stderr.exp
Modified: trunk/NEWS
==============================================================================
--- trunk/NEWS (original)
+++ trunk/NEWS Mon Apr 10 21:36:00 2017
@@ -154,6 +154,7 @@
and 2 args for FUTEX_TRYLOCK_PI
377717 Fix massive space leak when reading compressed debuginfo sections
377930 fcntl syscall wrapper is missing flock structure check
+378535 Valgrind reports INTERNAL ERROR in execve syscall wrapper
Release 3.12.0 (20 October 2016)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Modified: trunk/coregrind/m_syswrap/syswrap-generic.c
==============================================================================
--- trunk/coregrind/m_syswrap/syswrap-generic.c (original)
+++ trunk/coregrind/m_syswrap/syswrap-generic.c Mon Apr 10 21:36:00 2017
@@ -2826,14 +2826,26 @@
SysRes res;
Bool setuid_allowed, trace_this_child;
- PRINT("sys_execve ( %#lx(%s), %#lx, %#lx )", ARG1, (char*)ARG1, ARG2, ARG3);
+ PRINT("sys_execve ( %#lx(%s), %#lx, %#lx )", ARG1, (HChar*)ARG1, ARG2, ARG3);
PRE_REG_READ3(vki_off_t, "execve",
char *, filename, char **, argv, char **, envp);
PRE_MEM_RASCIIZ( "execve(filename)", ARG1 );
- if (ARG2 != 0)
+ if (ARG2 != 0) {
+ /* At least the terminating NULL must be addressable. */
+ if (!ML_(safe_to_deref)((HChar **) ARG2, sizeof(HChar *))) {
+ SET_STATUS_Failure(VKI_EFAULT);
+ return;
+ }
ML_(pre_argv_envp)( ARG2, tid, "execve(argv)", "execve(argv[i])" );
- if (ARG3 != 0)
+ }
+ if (ARG3 != 0) {
+ /* At least the terminating NULL must be addressable. */
+ if (!ML_(safe_to_deref)((HChar **) ARG3, sizeof(HChar *))) {
+ SET_STATUS_Failure(VKI_EFAULT);
+ return;
+ }
ML_(pre_argv_envp)( ARG3, tid, "execve(envp)", "execve(envp[i])" );
+ }
vg_assert(VG_(is_valid_tid)(tid));
tst = VG_(get_ThreadState)(tid);
Modified: trunk/coregrind/m_syswrap/syswrap-linux.c
==============================================================================
--- trunk/coregrind/m_syswrap/syswrap-linux.c (original)
+++ trunk/coregrind/m_syswrap/syswrap-linux.c Mon Apr 10 21:36:00 2017
@@ -2071,7 +2071,7 @@
PRE(sys_tkill)
{
- PRINT("sys_tgkill ( %ld, %ld )", SARG1, SARG2);
+ PRINT("sys_tkill ( %ld, %ld )", SARG1, SARG2);
PRE_REG_READ2(long, "tkill", int, tid, int, sig);
if (!ML_(client_signal_OK)(ARG2)) {
SET_STATUS_Failure( VKI_EINVAL );
Modified: trunk/memcheck/tests/x86-linux/scalar.c
==============================================================================
--- trunk/memcheck/tests/x86-linux/scalar.c (original)
+++ trunk/memcheck/tests/x86-linux/scalar.c Mon Apr 10 21:36:00 2017
@@ -85,10 +85,18 @@
SY(__NR_unlink, x0); FAIL;
// __NR_execve 11
- // Nb: could have 3 memory errors if we pass x0+1 as the 2nd and 3rd
- // args, except for bug #93174.
GO(__NR_execve, "3s 1m");
- SY(__NR_execve, x0, x0, x0); FAIL;
+ SY(__NR_execve, x0 + 1, x0 + 1, x0); FAIL;
+
+ GO(__NR_execve, "3s 1m");
+ SY(__NR_execve, x0 + 1, x0, x0 + 1); FAIL;
+
+ char *argv_envp[] = {(char *) (x0 + 1), NULL};
+ GO(__NR_execve, "4s 2m");
+ SY(__NR_execve, x0 + 1, x0 + argv_envp, x0); FAIL;
+
+ GO(__NR_execve, "4s 2m");
+ SY(__NR_execve, x0 + 1, x0, x0 + argv_envp); FAIL;
// __NR_chdir 12
GO(__NR_chdir, "1s 1m");
Modified: trunk/memcheck/tests/x86-linux/scalar.stderr.exp
==============================================================================
--- trunk/memcheck/tests/x86-linux/scalar.stderr.exp (original)
+++ trunk/memcheck/tests/x86-linux/scalar.stderr.exp Mon Apr 10 21:36:00 2017
@@ -155,19 +155,101 @@
-----------------------------------------------------
Syscall param execve(filename) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:91)
+ by 0x........: main (scalar.c:89)
Syscall param execve(argv) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:91)
+ by 0x........: main (scalar.c:89)
Syscall param execve(envp) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:91)
+ by 0x........: main (scalar.c:89)
Syscall param execve(filename) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:91)
+ by 0x........: main (scalar.c:89)
+ Address 0x........ is not stack'd, malloc'd or (recently) free'd
+
+-----------------------------------------------------
+ 11: __NR_execve 3s 1m
+-----------------------------------------------------
+Syscall param execve(filename) contains uninitialised byte(s)
+ ...
+ by 0x........: main (scalar.c:92)
+
+Syscall param execve(argv) contains uninitialised byte(s)
+ ...
+ by 0x........: main (scalar.c:92)
+
+Syscall param execve(envp) contains uninitialised byte(s)
+ ...
+ by 0x........: main (scalar.c:92)
+
+Syscall param execve(filename) points to unaddressable byte(s)
+ ...
+ by 0x........: main (scalar.c:92)
+ Address 0x........ is not stack'd, malloc'd or (recently) free'd
+
+-----------------------------------------------------
+ 11: __NR_execve 4s 2m
+-----------------------------------------------------
+Syscall param execve(filename) contains uninitialised byte(s)
+ ...
+ by 0x........: main (scalar.c:96)
+
+Syscall param execve(argv) contains uninitialised byte(s)
+ ...
+ by 0x........: main (scalar.c:96)
+
+Syscall param execve(envp) contains uninitialised byte(s)
+ ...
+ by 0x........: main (scalar.c:96)
+
+Syscall param execve(filename) points to unaddressable byte(s)
+ ...
+ by 0x........: main (scalar.c:96)
+ Address 0x........ is not stack'd, malloc'd or (recently) free'd
+
+Syscall param execve(argv) points to uninitialised byte(s)
+ ...
+ by 0x........: main (scalar.c:96)
+ Address 0x........ is on thread 1's stack
+ in frame #1, created by main (scalar.c:28)
+
+Syscall param execve(argv[i]) points to unaddressable byte(s)
+ ...
+ by 0x........: main (scalar.c:96)
+ Address 0x........ is not stack'd, malloc'd or (recently) free'd
+
+-----------------------------------------------------
+ 11: __NR_execve 4s 2m
+-----------------------------------------------------
+Syscall param execve(filename) contains uninitialised byte(s)
+ ...
+ by 0x........: main (scalar.c:99)
+
+Syscall param execve(argv) contains uninitialised byte(s)
+ ...
+ by 0x........: main (scalar.c:99)
+
+Syscall param execve(envp) contains uninitialised byte(s)
+ ...
+ by 0x........: main (scalar.c:99)
+
+Syscall param execve(filename) points to unaddressable byte(s)
+ ...
+ by 0x........: main (scalar.c:99)
+ Address 0x........ is not stack'd, malloc'd or (recently) free'd
+
+Syscall param execve(envp) points to uninitialised byte(s)
+ ...
+ by 0x........: main (scalar.c:99)
+ Address 0x........ is on thread 1's stack
+ in frame #1, created by main (scalar.c:28)
+
+Syscall param execve(envp[i]) points to unaddressable byte(s)
+ ...
+ by 0x........: main (scalar.c:99)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
-----------------------------------------------------
@@ -175,11 +257,11 @@
-----------------------------------------------------
Syscall param chdir(path) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:95)
+ by 0x........: main (scalar.c:103)
Syscall param chdir(path) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:95)
+ by 0x........: main (scalar.c:103)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
-----------------------------------------------------
@@ -187,11 +269,11 @@
-----------------------------------------------------
Syscall param time(t) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:99)
+ by 0x........: main (scalar.c:107)
Syscall param time(t) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:99)
+ by 0x........: main (scalar.c:107)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
-----------------------------------------------------
@@ -199,19 +281,19 @@
-----------------------------------------------------
Syscall param mknod(pathname) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:103)
+ by 0x........: main (scalar.c:111)
Syscall param mknod(mode) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:103)
+ by 0x........: main (scalar.c:111)
Syscall param mknod(dev) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:103)
+ by 0x........: main (scalar.c:111)
Syscall param mknod(pathname) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:103)
+ by 0x........: main (scalar.c:111)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
-----------------------------------------------------
@@ -219,15 +301,15 @@
-----------------------------------------------------
Syscall param chmod(path) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:107)
+ by 0x........: main (scalar.c:115)
Syscall param chmod(mode) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:107)
+ by 0x........: main (scalar.c:115)
Syscall param chmod(path) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:107)
+ by 0x........: main (scalar.c:115)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
-----------------------------------------------------
@@ -244,15 +326,15 @@
-----------------------------------------------------
Syscall param lseek(fd) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:123)
+ by 0x........: main (scalar.c:131)
Syscall param lseek(offset) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:123)
+ by 0x........: main (scalar.c:131)
Syscall param lseek(whence) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:123)
+ by 0x........: main (scalar.c:131)
-----------------------------------------------------
20: __NR_getpid 0s 0m
@@ -262,32 +344,32 @@
-----------------------------------------------------
Syscall param mount(source) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:131)
+ by 0x........: main (scalar.c:139)
Syscall param mount(target) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:131)
+ by 0x........: main (scalar.c:139)
Syscall param mount(type) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:131)
+ by 0x........: main (scalar.c:139)
Syscall param mount(flags) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:131)
+ by 0x........: main (scalar.c:139)
Syscall param mount(data) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:131)
+ by 0x........: main (scalar.c:139)
Syscall param mount(target) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:131)
+ by 0x........: main (scalar.c:139)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
Syscall param mount(type) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:131)
+ by 0x........: main (scalar.c:139)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
-----------------------------------------------------
@@ -295,11 +377,11 @@
-----------------------------------------------------
Syscall param umount(path) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:135)
+ by 0x........: main (scalar.c:143)
Syscall param umount(path) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:135)
+ by 0x........: main (scalar.c:143)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
-----------------------------------------------------
@@ -307,7 +389,7 @@
-----------------------------------------------------
Syscall param setuid16(uid) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:139)
+ by 0x........: main (scalar.c:147)
-----------------------------------------------------
24: __NR_getuid 0s 0m
@@ -320,23 +402,23 @@
-----------------------------------------------------
Syscall param ptrace(request) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:152)
+ by 0x........: main (scalar.c:160)
Syscall param ptrace(pid) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:152)
+ by 0x........: main (scalar.c:160)
Syscall param ptrace(addr) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:152)
+ by 0x........: main (scalar.c:160)
Syscall param ptrace(data) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:152)
+ by 0x........: main (scalar.c:160)
Syscall param ptrace(getregs) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:152)
+ by 0x........: main (scalar.c:160)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
-----------------------------------------------------
@@ -344,7 +426,7 @@
-----------------------------------------------------
Syscall param alarm(seconds) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:156)
+ by 0x........: main (scalar.c:164)
-----------------------------------------------------
28: __NR_oldfstat n/a
@@ -357,20 +439,20 @@
-----------------------------------------------------
Syscall param utime(filename) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:168)
+ by 0x........: main (scalar.c:176)
Syscall param utime(buf) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:168)
+ by 0x........: main (scalar.c:176)
Syscall param utime(filename) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:168)
+ by 0x........: main (scalar.c:176)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
Syscall param utime(buf) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:168)
+ by 0x........: main (scalar.c:176)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
-----------------------------------------------------
@@ -384,15 +466,15 @@
-----------------------------------------------------
Syscall param access(pathname) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:180)
+ by 0x........: main (scalar.c:188)
Syscall param access(mode) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:180)
+ by 0x........: main (scalar.c:188)
Syscall param access(pathname) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:180)
+ by 0x........: main (scalar.c:188)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
-----------------------------------------------------
@@ -400,7 +482,7 @@
-----------------------------------------------------
Syscall param nice(inc) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:184)
+ by 0x........: main (scalar.c:192)
-----------------------------------------------------
35: __NR_ftime ni
@@ -413,31 +495,31 @@
-----------------------------------------------------
Syscall param kill(pid) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:196)
+ by 0x........: main (scalar.c:204)
Syscall param kill(signal) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:196)
+ by 0x........: main (scalar.c:204)
-----------------------------------------------------
38: __NR_rename 2s 2m
-----------------------------------------------------
Syscall param rename(oldpath) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:200)
+ by 0x........: main (scalar.c:208)
Syscall param rename(newpath) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:200)
+ by 0x........: main (scalar.c:208)
Syscall param rename(oldpath) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:200)
+ by 0x........: main (scalar.c:208)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
Syscall param rename(newpath) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:200)
+ by 0x........: main (scalar.c:208)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
-----------------------------------------------------
@@ -445,15 +527,15 @@
-----------------------------------------------------
Syscall param mkdir(pathname) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:204)
+ by 0x........: main (scalar.c:212)
Syscall param mkdir(mode) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:204)
+ by 0x........: main (scalar.c:212)
Syscall param mkdir(pathname) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:204)
+ by 0x........: main (scalar.c:212)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
-----------------------------------------------------
@@ -461,11 +543,11 @@
-----------------------------------------------------
Syscall param rmdir(pathname) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:208)
+ by 0x........: main (scalar.c:216)
Syscall param rmdir(pathname) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:208)
+ by 0x........: main (scalar.c:216)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
-----------------------------------------------------
@@ -473,18 +555,18 @@
-----------------------------------------------------
Syscall param dup(oldfd) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:212)
+ by 0x........: main (scalar.c:220)
-----------------------------------------------------
42: __NR_pipe 1s 1m
-----------------------------------------------------
Syscall param pipe(filedes) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:216)
+ by 0x........: main (scalar.c:224)
Syscall param pipe(filedes) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:216)
+ by 0x........: main (scalar.c:224)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
-----------------------------------------------------
@@ -492,11 +574,14 @@
-----------------------------------------------------
Syscall param times(buf) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:220)
+ by 0x........: main (scalar.c:228)
+
+More than 100 errors detected. Subsequent errors
+will still be recorded, but in less detail than before.
Syscall param times(buf) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:220)
+ by 0x........: main (scalar.c:228)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
-----------------------------------------------------
@@ -507,14 +592,14 @@
-----------------------------------------------------
Syscall param brk(end_data_segment) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:228)
+ by 0x........: main (scalar.c:236)
-----------------------------------------------------
46: __NR_setgid 1s 0m
-----------------------------------------------------
Syscall param setgid16(gid) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:232)
+ by 0x........: main (scalar.c:240)
-----------------------------------------------------
47: __NR_getgid 0s 0m
@@ -533,11 +618,11 @@
-----------------------------------------------------
Syscall param acct(filename) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:252)
+ by 0x........: main (scalar.c:260)
Syscall param acct(filename) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:252)
+ by 0x........: main (scalar.c:260)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
-----------------------------------------------------
@@ -545,15 +630,15 @@
-----------------------------------------------------
Syscall param umount2(path) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:256)
+ by 0x........: main (scalar.c:264)
Syscall param umount2(flags) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:256)
+ by 0x........: main (scalar.c:264)
Syscall param umount2(path) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:256)
+ by 0x........: main (scalar.c:264)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
-----------------------------------------------------
@@ -564,19 +649,19 @@
-----------------------------------------------------
Syscall param ioctl(fd) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:265)
+ by 0x........: main (scalar.c:273)
Syscall param ioctl(request) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:265)
+ by 0x........: main (scalar.c:273)
Syscall param ioctl(arg) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:265)
+ by 0x........: main (scalar.c:273)
Syscall param ioctl(TCSET{S,SW,SF}) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:265)
+ by 0x........: main (scalar.c:273)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
-----------------------------------------------------
@@ -584,52 +669,49 @@
-----------------------------------------------------
Syscall param fcntl(fd) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:271)
+ by 0x........: main (scalar.c:279)
Syscall param fcntl(cmd) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:271)
+ by 0x........: main (scalar.c:279)
-----------------------------------------------------
55: __NR_fcntl (DUPFD) 1s 0m
-----------------------------------------------------
Syscall param fcntl(arg) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:277)
+ by 0x........: main (scalar.c:285)
-----------------------------------------------------
55: __NR_fcntl (GETLK) 1s 5m
-----------------------------------------------------
Syscall param fcntl(lock) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:283)
-
+ by 0x........: main (scalar.c:291)
-More than 100 errors detected. Subsequent errors
-will still be recorded, but in less detail than before.
Syscall param fcntl(lock->l_type) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:283)
+ by 0x........: main (scalar.c:291)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
Syscall param fcntl(lock->l_whence) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:283)
+ by 0x........: main (scalar.c:291)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
Syscall param fcntl(lock->l_start) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:283)
+ by 0x........: main (scalar.c:291)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
Syscall param fcntl(lock->l_len) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:283)
+ by 0x........: main (scalar.c:291)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
Syscall param fcntl(lock->l_pid) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:283)
+ by 0x........: main (scalar.c:291)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
-----------------------------------------------------
@@ -640,11 +722,11 @@
-----------------------------------------------------
Syscall param setpgid(pid) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:291)
+ by 0x........: main (scalar.c:299)
Syscall param setpgid(pgid) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:291)
+ by 0x........: main (scalar.c:299)
-----------------------------------------------------
58: __NR_ulimit ni
@@ -657,18 +739,18 @@
-----------------------------------------------------
Syscall param umask(mask) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:303)
+ by 0x........: main (scalar.c:311)
-----------------------------------------------------
61: __NR_chroot 1s 1m
-----------------------------------------------------
Syscall param chroot(path) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:307)
+ by 0x........: main (scalar.c:315)
Syscall param chroot(path) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:307)
+ by 0x........: main (scalar.c:315)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
-----------------------------------------------------
@@ -679,11 +761,11 @@
-----------------------------------------------------
Syscall param dup2(oldfd) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:315)
+ by 0x........: main (scalar.c:323)
Syscall param dup2(newfd) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:315)
+ by 0x........: main (scalar.c:323)
-----------------------------------------------------
64: __NR_getppid 0s 0m
@@ -699,40 +781,40 @@
-----------------------------------------------------
Syscall param sigaction(signum) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:331)
+ by 0x........: main (scalar.c:339)
Syscall param sigaction(act) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:331)
+ by 0x........: main (scalar.c:339)
Syscall param sigaction(oldact) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:331)
+ by 0x........: main (scalar.c:339)
Syscall param sigaction(act->sa_handler) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:331)
+ by 0x........: main (scalar.c:339)
Address 0x........ is 0 bytes after a block of size 4 alloc'd
at 0x........: malloc (vg_replace_malloc.c:...)
by 0x........: main (scalar.c:30)
Syscall param sigaction(act->sa_mask) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:331)
+ by 0x........: main (scalar.c:339)
Address 0x........ is 4 bytes after a block of size 4 alloc'd
at 0x........: malloc (vg_replace_malloc.c:...)
by 0x........: main (scalar.c:30)
Syscall param sigaction(act->sa_flags) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:331)
+ by 0x........: main (scalar.c:339)
Address 0x........ is 8 bytes after a block of size 4 alloc'd
at 0x........: malloc (vg_replace_malloc.c:...)
by 0x........: main (scalar.c:30)
Syscall param sigaction(oldact) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:331)
+ by 0x........: main (scalar.c:339)
Address 0x........ is 0 bytes after a block of size 4 alloc'd
at 0x........: malloc (vg_replace_malloc.c:...)
by 0x........: main (scalar.c:30)
@@ -748,22 +830,22 @@
-----------------------------------------------------
Syscall param setreuid16(ruid) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:343)
+ by 0x........: main (scalar.c:351)
Syscall param setreuid16(euid) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:343)
+ by 0x........: main (scalar.c:351)
-----------------------------------------------------
71: __NR_setregid 2s 0m
-----------------------------------------------------
Syscall param setregid16(rgid) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:347)
+ by 0x........: main (scalar.c:355)
Syscall param setregid16(egid) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:347)
+ by 0x........: main (scalar.c:355)
-----------------------------------------------------
72: __NR_sigsuspend ignore
@@ -773,11 +855,11 @@
-----------------------------------------------------
Syscall param sigpending(set) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:356)
+ by 0x........: main (scalar.c:364)
Syscall param sigpending(set) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:356)
+ by 0x........: main (scalar.c:364)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
-----------------------------------------------------
@@ -788,15 +870,15 @@
-----------------------------------------------------
Syscall param setrlimit(resource) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:364)
+ by 0x........: main (scalar.c:372)
Syscall param setrlimit(rlim) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:364)
+ by 0x........: main (scalar.c:372)
Syscall param setrlimit(rlim) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:364)
+ by 0x........: main (scalar.c:372)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
-----------------------------------------------------
@@ -804,15 +886,15 @@
-----------------------------------------------------
Syscall param old_getrlimit(resource) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:368)
+ by 0x........: main (scalar.c:376)
Syscall param old_getrlimit(rlim) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:368)
+ by 0x........: main (scalar.c:376)
Syscall param old_getrlimit(rlim) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:368)
+ by 0x........: main (scalar.c:376)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
-----------------------------------------------------
@@ -820,15 +902,15 @@
-----------------------------------------------------
Syscall param getrusage(who) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:372)
+ by 0x........: main (scalar.c:380)
Syscall param getrusage(usage) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:372)
+ by 0x........: main (scalar.c:380)
Syscall param getrusage(usage) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:372)
+ by 0x........: main (scalar.c:380)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
-----------------------------------------------------
@@ -836,20 +918,20 @@
-----------------------------------------------------
Syscall param gettimeofday(tv) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:376)
+ by 0x........: main (scalar.c:384)
Syscall param gettimeofday(tz) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:376)
+ by 0x........: main (scalar.c:384)
Syscall param gettimeofday(tv) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:376)
+ by 0x........: main (scalar.c:384)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
Syscall param gettimeofday(tz) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:376)
+ by 0x........: main (scalar.c:384)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
-----------------------------------------------------
@@ -857,20 +939,20 @@
-----------------------------------------------------
Syscall param settimeofday(tv) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:380)
+ by 0x........: main (scalar.c:388)
Syscall param settimeofday(tz) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:380)
+ by 0x........: main (scalar.c:388)
Syscall param settimeofday(tv) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:380)
+ by 0x........: main (scalar.c:388)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
Syscall param settimeofday(tz) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:380)
+ by 0x........: main (scalar.c:388)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
-----------------------------------------------------
@@ -878,15 +960,15 @@
-----------------------------------------------------
Syscall param getgroups16(size) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:384)
+ by 0x........: main (scalar.c:392)
Syscall param getgroups16(list) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:384)
+ by 0x........: main (scalar.c:392)
Syscall param getgroups16(list) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:384)
+ by 0x........: main (scalar.c:392)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
-----------------------------------------------------
@@ -894,15 +976,15 @@
-----------------------------------------------------
Syscall param setgroups16(size) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:388)
+ by 0x........: main (scalar.c:396)
Syscall param setgroups16(list) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:388)
+ by 0x........: main (scalar.c:396)
Syscall param setgroups16(list) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:388)
+ by 0x........: main (scalar.c:396)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
-----------------------------------------------------
@@ -910,32 +992,32 @@
-----------------------------------------------------
Syscall param old_select(args) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:394)
+ by 0x........: main (scalar.c:402)
Syscall param old_select(args) points to uninitialised byte(s)
...
- by 0x........: main (scalar.c:394)
+ by 0x........: main (scalar.c:402)
Address 0x........ is on thread 1's stack
in frame #1, created by main (scalar.c:28)
Syscall param old_select(readfds) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:394)
+ by 0x........: main (scalar.c:402)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
Syscall param old_select(writefds) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:394)
+ by 0x........: main (scalar.c:402)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
Syscall param old_select(exceptfds) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:394)
+ by 0x........: main (scalar.c:402)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
Syscall param old_select(timeout) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:394)
+ by 0x........: main (scalar.c:402)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
-----------------------------------------------------
@@ -943,20 +1025,20 @@
-----------------------------------------------------
Syscall param symlink(oldpath) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:399)
+ by 0x........: main (scalar.c:407)
Syscall param symlink(newpath) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:399)
+ by 0x........: main (scalar.c:407)
Syscall param symlink(oldpath) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:399)
+ by 0x........: main (scalar.c:407)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
Syscall param symlink(newpath) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:399)
+ by 0x........: main (scalar.c:407)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
-----------------------------------------------------
@@ -967,24 +1049,24 @@
-----------------------------------------------------
Syscall param readlink(path) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:407)
+ by 0x........: main (scalar.c:415)
Syscall param readlink(buf) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:407)
+ by 0x........: main (scalar.c:415)
Syscall param readlink(bufsiz) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:407)
+ by 0x........: main (scalar.c:415)
Syscall param readlink(path) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:407)
+ by 0x........: main (scalar.c:415)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
Syscall param readlink(buf) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:407)
+ by 0x........: main (scalar.c:415)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
-----------------------------------------------------
@@ -1004,11 +1086,11 @@
-----------------------------------------------------
Syscall param old_mmap(args) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:429)
+ by 0x........: main (scalar.c:437)
Syscall param old_mmap(args) points to uninitialised byte(s)
...
- by 0x........: main (scalar.c:429)
+ by 0x........: main (scalar.c:437)
Address 0x........ is on thread 1's stack
in frame #1, created by main (scalar.c:28)
@@ -1017,26 +1099,26 @@
-----------------------------------------------------
Syscall param munmap(start) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:434)
+ by 0x........: main (scalar.c:442)
Syscall param munmap(length) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:434)
+ by 0x........: main (scalar.c:442)
-----------------------------------------------------
92: __NR_truncate 2s 1m
-----------------------------------------------------
Syscall param truncate(path) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:438)
+ by 0x........: main (scalar.c:446)
Syscall param truncate(length) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:438)
+ by 0x........: main (scalar.c:446)
Syscall param truncate(path) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:438)
+ by 0x........: main (scalar.c:446)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
-----------------------------------------------------
@@ -1044,63 +1126,63 @@
-----------------------------------------------------
Syscall param ftruncate(fd) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:442)
+ by 0x........: main (scalar.c:450)
Syscall param ftruncate(length) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:442)
+ by 0x........: main (scalar.c:450)
-----------------------------------------------------
94: __NR_fchmod 2s 0m
-----------------------------------------------------
Syscall param fchmod(fildes) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:446)
+ by 0x........: main (scalar.c:454)
Syscall param fchmod(mode) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:446)
+ by 0x........: main (scalar.c:454)
-----------------------------------------------------
95: __NR_fchown 3s 0m
-----------------------------------------------------
Syscall param fchown16(fd) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:450)
+ by 0x........: main (scalar.c:458)
Syscall param fchown16(owner) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:450)
+ by 0x........: main (scalar.c:458)
Syscall param fchown16(group) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:450)
+ by 0x........: main (scalar.c:458)
-----------------------------------------------------
96: __NR_getpriority 2s 0m
-----------------------------------------------------
Syscall param getpriority(which) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:454)
+ by 0x........: main (scalar.c:462)
Syscall param getpriority(who) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:454)
+ by 0x........: main (scalar.c:462)
-----------------------------------------------------
97: __NR_setpriority 3s 0m
-----------------------------------------------------
Syscall param setpriority(which) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:458)
+ by 0x........: main (scalar.c:466)
Syscall param setpriority(who) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:458)
+ by 0x........: main (scalar.c:466)
Syscall param setpriority(prio) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:458)
+ by 0x........: main (scalar.c:466)
-----------------------------------------------------
98: __NR_profil ni
@@ -1110,20 +1192,20 @@
-----------------------------------------------------
Syscall param statfs(path) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:466)
+ by 0x........: main (scalar.c:474)
Syscall param statfs(buf) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:466)
+ by 0x........: main (scalar.c:474)
Syscall param statfs(path) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:466)
+ by 0x........: main (scalar.c:474)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
Syscall param statfs(buf) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:466)
+ by 0x........: main (scalar.c:474)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
-----------------------------------------------------
@@ -1131,15 +1213,15 @@
-----------------------------------------------------
Syscall param fstatfs(fd) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:470)
+ by 0x........: main (scalar.c:478)
Syscall param fstatfs(buf) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:470)
+ by 0x........: main (scalar.c:478)
Syscall param fstatfs(buf) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:470)
+ by 0x........: main (scalar.c:478)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
-----------------------------------------------------
@@ -1147,15 +1229,15 @@
-----------------------------------------------------
Syscall param ioperm(from) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:474)
+ by 0x........: main (scalar.c:482)
Syscall param ioperm(num) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:474)
+ by 0x........: main (scalar.c:482)
Syscall param ioperm(turn_on) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:474)
+ by 0x........: main (scalar.c:482)
-----------------------------------------------------
102: __NR_socketcall XXX
@@ -1165,19 +1247,19 @@
-----------------------------------------------------
Syscall param syslog(type) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:482)
+ by 0x........: main (scalar.c:490)
Syscall param syslog(bufp) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:482)
+ by 0x........: main (scalar.c:490)
Syscall param syslog(len) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:482)
+ by 0x........: main (scalar.c:490)
Syscall param syslog(bufp) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:482)
+ by 0x........: main (scalar.c:490)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
-----------------------------------------------------
@@ -1185,34 +1267,34 @@
-----------------------------------------------------
Syscall param setitimer(which) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:486)
+ by 0x........: main (scalar.c:494)
Syscall param setitimer(value) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:486)
+ by 0x........: main (scalar.c:494)
Syscall param setitimer(ovalue) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:486)
+ by 0x........: main (scalar.c:494)
Syscall param setitimer(&value->it_interval) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:486)
+ by 0x........: main (scalar.c:494)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
Syscall param setitimer(&value->it_value) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:486)
+ by 0x........: main (scalar.c:494)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
Syscall param setitimer(&ovalue->it_interval) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:486)
+ by 0x........: main (scalar.c:494)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
Syscall param setitimer(&ovalue->it_value) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:486)
+ by 0x........: main (scalar.c:494)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
-----------------------------------------------------
@@ -1220,20 +1302,20 @@
-----------------------------------------------------
Syscall param getitimer(which) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:490)
+ by 0x........: main (scalar.c:498)
Syscall param getitimer(value) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:490)
+ by 0x........: main (scalar.c:498)
Syscall param getitimer(&value->it_interval) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:490)
+ by 0x........: main (scalar.c:498)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
Syscall param getitimer(&value->it_value) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:490)
+ by 0x........: main (scalar.c:498)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
-----------------------------------------------------
@@ -1241,20 +1323,20 @@
-----------------------------------------------------
Syscall param stat(file_name) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:494)
+ by 0x........: main (scalar.c:502)
Syscall param stat(buf) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:494)
+ by 0x........: main (scalar.c:502)
Syscall param stat(file_name) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:494)
+ by 0x........: main (scalar.c:502)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
Syscall param stat(buf) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:494)
+ by 0x........: main (scalar.c:502)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
-----------------------------------------------------
@@ -1262,20 +1344,20 @@
-----------------------------------------------------
Syscall param lstat(file_name) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:498)
+ by 0x........: main (scalar.c:506)
Syscall param lstat(buf) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:498)
+ by 0x........: main (scalar.c:506)
Syscall param lstat(file_name) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:498)
+ by 0x........: main (scalar.c:506)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
Syscall param lstat(buf) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:498)
+ by 0x........: main (scalar.c:506)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
-----------------------------------------------------
@@ -1283,15 +1365,15 @@
-----------------------------------------------------
Syscall param fstat(fd) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:502)
+ by 0x........: main (scalar.c:510)
Syscall param fstat(buf) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:502)
+ by 0x........: main (scalar.c:510)
Syscall param fstat(buf) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:502)
+ by 0x........: main (scalar.c:510)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
-----------------------------------------------------
@@ -1302,7 +1384,7 @@
-----------------------------------------------------
Syscall param iopl(level) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:510)
+ by 0x........: main (scalar.c:518)
-----------------------------------------------------
111: __NR_vhangup 0s 0m
@@ -1318,28 +1400,28 @@
-----------------------------------------------------
Syscall param wait4(pid) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:526)
+ by 0x........: main (scalar.c:534)
Syscall param wait4(status) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:526)
+ by 0x........: main (scalar.c:534)
Syscall param wait4(options) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:526)
+ by 0x........: main (scalar.c:534)
Syscall param wait4(rusage) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:526)
+ by 0x........: main (scalar.c:534)
Syscall param wait4(status) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:526)
+ by 0x........: main (scalar.c:534)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
Syscall param wait4(rusage) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:526)
+ by 0x........: main (scalar.c:534)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
-----------------------------------------------------
@@ -1350,11 +1432,11 @@
-----------------------------------------------------
Syscall param sysinfo(info) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:534)
+ by 0x........: main (scalar.c:542)
Syscall param sysinfo(info) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:534)
+ by 0x........: main (scalar.c:542)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
-----------------------------------------------------
@@ -1362,34 +1444,34 @@
-----------------------------------------------------
Syscall param ipc(call) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:541)
+ by 0x........: main (scalar.c:549)
Syscall param ipc(first) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:541)
+ by 0x........: main (scalar.c:549)
Syscall param ipc(second) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:541)
+ by 0x........: main (scalar.c:549)
Syscall param ipc(third) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:541)
+ by 0x........: main (scalar.c:549)
Syscall param ipc(ptr) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:541)
+ by 0x........: main (scalar.c:549)
Syscall param ipc(fifth) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:541)
+ by 0x........: main (scalar.c:549)
-----------------------------------------------------
118: __NR_fsync 1s 0m
-----------------------------------------------------
Syscall param fsync(fd) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:545)
+ by 0x........: main (scalar.c:553)
-----------------------------------------------------
119: __NR_sigreturn n/a
@@ -1399,37 +1481,37 @@
-----------------------------------------------------
Syscall param clone(flags) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:556)
+ by 0x........: main (scalar.c:564)
Syscall param clone(child_stack) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:556)
+ by 0x........: main (scalar.c:564)
Syscall param clone(parent_tidptr) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:556)
+ by 0x........: main (scalar.c:564)
Syscall param clone(parent_tidptr) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:556)
+ by 0x........: main (scalar.c:564)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
Syscall param clone(tlsinfo) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:556)
+ by 0x........: main (scalar.c:564)
Syscall param clone(tlsinfo) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:556)
+ by 0x........: main (scalar.c:564)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
Syscall param clone(child_tidptr) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:556)
+ by 0x........: main (scalar.c:564)
Syscall param clone(child_tidptr) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:556)
+ by 0x........: main (scalar.c:564)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
-----------------------------------------------------
@@ -1440,11 +1522,11 @@
-----------------------------------------------------
Syscall param uname(buf) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:567)
+ by 0x........: main (scalar.c:575)
Syscall param uname(buf) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:567)
+ by 0x........: main (scalar.c:575)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
-----------------------------------------------------
@@ -1452,19 +1534,19 @@
-----------------------------------------------------
Syscall param modify_ldt(func) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:571)
+ by 0x........: main (scalar.c:579)
Syscall param modify_ldt(ptr) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:571)
+ by 0x........: main (scalar.c:579)
Syscall param modify_ldt(bytecount) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:571)
+ by 0x........: main (scalar.c:579)
Syscall param modify_ldt(ptr) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:571)
+ by 0x........: main (scalar.c:579)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
-----------------------------------------------------
@@ -1475,41 +1557,41 @@
-----------------------------------------------------
Syscall param mprotect(addr) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:580)
+ by 0x........: main (scalar.c:588)
Syscall param mprotect(len) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:580)
+ by 0x........: main (scalar.c:588)
Syscall param mprotect(prot) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:580)
+ by 0x........: main (scalar.c:588)
-----------------------------------------------------
126: __NR_sigprocmask 3s 2m
-----------------------------------------------------
Syscall param sigprocmask(how) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:584)
+ by 0x........: main (scalar.c:592)
Syscall param sigprocmask(set) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:584)
+ by 0x........: main (scalar.c:592)
Syscall param sigprocmask(oldset) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:584)
+ by 0x........: main (scalar.c:592)
Syscall param sigprocmask(set) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:584)
+ by 0x........: main (scalar.c:592)
Address 0x........ is 0 bytes after a block of size 4 alloc'd
at 0x........: malloc (vg_replace_malloc.c:...)
by 0x........: main (scalar.c:30)
Syscall param sigprocmask(oldset) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:584)
+ by 0x........: main (scalar.c:592)
Address 0x........ is 0 bytes after a block of size 4 alloc'd
at 0x........: malloc (vg_replace_malloc.c:...)
by 0x........: main (scalar.c:30)
@@ -1522,24 +1604,24 @@
-----------------------------------------------------
Syscall param init_module(umod) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:592)
+ by 0x........: main (scalar.c:600)
Syscall param init_module(len) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:592)
+ by 0x........: main (scalar.c:600)
Syscall param init_module(uargs) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:592)
+ by 0x........: main (scalar.c:600)
Syscall param init_module(umod) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:592)
+ by 0x........: main (scalar.c:600)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
Syscall param init_module(uargs) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:592)
+ by 0x........: main (scalar.c:600)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
-----------------------------------------------------
@@ -1553,23 +1635,23 @@
-----------------------------------------------------
Syscall param quotactl(cmd) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:604)
+ by 0x........: main (scalar.c:612)
Syscall param quotactl(special) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:604)
+ by 0x........: main (scalar.c:612)
Syscall param quotactl(id) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:604)
+ by 0x........: main (scalar.c:612)
Syscall param quotactl(addr) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:604)
+ by 0x........: main (scalar.c:612)
Syscall param quotactl(special) points to unaddressable byte(s)
...
- by 0x........: main (scalar.c:604)
+ by 0x........: main (scalar.c:612)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
-----------------------------------------------------
@@ -1577,14 +1659,14 @@
-----------------------------------------------------
Syscall param getpgid(pid) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:608)
+ by 0x........: main (scalar.c:616)
-----------------------------------------------------
133: __NR_fchdir 1s 0m
-----------------------------------------------------
Syscall param fchdir(fd) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:612)
+ by 0x........: main (scalar.c:620)
-----------------------------------------------------
134: __NR_bdflush n/a
@@ -1597,7 +1679,7 @@
-----------------------------------------------------
Syscall param personality(persona) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:624)
+ by 0x........: main (scalar.c:632)
-----------------------------------------------------
137: __NR_afs_syscall ni
@@ -1607,41 +1689,41 @@
-----------------------------------------------------
Syscall param setfsuid16(uid) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:632)
+ by 0x........: main (scalar.c:640)
-----------------------------------------------------
139: __NR_setfsgid 1s 0m
-----------------------------------------------------
Syscall param setfsgid16(gid) contains uninitialised byte(s)
...
- by 0x........: main (scalar.c:636)
+ by 0x........: main (scalar.c:644)
-----------------------------------------------------
140: __NR__llseek 5s 1m
-----------------------------------------------------
Syscall param llseek(fd) contains uninitialised byte(s)
...
...
[truncated message content] |
|
From: <sv...@va...> - 2017-04-10 17:56:06
|
Author: petarj
Date: Mon Apr 10 18:55:59 2017
New Revision: 16300
Log:
Update svn:ignore list
Add vgprintf_nvalgrind to it.
Modified:
trunk/none/tests/ (props changed)
|
|
From: <sv...@va...> - 2017-04-10 17:43:26
|
Author: petarj
Date: Mon Apr 10 18:43:20 2017
New Revision: 16299
Log:
mips64: update Makefile
Update Makefile with new name for the stdout.exp file.
Missed to do this as part of r16298.
Modified:
trunk/none/tests/mips64/Makefile.am
Modified: trunk/none/tests/mips64/Makefile.am
==============================================================================
--- trunk/none/tests/mips64/Makefile.am (original)
+++ trunk/none/tests/mips64/Makefile.am Mon Apr 10 18:43:20 2017
@@ -21,7 +21,7 @@
cvm_atomic.stdout.exp-LE cvm_atomic.stdout.exp-BE \
cvm_atomic.stdout.exp-non-octeon \
cvm_atomic.stderr.exp cvm_atomic.vgtest \
- cvm_atomic_thread.stdout.exp-LE cvm_atomic_thread.stdout.exp-non-octeon \
+ cvm_atomic_thread.stdout.exp cvm_atomic_thread.stdout.exp-non-octeon \
cvm_atomic_thread.stderr.exp cvm_atomic_thread.vgtest \
extract_insert_bit_field.stdout.exp-mips64 \
extract_insert_bit_field.stdout.exp-mips64r2 \
|
|
From: <sv...@va...> - 2017-04-10 17:11:10
|
Author: petarj
Date: Mon Apr 10 18:11:01 2017
New Revision: 16298
Log:
mips64: update cvm_atomic_thread test for BE
Update the test cvm_atomic_thread so it can be executed on BE boards too.
Reuse the stdout.exp file.
Based on patch from Tamara Vlahovic.
Added:
trunk/none/tests/mips64/cvm_atomic_thread.stdout.exp
- copied unchanged from r16295, trunk/none/tests/mips64/cvm_atomic_thread.stdout.exp-LE
Removed:
trunk/none/tests/mips64/cvm_atomic_thread.stdout.exp-LE
Modified:
trunk/none/tests/mips64/cvm_atomic_thread.c
Modified: trunk/none/tests/mips64/cvm_atomic_thread.c
==============================================================================
--- trunk/none/tests/mips64/cvm_atomic_thread.c (original)
+++ trunk/none/tests/mips64/cvm_atomic_thread.c Mon Apr 10 18:11:01 2017
@@ -14,7 +14,7 @@
#define NNN 3456987 // Number of repetition.
/* Expected values */
-long long int p1_expd[N] = { 2156643710, 2156643710, 3456986, 6913974,
+int p1_expd[N] = { 2156643710, 2156643710, 3456986, 6913974,
4288053322, 0, 4294967295,
6913974, 21777111,
3456986, 2153186724,
@@ -34,7 +34,7 @@
#define IS_8_ALIGNED(_ptr) (0 == (((unsigned long)(_ptr)) & 7))
-__attribute__((noinline)) void atomic_saa ( long long int* p, int n )
+__attribute__((noinline)) void atomic_saa ( int* p, int n )
{
#if (_MIPS_ARCH_OCTEON2)
unsigned long block[2] = { (unsigned long)p, (unsigned long)n };
@@ -66,7 +66,7 @@
#endif
}
-__attribute__((noinline)) void atomic_laa ( long long int* p, int n )
+__attribute__((noinline)) void atomic_laa ( int* p, int n )
{
#if (_MIPS_ARCH_OCTEON2)
unsigned long block[2] = { (unsigned long)p, (unsigned long)n };
@@ -98,7 +98,7 @@
#endif
}
-__attribute__((noinline)) void atomic_law ( long long int* p, int n )
+__attribute__((noinline)) void atomic_law ( int* p, int n )
{
#if (_MIPS_ARCH_OCTEON2)
unsigned long block[2] = { (unsigned long)p, (unsigned long)n };
@@ -130,7 +130,7 @@
#endif
}
-__attribute__((noinline)) void atomic_lai ( long long int* p )
+__attribute__((noinline)) void atomic_lai ( int* p )
{
#if (_MIPS_ARCH_OCTEON2)
unsigned long block[2] = { (unsigned long)p };
@@ -162,7 +162,7 @@
#endif
}
-__attribute__((noinline)) void atomic_lad ( long long int* p )
+__attribute__((noinline)) void atomic_lad ( int* p )
{
#if (_MIPS_ARCH_OCTEON2)
unsigned long block[2] = { (unsigned long)p };
@@ -194,7 +194,7 @@
#endif
}
-__attribute__((noinline)) void atomic_lac ( long long int* p )
+__attribute__((noinline)) void atomic_lac ( int* p )
{
#if (_MIPS_ARCH_OCTEON2)
unsigned long block[2] = { (unsigned long)p };
@@ -226,7 +226,7 @@
#endif
}
-__attribute__((noinline)) void atomic_las ( long long int* p )
+__attribute__((noinline)) void atomic_las ( int* p )
{
#if (_MIPS_ARCH_OCTEON2)
unsigned long block[2] = { (unsigned long)p };
@@ -307,7 +307,7 @@
#if (_MIPS_ARCH_OCTEON2)
int i, status;
char* page[N];
- long long int* p1[N];
+ int* p1[N];
long long int* p2[N];
pid_t child, pc2;
@@ -321,8 +321,8 @@
perror("mmap failed");
exit(1);
}
- p1[i] = (long long int*)(page[i]+0);
- p2[i] = (long long int*)(page[i]+256);
+ p1[i] = (int*)(page[i] + 0);
+ p2[i] = (long long int*)(page[i] + 256);
assert( IS_8_ALIGNED(p1[i]) );
assert( IS_8_ALIGNED(p2[i]) );
@@ -345,11 +345,11 @@
printf("child\n");
for (i = 0; i < NNN; i++) {
atomic_saa(p1[0], i);
- atomic_saad(p2[0], i+98765 ); /* ensure we hit the upper 32 bits */
+ atomic_saad(p2[0], i + 98765 ); /* ensure we hit the upper 32 bits */
atomic_laa(p1[1], i);
- atomic_laad(p2[1], i+98765 ); /* ensure we hit the upper 32 bits */
+ atomic_laad(p2[1], i + 98765 ); /* ensure we hit the upper 32 bits */
atomic_law(p1[2], i);
- atomic_lawd(p2[2], i+98765 ); /* ensure we hit the upper 32 bits */
+ atomic_lawd(p2[2], i + 98765 ); /* ensure we hit the upper 32 bits */
atomic_lai(p1[3]);
atomic_laid(p2[3]);
atomic_lad(p1[4]);
@@ -381,11 +381,11 @@
for (i = 0; i < NNN; i++) {
atomic_saa(p1[0], i);
- atomic_saad(p2[0], i+98765); /* ensure we hit the upper 32 bits */
+ atomic_saad(p2[0], i + 98765); /* ensure we hit the upper 32 bits */
atomic_laa(p1[1], i);
- atomic_laad(p2[1], i+98765); /* ensure we hit the upper 32 bits */
+ atomic_laad(p2[1], i + 98765); /* ensure we hit the upper 32 bits */
atomic_law(p1[2], i);
- atomic_lawd(p2[2], i+98765 ); /* ensure we hit the upper 32 bits */
+ atomic_lawd(p2[2], i + 98765 ); /* ensure we hit the upper 32 bits */
atomic_lai(p1[3]);
atomic_laid(p2[3]);
atomic_lad(p1[4]);
@@ -414,25 +414,25 @@
/* assert that child finished normally */
assert(WIFEXITED(status));
- printf("Store Atomic Add: 32 bit %lld, 64 bit %lld\n", *p1[0], *p2[0]);
- printf("Load Atomic Add: 32 bit %lld, 64 bit %lld\n", *p1[1], *p2[1]);
- printf("Load Atomic Swap: 32 bit %lld, 64 bit %lld\n", *p1[2], *p2[2]);
- printf("Load Atomic Increment: 32 bit %lld, 64 bit %lld\n", *p1[3], *p2[3]);
- printf("Load Atomic Decrement: 32 bit %lld, 64 bit %lld\n", *p1[4], *p2[4]);
- printf("Load Atomic Clear: 32 bit %lld, 64 bit %lld\n", *p1[5], *p2[5]);
- printf("Load Atomic Set: 32 bit %lld, 64 bit %lld\n", *p1[6], *p2[6]);
- printf("laa and saa: base1: %lld, base2: %lld\n", *p1[7], *p1[8]);
- printf("laad and saad: base1: %lld, base2: %lld\n", *p2[7], *p2[8]);
- printf("law and saa: base1: %lld, base2: %lld\n", *p1[9], *p1[10]);
- printf("lawd and saad: base1: %lld, base2: %lld\n", *p2[9], *p2[10]);
- printf("lai and saa: base1: %lld, base2: %lld\n", *p1[11], *p1[12]);
- printf("laid and saad: base1: %lld, base2: %lld\n", *p2[11], *p2[12]);
- printf("las and saa: base1: %lld, base2: %lld\n", *p1[13], *p1[14]);
- printf("lasd and saad: base1: %lld, base2: %lld\n", *p2[13], *p2[14]);
- printf("lad and saa: base1: %lld, base2: %lld\n", *p1[15], *p1[16]);
- printf("ladd and saad: base1: %lld, base2: %lld\n", *p2[15], *p2[16]);
- printf("lac and saa: base1: %lld, base2: %lld\n", *p1[17], *p1[18]);
- printf("lacd and saad: base1: %lld, base2: %lld\n", *p2[17], *p2[18]);
+ printf("Store Atomic Add: 32 bit %u, 64 bit %lld\n", *p1[0], *p2[0]);
+ printf("Load Atomic Add: 32 bit %u, 64 bit %lld\n", *p1[1], *p2[1]);
+ printf("Load Atomic Swap: 32 bit %u, 64 bit %lld\n", *p1[2], *p2[2]);
+ printf("Load Atomic Increment: 32 bit %u, 64 bit %lld\n", *p1[3], *p2[3]);
+ printf("Load Atomic Decrement: 32 bit %u, 64 bit %lld\n", *p1[4], *p2[4]);
+ printf("Load Atomic Clear: 32 bit %u, 64 bit %lld\n", *p1[5], *p2[5]);
+ printf("Load Atomic Set: 32 bit %u, 64 bit %lld\n", *p1[6], *p2[6]);
+ printf("laa and saa: base1: %u, base2: %u\n", *p1[7], *p1[8]);
+ printf("laad and saad: base1: %lld, base2: %lld\n", *p2[7], *p2[8]);
+ printf("law and saa: base1: %u, base2: %u\n", *p1[9], *p1[10]);
+ printf("lawd and saad: base1: %lld, base2: %lld\n", *p2[9], *p2[10]);
+ printf("lai and saa: base1: %u, base2: %u\n", *p1[11], *p1[12]);
+ printf("laid and saad: base1: %lld, base2: %lld\n", *p2[11], *p2[12]);
+ printf("las and saa: base1: %u, base2: %u\n", *p1[13], *p1[14]);
+ printf("lasd and saad: base1: %lld, base2: %lld\n", *p2[13], *p2[14]);
+ printf("lad and saa: base1: %u, base2: %u\n", *p1[15], *p1[16]);
+ printf("ladd and saad: base1: %lld, base2: %lld\n", *p2[15], *p2[16]);
+ printf("lac and saa: base1: %u, base2: %u\n", *p1[17], *p1[18]);
+ printf("lacd and saad: base1: %lld, base2: %lld\n", *p2[17], *p2[18]);
for (i = 0; i < N; i++) {
if (p1_expd[i] == *p1[i] && p2_expd[i] == *p2[i]) {
Removed: trunk/none/tests/mips64/cvm_atomic_thread.stdout.exp-LE
==============================================================================
--- trunk/none/tests/mips64/cvm_atomic_thread.stdout.exp-LE (original)
+++ trunk/none/tests/mips64/cvm_atomic_thread.stdout.exp-LE (removed)
@@ -1,43 +0,0 @@
-parent, pre-fork
-child
-parent, pre-fork
-parent
-Store Atomic Add: 32 bit 2156643710, 64 bit 12633614303292
-Load Atomic Add: 32 bit 2156643710, 64 bit 12633614303292
-Load Atomic Swap: 32 bit 3456986, 64 bit 3555751
-Load Atomic Increment: 32 bit 6913974, 64 bit 6913974
-Load Atomic Decrement: 32 bit 4288053322, 64 bit -6913974
-Load Atomic Clear: 32 bit 0, 64 bit 0
-Load Atomic Set: 32 bit 4294967295, 64 bit -1
-laa and saa: base1: 6913974, base2: 21777111
-laad and saad: base1: 6913974, base2: 23901514779351
-law and saa: base1: 3456986, base2: 2153186724
-lawd and saad: base1: 3456986, base2: 11950752204196
-lai and saa: base1: 6913974, base2: 21777111
-laid and saad: base1: 6913974, base2: 23901514779351
-las and saa: base1: 4294967295, base2: 4288053323
-lasd and saad: base1: -1, base2: -6913973
-lad and saa: base1: 4288053322, base2: 4273190185
-ladd and saad: base1: -6913974, base2: -23901514779351
-lac and saa: base1: 0, base2: 0
-lacd and saad: base1: 0, base2: 0
-PASS 1
-PASS 2
-PASS 3
-PASS 4
-PASS 5
-PASS 6
-PASS 7
-PASS 8
-PASS 9
-PASS 10
-PASS 11
-PASS 12
-PASS 13
-PASS 14
-PASS 15
-PASS 16
-PASS 17
-PASS 18
-PASS 19
-parent exits
|
|
From: Ivo R. <iv...@iv...> - 2017-04-07 16:58:25
|
I've prepared patch for this bug: https://bugs.kde.org/show_bug.cgi?id=378535 If you have any objections to it, please say so. I. |
|
From: <sv...@va...> - 2017-04-06 12:46:13
|
Author: petarj
Date: Thu Apr 6 13:46:06 2017
New Revision: 16297
Log:
Update NEWS
r16296 has fixed Bug 359202.
Modified:
trunk/NEWS
Modified: trunk/NEWS
==============================================================================
--- trunk/NEWS (original)
+++ trunk/NEWS Thu Apr 6 13:46:06 2017
@@ -105,6 +105,7 @@
352767 Wine/valgrind: noted but unhandled ioctl 0x5307 [..] (CDROMSTOP)
358213 helgrind/drd bar_bad testcase hangs or crashes with new glibc pthread
barrier implementation
+359202 Add musl libc configure/compile
368863 WARNING: unhandled arm64-linux syscall: 100 (get_robust_list)
368865 WARNING: unhandled arm64-linux syscall: 272 (kcmp)
368917 WARNING: unhandled arm64-linux syscall: 218 (request_key)
|
|
From: <sv...@va...> - 2017-04-06 12:39:26
|
Author: petarj Date: Thu Apr 6 13:39:15 2017 New Revision: 16296 Log: Add musl libc configure/compile - add musl libc detection (prevents configure error) - adjust preload and symbol names (based on the OpenWrt patch, see [1]) [1] https://dev.openwrt.org/browser/trunk/package/devel/valgrind/patches/ 200-musl_fix.patch?rev=46302 Patch by Peter Seiderer <ps....@gm...> It fixes Bug 359202. Modified: trunk/configure.ac trunk/coregrind/vg_preloaded.c trunk/include/pub_tool_redir.h Modified: trunk/configure.ac ============================================================================== --- trunk/configure.ac (original) +++ trunk/configure.ac Thu Apr 6 13:39:15 2017 @@ -990,6 +990,13 @@ GLIBC_VERSION="solaris" fi +# GLIBC_VERSION is empty if a musl libc is used, so use the toolchain tuple +# in this case. +if test x$GLIBC_VERSION = x; then + if $CC -dumpmachine | grep -q musl; then + GLIBC_VERSION=musl + fi +fi AC_MSG_CHECKING([the glibc version]) @@ -1045,10 +1052,15 @@ # DEFAULT_SUPP set in host_os switch-case above. # No other suppression file is used. ;; + musl) + AC_MSG_RESULT(Musl) + AC_DEFINE([MUSL_LIBC], 1, [Define to 1 if you're using Musl libc]) + # no DEFAULT_SUPP file yet for musl libc. + ;; 2.0|2.1|*) AC_MSG_RESULT([unsupported version ${GLIBC_VERSION}]) - AC_MSG_ERROR([Valgrind requires glibc version 2.2 or later,]) - AC_MSG_ERROR([Darwin libc, Bionic libc or Solaris libc]) + AC_MSG_ERROR([Valgrind requires glibc version 2.2 or later, uClibc,]) + AC_MSG_ERROR([musl libc, Darwin libc, Bionic libc or Solaris libc]) ;; esac Modified: trunk/coregrind/vg_preloaded.c ============================================================================== --- trunk/coregrind/vg_preloaded.c (original) +++ trunk/coregrind/vg_preloaded.c Thu Apr 6 13:39:15 2017 @@ -57,7 +57,7 @@ void VG_NOTIFY_ON_LOAD(freeres)(Vg_FreeresToRun to_run); void VG_NOTIFY_ON_LOAD(freeres)(Vg_FreeresToRun to_run) { -# if !defined(__UCLIBC__) \ +# if !defined(__UCLIBC__) && !defined(MUSL_LIBC) \ && !defined(VGPV_arm_linux_android) \ && !defined(VGPV_x86_linux_android) \ && !defined(VGPV_mips32_linux_android) \ Modified: trunk/include/pub_tool_redir.h ============================================================================== --- trunk/include/pub_tool_redir.h (original) +++ trunk/include/pub_tool_redir.h Thu Apr 6 13:39:15 2017 @@ -244,8 +244,11 @@ /* --- Soname of the standard C library. --- */ #if defined(VGO_linux) || defined(VGO_solaris) +# if defined(MUSL_LIBC) +# define VG_Z_LIBC_SONAME libcZdZa // libc.* +#else # define VG_Z_LIBC_SONAME libcZdsoZa // libc.so* - +#endif #elif defined(VGO_darwin) && (DARWIN_VERS <= DARWIN_10_6) # define VG_Z_LIBC_SONAME libSystemZdZaZddylib // libSystem.*.dylib @@ -276,7 +279,11 @@ /* --- Soname of the pthreads library. --- */ #if defined(VGO_linux) +# if defined(MUSL_LIBC) +# define VG_Z_LIBPTHREAD_SONAME libcZdZa // libc.* +#else # define VG_Z_LIBPTHREAD_SONAME libpthreadZdsoZd0 // libpthread.so.0 +#endif #elif defined(VGO_darwin) # define VG_Z_LIBPTHREAD_SONAME libSystemZdZaZddylib // libSystem.*.dylib #elif defined(VGO_solaris) |
|
From: <sv...@va...> - 2017-04-04 21:27:46
|
Author: iraisr
Date: Tue Apr 4 22:27:39 2017
New Revision: 16295
Log:
Adjust after adding a 'hint' to IRIfThenElse.
Modified:
branches/VALGRIND_JIT_HACKS/coregrind/m_gdbserver/m_gdbserver.c
branches/VALGRIND_JIT_HACKS/coregrind/m_translate.c
branches/VALGRIND_JIT_HACKS/memcheck/mc_translate.c
Modified: branches/VALGRIND_JIT_HACKS/coregrind/m_gdbserver/m_gdbserver.c
==============================================================================
--- branches/VALGRIND_JIT_HACKS/coregrind/m_gdbserver/m_gdbserver.c (original)
+++ branches/VALGRIND_JIT_HACKS/coregrind/m_gdbserver/m_gdbserver.c Tue Apr 4 22:27:39 2017
@@ -1298,13 +1298,14 @@
}
if (st->tag == Ist_IfThenElse) {
+ IRIfThenElse* ite = st->Ist.IfThenElse.details;
st = IRStmt_IfThenElse(
- st->Ist.IfThenElse.cond,
- instrument_for_gdbserver_IRStmtVec(st->Ist.IfThenElse.then_leg,
- stmts_out, instr_needed, layout, vge, gWordTy, hWordTy),
- instrument_for_gdbserver_IRStmtVec(st->Ist.IfThenElse.else_leg,
- stmts_out, instr_needed, layout, vge, gWordTy, hWordTy),
- st->Ist.IfThenElse.phi_nodes);
+ ite->cond, ite->hint,
+ instrument_for_gdbserver_IRStmtVec(ite->then_leg, stmts_out,
+ instr_needed, layout, vge, gWordTy, hWordTy),
+ instrument_for_gdbserver_IRStmtVec(ite->else_leg, stmts_out,
+ instr_needed, layout, vge, gWordTy, hWordTy),
+ ite->phi_nodes);
}
addStmtToIRStmtVec(stmts_out, st);
Modified: branches/VALGRIND_JIT_HACKS/coregrind/m_translate.c
==============================================================================
--- branches/VALGRIND_JIT_HACKS/coregrind/m_translate.c (original)
+++ branches/VALGRIND_JIT_HACKS/coregrind/m_translate.c Tue Apr 4 22:27:39 2017
@@ -648,15 +648,14 @@
}
if (st->tag == Ist_IfThenElse) {
+ IRIfThenElse* ite = st->Ist.IfThenElse.details;
st = IRStmt_IfThenElse(
- st->Ist.IfThenElse.cond,
- vg_SP_update_IRStmtVec(closureV, tyenv,
- st->Ist.IfThenElse.then_leg, out,
+ ite->cond, ite->hint,
+ vg_SP_update_IRStmtVec(closureV, tyenv, ite->then_leg, out,
layout, vge, vai, gWordTy, hWordTy),
- vg_SP_update_IRStmtVec(closureV, tyenv,
- st->Ist.IfThenElse.else_leg, out,
+ vg_SP_update_IRStmtVec(closureV, tyenv, ite->else_leg, out,
layout, vge, vai, gWordTy, hWordTy),
- st->Ist.IfThenElse.phi_nodes);
+ ite->phi_nodes);
}
/* well, not interesting. Just copy and keep going. */
Modified: branches/VALGRIND_JIT_HACKS/memcheck/mc_translate.c
==============================================================================
--- branches/VALGRIND_JIT_HACKS/memcheck/mc_translate.c (original)
+++ branches/VALGRIND_JIT_HACKS/memcheck/mc_translate.c Tue Apr 4 22:27:39 2017
@@ -6256,8 +6256,7 @@
static void instrument_IRStmtVec(IRStmtVec* stmts_in, UInt stmts_in_first,
MCEnv* mce);
-static void do_shadow_IfThenElse(MCEnv* mce, IRExpr* cond, IRStmtVec* then_leg,
- IRStmtVec* else_leg, IRPhiVec* phi_nodes_in)
+static void do_shadow_IfThenElse(MCEnv* mce, IRIfThenElse* ite)
{
IRTemp (*findShadowTmp)(MCEnv* mce, IRTemp orig);
HChar category;
@@ -6269,19 +6268,19 @@
category = 'V';
}
- complainIfUndefined(mce, cond, NULL);
+ complainIfUndefined(mce, ite->cond, NULL);
MCEnv then_mce;
- initMCEnv(mce->tyenv, then_leg, &then_mce, mce);
- instrument_IRStmtVec(then_leg, 0, &then_mce);
+ initMCEnv(mce->tyenv, ite->then_leg, &then_mce, mce);
+ instrument_IRStmtVec(ite->then_leg, 0, &then_mce);
MCEnv else_mce;
- initMCEnv(mce->tyenv, else_leg, &else_mce, mce);
- instrument_IRStmtVec(else_leg, 0, &else_mce);
+ initMCEnv(mce->tyenv, ite->else_leg, &else_mce, mce);
+ instrument_IRStmtVec(ite->else_leg, 0, &else_mce);
IRPhiVec* phi_nodes_out = emptyIRPhiVec();
- for (UInt i = 0; i < phi_nodes_in->phis_used; i++) {
- IRPhi* phi_in = phi_nodes_in->phis[i];
+ for (UInt i = 0; i < ite->phi_nodes->phis_used; i++) {
+ IRPhi* phi_in = ite->phi_nodes->phis[i];
IRPhi* phi_shadow = mkIRPhi(findShadowTmp(mce, phi_in->dst),
findShadowTmp(&then_mce, phi_in->srcThen),
findShadowTmp(&else_mce, phi_in->srcElse));
@@ -6289,8 +6288,8 @@
phi('C', mce, phi_nodes_out, phi_in);
}
- stmt(category, mce, IRStmt_IfThenElse(cond, then_mce.stmts, else_mce.stmts,
- phi_nodes_out));
+ stmt(category, mce, IRStmt_IfThenElse(ite->cond, ite->hint, then_mce.stmts,
+ else_mce.stmts, phi_nodes_out));
deinitMCEnv(&then_mce);
deinitMCEnv(&else_mce);
}
@@ -6440,9 +6439,9 @@
? isBogusAtom(st->Ist.LLSC.storedata)
: False);
case Ist_IfThenElse:
- return isBogusAtom(st->Ist.IfThenElse.cond)
- || isBogusIRStmtVec(st->Ist.IfThenElse.then_leg)
- || isBogusIRStmtVec(st->Ist.IfThenElse.else_leg);
+ return isBogusAtom(st->Ist.IfThenElse.details->cond)
+ || isBogusIRStmtVec(st->Ist.IfThenElse.details->then_leg)
+ || isBogusIRStmtVec(st->Ist.IfThenElse.details->else_leg);
default:
unhandled:
ppIRStmt(st, NULL, 0);
@@ -6566,10 +6565,7 @@
break;
case Ist_IfThenElse:
- do_shadow_IfThenElse(mce, st->Ist.IfThenElse.cond,
- st->Ist.IfThenElse.then_leg,
- st->Ist.IfThenElse.else_leg,
- st->Ist.IfThenElse.phi_nodes);
+ do_shadow_IfThenElse(mce, st->Ist.IfThenElse.details);
/* Note, do_shadow_IfThenElse copies the IfThenElse itself to the
output stmts, because it needs to add instrumentation to the legs
and to phi nodes. Hence skip the copy below. Also skip the
@@ -6981,8 +6977,8 @@
tl_assert(st);
if (st->tag == Ist_IfThenElse) {
- final_tidy_IRStmtVec(st->Ist.IfThenElse.then_leg);
- final_tidy_IRStmtVec(st->Ist.IfThenElse.else_leg);
+ final_tidy_IRStmtVec(st->Ist.IfThenElse.details->then_leg);
+ final_tidy_IRStmtVec(st->Ist.IfThenElse.details->else_leg);
}
if (st->tag != Ist_Dirty)
|
|
From: <sv...@va...> - 2017-04-04 21:26:54
|
Author: iraisr
Date: Tue Apr 4 22:26:45 2017
New Revision: 3345
Log:
Add a 'hint' to If-Then-Else control flow diamon.
Modified:
branches/VEX_JIT_HACKS/priv/ir_defs.c
branches/VEX_JIT_HACKS/priv/ir_opt.c
branches/VEX_JIT_HACKS/pub/libvex_ir.h
Modified: branches/VEX_JIT_HACKS/priv/ir_defs.c
==============================================================================
--- branches/VEX_JIT_HACKS/priv/ir_defs.c (original)
+++ branches/VEX_JIT_HACKS/priv/ir_defs.c Tue Apr 4 22:26:45 2017
@@ -1601,6 +1601,31 @@
ppIRTypeEnvDefd(NULL, defset, depth);
}
+void ppIRIfThenElse_Hint(IRIfThenElse_Hint hint)
+{
+ switch (hint) {
+ case IfThenElse_ThenLikely: vex_printf("IfThenElse_ThenLikely"); break;
+ case IfThenElse_ElseLikely: vex_printf("IfThenElse_ElseLikely"); break;
+ default: vpanic("ppIRIfThenElse_Hint");
+ }
+}
+
+void ppIRIfThenElse(const IRIfThenElse* ite, const IRTypeEnv* tyenv, UInt depth)
+{
+ vex_printf("if (");
+ ppIRExpr(ite->cond);
+ vex_printf(") [");
+ ppIRIfThenElse_Hint(ite->hint);
+ vex_printf("] then {\n");
+ ppIRStmtVec(ite->then_leg, tyenv, depth + 1);
+ print_depth(depth);
+ vex_printf("} else {\n");
+ ppIRStmtVec(ite->else_leg, tyenv, depth + 1);
+ print_depth(depth);
+ vex_printf("}\n");
+ ppIRPhiVec(ite->phi_nodes, depth);
+}
+
void ppIRStmt(const IRStmt* s, const IRTypeEnv* tyenv, UInt depth)
{
print_depth(depth);
@@ -1686,16 +1711,7 @@
vex_printf(" } ");
break;
case Ist_IfThenElse:
- vex_printf("if (");
- ppIRExpr(s->Ist.IfThenElse.cond);
- vex_printf(") then {\n");
- ppIRStmtVec(s->Ist.IfThenElse.then_leg, tyenv, depth + 1);
- print_depth(depth);
- vex_printf("} else {\n");
- ppIRStmtVec(s->Ist.IfThenElse.else_leg, tyenv, depth + 1);
- print_depth(depth);
- vex_printf("}\n");
- ppIRPhiVec(s->Ist.IfThenElse.phi_nodes, depth);
+ ppIRIfThenElse(s->Ist.IfThenElse.details, tyenv, depth);
break;
default:
vpanic("ppIRStmt");
@@ -2214,8 +2230,7 @@
return lg;
}
-
-/* Constructors -- IRStmt */
+/* Constructors -- IRIfThenElse */
IRPhi* mkIRPhi(IRTemp dst, IRTemp srcThen, IRTemp srcElse)
{
@@ -2245,6 +2260,22 @@
return defset;
}
+IRIfThenElse* mkIRIfThenElse(IRExpr* cond, IRIfThenElse_Hint hint,
+ IRStmtVec* then_leg, IRStmtVec* else_leg,
+ IRPhiVec* phi_nodes)
+{
+ IRIfThenElse* ite = LibVEX_Alloc_inline(sizeof(IRIfThenElse));
+ ite->cond = cond;
+ ite->hint = hint;
+ ite->then_leg = then_leg;
+ ite->else_leg = else_leg;
+ ite->phi_nodes = phi_nodes;
+ return ite;
+}
+
+
+/* Constructors -- IRStmt */
+
IRStmt* IRStmt_NoOp ( void )
{
/* Just use a single static closure. */
@@ -2353,15 +2384,14 @@
return s;
}
-IRStmt* IRStmt_IfThenElse(IRExpr* cond, IRStmtVec* then_leg,
- IRStmtVec* else_leg, IRPhiVec* phi_nodes)
-{
- IRStmt* s = LibVEX_Alloc_inline(sizeof(IRStmt));
- s->tag = Ist_IfThenElse;
- s->Ist.IfThenElse.cond = cond;
- s->Ist.IfThenElse.then_leg = then_leg;
- s->Ist.IfThenElse.else_leg = else_leg;
- s->Ist.IfThenElse.phi_nodes = phi_nodes;
+IRStmt* IRStmt_IfThenElse(IRExpr* cond, IRIfThenElse_Hint hint,
+ IRStmtVec* then_leg, IRStmtVec* else_leg,
+ IRPhiVec* phi_nodes)
+{
+ IRStmt* s = LibVEX_Alloc_inline(sizeof(IRStmt));
+ s->tag = Ist_IfThenElse;
+ s->Ist.IfThenElse.details = mkIRIfThenElse(cond, hint, then_leg, else_leg,
+ phi_nodes);
return s;
}
@@ -2673,11 +2703,13 @@
s->Ist.Exit.jk,
deepCopyIRConst(s->Ist.Exit.dst),
s->Ist.Exit.offsIP);
- case Ist_IfThenElse:
- return IRStmt_IfThenElse(deepCopyIRExpr(s->Ist.IfThenElse.cond),
- deepCopyIRStmtVec(s->Ist.IfThenElse.then_leg, parent),
- deepCopyIRStmtVec(s->Ist.IfThenElse.else_leg, parent),
- deepCopyIRPhiVec(s->Ist.IfThenElse.phi_nodes));
+ case Ist_IfThenElse: {
+ const IRIfThenElse* ite = s->Ist.IfThenElse.details;
+ return IRStmt_IfThenElse(deepCopyIRExpr(ite->cond), ite->hint,
+ deepCopyIRStmtVec(ite->then_leg, parent),
+ deepCopyIRStmtVec(ite->else_leg, parent),
+ deepCopyIRPhiVec(ite->phi_nodes));
+ }
default:
vpanic("deepCopyIRStmt");
}
@@ -3822,7 +3854,8 @@
addStmtToIRStmtVec(bb->stmts, st);
}
-IRStmt *addEmptyIfThenElse(IRSB* bb, IRStmtVec* parent, IRExpr* cond)
+IRStmt *addEmptyIfThenElse(IRSB* bb, IRStmtVec* parent, IRExpr* cond,
+ IRIfThenElse_Hint hint)
{
IRStmtVec* then_leg = emptyIRStmtVec();
then_leg->id = nextIRStmtVecID(bb);
@@ -3832,7 +3865,8 @@
else_leg->id = nextIRStmtVecID(bb);
else_leg->parent = parent;
- IRStmt* st = IRStmt_IfThenElse(cond, then_leg, else_leg, emptyIRPhiVec());
+ IRStmt* st = IRStmt_IfThenElse(cond, hint, then_leg, else_leg,
+ emptyIRPhiVec());
addStmtToIRStmtVec(parent, st);
return st;
}
@@ -4120,9 +4154,9 @@
case Ist_Exit:
return isIRAtom(st->Ist.Exit.guard);
case Ist_IfThenElse:
- return isIRAtom(st->Ist.IfThenElse.cond)
- && isFlatIRStmtVec(st->Ist.IfThenElse.then_leg)
- && isFlatIRStmtVec(st->Ist.IfThenElse.else_leg);
+ return isIRAtom(st->Ist.IfThenElse.details->cond)
+ && isFlatIRStmtVec(st->Ist.IfThenElse.details->then_leg)
+ && isFlatIRStmtVec(st->Ist.IfThenElse.details->else_leg);
default:
vpanic("isFlatIRStmt(st)");
}
@@ -4352,8 +4386,8 @@
{
vassert(stmt->tag == Ist_IfThenElse);
- IRStmtVec* then_leg = stmt->Ist.IfThenElse.then_leg;
- IRStmtVec* else_leg = stmt->Ist.IfThenElse.else_leg;
+ IRStmtVec* then_leg = stmt->Ist.IfThenElse.details->then_leg;
+ IRStmtVec* else_leg = stmt->Ist.IfThenElse.details->else_leg;
useBeforeDef_Temp(bb, then_leg, stmt, phi->srcThen, def_counts);
useBeforeDef_Temp(bb, else_leg, stmt, phi->srcElse, def_counts);
@@ -4456,7 +4490,7 @@
useBeforeDef_Expr(bb, stmts, stmt, stmt->Ist.Exit.guard, def_counts);
break;
case Ist_IfThenElse:
- useBeforeDef_Expr(bb, stmts, stmt, stmt->Ist.IfThenElse.cond,
+ useBeforeDef_Expr(bb, stmts, stmt, stmt->Ist.IfThenElse.details->cond,
def_counts);
/* Traversing into legs and phi nodes driven from
sanityCheckIRStmtVec(). */
@@ -5047,8 +5081,8 @@
sanityCheckFail(bb,stmt,"IRStmt.Exit.offsIP: too low");
break;
case Ist_IfThenElse:
- tcExpr(bb, stmts, stmt, stmt->Ist.IfThenElse.cond, gWordTy);
- if (typeOfIRExpr(tyenv, stmt->Ist.IfThenElse.cond) != Ity_I1)
+ tcExpr(bb, stmts, stmt, stmt->Ist.IfThenElse.details->cond, gWordTy);
+ if (typeOfIRExpr(tyenv, stmt->Ist.IfThenElse.details->cond) != Ity_I1)
sanityCheckFail(bb,stmt,"IRStmt.IfThenElse.cond: not :: Ity_I1");
/* Traversing into legs and phi nodes driven from
sanityCheckIRStmtVec(). */
@@ -5116,8 +5150,9 @@
tcStmt(bb, stmts, stmt, require_flat, gWordTy);
if (stmt->tag == Ist_IfThenElse) {
- const IRStmtVec* then_leg = stmt->Ist.IfThenElse.then_leg;
- const IRStmtVec* else_leg = stmt->Ist.IfThenElse.else_leg;
+ const IRIfThenElse* ite = stmt->Ist.IfThenElse.details;
+ const IRStmtVec* then_leg = ite->then_leg;
+ const IRStmtVec* else_leg = ite->else_leg;
if (then_leg->parent == NULL) {
sanityCheckFail(bb, stmt, "IfThenElse.then.parent is NULL");
@@ -5138,8 +5173,7 @@
id_counts, n_ids, gWordTy);
sanityCheckIRStmtVec(bb, else_leg, require_flat, def_counts,
id_counts, n_ids, gWordTy);
- sanityCheckIRPhiNodes(bb, stmts, stmt,
- stmt->Ist.IfThenElse.phi_nodes, def_counts);
+ sanityCheckIRPhiNodes(bb, stmts, stmt, ite->phi_nodes, def_counts);
}
}
}
Modified: branches/VEX_JIT_HACKS/priv/ir_opt.c
==============================================================================
--- branches/VEX_JIT_HACKS/priv/ir_opt.c (original)
+++ branches/VEX_JIT_HACKS/priv/ir_opt.c Tue Apr 4 22:26:45 2017
@@ -510,14 +510,16 @@
st->Ist.Exit.dst,
st->Ist.Exit.offsIP));
break;
- case Ist_IfThenElse:
- e1 = flatten_Expr(tyenv, stmts, st->Ist.IfThenElse.cond);
- addStmtToIRStmtVec(
- stmts, IRStmt_IfThenElse(e1,
- flatten_IRStmtVec(tyenv, st->Ist.IfThenElse.then_leg, parent),
- flatten_IRStmtVec(tyenv, st->Ist.IfThenElse.else_leg, parent),
- st->Ist.IfThenElse.phi_nodes));
+ case Ist_IfThenElse: {
+ IRIfThenElse* ite = st->Ist.IfThenElse.details;
+ e1 = flatten_Expr(tyenv, stmts, ite->cond);
+ addStmtToIRStmtVec(stmts,
+ IRStmt_IfThenElse(e1, ite->hint,
+ flatten_IRStmtVec(tyenv, ite->then_leg, parent),
+ flatten_IRStmtVec(tyenv, ite->else_leg, parent),
+ ite->phi_nodes));
break;
+ }
default:
vex_printf("\n");
ppIRStmt(st, tyenv, 0);
@@ -720,8 +722,9 @@
if (st->tag == Ist_IfThenElse) {
/* Consider "then" and "else" legs in isolation. */
- redundant_get_removal_IRStmtVec(tyenv, st->Ist.IfThenElse.then_leg);
- redundant_get_removal_IRStmtVec(tyenv, st->Ist.IfThenElse.else_leg);
+ IRIfThenElse* ite = st->Ist.IfThenElse.details;
+ redundant_get_removal_IRStmtVec(tyenv, ite->then_leg);
+ redundant_get_removal_IRStmtVec(tyenv, ite->else_leg);
}
} /* for (UInt i = 0; i < stmts->stmts_used; i++) */
@@ -1009,10 +1012,11 @@
/* Consider "then" and "else" legs in isolation. They get a new env. */
if (st->tag == Ist_IfThenElse) {
- redundant_put_removal_IRStmtVec(tyenv, st->Ist.IfThenElse.then_leg,
- preciseMemExnsFn, pxControl, newHHW());
- redundant_put_removal_IRStmtVec(tyenv, st->Ist.IfThenElse.else_leg,
- preciseMemExnsFn, pxControl, newHHW());
+ IRIfThenElse* ite = st->Ist.IfThenElse.details;
+ redundant_put_removal_IRStmtVec(tyenv, ite->then_leg, preciseMemExnsFn,
+ pxControl, newHHW());
+ redundant_put_removal_IRStmtVec(tyenv, ite->else_leg, preciseMemExnsFn,
+ pxControl, newHHW());
}
}
}
@@ -2862,9 +2866,9 @@
}
case Ist_IfThenElse: {
- vassert(isIRAtom(st->Ist.IfThenElse.cond));
- IRExpr *fcond = fold_Expr(env,
- subst_Expr(env, st->Ist.IfThenElse.cond));
+ IRIfThenElse* ite = st->Ist.IfThenElse.details;
+ vassert(isIRAtom(ite->cond));
+ IRExpr *fcond = fold_Expr(env, subst_Expr(env, ite->cond));
if (fcond->tag == Iex_Const) {
/* Interesting. The condition on this "if-then-else" has folded down
to a constant. */
@@ -2890,22 +2894,18 @@
vpanic("IfThenElse leg lifting unimplemented");
}
- SubstEnv* then_env
- = newSubstEnv(env->tyenv, st->Ist.IfThenElse.then_leg, env);
- IRStmtVec* then_stmts
- = subst_and_fold_Stmts(then_env, st->Ist.IfThenElse.then_leg);
+ SubstEnv* then_env = newSubstEnv(env->tyenv, ite->then_leg, env);
+ IRStmtVec* then_stmts = subst_and_fold_Stmts(then_env, ite->then_leg);
subst_and_fold_PhiNodes(then_env, then_stmts, True /* srcThen */,
- st->Ist.IfThenElse.phi_nodes);
+ ite->phi_nodes);
- SubstEnv* else_env
- = newSubstEnv(env->tyenv, st->Ist.IfThenElse.else_leg, env);
- IRStmtVec* else_stmts
- = subst_and_fold_Stmts(else_env, st->Ist.IfThenElse.else_leg);
+ SubstEnv* else_env = newSubstEnv(env->tyenv, ite->else_leg, env);
+ IRStmtVec* else_stmts = subst_and_fold_Stmts(else_env, ite->else_leg);
subst_and_fold_PhiNodes(else_env, else_stmts, False /* srcThen */,
- st->Ist.IfThenElse.phi_nodes);
+ ite->phi_nodes);
- return IRStmt_IfThenElse(fcond, then_stmts, else_stmts,
- st->Ist.IfThenElse.phi_nodes);
+ return IRStmt_IfThenElse(fcond, ite->hint, then_stmts, else_stmts,
+ ite->phi_nodes);
}
default:
@@ -3214,11 +3214,11 @@
addUses_Expr(set, st->Ist.Exit.guard);
return;
case Ist_IfThenElse: {
- addUses_Expr(set, st->Ist.IfThenElse.cond);
+ IRIfThenElse* ite = st->Ist.IfThenElse.details;
+ addUses_Expr(set, ite->cond);
- IRPhiVec* phi_nodes = st->Ist.IfThenElse.phi_nodes;
- for (UInt i = 0; i < phi_nodes->phis_used; i++) {
- const IRPhi* phi = phi_nodes->phis[i];
+ for (UInt i = 0; i < ite->phi_nodes->phis_used; i++) {
+ const IRPhi* phi = ite->phi_nodes->phis[i];
addUses_Temp(set, phi->srcThen);
addUses_Temp(set, phi->srcElse);
}
@@ -3226,10 +3226,8 @@
Int i_unconditional_exit; // TODO-JIT: unused at the moment
/* Consider both legs simultaneously. If either of them reports an
IRTemp in use, then it won't be eliminated. */
- do_deadcode_IRStmtVec(set, st->Ist.IfThenElse.then_leg,
- &i_unconditional_exit);
- do_deadcode_IRStmtVec(set, st->Ist.IfThenElse.else_leg,
- &i_unconditional_exit);
+ do_deadcode_IRStmtVec(set, ite->then_leg, &i_unconditional_exit);
+ do_deadcode_IRStmtVec(set, ite->else_leg, &i_unconditional_exit);
return;
}
default:
@@ -3357,8 +3355,9 @@
IRStmt* st = stmts->stmts[i];
if (st->tag == Ist_IfThenElse) {
- spec_helpers_IRStmtVec(st->Ist.IfThenElse.then_leg, specHelper, any);
- spec_helpers_IRStmtVec(st->Ist.IfThenElse.else_leg, specHelper, any);
+ IRIfThenElse* ite = st->Ist.IfThenElse.details;
+ spec_helpers_IRStmtVec(ite->then_leg, specHelper, any);
+ spec_helpers_IRStmtVec(ite->else_leg, specHelper, any);
continue;
}
@@ -4103,12 +4102,15 @@
case Ist_NoOp: case Ist_IMark: case Ist_AbiHint:
case Ist_WrTmp: case Ist_Exit: case Ist_LoadG:
paranoia = 0; break;
- case Ist_IfThenElse:
- anyDone |= do_cse_IRStmtVec(tyenv, st->Ist.IfThenElse.then_leg,
+ case Ist_IfThenElse: {
+ IRIfThenElse* ite = st->Ist.IfThenElse.details;
+ anyDone |= do_cse_IRStmtVec(tyenv, ite->then_leg,
allowLoadsToBeCSEd);
- anyDone |= do_cse_IRStmtVec(tyenv, st->Ist.IfThenElse.else_leg,
+ anyDone |= do_cse_IRStmtVec(tyenv, ite->else_leg,
allowLoadsToBeCSEd);
- paranoia = 0; break;
+ paranoia = 0;
+ break;
+ }
default:
vpanic("do_cse_IRStmtVec(1)");
}
@@ -4399,8 +4401,9 @@
}
if (st->tag == Ist_IfThenElse) {
- collapse_AddSub_chains_IRStmtVec(st->Ist.IfThenElse.then_leg);
- collapse_AddSub_chains_IRStmtVec(st->Ist.IfThenElse.else_leg);
+ IRIfThenElse* ite = st->Ist.IfThenElse.details;
+ collapse_AddSub_chains_IRStmtVec(ite->then_leg);
+ collapse_AddSub_chains_IRStmtVec(ite->else_leg);
}
} /* for */
}
@@ -4675,8 +4678,9 @@
}
if (st->tag == Ist_IfThenElse) {
- do_redundant_GetI_elimination(tyenv, st->Ist.IfThenElse.then_leg);
- do_redundant_GetI_elimination(tyenv, st->Ist.IfThenElse.else_leg);
+ IRIfThenElse* ite = st->Ist.IfThenElse.details;
+ do_redundant_GetI_elimination(tyenv, ite->then_leg);
+ do_redundant_GetI_elimination(tyenv, ite->else_leg);
}
}
}
@@ -4695,10 +4699,9 @@
IRStmt* st = stmts->stmts[i];
if (st->tag == Ist_IfThenElse) {
- do_redundant_PutI_elimination(tyenv, st->Ist.IfThenElse.then_leg,
- pxControl);
- do_redundant_PutI_elimination(tyenv, st->Ist.IfThenElse.else_leg,
- pxControl);
+ IRIfThenElse* ite = st->Ist.IfThenElse.details;
+ do_redundant_PutI_elimination(tyenv, ite->then_leg, pxControl);
+ do_redundant_PutI_elimination(tyenv, ite->else_leg, pxControl);
}
if (st->tag != Ist_PutI)
@@ -4898,19 +4901,18 @@
deltaIRExpr(d->mAddr, delta_tmp);
break;
case Ist_IfThenElse: {
- deltaIRExpr(st->Ist.IfThenElse.cond, delta_tmp);
+ IRIfThenElse* ite = st->Ist.IfThenElse.details;
+ deltaIRExpr(ite->cond, delta_tmp);
/* Traverse "then" and "else" legs. Also nested IRStmtVec's need to
be unrolled otherwise the main IRStmtVec will break horribly. */
- deltaIRStmtVec(tyenv, st->Ist.IfThenElse.then_leg, delta_tmp,
- delta_id, stmts);
- deltaIRStmtVec(tyenv, st->Ist.IfThenElse.else_leg, delta_tmp,
- delta_id, stmts);
+ deltaIRStmtVec(tyenv, ite->then_leg, delta_tmp, delta_id, stmts);
+ deltaIRStmtVec(tyenv, ite->else_leg, delta_tmp, delta_id, stmts);
- IRPhiVec* phi_nodes = st->Ist.IfThenElse.phi_nodes;
- for (UInt i = 0; i < phi_nodes->phis_used; i++) {
- phi_nodes->phis[i]->dst += delta_tmp;
- phi_nodes->phis[i]->srcThen += delta_tmp;
- phi_nodes->phis[i]->srcElse += delta_tmp;
+ for (UInt i = 0; i < ite->phi_nodes->phis_used; i++) {
+ IRPhi* phi = ite->phi_nodes->phis[i];
+ phi->dst += delta_tmp;
+ phi->srcThen += delta_tmp;
+ phi->srcElse += delta_tmp;
}
break;
}
@@ -5493,15 +5495,14 @@
aoccCount_Expr(uses, st->Ist.Exit.guard);
return;
case Ist_IfThenElse: {
- aoccCount_Expr(uses, st->Ist.IfThenElse.cond);
- aoccCount_IRStmtVec(uses, st->Ist.IfThenElse.then_leg,
- max_ga_known, max_ga);
- aoccCount_IRStmtVec(uses, st->Ist.IfThenElse.else_leg,
- max_ga_known, max_ga);
- IRPhiVec* phi_nodes = st->Ist.IfThenElse.phi_nodes;
- for (UInt i = 0; i < phi_nodes->phis_used; i++) {
- uses[phi_nodes->phis[i]->srcThen]++;
- uses[phi_nodes->phis[i]->srcElse]++;
+ IRIfThenElse* ite = st->Ist.IfThenElse.details;
+ aoccCount_Expr(uses, ite->cond);
+ aoccCount_IRStmtVec(uses, ite->then_leg, max_ga_known, max_ga);
+ aoccCount_IRStmtVec(uses, ite->else_leg, max_ga_known, max_ga);
+ for (UInt i = 0; i < ite->phi_nodes->phis_used; i++) {
+ IRPhi* phi = ite->phi_nodes->phis[i];
+ uses[phi->srcThen]++;
+ uses[phi->srcElse]++;
}
return;
}
@@ -5918,19 +5919,18 @@
}
return IRStmt_Dirty(d2);
case Ist_IfThenElse: {
+ IRIfThenElse* ite = st->Ist.IfThenElse.details;
ATmpInfo then_env[A_NENV];
initAEnv(then_env, env);
- IRStmtVec* then_leg
- = atbSubst_StmtVec(tyenv, then_env, st->Ist.IfThenElse.then_leg,
- preciseMemExnsFn, pxControl, uses);
+ IRStmtVec* then_leg = atbSubst_StmtVec(tyenv, then_env, ite->then_leg,
+ preciseMemExnsFn, pxControl, uses);
ATmpInfo else_env[A_NENV];
initAEnv(else_env, env);
- IRStmtVec* else_leg
- = atbSubst_StmtVec(tyenv, else_env, st->Ist.IfThenElse.else_leg,
- preciseMemExnsFn, pxControl, uses);
+ IRStmtVec* else_leg = atbSubst_StmtVec(tyenv, else_env, ite->else_leg,
+ preciseMemExnsFn, pxControl, uses);
- const IRPhiVec* phi_nodes = st->Ist.IfThenElse.phi_nodes;
+ const IRPhiVec* phi_nodes = ite->phi_nodes;
IRPhiVec* out = emptyIRPhiVec();
for (UInt i = 0; i < phi_nodes->phis_used; i++) {
IRPhi* phi = phi_nodes->phis[i];
@@ -5953,7 +5953,7 @@
}
}
- return IRStmt_IfThenElse(atbSubst_Expr(env, st->Ist.IfThenElse.cond),
+ return IRStmt_IfThenElse(atbSubst_Expr(env, ite->cond), ite->hint,
then_leg, else_leg, out);
}
default:
@@ -6309,11 +6309,11 @@
continue;
}
- IRStmtVec* then_leg = st->Ist.IfThenElse.then_leg;
- IRStmtVec* else_leg = st->Ist.IfThenElse.else_leg;
- IRPhiVec* phi_nodes = st->Ist.IfThenElse.phi_nodes;
- for (UInt j = 0; j < phi_nodes->phis_used; j++) {
- const IRPhi* phi = phi_nodes->phis[j];
+ IRIfThenElse* ite = st->Ist.IfThenElse.details;
+ IRStmtVec* then_leg = ite->then_leg;
+ IRStmtVec* else_leg = ite->else_leg;
+ for (UInt j = 0; j < ite->phi_nodes->phis_used; j++) {
+ const IRPhi* phi = ite->phi_nodes->phis[j];
addStmtToIRStmtVec(then_leg, IRStmt_WrTmp(phi->dst,
IRExpr_RdTmp(phi->srcThen)));
addStmtToIRStmtVec(else_leg, IRStmt_WrTmp(phi->dst,
@@ -6719,13 +6719,13 @@
case Ist_Exit:
vassert(isIRAtom(st->Ist.Exit.guard));
break;
- case Ist_IfThenElse:
- vassert(isIRAtom(st->Ist.IfThenElse.cond));
- changed |= do_XOR_TRANSFORM_IRStmtVec(tyenv,
- st->Ist.IfThenElse.then_leg);
- changed |= do_XOR_TRANSFORM_IRStmtVec(tyenv,
- st->Ist.IfThenElse.else_leg);
+ case Ist_IfThenElse: {
+ IRIfThenElse* ite = st->Ist.IfThenElse.details;
+ vassert(isIRAtom(ite->cond));
+ changed |= do_XOR_TRANSFORM_IRStmtVec(tyenv, ite->then_leg);
+ changed |= do_XOR_TRANSFORM_IRStmtVec(tyenv, ite->else_leg);
break;
+ }
default:
vex_printf("\n"); ppIRStmt(st, tyenv, 0);
vpanic("do_XOR_TRANSFORMS_IRStmtVec");
@@ -6937,13 +6937,15 @@
case Ist_Exit:
vassert(isIRAtom(st->Ist.Exit.guard));
break;
- case Ist_IfThenElse:
- vassert(isIRAtom(st->Ist.IfThenElse.cond));
+ case Ist_IfThenElse: {
+ IRIfThenElse* ite = st->Ist.IfThenElse.details;
+ vassert(isIRAtom(ite->cond));
considerExpensives_IRStmtVec(hasGetIorPutI, hasVorFtemps,
- tyenv, st->Ist.IfThenElse.then_leg);
+ tyenv, ite->then_leg);
considerExpensives_IRStmtVec(hasGetIorPutI, hasVorFtemps,
- tyenv, st->Ist.IfThenElse.else_leg);
+ tyenv, ite->else_leg);
break;
+ }
default:
bad:
ppIRStmt(st, tyenv, 0);
Modified: branches/VEX_JIT_HACKS/pub/libvex_ir.h
==============================================================================
--- branches/VEX_JIT_HACKS/pub/libvex_ir.h (original)
+++ branches/VEX_JIT_HACKS/pub/libvex_ir.h Tue Apr 4 22:26:45 2017
@@ -2777,17 +2777,60 @@
extern IRTempDefSet* emptyIRTempDefSet(void);
extern IRTempDefSet* deepCopyIRTempDefSet(const IRTempDefSet* defset);
-/* ------------------ Statements ------------------ */
-/* IRStmt and IRStmtVec are mutually recursive. */
+/* --------------- If-Then-Else control flow diamond --------------- */
+
+/* If-Then-Else control flow diamond. It contains:
+ - Guard controling whether "then" or "else" leg is taken
+ - A hint which leg is more likely to be taken (hot path vs cold path)
+ - "then" and "else" legs with vectors of statements
+ At the moment, nested "if-then-else" statements are not supported.
+ - Phi nodes, which are used to merge temporaries from "then" and "else" legs
+
+ A leg can either end with an unconditional exit or join the main flow.
+ At the moment, unconditional exits are not supported.
+*/
+
typedef
- struct _IRStmt
- IRStmt;
+ enum {
+ IfThenElse_ThenLikely=0x1E00,
+ IfThenElse_ElseLikely
+ }
+ IRIfThenElse_Hint;
+
+typedef
+ struct _IRStmtVec
+ IRStmtVec;
typedef
struct _IRTypeEnv
IRTypeEnv;
+typedef
+ struct {
+ IRExpr* cond;
+ IRIfThenElse_Hint hint;
+ IRStmtVec* then_leg;
+ IRStmtVec* else_leg;
+ IRPhiVec* phi_nodes;
+ }
+ IRIfThenElse;
+
+extern void ppIRIfThenElse_Hint(IRIfThenElse_Hint hint);
+extern void ppIRIfThenElse(const IRIfThenElse* ite, const IRTypeEnv* tyenv,
+ UInt depth);
+extern IRIfThenElse* mkIRIfThenElse(IRExpr* cond, IRIfThenElse_Hint hint,
+ IRStmtVec* then_leg, IRStmtVec* else_leg,
+ IRPhiVec* phi_nodes);
+
+
+/* ------------------ Statements ------------------ */
+
+/* IRStmt and IRStmtVec are mutually recursive. */
+typedef
+ struct _IRStmt
+ IRStmt;
+
/* Uniquely identifies IRStmtVec in an IRSB, no matter how deeply nested. */
typedef UShort IRStmtVecID;
@@ -2801,16 +2844,14 @@
to IRStmtVec #0.
- A set which keeps track of which IRTemp's are defined in this IRStmtVec.
*/
-typedef
- struct _IRStmtVec {
- IRStmt** stmts;
- UInt stmts_size;
- UInt stmts_used;
- IRStmtVecID id;
- struct _IRStmtVec* parent;
- IRTempDefSet* defset;
- }
- IRStmtVec;
+struct _IRStmtVec {
+ IRStmt** stmts;
+ UInt stmts_size;
+ UInt stmts_used;
+ IRStmtVecID id;
+ IRStmtVec* parent;
+ IRTempDefSet* defset;
+};
/* Pretty-prints a vector of statements. If 'tyenv' is not NULL, pretty-prints
IRStmtVec's defset using nicer ppIRTypeEnvDefd(). */
@@ -2841,7 +2882,7 @@
typedef
enum {
- Ist_NoOp=0x1E00,
+ Ist_NoOp=0x1F00,
Ist_IMark, /* META */
Ist_AbiHint, /* META */
Ist_Put,
@@ -3098,26 +3139,31 @@
Int offsIP; /* Guest state offset for IP */
} Exit;
- /* If-Then-Else control flow diamond. It contains:
- - Guard controling whether "then" or "else" leg is taken
- - "then" and "else" legs with vectors of statements
- At the moment, nested "if-then-else" statements are not supported.
- - Phi nodes, which are used to merge temporaries from "then" and
- "else" legs
- - TODO-JIT: A hint which leg is more likely to be taken (hot path)
-
- A leg can either end with an unconditional exit or join the main
- flow.
+ /* If-Then-Else control flow diamond. See IRIfThenElse for details.
ppIRIfThenElse output:
- if (<cond>) then { <IRStmtVec> } else { <IRStmtVec> }
- eg. if (t3) then { <then-statements> } else { <else-statements> }
- */
+ if (<cond>) [<hint>] then {
+ <IRTempDefSet>
+ <IRStmtVec>
+ } else {
+ <IRTempDefSet>
+ <IRStmtVec>
+ }
+ <phi-nodes>
+
+ eg. if (t3) [IfThenElse_ThenLikely] then {
+ t4:I32 t7:I32
+
+ t4=0x2
+ t7=Add32(t2,t1)
+ } else {
+ t5:I32
+
+ t5=0x3
+ }
+ t6=phi(t4,t5) */
struct {
- IRExpr* cond;
- IRStmtVec* then_leg;
- IRStmtVec* else_leg;
- IRPhiVec* phi_nodes;
+ IRIfThenElse* details;
} IfThenElse;
} Ist;
};
@@ -3141,8 +3187,9 @@
extern IRStmt* IRStmt_MBE ( IRMBusEvent event );
extern IRStmt* IRStmt_Exit ( IRExpr* guard, IRJumpKind jk, IRConst* dst,
Int offsIP );
-extern IRStmt* IRStmt_IfThenElse(IRExpr* cond, IRStmtVec* then_leg,
- IRStmtVec* else_leg, IRPhiVec* phi_nodes);
+extern IRStmt* IRStmt_IfThenElse(IRExpr* cond, IRIfThenElse_Hint hint,
+ IRStmtVec* then_leg, IRStmtVec* else_leg,
+ IRPhiVec* phi_nodes);
/* Deep-copy an IRStmt.
Parent is required for "if-then-else" statements. */
@@ -3242,7 +3289,8 @@
/* Allocates an empty IfThenElse, assigns it a valid IRStmtVecID
and sets the parent for both then and else legs.
The returned IRStmt is added to the parent IRStmtVec and ready to be used. */
-extern IRStmt *addEmptyIfThenElse(IRSB* bb, IRStmtVec* parent, IRExpr* cond);
+extern IRStmt *addEmptyIfThenElse(IRSB* bb, IRStmtVec* parent, IRExpr* cond,
+ IRIfThenElse_Hint hint);
/*---------------------------------------------------------------*/
/*--- Helper functions for the IR ---*/
|