Skip to content

fix uninitialized reg arr for VlWhole staticInst type#697

Merged
jensen-yan merged 1 commit into
OpenXiangShan:xs-devfrom
Rrraaaeee:fix-vlwhole
Jan 14, 2026
Merged

fix uninitialized reg arr for VlWhole staticInst type#697
jensen-yan merged 1 commit into
OpenXiangShan:xs-devfrom
Rrraaaeee:fix-vlwhole

Conversation

@Rrraaaeee

@Rrraaaeee Rrraaaeee commented Jan 9, 2026

Copy link
Copy Markdown
Contributor

Problem

When running gcpt with --debug-flags=Exec, a segmentation fault is encountered when dumping disassembly of vl1re64.v instruction.

When compiling gem5. with --with-asan, the following error is shown.

==1134360==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x50e0000304df at pc 0x561e9b58bf95 bp 0x7ffe4ce60cd0 sp 0x7ffe4ce60cc0
READ of size 12 at 0x50e0000304df thread T0
#0 0x561e9b58bf94 in gem5::RiscvISA::VlWholeMacroInst::generateDisassembly[abi:cxx11](unsigned long, gem5::loader::SymbolTable const*) const build/RISCV/arch/riscv/insts/vector.cc:247
#1 0x561e9876d564 in gem5::StaticInst::disassemble[abi:cxx11](unsigned long, gem5::loader::SymbolTable const*) const build/RISCV/cpu/static_inst.cc:64
#2 0x561e98727840 in gem5::Trace::ExeTracerRecord::traceInst(gem5::RefCountingPtrgem5::StaticInst const&, bool) build/RISCV/cpu/exetrace.cc:105
#3 0x561e9872d9a6 in gem5::Trace::ExeTracerRecord::dump() build/RISCV/cpu/exetrace.cc:174
#4 0x561e9990cd1d in gem5::o3::Commit::commitHead(gem5::RefCountingPtrgem5::o3::DynInst const&, unsigned int) build/RISCV/cpu/o3/commit.cc:1714
#5 0x561e9991d629 in gem5::o3::Commit::commitInsts() build/RISCV/cpu/o3/commit.cc:1196
#6 0x561e99926ddf in gem5::o3::Commit::commit() build/RISCV/cpu/o3/commit.cc:1069
#7 0x561e999290cf in gem5::o3::Commit::tick() build/RISCV/cpu/o3/commit.cc:801
#8 0x561e9998230d in gem5::o3::CPU::tick() build/RISCV/cpu/o3/cpu.cc:581
#9 0x561e95e76f7f in std::function<void ()>::operator()() const /usr/include/c++/11/bits/std_function.h:590

Root cause

The error happens in the following snippet, where accessing destRegIdx and srcRegIdx throws illegal memory access errors.

  std::string VlWholeMacroInst::generateDisassembly(Addr pc,
          const loader::SymbolTable *symtab) const
  {
      std::stringstream ss;
      // destRegIdx(0) and srcRegIdx(0) are uninitialized
      ss << mnemonic << ' ' << registerName(destRegIdx(0)) << ", " <<
          '(' << registerName(srcRegIdx(0)) << ')';
      return ss.str();
  }

The illegal memory access happens because the srcReg and dstReg fields are uninitialized for this StaticInst type.
From the generated StaticInst constructor for VlWhole instruction type in build/RISCV/arch/riscv/generated/decoder-ns.cc.inc, there is no reg arr initialization.

  Vl1re8_v::Vl1re8_v(ExtMachInst _machInst)
      : VlWholeMacroInst("vl1re8_v", _machInst, VectorWholeRegisterLoadOp)
  {
      // missing reg arr initializations
      size_t NFIELDS = machInst.nf + 1;
      eew = 8;
      StaticInstPtr microop;
      VectorMicroInfo vmi;
      for (int i = 0; i < NFIELDS; ++i) {
          vmi.rs = 0;
          vmi.re = VLEN / eew;
          vmi.microVd = VD + i;
          microop = new Vl1re8_vMicro(_machInst, i, vmi);
          microop->setDelayedCommit();
          microop->setFlag(IsLoad);
          this->microops.push_back(microop);
      }

      this->microops.front()->setFirstMicroop();
      this->microops.back()->setLastMicroop();
  }

After Fix

