Skip to content

libunwind::Registers_mips_o32::jumpto returns to the wrong address #152922

@Jade-Marker

Description

@Jade-Marker

In libunwind::Registers_mips_o32::jumpto, there is the following code

  lw    $30, (4 * 30)($4)
  // load new pc into ra
  lw    $31, (4 * 32)($4)
  // jump to ra, load a0 in the delay slot
  jr    $31

However, this does not work as intended! On mips, offset loads have a delay. So instead of returning to the new value of $ra, the program returns to the old value. This means that it instead returns to the end of UnwindCursor::jumpto, where both $sp and $ra are immediately overwritten.

There is a simple fix to this though. As the delay is only 1 cycle, swapping the order of the previous instruction ensures that $ra has the correct value on jump

  // load new pc into ra
  lw    $31, (4 * 32)($4)
  lw    $30, (4 * 30)($4)
  // jump to ra, load a0 in the delay slot
  jr    $31

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Status

    Done

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions