17cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby//===- lib/MC/MCDwarf.cpp - MCDwarf implementation ------------------------===// 27cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby// 37cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby// The LLVM Compiler Infrastructure 47cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby// 57cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby// This file is distributed under the University of Illinois Open Source 67cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby// License. See LICENSE.TXT for details. 77cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby// 87cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby//===----------------------------------------------------------------------===// 97cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby 107cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby#include "llvm/MC/MCDwarf.h" 11d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/Hashing.h" 12dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "llvm/ADT/STLExtras.h" 13d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/SmallString.h" 14d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/Twine.h" 15d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Config/config.h" 16e76a33b9567d78a5744dc52fcec3a6056d6fb576Evan Cheng#include "llvm/MC/MCAsmInfo.h" 17e76a33b9567d78a5744dc52fcec3a6056d6fb576Evan Cheng#include "llvm/MC/MCContext.h" 18d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCExpr.h" 19e76a33b9567d78a5744dc52fcec3a6056d6fb576Evan Cheng#include "llvm/MC/MCObjectFileInfo.h" 20dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "llvm/MC/MCObjectStreamer.h" 21e76a33b9567d78a5744dc52fcec3a6056d6fb576Evan Cheng#include "llvm/MC/MCRegisterInfo.h" 22cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines#include "llvm/MC/MCSection.h" 23c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby#include "llvm/MC/MCSymbol.h" 247cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby#include "llvm/Support/Debug.h" 25fe024d0a624404ada11fb330e7360abc5f88742eRafael Espindola#include "llvm/Support/ErrorHandling.h" 262d39a0e52df9ce050bd4e2de3a2ecca8fd9a87c3Jim Grosbach#include "llvm/Support/LEB128.h" 2794c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby#include "llvm/Support/Path.h" 2894c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby#include "llvm/Support/SourceMgr.h" 29d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Support/raw_ostream.h" 307cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderbyusing namespace llvm; 317cbf73a73f296167b6e978dbd919ed249e88eeb5Kevin Enderby 32c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby// Given a special op, return the address skip amount (in units of 33c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby// DWARF2_LINE_MIN_INSN_LENGTH. 34c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby#define SPECIAL_ADDR(op) (((op) - DWARF2_LINE_OPCODE_BASE)/DWARF2_LINE_RANGE) 35c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby 36c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby// The maximum address skip amount that can be encoded with a special op. 37c3882164cbf794dbe21816a2946a31bc9e02a419Bill Wendling#define MAX_SPECIAL_ADDR_DELTA SPECIAL_ADDR(255) 38c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby 39c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby// First special line opcode - leave room for the standard opcodes. 40c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby// Note: If you want to change this, you'll have to update the 412684d9e3c702b2ef9fd430155d94671d12fa994fJim Grosbach// "standard_opcode_lengths" table that is emitted in DwarfFileTable::Emit(). 42c3882164cbf794dbe21816a2946a31bc9e02a419Bill Wendling#define DWARF2_LINE_OPCODE_BASE 13 43c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby 44c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby// Minimum line offset in a special line info. opcode. This value 45c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby// was chosen to give a reasonable range of values. 46c3882164cbf794dbe21816a2946a31bc9e02a419Bill Wendling#define DWARF2_LINE_BASE -5 47c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby 48c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby// Range of line offsets in a special line info. opcode. 49c3882164cbf794dbe21816a2946a31bc9e02a419Bill Wendling#define DWARF2_LINE_RANGE 14 50c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby 51c1f4a4b2640dfc871bacacef53a95f1c96a9fe48Ulrich Weigandstatic inline uint64_t ScaleAddrDelta(MCContext &Context, uint64_t AddrDelta) { 5299cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling unsigned MinInsnLength = Context.getAsmInfo()->getMinInstAlignment(); 53c1f4a4b2640dfc871bacacef53a95f1c96a9fe48Ulrich Weigand if (MinInsnLength == 1) 54c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby return AddrDelta; 55c1f4a4b2640dfc871bacacef53a95f1c96a9fe48Ulrich Weigand if (AddrDelta % MinInsnLength != 0) { 56c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby // TODO: report this error, but really only once. 57c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby ; 58c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby } 59c1f4a4b2640dfc871bacacef53a95f1c96a9fe48Ulrich Weigand return AddrDelta / MinInsnLength; 60c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby} 61c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby 62c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby// 63c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby// This is called when an instruction is assembled into the specified section 64c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby// and if there is information from the last .loc directive that has yet to have 65c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby// a line entry made for it is made. 66c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby// 67dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid MCLineEntry::Make(MCObjectStreamer *MCOS, const MCSection *Section) { 68c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby if (!MCOS->getContext().getDwarfLocSeen()) 69c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby return; 70c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby 71c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby // Create a symbol at in the current section for use in the line entry. 72c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby MCSymbol *LineSym = MCOS->getContext().CreateTempSymbol(); 73c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby // Set the value of the symbol to use for the MCLineEntry. 74c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby MCOS->EmitLabel(LineSym); 75c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby 76c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby // Get the current .loc info saved in the context. 77c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby const MCDwarfLoc &DwarfLoc = MCOS->getContext().getCurrentDwarfLoc(); 78c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby 79c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby // Create a (local) line entry with the symbol and the current .loc info. 80c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby MCLineEntry LineEntry(LineSym, DwarfLoc); 81c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby 82c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby // clear DwarfLocSeen saying the current .loc info is now used. 833f55c24df9527de345f6cc960944840a7a101c6aKevin Enderby MCOS->getContext().ClearDwarfLocSeen(); 84c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby 85c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby // Add the line entry to this section's entries. 8636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MCOS->getContext() 8736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines .getMCDwarfLineTable(MCOS->getContext().getDwarfCompileUnitID()) 8836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines .getMCLineSections() 8936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines .addLineEntry(LineEntry, Section); 90c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby} 91c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby 92c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby// 93c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby// This helper routine returns an expression of End - Start + IntVal . 942684d9e3c702b2ef9fd430155d94671d12fa994fJim Grosbach// 955fad7a99c00980fc30ce16fb51ce09dc435c40adRafael Espindolastatic inline const MCExpr *MakeStartMinusEndExpr(const MCStreamer &MCOS, 965fad7a99c00980fc30ce16fb51ce09dc435c40adRafael Espindola const MCSymbol &Start, 975fad7a99c00980fc30ce16fb51ce09dc435c40adRafael Espindola const MCSymbol &End, 985fad7a99c00980fc30ce16fb51ce09dc435c40adRafael Espindola int IntVal) { 99c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None; 100c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby const MCExpr *Res = 1015fad7a99c00980fc30ce16fb51ce09dc435c40adRafael Espindola MCSymbolRefExpr::Create(&End, Variant, MCOS.getContext()); 102c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby const MCExpr *RHS = 1035fad7a99c00980fc30ce16fb51ce09dc435c40adRafael Espindola MCSymbolRefExpr::Create(&Start, Variant, MCOS.getContext()); 104c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby const MCExpr *Res1 = 1055fad7a99c00980fc30ce16fb51ce09dc435c40adRafael Espindola MCBinaryExpr::Create(MCBinaryExpr::Sub, Res, RHS, MCOS.getContext()); 106c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby const MCExpr *Res2 = 1075fad7a99c00980fc30ce16fb51ce09dc435c40adRafael Espindola MCConstantExpr::Create(IntVal, MCOS.getContext()); 108c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby const MCExpr *Res3 = 1095fad7a99c00980fc30ce16fb51ce09dc435c40adRafael Espindola MCBinaryExpr::Create(MCBinaryExpr::Sub, Res1, Res2, MCOS.getContext()); 110c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby return Res3; 111c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby} 112c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby 113c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby// 114c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby// This emits the Dwarf line table for the specified section from the entries 115c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby// in the LineSection. 116c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby// 11736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic inline void 118dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesEmitDwarfLineTable(MCObjectStreamer *MCOS, const MCSection *Section, 11936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCLineSection::MCLineEntryCollection &LineEntries) { 120c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby unsigned FileNum = 1; 121c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby unsigned LastLine = 1; 122c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby unsigned Column = 0; 123c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby unsigned Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0; 124c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby unsigned Isa = 0; 12536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned Discriminator = 0; 126dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MCSymbol *LastLabel = nullptr; 127c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby 128c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby // Loop through each MCLineEntry and encode the dwarf line number table. 12936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (auto it = LineEntries.begin(), 13036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ie = LineEntries.end(); 13136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines it != ie; ++it) { 132c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby 133c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby if (FileNum != it->getFileNum()) { 134c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby FileNum = it->getFileNum(); 135c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby MCOS->EmitIntValue(dwarf::DW_LNS_set_file, 1); 1363ff57094a7d176a759ddb1e1668489d89064f56cRafael Espindola MCOS->EmitULEB128IntValue(FileNum); 137c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby } 138c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby if (Column != it->getColumn()) { 139c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby Column = it->getColumn(); 140c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby MCOS->EmitIntValue(dwarf::DW_LNS_set_column, 1); 1413ff57094a7d176a759ddb1e1668489d89064f56cRafael Espindola MCOS->EmitULEB128IntValue(Column); 142c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby } 14336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Discriminator != it->getDiscriminator()) { 14436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Discriminator = it->getDiscriminator(); 14536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned Size = getULEB128Size(Discriminator); 14636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MCOS->EmitIntValue(dwarf::DW_LNS_extended_op, 1); 14736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MCOS->EmitULEB128IntValue(Size + 1); 14836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MCOS->EmitIntValue(dwarf::DW_LNE_set_discriminator, 1); 14936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MCOS->EmitULEB128IntValue(Discriminator); 15036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 151c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby if (Isa != it->getIsa()) { 152c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby Isa = it->getIsa(); 153c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby MCOS->EmitIntValue(dwarf::DW_LNS_set_isa, 1); 1543ff57094a7d176a759ddb1e1668489d89064f56cRafael Espindola MCOS->EmitULEB128IntValue(Isa); 155c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby } 156c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby if ((it->getFlags() ^ Flags) & DWARF2_FLAG_IS_STMT) { 157c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby Flags = it->getFlags(); 158c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby MCOS->EmitIntValue(dwarf::DW_LNS_negate_stmt, 1); 159c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby } 160c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby if (it->getFlags() & DWARF2_FLAG_BASIC_BLOCK) 161c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby MCOS->EmitIntValue(dwarf::DW_LNS_set_basic_block, 1); 162c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby if (it->getFlags() & DWARF2_FLAG_PROLOGUE_END) 163c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby MCOS->EmitIntValue(dwarf::DW_LNS_set_prologue_end, 1); 164c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby if (it->getFlags() & DWARF2_FLAG_EPILOGUE_BEGIN) 165c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby MCOS->EmitIntValue(dwarf::DW_LNS_set_epilogue_begin, 1); 166c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby 16764185cc6090f695c4f97c51cf2adc731f56d1a20Rafael Espindola int64_t LineDelta = static_cast<int64_t>(it->getLine()) - LastLine; 168c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby MCSymbol *Label = it->getLabel(); 169c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby 170c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby // At this point we want to emit/create the sequence to encode the delta in 171c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby // line numbers and the increment of the address from the previous Label 172c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby // and the current Label. 17399cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling const MCAsmInfo *asmInfo = MCOS->getContext().getAsmInfo(); 174672b93a3324cc1da6d374eed4c75c050a9cad7beEvan Cheng MCOS->EmitDwarfAdvanceLineAddr(LineDelta, LastLabel, Label, 17599cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling asmInfo->getPointerSize()); 176c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby 177c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby LastLine = it->getLine(); 178c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby LastLabel = Label; 179c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby } 180c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby 181c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby // Emit a DW_LNE_end_sequence for the end of the section. 182c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby // Using the pointer Section create a temporary label at the end of the 183c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby // section and use that and the LastLabel to compute the address delta 184c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby // and use INT64_MAX as the line delta which is the signal that this is 185c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby // actually a DW_LNE_end_sequence. 186c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby 187c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby // Switch to the section to be able to create a symbol at its end. 188df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne // TODO: keep track of the last subsection so that this symbol appears in the 189df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne // correct place. 190c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby MCOS->SwitchSection(Section); 19189b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola 19289b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola MCContext &context = MCOS->getContext(); 193c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby // Create a symbol at the end of the section. 19489b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola MCSymbol *SectionEnd = context.CreateTempSymbol(); 195c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby // Set the value of the symbol, as we are at the end of the section. 196c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby MCOS->EmitLabel(SectionEnd); 197c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby 198c8e41c591741b3da1077f7000274ad040bef8002Sylvestre Ledru // Switch back the dwarf line section. 199e76a33b9567d78a5744dc52fcec3a6056d6fb576Evan Cheng MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfLineSection()); 200195a0ce484cd12a5adae9184188f6d0fb52b84c0Rafael Espindola 20199cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling const MCAsmInfo *asmInfo = MCOS->getContext().getAsmInfo(); 202672b93a3324cc1da6d374eed4c75c050a9cad7beEvan Cheng MCOS->EmitDwarfAdvanceLineAddr(INT64_MAX, LastLabel, SectionEnd, 20399cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling asmInfo->getPointerSize()); 204c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby} 205c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby 206c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby// 207c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby// This emits the Dwarf file and the line tables. 208c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby// 209dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid MCDwarfLineTable::Emit(MCObjectStreamer *MCOS) { 21089b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola MCContext &context = MCOS->getContext(); 21136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 21236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines auto &LineTables = context.getMCDwarfLineTables(); 21336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 21436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Bail out early so we don't switch to the debug_line section needlessly and 21536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // in doing so create an unnecessary (if empty) section. 21636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (LineTables.empty()) 21736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 21836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 219c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby // Switch to the section where the table will be emitted into. 220e76a33b9567d78a5744dc52fcec3a6056d6fb576Evan Cheng MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfLineSection()); 221c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby 22243213cf1ac05b4198fcf9fa85d7da85477daafd1Manman Ren // Handle the rest of the Compile Units. 22336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (const auto &CUIDTablePair : LineTables) 22436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines CUIDTablePair.second.EmitCU(MCOS); 22536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 22636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 22736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid MCDwarfDwoLineTable::Emit(MCStreamer &MCOS) const { 22836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MCOS.EmitLabel(Header.Emit(&MCOS, None).second); 22936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 23036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 23136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstd::pair<MCSymbol *, MCSymbol *> MCDwarfLineTableHeader::Emit(MCStreamer *MCOS) const { 23236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines static const char StandardOpcodeLengths[] = { 23336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 0, // length of DW_LNS_copy 23436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 1, // length of DW_LNS_advance_pc 23536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 1, // length of DW_LNS_advance_line 23636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 1, // length of DW_LNS_set_file 23736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 1, // length of DW_LNS_set_column 23836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 0, // length of DW_LNS_negate_stmt 23936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 0, // length of DW_LNS_set_basic_block 24036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 0, // length of DW_LNS_const_add_pc 24136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 1, // length of DW_LNS_fixed_advance_pc 24236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 0, // length of DW_LNS_set_prologue_end 24336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 0, // length of DW_LNS_set_epilogue_begin 24436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 1 // DW_LNS_set_isa 24536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines }; 24636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(array_lengthof(StandardOpcodeLengths) == (DWARF2_LINE_OPCODE_BASE - 1)); 24736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return Emit(MCOS, StandardOpcodeLengths); 24843213cf1ac05b4198fcf9fa85d7da85477daafd1Manman Ren} 24943213cf1ac05b4198fcf9fa85d7da85477daafd1Manman Ren 25036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstd::pair<MCSymbol *, MCSymbol *> 25136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesMCDwarfLineTableHeader::Emit(MCStreamer *MCOS, 25236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ArrayRef<char> StandardOpcodeLengths) const { 25336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 25443213cf1ac05b4198fcf9fa85d7da85477daafd1Manman Ren MCContext &context = MCOS->getContext(); 25543213cf1ac05b4198fcf9fa85d7da85477daafd1Manman Ren 25643213cf1ac05b4198fcf9fa85d7da85477daafd1Manman Ren // Create a symbol at the beginning of the line table. 25736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MCSymbol *LineStartSym = Label; 25843213cf1ac05b4198fcf9fa85d7da85477daafd1Manman Ren if (!LineStartSym) 25943213cf1ac05b4198fcf9fa85d7da85477daafd1Manman Ren LineStartSym = context.CreateTempSymbol(); 26043213cf1ac05b4198fcf9fa85d7da85477daafd1Manman Ren // Set the value of the symbol, as we are at the start of the line table. 261c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby MCOS->EmitLabel(LineStartSym); 262c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby 263c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby // Create a symbol for the end of the section (to be set when we get there). 26489b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola MCSymbol *LineEndSym = context.CreateTempSymbol(); 265c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby 266c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby // The first 4 bytes is the total length of the information for this 267c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby // compilation unit (not including these 4 bytes for the length). 2685fad7a99c00980fc30ce16fb51ce09dc435c40adRafael Espindola MCOS->EmitAbsValue(MakeStartMinusEndExpr(*MCOS, *LineStartSym, *LineEndSym,4), 2690bbe0b440ee2cef47dcb7b281825eb70341c16ddRafael Espindola 4); 270c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby 271c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby // Next 2 bytes is the Version, which is Dwarf 2. 272c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby MCOS->EmitIntValue(2, 2); 273c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby 274c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby // Create a symbol for the end of the prologue (to be set when we get there). 27589b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola MCSymbol *ProEndSym = context.CreateTempSymbol(); // Lprologue_end 276c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby 277c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby // Length of the prologue, is the next 4 bytes. Which is the start of the 278c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby // section to the end of the prologue. Not including the 4 bytes for the 279c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby // total length, the 2 bytes for the version, and these 4 bytes for the 280c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby // length of the prologue. 2815fad7a99c00980fc30ce16fb51ce09dc435c40adRafael Espindola MCOS->EmitAbsValue(MakeStartMinusEndExpr(*MCOS, *LineStartSym, *ProEndSym, 282a3863ea2dacafc925a8272ebf9884fc64bef686cRafael Espindola (4 + 2 + 4)), 4); 283c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby 284c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby // Parameters of the state machine, are next. 28599cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling MCOS->EmitIntValue(context.getAsmInfo()->getMinInstAlignment(), 1); 286c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby MCOS->EmitIntValue(DWARF2_LINE_DEFAULT_IS_STMT, 1); 287c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby MCOS->EmitIntValue(DWARF2_LINE_BASE, 1); 288c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby MCOS->EmitIntValue(DWARF2_LINE_RANGE, 1); 28936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MCOS->EmitIntValue(StandardOpcodeLengths.size() + 1, 1); 290c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby 291c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby // Standard opcode lengths 29236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (char Length : StandardOpcodeLengths) 29336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MCOS->EmitIntValue(Length, 1); 294c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby 295c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby // Put out the directory and file tables. 296c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby 297c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby // First the directory table. 298c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby for (unsigned i = 0; i < MCDwarfDirs.size(); i++) { 29968ca56285f9b6e82eb16ff8ea02a301f2c489faeEric Christopher MCOS->EmitBytes(MCDwarfDirs[i]); // the DirectoryName 30068ca56285f9b6e82eb16ff8ea02a301f2c489faeEric Christopher MCOS->EmitBytes(StringRef("\0", 1)); // the null term. of the string 301c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby } 302c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby MCOS->EmitIntValue(0, 1); // Terminate the directory list 303c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby 304c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby // Second the file table. 305c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby for (unsigned i = 1; i < MCDwarfFiles.size(); i++) { 30636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(!MCDwarfFiles[i].Name.empty()); 30736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MCOS->EmitBytes(MCDwarfFiles[i].Name); // FileName 30868ca56285f9b6e82eb16ff8ea02a301f2c489faeEric Christopher MCOS->EmitBytes(StringRef("\0", 1)); // the null term. of the string 3093ff57094a7d176a759ddb1e1668489d89064f56cRafael Espindola // the Directory num 31036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MCOS->EmitULEB128IntValue(MCDwarfFiles[i].DirIndex); 311c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby MCOS->EmitIntValue(0, 1); // last modification timestamp (always 0) 312c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby MCOS->EmitIntValue(0, 1); // filesize (always 0) 313c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby } 314c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby MCOS->EmitIntValue(0, 1); // Terminate the file list 315c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby 316c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby // This is the end of the prologue, so set the value of the symbol at the 317c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby // end of the prologue (that was used in a previous expression). 318c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby MCOS->EmitLabel(ProEndSym); 319c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby 32036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return std::make_pair(LineStartSym, LineEndSym); 32136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 32236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 323dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid MCDwarfLineTable::EmitCU(MCObjectStreamer *MCOS) const { 32436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MCSymbol *LineEndSym = Header.Emit(MCOS).second; 32536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 326c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby // Put out the line tables. 32736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (const auto &LineSec : MCLineSections.getMCLineEntries()) 32836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EmitDwarfLineTable(MCOS, LineSec.first, LineSec.second); 329c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby 33036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (MCOS->getContext().getAsmInfo()->getLinkerRequiresNonEmptyDwarfLines() && 33136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MCLineSections.getMCLineEntries().empty()) { 332a8de83c68aaa03cafa0e3618fb8bf030b48f6540Rafael Espindola // The darwin9 linker has a bug (see PR8715). For for 32-bit architectures 3332684d9e3c702b2ef9fd430155d94671d12fa994fJim Grosbach // it requires: 334a8de83c68aaa03cafa0e3618fb8bf030b48f6540Rafael Espindola // total_length >= prologue_length + 10 335a8de83c68aaa03cafa0e3618fb8bf030b48f6540Rafael Espindola // We are 4 bytes short, since we have total_length = 51 and 336a8de83c68aaa03cafa0e3618fb8bf030b48f6540Rafael Espindola // prologue_length = 45 337a8de83c68aaa03cafa0e3618fb8bf030b48f6540Rafael Espindola 338a8de83c68aaa03cafa0e3618fb8bf030b48f6540Rafael Espindola // The regular end_sequence should be sufficient. 339a8de83c68aaa03cafa0e3618fb8bf030b48f6540Rafael Espindola MCDwarfLineAddr::Emit(MCOS, INT64_MAX, 0); 3405113cdbfff7df4c7a79a92e5aa971126254202c6Devang Patel } 3415113cdbfff7df4c7a79a92e5aa971126254202c6Devang Patel 342c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby // This is the end of the section, so set the value of the symbol at the end 343c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby // of this section (that was used in a previous expression). 344c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby MCOS->EmitLabel(LineEndSym); 34536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 346489d67927172941bf59b9f4829ab8910814fea24Rafael Espindola 34736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesunsigned MCDwarfLineTable::getFile(StringRef &Directory, StringRef &FileName, 34836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned FileNumber) { 34936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return Header.getFile(Directory, FileName, FileNumber); 35036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 35136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 35236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesunsigned MCDwarfLineTableHeader::getFile(StringRef &Directory, 35336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines StringRef &FileName, 35436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned FileNumber) { 35536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Directory == CompilationDir) 35636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Directory = ""; 35736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (FileName.empty()) { 35836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines FileName = "<stdin>"; 35936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Directory = ""; 36036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 36136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(!FileName.empty()); 36236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (FileNumber == 0) { 36336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines FileNumber = SourceIdMap.size() + 1; 36436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert((MCDwarfFiles.empty() || FileNumber == MCDwarfFiles.size()) && 36536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines "Don't mix autonumbered and explicit numbered line table usage"); 36636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines StringMapEntry<unsigned> &Ent = SourceIdMap.GetOrCreateValue( 36736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines (Directory + Twine('\0') + FileName).str(), FileNumber); 36836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Ent.getValue() != FileNumber) 36936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return Ent.getValue(); 37036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 37136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Make space for this FileNumber in the MCDwarfFiles vector if needed. 37236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MCDwarfFiles.resize(FileNumber + 1); 37336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 37436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Get the new MCDwarfFile slot for this FileNumber. 37536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MCDwarfFile &File = MCDwarfFiles[FileNumber]; 37636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 37736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // It is an error to use see the same number more than once. 37836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!File.Name.empty()) 37936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return 0; 38036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 38136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Directory.empty()) { 38236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Separate the directory part from the basename of the FileName. 38336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines StringRef tFileName = sys::path::filename(FileName); 38436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!tFileName.empty()) { 38536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Directory = sys::path::parent_path(FileName); 38636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!Directory.empty()) 38736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines FileName = tFileName; 38836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 38936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 39036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 39136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Find or make an entry in the MCDwarfDirs vector for this Directory. 39236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Capture directory name. 39336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned DirIndex; 39436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Directory.empty()) { 39536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // For FileNames with no directories a DirIndex of 0 is used. 39636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DirIndex = 0; 39736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else { 39836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DirIndex = 0; 39936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (unsigned End = MCDwarfDirs.size(); DirIndex < End; DirIndex++) { 40036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Directory == MCDwarfDirs[DirIndex]) 40136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 40236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 40336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (DirIndex >= MCDwarfDirs.size()) 40436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MCDwarfDirs.push_back(Directory); 40536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // The DirIndex is one based, as DirIndex of 0 is used for FileNames with 40636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // no directories. MCDwarfDirs[] is unlike MCDwarfFiles[] in that the 40736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // directory names are stored at MCDwarfDirs[DirIndex-1] where FileNames 40836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // are stored at MCDwarfFiles[FileNumber].Name . 40936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DirIndex++; 41036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 41136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 41236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines File.Name = FileName; 41336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines File.DirIndex = DirIndex; 41436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 41536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // return the allocated FileNumber. 41636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return FileNumber; 417c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby} 418c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby 419c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby/// Utility function to emit the encoding to a streamer. 420195a0ce484cd12a5adae9184188f6d0fb52b84c0Rafael Espindolavoid MCDwarfLineAddr::Emit(MCStreamer *MCOS, int64_t LineDelta, 421c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby uint64_t AddrDelta) { 422c1f4a4b2640dfc871bacacef53a95f1c96a9fe48Ulrich Weigand MCContext &Context = MCOS->getContext(); 423c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby SmallString<256> Tmp; 424c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby raw_svector_ostream OS(Tmp); 425c1f4a4b2640dfc871bacacef53a95f1c96a9fe48Ulrich Weigand MCDwarfLineAddr::Encode(Context, LineDelta, AddrDelta, OS); 42668ca56285f9b6e82eb16ff8ea02a301f2c489faeEric Christopher MCOS->EmitBytes(OS.str()); 427c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby} 428c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby 429c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby/// Utility function to encode a Dwarf pair of LineDelta and AddrDeltas. 430c1f4a4b2640dfc871bacacef53a95f1c96a9fe48Ulrich Weigandvoid MCDwarfLineAddr::Encode(MCContext &Context, int64_t LineDelta, 431c1f4a4b2640dfc871bacacef53a95f1c96a9fe48Ulrich Weigand uint64_t AddrDelta, raw_ostream &OS) { 432c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby uint64_t Temp, Opcode; 433c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby bool NeedCopy = false; 434c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby 435c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby // Scale the address delta by the minimum instruction length. 436c1f4a4b2640dfc871bacacef53a95f1c96a9fe48Ulrich Weigand AddrDelta = ScaleAddrDelta(Context, AddrDelta); 437c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby 438c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby // A LineDelta of INT64_MAX is a signal that this is actually a 4392684d9e3c702b2ef9fd430155d94671d12fa994fJim Grosbach // DW_LNE_end_sequence. We cannot use special opcodes here, since we want the 440c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby // end_sequence to emit the matrix entry. 441c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby if (LineDelta == INT64_MAX) { 442c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby if (AddrDelta == MAX_SPECIAL_ADDR_DELTA) 443c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby OS << char(dwarf::DW_LNS_const_add_pc); 444c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby else { 445c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby OS << char(dwarf::DW_LNS_advance_pc); 4462d39a0e52df9ce050bd4e2de3a2ecca8fd9a87c3Jim Grosbach encodeULEB128(AddrDelta, OS); 447c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby } 448c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby OS << char(dwarf::DW_LNS_extended_op); 449c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby OS << char(1); 450c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby OS << char(dwarf::DW_LNE_end_sequence); 451c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby return; 452c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby } 453c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby 454c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby // Bias the line delta by the base. 455c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby Temp = LineDelta - DWARF2_LINE_BASE; 456c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby 457c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby // If the line increment is out of range of a special opcode, we must encode 458c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby // it with DW_LNS_advance_line. 459c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby if (Temp >= DWARF2_LINE_RANGE) { 460c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby OS << char(dwarf::DW_LNS_advance_line); 4612d39a0e52df9ce050bd4e2de3a2ecca8fd9a87c3Jim Grosbach encodeSLEB128(LineDelta, OS); 462c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby 463c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby LineDelta = 0; 464c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby Temp = 0 - DWARF2_LINE_BASE; 465c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby NeedCopy = true; 466c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby } 467c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby 468c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby // Use DW_LNS_copy instead of a "line +0, addr +0" special opcode. 469c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby if (LineDelta == 0 && AddrDelta == 0) { 470c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby OS << char(dwarf::DW_LNS_copy); 471c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby return; 472c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby } 473c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby 474c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby // Bias the opcode by the special opcode base. 475c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby Temp += DWARF2_LINE_OPCODE_BASE; 476c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby 477c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby // Avoid overflow when addr_delta is large. 478c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby if (AddrDelta < 256 + MAX_SPECIAL_ADDR_DELTA) { 479c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby // Try using a special opcode. 480c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby Opcode = Temp + AddrDelta * DWARF2_LINE_RANGE; 481c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby if (Opcode <= 255) { 482c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby OS << char(Opcode); 483c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby return; 484c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby } 485c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby 486c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby // Try using DW_LNS_const_add_pc followed by special op. 487c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby Opcode = Temp + (AddrDelta - MAX_SPECIAL_ADDR_DELTA) * DWARF2_LINE_RANGE; 488c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby if (Opcode <= 255) { 489c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby OS << char(dwarf::DW_LNS_const_add_pc); 490c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby OS << char(Opcode); 491c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby return; 492c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby } 493c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby } 494c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby 495c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby // Otherwise use DW_LNS_advance_pc. 496c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby OS << char(dwarf::DW_LNS_advance_pc); 4972d39a0e52df9ce050bd4e2de3a2ecca8fd9a87c3Jim Grosbach encodeULEB128(AddrDelta, OS); 498c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby 499c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby if (NeedCopy) 500c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby OS << char(dwarf::DW_LNS_copy); 501c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby else 502c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby OS << char(Temp); 503c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby} 504c095793b4ab027181605c79c9808df12afe45d63Kevin Enderby 50594c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby// Utility function to write a tuple for .debug_abbrev. 50694c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderbystatic void EmitAbbrev(MCStreamer *MCOS, uint64_t Name, uint64_t Form) { 50794c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby MCOS->EmitULEB128IntValue(Name); 50894c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby MCOS->EmitULEB128IntValue(Form); 50994c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby} 51094c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby 51194c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby// When generating dwarf for assembly source files this emits 51294c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby// the data for .debug_abbrev section which contains three DIEs. 51394c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderbystatic void EmitGenDwarfAbbrev(MCStreamer *MCOS) { 51494c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby MCContext &context = MCOS->getContext(); 51594c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfAbbrevSection()); 51694c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby 51794c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby // DW_TAG_compile_unit DIE abbrev (1). 51894c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby MCOS->EmitULEB128IntValue(1); 51994c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby MCOS->EmitULEB128IntValue(dwarf::DW_TAG_compile_unit); 52094c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby MCOS->EmitIntValue(dwarf::DW_CHILDREN_yes, 1); 52194c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby EmitAbbrev(MCOS, dwarf::DW_AT_stmt_list, dwarf::DW_FORM_data4); 522cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (MCOS->getContext().getGenDwarfSectionSyms().size() > 1) { 523cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines EmitAbbrev(MCOS, dwarf::DW_AT_ranges, dwarf::DW_FORM_data4); 524cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } else { 525cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines EmitAbbrev(MCOS, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr); 526cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines EmitAbbrev(MCOS, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr); 527cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 52894c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby EmitAbbrev(MCOS, dwarf::DW_AT_name, dwarf::DW_FORM_string); 52936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!context.getCompilationDir().empty()) 53036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EmitAbbrev(MCOS, dwarf::DW_AT_comp_dir, dwarf::DW_FORM_string); 53194c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby StringRef DwarfDebugFlags = context.getDwarfDebugFlags(); 53294c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby if (!DwarfDebugFlags.empty()) 53394c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby EmitAbbrev(MCOS, dwarf::DW_AT_APPLE_flags, dwarf::DW_FORM_string); 53494c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby EmitAbbrev(MCOS, dwarf::DW_AT_producer, dwarf::DW_FORM_string); 53594c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby EmitAbbrev(MCOS, dwarf::DW_AT_language, dwarf::DW_FORM_data2); 53694c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby EmitAbbrev(MCOS, 0, 0); 53794c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby 53838fdb7d9fc40e9f29c3156b6625cac8d91d562e1Kevin Enderby // DW_TAG_label DIE abbrev (2). 53994c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby MCOS->EmitULEB128IntValue(2); 54038fdb7d9fc40e9f29c3156b6625cac8d91d562e1Kevin Enderby MCOS->EmitULEB128IntValue(dwarf::DW_TAG_label); 54194c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby MCOS->EmitIntValue(dwarf::DW_CHILDREN_yes, 1); 54294c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby EmitAbbrev(MCOS, dwarf::DW_AT_name, dwarf::DW_FORM_string); 54394c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby EmitAbbrev(MCOS, dwarf::DW_AT_decl_file, dwarf::DW_FORM_data4); 54494c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby EmitAbbrev(MCOS, dwarf::DW_AT_decl_line, dwarf::DW_FORM_data4); 54594c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby EmitAbbrev(MCOS, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr); 54694c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby EmitAbbrev(MCOS, dwarf::DW_AT_prototyped, dwarf::DW_FORM_flag); 54794c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby EmitAbbrev(MCOS, 0, 0); 54894c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby 54994c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby // DW_TAG_unspecified_parameters DIE abbrev (3). 55094c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby MCOS->EmitULEB128IntValue(3); 55194c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby MCOS->EmitULEB128IntValue(dwarf::DW_TAG_unspecified_parameters); 55294c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby MCOS->EmitIntValue(dwarf::DW_CHILDREN_no, 1); 55394c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby EmitAbbrev(MCOS, 0, 0); 55494c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby 55594c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby // Terminate the abbreviations for this compilation unit. 55694c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby MCOS->EmitIntValue(0, 1); 55794c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby} 55894c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby 55994c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby// When generating dwarf for assembly source files this emits the data for 560cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines// .debug_aranges section. This section contains a header and a table of pairs 561cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines// of PointerSize'ed values for the address and size of section(s) with line 562cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines// table entries. 56315ab115df57949fa55d92ffdfba491f7d02ed60fAlexey Samsonovstatic void EmitGenDwarfAranges(MCStreamer *MCOS, 56415ab115df57949fa55d92ffdfba491f7d02ed60fAlexey Samsonov const MCSymbol *InfoSectionSymbol) { 56594c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby MCContext &context = MCOS->getContext(); 56694c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby 567cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines auto &Sections = context.getGenDwarfSectionSyms(); 56894c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby 56994c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfARangesSection()); 57094c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby 57194c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby // This will be the length of the .debug_aranges section, first account for 57294c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby // the size of each item in the header (see below where we emit these items). 57394c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby int Length = 4 + 2 + 4 + 1 + 1; 57494c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby 57594c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby // Figure the padding after the header before the table of address and size 57694c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby // pairs who's values are PointerSize'ed. 57799cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling const MCAsmInfo *asmInfo = context.getAsmInfo(); 57899cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling int AddrSize = asmInfo->getPointerSize(); 57994c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby int Pad = 2 * AddrSize - (Length & (2 * AddrSize - 1)); 58094c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby if (Pad == 2 * AddrSize) 58194c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby Pad = 0; 58294c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby Length += Pad; 58394c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby 58494c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby // Add the size of the pair of PointerSize'ed values for the address and size 585cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // of each section we have in the table. 586cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Length += 2 * AddrSize * Sections.size(); 58794c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby // And the pair of terminating zeros. 58894c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby Length += 2 * AddrSize; 58994c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby 59094c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby 59194c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby // Emit the header for this section. 59294c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby // The 4 byte length not including the 4 byte value for the length. 59394c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby MCOS->EmitIntValue(Length - 4, 4); 59494c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby // The 2 byte version, which is 2. 59594c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby MCOS->EmitIntValue(2, 2); 59694c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby // The 4 byte offset to the compile unit in the .debug_info from the start 59715ab115df57949fa55d92ffdfba491f7d02ed60fAlexey Samsonov // of the .debug_info. 59815ab115df57949fa55d92ffdfba491f7d02ed60fAlexey Samsonov if (InfoSectionSymbol) 59915ab115df57949fa55d92ffdfba491f7d02ed60fAlexey Samsonov MCOS->EmitSymbolValue(InfoSectionSymbol, 4); 60015ab115df57949fa55d92ffdfba491f7d02ed60fAlexey Samsonov else 60115ab115df57949fa55d92ffdfba491f7d02ed60fAlexey Samsonov MCOS->EmitIntValue(0, 4); 60294c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby // The 1 byte size of an address. 60394c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby MCOS->EmitIntValue(AddrSize, 1); 60494c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby // The 1 byte size of a segment descriptor, we use a value of zero. 60594c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby MCOS->EmitIntValue(0, 1); 60694c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby // Align the header with the padding if needed, before we put out the table. 60794c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby for(int i = 0; i < Pad; i++) 60894c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby MCOS->EmitIntValue(0, 1); 60994c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby 610cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Now emit the table of pairs of PointerSize'ed values for the section 611cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // addresses and sizes. 612cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines for (const auto &sec : Sections) { 613cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MCSymbol *StartSymbol = sec.second.first; 614cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MCSymbol *EndSymbol = sec.second.second; 615cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines assert(StartSymbol && "StartSymbol must not be NULL"); 616cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines assert(EndSymbol && "EndSymbol must not be NULL"); 617cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 618cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines const MCExpr *Addr = MCSymbolRefExpr::Create( 619cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines StartSymbol, MCSymbolRefExpr::VK_None, context); 620cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines const MCExpr *Size = MakeStartMinusEndExpr(*MCOS, 621cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines *StartSymbol, *EndSymbol, 0); 622cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MCOS->EmitValue(Addr, AddrSize); 623cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MCOS->EmitAbsValue(Size, AddrSize); 624cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 62594c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby 62694c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby // And finally the pair of terminating zeros. 62794c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby MCOS->EmitIntValue(0, AddrSize); 62894c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby MCOS->EmitIntValue(0, AddrSize); 62994c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby} 63094c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby 63194c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby// When generating dwarf for assembly source files this emits the data for 63294c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby// .debug_info section which contains three parts. The header, the compile_unit 63338fdb7d9fc40e9f29c3156b6625cac8d91d562e1Kevin Enderby// DIE and a list of label DIEs. 634489d67927172941bf59b9f4829ab8910814fea24Rafael Espindolastatic void EmitGenDwarfInfo(MCStreamer *MCOS, 635489d67927172941bf59b9f4829ab8910814fea24Rafael Espindola const MCSymbol *AbbrevSectionSymbol, 636cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines const MCSymbol *LineSectionSymbol, 637cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines const MCSymbol *RangesSectionSymbol) { 63894c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby MCContext &context = MCOS->getContext(); 63994c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby 6402684d9e3c702b2ef9fd430155d94671d12fa994fJim Grosbach MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfInfoSection()); 64194c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby 64294c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby // Create a symbol at the start and end of this section used in here for the 64394c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby // expression to calculate the length in the header. 64494c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby MCSymbol *InfoStart = context.CreateTempSymbol(); 64594c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby MCOS->EmitLabel(InfoStart); 64694c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby MCSymbol *InfoEnd = context.CreateTempSymbol(); 64794c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby 64894c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby // First part: the header. 64994c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby 65094c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby // The 4 byte total length of the information for this compilation unit, not 65194c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby // including these 4 bytes. 65294c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby const MCExpr *Length = MakeStartMinusEndExpr(*MCOS, *InfoStart, *InfoEnd, 4); 65394c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby MCOS->EmitAbsValue(Length, 4); 65494c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby 655dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // The 2 byte DWARF version. 656dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MCOS->EmitIntValue(context.getDwarfVersion(), 2); 65794c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby 65894c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby // The 4 byte offset to the debug abbrevs from the start of the .debug_abbrev, 65994c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby // it is at the start of that section so this is zero. 660489d67927172941bf59b9f4829ab8910814fea24Rafael Espindola if (AbbrevSectionSymbol) { 661489d67927172941bf59b9f4829ab8910814fea24Rafael Espindola MCOS->EmitSymbolValue(AbbrevSectionSymbol, 4); 662489d67927172941bf59b9f4829ab8910814fea24Rafael Espindola } else { 663489d67927172941bf59b9f4829ab8910814fea24Rafael Espindola MCOS->EmitIntValue(0, 4); 664489d67927172941bf59b9f4829ab8910814fea24Rafael Espindola } 66594c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby 66699cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling const MCAsmInfo *asmInfo = context.getAsmInfo(); 66799cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling int AddrSize = asmInfo->getPointerSize(); 66894c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby // The 1 byte size of an address. 66994c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby MCOS->EmitIntValue(AddrSize, 1); 67094c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby 67194c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby // Second part: the compile_unit DIE. 67294c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby 67394c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby // The DW_TAG_compile_unit DIE abbrev (1). 67494c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby MCOS->EmitULEB128IntValue(1); 67594c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby 67694c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby // DW_AT_stmt_list, a 4 byte offset from the start of the .debug_line section, 67794c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby // which is at the start of that section so this is zero. 678489d67927172941bf59b9f4829ab8910814fea24Rafael Espindola if (LineSectionSymbol) { 679489d67927172941bf59b9f4829ab8910814fea24Rafael Espindola MCOS->EmitSymbolValue(LineSectionSymbol, 4); 680489d67927172941bf59b9f4829ab8910814fea24Rafael Espindola } else { 681489d67927172941bf59b9f4829ab8910814fea24Rafael Espindola MCOS->EmitIntValue(0, 4); 682489d67927172941bf59b9f4829ab8910814fea24Rafael Espindola } 68394c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby 684cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (RangesSectionSymbol) { 685cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // There are multiple sections containing code, so we must use the 686cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // .debug_ranges sections. 68794c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby 688cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // AT_ranges, the 4 byte offset from the start of the .debug_ranges section 689cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // to the address range list for this compilation unit. 690cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MCOS->EmitSymbolValue(RangesSectionSymbol, 4); 691cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } else { 692cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // If we only have one non-empty code section, we can use the simpler 693cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // AT_low_pc and AT_high_pc attributes. 694cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 695cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Find the first (and only) non-empty text section 696cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines auto &Sections = context.getGenDwarfSectionSyms(); 697cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines const auto TextSection = Sections.begin(); 698cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines assert(TextSection != Sections.end() && "No text section found"); 699cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 700cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MCSymbol *StartSymbol = TextSection->second.first; 701cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MCSymbol *EndSymbol = TextSection->second.second; 702cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines assert(StartSymbol && "StartSymbol must not be NULL"); 703cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines assert(EndSymbol && "EndSymbol must not be NULL"); 704cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 705cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // AT_low_pc, the first address of the default .text section. 706cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines const MCExpr *Start = MCSymbolRefExpr::Create( 707cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines StartSymbol, MCSymbolRefExpr::VK_None, context); 708cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MCOS->EmitValue(Start, AddrSize); 709cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 710cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // AT_high_pc, the last address of the default .text section. 711cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines const MCExpr *End = MCSymbolRefExpr::Create( 712cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines EndSymbol, MCSymbolRefExpr::VK_None, context); 713cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MCOS->EmitValue(End, AddrSize); 714cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 71594c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby 71694c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby // AT_name, the name of the source file. Reconstruct from the first directory 71794c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby // and file table entries. 71836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const SmallVectorImpl<std::string> &MCDwarfDirs = context.getMCDwarfDirs(); 71994c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby if (MCDwarfDirs.size() > 0) { 72068ca56285f9b6e82eb16ff8ea02a301f2c489faeEric Christopher MCOS->EmitBytes(MCDwarfDirs[0]); 721dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MCOS->EmitBytes(sys::path::get_separator()); 72294c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby } 72336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const SmallVectorImpl<MCDwarfFile> &MCDwarfFiles = 72494c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby MCOS->getContext().getMCDwarfFiles(); 72536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MCOS->EmitBytes(MCDwarfFiles[1].Name); 72694c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby MCOS->EmitIntValue(0, 1); // NULL byte to terminate the string. 72794c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby 72894c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby // AT_comp_dir, the working directory the assembly was done in. 72936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!context.getCompilationDir().empty()) { 73036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MCOS->EmitBytes(context.getCompilationDir()); 73136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MCOS->EmitIntValue(0, 1); // NULL byte to terminate the string. 73236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 73394c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby 73494c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby // AT_APPLE_flags, the command line arguments of the assembler tool. 73594c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby StringRef DwarfDebugFlags = context.getDwarfDebugFlags(); 73694c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby if (!DwarfDebugFlags.empty()){ 73768ca56285f9b6e82eb16ff8ea02a301f2c489faeEric Christopher MCOS->EmitBytes(DwarfDebugFlags); 73894c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby MCOS->EmitIntValue(0, 1); // NULL byte to terminate the string. 73994c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby } 74094c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby 74194c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby // AT_producer, the version of the assembler tool. 74275c9b9384f50e9387f24dd7ce6af403cbda6d19aKevin Enderby StringRef DwarfDebugProducer = context.getDwarfDebugProducer(); 74375c9b9384f50e9387f24dd7ce6af403cbda6d19aKevin Enderby if (!DwarfDebugProducer.empty()){ 74475c9b9384f50e9387f24dd7ce6af403cbda6d19aKevin Enderby MCOS->EmitBytes(DwarfDebugProducer); 74575c9b9384f50e9387f24dd7ce6af403cbda6d19aKevin Enderby } 74675c9b9384f50e9387f24dd7ce6af403cbda6d19aKevin Enderby else { 74775c9b9384f50e9387f24dd7ce6af403cbda6d19aKevin Enderby MCOS->EmitBytes(StringRef("llvm-mc (based on LLVM ")); 74875c9b9384f50e9387f24dd7ce6af403cbda6d19aKevin Enderby MCOS->EmitBytes(StringRef(PACKAGE_VERSION)); 74975c9b9384f50e9387f24dd7ce6af403cbda6d19aKevin Enderby MCOS->EmitBytes(StringRef(")")); 75075c9b9384f50e9387f24dd7ce6af403cbda6d19aKevin Enderby } 75194c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby MCOS->EmitIntValue(0, 1); // NULL byte to terminate the string. 75294c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby 75394c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby // AT_language, a 4 byte value. We use DW_LANG_Mips_Assembler as the dwarf2 75494c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby // draft has no standard code for assembler. 75594c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby MCOS->EmitIntValue(dwarf::DW_LANG_Mips_Assembler, 2); 75694c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby 75738fdb7d9fc40e9f29c3156b6625cac8d91d562e1Kevin Enderby // Third part: the list of label DIEs. 75894c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby 75911c2defa9157bd589cb322218c718c4492ed5746Kevin Enderby // Loop on saved info for dwarf labels and create the DIEs for them. 760dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const std::vector<MCGenDwarfLabelEntry> &Entries = 761dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MCOS->getContext().getMCGenDwarfLabelEntries(); 762dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines for (const auto &Entry : Entries) { 76338fdb7d9fc40e9f29c3156b6625cac8d91d562e1Kevin Enderby // The DW_TAG_label DIE abbrev (2). 76494c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby MCOS->EmitULEB128IntValue(2); 76594c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby 76694c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby // AT_name, of the label without any leading underbar. 767dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MCOS->EmitBytes(Entry.getName()); 76894c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby MCOS->EmitIntValue(0, 1); // NULL byte to terminate the string. 76994c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby 77094c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby // AT_decl_file, index into the file table. 771dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MCOS->EmitIntValue(Entry.getFileNumber(), 4); 77294c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby 77394c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby // AT_decl_line, source line number. 774dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MCOS->EmitIntValue(Entry.getLineNumber(), 4); 77594c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby 77694c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby // AT_low_pc, start address of the label. 777dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const MCExpr *AT_low_pc = MCSymbolRefExpr::Create(Entry.getLabel(), 77894c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby MCSymbolRefExpr::VK_None, context); 77936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MCOS->EmitValue(AT_low_pc, AddrSize); 78094c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby 78194c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby // DW_AT_prototyped, a one byte flag value of 0 saying we have no prototype. 78294c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby MCOS->EmitIntValue(0, 1); 78394c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby 78494c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby // The DW_TAG_unspecified_parameters DIE abbrev (3). 78594c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby MCOS->EmitULEB128IntValue(3); 78694c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby 78794c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby // Add the NULL DIE terminating the DW_TAG_unspecified_parameters DIE's. 78894c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby MCOS->EmitIntValue(0, 1); 78994c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby } 79094c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby 79194c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby // Add the NULL DIE terminating the Compile Unit DIE's. 79294c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby MCOS->EmitIntValue(0, 1); 79394c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby 79494c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby // Now set the value of the symbol at the end of the info section. 79594c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby MCOS->EmitLabel(InfoEnd); 79694c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby} 79794c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby 798cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines// When generating dwarf for assembly source files this emits the data for 799cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines// .debug_ranges section. We only emit one range list, which spans all of the 800cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines// executable sections of this file. 801cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesstatic void EmitGenDwarfRanges(MCStreamer *MCOS) { 802cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MCContext &context = MCOS->getContext(); 803cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines auto &Sections = context.getGenDwarfSectionSyms(); 804cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 805cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines const MCAsmInfo *AsmInfo = context.getAsmInfo(); 806cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines int AddrSize = AsmInfo->getPointerSize(); 807cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 808cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfRangesSection()); 809cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 810cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines for (const auto sec : Sections) { 811cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 812cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MCSymbol *StartSymbol = sec.second.first; 813cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MCSymbol *EndSymbol = sec.second.second; 814cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines assert(StartSymbol && "StartSymbol must not be NULL"); 815cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines assert(EndSymbol && "EndSymbol must not be NULL"); 816cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 817cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Emit a base address selection entry for the start of this section 818cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines const MCExpr *SectionStartAddr = MCSymbolRefExpr::Create( 819cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines StartSymbol, MCSymbolRefExpr::VK_None, context); 820cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MCOS->EmitFill(AddrSize, 0xFF); 821cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MCOS->EmitValue(SectionStartAddr, AddrSize); 822cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 823cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Emit a range list entry spanning this section 824cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines const MCExpr *SectionSize = MakeStartMinusEndExpr(*MCOS, 825cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines *StartSymbol, *EndSymbol, 0); 826cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MCOS->EmitIntValue(0, AddrSize); 827cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MCOS->EmitAbsValue(SectionSize, AddrSize); 828cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 829cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 830cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Emit end of list entry 831cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MCOS->EmitIntValue(0, AddrSize); 832cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MCOS->EmitIntValue(0, AddrSize); 833cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines} 834cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 83594c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby// 83694c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby// When generating dwarf for assembly source files this emits the Dwarf 83794c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby// sections. 83894c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby// 83936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid MCGenDwarfInfo::Emit(MCStreamer *MCOS) { 84094c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby MCContext &context = MCOS->getContext(); 841cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 842cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Create the dwarf sections in this order (.debug_line already created). 84399cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling const MCAsmInfo *AsmInfo = context.getAsmInfo(); 84415ab115df57949fa55d92ffdfba491f7d02ed60fAlexey Samsonov bool CreateDwarfSectionSymbols = 84599cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling AsmInfo->doesDwarfUseRelocationsAcrossSections(); 84636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MCSymbol *LineSectionSymbol = nullptr; 84736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (CreateDwarfSectionSymbols) 84836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines LineSectionSymbol = MCOS->getDwarfLineTableSymbol(0); 849dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MCSymbol *AbbrevSectionSymbol = nullptr; 850dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MCSymbol *InfoSectionSymbol = nullptr; 851cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MCSymbol *RangesSectionSymbol = NULL; 852cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 853cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Create end symbols for each section, and remove empty sections 854cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MCOS->getContext().finalizeDwarfSections(*MCOS); 855cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 856cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // If there are no sections to generate debug info for, we don't need 857cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // to do anything 858cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (MCOS->getContext().getGenDwarfSectionSyms().empty()) 859cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return; 860cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 861cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // We only need to use the .debug_ranges section if we have multiple 862cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // code sections. 863cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines const bool UseRangesSection = 864cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MCOS->getContext().getGenDwarfSectionSyms().size() > 1; 865cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines CreateDwarfSectionSymbols |= UseRangesSection; 866cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 86794c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfInfoSection()); 86815ab115df57949fa55d92ffdfba491f7d02ed60fAlexey Samsonov if (CreateDwarfSectionSymbols) { 86915ab115df57949fa55d92ffdfba491f7d02ed60fAlexey Samsonov InfoSectionSymbol = context.CreateTempSymbol(); 87015ab115df57949fa55d92ffdfba491f7d02ed60fAlexey Samsonov MCOS->EmitLabel(InfoSectionSymbol); 87115ab115df57949fa55d92ffdfba491f7d02ed60fAlexey Samsonov } 87294c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfAbbrevSection()); 87315ab115df57949fa55d92ffdfba491f7d02ed60fAlexey Samsonov if (CreateDwarfSectionSymbols) { 874489d67927172941bf59b9f4829ab8910814fea24Rafael Espindola AbbrevSectionSymbol = context.CreateTempSymbol(); 875489d67927172941bf59b9f4829ab8910814fea24Rafael Espindola MCOS->EmitLabel(AbbrevSectionSymbol); 876489d67927172941bf59b9f4829ab8910814fea24Rafael Espindola } 877cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (UseRangesSection) { 878cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfRangesSection()); 879cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (CreateDwarfSectionSymbols) { 880cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines RangesSectionSymbol = context.CreateTempSymbol(); 881cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MCOS->EmitLabel(RangesSectionSymbol); 882cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 883cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 88494c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby 885cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines assert((RangesSectionSymbol != NULL) || !UseRangesSection); 886cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 887cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfARangesSection()); 88894c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby 88994c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby // Output the data for .debug_aranges section. 89015ab115df57949fa55d92ffdfba491f7d02ed60fAlexey Samsonov EmitGenDwarfAranges(MCOS, InfoSectionSymbol); 89194c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby 892cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (UseRangesSection) 893cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines EmitGenDwarfRanges(MCOS); 894cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 89594c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby // Output the data for .debug_abbrev section. 89694c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby EmitGenDwarfAbbrev(MCOS); 89794c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby 89894c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby // Output the data for .debug_info section. 899cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines EmitGenDwarfInfo(MCOS, AbbrevSectionSymbol, LineSectionSymbol, 900cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines RangesSectionSymbol); 90194c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby} 90294c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby 90394c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby// 90494c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby// When generating dwarf for assembly source files this is called when symbol 90594c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby// for a label is created. If this symbol is not a temporary and is in the 90694c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby// section that dwarf is being generated for, save the needed info to create 90711c2defa9157bd589cb322218c718c4492ed5746Kevin Enderby// a dwarf label. 90894c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby// 90911c2defa9157bd589cb322218c718c4492ed5746Kevin Enderbyvoid MCGenDwarfLabelEntry::Make(MCSymbol *Symbol, MCStreamer *MCOS, 91094c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby SourceMgr &SrcMgr, SMLoc &Loc) { 911cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // We won't create dwarf labels for temporary symbols. 91294c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby if (Symbol->isTemporary()) 91394c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby return; 91494c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby MCContext &context = MCOS->getContext(); 915cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // We won't create dwarf labels for symbols in sections that we are not 916cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // generating debug info for. 917cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (!context.getGenDwarfSectionSyms().count(MCOS->getCurrentSection().first)) 91894c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby return; 91994c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby 92011c2defa9157bd589cb322218c718c4492ed5746Kevin Enderby // The dwarf label's name does not have the symbol name's leading 92194c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby // underbar if any. 92294c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby StringRef Name = Symbol->getName(); 92394c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby if (Name.startswith("_")) 92494c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby Name = Name.substr(1, Name.size()-1); 92594c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby 92611c2defa9157bd589cb322218c718c4492ed5746Kevin Enderby // Get the dwarf file number to be used for the dwarf label. 92794c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby unsigned FileNumber = context.getGenDwarfFileNumber(); 92894c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby 92994c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby // Finding the line number is the expensive part which is why we just don't 93011c2defa9157bd589cb322218c718c4492ed5746Kevin Enderby // pass it in as for some symbols we won't create a dwarf label. 931cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines unsigned CurBuffer = SrcMgr.FindBufferContainingLoc(Loc); 93294c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby unsigned LineNumber = SrcMgr.FindLineNumber(Loc, CurBuffer); 93394c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby 93494c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby // We create a temporary symbol for use for the AT_high_pc and AT_low_pc 93594c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby // values so that they don't have things like an ARM thumb bit from the 93694c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby // original symbol. So when used they won't get a low bit set after 93794c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby // relocation. 93894c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby MCSymbol *Label = context.CreateTempSymbol(); 93994c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby MCOS->EmitLabel(Label); 94094c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby 94194c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby // Create and entry for the info and add it to the other entries. 942dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MCOS->getContext().addMCGenDwarfLabelEntry( 943dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MCGenDwarfLabelEntry(Name, FileNumber, LineNumber, Label)); 94494c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby} 94594c2e85bea1ab1b837a4c055ccc83d5cd32dd027Kevin Enderby 94689b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindolastatic int getDataAlignmentFactor(MCStreamer &streamer) { 94789b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola MCContext &context = streamer.getContext(); 94899cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling const MCAsmInfo *asmInfo = context.getAsmInfo(); 94999cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling int size = asmInfo->getCalleeSaveStackSlotSize(); 95099cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling if (asmInfo->isStackGrowthDirectionUp()) 95189b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola return size; 9521be0e271a07925b928ba89848934f1ea6f1854e2Evan Cheng else 9531be0e271a07925b928ba89848934f1ea6f1854e2Evan Cheng return -size; 95489b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola} 95589b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola 956abf9af60add19a0f037bb2a05433769bfd1e7f6fRafael Espindolastatic unsigned getSizeForEncoding(MCStreamer &streamer, 957abf9af60add19a0f037bb2a05433769bfd1e7f6fRafael Espindola unsigned symbolEncoding) { 95825f492e77858dc5a95fcd7180e73aff47925b668Rafael Espindola MCContext &context = streamer.getContext(); 95925f492e77858dc5a95fcd7180e73aff47925b668Rafael Espindola unsigned format = symbolEncoding & 0x0f; 96025f492e77858dc5a95fcd7180e73aff47925b668Rafael Espindola switch (format) { 961858143816d43e58b17bfd11cb1b57afbd7f0f893Craig Topper default: llvm_unreachable("Unknown Encoding"); 96225f492e77858dc5a95fcd7180e73aff47925b668Rafael Espindola case dwarf::DW_EH_PE_absptr: 96325f492e77858dc5a95fcd7180e73aff47925b668Rafael Espindola case dwarf::DW_EH_PE_signed: 96499cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling return context.getAsmInfo()->getPointerSize(); 96525f492e77858dc5a95fcd7180e73aff47925b668Rafael Espindola case dwarf::DW_EH_PE_udata2: 96625f492e77858dc5a95fcd7180e73aff47925b668Rafael Espindola case dwarf::DW_EH_PE_sdata2: 967abf9af60add19a0f037bb2a05433769bfd1e7f6fRafael Espindola return 2; 96825f492e77858dc5a95fcd7180e73aff47925b668Rafael Espindola case dwarf::DW_EH_PE_udata4: 96925f492e77858dc5a95fcd7180e73aff47925b668Rafael Espindola case dwarf::DW_EH_PE_sdata4: 970abf9af60add19a0f037bb2a05433769bfd1e7f6fRafael Espindola return 4; 97125f492e77858dc5a95fcd7180e73aff47925b668Rafael Espindola case dwarf::DW_EH_PE_udata8: 97225f492e77858dc5a95fcd7180e73aff47925b668Rafael Espindola case dwarf::DW_EH_PE_sdata8: 973abf9af60add19a0f037bb2a05433769bfd1e7f6fRafael Espindola return 8; 97425f492e77858dc5a95fcd7180e73aff47925b668Rafael Espindola } 975abf9af60add19a0f037bb2a05433769bfd1e7f6fRafael Espindola} 976abf9af60add19a0f037bb2a05433769bfd1e7f6fRafael Espindola 97736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic void EmitFDESymbol(MCStreamer &streamer, const MCSymbol &symbol, 97836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned symbolEncoding, bool isEH, 979dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const char *comment = nullptr) { 980a0057ca13f06b8de08483c3e3a143a7236c67097Rafael Espindola MCContext &context = streamer.getContext(); 98199cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling const MCAsmInfo *asmInfo = context.getAsmInfo(); 98299cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling const MCExpr *v = asmInfo->getExprForFDESymbol(&symbol, 98399cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling symbolEncoding, 98499cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling streamer); 985abf9af60add19a0f037bb2a05433769bfd1e7f6fRafael Espindola unsigned size = getSizeForEncoding(streamer, symbolEncoding); 9862541c41f3e2af94585e14353a91f02facd65e415Bill Wendling if (streamer.isVerboseAsm() && comment) streamer.AddComment(comment); 98736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (asmInfo->doDwarfFDESymbolsUseAbsDiff() && isEH) 98836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines streamer.EmitAbsValue(v, size); 98936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else 99036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines streamer.EmitValue(v, size); 99125f492e77858dc5a95fcd7180e73aff47925b668Rafael Espindola} 99225f492e77858dc5a95fcd7180e73aff47925b668Rafael Espindola 993bfa27cc5d72e061a96efbb461864d40bc8089ec2Rafael Espindolastatic void EmitPersonality(MCStreamer &streamer, const MCSymbol &symbol, 994bfa27cc5d72e061a96efbb461864d40bc8089ec2Rafael Espindola unsigned symbolEncoding) { 995bfa27cc5d72e061a96efbb461864d40bc8089ec2Rafael Espindola MCContext &context = streamer.getContext(); 99699cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling const MCAsmInfo *asmInfo = context.getAsmInfo(); 99799cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling const MCExpr *v = asmInfo->getExprForPersonalitySymbol(&symbol, 99899cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling symbolEncoding, 99999cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling streamer); 1000bfa27cc5d72e061a96efbb461864d40bc8089ec2Rafael Espindola unsigned size = getSizeForEncoding(streamer, symbolEncoding); 1001debd7e4e8bc5cfe61bfb71835ce2b1a3fbccc2beRafael Espindola streamer.EmitValue(v, size); 1002bfa27cc5d72e061a96efbb461864d40bc8089ec2Rafael Espindola} 1003bfa27cc5d72e061a96efbb461864d40bc8089ec2Rafael Espindola 100425f492e77858dc5a95fcd7180e73aff47925b668Rafael Espindolanamespace { 100525f492e77858dc5a95fcd7180e73aff47925b668Rafael Espindola class FrameEmitterImpl { 100625f492e77858dc5a95fcd7180e73aff47925b668Rafael Espindola int CFAOffset; 1007514cecc72b23bb75108844285ab8f3616a08bac5Rafael Espindola int CIENum; 100840a7dbbeff44c4cbd8c7e4f07f28dd614f8a5d08Rafael Espindola bool IsEH; 1009e3a0e987f3d4f07512cdb64b9034369f966cb448Rafael Espindola const MCSymbol *SectionStart; 101025f492e77858dc5a95fcd7180e73aff47925b668Rafael Espindola public: 1011dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines FrameEmitterImpl(bool isEH) 1012dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines : CFAOffset(0), CIENum(0), IsEH(isEH), SectionStart(nullptr) {} 10131424c3c3e696868775ac5bfc57d27a0ac3bc6c63Bill Wendling 10141424c3c3e696868775ac5bfc57d27a0ac3bc6c63Bill Wendling void setSectionStart(const MCSymbol *Label) { SectionStart = Label; } 101525f492e77858dc5a95fcd7180e73aff47925b668Rafael Espindola 1016d6d2ef158210f0634e31527193aa13778d48f66cBill Wendling /// EmitCompactUnwind - Emit the unwind information in a compact way. 10173c08eef20b9cfc31d4ae3a43f1c9a57a4ab2cad7Bill Wendling void EmitCompactUnwind(MCStreamer &streamer, 1018e3cd13f0e2d4e2ef30f8a57c0a82d328102eeb26Bill Wendling const MCDwarfFrameInfo &frame); 1019e3cd13f0e2d4e2ef30f8a57c0a82d328102eeb26Bill Wendling 1020dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const MCSymbol &EmitCIE(MCObjectStreamer &streamer, 102125f492e77858dc5a95fcd7180e73aff47925b668Rafael Espindola const MCSymbol *personality, 102225f492e77858dc5a95fcd7180e73aff47925b668Rafael Espindola unsigned personalityEncoding, 102325f492e77858dc5a95fcd7180e73aff47925b668Rafael Espindola const MCSymbol *lsda, 102416d7d437e03ce87fdaef7971919302920d54a966Rafael Espindola bool IsSignalFrame, 102536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned lsdaEncoding, 102636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool IsSimple); 1027dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MCSymbol *EmitFDE(MCObjectStreamer &streamer, 102825f492e77858dc5a95fcd7180e73aff47925b668Rafael Espindola const MCSymbol &cieStart, 10299f270dadd429771dded5a8572da8c74513771c15Rafael Espindola const MCDwarfFrameInfo &frame); 1030dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines void EmitCFIInstructions(MCObjectStreamer &streamer, 10319e4bd87f470132ec907afdc3eed4e34cb4859240Bill Wendling ArrayRef<MCCFIInstruction> Instrs, 103225f492e77858dc5a95fcd7180e73aff47925b668Rafael Espindola MCSymbol *BaseLabel); 1033dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines void EmitCFIInstruction(MCObjectStreamer &Streamer, 103425f492e77858dc5a95fcd7180e73aff47925b668Rafael Espindola const MCCFIInstruction &Instr); 103525f492e77858dc5a95fcd7180e73aff47925b668Rafael Espindola }; 10363c163cfa60f9f196cd6a5a04e07baec3947fee0bBill Wendling 10373c163cfa60f9f196cd6a5a04e07baec3947fee0bBill Wendling} // end anonymous namespace 10383c163cfa60f9f196cd6a5a04e07baec3947fee0bBill Wendling 10393c163cfa60f9f196cd6a5a04e07baec3947fee0bBill Wendlingstatic void EmitEncodingByte(MCStreamer &Streamer, unsigned Encoding, 10403c163cfa60f9f196cd6a5a04e07baec3947fee0bBill Wendling StringRef Prefix) { 10413c163cfa60f9f196cd6a5a04e07baec3947fee0bBill Wendling if (Streamer.isVerboseAsm()) { 1042eb9fa666f9ea27334aa728d7b6b435b5c20a2c4cBenjamin Kramer const char *EncStr; 10433c163cfa60f9f196cd6a5a04e07baec3947fee0bBill Wendling switch (Encoding) { 1044eb9fa666f9ea27334aa728d7b6b435b5c20a2c4cBenjamin Kramer default: EncStr = "<unknown encoding>"; break; 1045eb9fa666f9ea27334aa728d7b6b435b5c20a2c4cBenjamin Kramer case dwarf::DW_EH_PE_absptr: EncStr = "absptr"; break; 1046eb9fa666f9ea27334aa728d7b6b435b5c20a2c4cBenjamin Kramer case dwarf::DW_EH_PE_omit: EncStr = "omit"; break; 1047eb9fa666f9ea27334aa728d7b6b435b5c20a2c4cBenjamin Kramer case dwarf::DW_EH_PE_pcrel: EncStr = "pcrel"; break; 1048eb9fa666f9ea27334aa728d7b6b435b5c20a2c4cBenjamin Kramer case dwarf::DW_EH_PE_udata4: EncStr = "udata4"; break; 1049eb9fa666f9ea27334aa728d7b6b435b5c20a2c4cBenjamin Kramer case dwarf::DW_EH_PE_udata8: EncStr = "udata8"; break; 1050eb9fa666f9ea27334aa728d7b6b435b5c20a2c4cBenjamin Kramer case dwarf::DW_EH_PE_sdata4: EncStr = "sdata4"; break; 1051eb9fa666f9ea27334aa728d7b6b435b5c20a2c4cBenjamin Kramer case dwarf::DW_EH_PE_sdata8: EncStr = "sdata8"; break; 1052eb9fa666f9ea27334aa728d7b6b435b5c20a2c4cBenjamin Kramer case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata4: 1053eb9fa666f9ea27334aa728d7b6b435b5c20a2c4cBenjamin Kramer EncStr = "pcrel udata4"; 1054eb9fa666f9ea27334aa728d7b6b435b5c20a2c4cBenjamin Kramer break; 1055eb9fa666f9ea27334aa728d7b6b435b5c20a2c4cBenjamin Kramer case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4: 1056eb9fa666f9ea27334aa728d7b6b435b5c20a2c4cBenjamin Kramer EncStr = "pcrel sdata4"; 1057eb9fa666f9ea27334aa728d7b6b435b5c20a2c4cBenjamin Kramer break; 1058eb9fa666f9ea27334aa728d7b6b435b5c20a2c4cBenjamin Kramer case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata8: 1059eb9fa666f9ea27334aa728d7b6b435b5c20a2c4cBenjamin Kramer EncStr = "pcrel udata8"; 1060eb9fa666f9ea27334aa728d7b6b435b5c20a2c4cBenjamin Kramer break; 1061eb9fa666f9ea27334aa728d7b6b435b5c20a2c4cBenjamin Kramer case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8: 1062eb9fa666f9ea27334aa728d7b6b435b5c20a2c4cBenjamin Kramer EncStr = "screl sdata8"; 1063eb9fa666f9ea27334aa728d7b6b435b5c20a2c4cBenjamin Kramer break; 10643c163cfa60f9f196cd6a5a04e07baec3947fee0bBill Wendling case dwarf::DW_EH_PE_indirect |dwarf::DW_EH_PE_pcrel|dwarf::DW_EH_PE_udata4: 10653c163cfa60f9f196cd6a5a04e07baec3947fee0bBill Wendling EncStr = "indirect pcrel udata4"; 1066eb9fa666f9ea27334aa728d7b6b435b5c20a2c4cBenjamin Kramer break; 10673c163cfa60f9f196cd6a5a04e07baec3947fee0bBill Wendling case dwarf::DW_EH_PE_indirect |dwarf::DW_EH_PE_pcrel|dwarf::DW_EH_PE_sdata4: 10683c163cfa60f9f196cd6a5a04e07baec3947fee0bBill Wendling EncStr = "indirect pcrel sdata4"; 1069eb9fa666f9ea27334aa728d7b6b435b5c20a2c4cBenjamin Kramer break; 10703c163cfa60f9f196cd6a5a04e07baec3947fee0bBill Wendling case dwarf::DW_EH_PE_indirect |dwarf::DW_EH_PE_pcrel|dwarf::DW_EH_PE_udata8: 10713c163cfa60f9f196cd6a5a04e07baec3947fee0bBill Wendling EncStr = "indirect pcrel udata8"; 1072eb9fa666f9ea27334aa728d7b6b435b5c20a2c4cBenjamin Kramer break; 10733c163cfa60f9f196cd6a5a04e07baec3947fee0bBill Wendling case dwarf::DW_EH_PE_indirect |dwarf::DW_EH_PE_pcrel|dwarf::DW_EH_PE_sdata8: 10743c163cfa60f9f196cd6a5a04e07baec3947fee0bBill Wendling EncStr = "indirect pcrel sdata8"; 1075eb9fa666f9ea27334aa728d7b6b435b5c20a2c4cBenjamin Kramer break; 10763c163cfa60f9f196cd6a5a04e07baec3947fee0bBill Wendling } 10773c163cfa60f9f196cd6a5a04e07baec3947fee0bBill Wendling 10783c163cfa60f9f196cd6a5a04e07baec3947fee0bBill Wendling Streamer.AddComment(Twine(Prefix) + " = " + EncStr); 10793c163cfa60f9f196cd6a5a04e07baec3947fee0bBill Wendling } 10803c163cfa60f9f196cd6a5a04e07baec3947fee0bBill Wendling 10813c163cfa60f9f196cd6a5a04e07baec3947fee0bBill Wendling Streamer.EmitIntValue(Encoding, 1); 108225f492e77858dc5a95fcd7180e73aff47925b668Rafael Espindola} 108325f492e77858dc5a95fcd7180e73aff47925b668Rafael Espindola 1084dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid FrameEmitterImpl::EmitCFIInstruction(MCObjectStreamer &Streamer, 108525f492e77858dc5a95fcd7180e73aff47925b668Rafael Espindola const MCCFIInstruction &Instr) { 1086fe024d0a624404ada11fb330e7360abc5f88742eRafael Espindola int dataAlignmentFactor = getDataAlignmentFactor(Streamer); 1087efd24ddbffc1e69fa88089de036d1873c950dfb5Bill Wendling bool VerboseAsm = Streamer.isVerboseAsm(); 108889b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola 1089fe024d0a624404ada11fb330e7360abc5f88742eRafael Espindola switch (Instr.getOperation()) { 1090f4f14f68f6078ea6681ee27b5bf42719d7db3441Rafael Espindola case MCCFIInstruction::OpRegister: { 1091f4f14f68f6078ea6681ee27b5bf42719d7db3441Rafael Espindola unsigned Reg1 = Instr.getRegister(); 1092f4f14f68f6078ea6681ee27b5bf42719d7db3441Rafael Espindola unsigned Reg2 = Instr.getRegister2(); 1093f4f14f68f6078ea6681ee27b5bf42719d7db3441Rafael Espindola if (VerboseAsm) { 1094f4f14f68f6078ea6681ee27b5bf42719d7db3441Rafael Espindola Streamer.AddComment("DW_CFA_register"); 1095f4f14f68f6078ea6681ee27b5bf42719d7db3441Rafael Espindola Streamer.AddComment(Twine("Reg1 ") + Twine(Reg1)); 1096f4f14f68f6078ea6681ee27b5bf42719d7db3441Rafael Espindola Streamer.AddComment(Twine("Reg2 ") + Twine(Reg2)); 1097f4f14f68f6078ea6681ee27b5bf42719d7db3441Rafael Espindola } 1098f4f14f68f6078ea6681ee27b5bf42719d7db3441Rafael Espindola Streamer.EmitIntValue(dwarf::DW_CFA_register, 1); 1099f4f14f68f6078ea6681ee27b5bf42719d7db3441Rafael Espindola Streamer.EmitULEB128IntValue(Reg1); 1100f4f14f68f6078ea6681ee27b5bf42719d7db3441Rafael Espindola Streamer.EmitULEB128IntValue(Reg2); 1101f4f14f68f6078ea6681ee27b5bf42719d7db3441Rafael Espindola return; 1102f4f14f68f6078ea6681ee27b5bf42719d7db3441Rafael Espindola } 110383ba58e5f0a5afbb23d7d2092d817accded4455aVenkatraman Govindaraju case MCCFIInstruction::OpWindowSave: { 110483ba58e5f0a5afbb23d7d2092d817accded4455aVenkatraman Govindaraju Streamer.EmitIntValue(dwarf::DW_CFA_GNU_window_save, 1); 110583ba58e5f0a5afbb23d7d2092d817accded4455aVenkatraman Govindaraju return; 110683ba58e5f0a5afbb23d7d2092d817accded4455aVenkatraman Govindaraju } 11077f74d2c2c197eec76ae2b41fed9c227c0dcc04cbRafael Espindola case MCCFIInstruction::OpUndefined: { 1108ff233c9e5c3e439fd1eed84b9a9e88a5370572dbRafael Espindola unsigned Reg = Instr.getRegister(); 1109c8fec7e21f5c24303eab8a8592f3b8faff347d86Rafael Espindola if (VerboseAsm) { 1110c8fec7e21f5c24303eab8a8592f3b8faff347d86Rafael Espindola Streamer.AddComment("DW_CFA_undefined"); 1111c8fec7e21f5c24303eab8a8592f3b8faff347d86Rafael Espindola Streamer.AddComment(Twine("Reg ") + Twine(Reg)); 1112c8fec7e21f5c24303eab8a8592f3b8faff347d86Rafael Espindola } 1113c8fec7e21f5c24303eab8a8592f3b8faff347d86Rafael Espindola Streamer.EmitIntValue(dwarf::DW_CFA_undefined, 1); 1114c8fec7e21f5c24303eab8a8592f3b8faff347d86Rafael Espindola Streamer.EmitULEB128IntValue(Reg); 1115c8fec7e21f5c24303eab8a8592f3b8faff347d86Rafael Espindola return; 1116c8fec7e21f5c24303eab8a8592f3b8faff347d86Rafael Espindola } 11177f74d2c2c197eec76ae2b41fed9c227c0dcc04cbRafael Espindola case MCCFIInstruction::OpAdjustCfaOffset: 11187f74d2c2c197eec76ae2b41fed9c227c0dcc04cbRafael Espindola case MCCFIInstruction::OpDefCfaOffset: { 11197f74d2c2c197eec76ae2b41fed9c227c0dcc04cbRafael Espindola const bool IsRelative = 11207f74d2c2c197eec76ae2b41fed9c227c0dcc04cbRafael Espindola Instr.getOperation() == MCCFIInstruction::OpAdjustCfaOffset; 112189b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola 11227f74d2c2c197eec76ae2b41fed9c227c0dcc04cbRafael Espindola if (VerboseAsm) 11237f74d2c2c197eec76ae2b41fed9c227c0dcc04cbRafael Espindola Streamer.AddComment("DW_CFA_def_cfa_offset"); 11247f74d2c2c197eec76ae2b41fed9c227c0dcc04cbRafael Espindola Streamer.EmitIntValue(dwarf::DW_CFA_def_cfa_offset, 1); 11255d7dcd3335234d2a2bc16dc69f86fbb5dcaa8962Rafael Espindola 11267f74d2c2c197eec76ae2b41fed9c227c0dcc04cbRafael Espindola if (IsRelative) 1127ff233c9e5c3e439fd1eed84b9a9e88a5370572dbRafael Espindola CFAOffset += Instr.getOffset(); 11287f74d2c2c197eec76ae2b41fed9c227c0dcc04cbRafael Espindola else 1129ff233c9e5c3e439fd1eed84b9a9e88a5370572dbRafael Espindola CFAOffset = -Instr.getOffset(); 113089b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola 11317f74d2c2c197eec76ae2b41fed9c227c0dcc04cbRafael Espindola if (VerboseAsm) 11327f74d2c2c197eec76ae2b41fed9c227c0dcc04cbRafael Espindola Streamer.AddComment(Twine("Offset " + Twine(CFAOffset))); 11337f74d2c2c197eec76ae2b41fed9c227c0dcc04cbRafael Espindola Streamer.EmitULEB128IntValue(CFAOffset); 11347f74d2c2c197eec76ae2b41fed9c227c0dcc04cbRafael Espindola 11357f74d2c2c197eec76ae2b41fed9c227c0dcc04cbRafael Espindola return; 11367f74d2c2c197eec76ae2b41fed9c227c0dcc04cbRafael Espindola } 11377f74d2c2c197eec76ae2b41fed9c227c0dcc04cbRafael Espindola case MCCFIInstruction::OpDefCfa: { 11387f74d2c2c197eec76ae2b41fed9c227c0dcc04cbRafael Espindola if (VerboseAsm) 11397f74d2c2c197eec76ae2b41fed9c227c0dcc04cbRafael Espindola Streamer.AddComment("DW_CFA_def_cfa"); 11407f74d2c2c197eec76ae2b41fed9c227c0dcc04cbRafael Espindola Streamer.EmitIntValue(dwarf::DW_CFA_def_cfa, 1); 11417f74d2c2c197eec76ae2b41fed9c227c0dcc04cbRafael Espindola 11427f74d2c2c197eec76ae2b41fed9c227c0dcc04cbRafael Espindola if (VerboseAsm) 1143ff233c9e5c3e439fd1eed84b9a9e88a5370572dbRafael Espindola Streamer.AddComment(Twine("Reg ") + Twine(Instr.getRegister())); 1144ff233c9e5c3e439fd1eed84b9a9e88a5370572dbRafael Espindola Streamer.EmitULEB128IntValue(Instr.getRegister()); 11457f74d2c2c197eec76ae2b41fed9c227c0dcc04cbRafael Espindola 1146ff233c9e5c3e439fd1eed84b9a9e88a5370572dbRafael Espindola CFAOffset = -Instr.getOffset(); 11477f74d2c2c197eec76ae2b41fed9c227c0dcc04cbRafael Espindola 11487f74d2c2c197eec76ae2b41fed9c227c0dcc04cbRafael Espindola if (VerboseAsm) 11497f74d2c2c197eec76ae2b41fed9c227c0dcc04cbRafael Espindola Streamer.AddComment(Twine("Offset " + Twine(CFAOffset))); 11507f74d2c2c197eec76ae2b41fed9c227c0dcc04cbRafael Espindola Streamer.EmitULEB128IntValue(CFAOffset); 11517f74d2c2c197eec76ae2b41fed9c227c0dcc04cbRafael Espindola 11527f74d2c2c197eec76ae2b41fed9c227c0dcc04cbRafael Espindola return; 11537f74d2c2c197eec76ae2b41fed9c227c0dcc04cbRafael Espindola } 11547f74d2c2c197eec76ae2b41fed9c227c0dcc04cbRafael Espindola 11557f74d2c2c197eec76ae2b41fed9c227c0dcc04cbRafael Espindola case MCCFIInstruction::OpDefCfaRegister: { 11567f74d2c2c197eec76ae2b41fed9c227c0dcc04cbRafael Espindola if (VerboseAsm) 11577f74d2c2c197eec76ae2b41fed9c227c0dcc04cbRafael Espindola Streamer.AddComment("DW_CFA_def_cfa_register"); 11587f74d2c2c197eec76ae2b41fed9c227c0dcc04cbRafael Espindola Streamer.EmitIntValue(dwarf::DW_CFA_def_cfa_register, 1); 11597f74d2c2c197eec76ae2b41fed9c227c0dcc04cbRafael Espindola 11607f74d2c2c197eec76ae2b41fed9c227c0dcc04cbRafael Espindola if (VerboseAsm) 1161ff233c9e5c3e439fd1eed84b9a9e88a5370572dbRafael Espindola Streamer.AddComment(Twine("Reg ") + Twine(Instr.getRegister())); 1162ff233c9e5c3e439fd1eed84b9a9e88a5370572dbRafael Espindola Streamer.EmitULEB128IntValue(Instr.getRegister()); 11637f74d2c2c197eec76ae2b41fed9c227c0dcc04cbRafael Espindola 11647f74d2c2c197eec76ae2b41fed9c227c0dcc04cbRafael Espindola return; 11657f74d2c2c197eec76ae2b41fed9c227c0dcc04cbRafael Espindola } 11667f74d2c2c197eec76ae2b41fed9c227c0dcc04cbRafael Espindola 11677f74d2c2c197eec76ae2b41fed9c227c0dcc04cbRafael Espindola case MCCFIInstruction::OpOffset: 11687f74d2c2c197eec76ae2b41fed9c227c0dcc04cbRafael Espindola case MCCFIInstruction::OpRelOffset: { 11697f74d2c2c197eec76ae2b41fed9c227c0dcc04cbRafael Espindola const bool IsRelative = 11707f74d2c2c197eec76ae2b41fed9c227c0dcc04cbRafael Espindola Instr.getOperation() == MCCFIInstruction::OpRelOffset; 117189b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola 1172ff233c9e5c3e439fd1eed84b9a9e88a5370572dbRafael Espindola unsigned Reg = Instr.getRegister(); 1173ff233c9e5c3e439fd1eed84b9a9e88a5370572dbRafael Espindola int Offset = Instr.getOffset(); 117425f492e77858dc5a95fcd7180e73aff47925b668Rafael Espindola if (IsRelative) 117525f492e77858dc5a95fcd7180e73aff47925b668Rafael Espindola Offset -= CFAOffset; 117625f492e77858dc5a95fcd7180e73aff47925b668Rafael Espindola Offset = Offset / dataAlignmentFactor; 117789b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola 117889b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola if (Offset < 0) { 1179efd24ddbffc1e69fa88089de036d1873c950dfb5Bill Wendling if (VerboseAsm) Streamer.AddComment("DW_CFA_offset_extended_sf"); 1180fe024d0a624404ada11fb330e7360abc5f88742eRafael Espindola Streamer.EmitIntValue(dwarf::DW_CFA_offset_extended_sf, 1); 1181efd24ddbffc1e69fa88089de036d1873c950dfb5Bill Wendling if (VerboseAsm) Streamer.AddComment(Twine("Reg ") + Twine(Reg)); 1182fe024d0a624404ada11fb330e7360abc5f88742eRafael Espindola Streamer.EmitULEB128IntValue(Reg); 1183efd24ddbffc1e69fa88089de036d1873c950dfb5Bill Wendling if (VerboseAsm) Streamer.AddComment(Twine("Offset ") + Twine(Offset)); 1184fe024d0a624404ada11fb330e7360abc5f88742eRafael Espindola Streamer.EmitSLEB128IntValue(Offset); 118589b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola } else if (Reg < 64) { 1186e08d4335ad29d74008222b4d7ac91c153ed66becBill Wendling if (VerboseAsm) Streamer.AddComment(Twine("DW_CFA_offset + Reg(") + 1187e08d4335ad29d74008222b4d7ac91c153ed66becBill Wendling Twine(Reg) + ")"); 1188fe024d0a624404ada11fb330e7360abc5f88742eRafael Espindola Streamer.EmitIntValue(dwarf::DW_CFA_offset + Reg, 1); 1189efd24ddbffc1e69fa88089de036d1873c950dfb5Bill Wendling if (VerboseAsm) Streamer.AddComment(Twine("Offset ") + Twine(Offset)); 1190eccbad78e0854743e358841b64f9e0f5eba82861Rafael Espindola Streamer.EmitULEB128IntValue(Offset); 119189b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola } else { 1192efd24ddbffc1e69fa88089de036d1873c950dfb5Bill Wendling if (VerboseAsm) Streamer.AddComment("DW_CFA_offset_extended"); 1193fe024d0a624404ada11fb330e7360abc5f88742eRafael Espindola Streamer.EmitIntValue(dwarf::DW_CFA_offset_extended, 1); 1194efd24ddbffc1e69fa88089de036d1873c950dfb5Bill Wendling if (VerboseAsm) Streamer.AddComment(Twine("Reg ") + Twine(Reg)); 1195eccbad78e0854743e358841b64f9e0f5eba82861Rafael Espindola Streamer.EmitULEB128IntValue(Reg); 1196efd24ddbffc1e69fa88089de036d1873c950dfb5Bill Wendling if (VerboseAsm) Streamer.AddComment(Twine("Offset ") + Twine(Offset)); 1197eccbad78e0854743e358841b64f9e0f5eba82861Rafael Espindola Streamer.EmitULEB128IntValue(Offset); 1198fe024d0a624404ada11fb330e7360abc5f88742eRafael Espindola } 1199fe024d0a624404ada11fb330e7360abc5f88742eRafael Espindola return; 1200fe024d0a624404ada11fb330e7360abc5f88742eRafael Espindola } 12017f74d2c2c197eec76ae2b41fed9c227c0dcc04cbRafael Espindola case MCCFIInstruction::OpRememberState: 1202efd24ddbffc1e69fa88089de036d1873c950dfb5Bill Wendling if (VerboseAsm) Streamer.AddComment("DW_CFA_remember_state"); 1203fe024d0a624404ada11fb330e7360abc5f88742eRafael Espindola Streamer.EmitIntValue(dwarf::DW_CFA_remember_state, 1); 1204fe024d0a624404ada11fb330e7360abc5f88742eRafael Espindola return; 12057f74d2c2c197eec76ae2b41fed9c227c0dcc04cbRafael Espindola case MCCFIInstruction::OpRestoreState: 1206efd24ddbffc1e69fa88089de036d1873c950dfb5Bill Wendling if (VerboseAsm) Streamer.AddComment("DW_CFA_restore_state"); 1207fe024d0a624404ada11fb330e7360abc5f88742eRafael Espindola Streamer.EmitIntValue(dwarf::DW_CFA_restore_state, 1); 1208fe024d0a624404ada11fb330e7360abc5f88742eRafael Espindola return; 12097f74d2c2c197eec76ae2b41fed9c227c0dcc04cbRafael Espindola case MCCFIInstruction::OpSameValue: { 1210ff233c9e5c3e439fd1eed84b9a9e88a5370572dbRafael Espindola unsigned Reg = Instr.getRegister(); 1211efd24ddbffc1e69fa88089de036d1873c950dfb5Bill Wendling if (VerboseAsm) Streamer.AddComment("DW_CFA_same_value"); 1212c57543964d1382d3d3a5005f415b6c0f49671b3aRafael Espindola Streamer.EmitIntValue(dwarf::DW_CFA_same_value, 1); 1213efd24ddbffc1e69fa88089de036d1873c950dfb5Bill Wendling if (VerboseAsm) Streamer.AddComment(Twine("Reg ") + Twine(Reg)); 1214e8cfbd843d737e1f95c3032c7670c2be3838a6f6Rafael Espindola Streamer.EmitULEB128IntValue(Reg); 1215c57543964d1382d3d3a5005f415b6c0f49671b3aRafael Espindola return; 1216c57543964d1382d3d3a5005f415b6c0f49671b3aRafael Espindola } 12177f74d2c2c197eec76ae2b41fed9c227c0dcc04cbRafael Espindola case MCCFIInstruction::OpRestore: { 1218ff233c9e5c3e439fd1eed84b9a9e88a5370572dbRafael Espindola unsigned Reg = Instr.getRegister(); 1219ed23bdb65fe86cdb7a38c8c1998ec965e6973966Rafael Espindola if (VerboseAsm) { 1220ed23bdb65fe86cdb7a38c8c1998ec965e6973966Rafael Espindola Streamer.AddComment("DW_CFA_restore"); 1221ed23bdb65fe86cdb7a38c8c1998ec965e6973966Rafael Espindola Streamer.AddComment(Twine("Reg ") + Twine(Reg)); 1222ed23bdb65fe86cdb7a38c8c1998ec965e6973966Rafael Espindola } 1223ed23bdb65fe86cdb7a38c8c1998ec965e6973966Rafael Espindola Streamer.EmitIntValue(dwarf::DW_CFA_restore | Reg, 1); 1224ed23bdb65fe86cdb7a38c8c1998ec965e6973966Rafael Espindola return; 1225ed23bdb65fe86cdb7a38c8c1998ec965e6973966Rafael Espindola } 12267f74d2c2c197eec76ae2b41fed9c227c0dcc04cbRafael Espindola case MCCFIInstruction::OpEscape: 12276f0b181bc70318f8d5d4b9bdead7fc748677fe2aRafael Espindola if (VerboseAsm) Streamer.AddComment("Escape bytes"); 122868ca56285f9b6e82eb16ff8ea02a301f2c489faeEric Christopher Streamer.EmitBytes(Instr.getValues()); 12296f0b181bc70318f8d5d4b9bdead7fc748677fe2aRafael Espindola return; 1230fe024d0a624404ada11fb330e7360abc5f88742eRafael Espindola } 1231fe024d0a624404ada11fb330e7360abc5f88742eRafael Espindola llvm_unreachable("Unhandled case in switch"); 1232fe024d0a624404ada11fb330e7360abc5f88742eRafael Espindola} 1233fe024d0a624404ada11fb330e7360abc5f88742eRafael Espindola 1234fe024d0a624404ada11fb330e7360abc5f88742eRafael Espindola/// EmitFrameMoves - Emit frame instructions to describe the layout of the 1235fe024d0a624404ada11fb330e7360abc5f88742eRafael Espindola/// frame. 1236dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid FrameEmitterImpl::EmitCFIInstructions(MCObjectStreamer &streamer, 12379e4bd87f470132ec907afdc3eed4e34cb4859240Bill Wendling ArrayRef<MCCFIInstruction> Instrs, 123825f492e77858dc5a95fcd7180e73aff47925b668Rafael Espindola MCSymbol *BaseLabel) { 1239fe024d0a624404ada11fb330e7360abc5f88742eRafael Espindola for (unsigned i = 0, N = Instrs.size(); i < N; ++i) { 1240fe024d0a624404ada11fb330e7360abc5f88742eRafael Espindola const MCCFIInstruction &Instr = Instrs[i]; 1241fe024d0a624404ada11fb330e7360abc5f88742eRafael Espindola MCSymbol *Label = Instr.getLabel(); 1242fe024d0a624404ada11fb330e7360abc5f88742eRafael Espindola // Throw out move if the label is invalid. 1243fe024d0a624404ada11fb330e7360abc5f88742eRafael Espindola if (Label && !Label->isDefined()) continue; // Not emitted, in dead code. 1244fe024d0a624404ada11fb330e7360abc5f88742eRafael Espindola 1245fe024d0a624404ada11fb330e7360abc5f88742eRafael Espindola // Advance row if new location. 1246fe024d0a624404ada11fb330e7360abc5f88742eRafael Espindola if (BaseLabel && Label) { 1247fe024d0a624404ada11fb330e7360abc5f88742eRafael Espindola MCSymbol *ThisSym = Label; 1248fe024d0a624404ada11fb330e7360abc5f88742eRafael Espindola if (ThisSym != BaseLabel) { 1249d221cd676b44d8118b1db152ecc2168538479626Bill Wendling if (streamer.isVerboseAsm()) streamer.AddComment("DW_CFA_advance_loc4"); 1250fe024d0a624404ada11fb330e7360abc5f88742eRafael Espindola streamer.EmitDwarfAdvanceFrameAddr(BaseLabel, ThisSym); 1251fe024d0a624404ada11fb330e7360abc5f88742eRafael Espindola BaseLabel = ThisSym; 1252fe024d0a624404ada11fb330e7360abc5f88742eRafael Espindola } 125389b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola } 1254fe024d0a624404ada11fb330e7360abc5f88742eRafael Espindola 1255b40a71fda188f8ca564e606ac2cb051a44ada311Rafael Espindola EmitCFIInstruction(streamer, Instr); 125689b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola } 125789b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola} 125889b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola 1259d6d2ef158210f0634e31527193aa13778d48f66cBill Wendling/// EmitCompactUnwind - Emit the unwind information in a compact way. 12603c08eef20b9cfc31d4ae3a43f1c9a57a4ab2cad7Bill Wendlingvoid FrameEmitterImpl::EmitCompactUnwind(MCStreamer &Streamer, 1261e3cd13f0e2d4e2ef30f8a57c0a82d328102eeb26Bill Wendling const MCDwarfFrameInfo &Frame) { 1262e3cd13f0e2d4e2ef30f8a57c0a82d328102eeb26Bill Wendling MCContext &Context = Streamer.getContext(); 1263e76a33b9567d78a5744dc52fcec3a6056d6fb576Evan Cheng const MCObjectFileInfo *MOFI = Context.getObjectFileInfo(); 12643c163cfa60f9f196cd6a5a04e07baec3947fee0bBill Wendling bool VerboseAsm = Streamer.isVerboseAsm(); 1265e3cd13f0e2d4e2ef30f8a57c0a82d328102eeb26Bill Wendling 1266e3cd13f0e2d4e2ef30f8a57c0a82d328102eeb26Bill Wendling // range-start range-length compact-unwind-enc personality-func lsda 1267e3cd13f0e2d4e2ef30f8a57c0a82d328102eeb26Bill Wendling // _foo LfooEnd-_foo 0x00000023 0 0 1268e3cd13f0e2d4e2ef30f8a57c0a82d328102eeb26Bill Wendling // _bar LbarEnd-_bar 0x00000025 __gxx_personality except_tab1 1269e3cd13f0e2d4e2ef30f8a57c0a82d328102eeb26Bill Wendling // 1270e3cd13f0e2d4e2ef30f8a57c0a82d328102eeb26Bill Wendling // .section __LD,__compact_unwind,regular,debug 1271e3cd13f0e2d4e2ef30f8a57c0a82d328102eeb26Bill Wendling // 1272e3cd13f0e2d4e2ef30f8a57c0a82d328102eeb26Bill Wendling // # compact unwind for _foo 1273e3cd13f0e2d4e2ef30f8a57c0a82d328102eeb26Bill Wendling // .quad _foo 1274e3cd13f0e2d4e2ef30f8a57c0a82d328102eeb26Bill Wendling // .set L1,LfooEnd-_foo 1275e3cd13f0e2d4e2ef30f8a57c0a82d328102eeb26Bill Wendling // .long L1 1276e3cd13f0e2d4e2ef30f8a57c0a82d328102eeb26Bill Wendling // .long 0x01010001 1277e3cd13f0e2d4e2ef30f8a57c0a82d328102eeb26Bill Wendling // .quad 0 1278e3cd13f0e2d4e2ef30f8a57c0a82d328102eeb26Bill Wendling // .quad 0 1279e3cd13f0e2d4e2ef30f8a57c0a82d328102eeb26Bill Wendling // 1280e3cd13f0e2d4e2ef30f8a57c0a82d328102eeb26Bill Wendling // # compact unwind for _bar 1281e3cd13f0e2d4e2ef30f8a57c0a82d328102eeb26Bill Wendling // .quad _bar 1282e3cd13f0e2d4e2ef30f8a57c0a82d328102eeb26Bill Wendling // .set L2,LbarEnd-_bar 1283e3cd13f0e2d4e2ef30f8a57c0a82d328102eeb26Bill Wendling // .long L2 1284e3cd13f0e2d4e2ef30f8a57c0a82d328102eeb26Bill Wendling // .long 0x01020011 1285e3cd13f0e2d4e2ef30f8a57c0a82d328102eeb26Bill Wendling // .quad __gxx_personality 1286e3cd13f0e2d4e2ef30f8a57c0a82d328102eeb26Bill Wendling // .quad except_tab1 1287e3cd13f0e2d4e2ef30f8a57c0a82d328102eeb26Bill Wendling 1288e52e3f2c020354c8e0e966b719152b08349d0334Bill Wendling uint32_t Encoding = Frame.CompactUnwindEncoding; 1289fa2b25c57300dc9c518ea35bbc9dc8658fdbf454Bill Wendling if (!Encoding) return; 129062c75ad4301f07c94d7a231d2da9f9cd47b7824cBill Wendling bool DwarfEHFrameOnly = (Encoding == MOFI->getCompactUnwindDwarfEHFrameOnly()); 12916a6b8c3e96b9e1ca7092eafd0cfb219cbbfbdfc4Bill Wendling 12924bb5b037126ea35f35d5a490b03ccffa8677fa5eBill Wendling // The encoding needs to know we have an LSDA. 129362c75ad4301f07c94d7a231d2da9f9cd47b7824cBill Wendling if (!DwarfEHFrameOnly && Frame.Lsda) 12944bb5b037126ea35f35d5a490b03ccffa8677fa5eBill Wendling Encoding |= 0x40000000; 12954bb5b037126ea35f35d5a490b03ccffa8677fa5eBill Wendling 1296e3cd13f0e2d4e2ef30f8a57c0a82d328102eeb26Bill Wendling // Range Start 1297dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned FDEEncoding = MOFI->getFDEEncoding(); 12989056e9032001a2d47057cecec5e39895cbc31799Bill Wendling unsigned Size = getSizeForEncoding(Streamer, FDEEncoding); 12993c163cfa60f9f196cd6a5a04e07baec3947fee0bBill Wendling if (VerboseAsm) Streamer.AddComment("Range Start"); 1300cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Streamer.EmitSymbolValue(Frame.Begin, Size); 1301e3cd13f0e2d4e2ef30f8a57c0a82d328102eeb26Bill Wendling 1302e3cd13f0e2d4e2ef30f8a57c0a82d328102eeb26Bill Wendling // Range Length 1303e3cd13f0e2d4e2ef30f8a57c0a82d328102eeb26Bill Wendling const MCExpr *Range = MakeStartMinusEndExpr(Streamer, *Frame.Begin, 1304e3cd13f0e2d4e2ef30f8a57c0a82d328102eeb26Bill Wendling *Frame.End, 0); 13053c163cfa60f9f196cd6a5a04e07baec3947fee0bBill Wendling if (VerboseAsm) Streamer.AddComment("Range Length"); 13069287a6eef336585628a55e1f33e1e3ea9d7f81cfBill Wendling Streamer.EmitAbsValue(Range, 4); 13079287a6eef336585628a55e1f33e1e3ea9d7f81cfBill Wendling 13089287a6eef336585628a55e1f33e1e3ea9d7f81cfBill Wendling // Compact Encoding 13099287a6eef336585628a55e1f33e1e3ea9d7f81cfBill Wendling Size = getSizeForEncoding(Streamer, dwarf::DW_EH_PE_udata4); 131070be28a5adba5bcae0c6dcd63f17592864c351fcBenjamin Kramer if (VerboseAsm) Streamer.AddComment("Compact Unwind Encoding: 0x" + 131170be28a5adba5bcae0c6dcd63f17592864c351fcBenjamin Kramer Twine::utohexstr(Encoding)); 13129287a6eef336585628a55e1f33e1e3ea9d7f81cfBill Wendling Streamer.EmitIntValue(Encoding, Size); 13139287a6eef336585628a55e1f33e1e3ea9d7f81cfBill Wendling 13149056e9032001a2d47057cecec5e39895cbc31799Bill Wendling // Personality Function 13154bb5b037126ea35f35d5a490b03ccffa8677fa5eBill Wendling Size = getSizeForEncoding(Streamer, dwarf::DW_EH_PE_absptr); 13163c163cfa60f9f196cd6a5a04e07baec3947fee0bBill Wendling if (VerboseAsm) Streamer.AddComment("Personality Function"); 131762c75ad4301f07c94d7a231d2da9f9cd47b7824cBill Wendling if (!DwarfEHFrameOnly && Frame.Personality) 13189056e9032001a2d47057cecec5e39895cbc31799Bill Wendling Streamer.EmitSymbolValue(Frame.Personality, Size); 13194498d39680abe3970dc84dca973aff46d0f9039bBill Wendling else 13204498d39680abe3970dc84dca973aff46d0f9039bBill Wendling Streamer.EmitIntValue(0, Size); // No personality fn 13219056e9032001a2d47057cecec5e39895cbc31799Bill Wendling 13229056e9032001a2d47057cecec5e39895cbc31799Bill Wendling // LSDA 13234498d39680abe3970dc84dca973aff46d0f9039bBill Wendling Size = getSizeForEncoding(Streamer, Frame.LsdaEncoding); 13243c163cfa60f9f196cd6a5a04e07baec3947fee0bBill Wendling if (VerboseAsm) Streamer.AddComment("LSDA"); 132562c75ad4301f07c94d7a231d2da9f9cd47b7824cBill Wendling if (!DwarfEHFrameOnly && Frame.Lsda) 13269056e9032001a2d47057cecec5e39895cbc31799Bill Wendling Streamer.EmitSymbolValue(Frame.Lsda, Size); 13274498d39680abe3970dc84dca973aff46d0f9039bBill Wendling else 13284498d39680abe3970dc84dca973aff46d0f9039bBill Wendling Streamer.EmitIntValue(0, Size); // No LSDA 1329e3cd13f0e2d4e2ef30f8a57c0a82d328102eeb26Bill Wendling} 1330e3cd13f0e2d4e2ef30f8a57c0a82d328102eeb26Bill Wendling 1331dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesconst MCSymbol &FrameEmitterImpl::EmitCIE(MCObjectStreamer &streamer, 133225f492e77858dc5a95fcd7180e73aff47925b668Rafael Espindola const MCSymbol *personality, 133325f492e77858dc5a95fcd7180e73aff47925b668Rafael Espindola unsigned personalityEncoding, 133425f492e77858dc5a95fcd7180e73aff47925b668Rafael Espindola const MCSymbol *lsda, 133516d7d437e03ce87fdaef7971919302920d54a966Rafael Espindola bool IsSignalFrame, 133636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned lsdaEncoding, 133736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool IsSimple) { 133889b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola MCContext &context = streamer.getContext(); 133999cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling const MCRegisterInfo *MRI = context.getRegisterInfo(); 1340e76a33b9567d78a5744dc52fcec3a6056d6fb576Evan Cheng const MCObjectFileInfo *MOFI = context.getObjectFileInfo(); 13413c163cfa60f9f196cd6a5a04e07baec3947fee0bBill Wendling bool verboseAsm = streamer.isVerboseAsm(); 1342514cecc72b23bb75108844285ab8f3616a08bac5Rafael Espindola 1343cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MCSymbol *sectionStart = context.CreateTempSymbol(); 13443c163cfa60f9f196cd6a5a04e07baec3947fee0bBill Wendling streamer.EmitLabel(sectionStart); 1345514cecc72b23bb75108844285ab8f3616a08bac5Rafael Espindola CIENum++; 1346514cecc72b23bb75108844285ab8f3616a08bac5Rafael Espindola 13476a6b8c3e96b9e1ca7092eafd0cfb219cbbfbdfc4Bill Wendling MCSymbol *sectionEnd = context.CreateTempSymbol(); 134889b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola 134989b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola // Length 135089b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola const MCExpr *Length = MakeStartMinusEndExpr(streamer, *sectionStart, 135189b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola *sectionEnd, 4); 13523c163cfa60f9f196cd6a5a04e07baec3947fee0bBill Wendling if (verboseAsm) streamer.AddComment("CIE Length"); 13539266cc400ee2fc86abb24ab0819d9da280fb61c4Rafael Espindola streamer.EmitAbsValue(Length, 4); 135489b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola 135589b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola // CIE ID 135640a7dbbeff44c4cbd8c7e4f07f28dd614f8a5d08Rafael Espindola unsigned CIE_ID = IsEH ? 0 : -1; 13573c163cfa60f9f196cd6a5a04e07baec3947fee0bBill Wendling if (verboseAsm) streamer.AddComment("CIE ID Tag"); 135840a7dbbeff44c4cbd8c7e4f07f28dd614f8a5d08Rafael Espindola streamer.EmitIntValue(CIE_ID, 4); 135989b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola 136089b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola // Version 13613c163cfa60f9f196cd6a5a04e07baec3947fee0bBill Wendling if (verboseAsm) streamer.AddComment("DW_CIE_VERSION"); 1362cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // For DWARF2, we use CIE version 1 1363cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // For DWARF3+, we use CIE version 3 1364cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines uint8_t CIEVersion = context.getDwarfVersion() <= 2 ? 1 : 3; 1365cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines streamer.EmitIntValue(CIEVersion, 1); 136689b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola 136789b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola // Augmentation String 136889b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola SmallString<8> Augmentation; 136940a7dbbeff44c4cbd8c7e4f07f28dd614f8a5d08Rafael Espindola if (IsEH) { 13703c163cfa60f9f196cd6a5a04e07baec3947fee0bBill Wendling if (verboseAsm) streamer.AddComment("CIE Augmentation"); 137140a7dbbeff44c4cbd8c7e4f07f28dd614f8a5d08Rafael Espindola Augmentation += "z"; 137240a7dbbeff44c4cbd8c7e4f07f28dd614f8a5d08Rafael Espindola if (personality) 137340a7dbbeff44c4cbd8c7e4f07f28dd614f8a5d08Rafael Espindola Augmentation += "P"; 137440a7dbbeff44c4cbd8c7e4f07f28dd614f8a5d08Rafael Espindola if (lsda) 137540a7dbbeff44c4cbd8c7e4f07f28dd614f8a5d08Rafael Espindola Augmentation += "L"; 137640a7dbbeff44c4cbd8c7e4f07f28dd614f8a5d08Rafael Espindola Augmentation += "R"; 137716d7d437e03ce87fdaef7971919302920d54a966Rafael Espindola if (IsSignalFrame) 137816d7d437e03ce87fdaef7971919302920d54a966Rafael Espindola Augmentation += "S"; 137968ca56285f9b6e82eb16ff8ea02a301f2c489faeEric Christopher streamer.EmitBytes(Augmentation.str()); 138040a7dbbeff44c4cbd8c7e4f07f28dd614f8a5d08Rafael Espindola } 138189b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola streamer.EmitIntValue(0, 1); 138289b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola 138389b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola // Code Alignment Factor 13843c163cfa60f9f196cd6a5a04e07baec3947fee0bBill Wendling if (verboseAsm) streamer.AddComment("CIE Code Alignment Factor"); 138599cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling streamer.EmitULEB128IntValue(context.getAsmInfo()->getMinInstAlignment()); 138689b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola 138789b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola // Data Alignment Factor 13883c163cfa60f9f196cd6a5a04e07baec3947fee0bBill Wendling if (verboseAsm) streamer.AddComment("CIE Data Alignment Factor"); 138989b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola streamer.EmitSLEB128IntValue(getDataAlignmentFactor(streamer)); 139089b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola 139189b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola // Return Address Register 13923c163cfa60f9f196cd6a5a04e07baec3947fee0bBill Wendling if (verboseAsm) streamer.AddComment("CIE Return Address Column"); 1393cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (CIEVersion == 1) { 1394cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines assert(MRI->getRARegister() <= 255 && 1395cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines "DWARF 2 encodes return_address_register in one byte"); 1396cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines streamer.EmitIntValue(MRI->getDwarfRegNum(MRI->getRARegister(), true), 1); 1397cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } else { 1398cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines streamer.EmitULEB128IntValue( 1399cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MRI->getDwarfRegNum(MRI->getRARegister(), true)); 1400cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 140189b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola 140289b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola // Augmentation Data Length (optional) 14031f6c87554a0d78103b95816fd2c1ce392b366bcfRafael Espindola 14041f6c87554a0d78103b95816fd2c1ce392b366bcfRafael Espindola unsigned augmentationLength = 0; 140540a7dbbeff44c4cbd8c7e4f07f28dd614f8a5d08Rafael Espindola if (IsEH) { 140640a7dbbeff44c4cbd8c7e4f07f28dd614f8a5d08Rafael Espindola if (personality) { 140740a7dbbeff44c4cbd8c7e4f07f28dd614f8a5d08Rafael Espindola // Personality Encoding 140840a7dbbeff44c4cbd8c7e4f07f28dd614f8a5d08Rafael Espindola augmentationLength += 1; 140940a7dbbeff44c4cbd8c7e4f07f28dd614f8a5d08Rafael Espindola // Personality 141040a7dbbeff44c4cbd8c7e4f07f28dd614f8a5d08Rafael Espindola augmentationLength += getSizeForEncoding(streamer, personalityEncoding); 141140a7dbbeff44c4cbd8c7e4f07f28dd614f8a5d08Rafael Espindola } 141240a7dbbeff44c4cbd8c7e4f07f28dd614f8a5d08Rafael Espindola if (lsda) 141340a7dbbeff44c4cbd8c7e4f07f28dd614f8a5d08Rafael Espindola augmentationLength += 1; 141440a7dbbeff44c4cbd8c7e4f07f28dd614f8a5d08Rafael Espindola // Encoding of the FDE pointers 14151f6c87554a0d78103b95816fd2c1ce392b366bcfRafael Espindola augmentationLength += 1; 14161f6c87554a0d78103b95816fd2c1ce392b366bcfRafael Espindola 14173c163cfa60f9f196cd6a5a04e07baec3947fee0bBill Wendling if (verboseAsm) streamer.AddComment("Augmentation Size"); 141840a7dbbeff44c4cbd8c7e4f07f28dd614f8a5d08Rafael Espindola streamer.EmitULEB128IntValue(augmentationLength); 141989b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola 142040a7dbbeff44c4cbd8c7e4f07f28dd614f8a5d08Rafael Espindola // Augmentation Data (optional) 142140a7dbbeff44c4cbd8c7e4f07f28dd614f8a5d08Rafael Espindola if (personality) { 142240a7dbbeff44c4cbd8c7e4f07f28dd614f8a5d08Rafael Espindola // Personality Encoding 14233c163cfa60f9f196cd6a5a04e07baec3947fee0bBill Wendling EmitEncodingByte(streamer, personalityEncoding, 14243c163cfa60f9f196cd6a5a04e07baec3947fee0bBill Wendling "Personality Encoding"); 142540a7dbbeff44c4cbd8c7e4f07f28dd614f8a5d08Rafael Espindola // Personality 14263c163cfa60f9f196cd6a5a04e07baec3947fee0bBill Wendling if (verboseAsm) streamer.AddComment("Personality"); 142740a7dbbeff44c4cbd8c7e4f07f28dd614f8a5d08Rafael Espindola EmitPersonality(streamer, *personality, personalityEncoding); 142840a7dbbeff44c4cbd8c7e4f07f28dd614f8a5d08Rafael Espindola } 14293c163cfa60f9f196cd6a5a04e07baec3947fee0bBill Wendling 143040a7dbbeff44c4cbd8c7e4f07f28dd614f8a5d08Rafael Espindola if (lsda) 14313c163cfa60f9f196cd6a5a04e07baec3947fee0bBill Wendling EmitEncodingByte(streamer, lsdaEncoding, "LSDA Encoding"); 14323c163cfa60f9f196cd6a5a04e07baec3947fee0bBill Wendling 143340a7dbbeff44c4cbd8c7e4f07f28dd614f8a5d08Rafael Espindola // Encoding of the FDE pointers 1434dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines EmitEncodingByte(streamer, MOFI->getFDEEncoding(), "FDE Encoding"); 1435bdc3167c086dd4358e24692075db5e7784140843Rafael Espindola } 143689b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola 143789b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola // Initial Instructions 143889b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola 143999cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling const MCAsmInfo *MAI = context.getAsmInfo(); 144036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!IsSimple) { 144136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const std::vector<MCCFIInstruction> &Instructions = 144236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MAI->getInitialFrameState(); 1443dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines EmitCFIInstructions(streamer, Instructions, nullptr); 144436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 144589b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola 144689b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola // Padding 144799cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling streamer.EmitValueToAlignment(IsEH ? 4 : MAI->getPointerSize()); 144889b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola 144989b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola streamer.EmitLabel(sectionEnd); 145089b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola return *sectionStart; 145189b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola} 145289b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola 1453dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesMCSymbol *FrameEmitterImpl::EmitFDE(MCObjectStreamer &streamer, 145425f492e77858dc5a95fcd7180e73aff47925b668Rafael Espindola const MCSymbol &cieStart, 14559f270dadd429771dded5a8572da8c74513771c15Rafael Espindola const MCDwarfFrameInfo &frame) { 1456bdc3167c086dd4358e24692075db5e7784140843Rafael Espindola MCContext &context = streamer.getContext(); 1457bdc3167c086dd4358e24692075db5e7784140843Rafael Espindola MCSymbol *fdeStart = context.CreateTempSymbol(); 1458bdc3167c086dd4358e24692075db5e7784140843Rafael Espindola MCSymbol *fdeEnd = context.CreateTempSymbol(); 1459e76a33b9567d78a5744dc52fcec3a6056d6fb576Evan Cheng const MCObjectFileInfo *MOFI = context.getObjectFileInfo(); 14602541c41f3e2af94585e14353a91f02facd65e415Bill Wendling bool verboseAsm = streamer.isVerboseAsm(); 146189b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola 146289b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola // Length 146389b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola const MCExpr *Length = MakeStartMinusEndExpr(streamer, *fdeStart, *fdeEnd, 0); 14642541c41f3e2af94585e14353a91f02facd65e415Bill Wendling if (verboseAsm) streamer.AddComment("FDE Length"); 14659266cc400ee2fc86abb24ab0819d9da280fb61c4Rafael Espindola streamer.EmitAbsValue(Length, 4); 146689b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola 146789b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola streamer.EmitLabel(fdeStart); 1468e3a0e987f3d4f07512cdb64b9034369f966cb448Rafael Espindola 146989b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola // CIE Pointer 147099cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling const MCAsmInfo *asmInfo = context.getAsmInfo(); 14710d450dc65906a30beb56aeb1ee22b45b1cd4596cRafael Espindola if (IsEH) { 14720d450dc65906a30beb56aeb1ee22b45b1cd4596cRafael Espindola const MCExpr *offset = MakeStartMinusEndExpr(streamer, cieStart, *fdeStart, 14730d450dc65906a30beb56aeb1ee22b45b1cd4596cRafael Espindola 0); 14742541c41f3e2af94585e14353a91f02facd65e415Bill Wendling if (verboseAsm) streamer.AddComment("FDE CIE Offset"); 14750d450dc65906a30beb56aeb1ee22b45b1cd4596cRafael Espindola streamer.EmitAbsValue(offset, 4); 147699cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling } else if (!asmInfo->doesDwarfUseRelocationsAcrossSections()) { 1477e3a0e987f3d4f07512cdb64b9034369f966cb448Rafael Espindola const MCExpr *offset = MakeStartMinusEndExpr(streamer, *SectionStart, 1478e3a0e987f3d4f07512cdb64b9034369f966cb448Rafael Espindola cieStart, 0); 1479e3a0e987f3d4f07512cdb64b9034369f966cb448Rafael Espindola streamer.EmitAbsValue(offset, 4); 14800d450dc65906a30beb56aeb1ee22b45b1cd4596cRafael Espindola } else { 14810d450dc65906a30beb56aeb1ee22b45b1cd4596cRafael Espindola streamer.EmitSymbolValue(&cieStart, 4); 14820d450dc65906a30beb56aeb1ee22b45b1cd4596cRafael Espindola } 14832541c41f3e2af94585e14353a91f02facd65e415Bill Wendling 148489b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola // PC Begin 1485dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines unsigned PCEncoding = 1486dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines IsEH ? MOFI->getFDEEncoding() : (unsigned)dwarf::DW_EH_PE_absptr; 14870c5602de8c0dfa716f54306a1c540b98ab803584Nick Lewycky unsigned PCSize = getSizeForEncoding(streamer, PCEncoding); 148836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EmitFDESymbol(streamer, *frame.Begin, PCEncoding, IsEH, "FDE initial location"); 148989b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola 149089b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola // PC Range 149189b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola const MCExpr *Range = MakeStartMinusEndExpr(streamer, *frame.Begin, 149289b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola *frame.End, 0); 14932541c41f3e2af94585e14353a91f02facd65e415Bill Wendling if (verboseAsm) streamer.AddComment("FDE address range"); 14940c5602de8c0dfa716f54306a1c540b98ab803584Nick Lewycky streamer.EmitAbsValue(Range, PCSize); 149589b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola 149640a7dbbeff44c4cbd8c7e4f07f28dd614f8a5d08Rafael Espindola if (IsEH) { 149740a7dbbeff44c4cbd8c7e4f07f28dd614f8a5d08Rafael Espindola // Augmentation Data Length 149840a7dbbeff44c4cbd8c7e4f07f28dd614f8a5d08Rafael Espindola unsigned augmentationLength = 0; 14991f6c87554a0d78103b95816fd2c1ce392b366bcfRafael Espindola 150040a7dbbeff44c4cbd8c7e4f07f28dd614f8a5d08Rafael Espindola if (frame.Lsda) 150140a7dbbeff44c4cbd8c7e4f07f28dd614f8a5d08Rafael Espindola augmentationLength += getSizeForEncoding(streamer, frame.LsdaEncoding); 15021f6c87554a0d78103b95816fd2c1ce392b366bcfRafael Espindola 15032541c41f3e2af94585e14353a91f02facd65e415Bill Wendling if (verboseAsm) streamer.AddComment("Augmentation size"); 150440a7dbbeff44c4cbd8c7e4f07f28dd614f8a5d08Rafael Espindola streamer.EmitULEB128IntValue(augmentationLength); 150589b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola 150640a7dbbeff44c4cbd8c7e4f07f28dd614f8a5d08Rafael Espindola // Augmentation Data 150740a7dbbeff44c4cbd8c7e4f07f28dd614f8a5d08Rafael Espindola if (frame.Lsda) 150836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EmitFDESymbol(streamer, *frame.Lsda, frame.LsdaEncoding, true, 150936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines "Language Specific Data Area"); 151040a7dbbeff44c4cbd8c7e4f07f28dd614f8a5d08Rafael Espindola } 15114892dff07e7d99eb37aee868c4f2c91e9c7eba14Rafael Espindola 151289b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola // Call Frame Instructions 1513b40a71fda188f8ca564e606ac2cb051a44ada311Rafael Espindola EmitCFIInstructions(streamer, frame.Instructions, frame.Begin); 15145bba08425374ca36fe5fbc7423ce1a09858e4097Rafael Espindola 151589b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola // Padding 15160c5602de8c0dfa716f54306a1c540b98ab803584Nick Lewycky streamer.EmitValueToAlignment(PCSize); 1517dfe125cc9cfd524575973daa297c9aad10470390Rafael Espindola 1518dfe125cc9cfd524575973daa297c9aad10470390Rafael Espindola return fdeEnd; 151989b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola} 152089b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola 152119282365147f498a60463d250dbed2f8e1b81861Benjamin Kramernamespace { 152219282365147f498a60463d250dbed2f8e1b81861Benjamin Kramer struct CIEKey { 1523dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines static const CIEKey getEmptyKey() { 1524dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return CIEKey(nullptr, 0, -1, false, false); 1525dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 1526dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines static const CIEKey getTombstoneKey() { 1527dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return CIEKey(nullptr, -1, 0, false, false); 1528dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 152919282365147f498a60463d250dbed2f8e1b81861Benjamin Kramer 1530cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines CIEKey(const MCSymbol *Personality_, unsigned PersonalityEncoding_, 1531cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines unsigned LsdaEncoding_, bool IsSignalFrame_, bool IsSimple_) 1532cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines : Personality(Personality_), PersonalityEncoding(PersonalityEncoding_), 1533cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines LsdaEncoding(LsdaEncoding_), IsSignalFrame(IsSignalFrame_), 1534cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines IsSimple(IsSimple_) {} 1535cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines const MCSymbol *Personality; 153619282365147f498a60463d250dbed2f8e1b81861Benjamin Kramer unsigned PersonalityEncoding; 153719282365147f498a60463d250dbed2f8e1b81861Benjamin Kramer unsigned LsdaEncoding; 153816d7d437e03ce87fdaef7971919302920d54a966Rafael Espindola bool IsSignalFrame; 153936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool IsSimple; 154019282365147f498a60463d250dbed2f8e1b81861Benjamin Kramer }; 154119282365147f498a60463d250dbed2f8e1b81861Benjamin Kramer} 1542bdc3167c086dd4358e24692075db5e7784140843Rafael Espindola 1543bdc3167c086dd4358e24692075db5e7784140843Rafael Espindolanamespace llvm { 1544bdc3167c086dd4358e24692075db5e7784140843Rafael Espindola template <> 1545bdc3167c086dd4358e24692075db5e7784140843Rafael Espindola struct DenseMapInfo<CIEKey> { 1546bdc3167c086dd4358e24692075db5e7784140843Rafael Espindola static CIEKey getEmptyKey() { 154719282365147f498a60463d250dbed2f8e1b81861Benjamin Kramer return CIEKey::getEmptyKey(); 1548bdc3167c086dd4358e24692075db5e7784140843Rafael Espindola } 1549bdc3167c086dd4358e24692075db5e7784140843Rafael Espindola static CIEKey getTombstoneKey() { 155019282365147f498a60463d250dbed2f8e1b81861Benjamin Kramer return CIEKey::getTombstoneKey(); 1551bdc3167c086dd4358e24692075db5e7784140843Rafael Espindola } 1552bdc3167c086dd4358e24692075db5e7784140843Rafael Espindola static unsigned getHashValue(const CIEKey &Key) { 15537484920cf5d95b21fa750229f8ce0d1624c918ecBenjamin Kramer return static_cast<unsigned>(hash_combine(Key.Personality, 15547484920cf5d95b21fa750229f8ce0d1624c918ecBenjamin Kramer Key.PersonalityEncoding, 15557484920cf5d95b21fa750229f8ce0d1624c918ecBenjamin Kramer Key.LsdaEncoding, 155636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Key.IsSignalFrame, 155736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Key.IsSimple)); 1558bdc3167c086dd4358e24692075db5e7784140843Rafael Espindola } 1559bdc3167c086dd4358e24692075db5e7784140843Rafael Espindola static bool isEqual(const CIEKey &LHS, 1560bdc3167c086dd4358e24692075db5e7784140843Rafael Espindola const CIEKey &RHS) { 1561bdc3167c086dd4358e24692075db5e7784140843Rafael Espindola return LHS.Personality == RHS.Personality && 1562bdc3167c086dd4358e24692075db5e7784140843Rafael Espindola LHS.PersonalityEncoding == RHS.PersonalityEncoding && 156316d7d437e03ce87fdaef7971919302920d54a966Rafael Espindola LHS.LsdaEncoding == RHS.LsdaEncoding && 156436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines LHS.IsSignalFrame == RHS.IsSignalFrame && 156536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines LHS.IsSimple == RHS.IsSimple; 1566bdc3167c086dd4358e24692075db5e7784140843Rafael Espindola } 1567bdc3167c086dd4358e24692075db5e7784140843Rafael Espindola }; 1568bdc3167c086dd4358e24692075db5e7784140843Rafael Espindola} 1569bdc3167c086dd4358e24692075db5e7784140843Rafael Espindola 1570dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid MCDwarfFrameEmitter::Emit(MCObjectStreamer &Streamer, MCAsmBackend *MAB, 1571dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines bool IsEH) { 1572da11df0c22f5d0ba2e2be3ae4a7076c806233db8Bill Wendling Streamer.generateCompactUnwindEncodings(MAB); 1573da11df0c22f5d0ba2e2be3ae4a7076c806233db8Bill Wendling 1574a8c9e6a943bc0873d1ce781d2444a6d6137f0e17Bill Wendling MCContext &Context = Streamer.getContext(); 157579b40f10c00d38f81272bc683bd94e24607f3897Bill Wendling const MCObjectFileInfo *MOFI = Context.getObjectFileInfo(); 1576dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines FrameEmitterImpl Emitter(IsEH); 1577d8ab8e9707e6170218ce82516d15b36f54b4bc1cBill Wendling ArrayRef<MCDwarfFrameInfo> FrameArray = Streamer.getFrameInfos(); 15781424c3c3e696868775ac5bfc57d27a0ac3bc6c63Bill Wendling 1579d8ab8e9707e6170218ce82516d15b36f54b4bc1cBill Wendling // Emit the compact unwind info if available. 158036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool NeedsEHFrameSection = !MOFI->getSupportsCompactUnwindWithoutEHFrame(); 1581c60e252ef6d795170c3f32e276c8f6f77d56783eBill Wendling if (IsEH && MOFI->getCompactUnwindSection()) { 1582c60e252ef6d795170c3f32e276c8f6f77d56783eBill Wendling bool SectionEmitted = false; 158332ec93d431c54b6227a978201813398ffaaeff17Bob Wilson for (unsigned i = 0, n = FrameArray.size(); i < n; ++i) { 158432ec93d431c54b6227a978201813398ffaaeff17Bob Wilson const MCDwarfFrameInfo &Frame = FrameArray[i]; 158532ec93d431c54b6227a978201813398ffaaeff17Bob Wilson if (Frame.CompactUnwindEncoding == 0) continue; 158632ec93d431c54b6227a978201813398ffaaeff17Bob Wilson if (!SectionEmitted) { 158732ec93d431c54b6227a978201813398ffaaeff17Bob Wilson Streamer.SwitchSection(MOFI->getCompactUnwindSection()); 158899cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling Streamer.EmitValueToAlignment(Context.getAsmInfo()->getPointerSize()); 158932ec93d431c54b6227a978201813398ffaaeff17Bob Wilson SectionEmitted = true; 1590c60e252ef6d795170c3f32e276c8f6f77d56783eBill Wendling } 159136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines NeedsEHFrameSection |= 159236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Frame.CompactUnwindEncoding == 159336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MOFI->getCompactUnwindDwarfEHFrameOnly(); 159432ec93d431c54b6227a978201813398ffaaeff17Bob Wilson Emitter.EmitCompactUnwind(Streamer, Frame); 15951424c3c3e696868775ac5bfc57d27a0ac3bc6c63Bill Wendling } 1596c60e252ef6d795170c3f32e276c8f6f77d56783eBill Wendling } 15971424c3c3e696868775ac5bfc57d27a0ac3bc6c63Bill Wendling 159836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!NeedsEHFrameSection) return; 159936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 160079b40f10c00d38f81272bc683bd94e24607f3897Bill Wendling const MCSection &Section = 160179b40f10c00d38f81272bc683bd94e24607f3897Bill Wendling IsEH ? *const_cast<MCObjectFileInfo*>(MOFI)->getEHFrameSection() : 160279b40f10c00d38f81272bc683bd94e24607f3897Bill Wendling *MOFI->getDwarfFrameSection(); 160336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 1604a8c9e6a943bc0873d1ce781d2444a6d6137f0e17Bill Wendling Streamer.SwitchSection(&Section); 1605a8c9e6a943bc0873d1ce781d2444a6d6137f0e17Bill Wendling MCSymbol *SectionStart = Context.CreateTempSymbol(); 1606a8c9e6a943bc0873d1ce781d2444a6d6137f0e17Bill Wendling Streamer.EmitLabel(SectionStart); 16071424c3c3e696868775ac5bfc57d27a0ac3bc6c63Bill Wendling Emitter.setSectionStart(SectionStart); 1608a8c9e6a943bc0873d1ce781d2444a6d6137f0e17Bill Wendling 1609dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MCSymbol *FDEEnd = nullptr; 1610cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines DenseMap<CIEKey, const MCSymbol *> CIEStarts; 1611d7c8ccae8e48dce3ab7c3e9b4d8a309998c47961Rafael Espindola 1612dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const MCSymbol *DummyDebugKey = nullptr; 161336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines NeedsEHFrameSection = !MOFI->getSupportsCompactUnwindWithoutEHFrame(); 16141424c3c3e696868775ac5bfc57d27a0ac3bc6c63Bill Wendling for (unsigned i = 0, n = FrameArray.size(); i < n; ++i) { 16151424c3c3e696868775ac5bfc57d27a0ac3bc6c63Bill Wendling const MCDwarfFrameInfo &Frame = FrameArray[i]; 161636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 161736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Emit the label from the previous iteration 161836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (FDEEnd) { 161936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Streamer.EmitLabel(FDEEnd); 1620dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines FDEEnd = nullptr; 162136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 162236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 162336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!NeedsEHFrameSection && Frame.CompactUnwindEncoding != 162436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MOFI->getCompactUnwindDwarfEHFrameOnly()) 162536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Don't generate an EH frame if we don't need one. I.e., it's taken care 162636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // of by the compact unwind encoding. 162736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines continue; 162836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 1629a8c9e6a943bc0873d1ce781d2444a6d6137f0e17Bill Wendling CIEKey Key(Frame.Personality, Frame.PersonalityEncoding, 163036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Frame.LsdaEncoding, Frame.IsSignalFrame, Frame.IsSimple); 1631a8c9e6a943bc0873d1ce781d2444a6d6137f0e17Bill Wendling const MCSymbol *&CIEStart = IsEH ? CIEStarts[Key] : DummyDebugKey; 1632a8c9e6a943bc0873d1ce781d2444a6d6137f0e17Bill Wendling if (!CIEStart) 1633a8c9e6a943bc0873d1ce781d2444a6d6137f0e17Bill Wendling CIEStart = &Emitter.EmitCIE(Streamer, Frame.Personality, 1634a8c9e6a943bc0873d1ce781d2444a6d6137f0e17Bill Wendling Frame.PersonalityEncoding, Frame.Lsda, 163516d7d437e03ce87fdaef7971919302920d54a966Rafael Espindola Frame.IsSignalFrame, 163636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Frame.LsdaEncoding, 163736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Frame.IsSimple); 1638e3cd13f0e2d4e2ef30f8a57c0a82d328102eeb26Bill Wendling 1639a8c9e6a943bc0873d1ce781d2444a6d6137f0e17Bill Wendling FDEEnd = Emitter.EmitFDE(Streamer, *CIEStart, Frame); 1640dfe125cc9cfd524575973daa297c9aad10470390Rafael Espindola } 1641d7c8ccae8e48dce3ab7c3e9b4d8a309998c47961Rafael Espindola 164299cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling Streamer.EmitValueToAlignment(Context.getAsmInfo()->getPointerSize()); 1643a8c9e6a943bc0873d1ce781d2444a6d6137f0e17Bill Wendling if (FDEEnd) 1644a8c9e6a943bc0873d1ce781d2444a6d6137f0e17Bill Wendling Streamer.EmitLabel(FDEEnd); 164589b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola} 1646245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola 1647dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid MCDwarfFrameEmitter::EmitAdvanceLoc(MCObjectStreamer &Streamer, 1648245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola uint64_t AddrDelta) { 1649c1f4a4b2640dfc871bacacef53a95f1c96a9fe48Ulrich Weigand MCContext &Context = Streamer.getContext(); 1650245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola SmallString<256> Tmp; 1651245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola raw_svector_ostream OS(Tmp); 1652c1f4a4b2640dfc871bacacef53a95f1c96a9fe48Ulrich Weigand MCDwarfFrameEmitter::EncodeAdvanceLoc(Context, AddrDelta, OS); 165368ca56285f9b6e82eb16ff8ea02a301f2c489faeEric Christopher Streamer.EmitBytes(OS.str()); 1654245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola} 1655245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola 1656c1f4a4b2640dfc871bacacef53a95f1c96a9fe48Ulrich Weigandvoid MCDwarfFrameEmitter::EncodeAdvanceLoc(MCContext &Context, 1657c1f4a4b2640dfc871bacacef53a95f1c96a9fe48Ulrich Weigand uint64_t AddrDelta, 16584eafe109459eb115f13f1d19c5ff3cb3678e8c7aRafael Espindola raw_ostream &OS) { 1659c1f4a4b2640dfc871bacacef53a95f1c96a9fe48Ulrich Weigand // Scale the address delta by the minimum instruction length. 1660c1f4a4b2640dfc871bacacef53a95f1c96a9fe48Ulrich Weigand AddrDelta = ScaleAddrDelta(Context, AddrDelta); 1661c1f4a4b2640dfc871bacacef53a95f1c96a9fe48Ulrich Weigand 16623b78cdc57ae25ff021fd67171a7c82d533477a19Rafael Espindola if (AddrDelta == 0) { 16634eafe109459eb115f13f1d19c5ff3cb3678e8c7aRafael Espindola } else if (isUIntN(6, AddrDelta)) { 1664245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola uint8_t Opcode = dwarf::DW_CFA_advance_loc | AddrDelta; 1665245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola OS << Opcode; 16664eafe109459eb115f13f1d19c5ff3cb3678e8c7aRafael Espindola } else if (isUInt<8>(AddrDelta)) { 1667245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola OS << uint8_t(dwarf::DW_CFA_advance_loc1); 1668245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola OS << uint8_t(AddrDelta); 16694eafe109459eb115f13f1d19c5ff3cb3678e8c7aRafael Espindola } else if (isUInt<16>(AddrDelta)) { 1670a7e450574c45209ca0b05ff715f9e7dddcbd936cRafael Espindola // FIXME: check what is the correct behavior on a big endian machine. 1671245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola OS << uint8_t(dwarf::DW_CFA_advance_loc2); 1672a7e450574c45209ca0b05ff715f9e7dddcbd936cRafael Espindola OS << uint8_t( AddrDelta & 0xff); 1673a7e450574c45209ca0b05ff715f9e7dddcbd936cRafael Espindola OS << uint8_t((AddrDelta >> 8) & 0xff); 1674245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola } else { 1675a7e450574c45209ca0b05ff715f9e7dddcbd936cRafael Espindola // FIXME: check what is the correct behavior on a big endian machine. 1676245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola assert(isUInt<32>(AddrDelta)); 1677245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola OS << uint8_t(dwarf::DW_CFA_advance_loc4); 1678a7e450574c45209ca0b05ff715f9e7dddcbd936cRafael Espindola OS << uint8_t( AddrDelta & 0xff); 1679a7e450574c45209ca0b05ff715f9e7dddcbd936cRafael Espindola OS << uint8_t((AddrDelta >> 8) & 0xff); 1680a7e450574c45209ca0b05ff715f9e7dddcbd936cRafael Espindola OS << uint8_t((AddrDelta >> 16) & 0xff); 1681a7e450574c45209ca0b05ff715f9e7dddcbd936cRafael Espindola OS << uint8_t((AddrDelta >> 24) & 0xff); 1682a7e450574c45209ca0b05ff715f9e7dddcbd936cRafael Espindola 1683245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola } 1684245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola} 1685