After the fix, the register fields are correctly initialized and no illegal memory access fault is observed.

  Vl1re8_v::Vl1re8_v(ExtMachInst _machInst)
      : VlWholeMacroInst("vl1re8_v", _machInst, VectorWholeRegisterLoadOp)
  {

      setRegIdxArrays(
          reinterpret_cast<RegIdArrayPtr>(
              &std::remove_pointer_t<decltype(this)>::srcRegIdxArr),
          reinterpret_cast<RegIdArrayPtr>(
              &std::remove_pointer_t<decltype(this)>::destRegIdxArr));
              ;

      size_t NFIELDS = machInst.nf + 1;
      eew = 8;
      StaticInstPtr microop;
      VectorMicroInfo vmi;
      for (int i = 0; i < NFIELDS; ++i) {
          vmi.rs = 0;
          vmi.re = VLEN / eew;
          vmi.microVd = VD + i;
          microop = new Vl1re8_vMicro(_machInst, i, vmi);
          microop->setDelayedCommit();
          microop->setFlag(IsLoad);
          this->microops.push_back(microop);
      }

      this->microops.front()->setFirstMicroop();
      this->microops.back()->setLastMicroop();
  }

Summary by CodeRabbit

  • Bug Fixes
    • Fixed vector instruction initialization order to ensure proper register configuration during construction.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai

coderabbitai Bot commented Jan 9, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

A register index array initialization call has been added to the VlWholeConstructor constructor body in the RISC-V vector ISA module, executed before NFIELDS initialization, to ensure proper runtime setup of the constructor.

Changes

Cohort / File(s) Summary
Vector ISA Constructor Initialization
src/arch/riscv/isa/vector/base/vector_mem.temp.isa
Added reg_idx_arr initialization call in VlWholeConstructor constructor before NFIELDS setup

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~3 minutes

Poem

🐰 A whisker-twitch and a hop so small,
The reg_idx_arr now answers the call,
Before NFIELDS takes its place,
Initialization runs at pace! ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title accurately and specifically describes the main change: fixing uninitialized register arrays for VlWhole StaticInst type, directly addressing the root cause of the heap-buffer-overflow bug described in the PR objectives.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In @src/arch/riscv/isa/vector/base/vector_mem.temp.isa:
- Around line 426-427: VsWholeConstructor is missing the same
register-index-array initialization added to VlWholeConstructor, leading to
potential heap-buffer-overflow when generateDisassembly reads srcRegIdxArr[8];
add the same initialization macro/token `%(set_reg_idx_arr)s;` (or equivalent
code that sets/zeros srcRegIdxArr and dstRegIdxArr) at the start of the
VsWholeConstructor constructor body so its srcRegIdxArr[8] members are
initialized before any micro-op creation or generateDisassembly usage.
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e46fe3b and 51174fb.

📒 Files selected for processing (1)
  • src/arch/riscv/isa/vector/base/vector_mem.temp.isa

Comment on lines +426 to +427
%(set_reg_idx_arr)s;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# First, verify the file exists and check the structure around lines 426-427
echo "=== Checking file existence and basic structure ==="
if [ -f "src/arch/riscv/isa/vector/base/vector_mem.temp.isa" ]; then
    echo "File found."
    echo ""
    echo "=== Content around lines 426-427 ==="
    sed -n '410,445p' "src/arch/riscv/isa/vector/base/vector_mem.temp.isa" | cat -n
else
    echo "File not found at specified path"
    find . -name "vector_mem.temp.isa" 2>/dev/null
fi

Repository: OpenXiangShan/GEM5

Length of output: 1205


🏁 Script executed:

#!/bin/bash
# Check usage of %(set_reg_idx_arr)s; throughout the file
echo "=== Checking %(set_reg_idx_arr)s; usage ==="
rg -n "set_reg_idx_arr" "src/arch/riscv/isa/vector/base/vector_mem.temp.isa"

echo ""
echo "=== Checking for constructor definitions ==="
rg -n "def template.*Constructor" "src/arch/riscv/isa/vector/base/vector_mem.temp.isa" | head -30

Repository: OpenXiangShan/GEM5

Length of output: 965


🏁 Script executed:

#!/bin/bash
# Check register array declarations
echo "=== Checking register array declarations ==="
rg -n "reg_idx_arr_decl\|reg_idx_arr" "src/arch/riscv/isa/vector/base/vector_mem.temp.isa" | head -20

echo ""
echo "=== Check for generateDisassembly in macro instructions ==="
rg -n "generateDisassembly" "src/arch/riscv/isa/vector/base/vector_mem.temp.isa"

Repository: OpenXiangShan/GEM5

Length of output: 829


🏁 Script executed:

