MCDwarf.cpp 57 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557
  1. //===- lib/MC/MCDwarf.cpp - MCDwarf implementation ------------------------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. #include "llvm/MC/MCDwarf.h"
  10. #include "llvm/ADT/Hashing.h"
  11. #include "llvm/ADT/SmallString.h"
  12. #include "llvm/ADT/Twine.h"
  13. #include "llvm/Config/config.h"
  14. #include "llvm/MC/MCAsmInfo.h"
  15. #include "llvm/MC/MCContext.h"
  16. #include "llvm/MC/MCExpr.h"
  17. #include "llvm/MC/MCObjectFileInfo.h"
  18. #include "llvm/MC/MCObjectWriter.h"
  19. #include "llvm/MC/MCRegisterInfo.h"
  20. #include "llvm/MC/MCStreamer.h"
  21. #include "llvm/MC/MCSymbol.h"
  22. #include "llvm/Support/Debug.h"
  23. #include "llvm/Support/ErrorHandling.h"
  24. #include "llvm/Support/LEB128.h"
  25. #include "llvm/Support/Path.h"
  26. #include "llvm/Support/SourceMgr.h"
  27. #include "llvm/Support/raw_ostream.h"
  28. using namespace llvm;
  29. // Given a special op, return the address skip amount (in units of
  30. // DWARF2_LINE_MIN_INSN_LENGTH.
  31. #define SPECIAL_ADDR(op) (((op) - DWARF2_LINE_OPCODE_BASE)/DWARF2_LINE_RANGE)
  32. // The maximum address skip amount that can be encoded with a special op.
  33. #define MAX_SPECIAL_ADDR_DELTA SPECIAL_ADDR(255)
  34. // First special line opcode - leave room for the standard opcodes.
  35. // Note: If you want to change this, you'll have to update the
  36. // "standard_opcode_lengths" table that is emitted in DwarfFileTable::Emit().
  37. #define DWARF2_LINE_OPCODE_BASE 13
  38. // Minimum line offset in a special line info. opcode. This value
  39. // was chosen to give a reasonable range of values.
  40. #define DWARF2_LINE_BASE -5
  41. // Range of line offsets in a special line info. opcode.
  42. #define DWARF2_LINE_RANGE 14
  43. // Define the architecture-dependent minimum instruction length (in bytes).
  44. // This value should be rather too small than too big.
  45. #define DWARF2_LINE_MIN_INSN_LENGTH 1
  46. // Note: when DWARF2_LINE_MIN_INSN_LENGTH == 1 which is the current setting,
  47. // this routine is a nop and will be optimized away.
  48. static inline uint64_t ScaleAddrDelta(uint64_t AddrDelta) {
  49. if (DWARF2_LINE_MIN_INSN_LENGTH == 1)
  50. return AddrDelta;
  51. if (AddrDelta % DWARF2_LINE_MIN_INSN_LENGTH != 0) {
  52. // TODO: report this error, but really only once.
  53. ;
  54. }
  55. return AddrDelta / DWARF2_LINE_MIN_INSN_LENGTH;
  56. }
  57. //
  58. // This is called when an instruction is assembled into the specified section
  59. // and if there is information from the last .loc directive that has yet to have
  60. // a line entry made for it is made.
  61. //
  62. void MCLineEntry::Make(MCStreamer *MCOS, const MCSection *Section) {
  63. if (!MCOS->getContext().getDwarfLocSeen())
  64. return;
  65. // Create a symbol at in the current section for use in the line entry.
  66. MCSymbol *LineSym = MCOS->getContext().CreateTempSymbol();
  67. // Set the value of the symbol to use for the MCLineEntry.
  68. MCOS->EmitLabel(LineSym);
  69. // Get the current .loc info saved in the context.
  70. const MCDwarfLoc &DwarfLoc = MCOS->getContext().getCurrentDwarfLoc();
  71. // Create a (local) line entry with the symbol and the current .loc info.
  72. MCLineEntry LineEntry(LineSym, DwarfLoc);
  73. // clear DwarfLocSeen saying the current .loc info is now used.
  74. MCOS->getContext().ClearDwarfLocSeen();
  75. // Get the MCLineSection for this section, if one does not exist for this
  76. // section create it.
  77. const DenseMap<const MCSection *, MCLineSection *> &MCLineSections =
  78. MCOS->getContext().getMCLineSections();
  79. MCLineSection *LineSection = MCLineSections.lookup(Section);
  80. if (!LineSection) {
  81. // Create a new MCLineSection. This will be deleted after the dwarf line
  82. // table is created using it by iterating through the MCLineSections
  83. // DenseMap.
  84. LineSection = new MCLineSection;
  85. // Save a pointer to the new LineSection into the MCLineSections DenseMap.
  86. MCOS->getContext().addMCLineSection(Section, LineSection);
  87. }
  88. // Add the line entry to this section's entries.
  89. LineSection->addLineEntry(LineEntry,
  90. MCOS->getContext().getDwarfCompileUnitID());
  91. }
  92. //
  93. // This helper routine returns an expression of End - Start + IntVal .
  94. //
  95. static inline const MCExpr *MakeStartMinusEndExpr(const MCStreamer &MCOS,
  96. const MCSymbol &Start,
  97. const MCSymbol &End,
  98. int IntVal) {
  99. MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
  100. const MCExpr *Res =
  101. MCSymbolRefExpr::Create(&End, Variant, MCOS.getContext());
  102. const MCExpr *RHS =
  103. MCSymbolRefExpr::Create(&Start, Variant, MCOS.getContext());
  104. const MCExpr *Res1 =
  105. MCBinaryExpr::Create(MCBinaryExpr::Sub, Res, RHS, MCOS.getContext());
  106. const MCExpr *Res2 =
  107. MCConstantExpr::Create(IntVal, MCOS.getContext());
  108. const MCExpr *Res3 =
  109. MCBinaryExpr::Create(MCBinaryExpr::Sub, Res1, Res2, MCOS.getContext());
  110. return Res3;
  111. }
  112. //
  113. // This emits the Dwarf line table for the specified section from the entries
  114. // in the LineSection.
  115. //
  116. static inline void EmitDwarfLineTable(MCStreamer *MCOS,
  117. const MCSection *Section,
  118. const MCLineSection *LineSection,
  119. unsigned CUID) {
  120. // This LineSection does not contain any LineEntry for the given Compile Unit.
  121. if (!LineSection->containEntriesForID(CUID))
  122. return;
  123. unsigned FileNum = 1;
  124. unsigned LastLine = 1;
  125. unsigned Column = 0;
  126. unsigned Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0;
  127. unsigned Isa = 0;
  128. MCSymbol *LastLabel = NULL;
  129. // Loop through each MCLineEntry and encode the dwarf line number table.
  130. for (MCLineSection::const_iterator
  131. it = LineSection->getMCLineEntries(CUID).begin(),
  132. ie = LineSection->getMCLineEntries(CUID).end(); it != ie; ++it) {
  133. if (FileNum != it->getFileNum()) {
  134. FileNum = it->getFileNum();
  135. MCOS->EmitIntValue(dwarf::DW_LNS_set_file, 1);
  136. MCOS->EmitULEB128IntValue(FileNum);
  137. }
  138. if (Column != it->getColumn()) {
  139. Column = it->getColumn();
  140. MCOS->EmitIntValue(dwarf::DW_LNS_set_column, 1);
  141. MCOS->EmitULEB128IntValue(Column);
  142. }
  143. if (Isa != it->getIsa()) {
  144. Isa = it->getIsa();
  145. MCOS->EmitIntValue(dwarf::DW_LNS_set_isa, 1);
  146. MCOS->EmitULEB128IntValue(Isa);
  147. }
  148. if ((it->getFlags() ^ Flags) & DWARF2_FLAG_IS_STMT) {
  149. Flags = it->getFlags();
  150. MCOS->EmitIntValue(dwarf::DW_LNS_negate_stmt, 1);
  151. }
  152. if (it->getFlags() & DWARF2_FLAG_BASIC_BLOCK)
  153. MCOS->EmitIntValue(dwarf::DW_LNS_set_basic_block, 1);
  154. if (it->getFlags() & DWARF2_FLAG_PROLOGUE_END)
  155. MCOS->EmitIntValue(dwarf::DW_LNS_set_prologue_end, 1);
  156. if (it->getFlags() & DWARF2_FLAG_EPILOGUE_BEGIN)
  157. MCOS->EmitIntValue(dwarf::DW_LNS_set_epilogue_begin, 1);
  158. int64_t LineDelta = static_cast<int64_t>(it->getLine()) - LastLine;
  159. MCSymbol *Label = it->getLabel();
  160. // At this point we want to emit/create the sequence to encode the delta in
  161. // line numbers and the increment of the address from the previous Label
  162. // and the current Label.
  163. const MCAsmInfo &asmInfo = MCOS->getContext().getAsmInfo();
  164. MCOS->EmitDwarfAdvanceLineAddr(LineDelta, LastLabel, Label,
  165. asmInfo.getPointerSize());
  166. LastLine = it->getLine();
  167. LastLabel = Label;
  168. }
  169. // Emit a DW_LNE_end_sequence for the end of the section.
  170. // Using the pointer Section create a temporary label at the end of the
  171. // section and use that and the LastLabel to compute the address delta
  172. // and use INT64_MAX as the line delta which is the signal that this is
  173. // actually a DW_LNE_end_sequence.
  174. // Switch to the section to be able to create a symbol at its end.
  175. MCOS->SwitchSection(Section);
  176. MCContext &context = MCOS->getContext();
  177. // Create a symbol at the end of the section.
  178. MCSymbol *SectionEnd = context.CreateTempSymbol();
  179. // Set the value of the symbol, as we are at the end of the section.
  180. MCOS->EmitLabel(SectionEnd);
  181. // Switch back the dwarf line section.
  182. MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfLineSection());
  183. const MCAsmInfo &asmInfo = MCOS->getContext().getAsmInfo();
  184. MCOS->EmitDwarfAdvanceLineAddr(INT64_MAX, LastLabel, SectionEnd,
  185. asmInfo.getPointerSize());
  186. }
  187. //
  188. // This emits the Dwarf file and the line tables.
  189. //
  190. const MCSymbol *MCDwarfFileTable::Emit(MCStreamer *MCOS) {
  191. MCContext &context = MCOS->getContext();
  192. // Switch to the section where the table will be emitted into.
  193. MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfLineSection());
  194. const DenseMap<unsigned, MCSymbol *> &MCLineTableSymbols =
  195. MCOS->getContext().getMCLineTableSymbols();
  196. // CUID and MCLineTableSymbols are set in DwarfDebug, when DwarfDebug does
  197. // not exist, CUID will be 0 and MCLineTableSymbols will be empty.
  198. // Handle Compile Unit 0, the line table start symbol is the section symbol.
  199. const MCSymbol *LineStartSym = EmitCU(MCOS, 0);
  200. // Handle the rest of the Compile Units.
  201. for (unsigned Is = 1, Ie = MCLineTableSymbols.size(); Is < Ie; Is++)
  202. EmitCU(MCOS, Is);
  203. // Now delete the MCLineSections that were created in MCLineEntry::Make()
  204. // and used to emit the line table.
  205. const DenseMap<const MCSection *, MCLineSection *> &MCLineSections =
  206. MCOS->getContext().getMCLineSections();
  207. for (DenseMap<const MCSection *, MCLineSection *>::const_iterator it =
  208. MCLineSections.begin(), ie = MCLineSections.end(); it != ie;
  209. ++it)
  210. delete it->second;
  211. return LineStartSym;
  212. }
  213. const MCSymbol *MCDwarfFileTable::EmitCU(MCStreamer *MCOS, unsigned CUID) {
  214. MCContext &context = MCOS->getContext();
  215. // Create a symbol at the beginning of the line table.
  216. MCSymbol *LineStartSym = MCOS->getContext().getMCLineTableSymbol(CUID);
  217. if (!LineStartSym)
  218. LineStartSym = context.CreateTempSymbol();
  219. // Set the value of the symbol, as we are at the start of the line table.
  220. MCOS->EmitLabel(LineStartSym);
  221. // Create a symbol for the end of the section (to be set when we get there).
  222. MCSymbol *LineEndSym = context.CreateTempSymbol();
  223. // The first 4 bytes is the total length of the information for this
  224. // compilation unit (not including these 4 bytes for the length).
  225. MCOS->EmitAbsValue(MakeStartMinusEndExpr(*MCOS, *LineStartSym, *LineEndSym,4),
  226. 4);
  227. // Next 2 bytes is the Version, which is Dwarf 2.
  228. MCOS->EmitIntValue(2, 2);
  229. // Create a symbol for the end of the prologue (to be set when we get there).
  230. MCSymbol *ProEndSym = context.CreateTempSymbol(); // Lprologue_end
  231. // Length of the prologue, is the next 4 bytes. Which is the start of the
  232. // section to the end of the prologue. Not including the 4 bytes for the
  233. // total length, the 2 bytes for the version, and these 4 bytes for the
  234. // length of the prologue.
  235. MCOS->EmitAbsValue(MakeStartMinusEndExpr(*MCOS, *LineStartSym, *ProEndSym,
  236. (4 + 2 + 4)), 4, 0);
  237. // Parameters of the state machine, are next.
  238. MCOS->EmitIntValue(DWARF2_LINE_MIN_INSN_LENGTH, 1);
  239. MCOS->EmitIntValue(DWARF2_LINE_DEFAULT_IS_STMT, 1);
  240. MCOS->EmitIntValue(DWARF2_LINE_BASE, 1);
  241. MCOS->EmitIntValue(DWARF2_LINE_RANGE, 1);
  242. MCOS->EmitIntValue(DWARF2_LINE_OPCODE_BASE, 1);
  243. // Standard opcode lengths
  244. MCOS->EmitIntValue(0, 1); // length of DW_LNS_copy
  245. MCOS->EmitIntValue(1, 1); // length of DW_LNS_advance_pc
  246. MCOS->EmitIntValue(1, 1); // length of DW_LNS_advance_line
  247. MCOS->EmitIntValue(1, 1); // length of DW_LNS_set_file
  248. MCOS->EmitIntValue(1, 1); // length of DW_LNS_set_column
  249. MCOS->EmitIntValue(0, 1); // length of DW_LNS_negate_stmt
  250. MCOS->EmitIntValue(0, 1); // length of DW_LNS_set_basic_block
  251. MCOS->EmitIntValue(0, 1); // length of DW_LNS_const_add_pc
  252. MCOS->EmitIntValue(1, 1); // length of DW_LNS_fixed_advance_pc
  253. MCOS->EmitIntValue(0, 1); // length of DW_LNS_set_prologue_end
  254. MCOS->EmitIntValue(0, 1); // length of DW_LNS_set_epilogue_begin
  255. MCOS->EmitIntValue(1, 1); // DW_LNS_set_isa
  256. // Put out the directory and file tables.
  257. // First the directory table.
  258. const SmallVectorImpl<StringRef> &MCDwarfDirs =
  259. context.getMCDwarfDirs(CUID);
  260. for (unsigned i = 0; i < MCDwarfDirs.size(); i++) {
  261. MCOS->EmitBytes(MCDwarfDirs[i]); // the DirectoryName
  262. MCOS->EmitBytes(StringRef("\0", 1)); // the null term. of the string
  263. }
  264. MCOS->EmitIntValue(0, 1); // Terminate the directory list
  265. // Second the file table.
  266. const SmallVectorImpl<MCDwarfFile *> &MCDwarfFiles =
  267. MCOS->getContext().getMCDwarfFiles(CUID);
  268. for (unsigned i = 1; i < MCDwarfFiles.size(); i++) {
  269. MCOS->EmitBytes(MCDwarfFiles[i]->getName()); // FileName
  270. MCOS->EmitBytes(StringRef("\0", 1)); // the null term. of the string
  271. // the Directory num
  272. MCOS->EmitULEB128IntValue(MCDwarfFiles[i]->getDirIndex());
  273. MCOS->EmitIntValue(0, 1); // last modification timestamp (always 0)
  274. MCOS->EmitIntValue(0, 1); // filesize (always 0)
  275. }
  276. MCOS->EmitIntValue(0, 1); // Terminate the file list
  277. // This is the end of the prologue, so set the value of the symbol at the
  278. // end of the prologue (that was used in a previous expression).
  279. MCOS->EmitLabel(ProEndSym);
  280. // Put out the line tables.
  281. const DenseMap<const MCSection *, MCLineSection *> &MCLineSections =
  282. MCOS->getContext().getMCLineSections();
  283. const std::vector<const MCSection *> &MCLineSectionOrder =
  284. MCOS->getContext().getMCLineSectionOrder();
  285. for (std::vector<const MCSection*>::const_iterator it =
  286. MCLineSectionOrder.begin(), ie = MCLineSectionOrder.end(); it != ie;
  287. ++it) {
  288. const MCSection *Sec = *it;
  289. const MCLineSection *Line = MCLineSections.lookup(Sec);
  290. EmitDwarfLineTable(MCOS, Sec, Line, CUID);
  291. }
  292. if (MCOS->getContext().getAsmInfo().getLinkerRequiresNonEmptyDwarfLines()
  293. && MCLineSectionOrder.begin() == MCLineSectionOrder.end()) {
  294. // The darwin9 linker has a bug (see PR8715). For for 32-bit architectures
  295. // it requires:
  296. // total_length >= prologue_length + 10
  297. // We are 4 bytes short, since we have total_length = 51 and
  298. // prologue_length = 45
  299. // The regular end_sequence should be sufficient.
  300. MCDwarfLineAddr::Emit(MCOS, INT64_MAX, 0);
  301. }
  302. // This is the end of the section, so set the value of the symbol at the end
  303. // of this section (that was used in a previous expression).
  304. MCOS->EmitLabel(LineEndSym);
  305. return LineStartSym;
  306. }
  307. /// Utility function to write the encoding to an object writer.
  308. void MCDwarfLineAddr::Write(MCObjectWriter *OW, int64_t LineDelta,
  309. uint64_t AddrDelta) {
  310. SmallString<256> Tmp;
  311. raw_svector_ostream OS(Tmp);
  312. MCDwarfLineAddr::Encode(LineDelta, AddrDelta, OS);
  313. OW->WriteBytes(OS.str());
  314. }
  315. /// Utility function to emit the encoding to a streamer.
  316. void MCDwarfLineAddr::Emit(MCStreamer *MCOS, int64_t LineDelta,
  317. uint64_t AddrDelta) {
  318. SmallString<256> Tmp;
  319. raw_svector_ostream OS(Tmp);
  320. MCDwarfLineAddr::Encode(LineDelta, AddrDelta, OS);
  321. MCOS->EmitBytes(OS.str());
  322. }
  323. /// Utility function to encode a Dwarf pair of LineDelta and AddrDeltas.
  324. void MCDwarfLineAddr::Encode(int64_t LineDelta, uint64_t AddrDelta,
  325. raw_ostream &OS) {
  326. uint64_t Temp, Opcode;
  327. bool NeedCopy = false;
  328. // Scale the address delta by the minimum instruction length.
  329. AddrDelta = ScaleAddrDelta(AddrDelta);
  330. // A LineDelta of INT64_MAX is a signal that this is actually a
  331. // DW_LNE_end_sequence. We cannot use special opcodes here, since we want the
  332. // end_sequence to emit the matrix entry.
  333. if (LineDelta == INT64_MAX) {
  334. if (AddrDelta == MAX_SPECIAL_ADDR_DELTA)
  335. OS << char(dwarf::DW_LNS_const_add_pc);
  336. else {
  337. OS << char(dwarf::DW_LNS_advance_pc);
  338. encodeULEB128(AddrDelta, OS);
  339. }
  340. OS << char(dwarf::DW_LNS_extended_op);
  341. OS << char(1);
  342. OS << char(dwarf::DW_LNE_end_sequence);
  343. return;
  344. }
  345. // Bias the line delta by the base.
  346. Temp = LineDelta - DWARF2_LINE_BASE;
  347. // If the line increment is out of range of a special opcode, we must encode
  348. // it with DW_LNS_advance_line.
  349. if (Temp >= DWARF2_LINE_RANGE) {
  350. OS << char(dwarf::DW_LNS_advance_line);
  351. encodeSLEB128(LineDelta, OS);
  352. LineDelta = 0;
  353. Temp = 0 - DWARF2_LINE_BASE;
  354. NeedCopy = true;
  355. }
  356. // Use DW_LNS_copy instead of a "line +0, addr +0" special opcode.
  357. if (LineDelta == 0 && AddrDelta == 0) {
  358. OS << char(dwarf::DW_LNS_copy);
  359. return;
  360. }
  361. // Bias the opcode by the special opcode base.
  362. Temp += DWARF2_LINE_OPCODE_BASE;
  363. // Avoid overflow when addr_delta is large.
  364. if (AddrDelta < 256 + MAX_SPECIAL_ADDR_DELTA) {
  365. // Try using a special opcode.
  366. Opcode = Temp + AddrDelta * DWARF2_LINE_RANGE;
  367. if (Opcode <= 255) {
  368. OS << char(Opcode);
  369. return;
  370. }
  371. // Try using DW_LNS_const_add_pc followed by special op.
  372. Opcode = Temp + (AddrDelta - MAX_SPECIAL_ADDR_DELTA) * DWARF2_LINE_RANGE;
  373. if (Opcode <= 255) {
  374. OS << char(dwarf::DW_LNS_const_add_pc);
  375. OS << char(Opcode);
  376. return;
  377. }
  378. }
  379. // Otherwise use DW_LNS_advance_pc.
  380. OS << char(dwarf::DW_LNS_advance_pc);
  381. encodeULEB128(AddrDelta, OS);
  382. if (NeedCopy)
  383. OS << char(dwarf::DW_LNS_copy);
  384. else
  385. OS << char(Temp);
  386. }
  387. void MCDwarfFile::print(raw_ostream &OS) const {
  388. OS << '"' << getName() << '"';
  389. }
  390. #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
  391. void MCDwarfFile::dump() const {
  392. print(dbgs());
  393. }
  394. #endif
  395. // Utility function to write a tuple for .debug_abbrev.
  396. static void EmitAbbrev(MCStreamer *MCOS, uint64_t Name, uint64_t Form) {
  397. MCOS->EmitULEB128IntValue(Name);
  398. MCOS->EmitULEB128IntValue(Form);
  399. }
  400. // When generating dwarf for assembly source files this emits
  401. // the data for .debug_abbrev section which contains three DIEs.
  402. static void EmitGenDwarfAbbrev(MCStreamer *MCOS) {
  403. MCContext &context = MCOS->getContext();
  404. MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfAbbrevSection());
  405. // DW_TAG_compile_unit DIE abbrev (1).
  406. MCOS->EmitULEB128IntValue(1);
  407. MCOS->EmitULEB128IntValue(dwarf::DW_TAG_compile_unit);
  408. MCOS->EmitIntValue(dwarf::DW_CHILDREN_yes, 1);
  409. EmitAbbrev(MCOS, dwarf::DW_AT_stmt_list, dwarf::DW_FORM_data4);
  410. EmitAbbrev(MCOS, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr);
  411. EmitAbbrev(MCOS, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr);
  412. EmitAbbrev(MCOS, dwarf::DW_AT_name, dwarf::DW_FORM_string);
  413. EmitAbbrev(MCOS, dwarf::DW_AT_comp_dir, dwarf::DW_FORM_string);
  414. StringRef DwarfDebugFlags = context.getDwarfDebugFlags();
  415. if (!DwarfDebugFlags.empty())
  416. EmitAbbrev(MCOS, dwarf::DW_AT_APPLE_flags, dwarf::DW_FORM_string);
  417. EmitAbbrev(MCOS, dwarf::DW_AT_producer, dwarf::DW_FORM_string);
  418. EmitAbbrev(MCOS, dwarf::DW_AT_language, dwarf::DW_FORM_data2);
  419. EmitAbbrev(MCOS, 0, 0);
  420. // DW_TAG_label DIE abbrev (2).
  421. MCOS->EmitULEB128IntValue(2);
  422. MCOS->EmitULEB128IntValue(dwarf::DW_TAG_label);
  423. MCOS->EmitIntValue(dwarf::DW_CHILDREN_yes, 1);
  424. EmitAbbrev(MCOS, dwarf::DW_AT_name, dwarf::DW_FORM_string);
  425. EmitAbbrev(MCOS, dwarf::DW_AT_decl_file, dwarf::DW_FORM_data4);
  426. EmitAbbrev(MCOS, dwarf::DW_AT_decl_line, dwarf::DW_FORM_data4);
  427. EmitAbbrev(MCOS, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr);
  428. EmitAbbrev(MCOS, dwarf::DW_AT_prototyped, dwarf::DW_FORM_flag);
  429. EmitAbbrev(MCOS, 0, 0);
  430. // DW_TAG_unspecified_parameters DIE abbrev (3).
  431. MCOS->EmitULEB128IntValue(3);
  432. MCOS->EmitULEB128IntValue(dwarf::DW_TAG_unspecified_parameters);
  433. MCOS->EmitIntValue(dwarf::DW_CHILDREN_no, 1);
  434. EmitAbbrev(MCOS, 0, 0);
  435. // Terminate the abbreviations for this compilation unit.
  436. MCOS->EmitIntValue(0, 1);
  437. }
  438. // When generating dwarf for assembly source files this emits the data for
  439. // .debug_aranges section. Which contains a header and a table of pairs of
  440. // PointerSize'ed values for the address and size of section(s) with line table
  441. // entries (just the default .text in our case) and a terminating pair of zeros.
  442. static void EmitGenDwarfAranges(MCStreamer *MCOS,
  443. const MCSymbol *InfoSectionSymbol) {
  444. MCContext &context = MCOS->getContext();
  445. // Create a symbol at the end of the section that we are creating the dwarf
  446. // debugging info to use later in here as part of the expression to calculate
  447. // the size of the section for the table.
  448. MCOS->SwitchSection(context.getGenDwarfSection());
  449. MCSymbol *SectionEndSym = context.CreateTempSymbol();
  450. MCOS->EmitLabel(SectionEndSym);
  451. context.setGenDwarfSectionEndSym(SectionEndSym);
  452. MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfARangesSection());
  453. // This will be the length of the .debug_aranges section, first account for
  454. // the size of each item in the header (see below where we emit these items).
  455. int Length = 4 + 2 + 4 + 1 + 1;
  456. // Figure the padding after the header before the table of address and size
  457. // pairs who's values are PointerSize'ed.
  458. const MCAsmInfo &asmInfo = context.getAsmInfo();
  459. int AddrSize = asmInfo.getPointerSize();
  460. int Pad = 2 * AddrSize - (Length & (2 * AddrSize - 1));
  461. if (Pad == 2 * AddrSize)
  462. Pad = 0;
  463. Length += Pad;
  464. // Add the size of the pair of PointerSize'ed values for the address and size
  465. // of the one default .text section we have in the table.
  466. Length += 2 * AddrSize;
  467. // And the pair of terminating zeros.
  468. Length += 2 * AddrSize;
  469. // Emit the header for this section.
  470. // The 4 byte length not including the 4 byte value for the length.
  471. MCOS->EmitIntValue(Length - 4, 4);
  472. // The 2 byte version, which is 2.
  473. MCOS->EmitIntValue(2, 2);
  474. // The 4 byte offset to the compile unit in the .debug_info from the start
  475. // of the .debug_info.
  476. if (InfoSectionSymbol)
  477. MCOS->EmitSymbolValue(InfoSectionSymbol, 4);
  478. else
  479. MCOS->EmitIntValue(0, 4);
  480. // The 1 byte size of an address.
  481. MCOS->EmitIntValue(AddrSize, 1);
  482. // The 1 byte size of a segment descriptor, we use a value of zero.
  483. MCOS->EmitIntValue(0, 1);
  484. // Align the header with the padding if needed, before we put out the table.
  485. for(int i = 0; i < Pad; i++)
  486. MCOS->EmitIntValue(0, 1);
  487. // Now emit the table of pairs of PointerSize'ed values for the section(s)
  488. // address and size, in our case just the one default .text section.
  489. const MCExpr *Addr = MCSymbolRefExpr::Create(
  490. context.getGenDwarfSectionStartSym(), MCSymbolRefExpr::VK_None, context);
  491. const MCExpr *Size = MakeStartMinusEndExpr(*MCOS,
  492. *context.getGenDwarfSectionStartSym(), *SectionEndSym, 0);
  493. MCOS->EmitAbsValue(Addr, AddrSize);
  494. MCOS->EmitAbsValue(Size, AddrSize);
  495. // And finally the pair of terminating zeros.
  496. MCOS->EmitIntValue(0, AddrSize);
  497. MCOS->EmitIntValue(0, AddrSize);
  498. }
  499. // When generating dwarf for assembly source files this emits the data for
  500. // .debug_info section which contains three parts. The header, the compile_unit
  501. // DIE and a list of label DIEs.
  502. static void EmitGenDwarfInfo(MCStreamer *MCOS,
  503. const MCSymbol *AbbrevSectionSymbol,
  504. const MCSymbol *LineSectionSymbol) {
  505. MCContext &context = MCOS->getContext();
  506. MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfInfoSection());
  507. // Create a symbol at the start and end of this section used in here for the
  508. // expression to calculate the length in the header.
  509. MCSymbol *InfoStart = context.CreateTempSymbol();
  510. MCOS->EmitLabel(InfoStart);
  511. MCSymbol *InfoEnd = context.CreateTempSymbol();
  512. // First part: the header.
  513. // The 4 byte total length of the information for this compilation unit, not
  514. // including these 4 bytes.
  515. const MCExpr *Length = MakeStartMinusEndExpr(*MCOS, *InfoStart, *InfoEnd, 4);
  516. MCOS->EmitAbsValue(Length, 4);
  517. // The 2 byte DWARF version, which is 2.
  518. MCOS->EmitIntValue(2, 2);
  519. // The 4 byte offset to the debug abbrevs from the start of the .debug_abbrev,
  520. // it is at the start of that section so this is zero.
  521. if (AbbrevSectionSymbol) {
  522. MCOS->EmitSymbolValue(AbbrevSectionSymbol, 4);
  523. } else {
  524. MCOS->EmitIntValue(0, 4);
  525. }
  526. const MCAsmInfo &asmInfo = context.getAsmInfo();
  527. int AddrSize = asmInfo.getPointerSize();
  528. // The 1 byte size of an address.
  529. MCOS->EmitIntValue(AddrSize, 1);
  530. // Second part: the compile_unit DIE.
  531. // The DW_TAG_compile_unit DIE abbrev (1).
  532. MCOS->EmitULEB128IntValue(1);
  533. // DW_AT_stmt_list, a 4 byte offset from the start of the .debug_line section,
  534. // which is at the start of that section so this is zero.
  535. if (LineSectionSymbol) {
  536. MCOS->EmitSymbolValue(LineSectionSymbol, 4);
  537. } else {
  538. MCOS->EmitIntValue(0, 4);
  539. }
  540. // AT_low_pc, the first address of the default .text section.
  541. const MCExpr *Start = MCSymbolRefExpr::Create(
  542. context.getGenDwarfSectionStartSym(), MCSymbolRefExpr::VK_None, context);
  543. MCOS->EmitAbsValue(Start, AddrSize);
  544. // AT_high_pc, the last address of the default .text section.
  545. const MCExpr *End = MCSymbolRefExpr::Create(
  546. context.getGenDwarfSectionEndSym(), MCSymbolRefExpr::VK_None, context);
  547. MCOS->EmitAbsValue(End, AddrSize);
  548. // AT_name, the name of the source file. Reconstruct from the first directory
  549. // and file table entries.
  550. const SmallVectorImpl<StringRef> &MCDwarfDirs =
  551. context.getMCDwarfDirs();
  552. if (MCDwarfDirs.size() > 0) {
  553. MCOS->EmitBytes(MCDwarfDirs[0]);
  554. MCOS->EmitBytes("/");
  555. }
  556. const SmallVectorImpl<MCDwarfFile *> &MCDwarfFiles =
  557. MCOS->getContext().getMCDwarfFiles();
  558. MCOS->EmitBytes(MCDwarfFiles[1]->getName());
  559. MCOS->EmitIntValue(0, 1); // NULL byte to terminate the string.
  560. // AT_comp_dir, the working directory the assembly was done in.
  561. MCOS->EmitBytes(context.getCompilationDir());
  562. MCOS->EmitIntValue(0, 1); // NULL byte to terminate the string.
  563. // AT_APPLE_flags, the command line arguments of the assembler tool.
  564. StringRef DwarfDebugFlags = context.getDwarfDebugFlags();
  565. if (!DwarfDebugFlags.empty()){
  566. MCOS->EmitBytes(DwarfDebugFlags);
  567. MCOS->EmitIntValue(0, 1); // NULL byte to terminate the string.
  568. }
  569. // AT_producer, the version of the assembler tool.
  570. StringRef DwarfDebugProducer = context.getDwarfDebugProducer();
  571. if (!DwarfDebugProducer.empty()){
  572. MCOS->EmitBytes(DwarfDebugProducer);
  573. }
  574. else {
  575. MCOS->EmitBytes(StringRef("llvm-mc (based on LLVM "));
  576. MCOS->EmitBytes(StringRef(PACKAGE_VERSION));
  577. MCOS->EmitBytes(StringRef(")"));
  578. }
  579. MCOS->EmitIntValue(0, 1); // NULL byte to terminate the string.
  580. // AT_language, a 4 byte value. We use DW_LANG_Mips_Assembler as the dwarf2
  581. // draft has no standard code for assembler.
  582. MCOS->EmitIntValue(dwarf::DW_LANG_Mips_Assembler, 2);
  583. // Third part: the list of label DIEs.
  584. // Loop on saved info for dwarf labels and create the DIEs for them.
  585. const std::vector<const MCGenDwarfLabelEntry *> &Entries =
  586. MCOS->getContext().getMCGenDwarfLabelEntries();
  587. for (std::vector<const MCGenDwarfLabelEntry *>::const_iterator it =
  588. Entries.begin(), ie = Entries.end(); it != ie;
  589. ++it) {
  590. const MCGenDwarfLabelEntry *Entry = *it;
  591. // The DW_TAG_label DIE abbrev (2).
  592. MCOS->EmitULEB128IntValue(2);
  593. // AT_name, of the label without any leading underbar.
  594. MCOS->EmitBytes(Entry->getName());
  595. MCOS->EmitIntValue(0, 1); // NULL byte to terminate the string.
  596. // AT_decl_file, index into the file table.
  597. MCOS->EmitIntValue(Entry->getFileNumber(), 4);
  598. // AT_decl_line, source line number.
  599. MCOS->EmitIntValue(Entry->getLineNumber(), 4);
  600. // AT_low_pc, start address of the label.
  601. const MCExpr *AT_low_pc = MCSymbolRefExpr::Create(Entry->getLabel(),
  602. MCSymbolRefExpr::VK_None, context);
  603. MCOS->EmitAbsValue(AT_low_pc, AddrSize);
  604. // DW_AT_prototyped, a one byte flag value of 0 saying we have no prototype.
  605. MCOS->EmitIntValue(0, 1);
  606. // The DW_TAG_unspecified_parameters DIE abbrev (3).
  607. MCOS->EmitULEB128IntValue(3);
  608. // Add the NULL DIE terminating the DW_TAG_unspecified_parameters DIE's.
  609. MCOS->EmitIntValue(0, 1);
  610. }
  611. // Deallocate the MCGenDwarfLabelEntry classes that saved away the info
  612. // for the dwarf labels.
  613. for (std::vector<const MCGenDwarfLabelEntry *>::const_iterator it =
  614. Entries.begin(), ie = Entries.end(); it != ie;
  615. ++it) {
  616. const MCGenDwarfLabelEntry *Entry = *it;
  617. delete Entry;
  618. }
  619. // Add the NULL DIE terminating the Compile Unit DIE's.
  620. MCOS->EmitIntValue(0, 1);
  621. // Now set the value of the symbol at the end of the info section.
  622. MCOS->EmitLabel(InfoEnd);
  623. }
  624. //
  625. // When generating dwarf for assembly source files this emits the Dwarf
  626. // sections.
  627. //
  628. void MCGenDwarfInfo::Emit(MCStreamer *MCOS, const MCSymbol *LineSectionSymbol) {
  629. // Create the dwarf sections in this order (.debug_line already created).
  630. MCContext &context = MCOS->getContext();
  631. const MCAsmInfo &AsmInfo = context.getAsmInfo();
  632. bool CreateDwarfSectionSymbols =
  633. AsmInfo.doesDwarfUseRelocationsAcrossSections();
  634. if (!CreateDwarfSectionSymbols)
  635. LineSectionSymbol = NULL;
  636. MCSymbol *AbbrevSectionSymbol = NULL;
  637. MCSymbol *InfoSectionSymbol = NULL;
  638. MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfInfoSection());
  639. if (CreateDwarfSectionSymbols) {
  640. InfoSectionSymbol = context.CreateTempSymbol();
  641. MCOS->EmitLabel(InfoSectionSymbol);
  642. }
  643. MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfAbbrevSection());
  644. if (CreateDwarfSectionSymbols) {
  645. AbbrevSectionSymbol = context.CreateTempSymbol();
  646. MCOS->EmitLabel(AbbrevSectionSymbol);
  647. }
  648. MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfARangesSection());
  649. // If there are no line table entries then do not emit any section contents.
  650. if (context.getMCLineSections().empty())
  651. return;
  652. // Output the data for .debug_aranges section.
  653. EmitGenDwarfAranges(MCOS, InfoSectionSymbol);
  654. // Output the data for .debug_abbrev section.
  655. EmitGenDwarfAbbrev(MCOS);
  656. // Output the data for .debug_info section.
  657. EmitGenDwarfInfo(MCOS, AbbrevSectionSymbol, LineSectionSymbol);
  658. }
  659. //
  660. // When generating dwarf for assembly source files this is called when symbol
  661. // for a label is created. If this symbol is not a temporary and is in the
  662. // section that dwarf is being generated for, save the needed info to create
  663. // a dwarf label.
  664. //
  665. void MCGenDwarfLabelEntry::Make(MCSymbol *Symbol, MCStreamer *MCOS,
  666. SourceMgr &SrcMgr, SMLoc &Loc) {
  667. // We won't create dwarf labels for temporary symbols or symbols not in
  668. // the default text.
  669. if (Symbol->isTemporary())
  670. return;
  671. MCContext &context = MCOS->getContext();
  672. if (context.getGenDwarfSection() != MCOS->getCurrentSection())
  673. return;
  674. // The dwarf label's name does not have the symbol name's leading
  675. // underbar if any.
  676. StringRef Name = Symbol->getName();
  677. if (Name.startswith("_"))
  678. Name = Name.substr(1, Name.size()-1);
  679. // Get the dwarf file number to be used for the dwarf label.
  680. unsigned FileNumber = context.getGenDwarfFileNumber();
  681. // Finding the line number is the expensive part which is why we just don't
  682. // pass it in as for some symbols we won't create a dwarf label.
  683. int CurBuffer = SrcMgr.FindBufferContainingLoc(Loc);
  684. unsigned LineNumber = SrcMgr.FindLineNumber(Loc, CurBuffer);
  685. // We create a temporary symbol for use for the AT_high_pc and AT_low_pc
  686. // values so that they don't have things like an ARM thumb bit from the
  687. // original symbol. So when used they won't get a low bit set after
  688. // relocation.
  689. MCSymbol *Label = context.CreateTempSymbol();
  690. MCOS->EmitLabel(Label);
  691. // Create and entry for the info and add it to the other entries.
  692. MCGenDwarfLabelEntry *Entry =
  693. new MCGenDwarfLabelEntry(Name, FileNumber, LineNumber, Label);
  694. MCOS->getContext().addMCGenDwarfLabelEntry(Entry);
  695. }
  696. static int getDataAlignmentFactor(MCStreamer &streamer) {
  697. MCContext &context = streamer.getContext();
  698. const MCAsmInfo &asmInfo = context.getAsmInfo();
  699. int size = asmInfo.getCalleeSaveStackSlotSize();
  700. if (asmInfo.isStackGrowthDirectionUp())
  701. return size;
  702. else
  703. return -size;
  704. }
  705. static unsigned getSizeForEncoding(MCStreamer &streamer,
  706. unsigned symbolEncoding) {
  707. MCContext &context = streamer.getContext();
  708. unsigned format = symbolEncoding & 0x0f;
  709. switch (format) {
  710. default: llvm_unreachable("Unknown Encoding");
  711. case dwarf::DW_EH_PE_absptr:
  712. case dwarf::DW_EH_PE_signed:
  713. return context.getAsmInfo().getPointerSize();
  714. case dwarf::DW_EH_PE_udata2:
  715. case dwarf::DW_EH_PE_sdata2:
  716. return 2;
  717. case dwarf::DW_EH_PE_udata4:
  718. case dwarf::DW_EH_PE_sdata4:
  719. return 4;
  720. case dwarf::DW_EH_PE_udata8:
  721. case dwarf::DW_EH_PE_sdata8:
  722. return 8;
  723. }
  724. }
  725. static void EmitSymbol(MCStreamer &streamer, const MCSymbol &symbol,
  726. unsigned symbolEncoding, const char *comment = 0) {
  727. MCContext &context = streamer.getContext();
  728. const MCAsmInfo &asmInfo = context.getAsmInfo();
  729. const MCExpr *v = asmInfo.getExprForFDESymbol(&symbol,
  730. symbolEncoding,
  731. streamer);
  732. unsigned size = getSizeForEncoding(streamer, symbolEncoding);
  733. if (streamer.isVerboseAsm() && comment) streamer.AddComment(comment);
  734. streamer.EmitAbsValue(v, size);
  735. }
  736. static void EmitPersonality(MCStreamer &streamer, const MCSymbol &symbol,
  737. unsigned symbolEncoding) {
  738. MCContext &context = streamer.getContext();
  739. const MCAsmInfo &asmInfo = context.getAsmInfo();
  740. const MCExpr *v = asmInfo.getExprForPersonalitySymbol(&symbol,
  741. symbolEncoding,
  742. streamer);
  743. unsigned size = getSizeForEncoding(streamer, symbolEncoding);
  744. streamer.EmitValue(v, size);
  745. }
  746. static const MachineLocation TranslateMachineLocation(
  747. const MCRegisterInfo &MRI,
  748. const MachineLocation &Loc) {
  749. unsigned Reg = Loc.getReg() == MachineLocation::VirtualFP ?
  750. MachineLocation::VirtualFP :
  751. unsigned(MRI.getDwarfRegNum(Loc.getReg(), true));
  752. const MachineLocation &NewLoc = Loc.isReg() ?
  753. MachineLocation(Reg) : MachineLocation(Reg, Loc.getOffset());
  754. return NewLoc;
  755. }
  756. namespace {
  757. class FrameEmitterImpl {
  758. int CFAOffset;
  759. int CIENum;
  760. bool UsingCFI;
  761. bool IsEH;
  762. const MCSymbol *SectionStart;
  763. public:
  764. FrameEmitterImpl(bool usingCFI, bool isEH)
  765. : CFAOffset(0), CIENum(0), UsingCFI(usingCFI), IsEH(isEH),
  766. SectionStart(0) {}
  767. void setSectionStart(const MCSymbol *Label) { SectionStart = Label; }
  768. /// EmitCompactUnwind - Emit the unwind information in a compact way. If
  769. /// we're successful, return 'true'. Otherwise, return 'false' and it will
  770. /// emit the normal CIE and FDE.
  771. bool EmitCompactUnwind(MCStreamer &streamer,
  772. const MCDwarfFrameInfo &frame);
  773. const MCSymbol &EmitCIE(MCStreamer &streamer,
  774. const MCSymbol *personality,
  775. unsigned personalityEncoding,
  776. const MCSymbol *lsda,
  777. bool IsSignalFrame,
  778. unsigned lsdaEncoding);
  779. MCSymbol *EmitFDE(MCStreamer &streamer,
  780. const MCSymbol &cieStart,
  781. const MCDwarfFrameInfo &frame);
  782. void EmitCFIInstructions(MCStreamer &streamer,
  783. const std::vector<MCCFIInstruction> &Instrs,
  784. MCSymbol *BaseLabel);
  785. void EmitCFIInstruction(MCStreamer &Streamer,
  786. const MCCFIInstruction &Instr);
  787. };
  788. } // end anonymous namespace
  789. static void EmitEncodingByte(MCStreamer &Streamer, unsigned Encoding,
  790. StringRef Prefix) {
  791. if (Streamer.isVerboseAsm()) {
  792. const char *EncStr;
  793. switch (Encoding) {
  794. default: EncStr = "<unknown encoding>"; break;
  795. case dwarf::DW_EH_PE_absptr: EncStr = "absptr"; break;
  796. case dwarf::DW_EH_PE_omit: EncStr = "omit"; break;
  797. case dwarf::DW_EH_PE_pcrel: EncStr = "pcrel"; break;
  798. case dwarf::DW_EH_PE_udata4: EncStr = "udata4"; break;
  799. case dwarf::DW_EH_PE_udata8: EncStr = "udata8"; break;
  800. case dwarf::DW_EH_PE_sdata4: EncStr = "sdata4"; break;
  801. case dwarf::DW_EH_PE_sdata8: EncStr = "sdata8"; break;
  802. case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata4:
  803. EncStr = "pcrel udata4";
  804. break;
  805. case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4:
  806. EncStr = "pcrel sdata4";
  807. break;
  808. case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata8:
  809. EncStr = "pcrel udata8";
  810. break;
  811. case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8:
  812. EncStr = "screl sdata8";
  813. break;
  814. case dwarf::DW_EH_PE_indirect |dwarf::DW_EH_PE_pcrel|dwarf::DW_EH_PE_udata4:
  815. EncStr = "indirect pcrel udata4";
  816. break;
  817. case dwarf::DW_EH_PE_indirect |dwarf::DW_EH_PE_pcrel|dwarf::DW_EH_PE_sdata4:
  818. EncStr = "indirect pcrel sdata4";
  819. break;
  820. case dwarf::DW_EH_PE_indirect |dwarf::DW_EH_PE_pcrel|dwarf::DW_EH_PE_udata8:
  821. EncStr = "indirect pcrel udata8";
  822. break;
  823. case dwarf::DW_EH_PE_indirect |dwarf::DW_EH_PE_pcrel|dwarf::DW_EH_PE_sdata8:
  824. EncStr = "indirect pcrel sdata8";
  825. break;
  826. }
  827. Streamer.AddComment(Twine(Prefix) + " = " + EncStr);
  828. }
  829. Streamer.EmitIntValue(Encoding, 1);
  830. }
  831. void FrameEmitterImpl::EmitCFIInstruction(MCStreamer &Streamer,
  832. const MCCFIInstruction &Instr) {
  833. int dataAlignmentFactor = getDataAlignmentFactor(Streamer);
  834. bool VerboseAsm = Streamer.isVerboseAsm();
  835. switch (Instr.getOperation()) {
  836. case MCCFIInstruction::OpRegister: {
  837. unsigned Reg1 = Instr.getRegister();
  838. unsigned Reg2 = Instr.getRegister2();
  839. if (VerboseAsm) {
  840. Streamer.AddComment("DW_CFA_register");
  841. Streamer.AddComment(Twine("Reg1 ") + Twine(Reg1));
  842. Streamer.AddComment(Twine("Reg2 ") + Twine(Reg2));
  843. }
  844. Streamer.EmitIntValue(dwarf::DW_CFA_register, 1);
  845. Streamer.EmitULEB128IntValue(Reg1);
  846. Streamer.EmitULEB128IntValue(Reg2);
  847. return;
  848. }
  849. case MCCFIInstruction::OpUndefined: {
  850. unsigned Reg = Instr.getRegister();
  851. if (VerboseAsm) {
  852. Streamer.AddComment("DW_CFA_undefined");
  853. Streamer.AddComment(Twine("Reg ") + Twine(Reg));
  854. }
  855. Streamer.EmitIntValue(dwarf::DW_CFA_undefined, 1);
  856. Streamer.EmitULEB128IntValue(Reg);
  857. return;
  858. }
  859. case MCCFIInstruction::OpAdjustCfaOffset:
  860. case MCCFIInstruction::OpDefCfaOffset: {
  861. const bool IsRelative =
  862. Instr.getOperation() == MCCFIInstruction::OpAdjustCfaOffset;
  863. if (VerboseAsm)
  864. Streamer.AddComment("DW_CFA_def_cfa_offset");
  865. Streamer.EmitIntValue(dwarf::DW_CFA_def_cfa_offset, 1);
  866. if (IsRelative)
  867. CFAOffset += Instr.getOffset();
  868. else
  869. CFAOffset = -Instr.getOffset();
  870. if (VerboseAsm)
  871. Streamer.AddComment(Twine("Offset " + Twine(CFAOffset)));
  872. Streamer.EmitULEB128IntValue(CFAOffset);
  873. return;
  874. }
  875. case MCCFIInstruction::OpDefCfa: {
  876. if (VerboseAsm)
  877. Streamer.AddComment("DW_CFA_def_cfa");
  878. Streamer.EmitIntValue(dwarf::DW_CFA_def_cfa, 1);
  879. if (VerboseAsm)
  880. Streamer.AddComment(Twine("Reg ") + Twine(Instr.getRegister()));
  881. Streamer.EmitULEB128IntValue(Instr.getRegister());
  882. CFAOffset = -Instr.getOffset();
  883. if (VerboseAsm)
  884. Streamer.AddComment(Twine("Offset " + Twine(CFAOffset)));
  885. Streamer.EmitULEB128IntValue(CFAOffset);
  886. return;
  887. }
  888. case MCCFIInstruction::OpDefCfaRegister: {
  889. if (VerboseAsm)
  890. Streamer.AddComment("DW_CFA_def_cfa_register");
  891. Streamer.EmitIntValue(dwarf::DW_CFA_def_cfa_register, 1);
  892. if (VerboseAsm)
  893. Streamer.AddComment(Twine("Reg ") + Twine(Instr.getRegister()));
  894. Streamer.EmitULEB128IntValue(Instr.getRegister());
  895. return;
  896. }
  897. case MCCFIInstruction::OpOffset:
  898. case MCCFIInstruction::OpRelOffset: {
  899. const bool IsRelative =
  900. Instr.getOperation() == MCCFIInstruction::OpRelOffset;
  901. unsigned Reg = Instr.getRegister();
  902. int Offset = Instr.getOffset();
  903. if (IsRelative)
  904. Offset -= CFAOffset;
  905. Offset = Offset / dataAlignmentFactor;
  906. if (Offset < 0) {
  907. if (VerboseAsm) Streamer.AddComment("DW_CFA_offset_extended_sf");
  908. Streamer.EmitIntValue(dwarf::DW_CFA_offset_extended_sf, 1);
  909. if (VerboseAsm) Streamer.AddComment(Twine("Reg ") + Twine(Reg));
  910. Streamer.EmitULEB128IntValue(Reg);
  911. if (VerboseAsm) Streamer.AddComment(Twine("Offset ") + Twine(Offset));
  912. Streamer.EmitSLEB128IntValue(Offset);
  913. } else if (Reg < 64) {
  914. if (VerboseAsm) Streamer.AddComment(Twine("DW_CFA_offset + Reg(") +
  915. Twine(Reg) + ")");
  916. Streamer.EmitIntValue(dwarf::DW_CFA_offset + Reg, 1);
  917. if (VerboseAsm) Streamer.AddComment(Twine("Offset ") + Twine(Offset));
  918. Streamer.EmitULEB128IntValue(Offset);
  919. } else {
  920. if (VerboseAsm) Streamer.AddComment("DW_CFA_offset_extended");
  921. Streamer.EmitIntValue(dwarf::DW_CFA_offset_extended, 1);
  922. if (VerboseAsm) Streamer.AddComment(Twine("Reg ") + Twine(Reg));
  923. Streamer.EmitULEB128IntValue(Reg);
  924. if (VerboseAsm) Streamer.AddComment(Twine("Offset ") + Twine(Offset));
  925. Streamer.EmitULEB128IntValue(Offset);
  926. }
  927. return;
  928. }
  929. case MCCFIInstruction::OpRememberState:
  930. if (VerboseAsm) Streamer.AddComment("DW_CFA_remember_state");
  931. Streamer.EmitIntValue(dwarf::DW_CFA_remember_state, 1);
  932. return;
  933. case MCCFIInstruction::OpRestoreState:
  934. if (VerboseAsm) Streamer.AddComment("DW_CFA_restore_state");
  935. Streamer.EmitIntValue(dwarf::DW_CFA_restore_state, 1);
  936. return;
  937. case MCCFIInstruction::OpSameValue: {
  938. unsigned Reg = Instr.getRegister();
  939. if (VerboseAsm) Streamer.AddComment("DW_CFA_same_value");
  940. Streamer.EmitIntValue(dwarf::DW_CFA_same_value, 1);
  941. if (VerboseAsm) Streamer.AddComment(Twine("Reg ") + Twine(Reg));
  942. Streamer.EmitULEB128IntValue(Reg);
  943. return;
  944. }
  945. case MCCFIInstruction::OpRestore: {
  946. unsigned Reg = Instr.getRegister();
  947. if (VerboseAsm) {
  948. Streamer.AddComment("DW_CFA_restore");
  949. Streamer.AddComment(Twine("Reg ") + Twine(Reg));
  950. }
  951. Streamer.EmitIntValue(dwarf::DW_CFA_restore | Reg, 1);
  952. return;
  953. }
  954. case MCCFIInstruction::OpEscape:
  955. if (VerboseAsm) Streamer.AddComment("Escape bytes");
  956. Streamer.EmitBytes(Instr.getValues());
  957. return;
  958. }
  959. llvm_unreachable("Unhandled case in switch");
  960. }
  961. /// EmitFrameMoves - Emit frame instructions to describe the layout of the
  962. /// frame.
  963. void FrameEmitterImpl::EmitCFIInstructions(MCStreamer &streamer,
  964. const std::vector<MCCFIInstruction> &Instrs,
  965. MCSymbol *BaseLabel) {
  966. for (unsigned i = 0, N = Instrs.size(); i < N; ++i) {
  967. const MCCFIInstruction &Instr = Instrs[i];
  968. MCSymbol *Label = Instr.getLabel();
  969. // Throw out move if the label is invalid.
  970. if (Label && !Label->isDefined()) continue; // Not emitted, in dead code.
  971. // Advance row if new location.
  972. if (BaseLabel && Label) {
  973. MCSymbol *ThisSym = Label;
  974. if (ThisSym != BaseLabel) {
  975. if (streamer.isVerboseAsm()) streamer.AddComment("DW_CFA_advance_loc4");
  976. streamer.EmitDwarfAdvanceFrameAddr(BaseLabel, ThisSym);
  977. BaseLabel = ThisSym;
  978. }
  979. }
  980. EmitCFIInstruction(streamer, Instr);
  981. }
  982. }
  983. /// EmitCompactUnwind - Emit the unwind information in a compact way. If we're
  984. /// successful, return 'true'. Otherwise, return 'false' and it will emit the
  985. /// normal CIE and FDE.
  986. bool FrameEmitterImpl::EmitCompactUnwind(MCStreamer &Streamer,
  987. const MCDwarfFrameInfo &Frame) {
  988. MCContext &Context = Streamer.getContext();
  989. const MCObjectFileInfo *MOFI = Context.getObjectFileInfo();
  990. bool VerboseAsm = Streamer.isVerboseAsm();
  991. // range-start range-length compact-unwind-enc personality-func lsda
  992. // _foo LfooEnd-_foo 0x00000023 0 0
  993. // _bar LbarEnd-_bar 0x00000025 __gxx_personality except_tab1
  994. //
  995. // .section __LD,__compact_unwind,regular,debug
  996. //
  997. // # compact unwind for _foo
  998. // .quad _foo
  999. // .set L1,LfooEnd-_foo
  1000. // .long L1
  1001. // .long 0x01010001
  1002. // .quad 0
  1003. // .quad 0
  1004. //
  1005. // # compact unwind for _bar
  1006. // .quad _bar
  1007. // .set L2,LbarEnd-_bar
  1008. // .long L2
  1009. // .long 0x01020011
  1010. // .quad __gxx_personality
  1011. // .quad except_tab1
  1012. uint32_t Encoding = Frame.CompactUnwindEncoding;
  1013. bool DwarfEHFrameOnly = (Encoding == MOFI->getCompactUnwindDwarfEHFrameOnly());
  1014. // The encoding needs to know we have an LSDA.
  1015. if (!DwarfEHFrameOnly && Frame.Lsda)
  1016. Encoding |= 0x40000000;
  1017. Streamer.SwitchSection(MOFI->getCompactUnwindSection());
  1018. // Range Start
  1019. unsigned FDEEncoding = MOFI->getFDEEncoding(UsingCFI);
  1020. unsigned Size = getSizeForEncoding(Streamer, FDEEncoding);
  1021. if (VerboseAsm) Streamer.AddComment("Range Start");
  1022. Streamer.EmitSymbolValue(Frame.Function, Size);
  1023. // Range Length
  1024. const MCExpr *Range = MakeStartMinusEndExpr(Streamer, *Frame.Begin,
  1025. *Frame.End, 0);
  1026. if (VerboseAsm) Streamer.AddComment("Range Length");
  1027. Streamer.EmitAbsValue(Range, 4);
  1028. // Compact Encoding
  1029. Size = getSizeForEncoding(Streamer, dwarf::DW_EH_PE_udata4);
  1030. if (VerboseAsm) Streamer.AddComment("Compact Unwind Encoding: 0x" +
  1031. Twine::utohexstr(Encoding));
  1032. Streamer.EmitIntValue(Encoding, Size);
  1033. // Personality Function
  1034. Size = getSizeForEncoding(Streamer, dwarf::DW_EH_PE_absptr);
  1035. if (VerboseAsm) Streamer.AddComment("Personality Function");
  1036. if (!DwarfEHFrameOnly && Frame.Personality)
  1037. Streamer.EmitSymbolValue(Frame.Personality, Size);
  1038. else
  1039. Streamer.EmitIntValue(0, Size); // No personality fn
  1040. // LSDA
  1041. Size = getSizeForEncoding(Streamer, Frame.LsdaEncoding);
  1042. if (VerboseAsm) Streamer.AddComment("LSDA");
  1043. if (!DwarfEHFrameOnly && Frame.Lsda)
  1044. Streamer.EmitSymbolValue(Frame.Lsda, Size);
  1045. else
  1046. Streamer.EmitIntValue(0, Size); // No LSDA
  1047. return true;
  1048. }
  1049. const MCSymbol &FrameEmitterImpl::EmitCIE(MCStreamer &streamer,
  1050. const MCSymbol *personality,
  1051. unsigned personalityEncoding,
  1052. const MCSymbol *lsda,
  1053. bool IsSignalFrame,
  1054. unsigned lsdaEncoding) {
  1055. MCContext &context = streamer.getContext();
  1056. const MCRegisterInfo &MRI = context.getRegisterInfo();
  1057. const MCObjectFileInfo *MOFI = context.getObjectFileInfo();
  1058. bool verboseAsm = streamer.isVerboseAsm();
  1059. MCSymbol *sectionStart;
  1060. if (MOFI->isFunctionEHFrameSymbolPrivate() || !IsEH)
  1061. sectionStart = context.CreateTempSymbol();
  1062. else
  1063. sectionStart = context.GetOrCreateSymbol(Twine("EH_frame") + Twine(CIENum));
  1064. streamer.EmitLabel(sectionStart);
  1065. CIENum++;
  1066. MCSymbol *sectionEnd = context.CreateTempSymbol();
  1067. // Length
  1068. const MCExpr *Length = MakeStartMinusEndExpr(streamer, *sectionStart,
  1069. *sectionEnd, 4);
  1070. if (verboseAsm) streamer.AddComment("CIE Length");
  1071. streamer.EmitAbsValue(Length, 4);
  1072. // CIE ID
  1073. unsigned CIE_ID = IsEH ? 0 : -1;
  1074. if (verboseAsm) streamer.AddComment("CIE ID Tag");
  1075. streamer.EmitIntValue(CIE_ID, 4);
  1076. // Version
  1077. if (verboseAsm) streamer.AddComment("DW_CIE_VERSION");
  1078. streamer.EmitIntValue(dwarf::DW_CIE_VERSION, 1);
  1079. // Augmentation String
  1080. SmallString<8> Augmentation;
  1081. if (IsEH) {
  1082. if (verboseAsm) streamer.AddComment("CIE Augmentation");
  1083. Augmentation += "z";
  1084. if (personality)
  1085. Augmentation += "P";
  1086. if (lsda)
  1087. Augmentation += "L";
  1088. Augmentation += "R";
  1089. if (IsSignalFrame)
  1090. Augmentation += "S";
  1091. streamer.EmitBytes(Augmentation.str());
  1092. }
  1093. streamer.EmitIntValue(0, 1);
  1094. // Code Alignment Factor
  1095. if (verboseAsm) streamer.AddComment("CIE Code Alignment Factor");
  1096. streamer.EmitULEB128IntValue(1);
  1097. // Data Alignment Factor
  1098. if (verboseAsm) streamer.AddComment("CIE Data Alignment Factor");
  1099. streamer.EmitSLEB128IntValue(getDataAlignmentFactor(streamer));
  1100. // Return Address Register
  1101. if (verboseAsm) streamer.AddComment("CIE Return Address Column");
  1102. streamer.EmitULEB128IntValue(MRI.getDwarfRegNum(MRI.getRARegister(), true));
  1103. // Augmentation Data Length (optional)
  1104. unsigned augmentationLength = 0;
  1105. if (IsEH) {
  1106. if (personality) {
  1107. // Personality Encoding
  1108. augmentationLength += 1;
  1109. // Personality
  1110. augmentationLength += getSizeForEncoding(streamer, personalityEncoding);
  1111. }
  1112. if (lsda)
  1113. augmentationLength += 1;
  1114. // Encoding of the FDE pointers
  1115. augmentationLength += 1;
  1116. if (verboseAsm) streamer.AddComment("Augmentation Size");
  1117. streamer.EmitULEB128IntValue(augmentationLength);
  1118. // Augmentation Data (optional)
  1119. if (personality) {
  1120. // Personality Encoding
  1121. EmitEncodingByte(streamer, personalityEncoding,
  1122. "Personality Encoding");
  1123. // Personality
  1124. if (verboseAsm) streamer.AddComment("Personality");
  1125. EmitPersonality(streamer, *personality, personalityEncoding);
  1126. }
  1127. if (lsda)
  1128. EmitEncodingByte(streamer, lsdaEncoding, "LSDA Encoding");
  1129. // Encoding of the FDE pointers
  1130. EmitEncodingByte(streamer, MOFI->getFDEEncoding(UsingCFI),
  1131. "FDE Encoding");
  1132. }
  1133. // Initial Instructions
  1134. const MCAsmInfo &MAI = context.getAsmInfo();
  1135. const std::vector<MachineMove> &Moves = MAI.getInitialFrameState();
  1136. std::vector<MCCFIInstruction> Instructions;
  1137. for (int i = 0, n = Moves.size(); i != n; ++i) {
  1138. MCSymbol *Label = Moves[i].getLabel();
  1139. const MachineLocation &Dst =
  1140. TranslateMachineLocation(MRI, Moves[i].getDestination());
  1141. const MachineLocation &Src =
  1142. TranslateMachineLocation(MRI, Moves[i].getSource());
  1143. if (Dst.isReg()) {
  1144. assert(Dst.getReg() == MachineLocation::VirtualFP);
  1145. assert(!Src.isReg());
  1146. MCCFIInstruction Inst =
  1147. MCCFIInstruction::createDefCfa(Label, Src.getReg(), -Src.getOffset());
  1148. Instructions.push_back(Inst);
  1149. } else {
  1150. assert(Src.isReg());
  1151. unsigned Reg = Src.getReg();
  1152. int Offset = Dst.getOffset();
  1153. MCCFIInstruction Inst =
  1154. MCCFIInstruction::createOffset(Label, Reg, Offset);
  1155. Instructions.push_back(Inst);
  1156. }
  1157. }
  1158. EmitCFIInstructions(streamer, Instructions, NULL);
  1159. // Padding
  1160. streamer.EmitValueToAlignment(IsEH
  1161. ? 4 : context.getAsmInfo().getPointerSize());
  1162. streamer.EmitLabel(sectionEnd);
  1163. return *sectionStart;
  1164. }
  1165. MCSymbol *FrameEmitterImpl::EmitFDE(MCStreamer &streamer,
  1166. const MCSymbol &cieStart,
  1167. const MCDwarfFrameInfo &frame) {
  1168. MCContext &context = streamer.getContext();
  1169. MCSymbol *fdeStart = context.CreateTempSymbol();
  1170. MCSymbol *fdeEnd = context.CreateTempSymbol();
  1171. const MCObjectFileInfo *MOFI = context.getObjectFileInfo();
  1172. bool verboseAsm = streamer.isVerboseAsm();
  1173. if (IsEH && frame.Function && !MOFI->isFunctionEHFrameSymbolPrivate()) {
  1174. MCSymbol *EHSym =
  1175. context.GetOrCreateSymbol(frame.Function->getName() + Twine(".eh"));
  1176. streamer.EmitEHSymAttributes(frame.Function, EHSym);
  1177. streamer.EmitLabel(EHSym);
  1178. }
  1179. // Length
  1180. const MCExpr *Length = MakeStartMinusEndExpr(streamer, *fdeStart, *fdeEnd, 0);
  1181. if (verboseAsm) streamer.AddComment("FDE Length");
  1182. streamer.EmitAbsValue(Length, 4);
  1183. streamer.EmitLabel(fdeStart);
  1184. // CIE Pointer
  1185. const MCAsmInfo &asmInfo = context.getAsmInfo();
  1186. if (IsEH) {
  1187. const MCExpr *offset = MakeStartMinusEndExpr(streamer, cieStart, *fdeStart,
  1188. 0);
  1189. if (verboseAsm) streamer.AddComment("FDE CIE Offset");
  1190. streamer.EmitAbsValue(offset, 4);
  1191. } else if (!asmInfo.doesDwarfUseRelocationsAcrossSections()) {
  1192. const MCExpr *offset = MakeStartMinusEndExpr(streamer, *SectionStart,
  1193. cieStart, 0);
  1194. streamer.EmitAbsValue(offset, 4);
  1195. } else {
  1196. streamer.EmitSymbolValue(&cieStart, 4);
  1197. }
  1198. // PC Begin
  1199. unsigned PCEncoding = IsEH ? MOFI->getFDEEncoding(UsingCFI)
  1200. : (unsigned)dwarf::DW_EH_PE_absptr;
  1201. unsigned PCSize = getSizeForEncoding(streamer, PCEncoding);
  1202. EmitSymbol(streamer, *frame.Begin, PCEncoding, "FDE initial location");
  1203. // PC Range
  1204. const MCExpr *Range = MakeStartMinusEndExpr(streamer, *frame.Begin,
  1205. *frame.End, 0);
  1206. if (verboseAsm) streamer.AddComment("FDE address range");
  1207. streamer.EmitAbsValue(Range, PCSize);
  1208. if (IsEH) {
  1209. // Augmentation Data Length
  1210. unsigned augmentationLength = 0;
  1211. if (frame.Lsda)
  1212. augmentationLength += getSizeForEncoding(streamer, frame.LsdaEncoding);
  1213. if (verboseAsm) streamer.AddComment("Augmentation size");
  1214. streamer.EmitULEB128IntValue(augmentationLength);
  1215. // Augmentation Data
  1216. if (frame.Lsda)
  1217. EmitSymbol(streamer, *frame.Lsda, frame.LsdaEncoding,
  1218. "Language Specific Data Area");
  1219. }
  1220. // Call Frame Instructions
  1221. EmitCFIInstructions(streamer, frame.Instructions, frame.Begin);
  1222. // Padding
  1223. streamer.EmitValueToAlignment(PCSize);
  1224. return fdeEnd;
  1225. }
  1226. namespace {
  1227. struct CIEKey {
  1228. static const CIEKey getEmptyKey() { return CIEKey(0, 0, -1, false); }
  1229. static const CIEKey getTombstoneKey() { return CIEKey(0, -1, 0, false); }
  1230. CIEKey(const MCSymbol* Personality_, unsigned PersonalityEncoding_,
  1231. unsigned LsdaEncoding_, bool IsSignalFrame_) :
  1232. Personality(Personality_), PersonalityEncoding(PersonalityEncoding_),
  1233. LsdaEncoding(LsdaEncoding_), IsSignalFrame(IsSignalFrame_) {
  1234. }
  1235. const MCSymbol* Personality;
  1236. unsigned PersonalityEncoding;
  1237. unsigned LsdaEncoding;
  1238. bool IsSignalFrame;
  1239. };
  1240. }
  1241. namespace llvm {
  1242. template <>
  1243. struct DenseMapInfo<CIEKey> {
  1244. static CIEKey getEmptyKey() {
  1245. return CIEKey::getEmptyKey();
  1246. }
  1247. static CIEKey getTombstoneKey() {
  1248. return CIEKey::getTombstoneKey();
  1249. }
  1250. static unsigned getHashValue(const CIEKey &Key) {
  1251. return static_cast<unsigned>(hash_combine(Key.Personality,
  1252. Key.PersonalityEncoding,
  1253. Key.LsdaEncoding,
  1254. Key.IsSignalFrame));
  1255. }
  1256. static bool isEqual(const CIEKey &LHS,
  1257. const CIEKey &RHS) {
  1258. return LHS.Personality == RHS.Personality &&
  1259. LHS.PersonalityEncoding == RHS.PersonalityEncoding &&
  1260. LHS.LsdaEncoding == RHS.LsdaEncoding &&
  1261. LHS.IsSignalFrame == RHS.IsSignalFrame;
  1262. }
  1263. };
  1264. }
  1265. void MCDwarfFrameEmitter::Emit(MCStreamer &Streamer,
  1266. bool UsingCFI,
  1267. bool IsEH) {
  1268. MCContext &Context = Streamer.getContext();
  1269. MCObjectFileInfo *MOFI =
  1270. const_cast<MCObjectFileInfo*>(Context.getObjectFileInfo());
  1271. FrameEmitterImpl Emitter(UsingCFI, IsEH);
  1272. ArrayRef<MCDwarfFrameInfo> FrameArray = Streamer.getFrameInfos();
  1273. // Emit the compact unwind info if available.
  1274. if (IsEH && MOFI->getCompactUnwindSection())
  1275. for (unsigned i = 0, n = Streamer.getNumFrameInfos(); i < n; ++i) {
  1276. const MCDwarfFrameInfo &Frame = Streamer.getFrameInfo(i);
  1277. if (Frame.CompactUnwindEncoding)
  1278. Emitter.EmitCompactUnwind(Streamer, Frame);
  1279. }
  1280. const MCSection &Section = IsEH ? *MOFI->getEHFrameSection() :
  1281. *MOFI->getDwarfFrameSection();
  1282. Streamer.SwitchSection(&Section);
  1283. MCSymbol *SectionStart = Context.CreateTempSymbol();
  1284. Streamer.EmitLabel(SectionStart);
  1285. Emitter.setSectionStart(SectionStart);
  1286. MCSymbol *FDEEnd = NULL;
  1287. DenseMap<CIEKey, const MCSymbol*> CIEStarts;
  1288. const MCSymbol *DummyDebugKey = NULL;
  1289. for (unsigned i = 0, n = FrameArray.size(); i < n; ++i) {
  1290. const MCDwarfFrameInfo &Frame = FrameArray[i];
  1291. CIEKey Key(Frame.Personality, Frame.PersonalityEncoding,
  1292. Frame.LsdaEncoding, Frame.IsSignalFrame);
  1293. const MCSymbol *&CIEStart = IsEH ? CIEStarts[Key] : DummyDebugKey;
  1294. if (!CIEStart)
  1295. CIEStart = &Emitter.EmitCIE(Streamer, Frame.Personality,
  1296. Frame.PersonalityEncoding, Frame.Lsda,
  1297. Frame.IsSignalFrame,
  1298. Frame.LsdaEncoding);
  1299. FDEEnd = Emitter.EmitFDE(Streamer, *CIEStart, Frame);
  1300. if (i != n - 1)
  1301. Streamer.EmitLabel(FDEEnd);
  1302. }
  1303. Streamer.EmitValueToAlignment(Context.getAsmInfo().getPointerSize());
  1304. if (FDEEnd)
  1305. Streamer.EmitLabel(FDEEnd);
  1306. }
  1307. void MCDwarfFrameEmitter::EmitAdvanceLoc(MCStreamer &Streamer,
  1308. uint64_t AddrDelta) {
  1309. SmallString<256> Tmp;
  1310. raw_svector_ostream OS(Tmp);
  1311. MCDwarfFrameEmitter::EncodeAdvanceLoc(AddrDelta, OS);
  1312. Streamer.EmitBytes(OS.str());
  1313. }
  1314. void MCDwarfFrameEmitter::EncodeAdvanceLoc(uint64_t AddrDelta,
  1315. raw_ostream &OS) {
  1316. // FIXME: Assumes the code alignment factor is 1.
  1317. if (AddrDelta == 0) {
  1318. } else if (isUIntN(6, AddrDelta)) {
  1319. uint8_t Opcode = dwarf::DW_CFA_advance_loc | AddrDelta;
  1320. OS << Opcode;
  1321. } else if (isUInt<8>(AddrDelta)) {
  1322. OS << uint8_t(dwarf::DW_CFA_advance_loc1);
  1323. OS << uint8_t(AddrDelta);
  1324. } else if (isUInt<16>(AddrDelta)) {
  1325. // FIXME: check what is the correct behavior on a big endian machine.
  1326. OS << uint8_t(dwarf::DW_CFA_advance_loc2);
  1327. OS << uint8_t( AddrDelta & 0xff);
  1328. OS << uint8_t((AddrDelta >> 8) & 0xff);
  1329. } else {
  1330. // FIXME: check what is the correct behavior on a big endian machine.
  1331. assert(isUInt<32>(AddrDelta));
  1332. OS << uint8_t(dwarf::DW_CFA_advance_loc4);
  1333. OS << uint8_t( AddrDelta & 0xff);
  1334. OS << uint8_t((AddrDelta >> 8) & 0xff);
  1335. OS << uint8_t((AddrDelta >> 16) & 0xff);
  1336. OS << uint8_t((AddrDelta >> 24) & 0xff);
  1337. }
  1338. }