summary refs log tree commit diff stats
path: root/contrib/plugins/execlog.c (follow)
Commit message (Collapse)AuthorAgeFilesLines
* contrib/plugins/execlog: Explicitly check for qemu_plugin_read_register() ↵Peter Maydell2025-09-261-0/+1
| | | | | | | | | | | | | | | | | | | failure In insn_check_regs() we don't explicitly check whether qemu_plugin_read_register() failed, which confuses Coverity into thinking that sz can be -1 in the memcmp(). In fact the assertion that sz == reg->last->len means this can't happen, but it's clearer to both humans and Coverity if we explicitly assert that sz > 0, as we already do in init_vcpu_register(). Coverity: CID 1611901, 1611902 Fixes: af6e4e0a22c1 ("contrib/plugins: extend execlog to track register changes") Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org> Message-ID: <20250710144543.1187715-1-peter.maydell@linaro.org> Signed-off-by: Alex Bennée <alex.bennee@linaro.org> Message-ID: <20250922093711.2768983-17-alex.bennee@linaro.org>
* contrib/plugins/execlog: Add tab to the separator search of insn_disasYodel Eldar2025-07-141-6/+9
| | | | | | | | | | | | | | | | | | | | | | | | | Currently, execlog searches for a space separator between the instruction mnemonic and operands, but some disassemblers, e.g. Alpha's, use a tab separator instead; this results in a null pointer being passed as the haystack in g_strstr during a subsequent register search, i.e. undefined behavior, because of a missing null check. This patch adds tab to the separator search and a null check on the result. Also, an affected pointer is changed to const. Lastly, a break statement was added to immediately terminate the register search when a user-requested register is found in the current instruction as a trivial optimization, because searching for the remaining requested registers is unnecessary once one is found. Suggested-by: Alex Bennée <alex.bennee@linaro.org> Signed-off-by: Yodel Eldar <yodel.eldar@gmail.com> Message-ID: <20250630164124.26315-2-yodel.eldar@gmail.com> Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org> Signed-off-by: Alex Bennée <alex.bennee@linaro.org> Message-ID: <20250710104531.3099313-4-alex.bennee@linaro.org>
* contrib/plugins/execlog: Fix shadowed declaration warningPierrick Bouvier2024-08-201-2/+2
| | | | | | | | | | | | | | | | | Found on debian stable. ../contrib/plugins/execlog.c: In function ‘vcpu_tb_trans’: ../contrib/plugins/execlog.c:236:22: error: declaration of ‘n’ shadows a previous local [-Werror=shadow=local] 236 | for (int n = 0; n < all_reg_names->len; n++) { | ^ ../contrib/plugins/execlog.c:184:12: note: shadowed declaration is here 184 | size_t n = qemu_plugin_tb_n_insns(tb); | Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org> Reviewed-by: Thomas Huth <thuth@redhat.com> Message-ID: <20240814233645.944327-2-pierrick.bouvier@linaro.org> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
* plugins/execlog.c: correct dump of registers valuesFrédéric Pétrot2024-07-221-1/+1
| | | | | | | | | | | Register values are dumped as 'sz' chunks of two nibbles in the execlog plugin, sz was 1 too big. Signed-off-by: Frédéric Pétrot <frederic.petrot@univ-grenoble-alpes.fr> Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org> Message-Id: <20240620083805.73603-1-frederic.petrot@univ-grenoble-alpes.fr> Signed-off-by: Alex Bennée <alex.bennee@linaro.org> Message-Id: <20240718094523.1198645-8-alex.bennee@linaro.org>
* plugins: Copy memory in qemu_plugin_insn_dataRichard Henderson2024-05-151-2/+3
| | | | | | | | Instead of returning a host pointer, copy the data into storage provided by the caller. Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
* contrib/plugins/execlog: Fix compiler warningYao Xingtao2024-03-261-3/+21
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 1. The g_pattern_match_string() is deprecated when glib2 version >= 2.70. Use g_pattern_spec_match_string() instead to avoid this problem. 2. The type of second parameter in g_ptr_array_add() is 'gpointer' {aka 'void *'}, but the type of reg->name is 'const char*'. Cast the type of reg->name to 'gpointer' to avoid this problem. compiler warning message: contrib/plugins/execlog.c:330:17: warning: ‘g_pattern_match_string’ is deprecated: Use 'g_pattern_spec_match_string' instead [-Wdeprecated-declarations] 330 | if (g_pattern_match_string(pat, rd->name) || | ^~ In file included from /usr/include/glib-2.0/glib.h:67, from contrib/plugins/execlog.c:9: /usr/include/glib-2.0/glib/gpattern.h:57:15: note: declared here 57 | gboolean g_pattern_match_string (GPatternSpec *pspec, | ^~~~~~~~~~~~~~~~~~~~~~ contrib/plugins/execlog.c:331:21: warning: ‘g_pattern_match_string’ is deprecated: Use 'g_pattern_spec_match_string' instead [-Wdeprecated-declarations] 331 | g_pattern_match_string(pat, rd_lower)) { | ^~~~~~~~~~~~~~~~~~~~~~ /usr/include/glib-2.0/glib/gpattern.h:57:15: note: declared here 57 | gboolean g_pattern_match_string (GPatternSpec *pspec, | ^~~~~~~~~~~~~~~~~~~~~~ contrib/plugins/execlog.c:339:63: warning: passing argument 2 of ‘g_ptr_array_add’ discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers] 339 | g_ptr_array_add(all_reg_names, reg->name); | ~~~^~~~~~ In file included from /usr/include/glib-2.0/glib.h:33: /usr/include/glib-2.0/glib/garray.h:198:62: note: expected ‘gpointer’ {aka ‘void *’} but argument is of type ‘const char *’ 198 | gpointer data); | ~~~~~~~~~~~~~~~~~~^~~~ Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2210 Signed-off-by: Yao Xingtao <yaoxt.fnst@fujitsu.com> Message-ID: <20240326015257.21516-1-yaoxt.fnst@fujitsu.com> Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
* contrib/plugins: extend execlog to track register changesAlex Bennée2024-02-281-51/+265
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | With the new plugin register API we can now track changes to register values. Currently the implementation is fairly dumb which will slow down if a large number of register values are being tracked. This could be improved by only instrumenting instructions which mention registers we are interested in tracking. Example usage: ./qemu-aarch64 -D plugin.log -d plugin \ -cpu max,sve256=on \ -plugin contrib/plugins/libexeclog.so,reg=sp,reg=z\* \ ./tests/tcg/aarch64-linux-user/sha512-sve will display in the execlog any changes to the stack pointer (sp) and the SVE Z registers. As testing registers every instruction will be quite a heavy operation there is an additional flag which attempts to optimise the register tracking by only instrumenting instructions which are likely to change its value. This relies on the QEMU disassembler showing up the register names in disassembly so is an explicit opt-in. Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org> Cc: Akihiko Odaki <akihiko.odaki@daynix.com> Based-On: <20231025093128.33116-19-akihiko.odaki@daynix.com> Signed-off-by: Alex Bennée <alex.bennee@linaro.org> Message-Id: <20240227144335.1196131-27-alex.bennee@linaro.org>
* contrib/plugins: fix imatchAlex Bennée2024-02-281-1/+1
| | | | | | | | | | We can't directly save the ephemeral imatch from argv as that memory will get recycled. Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Signed-off-by: Alex Bennée <alex.bennee@linaro.org> Message-Id: <20240227144335.1196131-26-alex.bennee@linaro.org>
* contrib/plugins: Use GRWLock in execlogAkihiko Odaki2023-10-111-6/+10
| | | | | | | | | | | | | | | | | | | | execlog had the following comment: > As we could have multiple threads trying to do this we need to > serialise the expansion under a lock. Threads accessing already > created entries can continue without issue even if the ptr array > gets reallocated during resize. However, when the ptr array gets reallocated, the other threads may have a stale reference to the old buffer. This results in use-after-free. Use GRWLock to properly fix this issue. Fixes: 3d7caf145e ("contrib/plugins: add execlog to log instruction execution and memory access") Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com> Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Message-Id: <20230912224107.29669-5-akihiko.odaki@daynix.com> Signed-off-by: Alex Bennée <alex.bennee@linaro.org> Message-Id: <20231009164104.369749-12-alex.bennee@linaro.org>
* plugins: fix memory leak while parsing optionsAlex Bennée2023-07-031-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | It was hard to track down this leak as it was an internal allocation by glib and the backtraces did not give much away. The autofree was freeing the allocation with g_free() but not taking care of the individual strings. They should have been freed with g_strfreev() instead. Searching the glib source code for the correct string free function led to: G_DEFINE_AUTO_CLEANUP_FREE_FUNC(GStrv, g_strfreev, NULL) and indeed if you read to the bottom of the documentation page you will find: typedef gchar** GStrv; A typedef alias for gchar**. This is mostly useful when used together with g_auto(). So fix up all the g_autofree g_strsplit case that smugly thought they had de-allocation covered. Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Signed-off-by: Alex Bennée <alex.bennee@linaro.org> Message-Id: <20230630180423.558337-21-alex.bennee@linaro.org>
* contrib/plugins: protect execlog's last_exec expansionAlex Bennée2022-10-311-8/+30
| | | | | | | | | | | | | | | We originally naively treated expansion as safe because we expected each new CPU/thread to appear in order. However the -M raspi2 model triggered a case where a new high cpu_index thread started executing just before a smaller one. Clean this up by converting the GArray into the simpler GPtrArray and then holding a lock for the expansion. Signed-off-by: Alex Bennée <alex.bennee@linaro.org> Cc: Alexandre Iooss <erdnaxe@crans.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-Id: <20221027183637.2772968-29-alex.bennee@linaro.org>
* contrib/plugins: reset skip when matching in execlogAlex Bennée2022-10-061-1/+4
| | | | | | | | | | | | | The purpose of the matches was to only track the execution of instructions we care about. Without resetting skip to the value at the start of the block we end up dumping all instructions after the match with the consequent load on the instrumentation. Signed-off-by: Alex Bennée <alex.bennee@linaro.org> Cc: Alexandre Iooss <erdnaxe@crans.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Message-Id: <20220929114231.583801-40-alex.bennee@linaro.org>
* plugins: extend execlog to filter matchesAlex Bennée2022-10-061-14/+82
| | | | | | | | | | | | | | | | | | | | | Sometimes the whole execlog is just two much so add the ability to filter by instruction opcode or address. [AJB: this shows for example qemu-system-aarch64 -display none -serial mon:stdio \ -M virt -cpu max \ -semihosting-config enable=on \ -kernel ./tests/tcg/aarch64-softmmu/memory-sve \ -plugin ./contrib/plugins/libexeclog.so,ifilter=st1w,afilter=0x40001808 -d plugin -D plugin.out the st1w SVE instruction is not instrumenting its stores.] Signed-off-by: Alex Bennée <alex.bennee@linaro.org> Reviewed-by: Alexandre Iooss <erdnaxe@crans.org> Cc: Robert Henry <robhenry@microsoft.com> Cc: Aaron Lindsay <aaron@os.amperecomputing.com> Message-Id: <20220929114231.583801-36-alex.bennee@linaro.org>
* plugins/execlog: removed unintended "s" at the end of log lines.Mahmoud Mandour2021-09-021-1/+1
| | | | | | | | Signed-off-by: Mahmoud Mandour <ma.mandourr@gmail.com> Signed-off-by: Alex Bennée <alex.bennee@linaro.org> Message-Id: <20210803151428.125323-1-ma.mandourr@gmail.com> Message-Id: <20210806141015.2487502-2-alex.bennee@linaro.org> Cc: qemu-stable@nongnu.org
* contrib/plugins: add execlog to log instruction execution and memory accessAlexandre Iooss2021-07-141-0/+153
Log instruction execution and memory access to a file. This plugin can be used for reverse engineering or for side-channel analysis using QEMU. Signed-off-by: Alexandre Iooss <erdnaxe@crans.org> Signed-off-by: Alex Bennée <alex.bennee@linaro.org> Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Message-Id: <20210702081307.1653644-2-erdnaxe@crans.org> Message-Id: <20210709143005.1554-35-alex.bennee@linaro.org>