#!/bin/bash
# Check VsWholeConstructor (similar structure to VlWholeConstructor)
echo "=== VsWholeConstructor (line 1186) context ==="
sed -n '1186,1235p' "src/arch/riscv/isa/vector/base/vector_mem.temp.isa" | cat -n

echo ""
echo "=== Check if VsWholeConstructor has set_reg_idx_arr ==="
sed -n '1186,1235p' "src/arch/riscv/isa/vector/base/vector_mem.temp.isa" | grep -n "set_reg_idx_arr"

Repository: OpenXiangShan/GEM5

Length of output: 2137


🏁 Script executed:

#!/bin/bash
# Check around line 117 and 351 to confirm they're micro templates
echo "=== Around line 117 (after VleConstructor at 45) ==="
sed -n '100,130p' "src/arch/riscv/isa/vector/base/vector_mem.temp.isa" | cat -n

echo ""
echo "=== Around line 351 (after VleffConstructor at 310) ==="
sed -n '330,365p' "src/arch/riscv/isa/vector/base/vector_mem.temp.isa" | cat -n

Repository: OpenXiangShan/GEM5

Length of output: 2615


🏁 Script executed:

#!/bin/bash
# Check VleConstructor and its structure
echo "=== VleConstructor (line 45) context ==="
sed -n '45,100p' "src/arch/riscv/isa/vector/base/vector_mem.temp.isa" | cat -n

echo ""
echo "=== VleffConstructor (line 310) context ==="
sed -n '310,360p' "src/arch/riscv/isa/vector/base/vector_mem.temp.isa" | cat -n

Repository: OpenXiangShan/GEM5

Length of output: 4567


🏁 Script executed:

#!/bin/bash
# Check the relationship between VsWholeConstructor and VsWholeMicroDeclare
echo "=== Checking VsWholeConstructor full structure ==="
sed -n '1186,1210p' "src/arch/riscv/isa/vector/base/vector_mem.temp.isa" | cat -n

echo ""
echo "=== Checking VsWholeMicroDeclare definition starts ==="
grep -n "def template VsWholeMicroDeclare" "src/arch/riscv/isa/vector/base/vector_mem.temp.isa"

echo ""
echo "=== Comparing VlWholeConstructor and VlWholeMicroDeclare structure ==="
echo "=== VlWholeConstructor at line 421 ==="
sed -n '421,450p' "src/arch/riscv/isa/vector/base/vector_mem.temp.isa" | cat -n

Repository: OpenXiangShan/GEM5

Length of output: 2135


🏁 Script executed:

#!/bin/bash
# Check if there are any other "Whole" constructors that might have the same issue
echo "=== All 'Whole' related templates ==="
rg -n "def template.*Whole" "src/arch/riscv/isa/vector/base/vector_mem.temp.isa"

echo ""
echo "=== Check which ones have set_reg_idx_arr in constructors (not micro) ==="
echo "Looking at each Whole constructor:"
echo ""
echo "VlWholeConstructor (421):"
sed -n '421,455p' "src/arch/riscv/isa/vector/base/vector_mem.temp.isa" | grep "set_reg_idx_arr"

echo ""
echo "VsWholeConstructor (1186):"
sed -n '1186,1215p' "src/arch/riscv/isa/vector/base/vector_mem.temp.isa" | grep "set_reg_idx_arr"

Repository: OpenXiangShan/GEM5

Length of output: 489


🏁 Script executed:

#!/bin/bash
# Check VsWholeMicroDeclare for register arrays
echo "=== VsWholeMicroDeclare (line 1210) ==="
sed -n '1210,1240p' "src/arch/riscv/isa/vector/base/vector_mem.temp.isa" | cat -n

echo ""
echo "=== Compare: VlWholeMicroDeclare (line 448) ==="
sed -n '448,475p' "src/arch/riscv/isa/vector/base/vector_mem.temp.isa" | cat -n

Repository: OpenXiangShan/GEM5

Length of output: 2566


🏁 Script executed:

#!/bin/bash
# Verify if both Whole micro classes have register arrays and generateDisassembly
echo "=== Check register arrays in both Whole micro classes ==="
rg -A 10 "def template VlWholeMicroDeclare" "src/arch/riscv/isa/vector/base/vector_mem.temp.isa" | head -20

echo ""
echo "=== VsWhole micro class ==="
rg -A 10 "def template VsWholeMicroDeclare" "src/arch/riscv/isa/vector/base/vector_mem.temp.isa" | head -20

