Home | History | Annotate | Line # | Download | only in libunwind
DwarfParser.hpp revision 1.2.2.1
      1      1.1  joerg //===--------------------------- DwarfParser.hpp --------------------------===//
      2      1.1  joerg //
      3      1.1  joerg //                     The LLVM Compiler Infrastructure
      4      1.1  joerg //
      5      1.1  joerg // This file is dual licensed under the MIT and the University of Illinois Open
      6      1.1  joerg // Source Licenses. See LICENSE.TXT for details.
      7      1.1  joerg //
      8      1.1  joerg //
      9      1.1  joerg //  Parses DWARF CFIs (FDEs and CIEs).
     10      1.1  joerg //
     11      1.1  joerg //===----------------------------------------------------------------------===//
     12      1.1  joerg 
     13      1.1  joerg #ifndef __DWARF_PARSER_HPP__
     14      1.1  joerg #define __DWARF_PARSER_HPP__
     15      1.1  joerg 
     16      1.1  joerg #include <cstdint>
     17      1.1  joerg #include <cstdlib>
     18      1.1  joerg 
     19      1.1  joerg #include "dwarf2.h"
     20      1.1  joerg #include "AddressSpace.hpp"
     21      1.1  joerg 
     22      1.1  joerg namespace _Unwind {
     23      1.1  joerg 
     24      1.1  joerg /// CFI_Parser does basic parsing of a CFI (Call Frame Information) records.
     25      1.1  joerg /// See Dwarf Spec for details:
     26      1.1  joerg ///    http://refspecs.linuxbase.org/LSB_3.1.0/LSB-Core-generic/LSB-Core-generic/ehframechpt.html
     27      1.1  joerg ///
     28      1.1  joerg template <typename A, typename R> class CFI_Parser {
     29      1.1  joerg public:
     30      1.1  joerg   typedef typename A::pint_t pint_t;
     31      1.1  joerg 
     32      1.1  joerg   /// Information encoded in a CIE (Common Information Entry)
     33      1.1  joerg   struct CIE_Info {
     34      1.1  joerg     pint_t cieStart;
     35      1.1  joerg     pint_t cieLength;
     36      1.1  joerg     pint_t cieInstructions;
     37      1.1  joerg     pint_t personality;
     38      1.1  joerg     uint32_t codeAlignFactor;
     39      1.1  joerg     int dataAlignFactor;
     40      1.1  joerg     uint8_t pointerEncoding;
     41      1.1  joerg     uint8_t lsdaEncoding;
     42      1.1  joerg     uint8_t personalityEncoding;
     43      1.1  joerg     uint8_t personalityOffsetInCIE;
     44      1.1  joerg     bool isSignalFrame;
     45      1.1  joerg     bool fdesHaveAugmentationData;
     46  1.2.2.1    tls     uint8_t returnAddressRegister;
     47      1.1  joerg   };
     48      1.1  joerg 
     49      1.1  joerg   /// Information about an FDE (Frame Description Entry)
     50      1.1  joerg   struct FDE_Info {
     51      1.1  joerg     pint_t fdeStart;
     52      1.1  joerg     pint_t fdeLength;
     53      1.1  joerg     pint_t fdeInstructions;
     54      1.1  joerg     pint_t pcStart;
     55      1.1  joerg     pint_t pcEnd;
     56      1.1  joerg     pint_t lsda;
     57      1.1  joerg   };
     58      1.1  joerg 
     59      1.1  joerg   /// Information about a frame layout and registers saved determined
     60      1.1  joerg   /// by "running" the DWARF FDE "instructions"
     61      1.1  joerg   enum {
     62      1.1  joerg     kMaxRegisterNumber = R::LAST_REGISTER + 1
     63      1.1  joerg   };
     64      1.1  joerg   enum RegisterSavedWhere {
     65      1.1  joerg     kRegisterUnused,
     66      1.1  joerg     kRegisterInCFA,
     67      1.1  joerg     kRegisterOffsetFromCFA,
     68      1.1  joerg     kRegisterInRegister,
     69      1.1  joerg     kRegisterAtExpression,
     70      1.1  joerg     kRegisterIsExpression,
     71      1.1  joerg   };
     72      1.1  joerg   struct RegisterLocation {
     73      1.1  joerg     RegisterSavedWhere location;
     74      1.1  joerg     int64_t value;
     75      1.1  joerg   };
     76      1.1  joerg   struct PrologInfo {
     77      1.1  joerg     uint32_t cfaRegister;
     78      1.1  joerg     int32_t cfaRegisterOffset; // CFA = (cfaRegister)+cfaRegisterOffset
     79      1.1  joerg     int64_t cfaExpression;     // CFA = expression
     80      1.1  joerg     uint32_t spExtraArgSize;
     81      1.1  joerg     uint32_t codeOffsetAtStackDecrement;
     82      1.1  joerg     RegisterLocation savedRegisters[kMaxRegisterNumber];
     83      1.1  joerg   };
     84      1.1  joerg 
     85      1.1  joerg   struct PrologInfoStackEntry {
     86      1.1  joerg     PrologInfoStackEntry(PrologInfoStackEntry *n, const PrologInfo &i)
     87      1.1  joerg         : next(n), info(i) {}
     88      1.1  joerg     PrologInfoStackEntry *next;
     89      1.1  joerg     PrologInfo info;
     90      1.1  joerg   };
     91      1.1  joerg 
     92      1.1  joerg   static void findPCRange(A &, pint_t, pint_t &, pint_t &);
     93      1.1  joerg 
     94      1.1  joerg   static bool decodeFDE(A &, pint_t, FDE_Info *, CIE_Info *,
     95      1.1  joerg                         unw_proc_info_t *ctx);
     96      1.1  joerg   static bool parseFDEInstructions(A &, const FDE_Info &, const CIE_Info &,
     97      1.1  joerg                                    pint_t, PrologInfo *, unw_proc_info_t *ctx);
     98      1.1  joerg 
     99      1.1  joerg   static bool parseCIE(A &, pint_t, CIE_Info *);
    100      1.1  joerg 
    101      1.1  joerg private:
    102      1.1  joerg   static bool parseInstructions(A &, pint_t, pint_t, const CIE_Info &, pint_t,
    103      1.1  joerg                                 PrologInfoStackEntry *&, PrologInfo *,
    104      1.1  joerg                                 unw_proc_info_t *ctx);
    105      1.1  joerg };
    106      1.1  joerg 
    107      1.1  joerg ///
    108      1.1  joerg /// Parse a FDE and return the last PC it covers.
    109      1.1  joerg ///
    110      1.1  joerg template <typename A, typename R>
    111      1.1  joerg void CFI_Parser<A, R>::findPCRange(A &addressSpace, pint_t fde, pint_t &pcStart,
    112      1.1  joerg                                    pint_t &pcEnd) {
    113      1.1  joerg   pcStart = 0;
    114      1.1  joerg   pcEnd = 0;
    115      1.1  joerg   pint_t p = fde;
    116      1.1  joerg   uint64_t cfiLength = addressSpace.get32(p);
    117      1.1  joerg   p += 4;
    118      1.1  joerg   if (cfiLength == 0xffffffff) {
    119      1.1  joerg     // 0xffffffff means length is really the next 8 Bytes.
    120      1.1  joerg     cfiLength = addressSpace.get64(p);
    121      1.1  joerg     p += 8;
    122      1.1  joerg   }
    123      1.1  joerg   if (cfiLength == 0)
    124      1.1  joerg     return;
    125      1.1  joerg   uint32_t ciePointer = addressSpace.get32(p);
    126      1.1  joerg   if (ciePointer == 0)
    127      1.1  joerg     return;
    128      1.1  joerg   pint_t nextCFI = p + cfiLength;
    129      1.1  joerg   pint_t cieStart = p - ciePointer;
    130      1.1  joerg   typename CFI_Parser<A, R>::CIE_Info cieInfo;
    131      1.1  joerg   if (!parseCIE(addressSpace, cieStart, &cieInfo))
    132      1.1  joerg     return;
    133      1.1  joerg   p += 4;
    134      1.1  joerg   // Parse pc begin and range.
    135      1.1  joerg   pcStart = addressSpace.getEncodedP(p, nextCFI, cieInfo.pointerEncoding, NULL);
    136      1.1  joerg   pcEnd = pcStart + addressSpace.getEncodedP(
    137      1.1  joerg                         p, nextCFI, cieInfo.pointerEncoding & 0x0F, NULL);
    138      1.1  joerg }
    139      1.1  joerg 
    140      1.1  joerg ///
    141      1.1  joerg /// Parse a FDE into a CIE_Info and an FDE_Info
    142      1.1  joerg ///
    143      1.1  joerg template <typename A, typename R>
    144      1.1  joerg bool CFI_Parser<A, R>::decodeFDE(A &addressSpace, pint_t fdeStart,
    145      1.1  joerg                                  FDE_Info *fdeInfo, CIE_Info *cieInfo,
    146      1.1  joerg                                  unw_proc_info_t *ctx) {
    147      1.1  joerg   pint_t p = fdeStart;
    148      1.1  joerg   uint64_t cfiLength = addressSpace.get32(p);
    149      1.1  joerg   p += 4;
    150      1.1  joerg   if (cfiLength == 0xffffffff) {
    151      1.1  joerg     // 0xffffffff means length is really the next 8 Bytes.
    152      1.1  joerg     cfiLength = addressSpace.get64(p);
    153      1.1  joerg     p += 8;
    154      1.1  joerg   }
    155      1.1  joerg   if (cfiLength == 0)
    156      1.1  joerg     return false;
    157      1.1  joerg   uint32_t ciePointer = addressSpace.get32(p);
    158      1.1  joerg   if (ciePointer == 0)
    159      1.1  joerg     return false;
    160      1.1  joerg   pint_t nextCFI = p + cfiLength;
    161      1.1  joerg   pint_t cieStart = p - ciePointer;
    162      1.1  joerg   if (!parseCIE(addressSpace, cieStart, cieInfo))
    163      1.1  joerg     return false;
    164      1.1  joerg   p += 4;
    165      1.1  joerg   // Parse pc begin and range.
    166      1.1  joerg   pint_t pcStart =
    167      1.1  joerg       addressSpace.getEncodedP(p, nextCFI, cieInfo->pointerEncoding, ctx);
    168      1.1  joerg   pint_t pcRange = addressSpace.getEncodedP(
    169      1.1  joerg       p, nextCFI, cieInfo->pointerEncoding & 0x0F, ctx);
    170      1.1  joerg   // Parse rest of info.
    171      1.1  joerg   fdeInfo->lsda = 0;
    172      1.1  joerg   // Check for augmentation length
    173      1.1  joerg   if (cieInfo->fdesHaveAugmentationData) {
    174      1.1  joerg     uintptr_t augLen = addressSpace.getULEB128(p, nextCFI);
    175      1.1  joerg     pint_t endOfAug = p + augLen;
    176      1.2  joerg     if (cieInfo->lsdaEncoding != DW_EH_PE_omit) {
    177      1.1  joerg       // Peek at value (without indirection).  Zero means no LSDA.
    178      1.1  joerg       pint_t lsdaStart = p;
    179      1.1  joerg       if (addressSpace.getEncodedP(p, nextCFI, cieInfo->lsdaEncoding & 0x0F,
    180      1.1  joerg                                    ctx) != 0) {
    181      1.1  joerg         // Reset pointer and re-parse LSDA address.
    182      1.1  joerg         p = lsdaStart;
    183      1.1  joerg         fdeInfo->lsda =
    184      1.1  joerg             addressSpace.getEncodedP(p, nextCFI, cieInfo->lsdaEncoding, ctx);
    185      1.1  joerg       }
    186      1.1  joerg     }
    187      1.1  joerg     p = endOfAug;
    188      1.1  joerg   }
    189      1.1  joerg   fdeInfo->fdeStart = fdeStart;
    190      1.1  joerg   fdeInfo->fdeLength = nextCFI - fdeStart;
    191      1.1  joerg   fdeInfo->fdeInstructions = p;
    192      1.1  joerg   fdeInfo->pcStart = pcStart;
    193      1.1  joerg   fdeInfo->pcEnd = pcStart + pcRange;
    194      1.1  joerg   return true;
    195      1.1  joerg }
    196      1.1  joerg 
    197      1.1  joerg /// Extract info from a CIE
    198      1.1  joerg template <typename A, typename R>
    199      1.1  joerg bool CFI_Parser<A, R>::parseCIE(A &addressSpace, pint_t cie,
    200      1.1  joerg                                 CIE_Info *cieInfo) {
    201      1.1  joerg   cieInfo->pointerEncoding = 0;
    202      1.2  joerg   cieInfo->lsdaEncoding = DW_EH_PE_omit;
    203      1.1  joerg   cieInfo->personalityEncoding = 0;
    204      1.1  joerg   cieInfo->personalityOffsetInCIE = 0;
    205      1.1  joerg   cieInfo->personality = 0;
    206      1.1  joerg   cieInfo->codeAlignFactor = 0;
    207      1.1  joerg   cieInfo->dataAlignFactor = 0;
    208      1.1  joerg   cieInfo->isSignalFrame = false;
    209      1.1  joerg   cieInfo->fdesHaveAugmentationData = false;
    210      1.1  joerg   cieInfo->cieStart = cie;
    211      1.1  joerg   pint_t p = cie;
    212      1.1  joerg   uint64_t cieLength = addressSpace.get32(p);
    213      1.1  joerg   p += 4;
    214      1.1  joerg   pint_t cieContentEnd = p + cieLength;
    215      1.1  joerg   if (cieLength == 0xffffffff) {
    216      1.1  joerg     // 0xffffffff means length is really the next 8 Bytes.
    217      1.1  joerg     cieLength = addressSpace.get64(p);
    218      1.1  joerg     p += 8;
    219      1.1  joerg     cieContentEnd = p + cieLength;
    220      1.1  joerg   }
    221      1.1  joerg   if (cieLength == 0)
    222      1.1  joerg     return true;
    223      1.1  joerg   // CIE ID is always 0
    224      1.1  joerg   if (addressSpace.get32(p) != 0)
    225      1.1  joerg     return false;
    226      1.1  joerg   p += 4;
    227      1.1  joerg   // Version is always 1 or 3
    228      1.1  joerg   uint8_t version = addressSpace.get8(p);
    229      1.1  joerg   if (version != 1 && version != 3)
    230      1.1  joerg     return false;
    231      1.1  joerg   ++p;
    232      1.1  joerg   // Save start of augmentation string and find end.
    233      1.1  joerg   pint_t strStart = p;
    234      1.1  joerg   while (addressSpace.get8(p) != 0)
    235      1.1  joerg     ++p;
    236      1.1  joerg   ++p;
    237      1.1  joerg   // Parse code aligment factor
    238      1.1  joerg   cieInfo->codeAlignFactor = addressSpace.getULEB128(p, cieContentEnd);
    239      1.1  joerg   // Parse data alignment factor
    240      1.1  joerg   cieInfo->dataAlignFactor = addressSpace.getSLEB128(p, cieContentEnd);
    241      1.1  joerg   // Parse return address register
    242  1.2.2.1    tls   cieInfo->returnAddressRegister = (uint8_t)addressSpace.getULEB128(p, cieContentEnd);
    243      1.1  joerg   // Parse augmentation data based on augmentation string.
    244      1.1  joerg   if (addressSpace.get8(strStart) == 'z') {
    245      1.1  joerg     // parse augmentation data length
    246      1.1  joerg     addressSpace.getULEB128(p, cieContentEnd);
    247      1.1  joerg     for (pint_t s = strStart; addressSpace.get8(s) != '\0'; ++s) {
    248      1.1  joerg       switch (addressSpace.get8(s)) {
    249      1.1  joerg       case 'z':
    250      1.1  joerg         cieInfo->fdesHaveAugmentationData = true;
    251      1.1  joerg         break;
    252      1.1  joerg       case 'P':
    253      1.1  joerg         cieInfo->personalityEncoding = addressSpace.get8(p);
    254      1.1  joerg         ++p;
    255      1.1  joerg         cieInfo->personalityOffsetInCIE = p - cie;
    256      1.1  joerg         cieInfo->personality = addressSpace.getEncodedP(
    257      1.1  joerg             p, cieContentEnd, cieInfo->personalityEncoding, NULL);
    258      1.1  joerg         break;
    259      1.1  joerg       case 'L':
    260      1.1  joerg         cieInfo->lsdaEncoding = addressSpace.get8(p);
    261      1.1  joerg         ++p;
    262      1.1  joerg         break;
    263      1.1  joerg       case 'R':
    264      1.1  joerg         cieInfo->pointerEncoding = addressSpace.get8(p);
    265      1.1  joerg         ++p;
    266      1.1  joerg         break;
    267      1.1  joerg       case 'S':
    268      1.1  joerg         cieInfo->isSignalFrame = true;
    269      1.1  joerg         break;
    270      1.1  joerg       default:
    271      1.1  joerg         // ignore unknown letters
    272      1.1  joerg         break;
    273      1.1  joerg       }
    274      1.1  joerg     }
    275      1.1  joerg   }
    276      1.1  joerg   cieInfo->cieLength = cieContentEnd - cieInfo->cieStart;
    277      1.1  joerg   cieInfo->cieInstructions = p;
    278      1.1  joerg   return true;
    279      1.1  joerg }
    280      1.1  joerg 
    281      1.1  joerg /// "Run" the dwarf instructions and create the abstact PrologInfo for an FDE.
    282      1.1  joerg template <typename A, typename R>
    283      1.1  joerg bool CFI_Parser<A, R>::parseFDEInstructions(A &addressSpace,
    284      1.1  joerg                                             const FDE_Info &fdeInfo,
    285      1.1  joerg                                             const CIE_Info &cieInfo,
    286      1.1  joerg                                             pint_t upToPC, PrologInfo *results,
    287      1.1  joerg                                             unw_proc_info_t *ctx) {
    288      1.1  joerg   // Clear results.
    289      1.1  joerg   memset(results, 0, sizeof(*results));
    290      1.1  joerg   PrologInfoStackEntry *rememberStack = NULL;
    291      1.1  joerg 
    292      1.1  joerg   // First parse the CIE then FDE instructions.
    293      1.1  joerg   if (!parseInstructions(addressSpace, cieInfo.cieInstructions,
    294      1.1  joerg                          cieInfo.cieStart + cieInfo.cieLength, cieInfo,
    295      1.1  joerg                          (pint_t)(-1), rememberStack, results, ctx))
    296      1.1  joerg     return false;
    297      1.1  joerg   return parseInstructions(addressSpace, fdeInfo.fdeInstructions,
    298      1.1  joerg                            fdeInfo.fdeStart + fdeInfo.fdeLength, cieInfo,
    299      1.1  joerg                            upToPC - fdeInfo.pcStart, rememberStack, results,
    300      1.1  joerg                            ctx);
    301      1.1  joerg }
    302      1.1  joerg 
    303      1.1  joerg /// "Run" the DWARF instructions.
    304      1.1  joerg template <typename A, typename R>
    305      1.1  joerg bool
    306      1.1  joerg CFI_Parser<A, R>::parseInstructions(A &addressSpace, pint_t instructions,
    307      1.1  joerg                                     pint_t instructionsEnd,
    308      1.1  joerg                                     const CIE_Info &cieInfo, pint_t pcoffset,
    309      1.1  joerg                                     PrologInfoStackEntry *&rememberStack,
    310      1.1  joerg                                     PrologInfo *results, unw_proc_info_t *ctx) {
    311      1.1  joerg   pint_t p = instructions;
    312      1.1  joerg   uint32_t codeOffset = 0;
    313      1.1  joerg   PrologInfo initialState = *results;
    314      1.1  joerg 
    315      1.1  joerg   // See Dwarf Spec, section 6.4.2 for details on unwind opcodes.
    316      1.1  joerg   while (p < instructionsEnd && codeOffset < pcoffset) {
    317      1.1  joerg     uint64_t reg;
    318      1.1  joerg     uint64_t reg2;
    319      1.1  joerg     int64_t offset;
    320      1.1  joerg     uint64_t length;
    321      1.1  joerg     uint8_t opcode = addressSpace.get8(p);
    322      1.1  joerg     uint8_t operand;
    323      1.1  joerg     PrologInfoStackEntry *entry;
    324      1.1  joerg     ++p;
    325      1.1  joerg     switch (opcode) {
    326      1.1  joerg     case DW_CFA_nop:
    327      1.1  joerg       break;
    328      1.1  joerg     case DW_CFA_set_loc:
    329      1.1  joerg       codeOffset = addressSpace.getEncodedP(p, instructionsEnd,
    330      1.1  joerg                                             cieInfo.pointerEncoding, ctx);
    331      1.1  joerg       break;
    332      1.1  joerg     case DW_CFA_advance_loc1:
    333      1.1  joerg       codeOffset += (addressSpace.get8(p) * cieInfo.codeAlignFactor);
    334      1.1  joerg       p += 1;
    335      1.1  joerg       break;
    336      1.1  joerg     case DW_CFA_advance_loc2:
    337      1.1  joerg       codeOffset += (addressSpace.get16(p) * cieInfo.codeAlignFactor);
    338      1.1  joerg       p += 2;
    339      1.1  joerg       break;
    340      1.1  joerg     case DW_CFA_advance_loc4:
    341      1.1  joerg       codeOffset += (addressSpace.get32(p) * cieInfo.codeAlignFactor);
    342      1.1  joerg       p += 4;
    343      1.1  joerg       break;
    344      1.1  joerg     case DW_CFA_offset_extended:
    345      1.1  joerg       reg = R::dwarf2regno(addressSpace.getULEB128(p, instructionsEnd));
    346      1.1  joerg       offset =
    347      1.1  joerg           addressSpace.getULEB128(p, instructionsEnd) * cieInfo.dataAlignFactor;
    348      1.1  joerg       if (reg > kMaxRegisterNumber)
    349      1.1  joerg         return false;
    350      1.1  joerg       results->savedRegisters[reg].location = kRegisterInCFA;
    351      1.1  joerg       results->savedRegisters[reg].value = offset;
    352      1.1  joerg       break;
    353      1.1  joerg     case DW_CFA_restore_extended:
    354      1.1  joerg       reg = R::dwarf2regno(addressSpace.getULEB128(p, instructionsEnd));
    355      1.1  joerg       if (reg > kMaxRegisterNumber)
    356      1.1  joerg         return false;
    357      1.1  joerg       results->savedRegisters[reg] = initialState.savedRegisters[reg];
    358      1.1  joerg       break;
    359      1.1  joerg     case DW_CFA_undefined:
    360      1.1  joerg       reg = R::dwarf2regno(addressSpace.getULEB128(p, instructionsEnd));
    361      1.1  joerg       if (reg > kMaxRegisterNumber)
    362      1.1  joerg         return false;
    363      1.1  joerg       results->savedRegisters[reg].location = kRegisterUnused;
    364      1.1  joerg       break;
    365      1.1  joerg     case DW_CFA_same_value:
    366      1.1  joerg       reg = R::dwarf2regno(addressSpace.getULEB128(p, instructionsEnd));
    367      1.1  joerg       if (reg > kMaxRegisterNumber)
    368      1.1  joerg         return false;
    369      1.1  joerg       // "same value" means register was stored in frame, but its current
    370      1.1  joerg       // value has not changed, so no need to restore from frame.
    371      1.1  joerg       // We model this as if the register was never saved.
    372      1.1  joerg       results->savedRegisters[reg].location = kRegisterUnused;
    373      1.1  joerg       break;
    374      1.1  joerg     case DW_CFA_register:
    375      1.1  joerg       reg = R::dwarf2regno(addressSpace.getULEB128(p, instructionsEnd));
    376      1.1  joerg       reg2 = R::dwarf2regno(addressSpace.getULEB128(p, instructionsEnd));
    377      1.1  joerg       if (reg > kMaxRegisterNumber)
    378      1.1  joerg         return false;
    379      1.1  joerg       if (reg2 > kMaxRegisterNumber)
    380      1.1  joerg         return false;
    381      1.1  joerg       results->savedRegisters[reg].location = kRegisterInRegister;
    382      1.1  joerg       results->savedRegisters[reg].value = reg2;
    383      1.1  joerg       break;
    384      1.1  joerg     case DW_CFA_remember_state:
    385      1.1  joerg       // avoid operator new, because that would be an upward dependency
    386      1.1  joerg       entry = (PrologInfoStackEntry *)malloc(sizeof(PrologInfoStackEntry));
    387      1.1  joerg       if (entry == NULL)
    388      1.1  joerg         return false;
    389      1.1  joerg 
    390      1.1  joerg       entry->next = rememberStack;
    391      1.1  joerg       entry->info = *results;
    392      1.1  joerg       rememberStack = entry;
    393      1.1  joerg       break;
    394      1.1  joerg     case DW_CFA_restore_state:
    395      1.1  joerg       if (rememberStack == NULL)
    396      1.1  joerg         return false;
    397      1.1  joerg       {
    398      1.1  joerg         PrologInfoStackEntry *top = rememberStack;
    399      1.1  joerg         *results = top->info;
    400      1.1  joerg         rememberStack = top->next;
    401      1.1  joerg         free((char *)top);
    402      1.1  joerg       }
    403      1.1  joerg       break;
    404      1.1  joerg     case DW_CFA_def_cfa:
    405      1.1  joerg       reg = R::dwarf2regno(addressSpace.getULEB128(p, instructionsEnd));
    406      1.1  joerg       offset = addressSpace.getULEB128(p, instructionsEnd);
    407      1.1  joerg       if (reg > kMaxRegisterNumber)
    408      1.1  joerg         return false;
    409      1.1  joerg       results->cfaRegister = reg;
    410      1.1  joerg       results->cfaRegisterOffset = offset;
    411      1.1  joerg       break;
    412      1.1  joerg     case DW_CFA_def_cfa_register:
    413      1.1  joerg       reg = R::dwarf2regno(addressSpace.getULEB128(p, instructionsEnd));
    414      1.1  joerg       if (reg > kMaxRegisterNumber)
    415      1.1  joerg         return false;
    416      1.1  joerg       results->cfaRegister = reg;
    417      1.1  joerg       break;
    418      1.1  joerg     case DW_CFA_def_cfa_offset:
    419      1.1  joerg       results->cfaRegisterOffset = addressSpace.getULEB128(p, instructionsEnd);
    420      1.1  joerg       results->codeOffsetAtStackDecrement = codeOffset;
    421      1.1  joerg       break;
    422      1.1  joerg     case DW_CFA_def_cfa_expression:
    423      1.1  joerg       results->cfaRegister = 0;
    424      1.1  joerg       results->cfaExpression = p;
    425      1.1  joerg       length = addressSpace.getULEB128(p, instructionsEnd);
    426      1.1  joerg       p += length;
    427      1.1  joerg       break;
    428      1.1  joerg     case DW_CFA_expression:
    429      1.1  joerg       reg = R::dwarf2regno(addressSpace.getULEB128(p, instructionsEnd));
    430      1.1  joerg       if (reg > kMaxRegisterNumber)
    431      1.1  joerg         return false;
    432      1.1  joerg       results->savedRegisters[reg].location = kRegisterAtExpression;
    433      1.1  joerg       results->savedRegisters[reg].value = p;
    434      1.1  joerg       length = addressSpace.getULEB128(p, instructionsEnd);
    435      1.1  joerg       p += length;
    436      1.1  joerg       break;
    437      1.1  joerg     case DW_CFA_offset_extended_sf:
    438      1.1  joerg       reg = R::dwarf2regno(addressSpace.getULEB128(p, instructionsEnd));
    439      1.1  joerg       if (reg > kMaxRegisterNumber)
    440      1.1  joerg         return false;
    441      1.1  joerg       offset =
    442      1.1  joerg           addressSpace.getSLEB128(p, instructionsEnd) * cieInfo.dataAlignFactor;
    443      1.1  joerg       results->savedRegisters[reg].location = kRegisterInCFA;
    444      1.1  joerg       results->savedRegisters[reg].value = offset;
    445      1.1  joerg       break;
    446      1.1  joerg     case DW_CFA_def_cfa_sf:
    447      1.1  joerg       reg = R::dwarf2regno(addressSpace.getULEB128(p, instructionsEnd));
    448      1.1  joerg       offset =
    449      1.1  joerg           addressSpace.getSLEB128(p, instructionsEnd) * cieInfo.dataAlignFactor;
    450      1.1  joerg       if (reg > kMaxRegisterNumber)
    451      1.1  joerg         return false;
    452      1.1  joerg       results->cfaRegister = reg;
    453      1.1  joerg       results->cfaRegisterOffset = offset;
    454      1.1  joerg       break;
    455      1.1  joerg     case DW_CFA_def_cfa_offset_sf:
    456      1.1  joerg       results->cfaRegisterOffset =
    457      1.1  joerg           addressSpace.getSLEB128(p, instructionsEnd) * cieInfo.dataAlignFactor;
    458      1.1  joerg       results->codeOffsetAtStackDecrement = codeOffset;
    459      1.1  joerg       break;
    460      1.1  joerg     case DW_CFA_val_offset:
    461      1.1  joerg       reg = R::dwarf2regno(addressSpace.getULEB128(p, instructionsEnd));
    462      1.1  joerg       offset =
    463      1.1  joerg           addressSpace.getULEB128(p, instructionsEnd) * cieInfo.dataAlignFactor;
    464  1.2.2.1    tls       if (reg > kMaxRegisterNumber)
    465  1.2.2.1    tls         return false;
    466      1.1  joerg       results->savedRegisters[reg].location = kRegisterOffsetFromCFA;
    467      1.1  joerg       results->savedRegisters[reg].value = offset;
    468      1.1  joerg       break;
    469      1.1  joerg     case DW_CFA_val_offset_sf:
    470      1.1  joerg       reg = R::dwarf2regno(addressSpace.getULEB128(p, instructionsEnd));
    471      1.1  joerg       if (reg > kMaxRegisterNumber)
    472      1.1  joerg         return false;
    473      1.1  joerg       offset =
    474      1.1  joerg           addressSpace.getSLEB128(p, instructionsEnd) * cieInfo.dataAlignFactor;
    475      1.1  joerg       results->savedRegisters[reg].location = kRegisterOffsetFromCFA;
    476      1.1  joerg       results->savedRegisters[reg].value = offset;
    477      1.1  joerg       break;
    478      1.1  joerg     case DW_CFA_val_expression:
    479      1.1  joerg       reg = R::dwarf2regno(addressSpace.getULEB128(p, instructionsEnd));
    480      1.1  joerg       if (reg > kMaxRegisterNumber)
    481      1.1  joerg         return false;
    482      1.1  joerg       results->savedRegisters[reg].location = kRegisterIsExpression;
    483      1.1  joerg       results->savedRegisters[reg].value = p;
    484      1.1  joerg       length = addressSpace.getULEB128(p, instructionsEnd);
    485      1.1  joerg       p += length;
    486      1.1  joerg       break;
    487  1.2.2.1    tls     case DW_CFA_GNU_window_save:
    488  1.2.2.1    tls #if defined(__sparc__)
    489  1.2.2.1    tls       for (reg = 8; reg < 16; ++reg) {
    490  1.2.2.1    tls         results->savedRegisters[reg].location = kRegisterInRegister;
    491  1.2.2.1    tls         results->savedRegisters[reg].value = reg + 16;
    492  1.2.2.1    tls       }
    493  1.2.2.1    tls       for (reg = 16; reg < 32; ++reg) {
    494  1.2.2.1    tls         results->savedRegisters[reg].location = kRegisterInCFA;
    495  1.2.2.1    tls         results->savedRegisters[reg].value = (reg - 16) * sizeof(typename R::reg_t);
    496  1.2.2.1    tls       }
    497  1.2.2.1    tls       break;
    498  1.2.2.1    tls #else
    499  1.2.2.1    tls       return false;
    500  1.2.2.1    tls #endif
    501      1.1  joerg     case DW_CFA_GNU_args_size:
    502      1.1  joerg       offset = addressSpace.getULEB128(p, instructionsEnd);
    503      1.1  joerg       results->spExtraArgSize = offset;
    504      1.1  joerg       break;
    505      1.1  joerg     case DW_CFA_GNU_negative_offset_extended:
    506      1.1  joerg       reg = R::dwarf2regno(addressSpace.getULEB128(p, instructionsEnd));
    507      1.1  joerg       if (reg > kMaxRegisterNumber)
    508      1.1  joerg         return false;
    509      1.1  joerg       offset =
    510      1.1  joerg           addressSpace.getULEB128(p, instructionsEnd) * cieInfo.dataAlignFactor;
    511      1.1  joerg       results->savedRegisters[reg].location = kRegisterInCFA;
    512      1.1  joerg       results->savedRegisters[reg].value = -offset;
    513      1.1  joerg       break;
    514      1.1  joerg     default:
    515      1.1  joerg       operand = opcode & 0x3F;
    516      1.1  joerg       switch (opcode & 0xC0) {
    517      1.1  joerg       case DW_CFA_offset:
    518      1.1  joerg         reg = R::dwarf2regno(operand);
    519      1.1  joerg         if (reg > kMaxRegisterNumber)
    520      1.1  joerg           return false;
    521      1.1  joerg         offset = addressSpace.getULEB128(p, instructionsEnd) *
    522      1.1  joerg                  cieInfo.dataAlignFactor;
    523      1.1  joerg         results->savedRegisters[reg].location = kRegisterInCFA;
    524      1.1  joerg         results->savedRegisters[reg].value = offset;
    525      1.1  joerg         break;
    526      1.1  joerg       case DW_CFA_advance_loc:
    527      1.1  joerg         codeOffset += operand * cieInfo.codeAlignFactor;
    528      1.1  joerg         break;
    529      1.1  joerg       case DW_CFA_restore:
    530      1.1  joerg         reg = R::dwarf2regno(operand);
    531      1.1  joerg         if (reg > kMaxRegisterNumber)
    532      1.1  joerg           return false;
    533      1.1  joerg         results->savedRegisters[reg] = initialState.savedRegisters[reg];
    534      1.1  joerg         break;
    535      1.1  joerg       default:
    536      1.1  joerg         return false;
    537      1.1  joerg       }
    538      1.1  joerg     }
    539      1.1  joerg   }
    540      1.1  joerg 
    541      1.1  joerg   return true;
    542      1.1  joerg }
    543      1.1  joerg 
    544      1.1  joerg } // namespace _Unwind
    545      1.1  joerg 
    546      1.1  joerg #endif // __DWARF_PARSER_HPP__
    547