| .. | .. |
|---|
| 300 | 300 | return URC_OK; |
|---|
| 301 | 301 | } |
|---|
| 302 | 302 | |
|---|
| 303 | +static unsigned long unwind_decode_uleb128(struct unwind_ctrl_block *ctrl) |
|---|
| 304 | +{ |
|---|
| 305 | + unsigned long bytes = 0; |
|---|
| 306 | + unsigned long insn; |
|---|
| 307 | + unsigned long result = 0; |
|---|
| 308 | + |
|---|
| 309 | + /* |
|---|
| 310 | + * unwind_get_byte() will advance `ctrl` one instruction at a time, so |
|---|
| 311 | + * loop until we get an instruction byte where bit 7 is not set. |
|---|
| 312 | + * |
|---|
| 313 | + * Note: This decodes a maximum of 4 bytes to output 28 bits data where |
|---|
| 314 | + * max is 0xfffffff: that will cover a vsp increment of 1073742336, hence |
|---|
| 315 | + * it is sufficient for unwinding the stack. |
|---|
| 316 | + */ |
|---|
| 317 | + do { |
|---|
| 318 | + insn = unwind_get_byte(ctrl); |
|---|
| 319 | + result |= (insn & 0x7f) << (bytes * 7); |
|---|
| 320 | + bytes++; |
|---|
| 321 | + } while (!!(insn & 0x80) && (bytes != sizeof(result))); |
|---|
| 322 | + |
|---|
| 323 | + return result; |
|---|
| 324 | +} |
|---|
| 325 | + |
|---|
| 303 | 326 | /* |
|---|
| 304 | 327 | * Execute the current unwind instruction. |
|---|
| 305 | 328 | */ |
|---|
| .. | .. |
|---|
| 353 | 376 | if (ret) |
|---|
| 354 | 377 | goto error; |
|---|
| 355 | 378 | } else if (insn == 0xb2) { |
|---|
| 356 | | - unsigned long uleb128 = unwind_get_byte(ctrl); |
|---|
| 379 | + unsigned long uleb128 = unwind_decode_uleb128(ctrl); |
|---|
| 357 | 380 | |
|---|
| 358 | 381 | ctrl->vrs[SP] += 0x204 + (uleb128 << 2); |
|---|
| 359 | 382 | } else { |
|---|