|
|
|||
File indexing completed on 2026-05-10 08:44:27
0001 //===-- llvm/Support/ARMWinEH.h - Windows on ARM EH Constants ---*- C++ -*-===// 0002 // 0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 0004 // See https://llvm.org/LICENSE.txt for license information. 0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 0006 // 0007 //===----------------------------------------------------------------------===// 0008 0009 #ifndef LLVM_SUPPORT_ARMWINEH_H 0010 #define LLVM_SUPPORT_ARMWINEH_H 0011 0012 #include "llvm/ADT/ArrayRef.h" 0013 #include "llvm/Support/Endian.h" 0014 0015 namespace llvm { 0016 namespace ARM { 0017 namespace WinEH { 0018 enum class RuntimeFunctionFlag { 0019 RFF_Unpacked, /// unpacked entry 0020 RFF_Packed, /// packed entry 0021 RFF_PackedFragment, /// packed entry representing a fragment 0022 RFF_Reserved, /// reserved 0023 }; 0024 0025 enum class ReturnType { 0026 RT_POP, /// return via pop {pc} (L flag must be set) 0027 RT_B, /// 16-bit branch 0028 RT_BW, /// 32-bit branch 0029 RT_NoEpilogue, /// no epilogue (fragment) 0030 }; 0031 0032 /// RuntimeFunction - An entry in the table of procedure data (.pdata) 0033 /// 0034 /// This is ARM specific, but the Function Start RVA, Flag and 0035 /// ExceptionInformationRVA fields work identically for ARM64. 0036 /// 0037 /// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0038 /// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 0039 /// +---------------------------------------------------------------+ 0040 /// | Function Start RVA | 0041 /// +-------------------+-+-+-+-----+-+---+---------------------+---+ 0042 /// | Stack Adjust |C|L|R| Reg |H|Ret| Function Length |Flg| 0043 /// +-------------------+-+-+-+-----+-+---+---------------------+---+ 0044 /// 0045 /// Flag : 2-bit field with the following meanings: 0046 /// - 00 = packed unwind data not used; reamining bits point to .xdata record 0047 /// - 01 = packed unwind data 0048 /// - 10 = packed unwind data, function assumed to have no prologue; useful 0049 /// for function fragments that are discontiguous with the start of the 0050 /// function 0051 /// - 11 = reserved 0052 /// Function Length : 11-bit field providing the length of the entire function 0053 /// in bytes, divided by 2; if the function is greater than 0054 /// 4KB, a full .xdata record must be used instead 0055 /// Ret : 2-bit field indicating how the function returns 0056 /// - 00 = return via pop {pc} (the L bit must be set) 0057 /// - 01 = return via 16-bit branch 0058 /// - 10 = return via 32-bit branch 0059 /// - 11 = no epilogue; useful for function fragments that may only contain a 0060 /// prologue but the epilogue is elsewhere 0061 /// H : 1-bit flag indicating whether the function "homes" the integer parameter 0062 /// registers (r0-r3), allocating 16-bytes on the stack 0063 /// Reg : 3-bit field indicating the index of the last saved non-volatile 0064 /// register. If the R bit is set to 0, then only integer registers are 0065 /// saved (r4-rN, where N is 4 + Reg). If the R bit is set to 1, then 0066 /// only floating-point registers are being saved (d8-dN, where N is 0067 /// 8 + Reg). The special case of the R bit being set to 1 and Reg equal 0068 /// to 7 indicates that no registers are saved. 0069 /// R : 1-bit flag indicating whether the non-volatile registers are integer or 0070 /// floating-point. 0 indicates integer, 1 indicates floating-point. The 0071 /// special case of the R-flag being set and Reg being set to 7 indicates 0072 /// that no non-volatile registers are saved. 0073 /// L : 1-bit flag indicating whether the function saves/restores the link 0074 /// register (LR) 0075 /// C : 1-bit flag indicating whether the function includes extra instructions 0076 /// to setup a frame chain for fast walking. If this flag is set, r11 is 0077 /// implicitly added to the list of saved non-volatile integer registers. 0078 /// Stack Adjust : 10-bit field indicating the number of bytes of stack that are 0079 /// allocated for this function. Only values between 0x000 and 0080 /// 0x3f3 can be directly encoded. If the value is 0x3f4 or 0081 /// greater, then the low 4 bits have special meaning as follows: 0082 /// - Bit 0-1 0083 /// indicate the number of words' of adjustment (1-4), minus 1 0084 /// - Bit 2 0085 /// indicates if the prologue combined adjustment into push 0086 /// - Bit 3 0087 /// indicates if the epilogue combined adjustment into pop 0088 /// 0089 /// RESTRICTIONS: 0090 /// - IF C is SET: 0091 /// + L flag must be set since frame chaining requires r11 and lr 0092 /// + r11 must NOT be included in the set of registers described by Reg 0093 /// - IF Ret is 0: 0094 /// + L flag must be set 0095 0096 // NOTE: RuntimeFunction is meant to be a simple class that provides raw access 0097 // to all fields in the structure. The accessor methods reflect the names of 0098 // the bitfields that they correspond to. Although some obvious simplifications 0099 // are possible via merging of methods, it would prevent the use of this class 0100 // to fully inspect the contents of the data structure which is particularly 0101 // useful for scenarios such as llvm-readobj to aid in testing. 0102 0103 class RuntimeFunction { 0104 public: 0105 const support::ulittle32_t BeginAddress; 0106 const support::ulittle32_t UnwindData; 0107 0108 RuntimeFunction(const support::ulittle32_t *Data) 0109 : BeginAddress(Data[0]), UnwindData(Data[1]) {} 0110 0111 RuntimeFunction(const support::ulittle32_t BeginAddress, 0112 const support::ulittle32_t UnwindData) 0113 : BeginAddress(BeginAddress), UnwindData(UnwindData) {} 0114 0115 RuntimeFunctionFlag Flag() const { 0116 return RuntimeFunctionFlag(UnwindData & 0x3); 0117 } 0118 0119 uint32_t ExceptionInformationRVA() const { 0120 assert(Flag() == RuntimeFunctionFlag::RFF_Unpacked && 0121 "unpacked form required for this operation"); 0122 return (UnwindData & ~0x3); 0123 } 0124 0125 uint32_t PackedUnwindData() const { 0126 assert((Flag() == RuntimeFunctionFlag::RFF_Packed || 0127 Flag() == RuntimeFunctionFlag::RFF_PackedFragment) && 0128 "packed form required for this operation"); 0129 return (UnwindData & ~0x3); 0130 } 0131 uint32_t FunctionLength() const { 0132 assert((Flag() == RuntimeFunctionFlag::RFF_Packed || 0133 Flag() == RuntimeFunctionFlag::RFF_PackedFragment) && 0134 "packed form required for this operation"); 0135 return (((UnwindData & 0x00001ffc) >> 2) << 1); 0136 } 0137 ReturnType Ret() const { 0138 assert((Flag() == RuntimeFunctionFlag::RFF_Packed || 0139 Flag() == RuntimeFunctionFlag::RFF_PackedFragment) && 0140 "packed form required for this operation"); 0141 assert(((UnwindData & 0x00006000) || L()) && "L must be set to 1"); 0142 return ReturnType((UnwindData & 0x00006000) >> 13); 0143 } 0144 bool H() const { 0145 assert((Flag() == RuntimeFunctionFlag::RFF_Packed || 0146 Flag() == RuntimeFunctionFlag::RFF_PackedFragment) && 0147 "packed form required for this operation"); 0148 return ((UnwindData & 0x00008000) >> 15); 0149 } 0150 uint8_t Reg() const { 0151 assert((Flag() == RuntimeFunctionFlag::RFF_Packed || 0152 Flag() == RuntimeFunctionFlag::RFF_PackedFragment) && 0153 "packed form required for this operation"); 0154 return ((UnwindData & 0x00070000) >> 16); 0155 } 0156 bool R() const { 0157 assert((Flag() == RuntimeFunctionFlag::RFF_Packed || 0158 Flag() == RuntimeFunctionFlag::RFF_PackedFragment) && 0159 "packed form required for this operation"); 0160 return ((UnwindData & 0x00080000) >> 19); 0161 } 0162 bool L() const { 0163 assert((Flag() == RuntimeFunctionFlag::RFF_Packed || 0164 Flag() == RuntimeFunctionFlag::RFF_PackedFragment) && 0165 "packed form required for this operation"); 0166 return ((UnwindData & 0x00100000) >> 20); 0167 } 0168 bool C() const { 0169 assert((Flag() == RuntimeFunctionFlag::RFF_Packed || 0170 Flag() == RuntimeFunctionFlag::RFF_PackedFragment) && 0171 "packed form required for this operation"); 0172 assert(((~UnwindData & 0x00200000) || L()) && 0173 "L flag must be set, chaining requires r11 and LR"); 0174 assert(((~UnwindData & 0x00200000) || (Reg() < 7) || R()) && 0175 "r11 must not be included in Reg; C implies r11"); 0176 return ((UnwindData & 0x00200000) >> 21); 0177 } 0178 uint16_t StackAdjust() const { 0179 assert((Flag() == RuntimeFunctionFlag::RFF_Packed || 0180 Flag() == RuntimeFunctionFlag::RFF_PackedFragment) && 0181 "packed form required for this operation"); 0182 return ((UnwindData & 0xffc00000) >> 22); 0183 } 0184 }; 0185 0186 /// PrologueFolding - pseudo-flag derived from Stack Adjust indicating that the 0187 /// prologue has stack adjustment combined into the push 0188 inline bool PrologueFolding(const RuntimeFunction &RF) { 0189 return RF.StackAdjust() >= 0x3f4 && (RF.StackAdjust() & 0x4); 0190 } 0191 /// Epilogue - pseudo-flag derived from Stack Adjust indicating that the 0192 /// epilogue has stack adjustment combined into the pop 0193 inline bool EpilogueFolding(const RuntimeFunction &RF) { 0194 return RF.StackAdjust() >= 0x3f4 && (RF.StackAdjust() & 0x8); 0195 } 0196 /// StackAdjustment - calculated stack adjustment in words. The stack 0197 /// adjustment should be determined via this function to account for the special 0198 /// handling the special encoding when the value is >= 0x3f4. 0199 inline uint16_t StackAdjustment(const RuntimeFunction &RF) { 0200 uint16_t Adjustment = RF.StackAdjust(); 0201 if (Adjustment >= 0x3f4) 0202 return (Adjustment & 0x3) + 1; 0203 return Adjustment; 0204 } 0205 0206 /// SavedRegisterMask - Utility function to calculate the set of saved general 0207 /// purpose (r0-r15) and VFP (d0-d31) registers. 0208 std::pair<uint16_t, uint32_t> SavedRegisterMask(const RuntimeFunction &RF, 0209 bool Prologue = true); 0210 0211 /// RuntimeFunctionARM64 - An entry in the table of procedure data (.pdata) 0212 /// 0213 /// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0214 /// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 0215 /// +---------------------------------------------------------------+ 0216 /// | Function Start RVA | 0217 /// +-----------------+---+-+-------+-----+---------------------+---+ 0218 /// | Frame Size |CR |H| RegI |RegF | Function Length |Flg| 0219 /// +-----------------+---+-+-------+-----+---------------------+---+ 0220 /// 0221 /// See https://docs.microsoft.com/en-us/cpp/build/arm64-exception-handling 0222 /// for the full reference for this struct. 0223 0224 class RuntimeFunctionARM64 { 0225 public: 0226 const support::ulittle32_t BeginAddress; 0227 const support::ulittle32_t UnwindData; 0228 0229 RuntimeFunctionARM64(const support::ulittle32_t *Data) 0230 : BeginAddress(Data[0]), UnwindData(Data[1]) {} 0231 0232 RuntimeFunctionARM64(const support::ulittle32_t BeginAddress, 0233 const support::ulittle32_t UnwindData) 0234 : BeginAddress(BeginAddress), UnwindData(UnwindData) {} 0235 0236 RuntimeFunctionFlag Flag() const { 0237 return RuntimeFunctionFlag(UnwindData & 0x3); 0238 } 0239 0240 uint32_t ExceptionInformationRVA() const { 0241 assert(Flag() == RuntimeFunctionFlag::RFF_Unpacked && 0242 "unpacked form required for this operation"); 0243 return (UnwindData & ~0x3); 0244 } 0245 0246 uint32_t PackedUnwindData() const { 0247 assert((Flag() == RuntimeFunctionFlag::RFF_Packed || 0248 Flag() == RuntimeFunctionFlag::RFF_PackedFragment) && 0249 "packed form required for this operation"); 0250 return (UnwindData & ~0x3); 0251 } 0252 uint32_t FunctionLength() const { 0253 assert((Flag() == RuntimeFunctionFlag::RFF_Packed || 0254 Flag() == RuntimeFunctionFlag::RFF_PackedFragment) && 0255 "packed form required for this operation"); 0256 return (((UnwindData & 0x00001ffc) >> 2) << 2); 0257 } 0258 uint8_t RegF() const { 0259 assert((Flag() == RuntimeFunctionFlag::RFF_Packed || 0260 Flag() == RuntimeFunctionFlag::RFF_PackedFragment) && 0261 "packed form required for this operation"); 0262 return ((UnwindData & 0x0000e000) >> 13); 0263 } 0264 uint8_t RegI() const { 0265 assert((Flag() == RuntimeFunctionFlag::RFF_Packed || 0266 Flag() == RuntimeFunctionFlag::RFF_PackedFragment) && 0267 "packed form required for this operation"); 0268 return ((UnwindData & 0x000f0000) >> 16); 0269 } 0270 bool H() const { 0271 assert((Flag() == RuntimeFunctionFlag::RFF_Packed || 0272 Flag() == RuntimeFunctionFlag::RFF_PackedFragment) && 0273 "packed form required for this operation"); 0274 return ((UnwindData & 0x00100000) >> 20); 0275 } 0276 uint8_t CR() const { 0277 assert((Flag() == RuntimeFunctionFlag::RFF_Packed || 0278 Flag() == RuntimeFunctionFlag::RFF_PackedFragment) && 0279 "packed form required for this operation"); 0280 return ((UnwindData & 0x600000) >> 21); 0281 } 0282 uint16_t FrameSize() const { 0283 assert((Flag() == RuntimeFunctionFlag::RFF_Packed || 0284 Flag() == RuntimeFunctionFlag::RFF_PackedFragment) && 0285 "packed form required for this operation"); 0286 return ((UnwindData & 0xff800000) >> 23); 0287 } 0288 }; 0289 0290 /// ExceptionDataRecord - An entry in the table of exception data (.xdata) 0291 /// 0292 /// The format on ARM is: 0293 /// 0294 /// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0295 /// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 0296 /// +-------+---------+-+-+-+---+-----------------------------------+ 0297 /// | C Wrd | Epi Cnt |F|E|X|Ver| Function Length | 0298 /// +-------+--------+'-'-'-'---'---+-------------------------------+ 0299 /// | Reserved |Ex. Code Words| (Extended Epilogue Count) | 0300 /// +-------+--------+--------------+-------------------------------+ 0301 /// 0302 /// The format on ARM64 is: 0303 /// 0304 /// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0305 /// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 0306 /// +---------+---------+-+-+---+-----------------------------------+ 0307 /// | C Wrd | Epi Cnt |E|X|Ver| Function Length | 0308 /// +---------+------+--'-'-'---'---+-------------------------------+ 0309 /// | Reserved |Ex. Code Words| (Extended Epilogue Count) | 0310 /// +-------+--------+--------------+-------------------------------+ 0311 /// 0312 /// Function Length : 18-bit field indicating the total length of the function 0313 /// in bytes divided by 2. If a function is larger than 0314 /// 512KB, then multiple pdata and xdata records must be used. 0315 /// Vers : 2-bit field describing the version of the remaining structure. Only 0316 /// version 0 is currently defined (values 1-3 are not permitted). 0317 /// X : 1-bit field indicating the presence of exception data 0318 /// E : 1-bit field indicating that the single epilogue is packed into the 0319 /// header 0320 /// F : 1-bit field indicating that the record describes a function fragment 0321 /// (implies that no prologue is present, and prologue processing should be 0322 /// skipped) (ARM only) 0323 /// Epilogue Count : 5-bit field that differs in meaning based on the E field. 0324 /// 0325 /// If E is set, then this field specifies the index of the 0326 /// first unwind code describing the (only) epilogue. 0327 /// 0328 /// Otherwise, this field indicates the number of exception 0329 /// scopes. If more than 31 scopes exist, then this field and 0330 /// the Code Words field must both be set to 0 to indicate that 0331 /// an extension word is required. 0332 /// Code Words : 4-bit (5-bit on ARM64) field that specifies the number of 0333 /// 32-bit words needed to contain all the unwind codes. If more 0334 /// than 15 words (31 words on ARM64) are required, then this field 0335 /// and the Epilogue Count field must both be set to 0 to indicate 0336 /// that an extension word is required. 0337 /// Extended Epilogue Count, Extended Code Words : 0338 /// Valid only if Epilog Count and Code Words are both 0339 /// set to 0. Provides an 8-bit extended code word 0340 /// count and 16-bits for epilogue count 0341 /// 0342 /// The epilogue scope format on ARM is: 0343 /// 0344 /// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0345 /// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 0346 /// +----------------+------+---+---+-------------------------------+ 0347 /// | Ep Start Idx | Cond |Res| Epilogue Start Offset | 0348 /// +----------------+------+---+-----------------------------------+ 0349 /// 0350 /// The epilogue scope format on ARM64 is: 0351 /// 0352 /// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0353 /// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 0354 /// +-------------------+-------+---+-------------------------------+ 0355 /// | Ep Start Idx | Res | Epilogue Start Offset | 0356 /// +-------------------+-------+-----------------------------------+ 0357 /// 0358 /// If the E bit is unset in the header, the header is followed by a series of 0359 /// epilogue scopes, which are sorted by their offset. 0360 /// 0361 /// Epilogue Start Offset: 18-bit field encoding the offset of epilogue relative 0362 /// to the start of the function in bytes divided by two 0363 /// Res : 2-bit field reserved for future expansion (must be set to 0) 0364 /// Condition : (ARM only) 4-bit field providing the condition under which the 0365 /// epilogue is executed. Unconditional epilogues should set this 0366 /// field to 0xe. Epilogues must be entirely conditional or 0367 /// unconditional, and in Thumb-2 mode. The epilogue begins with 0368 /// the first instruction after the IT opcode. 0369 /// Epilogue Start Index : 8-bit field indicating the byte index of the first 0370 /// unwind code describing the epilogue 0371 /// 0372 /// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0373 /// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 0374 /// +---------------+---------------+---------------+---------------+ 0375 /// | Unwind Code 3 | Unwind Code 2 | Unwind Code 1 | Unwind Code 0 | 0376 /// +---------------+---------------+---------------+---------------+ 0377 /// 0378 /// Following the epilogue scopes, the byte code describing the unwinding 0379 /// follows. This is padded to align up to word alignment. Bytes are stored in 0380 /// little endian. 0381 /// 0382 /// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0383 /// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 0384 /// +---------------------------------------------------------------+ 0385 /// | Exception Handler RVA (requires X = 1) | 0386 /// +---------------------------------------------------------------+ 0387 /// | (possibly followed by data required for exception handler) | 0388 /// +---------------------------------------------------------------+ 0389 /// 0390 /// If the X bit is set in the header, the unwind byte code is followed by the 0391 /// exception handler information. This constants of one Exception Handler RVA 0392 /// which is the address to the exception handler, followed immediately by the 0393 /// variable length data associated with the exception handler. 0394 /// 0395 0396 struct EpilogueScope { 0397 const support::ulittle32_t ES; 0398 0399 EpilogueScope(const support::ulittle32_t Data) : ES(Data) {} 0400 // Same for both ARM and AArch64. 0401 uint32_t EpilogueStartOffset() const { 0402 return (ES & 0x0003ffff); 0403 } 0404 0405 // Different implementations for ARM and AArch64. 0406 uint8_t ResARM() const { 0407 return ((ES & 0x000c0000) >> 18); 0408 } 0409 0410 uint8_t ResAArch64() const { 0411 return ((ES & 0x000f0000) >> 18); 0412 } 0413 0414 // Condition is only applicable to ARM. 0415 uint8_t Condition() const { 0416 return ((ES & 0x00f00000) >> 20); 0417 } 0418 0419 // Different implementations for ARM and AArch64. 0420 uint8_t EpilogueStartIndexARM() const { 0421 return ((ES & 0xff000000) >> 24); 0422 } 0423 0424 uint16_t EpilogueStartIndexAArch64() const { 0425 return ((ES & 0xffc00000) >> 22); 0426 } 0427 }; 0428 0429 struct ExceptionDataRecord; 0430 inline size_t HeaderWords(const ExceptionDataRecord &XR); 0431 0432 struct ExceptionDataRecord { 0433 const support::ulittle32_t *Data; 0434 bool isAArch64; 0435 0436 ExceptionDataRecord(const support::ulittle32_t *Data, bool isAArch64) : 0437 Data(Data), isAArch64(isAArch64) {} 0438 0439 uint32_t FunctionLength() const { 0440 return (Data[0] & 0x0003ffff); 0441 } 0442 0443 uint32_t FunctionLengthInBytesARM() const { 0444 return FunctionLength() << 1; 0445 } 0446 0447 uint32_t FunctionLengthInBytesAArch64() const { 0448 return FunctionLength() << 2; 0449 } 0450 0451 uint8_t Vers() const { 0452 return (Data[0] & 0x000C0000) >> 18; 0453 } 0454 0455 bool X() const { 0456 return ((Data[0] & 0x00100000) >> 20); 0457 } 0458 0459 bool E() const { 0460 return ((Data[0] & 0x00200000) >> 21); 0461 } 0462 0463 bool F() const { 0464 assert(!isAArch64 && "Fragments are only supported on ARMv7 WinEH"); 0465 return ((Data[0] & 0x00400000) >> 22); 0466 } 0467 0468 uint16_t EpilogueCount() const { 0469 if (HeaderWords(*this) == 1) { 0470 if (isAArch64) 0471 return (Data[0] & 0x07C00000) >> 22; 0472 return (Data[0] & 0x0f800000) >> 23; 0473 } 0474 return Data[1] & 0x0000ffff; 0475 } 0476 0477 uint8_t CodeWords() const { 0478 if (HeaderWords(*this) == 1) { 0479 if (isAArch64) 0480 return (Data[0] & 0xf8000000) >> 27; 0481 return (Data[0] & 0xf0000000) >> 28; 0482 } 0483 return (Data[1] & 0x00ff0000) >> 16; 0484 } 0485 0486 ArrayRef<support::ulittle32_t> EpilogueScopes() const { 0487 assert(E() == 0 && "epilogue scopes are only present when the E bit is 0"); 0488 size_t Offset = HeaderWords(*this); 0489 return ArrayRef(&Data[Offset], EpilogueCount()); 0490 } 0491 0492 ArrayRef<uint8_t> UnwindByteCode() const { 0493 const size_t Offset = HeaderWords(*this) 0494 + (E() ? 0 : EpilogueCount()); 0495 const uint8_t *ByteCode = 0496 reinterpret_cast<const uint8_t *>(&Data[Offset]); 0497 return ArrayRef(ByteCode, CodeWords() * sizeof(uint32_t)); 0498 } 0499 0500 uint32_t ExceptionHandlerRVA() const { 0501 assert(X() && "Exception Handler RVA is only valid if the X bit is set"); 0502 return Data[HeaderWords(*this) + (E() ? 0 : EpilogueCount()) + CodeWords()]; 0503 } 0504 0505 uint32_t ExceptionHandlerParameter() const { 0506 assert(X() && "Exception Handler RVA is only valid if the X bit is set"); 0507 return Data[HeaderWords(*this) + (E() ? 0 : EpilogueCount()) + CodeWords() + 0508 1]; 0509 } 0510 }; 0511 0512 inline size_t HeaderWords(const ExceptionDataRecord &XR) { 0513 if (XR.isAArch64) 0514 return (XR.Data[0] & 0xffc00000) ? 1 : 2; 0515 return (XR.Data[0] & 0xff800000) ? 1 : 2; 0516 } 0517 } 0518 } 0519 } 0520 0521 #endif
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|