Home | History | Annotate | Line # | Download | only in libunwind
DwarfParser.hpp revision 1.5.46.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.4    joerg     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.5.46.1  thorpej   cieInfo->returnAddressRegister = R::dwarf2regno((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.5    joerg       if (reg > kMaxRegisterNumber)
    465       1.5    joerg         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.3    joerg     case DW_CFA_GNU_window_save:
    488       1.3    joerg #if defined(__sparc__)
    489       1.3    joerg       for (reg = 8; reg < 16; ++reg) {
    490       1.3    joerg         results->savedRegisters[reg].location = kRegisterInRegister;
    491       1.3    joerg         results->savedRegisters[reg].value = reg + 16;
    492       1.3    joerg       }
    493       1.3    joerg       for (reg = 16; reg < 32; ++reg) {
    494       1.3    joerg         results->savedRegisters[reg].location = kRegisterInCFA;
    495       1.3    joerg         results->savedRegisters[reg].value = (reg - 16) * sizeof(typename R::reg_t);
    496       1.3    joerg       }
    497       1.3    joerg       break;
    498       1.3    joerg #else
    499       1.3    joerg       return false;
    500       1.3    joerg #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