mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-01-30 12:44:10 +08:00
c47886c7a1
regcache::transfer_regset iterates over an array of regcache_map_entry, transferring the registers (between regcache and buffer) described by those entries. It stops either when it reaches the end of the regcache_map_entry array (marked by a null entry) or (it seems like the intent is) when it reaches the end of the buffer (in which case not all described registers are transferred). I said "seems like the intent is", because there appears to be a small bug. transfer_regset is made of two loops: foreach regcache_map_entry: foreach register described by the regcache_map_entry: if the register doesn't fit in the remainder of the buffer: break transfer register When stopping because we have reached the end of the buffer, the break only breaks out of the inner loop. This problem causes some failures when I run tests such as gdb.arch/aarch64-sme-core-3.exp (on AArch64 Linux, in qemu). This is partly due to aarch64_linux_iterate_over_regset_sections failing to add a null terminator in its regcache_map_entry array, but I think there is still a problem in transfer_regset. The sequence to the crash is: - The `regcache_map_entry za_regmap` object built in aarch64_linux_iterate_over_regset_sections does not have a null terminator. - When the target does not have a ZA register, aarch64_linux_collect_za_regset calls `regcache->collect_regset` with a size of 0 (it's actually pointless, but still it should work). - transfer_regset gets called with a buffer size of 0. - transfer_regset detects that the register to transfer wouldn't fit in 0 bytes, so it breaks out of the inner loop. - The outer loop tries to go read the next regcache_map_entry, but there isn't one, and we start reading garbage. Obviously, this would get fixed by making aarch64_linux_iterate_over_regset_sections use a null terminator (which is what the following patch does). But I think that when detecting that there is not enough buffer left for the current register, transfer_regset should return, not only break out of the inner loop. This is a kind of contrived scenario, but imagine we have these two regcache_map_entry objects: - 2 registers of 8 bytes - 2 registers of 4 bytes For some reason, the caller passes a buffer of 12 bytes. transfer_regset will detect that the second 8 byte register does not fit, and break out of the inner loop. However, it will then go try the next regcache_map_entry. It will see that it can fit one 4 byte register in the remaining buffer space, and transfer it from/to there. This is very likely not an expected behavior, we wouldn't expect to read/write this sequence of registers from/to the buffer. In this example, whether passing a 12 bytes buffer makes sense or whether it is a size computation bug in the caller, we don't know, but I think that exiting as soon as a register doesn't fit is the sane thing to do. Change-Id: Ia349627d2e5d281822ade92a8e7a4dea4f839e07 Reviewed-By: John Baldwin <jhb@FreeBSD.org> Reviewed-By: Luis Machado <luis.machado@arm.com> |
||
---|---|---|
bfd | ||
binutils | ||
config | ||
contrib | ||
cpu | ||
elfcpp | ||
etc | ||
gas | ||
gdb | ||
gdbserver | ||
gdbsupport | ||
gnulib | ||
gold | ||
gprof | ||
gprofng | ||
include | ||
ld | ||
libbacktrace | ||
libctf | ||
libdecnumber | ||
libiberty | ||
libsframe | ||
opcodes | ||
readline | ||
sim | ||
texinfo | ||
zlib | ||
.cvsignore | ||
.editorconfig | ||
.gitattributes | ||
.gitignore | ||
ar-lib | ||
ChangeLog | ||
compile | ||
config-ml.in | ||
config.guess | ||
config.rpath | ||
config.sub | ||
configure | ||
configure.ac | ||
COPYING | ||
COPYING3 | ||
COPYING3.LIB | ||
COPYING.LIB | ||
COPYING.LIBGLOSS | ||
COPYING.NEWLIB | ||
depcomp | ||
djunpack.bat | ||
install-sh | ||
libtool.m4 | ||
lt~obsolete.m4 | ||
ltgcc.m4 | ||
ltmain.sh | ||
ltoptions.m4 | ||
ltsugar.m4 | ||
ltversion.m4 | ||
MAINTAINERS | ||
Makefile.def | ||
Makefile.in | ||
Makefile.tpl | ||
makefile.vms | ||
missing | ||
mkdep | ||
mkinstalldirs | ||
move-if-change | ||
multilib.am | ||
README | ||
README-maintainer-mode | ||
SECURITY.txt | ||
setup.com | ||
src-release.sh | ||
symlink-tree | ||
test-driver | ||
ylwrap |
README for GNU development tools This directory contains various GNU compilers, assemblers, linkers, debuggers, etc., plus their support routines, definitions, and documentation. If you are receiving this as part of a GDB release, see the file gdb/README. If with a binutils release, see binutils/README; if with a libg++ release, see libg++/README, etc. That'll give you info about this package -- supported targets, how to use it, how to report bugs, etc. It is now possible to automatically configure and build a variety of tools with one command. To build all of the tools contained herein, run the ``configure'' script here, e.g.: ./configure make To install them (by default in /usr/local/bin, /usr/local/lib, etc), then do: make install (If the configure script can't determine your type of computer, give it the name as an argument, for instance ``./configure sun4''. You can use the script ``config.sub'' to test whether a name is recognized; if it is, config.sub translates it to a triplet specifying CPU, vendor, and OS.) If you have more than one compiler on your system, it is often best to explicitly set CC in the environment before running configure, and to also set CC when running make. For example (assuming sh/bash/ksh): CC=gcc ./configure make A similar example using csh: setenv CC gcc ./configure make Much of the code and documentation enclosed is copyright by the Free Software Foundation, Inc. See the file COPYING or COPYING.LIB in the various directories, for a description of the GNU General Public License terms under which you can copy the files. REPORTING BUGS: Again, see gdb/README, binutils/README, etc., for info on where and how to report problems.