Skip to content

Commit b5511ce

Browse files
author
Colin Robertson
committed
Acrolinx 87
1 parent 4540804 commit b5511ce

File tree

1 file changed

+2
-2
lines changed

1 file changed

+2
-2
lines changed

docs/build/arm64-exception-handling.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ The fields are as follows:
340340
- 10 = packed unwind data used for code without any prolog and epilog. Useful for describing separated function segments
341341
- 11 = reserved.
342342
- **Function Length** is an 11-bit field providing the length of the entire function in bytes, divided by 4. If the function is larger than 8k, a full .xdata record must be used instead.
343-
- **Frame Size** is a 9-bit field indicating the number of bytes of stack that is allocated for this function, divided by 16. Functions that allocate greater than (8k-16) bytes of stack must use a full .xdata record. This includes local variable area, outgoing parameter area, callee-saved Int and FP area, and home parameter area, but excludes the dynamic allocation area.
343+
- **Frame Size** is a 9-bit field indicating the number of bytes of stack that is allocated for this function, divided by 16. Functions that allocate greater than (8k-16) bytes of stack must use a full .xdata record. It includes the local variable area, outgoing parameter area, callee-saved Int and FP area, and home parameter area, but excludes the dynamic allocation area.
344344
- **CR** is a 2-bit flag indicating whether the function includes extra instructions to set up a frame chain and return link:
345345
- 00 = unchained function, \<x29,lr> pair is not saved in stack.
346346
- 01 = unchained function, \<lr> is saved in stack
@@ -410,7 +410,7 @@ So, for both the prolog and epilog, we're left with a common set of unwind codes
410410

411411
`set_fp`, `save_regp 0,240`, `save_fregp,0,224`, `save_fplr_x_256`, `end`
412412

413-
The epilog case is straightforward, since it's in normal order. Starting at offset 0 within the epilog (which starts at offset 0x100 in the function), we'd expect to execute the full unwind sequence, as no cleanup has yet been done. If we find ourselves one instruction in (at offset 2 in the epilog), we can successfully unwind by skipping the first unwind code. We can generalizing this situation, and assuma a 1:1 mapping between opcodes and unwind codes. Then to start unwinding from instruction n in the epilog, we should skip the first n unwind codes, and begin executing from there.
413+
The epilog case is straightforward, since it's in normal order. Starting at offset 0 within the epilog (which starts at offset 0x100 in the function), we'd expect to execute the full unwind sequence, as no cleanup has yet been done. If we find ourselves one instruction in (at offset 2 in the epilog), we can successfully unwind by skipping the first unwind code. We can generalize this situation, and assume a 1:1 mapping between opcodes and unwind codes. Then, to start unwinding from instruction *n* in the epilog, we should skip the first *n* unwind codes, and begin executing from there.
414414

415415
It turns out that a similar logic works for the prolog, except in reverse. If we start unwinding from offset 0 in the prolog, we want to execute nothing. If we unwind from offset 2, which is one instruction in, then we want to start executing the unwind sequence one unwind code from the end. (Remember, the codes are stored in reverse order.) And here too, we can generalize: if we start unwinding from instruction n in the prolog, we should start executing n unwind codes from the end of the list of codes.
416416

0 commit comments

Comments
 (0)