cpu: In SimpleIndirectPredictor, avoid an accidental nullptr deref.

The default value of IPredEntry::tag is 0, and if we just blindly
compare the tag we're looking for against this value, we might run into
cases where we match against an uninitialized IPredEntry. In that case,
IPredEntry::target has not been initialized, and if we try to use it in
lookup(...) we'll dereference nullptr and segfault.

To avoid that, we can just add one additional check that makes sure that
not only does the tag of the IPredEntry match, but also that the value
of target is not null, and so the IPredEntry *actually* has tag 0 and
isn't just uninitialized.

Change-Id: I892d0df7c00a0a4cd3ca215fe3a7586ddbca9395
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/53403
Maintainer: Gabe Black <gabe.black@gmail.com>
Reviewed-by: Jason Lowe-Power <power.jg@gmail.com>
Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
Gabe Black
2021-11-30 02:28:21 -08:00
parent 29a6b75e33
commit aa949dba0f

View File

@@ -104,7 +104,9 @@ SimpleIndirectPredictor::lookup(Addr br_addr, PCStateBase& target,
DPRINTF(Indirect, "Looking up %x (set:%d)\n", br_addr, set_index);
const auto &iset = targetCache[set_index];
for (auto way = iset.begin(); way != iset.end(); ++way) {
if (way->tag == tag) {
// tag may be 0 and match the default in way->tag, so we also have to
// check that way->target has been initialized.
if (way->tag == tag && way->target) {
DPRINTF(Indirect, "Hit %x (target:%s)\n", br_addr, *way->target);
set(target, *way->target);
return true;