Home | History | Annotate | Download | only in JIT
      1 //===----- JITDwarfEmitter.cpp - Write dwarf tables into memory -----------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file defines a JITDwarfEmitter object that is used by the JIT to
     11 // write dwarf tables to memory.
     12 //
     13 //===----------------------------------------------------------------------===//
     14 
     15 #include "JITDwarfEmitter.h"
     16 #include "JIT.h"
     17 #include "llvm/ADT/DenseMap.h"
     18 #include "llvm/CodeGen/JITCodeEmitter.h"
     19 #include "llvm/CodeGen/MachineFunction.h"
     20 #include "llvm/CodeGen/MachineModuleInfo.h"
     21 #include "llvm/ExecutionEngine/JITMemoryManager.h"
     22 #include "llvm/IR/DataLayout.h"
     23 #include "llvm/IR/Function.h"
     24 #include "llvm/MC/MCAsmInfo.h"
     25 #include "llvm/MC/MCSymbol.h"
     26 #include "llvm/MC/MachineLocation.h"
     27 #include "llvm/Support/ErrorHandling.h"
     28 #include "llvm/Target/TargetFrameLowering.h"
     29 #include "llvm/Target/TargetInstrInfo.h"
     30 #include "llvm/Target/TargetMachine.h"
     31 #include "llvm/Target/TargetRegisterInfo.h"
     32 using namespace llvm;
     33 
     34 JITDwarfEmitter::JITDwarfEmitter(JIT& theJit) : MMI(0), Jit(theJit) {}
     35 
     36 
     37 unsigned char* JITDwarfEmitter::EmitDwarfTable(MachineFunction& F,
     38                                                JITCodeEmitter& jce,
     39                                                unsigned char* StartFunction,
     40                                                unsigned char* EndFunction,
     41                                                unsigned char* &EHFramePtr) {
     42   assert(MMI && "MachineModuleInfo not registered!");
     43 
     44   const TargetMachine& TM = F.getTarget();
     45   TD = TM.getDataLayout();
     46   stackGrowthDirection = TM.getFrameLowering()->getStackGrowthDirection();
     47   RI = TM.getRegisterInfo();
     48   MAI = TM.getMCAsmInfo();
     49   JCE = &jce;
     50 
     51   unsigned char* ExceptionTable = EmitExceptionTable(&F, StartFunction,
     52                                                      EndFunction);
     53 
     54   unsigned char* Result = 0;
     55 
     56   const std::vector<const Function *> Personalities = MMI->getPersonalities();
     57   EHFramePtr = EmitCommonEHFrame(Personalities[MMI->getPersonalityIndex()]);
     58 
     59   Result = EmitEHFrame(Personalities[MMI->getPersonalityIndex()], EHFramePtr,
     60                        StartFunction, EndFunction, ExceptionTable);
     61 
     62   return Result;
     63 }
     64 
     65 
     66 void
     67 JITDwarfEmitter::EmitFrameMoves(intptr_t BaseLabelPtr,
     68                                 const std::vector<MachineMove> &Moves) const {
     69   unsigned PointerSize = TD->getPointerSize();
     70   int stackGrowth = stackGrowthDirection == TargetFrameLowering::StackGrowsUp ?
     71           PointerSize : -PointerSize;
     72   MCSymbol *BaseLabel = 0;
     73 
     74   for (unsigned i = 0, N = Moves.size(); i < N; ++i) {
     75     const MachineMove &Move = Moves[i];
     76     MCSymbol *Label = Move.getLabel();
     77 
     78     // Throw out move if the label is invalid.
     79     if (Label && (*JCE->getLabelLocations())[Label] == 0)
     80       continue;
     81 
     82     intptr_t LabelPtr = 0;
     83     if (Label) LabelPtr = JCE->getLabelAddress(Label);
     84 
     85     const MachineLocation &Dst = Move.getDestination();
     86     const MachineLocation &Src = Move.getSource();
     87 
     88     // Advance row if new location.
     89     if (BaseLabelPtr && Label && BaseLabel != Label) {
     90       JCE->emitByte(dwarf::DW_CFA_advance_loc4);
     91       JCE->emitInt32(LabelPtr - BaseLabelPtr);
     92 
     93       BaseLabel = Label;
     94       BaseLabelPtr = LabelPtr;
     95     }
     96 
     97     // If advancing cfa.
     98     if (Dst.isReg() && Dst.getReg() == MachineLocation::VirtualFP) {
     99       if (!Src.isReg()) {
    100         if (Src.getReg() == MachineLocation::VirtualFP) {
    101           JCE->emitByte(dwarf::DW_CFA_def_cfa_offset);
    102         } else {
    103           JCE->emitByte(dwarf::DW_CFA_def_cfa);
    104           JCE->emitULEB128Bytes(RI->getDwarfRegNum(Src.getReg(), true));
    105         }
    106 
    107         JCE->emitULEB128Bytes(-Src.getOffset());
    108       } else {
    109         llvm_unreachable("Machine move not supported yet.");
    110       }
    111     } else if (Src.isReg() &&
    112       Src.getReg() == MachineLocation::VirtualFP) {
    113       if (Dst.isReg()) {
    114         JCE->emitByte(dwarf::DW_CFA_def_cfa_register);
    115         JCE->emitULEB128Bytes(RI->getDwarfRegNum(Dst.getReg(), true));
    116       } else {
    117         llvm_unreachable("Machine move not supported yet.");
    118       }
    119     } else {
    120       unsigned Reg = RI->getDwarfRegNum(Src.getReg(), true);
    121       int Offset = Dst.getOffset() / stackGrowth;
    122 
    123       if (Offset < 0) {
    124         JCE->emitByte(dwarf::DW_CFA_offset_extended_sf);
    125         JCE->emitULEB128Bytes(Reg);
    126         JCE->emitSLEB128Bytes(Offset);
    127       } else if (Reg < 64) {
    128         JCE->emitByte(dwarf::DW_CFA_offset + Reg);
    129         JCE->emitULEB128Bytes(Offset);
    130       } else {
    131         JCE->emitByte(dwarf::DW_CFA_offset_extended);
    132         JCE->emitULEB128Bytes(Reg);
    133         JCE->emitULEB128Bytes(Offset);
    134       }
    135     }
    136   }
    137 }
    138 
    139 /// SharedTypeIds - How many leading type ids two landing pads have in common.
    140 static unsigned SharedTypeIds(const LandingPadInfo *L,
    141                               const LandingPadInfo *R) {
    142   const std::vector<int> &LIds = L->TypeIds, &RIds = R->TypeIds;
    143   unsigned LSize = LIds.size(), RSize = RIds.size();
    144   unsigned MinSize = LSize < RSize ? LSize : RSize;
    145   unsigned Count = 0;
    146 
    147   for (; Count != MinSize; ++Count)
    148     if (LIds[Count] != RIds[Count])
    149       return Count;
    150 
    151   return Count;
    152 }
    153 
    154 
    155 /// PadLT - Order landing pads lexicographically by type id.
    156 static bool PadLT(const LandingPadInfo *L, const LandingPadInfo *R) {
    157   const std::vector<int> &LIds = L->TypeIds, &RIds = R->TypeIds;
    158   unsigned LSize = LIds.size(), RSize = RIds.size();
    159   unsigned MinSize = LSize < RSize ? LSize : RSize;
    160 
    161   for (unsigned i = 0; i != MinSize; ++i)
    162     if (LIds[i] != RIds[i])
    163       return LIds[i] < RIds[i];
    164 
    165   return LSize < RSize;
    166 }
    167 
    168 namespace {
    169 
    170 /// ActionEntry - Structure describing an entry in the actions table.
    171 struct ActionEntry {
    172   int ValueForTypeID; // The value to write - may not be equal to the type id.
    173   int NextAction;
    174   struct ActionEntry *Previous;
    175 };
    176 
    177 /// PadRange - Structure holding a try-range and the associated landing pad.
    178 struct PadRange {
    179   // The index of the landing pad.
    180   unsigned PadIndex;
    181   // The index of the begin and end labels in the landing pad's label lists.
    182   unsigned RangeIndex;
    183 };
    184 
    185 typedef DenseMap<MCSymbol*, PadRange> RangeMapType;
    186 
    187 /// CallSiteEntry - Structure describing an entry in the call-site table.
    188 struct CallSiteEntry {
    189   MCSymbol *BeginLabel; // zero indicates the start of the function.
    190   MCSymbol *EndLabel;   // zero indicates the end of the function.
    191   MCSymbol *PadLabel;   // zero indicates that there is no landing pad.
    192   unsigned Action;
    193 };
    194 
    195 }
    196 
    197 unsigned char* JITDwarfEmitter::EmitExceptionTable(MachineFunction* MF,
    198                                          unsigned char* StartFunction,
    199                                          unsigned char* EndFunction) const {
    200   assert(MMI && "MachineModuleInfo not registered!");
    201 
    202   // Map all labels and get rid of any dead landing pads.
    203   MMI->TidyLandingPads(JCE->getLabelLocations());
    204 
    205   const std::vector<const GlobalVariable *> &TypeInfos = MMI->getTypeInfos();
    206   const std::vector<unsigned> &FilterIds = MMI->getFilterIds();
    207   const std::vector<LandingPadInfo> &PadInfos = MMI->getLandingPads();
    208   if (PadInfos.empty()) return 0;
    209 
    210   // Sort the landing pads in order of their type ids.  This is used to fold
    211   // duplicate actions.
    212   SmallVector<const LandingPadInfo *, 64> LandingPads;
    213   LandingPads.reserve(PadInfos.size());
    214   for (unsigned i = 0, N = PadInfos.size(); i != N; ++i)
    215     LandingPads.push_back(&PadInfos[i]);
    216   std::sort(LandingPads.begin(), LandingPads.end(), PadLT);
    217 
    218   // Negative type ids index into FilterIds, positive type ids index into
    219   // TypeInfos.  The value written for a positive type id is just the type
    220   // id itself.  For a negative type id, however, the value written is the
    221   // (negative) byte offset of the corresponding FilterIds entry.  The byte
    222   // offset is usually equal to the type id, because the FilterIds entries
    223   // are written using a variable width encoding which outputs one byte per
    224   // entry as long as the value written is not too large, but can differ.
    225   // This kind of complication does not occur for positive type ids because
    226   // type infos are output using a fixed width encoding.
    227   // FilterOffsets[i] holds the byte offset corresponding to FilterIds[i].
    228   SmallVector<int, 16> FilterOffsets;
    229   FilterOffsets.reserve(FilterIds.size());
    230   int Offset = -1;
    231   for(std::vector<unsigned>::const_iterator I = FilterIds.begin(),
    232     E = FilterIds.end(); I != E; ++I) {
    233     FilterOffsets.push_back(Offset);
    234     Offset -= MCAsmInfo::getULEB128Size(*I);
    235   }
    236 
    237   // Compute the actions table and gather the first action index for each
    238   // landing pad site.
    239   SmallVector<ActionEntry, 32> Actions;
    240   SmallVector<unsigned, 64> FirstActions;
    241   FirstActions.reserve(LandingPads.size());
    242 
    243   int FirstAction = 0;
    244   unsigned SizeActions = 0;
    245   for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) {
    246     const LandingPadInfo *LP = LandingPads[i];
    247     const std::vector<int> &TypeIds = LP->TypeIds;
    248     const unsigned NumShared = i ? SharedTypeIds(LP, LandingPads[i-1]) : 0;
    249     unsigned SizeSiteActions = 0;
    250 
    251     if (NumShared < TypeIds.size()) {
    252       unsigned SizeAction = 0;
    253       ActionEntry *PrevAction = 0;
    254 
    255       if (NumShared) {
    256         const unsigned SizePrevIds = LandingPads[i-1]->TypeIds.size();
    257         assert(Actions.size());
    258         PrevAction = &Actions.back();
    259         SizeAction = MCAsmInfo::getSLEB128Size(PrevAction->NextAction) +
    260           MCAsmInfo::getSLEB128Size(PrevAction->ValueForTypeID);
    261         for (unsigned j = NumShared; j != SizePrevIds; ++j) {
    262           SizeAction -= MCAsmInfo::getSLEB128Size(PrevAction->ValueForTypeID);
    263           SizeAction += -PrevAction->NextAction;
    264           PrevAction = PrevAction->Previous;
    265         }
    266       }
    267 
    268       // Compute the actions.
    269       for (unsigned I = NumShared, M = TypeIds.size(); I != M; ++I) {
    270         int TypeID = TypeIds[I];
    271         assert(-1-TypeID < (int)FilterOffsets.size() && "Unknown filter id!");
    272         int ValueForTypeID = TypeID < 0 ? FilterOffsets[-1 - TypeID] : TypeID;
    273         unsigned SizeTypeID = MCAsmInfo::getSLEB128Size(ValueForTypeID);
    274 
    275         int NextAction = SizeAction ? -(SizeAction + SizeTypeID) : 0;
    276         SizeAction = SizeTypeID + MCAsmInfo::getSLEB128Size(NextAction);
    277         SizeSiteActions += SizeAction;
    278 
    279         ActionEntry Action = {ValueForTypeID, NextAction, PrevAction};
    280         Actions.push_back(Action);
    281 
    282         PrevAction = &Actions.back();
    283       }
    284 
    285       // Record the first action of the landing pad site.
    286       FirstAction = SizeActions + SizeSiteActions - SizeAction + 1;
    287     } // else identical - re-use previous FirstAction
    288 
    289     FirstActions.push_back(FirstAction);
    290 
    291     // Compute this sites contribution to size.
    292     SizeActions += SizeSiteActions;
    293   }
    294 
    295   // Compute the call-site table.  Entries must be ordered by address.
    296   SmallVector<CallSiteEntry, 64> CallSites;
    297 
    298   RangeMapType PadMap;
    299   for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) {
    300     const LandingPadInfo *LandingPad = LandingPads[i];
    301     for (unsigned j=0, E = LandingPad->BeginLabels.size(); j != E; ++j) {
    302       MCSymbol *BeginLabel = LandingPad->BeginLabels[j];
    303       assert(!PadMap.count(BeginLabel) && "Duplicate landing pad labels!");
    304       PadRange P = { i, j };
    305       PadMap[BeginLabel] = P;
    306     }
    307   }
    308 
    309   bool MayThrow = false;
    310   MCSymbol *LastLabel = 0;
    311   for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
    312         I != E; ++I) {
    313     for (MachineBasicBlock::const_iterator MI = I->begin(), E = I->end();
    314           MI != E; ++MI) {
    315       if (!MI->isLabel()) {
    316         MayThrow |= MI->isCall();
    317         continue;
    318       }
    319 
    320       MCSymbol *BeginLabel = MI->getOperand(0).getMCSymbol();
    321       assert(BeginLabel && "Invalid label!");
    322 
    323       if (BeginLabel == LastLabel)
    324         MayThrow = false;
    325 
    326       RangeMapType::iterator L = PadMap.find(BeginLabel);
    327 
    328       if (L == PadMap.end())
    329         continue;
    330 
    331       PadRange P = L->second;
    332       const LandingPadInfo *LandingPad = LandingPads[P.PadIndex];
    333 
    334       assert(BeginLabel == LandingPad->BeginLabels[P.RangeIndex] &&
    335               "Inconsistent landing pad map!");
    336 
    337       // If some instruction between the previous try-range and this one may
    338       // throw, create a call-site entry with no landing pad for the region
    339       // between the try-ranges.
    340       if (MayThrow) {
    341         CallSiteEntry Site = {LastLabel, BeginLabel, 0, 0};
    342         CallSites.push_back(Site);
    343       }
    344 
    345       LastLabel = LandingPad->EndLabels[P.RangeIndex];
    346       CallSiteEntry Site = {BeginLabel, LastLabel,
    347         LandingPad->LandingPadLabel, FirstActions[P.PadIndex]};
    348 
    349       assert(Site.BeginLabel && Site.EndLabel && Site.PadLabel &&
    350               "Invalid landing pad!");
    351 
    352       // Try to merge with the previous call-site.
    353       if (CallSites.size()) {
    354         CallSiteEntry &Prev = CallSites.back();
    355         if (Site.PadLabel == Prev.PadLabel && Site.Action == Prev.Action) {
    356           // Extend the range of the previous entry.
    357           Prev.EndLabel = Site.EndLabel;
    358           continue;
    359         }
    360       }
    361 
    362       // Otherwise, create a new call-site.
    363       CallSites.push_back(Site);
    364     }
    365   }
    366   // If some instruction between the previous try-range and the end of the
    367   // function may throw, create a call-site entry with no landing pad for the
    368   // region following the try-range.
    369   if (MayThrow) {
    370     CallSiteEntry Site = {LastLabel, 0, 0, 0};
    371     CallSites.push_back(Site);
    372   }
    373 
    374   // Final tallies.
    375   unsigned SizeSites = CallSites.size() * (sizeof(int32_t) + // Site start.
    376                                             sizeof(int32_t) + // Site length.
    377                                             sizeof(int32_t)); // Landing pad.
    378   for (unsigned i = 0, e = CallSites.size(); i < e; ++i)
    379     SizeSites += MCAsmInfo::getULEB128Size(CallSites[i].Action);
    380 
    381   unsigned SizeTypes = TypeInfos.size() * TD->getPointerSize();
    382 
    383   unsigned TypeOffset = sizeof(int8_t) + // Call site format
    384                         // Call-site table length
    385                         MCAsmInfo::getULEB128Size(SizeSites) +
    386                         SizeSites + SizeActions + SizeTypes;
    387 
    388   // Begin the exception table.
    389   JCE->emitAlignmentWithFill(4, 0);
    390   // Asm->EOL("Padding");
    391 
    392   unsigned char* DwarfExceptionTable = (unsigned char*)JCE->getCurrentPCValue();
    393 
    394   // Emit the header.
    395   JCE->emitByte(dwarf::DW_EH_PE_omit);
    396   // Asm->EOL("LPStart format (DW_EH_PE_omit)");
    397   JCE->emitByte(dwarf::DW_EH_PE_absptr);
    398   // Asm->EOL("TType format (DW_EH_PE_absptr)");
    399   JCE->emitULEB128Bytes(TypeOffset);
    400   // Asm->EOL("TType base offset");
    401   JCE->emitByte(dwarf::DW_EH_PE_udata4);
    402   // Asm->EOL("Call site format (DW_EH_PE_udata4)");
    403   JCE->emitULEB128Bytes(SizeSites);
    404   // Asm->EOL("Call-site table length");
    405 
    406   // Emit the landing pad site information.
    407   for (unsigned i = 0; i < CallSites.size(); ++i) {
    408     CallSiteEntry &S = CallSites[i];
    409     intptr_t BeginLabelPtr = 0;
    410     intptr_t EndLabelPtr = 0;
    411 
    412     if (!S.BeginLabel) {
    413       BeginLabelPtr = (intptr_t)StartFunction;
    414       JCE->emitInt32(0);
    415     } else {
    416       BeginLabelPtr = JCE->getLabelAddress(S.BeginLabel);
    417       JCE->emitInt32(BeginLabelPtr - (intptr_t)StartFunction);
    418     }
    419 
    420     // Asm->EOL("Region start");
    421 
    422     if (!S.EndLabel)
    423       EndLabelPtr = (intptr_t)EndFunction;
    424     else
    425       EndLabelPtr = JCE->getLabelAddress(S.EndLabel);
    426 
    427     JCE->emitInt32(EndLabelPtr - BeginLabelPtr);
    428     //Asm->EOL("Region length");
    429 
    430     if (!S.PadLabel) {
    431       JCE->emitInt32(0);
    432     } else {
    433       unsigned PadLabelPtr = JCE->getLabelAddress(S.PadLabel);
    434       JCE->emitInt32(PadLabelPtr - (intptr_t)StartFunction);
    435     }
    436     // Asm->EOL("Landing pad");
    437 
    438     JCE->emitULEB128Bytes(S.Action);
    439     // Asm->EOL("Action");
    440   }
    441 
    442   // Emit the actions.
    443   for (unsigned I = 0, N = Actions.size(); I != N; ++I) {
    444     ActionEntry &Action = Actions[I];
    445 
    446     JCE->emitSLEB128Bytes(Action.ValueForTypeID);
    447     //Asm->EOL("TypeInfo index");
    448     JCE->emitSLEB128Bytes(Action.NextAction);
    449     //Asm->EOL("Next action");
    450   }
    451 
    452   // Emit the type ids.
    453   for (unsigned M = TypeInfos.size(); M; --M) {
    454     const GlobalVariable *GV = TypeInfos[M - 1];
    455 
    456     if (GV) {
    457       if (TD->getPointerSize() == sizeof(int32_t))
    458         JCE->emitInt32((intptr_t)Jit.getOrEmitGlobalVariable(GV));
    459       else
    460         JCE->emitInt64((intptr_t)Jit.getOrEmitGlobalVariable(GV));
    461     } else {
    462       if (TD->getPointerSize() == sizeof(int32_t))
    463         JCE->emitInt32(0);
    464       else
    465         JCE->emitInt64(0);
    466     }
    467     // Asm->EOL("TypeInfo");
    468   }
    469 
    470   // Emit the filter typeids.
    471   for (unsigned j = 0, M = FilterIds.size(); j < M; ++j) {
    472     unsigned TypeID = FilterIds[j];
    473     JCE->emitULEB128Bytes(TypeID);
    474     //Asm->EOL("Filter TypeInfo index");
    475   }
    476 
    477   JCE->emitAlignmentWithFill(4, 0);
    478 
    479   return DwarfExceptionTable;
    480 }
    481 
    482 unsigned char*
    483 JITDwarfEmitter::EmitCommonEHFrame(const Function* Personality) const {
    484   unsigned PointerSize = TD->getPointerSize();
    485   int stackGrowth = stackGrowthDirection == TargetFrameLowering::StackGrowsUp ?
    486           PointerSize : -PointerSize;
    487 
    488   unsigned char* StartCommonPtr = (unsigned char*)JCE->getCurrentPCValue();
    489   // EH Common Frame header
    490   JCE->allocateSpace(4, 0);
    491   unsigned char* FrameCommonBeginPtr = (unsigned char*)JCE->getCurrentPCValue();
    492   JCE->emitInt32((int)0);
    493   JCE->emitByte(dwarf::DW_CIE_VERSION);
    494   JCE->emitString(Personality ? "zPLR" : "zR");
    495   JCE->emitULEB128Bytes(1);
    496   JCE->emitSLEB128Bytes(stackGrowth);
    497   JCE->emitByte(RI->getDwarfRegNum(RI->getRARegister(), true));
    498 
    499   if (Personality) {
    500     // Augmentation Size: 3 small ULEBs of one byte each, and the personality
    501     // function which size is PointerSize.
    502     JCE->emitULEB128Bytes(3 + PointerSize);
    503 
    504     // We set the encoding of the personality as direct encoding because we use
    505     // the function pointer. The encoding is not relative because the current
    506     // PC value may be bigger than the personality function pointer.
    507     if (PointerSize == 4) {
    508       JCE->emitByte(dwarf::DW_EH_PE_sdata4);
    509       JCE->emitInt32(((intptr_t)Jit.getPointerToGlobal(Personality)));
    510     } else {
    511       JCE->emitByte(dwarf::DW_EH_PE_sdata8);
    512       JCE->emitInt64(((intptr_t)Jit.getPointerToGlobal(Personality)));
    513     }
    514 
    515     // LSDA encoding: This must match the encoding used in EmitEHFrame ()
    516     if (PointerSize == 4)
    517       JCE->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4);
    518     else
    519       JCE->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8);
    520     JCE->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4);
    521   } else {
    522     JCE->emitULEB128Bytes(1);
    523     JCE->emitULEB128Bytes(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4);
    524   }
    525 
    526   EmitFrameMoves(0, MAI->getInitialFrameState());
    527 
    528   JCE->emitAlignmentWithFill(PointerSize, dwarf::DW_CFA_nop);
    529 
    530   JCE->emitInt32At((uintptr_t*)StartCommonPtr,
    531                    (uintptr_t)((unsigned char*)JCE->getCurrentPCValue() -
    532                                FrameCommonBeginPtr));
    533 
    534   return StartCommonPtr;
    535 }
    536 
    537 
    538 unsigned char*
    539 JITDwarfEmitter::EmitEHFrame(const Function* Personality,
    540                              unsigned char* StartCommonPtr,
    541                              unsigned char* StartFunction,
    542                              unsigned char* EndFunction,
    543                              unsigned char* ExceptionTable) const {
    544   unsigned PointerSize = TD->getPointerSize();
    545 
    546   // EH frame header.
    547   unsigned char* StartEHPtr = (unsigned char*)JCE->getCurrentPCValue();
    548   JCE->allocateSpace(4, 0);
    549   unsigned char* FrameBeginPtr = (unsigned char*)JCE->getCurrentPCValue();
    550   // FDE CIE Offset
    551   JCE->emitInt32(FrameBeginPtr - StartCommonPtr);
    552   JCE->emitInt32(StartFunction - (unsigned char*)JCE->getCurrentPCValue());
    553   JCE->emitInt32(EndFunction - StartFunction);
    554 
    555   // If there is a personality and landing pads then point to the language
    556   // specific data area in the exception table.
    557   if (Personality) {
    558     JCE->emitULEB128Bytes(PointerSize == 4 ? 4 : 8);
    559 
    560     if (PointerSize == 4) {
    561       if (!MMI->getLandingPads().empty())
    562         JCE->emitInt32(ExceptionTable-(unsigned char*)JCE->getCurrentPCValue());
    563       else
    564         JCE->emitInt32((int)0);
    565     } else {
    566       if (!MMI->getLandingPads().empty())
    567         JCE->emitInt64(ExceptionTable-(unsigned char*)JCE->getCurrentPCValue());
    568       else
    569         JCE->emitInt64((int)0);
    570     }
    571   } else {
    572     JCE->emitULEB128Bytes(0);
    573   }
    574 
    575   // Indicate locations of function specific  callee saved registers in
    576   // frame.
    577   EmitFrameMoves((intptr_t)StartFunction, MMI->getFrameMoves());
    578 
    579   JCE->emitAlignmentWithFill(PointerSize, dwarf::DW_CFA_nop);
    580 
    581   // Indicate the size of the table
    582   JCE->emitInt32At((uintptr_t*)StartEHPtr,
    583                    (uintptr_t)((unsigned char*)JCE->getCurrentPCValue() -
    584                                StartEHPtr));
    585 
    586   // Double zeroes for the unwind runtime
    587   if (PointerSize == 8) {
    588     JCE->emitInt64(0);
    589     JCE->emitInt64(0);
    590   } else {
    591     JCE->emitInt32(0);
    592     JCE->emitInt32(0);
    593   }
    594 
    595   return StartEHPtr;
    596 }
    597