LLVM API Documentation

ARMWinEH.h
Go to the documentation of this file.
00001 //===-- llvm/Support/WinARMEH.h - Windows on ARM EH Constants ---*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 
00010 #ifndef LLVM_SUPPORT_ARMWINEH_H
00011 #define LLVM_SUPPORT_ARMWINEH_H
00012 
00013 #include "llvm/ADT/ArrayRef.h"
00014 #include "llvm/Support/Endian.h"
00015 
00016 namespace llvm {
00017 namespace ARM {
00018 namespace WinEH {
00019 enum class RuntimeFunctionFlag {
00020   RFF_Unpacked,       /// unpacked entry
00021   RFF_Packed,         /// packed entry
00022   RFF_PackedFragment, /// packed entry representing a fragment
00023   RFF_Reserved,       /// reserved
00024 };
00025 
00026 enum class ReturnType {
00027   RT_POP,             /// return via pop {pc} (L flag must be set)
00028   RT_B,               /// 16-bit branch
00029   RT_BW,              /// 32-bit branch
00030   RT_NoEpilogue,      /// no epilogue (fragment)
00031 };
00032 
00033 /// RuntimeFunction - An entry in the table of procedure data (.pdata)
00034 ///
00035 ///  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
00036 ///  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
00037 /// +---------------------------------------------------------------+
00038 /// |                     Function Start RVA                        |
00039 /// +-------------------+-+-+-+-----+-+---+---------------------+---+
00040 /// |    Stack Adjust   |C|L|R| Reg |H|Ret|   Function Length   |Flg|
00041 /// +-------------------+-+-+-+-----+-+---+---------------------+---+
00042 ///
00043 /// Flag : 2-bit field with the following meanings:
00044 ///   - 00 = packed unwind data not used; reamining bits point to .xdata record
00045 ///   - 01 = packed unwind data
00046 ///   - 10 = packed unwind data, function assumed to have no prologue; useful
00047 ///          for function fragments that are discontiguous with the start of the
00048 ///          function
00049 ///   - 11 = reserved
00050 /// Function Length : 11-bit field providing the length of the entire function
00051 ///                   in bytes, divided by 2; if the function is greater than
00052 ///                   4KB, a full .xdata record must be used instead
00053 /// Ret : 2-bit field indicating how the function returns
00054 ///   - 00 = return via pop {pc} (the L bit must be set)
00055 ///   - 01 = return via 16-bit branch
00056 ///   - 10 = return via 32-bit branch
00057 ///   - 11 = no epilogue; useful for function fragments that may only contain a
00058 ///          prologue but the epilogue is elsewhere
00059 /// H : 1-bit flag indicating whether the function "homes" the integer parameter
00060 ///     registers (r0-r3), allocating 16-bytes on the stack
00061 /// Reg : 3-bit field indicating the index of the last saved non-volatile
00062 ///       register.  If the R bit is set to 0, then only integer registers are
00063 ///       saved (r4-rN, where N is 4 + Reg).  If the R bit is set to 1, then
00064 ///       only floating-point registers are being saved (d8-dN, where N is
00065 ///       8 + Reg).  The special case of the R bit being set to 1 and Reg equal
00066 ///       to 7 indicates that no registers are saved.
00067 /// R : 1-bit flag indicating whether the non-volatile registers are integer or
00068 ///     floating-point.  0 indicates integer, 1 indicates floating-point.  The
00069 ///     special case of the R-flag being set and Reg being set to 7 indicates
00070 ///     that no non-volatile registers are saved.
00071 /// L : 1-bit flag indicating whether the function saves/restores the link
00072 ///     register (LR)
00073 /// C : 1-bit flag indicating whether the function includes extra instructions
00074 ///     to setup a frame chain for fast walking.  If this flag is set, r11 is
00075 ///     implicitly added to the list of saved non-volatile integer registers.
00076 /// Stack Adjust : 10-bit field indicating the number of bytes of stack that are
00077 ///                allocated for this function.  Only values between 0x000 and
00078 ///                0x3f3 can be directly encoded.  If the value is 0x3f4 or
00079 ///                greater, then the low 4 bits have special meaning as follows:
00080 ///                - Bit 0-1
00081 ///                  indicate the number of words' of adjustment (1-4), minus 1
00082 ///                - Bit 2
00083 ///                  indicates if the prologue combined adjustment into push
00084 ///                - Bit 3
00085 ///                  indicates if the epilogue combined adjustment into pop
00086 ///
00087 /// RESTRICTIONS:
00088 ///   - IF C is SET:
00089 ///     + L flag must be set since frame chaining requires r11 and lr
00090 ///     + r11 must NOT be included in the set of registers described by Reg
00091 ///   - IF Ret is 0:
00092 ///     + L flag must be set
00093 
00094 // NOTE: RuntimeFunction is meant to be a simple class that provides raw access
00095 // to all fields in the structure.  The accessor methods reflect the names of
00096 // the bitfields that they correspond to.  Although some obvious simplifications
00097 // are possible via merging of methods, it would prevent the use of this class
00098 // to fully inspect the contents of the data structure which is particularly
00099 // useful for scenarios such as llvm-readobj to aid in testing.
00100 
00101 class RuntimeFunction {
00102 public:
00103   const support::ulittle32_t BeginAddress;
00104   const support::ulittle32_t UnwindData;
00105 
00106   RuntimeFunction(const support::ulittle32_t *Data)
00107     : BeginAddress(Data[0]), UnwindData(Data[1]) {}
00108 
00109   RuntimeFunction(const support::ulittle32_t BeginAddress,
00110                   const support::ulittle32_t UnwindData)
00111     : BeginAddress(BeginAddress), UnwindData(UnwindData) {}
00112 
00113   RuntimeFunctionFlag Flag() const {
00114     return RuntimeFunctionFlag(UnwindData & 0x3);
00115   }
00116 
00117   uint32_t ExceptionInformationRVA() const {
00118     assert(Flag() == RuntimeFunctionFlag::RFF_Unpacked &&
00119            "unpacked form required for this operation");
00120     return (UnwindData & ~0x3);
00121   }
00122 
00123   uint32_t PackedUnwindData() const {
00124     assert((Flag() == RuntimeFunctionFlag::RFF_Packed ||
00125             Flag() == RuntimeFunctionFlag::RFF_PackedFragment) &&
00126            "packed form required for this operation");
00127     return (UnwindData & ~0x3);
00128   }
00129   uint32_t FunctionLength() const {
00130     assert((Flag() == RuntimeFunctionFlag::RFF_Packed ||
00131             Flag() == RuntimeFunctionFlag::RFF_PackedFragment) &&
00132            "packed form required for this operation");
00133     return (((UnwindData & 0x00001ffc) >> 2) << 1);
00134   }
00135   ReturnType Ret() const {
00136     assert((Flag() == RuntimeFunctionFlag::RFF_Packed ||
00137             Flag() == RuntimeFunctionFlag::RFF_PackedFragment) &&
00138            "packed form required for this operation");
00139     assert(((UnwindData & 0x00006000) || L()) && "L must be set to 1");
00140     return ReturnType((UnwindData & 0x00006000) >> 13);
00141   }
00142   bool H() const {
00143     assert((Flag() == RuntimeFunctionFlag::RFF_Packed ||
00144             Flag() == RuntimeFunctionFlag::RFF_PackedFragment) &&
00145            "packed form required for this operation");
00146     return ((UnwindData & 0x00008000) >> 15);
00147   }
00148   uint8_t Reg() const {
00149     assert((Flag() == RuntimeFunctionFlag::RFF_Packed ||
00150             Flag() == RuntimeFunctionFlag::RFF_PackedFragment) &&
00151            "packed form required for this operation");
00152     return ((UnwindData & 0x00070000) >> 16);
00153   }
00154   bool R() const {
00155     assert((Flag() == RuntimeFunctionFlag::RFF_Packed ||
00156             Flag() == RuntimeFunctionFlag::RFF_PackedFragment) &&
00157            "packed form required for this operation");
00158     return ((UnwindData & 0x00080000) >> 19);
00159   }
00160   bool L() const {
00161     assert((Flag() == RuntimeFunctionFlag::RFF_Packed ||
00162             Flag() == RuntimeFunctionFlag::RFF_PackedFragment) &&
00163            "packed form required for this operation");
00164     return ((UnwindData & 0x00100000) >> 20);
00165   }
00166   bool C() const {
00167     assert((Flag() == RuntimeFunctionFlag::RFF_Packed ||
00168             Flag() == RuntimeFunctionFlag::RFF_PackedFragment) &&
00169            "packed form required for this operation");
00170     assert(((~UnwindData & 0x00200000) || L()) &&
00171            "L flag must be set, chaining requires r11 and LR");
00172     assert(((~UnwindData & 0x00200000) || (Reg() < 7) || R()) &&
00173            "r11 must not be included in Reg; C implies r11");
00174     return ((UnwindData & 0x00200000) >> 21);
00175   }
00176   uint16_t StackAdjust() const {
00177     assert((Flag() == RuntimeFunctionFlag::RFF_Packed ||
00178             Flag() == RuntimeFunctionFlag::RFF_PackedFragment) &&
00179            "packed form required for this operation");
00180     return ((UnwindData & 0xffc00000) >> 22);
00181   }
00182 };
00183 
00184 /// PrologueFolding - pseudo-flag derived from Stack Adjust indicating that the
00185 /// prologue has stack adjustment combined into the push
00186 inline bool PrologueFolding(const RuntimeFunction &RF) {
00187   return RF.StackAdjust() >= 0x3f4 && (RF.StackAdjust() & 0x4);
00188 }
00189 /// Epilogue - pseudo-flag derived from Stack Adjust indicating that the
00190 /// epilogue has stack adjustment combined into the pop
00191 inline bool EpilogueFolding(const RuntimeFunction &RF) {
00192   return RF.StackAdjust() >= 0x3f4 && (RF.StackAdjust() & 0x8);
00193 }
00194 /// StackAdjustment - calculated stack adjustment in words.  The stack
00195 /// adjustment should be determined via this function to account for the special
00196 /// handling the special encoding when the value is >= 0x3f4.
00197 inline uint16_t StackAdjustment(const RuntimeFunction &RF) {
00198   uint16_t Adjustment = RF.StackAdjust();
00199   if (Adjustment >= 0x3f4)
00200     return (Adjustment & 0x3) ? ((Adjustment & 0x3) << 2) - 1 : 0;
00201   return Adjustment;
00202 }
00203 
00204 /// SavedRegisterMask - Utility function to calculate the set of saved general
00205 /// purpose (r0-r15) and VFP (d0-d31) registers.
00206 std::pair<uint16_t, uint32_t> SavedRegisterMask(const RuntimeFunction &RF);
00207 
00208 /// ExceptionDataRecord - An entry in the table of exception data (.xdata)
00209 ///
00210 ///  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
00211 ///  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
00212 /// +-------+---------+-+-+-+---+-----------------------------------+
00213 /// | C Wrd | Epi Cnt |F|E|X|Ver|         Function Length           |
00214 /// +-------+--------+'-'-'-'---'---+-------------------------------+
00215 /// |    Reserved    |Ex. Code Words|   (Extended Epilogue Count)   |
00216 /// +-------+--------+--------------+-------------------------------+
00217 ///
00218 /// Function Length : 18-bit field indicating the total length of the function
00219 ///                   in bytes divided by 2.  If a function is larger than
00220 ///                   512KB, then multiple pdata and xdata records must be used.
00221 /// Vers : 2-bit field describing the version of the remaining structure.  Only
00222 ///        version 0 is currently defined (values 1-3 are not permitted).
00223 /// X : 1-bit field indicating the presence of exception data
00224 /// E : 1-bit field indicating that the single epilogue is packed into the
00225 ///     header
00226 /// F : 1-bit field indicating that the record describes a function fragment
00227 ///     (implies that no prologue is present, and prologue processing should be
00228 ///     skipped)
00229 /// Epilogue Count : 5-bit field that differs in meaning based on the E field.
00230 ///
00231 ///                  If E is set, then this field specifies the index of the
00232 ///                  first unwind code describing the (only) epilogue.
00233 ///
00234 ///                  Otherwise, this field indicates the number of exception
00235 ///                  scopes.  If more than 31 scopes exist, then this field and
00236 ///                  the Code Words field must both be set to 0 to indicate that
00237 ///                  an extension word is required.
00238 /// Code Words : 4-bit field that species the number of 32-bit words needed to
00239 ///              contain all the unwind codes.  If more than 15 words (63 code
00240 ///              bytes) are required, then this field and the Epilogue Count
00241 ///              field must both be set to 0 to indicate that an extension word
00242 ///              is required.
00243 /// Extended Epilogue Count, Extended Code Words :
00244 ///                          Valid only if Epilog Count and Code Words are both
00245 ///                          set to 0.  Provides an 8-bit extended code word
00246 ///                          count and 16-bits for epilogue count
00247 ///
00248 ///  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
00249 ///  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
00250 /// +----------------+------+---+---+-------------------------------+
00251 /// |  Ep Start Idx  | Cond |Res|       Epilogue Start Offset       |
00252 /// +----------------+------+---+-----------------------------------+
00253 ///
00254 /// If the E bit is unset in the header, the header is followed by a series of
00255 /// epilogue scopes, which are sorted by their offset.
00256 ///
00257 /// Epilogue Start Offset: 18-bit field encoding the offset of epilogue relative
00258 ///                        to the start of the function in bytes divided by two
00259 /// Res : 2-bit field reserved for future expansion (must be set to 0)
00260 /// Condition : 4-bit field providing the condition under which the epilogue is
00261 ///             executed.  Unconditional epilogues should set this field to 0xe.
00262 ///             Epilogues must be entirely conditional or unconditional, and in
00263 ///             Thumb-2 mode.  The epilogue beings with the first instruction
00264 ///             after the IT opcode.
00265 /// Epilogue Start Index : 8-bit field indicating the byte index of the first
00266 ///                        unwind code describing the epilogue
00267 ///
00268 ///  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
00269 ///  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
00270 /// +---------------+---------------+---------------+---------------+
00271 /// | Unwind Code 3 | Unwind Code 2 | Unwind Code 1 | Unwind Code 0 |
00272 /// +---------------+---------------+---------------+---------------+
00273 ///
00274 /// Following the epilogue scopes, the byte code describing the unwinding
00275 /// follows.  This is padded to align up to word alignment.  Bytes are stored in
00276 /// little endian.
00277 ///
00278 ///  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
00279 ///  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
00280 /// +---------------------------------------------------------------+
00281 /// |           Exception Handler RVA (requires X = 1)              |
00282 /// +---------------------------------------------------------------+
00283 /// |  (possibly followed by data required for exception handler)   |
00284 /// +---------------------------------------------------------------+
00285 ///
00286 /// If the X bit is set in the header, the unwind byte code is followed by the
00287 /// exception handler information.  This constants of one Exception Handler RVA
00288 /// which is the address to the exception handler, followed immediately by the
00289 /// variable length data associated with the exception handler.
00290 ///
00291 
00292 struct EpilogueScope {
00293   const support::ulittle32_t ES;
00294 
00295   EpilogueScope(const support::ulittle32_t Data) : ES(Data) {}
00296   uint32_t EpilogueStartOffset() const {
00297     return (ES & 0x0003ffff);
00298   }
00299   uint8_t Res() const {
00300     return ((ES & 0x000c0000) >> 18);
00301   }
00302   uint8_t Condition() const {
00303     return ((ES & 0x00f00000) >> 20);
00304   }
00305   uint8_t EpilogueStartIndex() const {
00306     return ((ES & 0xff000000) >> 24);
00307   }
00308 };
00309 
00310 struct ExceptionDataRecord;
00311 inline size_t HeaderWords(const ExceptionDataRecord &XR);
00312 
00313 struct ExceptionDataRecord {
00314   const support::ulittle32_t *Data;
00315 
00316   ExceptionDataRecord(const support::ulittle32_t *Data) : Data(Data) {}
00317 
00318   uint32_t FunctionLength() const {
00319     return (Data[0] & 0x0003ffff);
00320   }
00321 
00322   uint8_t Vers() const {
00323     return (Data[0] & 0x000C0000) >> 18;
00324   }
00325 
00326   bool X() const {
00327     return ((Data[0] & 0x00100000) >> 20);
00328   }
00329 
00330   bool E() const {
00331     return ((Data[0] & 0x00200000) >> 21);
00332   }
00333 
00334   bool F() const {
00335     return ((Data[0] & 0x00400000) >> 22);
00336   }
00337 
00338   uint8_t EpilogueCount() const {
00339     if (HeaderWords(*this) == 1)
00340       return (Data[0] & 0x0f800000) >> 23;
00341     return Data[1] & 0x0000ffff;
00342   }
00343 
00344   uint8_t CodeWords() const {
00345     if (HeaderWords(*this) == 1)
00346       return (Data[0] & 0xf0000000) >> 28;
00347     return (Data[1] & 0x00ff0000) >> 16;
00348   }
00349 
00350   ArrayRef<support::ulittle32_t> EpilogueScopes() const {
00351     assert(E() == 0 && "epilogue scopes are only present when the E bit is 0");
00352     size_t Offset = HeaderWords(*this);
00353     return makeArrayRef(&Data[Offset], EpilogueCount());
00354   }
00355 
00356   ArrayRef<uint8_t> UnwindByteCode() const {
00357     const size_t Offset = HeaderWords(*this)
00358                         + (E() ? 0 :  EpilogueCount());
00359     const uint8_t *ByteCode =
00360       reinterpret_cast<const uint8_t *>(&Data[Offset]);
00361     return makeArrayRef(ByteCode, CodeWords() * sizeof(uint32_t));
00362   }
00363 
00364   uint32_t ExceptionHandlerRVA() const {
00365     assert(X() && "Exception Handler RVA is only valid if the X bit is set");
00366     return Data[HeaderWords(*this) + EpilogueCount() + CodeWords()];
00367   }
00368 
00369   uint32_t ExceptionHandlerParameter() const {
00370     assert(X() && "Exception Handler RVA is only valid if the X bit is set");
00371     return Data[HeaderWords(*this) + EpilogueCount() + CodeWords() + 1];
00372   }
00373 };
00374 
00375 inline size_t HeaderWords(const ExceptionDataRecord &XR) {
00376   return (XR.Data[0] & 0xff800000) ? 1 : 2;
00377 }
00378 }
00379 }
00380 }
00381 
00382 #endif