Skip to content

Commit 26b6139

Browse files
authored
Merge pull request MicrosoftDocs#1092 from corob-msft/cr-arm-abi-2
Remove section per review, update capitalization
2 parents fd5f522 + 265d9de commit 26b6139

1 file changed

Lines changed: 10 additions & 34 deletions

File tree

docs/build/arm64-exception-handling.md

Lines changed: 10 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,13 @@ These are the assumptions made in the exception handling description:
5151

5252
6. The stack frame layout is organized as described in next section.
5353

54-
## ARM64 Stack Frame Layout
54+
## ARM64 stack frame layout
5555

5656
![stack frame layout](../build/media/arm64-exception-handling-stack-frame.png "stack frame layout")
5757

5858
For frame chained functions, the fp and lr pair can be saved at any position in the local variable area depending on optimization considerations. The goal is to maximize the number of locals that can be reached by one single instruction based on frame pointer (r29) or stack pointer (sp). However for `alloca` functions, it must be chained and r29 must point to the bottom of stack. To allow for better register-pair-addressing-mode coverage, nonvolatile register aave areas are positioned at the top of the Local area stack. Here are examples that illustrate several of the most efficient prolog sequences. For the sake of clarity and better cache locality, the order of storing callee-saved registers in all canonical prologs is in "growing up" order. `#framesz` below represents the size of entire stack (excluding alloca area). `#localsz` and `#outsz` denote local area size (including the save area for the \<r29, lr> pair) and outgoing parameter size, respectively.
5959

60-
1. chained, #localsz <= 512
60+
1. Chained, #localsz <= 512
6161

6262
```asm
6363
stp r19,r20,[sp,-96]! // pre-indexed, save in 1st FP/INT pair
@@ -71,7 +71,7 @@ For frame chained functions, the fp and lr pair can be saved at any position in
7171
sub sp, #outsz // (optional for #outsz != 0)
7272
```
7373
74-
2. chained, #localsz > 512
74+
2. Chained, #localsz > 512
7575
7676
```asm
7777
stp r19,r20,[sp,-96]! // pre-indexed, save in 1st FP/INT pair
@@ -85,7 +85,7 @@ For frame chained functions, the fp and lr pair can be saved at any position in
8585
add r29,sp, #outsz // setup r29 points to bottom of local area
8686
```
8787
88-
3. unchained, leaf functions (lr unsaved)
88+
3. Unchained, leaf functions (lr unsaved)
8989
9090
```asm
9191
stp r19,r20,[sp, -72]! // pre-indexed, save in 1st FP/INT reg-pair
@@ -128,7 +128,7 @@ For frame chained functions, the fp and lr pair can be saved at any position in
128128
sub sp,#framesz-16 // allocate the remaining local area
129129
```
130130
131-
* The reg save area allocation is not folded into the stp because a pre-indexed reg-lr stp cannot be represented with the unwind codes.
131+
\* The reg save area allocation is not folded into the stp because a pre-indexed reg-lr stp cannot be represented with the unwind codes.
132132
133133
All locals are accessed based on SP. \<r29> points to the previous frame.
134134
@@ -157,7 +157,7 @@ For frame chained functions, the fp and lr pair can be saved at any position in
157157
158158
For optimization purpose, r29 can be put at any position in local area to provide a better coverage for "reg-pair" and pre-/post-indexed offset addressing mode. Locals below frame pointers can be accessed based on SP.
159159
160-
7. chained, frame size > 4K, with/without alloca(),
160+
7. Chained, frame size > 4K, with or without alloca(),
161161
162162
```asm
163163
stp r29, lr, [sp, -80]! // pre-indexed, save <r29,lr>
@@ -180,33 +180,9 @@ For frame chained functions, the fp and lr pair can be saved at any position in
180180
ldp r29, lr, [sp], -80 // post-indexed, reload <r29,lr>
181181
```
182182
183-
## ARM64 RFG (/d2rwg, /d2rfgfull)
183+
## ARM64 exception handling information
184184
185-
When ARM64 RFG is enabled (/d2rwg, /d2rfgfull) lr is encrypted before being stored on the stack and decrypted after being loaded from the stack. The actual encryption/decryption varies depending on the flavor of RFG.
186-
187-
### Example
188-
189-
```asm
190-
sub sp,sp,#0x10
191-
add lr,lr,x28 // add cookie reg to lr (start of encryption)
192-
ror lr,lr,x28 // ror lr with cookie reg (encryption contd.)
193-
eor lr,lr,x28 // eor lr with cookie reg (end of encryption)
194-
stp x19,lr,[sp] // store x19, encrypted lr on the stack
195-
...
196-
...
197-
ldp x19,lr,[sp] // load x19, encrypted lr from the stack
198-
eor lr,lr,x28 // eor lr with cookie reg (start of decryption)
199-
neg xip0,x28 // neg x28 (decryption contd. simulate rol)
200-
ror lr,lr,xip0 // ror lr, neg x28(decryption contd. simulate rol)
201-
sub lr,lr,x28 // sub cookie reg from lr (end of decryption)
202-
add sp,sp,#0x10
203-
```
204-
205-
With the current implementation, functions which have rfg enabled are required to emit .xdata.
206-
207-
## ARM64 Exception Handling Information
208-
209-
### .pdata Records
185+
### .pdata records
210186
211187
The .pdata records are an ordered array of fixed-length items which describe every stack-manipulating function in a PE binary. Note carefully the phrase "stack-manipulating": leaf functions which do not require any local storage and which do not need to save/restore non-volatile registers do not require a .pdata record; these should be explicitly omitted to save space. A unwind from one of these functions can simply get the return address from LR to move up to the caller.
212188
@@ -224,7 +200,7 @@ The fields are as follows:
224200
225201
- **Packed Unwind Data** is a compressed description of the operations needed to unwind from a function, assuming a canonical form. In this case, no .xdata record is required.
226202
227-
### .xdata Records
203+
### .xdata records
228204
229205
When the packed unwind format is insufficient to describe the unwinding of a function, a variable-length .xdata record must be created. The address of this record is stored in the second word of the .pdata record. The format of the .xdata is a packed variable-length set of words:
230206
@@ -294,7 +270,7 @@ ULONG ComputeXdataSize(PULONG *Xdata)
294270

295271
It should be noted that although the prolog and each epilog has its own index into the unwind codes, the table is shared between them, and it is entirely possible (and not altogether uncommon) that they can all share the same codes (see Example 2 in Appendix A below). Compiler writers should optimize for this case, in particular because the largest index that can be specified is 255, thus limiting the total number of unwind codes for a particular function.
296272

297-
### Unwind Codes
273+
### Unwind codes
298274

299275
The array of unwind codes is pool of sequences that describe exactly how to undo the effects of the prolog, in the order in which the operations need to be undone. The unwind codes can be thought of as a mini instruction set, encoded as a string of bytes. When execution is complete, the return address to the calling function is in the lr register, and all non-volatile registers are restored to their values at the time the function was called.
300276

0 commit comments

Comments
 (0)