Repository: OpenXiangShan/GEM5

Length of output: 798


🏁 Script executed:

#!/bin/bash
# Final verification: confirm both Whole constructors have identical structures
echo "=== VlWholeConstructor structure (has fix) ==="
sed -n '421,442p' "src/arch/riscv/isa/vector/base/vector_mem.temp.isa" | grep -E "(def template|%(set_reg_idx_arr|size_t NFIELDS|for|IsLoad)"

echo ""
echo "=== VsWholeConstructor structure (missing fix) ==="
sed -n '1186,1207p' "src/arch/riscv/isa/vector/base/vector_mem.temp.isa" | grep -E "(def template|%(set_reg_idx_arr|size_t NFIELDS|for|IsStore)"

Repository: OpenXiangShan/GEM5

Length of output: 225


🏁 Script executed:

#!/bin/bash
# Final verification: confirm both Whole constructors have identical structures
echo "=== VlWholeConstructor structure (has fix) ==="
sed -n '421,442p' "src/arch/riscv/isa/vector/base/vector_mem.temp.isa"

echo ""
echo "=== VsWholeConstructor structure (missing fix) ==="
sed -n '1186,1207p' "src/arch/riscv/isa/vector/base/vector_mem.temp.isa"

Repository: OpenXiangShan/GEM5

Length of output: 1415


Good fix, but VsWholeConstructor appears to have the same vulnerability.

The addition of %(set_reg_idx_arr)s; at line 426 correctly initializes register index arrays in VlWholeConstructor before they're accessed by generateDisassembly, preventing the heap-buffer-overflow. However, VsWholeConstructor (line 1186) has an identical structure with the same register array members (srcRegIdxArr[8]) and identical micro operation creation pattern, yet it lacks this initialization. Both macro constructors should have this fix for symmetry and correctness:

  • VlWholeConstructor (line 421): ✓ Has %(set_reg_idx_arr)s;
  • VsWholeConstructor (line 1186): ✗ Missing %(set_reg_idx_arr)s;

Verify and apply the same initialization to VsWholeConstructor.

🤖 Prompt for AI Agents
In @src/arch/riscv/isa/vector/base/vector_mem.temp.isa around lines 426 - 427,
VsWholeConstructor is missing the same register-index-array initialization added
to VlWholeConstructor, leading to potential heap-buffer-overflow when
generateDisassembly reads srcRegIdxArr[8]; add the same initialization
macro/token `%(set_reg_idx_arr)s;` (or equivalent code that sets/zeros
srcRegIdxArr and dstRegIdxArr) at the start of the VsWholeConstructor
constructor body so its srcRegIdxArr[8] members are initialized before any
micro-op creation or generateDisassembly usage.

@tastynoob

Copy link
Copy Markdown
Collaborator

Logically, printing the disassembly of macrop should be meaningless, because the macrop do not real execute and it just a empty shell, you should fix the Exec debug flags printf, just print the microp not macrop

@tastynoob

Copy link
Copy Markdown
Collaborator

Furthermore, repairing the disassembly of each macrop would be a very large undertaking.

@tastynoob tastynoob added do not merge wontfix This will not be worked on and removed do not merge labels Jan 9, 2026
@huxuan0307

Copy link
Copy Markdown
Contributor

LGTM!

I have checked the upsteam gem5 at the same template. I notice that every template XXXConstructor has initialized the srcRegIdx/dstRegIdx array to make sure that there will be no null pointers when gem5 make disassembly.

Could you please fix other similar bugs that does not initialize the srcRegIdx/dstRegIdx array?

@tastynoob

Copy link
Copy Markdown
Collaborator

Better way to repair it Completely:

  1. Fix all vector macoop‘s disasm
  2. Do not print macrop but microop

@huxuan0307

Copy link
Copy Markdown
Contributor

Need review by @seanwang2046

@jensen-yan

Copy link
Copy Markdown
Collaborator

Hi! The CI failure is not caused by your code - it's a permission issue with fork PRs trying to post comments.

I've just merged a fix to xs-dev. Please rebase your branch to pick up the updated workflow:

git fetch origin
git rebase origin/xs-dev
git push -f

Then re-run the CI and it should pass. Thanks!

@jensen-yan

Copy link
Copy Markdown
Collaborator

I'll force you to integrate it into the main storyline. Thank you so much for your contribution.

@jensen-yan jensen-yan merged commit 4897796 into OpenXiangShan:xs-dev Jan 14, 2026
5 of 9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

wontfix This will not be worked on

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants