Alexey Lapshin | 345bea1 | 2020-04-07 00:42:40 +0300 | [diff] [blame] | 1 | //===- DwarfStreamer.cpp --------------------------------------------------===// |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 2 | // |
Chandler Carruth | ca6d719 | 2019-01-19 08:50:56 +0000 | [diff] [blame] | 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| 4 | // See https://llvm.org/LICENSE.txt for license information. |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 6 | // |
| 7 | //===----------------------------------------------------------------------===// |
| 8 | |
Alexey Lapshin | 345bea1 | 2020-04-07 00:42:40 +0300 | [diff] [blame] | 9 | #include "llvm/DWARFLinker/DWARFStreamer.h" |
Alexey Lapshin | 345bea1 | 2020-04-07 00:42:40 +0300 | [diff] [blame] | 10 | #include "llvm/CodeGen/NonRelocatableStringpool.h" |
Alexey Lapshin | 95654b1 | 2019-12-20 19:23:31 +0300 | [diff] [blame] | 11 | #include "llvm/DWARFLinker/DWARFLinkerCompileUnit.h" |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 12 | #include "llvm/DebugInfo/DWARF/DWARFContext.h" |
Alexey Lapshin | 8a11d4e | 2022-09-23 09:34:26 +0300 | [diff] [blame] | 13 | #include "llvm/DebugInfo/DWARF/DWARFDebugMacro.h" |
Alexey Lapshin | 345bea1 | 2020-04-07 00:42:40 +0300 | [diff] [blame] | 14 | #include "llvm/MC/MCAsmBackend.h" |
| 15 | #include "llvm/MC/MCCodeEmitter.h" |
| 16 | #include "llvm/MC/MCDwarf.h" |
| 17 | #include "llvm/MC/MCObjectWriter.h" |
| 18 | #include "llvm/MC/MCSection.h" |
| 19 | #include "llvm/MC/MCStreamer.h" |
| 20 | #include "llvm/MC/MCSubtargetInfo.h" |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 21 | #include "llvm/MC/MCTargetOptions.h" |
serge-sans-paille | 54972d3 | 2020-03-04 00:47:43 +0100 | [diff] [blame] | 22 | #include "llvm/MC/MCTargetOptionsCommandFlags.h" |
Reid Kleckner | fd8be14 | 2021-10-08 10:48:15 -0700 | [diff] [blame] | 23 | #include "llvm/MC/TargetRegistry.h" |
Alexey Lapshin | 8a11d4e | 2022-09-23 09:34:26 +0300 | [diff] [blame] | 24 | #include "llvm/Support/FormatVariadic.h" |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 25 | #include "llvm/Support/LEB128.h" |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 26 | #include "llvm/Target/TargetOptions.h" |
Archibald Elliott | 64a2d25 | 2023-02-07 12:21:51 +0000 | [diff] [blame] | 27 | #include "llvm/TargetParser/Triple.h" |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 28 | |
| 29 | namespace llvm { |
serge-sans-paille | 54972d3 | 2020-03-04 00:47:43 +0100 | [diff] [blame] | 30 | |
Alexey Lapshin | 37c2eba | 2023-06-04 13:28:54 +0200 | [diff] [blame] | 31 | bool DwarfStreamer::init(Triple TheTriple, |
| 32 | StringRef Swift5ReflectionSegmentName) { |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 33 | std::string ErrorStr; |
| 34 | std::string TripleName; |
Alexey Lapshin | 37c2eba | 2023-06-04 13:28:54 +0200 | [diff] [blame] | 35 | StringRef Context = "dwarf streamer init"; |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 36 | |
| 37 | // Get the target. |
| 38 | const Target *TheTarget = |
| 39 | TargetRegistry::lookupTarget(TripleName, TheTriple, ErrorStr); |
| 40 | if (!TheTarget) |
Alexey Lapshin | 37c2eba | 2023-06-04 13:28:54 +0200 | [diff] [blame] | 41 | return error(ErrorStr, Context), false; |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 42 | TripleName = TheTriple.getTriple(); |
| 43 | |
| 44 | // Create all the MC Objects. |
| 45 | MRI.reset(TheTarget->createMCRegInfo(TripleName)); |
| 46 | if (!MRI) |
Alexey Lapshin | 37c2eba | 2023-06-04 13:28:54 +0200 | [diff] [blame] | 47 | return error(Twine("no register info for target ") + TripleName, Context), |
| 48 | false; |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 49 | |
serge-sans-paille | 54972d3 | 2020-03-04 00:47:43 +0100 | [diff] [blame] | 50 | MCTargetOptions MCOptions = mc::InitMCTargetOptionsFromFlags(); |
Mirko Brkusanin | 445a09f | 2019-10-23 12:24:35 +0200 | [diff] [blame] | 51 | MAI.reset(TheTarget->createMCAsmInfo(*MRI, TripleName, MCOptions)); |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 52 | if (!MAI) |
Alexey Lapshin | 37c2eba | 2023-06-04 13:28:54 +0200 | [diff] [blame] | 53 | return error("no asm info for target " + TripleName, Context), false; |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 54 | |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 55 | MSTI.reset(TheTarget->createMCSubtargetInfo(TripleName, "", "")); |
| 56 | if (!MSTI) |
Alexey Lapshin | 37c2eba | 2023-06-04 13:28:54 +0200 | [diff] [blame] | 57 | return error("no subtarget info for target " + TripleName, Context), false; |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 58 | |
Shubham Sandeep Rastogi | 2721597 | 2021-11-17 15:05:58 -0800 | [diff] [blame] | 59 | MC.reset(new MCContext(TheTriple, MAI.get(), MRI.get(), MSTI.get(), nullptr, |
| 60 | nullptr, true, Swift5ReflectionSegmentName)); |
| 61 | MOFI.reset(TheTarget->createMCObjectFileInfo(*MC, /*PIC=*/false, false)); |
Philipp Krones | d212d73 | 2021-05-23 14:15:23 -0700 | [diff] [blame] | 62 | MC->setObjectFileInfo(MOFI.get()); |
Philipp Krones | 2910450 | 2021-05-05 10:03:02 -0700 | [diff] [blame] | 63 | |
Jonas Devlieghere | 547eb4c | 2018-07-09 16:58:48 +0000 | [diff] [blame] | 64 | MAB = TheTarget->createMCAsmBackend(*MSTI, *MRI, MCOptions); |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 65 | if (!MAB) |
Alexey Lapshin | 37c2eba | 2023-06-04 13:28:54 +0200 | [diff] [blame] | 66 | return error("no asm backend for target " + TripleName, Context), false; |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 67 | |
| 68 | MII.reset(TheTarget->createMCInstrInfo()); |
| 69 | if (!MII) |
Alexey Lapshin | 37c2eba | 2023-06-04 13:28:54 +0200 | [diff] [blame] | 70 | return error("no instr info info for target " + TripleName, Context), false; |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 71 | |
Shao-Ce SUN | 2b9c3ff | 2022-02-16 13:09:59 +0800 | [diff] [blame] | 72 | MCE = TheTarget->createMCCodeEmitter(*MII, *MC); |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 73 | if (!MCE) |
Alexey Lapshin | 37c2eba | 2023-06-04 13:28:54 +0200 | [diff] [blame] | 74 | return error("no code emitter for target " + TripleName, Context), false; |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 75 | |
Alexey Lapshin | 345bea1 | 2020-04-07 00:42:40 +0300 | [diff] [blame] | 76 | switch (OutFileType) { |
Alexey Lapshin | 37c2eba | 2023-06-04 13:28:54 +0200 | [diff] [blame] | 77 | case OutputFileType::Assembly: { |
Jonas Devlieghere | 547eb4c | 2018-07-09 16:58:48 +0000 | [diff] [blame] | 78 | MIP = TheTarget->createMCInstPrinter(TheTriple, MAI->getAssemblerDialect(), |
| 79 | *MAI, *MII, *MRI); |
| 80 | MS = TheTarget->createAsmStreamer( |
Jonas Devlieghere | 77ff406 | 2019-08-15 15:54:37 +0000 | [diff] [blame] | 81 | *MC, std::make_unique<formatted_raw_ostream>(OutFile), true, true, MIP, |
Jonas Devlieghere | 547eb4c | 2018-07-09 16:58:48 +0000 | [diff] [blame] | 82 | std::unique_ptr<MCCodeEmitter>(MCE), std::unique_ptr<MCAsmBackend>(MAB), |
| 83 | true); |
| 84 | break; |
| 85 | } |
Alexey Lapshin | 37c2eba | 2023-06-04 13:28:54 +0200 | [diff] [blame] | 86 | case OutputFileType::Object: { |
Jonas Devlieghere | 547eb4c | 2018-07-09 16:58:48 +0000 | [diff] [blame] | 87 | MS = TheTarget->createMCObjectStreamer( |
| 88 | TheTriple, *MC, std::unique_ptr<MCAsmBackend>(MAB), |
| 89 | MAB->createObjectWriter(OutFile), std::unique_ptr<MCCodeEmitter>(MCE), |
| 90 | *MSTI, MCOptions.MCRelaxAll, MCOptions.MCIncrementalLinkerCompatible, |
| 91 | /*DWARFMustBeAtTheEnd*/ false); |
| 92 | break; |
| 93 | } |
| 94 | } |
| 95 | |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 96 | if (!MS) |
Alexey Lapshin | 37c2eba | 2023-06-04 13:28:54 +0200 | [diff] [blame] | 97 | return error("no object streamer for target " + TripleName, Context), false; |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 98 | |
| 99 | // Finally create the AsmPrinter we'll use to emit the DIEs. |
| 100 | TM.reset(TheTarget->createTargetMachine(TripleName, "", "", TargetOptions(), |
Kazu Hirata | c5abb07 | 2022-12-02 21:11:44 -0800 | [diff] [blame] | 101 | std::nullopt)); |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 102 | if (!TM) |
Alexey Lapshin | 37c2eba | 2023-06-04 13:28:54 +0200 | [diff] [blame] | 103 | return error("no target machine for target " + TripleName, Context), false; |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 104 | |
| 105 | Asm.reset(TheTarget->createAsmPrinter(*TM, std::unique_ptr<MCStreamer>(MS))); |
| 106 | if (!Asm) |
Alexey Lapshin | 37c2eba | 2023-06-04 13:28:54 +0200 | [diff] [blame] | 107 | return error("no asm printer for target " + TripleName, Context), false; |
Alexey Lapshin | bf2fa46 | 2023-01-15 22:31:35 +0100 | [diff] [blame] | 108 | Asm->setDwarfUsesRelocationsAcrossSections(false); |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 109 | |
| 110 | RangesSectionSize = 0; |
Alexey Lapshin | 7ddf4ce | 2023-02-26 18:57:50 +0100 | [diff] [blame] | 111 | RngListsSectionSize = 0; |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 112 | LocSectionSize = 0; |
Alexey Lapshin | 70c9be6 | 2023-02-27 17:59:30 +0100 | [diff] [blame] | 113 | LocListsSectionSize = 0; |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 114 | LineSectionSize = 0; |
| 115 | FrameSectionSize = 0; |
Alexey Lapshin | 5e7af8f | 2020-01-09 16:02:50 +0300 | [diff] [blame] | 116 | DebugInfoSectionSize = 0; |
Alexey Lapshin | 8a11d4e | 2022-09-23 09:34:26 +0300 | [diff] [blame] | 117 | MacInfoSectionSize = 0; |
| 118 | MacroSectionSize = 0; |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 119 | |
Alexey Lapshin | 37c2eba | 2023-06-04 13:28:54 +0200 | [diff] [blame] | 120 | return true; |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 121 | } |
| 122 | |
Fangrui Song | 0721f99 | 2022-06-07 00:31:02 -0700 | [diff] [blame] | 123 | void DwarfStreamer::finish() { MS->finish(); } |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 124 | |
| 125 | void DwarfStreamer::switchToDebugInfoSection(unsigned DwarfVersion) { |
Fangrui Song | 5cd8d2a | 2022-06-10 22:50:55 -0700 | [diff] [blame] | 126 | MS->switchSection(MOFI->getDwarfInfoSection()); |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 127 | MC->setDwarfVersion(DwarfVersion); |
| 128 | } |
| 129 | |
| 130 | /// Emit the compilation unit header for \p Unit in the debug_info section. |
| 131 | /// |
Jonas Devlieghere | 6418c15 | 2021-01-12 21:55:41 -0800 | [diff] [blame] | 132 | /// A Dwarf 4 section header is encoded as: |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 133 | /// uint32_t Unit length (omitting this field) |
| 134 | /// uint16_t Version |
| 135 | /// uint32_t Abbreviation table offset |
| 136 | /// uint8_t Address size |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 137 | /// Leading to a total of 11 bytes. |
Jonas Devlieghere | 6418c15 | 2021-01-12 21:55:41 -0800 | [diff] [blame] | 138 | /// |
| 139 | /// A Dwarf 5 section header is encoded as: |
| 140 | /// uint32_t Unit length (omitting this field) |
| 141 | /// uint16_t Version |
| 142 | /// uint8_t Unit type |
| 143 | /// uint8_t Address size |
| 144 | /// uint32_t Abbreviation table offset |
| 145 | /// Leading to a total of 12 bytes. |
| 146 | void DwarfStreamer::emitCompileUnitHeader(CompileUnit &Unit, |
| 147 | unsigned DwarfVersion) { |
| 148 | switchToDebugInfoSection(DwarfVersion); |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 149 | |
Jonas Devlieghere | 22c1513 | 2018-07-06 12:49:54 +0000 | [diff] [blame] | 150 | /// The start of the unit within its section. |
| 151 | Unit.setLabelBegin(Asm->createTempSymbol("cu_begin")); |
Fangrui Song | 3f0f64a | 2020-02-14 19:21:58 -0800 | [diff] [blame] | 152 | Asm->OutStreamer->emitLabel(Unit.getLabelBegin()); |
Jonas Devlieghere | 22c1513 | 2018-07-06 12:49:54 +0000 | [diff] [blame] | 153 | |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 154 | // Emit size of content not including length itself. The size has already |
| 155 | // been computed in CompileUnit::computeOffsets(). Subtract 4 to that size to |
| 156 | // account for the length field. |
| 157 | Asm->emitInt32(Unit.getNextUnitOffset() - Unit.getStartOffset() - 4); |
Jonas Devlieghere | 6418c15 | 2021-01-12 21:55:41 -0800 | [diff] [blame] | 158 | Asm->emitInt16(DwarfVersion); |
Jonas Devlieghere | 22c1513 | 2018-07-06 12:49:54 +0000 | [diff] [blame] | 159 | |
Jonas Devlieghere | 6418c15 | 2021-01-12 21:55:41 -0800 | [diff] [blame] | 160 | if (DwarfVersion >= 5) { |
| 161 | Asm->emitInt8(dwarf::DW_UT_compile); |
| 162 | Asm->emitInt8(Unit.getOrigUnit().getAddressByteSize()); |
| 163 | // We share one abbreviations table across all units so it's always at the |
| 164 | // start of the section. |
| 165 | Asm->emitInt32(0); |
| 166 | DebugInfoSectionSize += 12; |
| 167 | } else { |
| 168 | // We share one abbreviations table across all units so it's always at the |
| 169 | // start of the section. |
| 170 | Asm->emitInt32(0); |
| 171 | Asm->emitInt8(Unit.getOrigUnit().getAddressByteSize()); |
| 172 | DebugInfoSectionSize += 11; |
| 173 | } |
Jonas Devlieghere | f01fbc3 | 2018-07-25 23:01:38 +0000 | [diff] [blame] | 174 | |
| 175 | // Remember this CU. |
| 176 | EmittedUnits.push_back({Unit.getUniqueID(), Unit.getLabelBegin()}); |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 177 | } |
| 178 | |
| 179 | /// Emit the \p Abbrevs array as the shared abbreviation table |
| 180 | /// for the linked Dwarf file. |
| 181 | void DwarfStreamer::emitAbbrevs( |
| 182 | const std::vector<std::unique_ptr<DIEAbbrev>> &Abbrevs, |
| 183 | unsigned DwarfVersion) { |
Fangrui Song | 5cd8d2a | 2022-06-10 22:50:55 -0700 | [diff] [blame] | 184 | MS->switchSection(MOFI->getDwarfAbbrevSection()); |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 185 | MC->setDwarfVersion(DwarfVersion); |
| 186 | Asm->emitDwarfAbbrevs(Abbrevs); |
| 187 | } |
| 188 | |
| 189 | /// Recursively emit the DIE tree rooted at \p Die. |
| 190 | void DwarfStreamer::emitDIE(DIE &Die) { |
Fangrui Song | 5cd8d2a | 2022-06-10 22:50:55 -0700 | [diff] [blame] | 191 | MS->switchSection(MOFI->getDwarfInfoSection()); |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 192 | Asm->emitDwarfDIE(Die); |
Alexey Lapshin | 5e7af8f | 2020-01-09 16:02:50 +0300 | [diff] [blame] | 193 | DebugInfoSectionSize += Die.getSize(); |
| 194 | } |
| 195 | |
| 196 | /// Emit contents of section SecName From Obj. |
Alexey Lapshin | 7a5e528 | 2020-02-22 14:33:58 +0300 | [diff] [blame] | 197 | void DwarfStreamer::emitSectionContents(StringRef SecData, StringRef SecName) { |
Alexey Lapshin | 5e7af8f | 2020-01-09 16:02:50 +0300 | [diff] [blame] | 198 | MCSection *Section = |
| 199 | StringSwitch<MCSection *>(SecName) |
| 200 | .Case("debug_line", MC->getObjectFileInfo()->getDwarfLineSection()) |
| 201 | .Case("debug_loc", MC->getObjectFileInfo()->getDwarfLocSection()) |
| 202 | .Case("debug_ranges", |
| 203 | MC->getObjectFileInfo()->getDwarfRangesSection()) |
| 204 | .Case("debug_frame", MC->getObjectFileInfo()->getDwarfFrameSection()) |
| 205 | .Case("debug_aranges", |
| 206 | MC->getObjectFileInfo()->getDwarfARangesSection()) |
Alexey Lapshin | 7ddf4ce | 2023-02-26 18:57:50 +0100 | [diff] [blame] | 207 | .Case("debug_addr", MC->getObjectFileInfo()->getDwarfAddrSection()) |
| 208 | .Case("debug_rnglists", |
| 209 | MC->getObjectFileInfo()->getDwarfRnglistsSection()) |
Alexey Lapshin | 70c9be6 | 2023-02-27 17:59:30 +0100 | [diff] [blame] | 210 | .Case("debug_loclists", |
| 211 | MC->getObjectFileInfo()->getDwarfLoclistsSection()) |
Alexey Lapshin | 5e7af8f | 2020-01-09 16:02:50 +0300 | [diff] [blame] | 212 | .Default(nullptr); |
| 213 | |
| 214 | if (Section) { |
Fangrui Song | 5cd8d2a | 2022-06-10 22:50:55 -0700 | [diff] [blame] | 215 | MS->switchSection(Section); |
Alexey Lapshin | 5e7af8f | 2020-01-09 16:02:50 +0300 | [diff] [blame] | 216 | |
Alexey Lapshin | 7a5e528 | 2020-02-22 14:33:58 +0300 | [diff] [blame] | 217 | MS->emitBytes(SecData); |
Alexey Lapshin | 5e7af8f | 2020-01-09 16:02:50 +0300 | [diff] [blame] | 218 | } |
| 219 | } |
| 220 | |
| 221 | /// Emit DIE containing warnings. |
Fangrui Song | d4f6715 | 2020-02-06 14:48:28 -0800 | [diff] [blame] | 222 | void DwarfStreamer::emitPaperTrailWarningsDie(DIE &Die) { |
Alexey Lapshin | 5e7af8f | 2020-01-09 16:02:50 +0300 | [diff] [blame] | 223 | switchToDebugInfoSection(/* Version */ 2); |
| 224 | auto &Asm = getAsmPrinter(); |
| 225 | Asm.emitInt32(11 + Die.getSize() - 4); |
| 226 | Asm.emitInt16(2); |
| 227 | Asm.emitInt32(0); |
Philipp Krones | 2910450 | 2021-05-05 10:03:02 -0700 | [diff] [blame] | 228 | Asm.emitInt8(MC->getTargetTriple().isArch64Bit() ? 8 : 4); |
Alexey Lapshin | 5e7af8f | 2020-01-09 16:02:50 +0300 | [diff] [blame] | 229 | DebugInfoSectionSize += 11; |
| 230 | emitDIE(Die); |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 231 | } |
| 232 | |
| 233 | /// Emit the debug_str section stored in \p Pool. |
| 234 | void DwarfStreamer::emitStrings(const NonRelocatableStringpool &Pool) { |
Fangrui Song | 5cd8d2a | 2022-06-10 22:50:55 -0700 | [diff] [blame] | 235 | Asm->OutStreamer->switchSection(MOFI->getDwarfStrSection()); |
Pavel Labath | 6ad6592 | 2018-08-07 09:54:52 +0000 | [diff] [blame] | 236 | std::vector<DwarfStringPoolEntryRef> Entries = Pool.getEntriesForEmission(); |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 237 | for (auto Entry : Entries) { |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 238 | // Emit the string itself. |
Fangrui Song | 297d076 | 2020-02-14 18:16:24 -0800 | [diff] [blame] | 239 | Asm->OutStreamer->emitBytes(Entry.getString()); |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 240 | // Emit a null terminator. |
| 241 | Asm->emitInt8(0); |
| 242 | } |
Alexey Lapshin | e1d1493 | 2023-05-11 19:09:47 +0200 | [diff] [blame] | 243 | } |
Jonas Devlieghere | 6418c15 | 2021-01-12 21:55:41 -0800 | [diff] [blame] | 244 | |
Alexey Lapshin | e1d1493 | 2023-05-11 19:09:47 +0200 | [diff] [blame] | 245 | /// Emit the debug_line_str section stored in \p Pool. |
| 246 | void DwarfStreamer::emitLineStrings(const NonRelocatableStringpool &Pool) { |
| 247 | Asm->OutStreamer->switchSection(MOFI->getDwarfLineStrSection()); |
| 248 | std::vector<DwarfStringPoolEntryRef> Entries = Pool.getEntriesForEmission(); |
| 249 | for (auto Entry : Entries) { |
| 250 | // Emit the string itself. |
| 251 | Asm->OutStreamer->emitBytes(Entry.getString()); |
| 252 | // Emit a null terminator. |
| 253 | Asm->emitInt8(0); |
Jonas Devlieghere | 6418c15 | 2021-01-12 21:55:41 -0800 | [diff] [blame] | 254 | } |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 255 | } |
| 256 | |
Jonas Devlieghere | f01fbc3 | 2018-07-25 23:01:38 +0000 | [diff] [blame] | 257 | void DwarfStreamer::emitDebugNames( |
| 258 | AccelTable<DWARF5AccelTableStaticData> &Table) { |
| 259 | if (EmittedUnits.empty()) |
| 260 | return; |
| 261 | |
| 262 | // Build up data structures needed to emit this section. |
| 263 | std::vector<MCSymbol *> CompUnits; |
| 264 | DenseMap<unsigned, size_t> UniqueIdToCuMap; |
| 265 | unsigned Id = 0; |
| 266 | for (auto &CU : EmittedUnits) { |
| 267 | CompUnits.push_back(CU.LabelBegin); |
| 268 | // We might be omitting CUs, so we need to remap them. |
| 269 | UniqueIdToCuMap[CU.ID] = Id++; |
| 270 | } |
| 271 | |
Fangrui Song | 5cd8d2a | 2022-06-10 22:50:55 -0700 | [diff] [blame] | 272 | Asm->OutStreamer->switchSection(MOFI->getDwarfDebugNamesSection()); |
Jonas Devlieghere | f01fbc3 | 2018-07-25 23:01:38 +0000 | [diff] [blame] | 273 | emitDWARF5AccelTable( |
| 274 | Asm.get(), Table, CompUnits, |
| 275 | [&UniqueIdToCuMap](const DWARF5AccelTableStaticData &Entry) { |
| 276 | return UniqueIdToCuMap[Entry.getCUIndex()]; |
| 277 | }); |
| 278 | } |
| 279 | |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 280 | void DwarfStreamer::emitAppleNamespaces( |
| 281 | AccelTable<AppleAccelTableStaticOffsetData> &Table) { |
Fangrui Song | 5cd8d2a | 2022-06-10 22:50:55 -0700 | [diff] [blame] | 282 | Asm->OutStreamer->switchSection(MOFI->getDwarfAccelNamespaceSection()); |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 283 | auto *SectionBegin = Asm->createTempSymbol("namespac_begin"); |
Fangrui Song | 3f0f64a | 2020-02-14 19:21:58 -0800 | [diff] [blame] | 284 | Asm->OutStreamer->emitLabel(SectionBegin); |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 285 | emitAppleAccelTable(Asm.get(), Table, "namespac", SectionBegin); |
| 286 | } |
| 287 | |
| 288 | void DwarfStreamer::emitAppleNames( |
| 289 | AccelTable<AppleAccelTableStaticOffsetData> &Table) { |
Fangrui Song | 5cd8d2a | 2022-06-10 22:50:55 -0700 | [diff] [blame] | 290 | Asm->OutStreamer->switchSection(MOFI->getDwarfAccelNamesSection()); |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 291 | auto *SectionBegin = Asm->createTempSymbol("names_begin"); |
Fangrui Song | 3f0f64a | 2020-02-14 19:21:58 -0800 | [diff] [blame] | 292 | Asm->OutStreamer->emitLabel(SectionBegin); |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 293 | emitAppleAccelTable(Asm.get(), Table, "names", SectionBegin); |
| 294 | } |
| 295 | |
| 296 | void DwarfStreamer::emitAppleObjc( |
| 297 | AccelTable<AppleAccelTableStaticOffsetData> &Table) { |
Fangrui Song | 5cd8d2a | 2022-06-10 22:50:55 -0700 | [diff] [blame] | 298 | Asm->OutStreamer->switchSection(MOFI->getDwarfAccelObjCSection()); |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 299 | auto *SectionBegin = Asm->createTempSymbol("objc_begin"); |
Fangrui Song | 3f0f64a | 2020-02-14 19:21:58 -0800 | [diff] [blame] | 300 | Asm->OutStreamer->emitLabel(SectionBegin); |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 301 | emitAppleAccelTable(Asm.get(), Table, "objc", SectionBegin); |
| 302 | } |
| 303 | |
| 304 | void DwarfStreamer::emitAppleTypes( |
| 305 | AccelTable<AppleAccelTableStaticTypeData> &Table) { |
Fangrui Song | 5cd8d2a | 2022-06-10 22:50:55 -0700 | [diff] [blame] | 306 | Asm->OutStreamer->switchSection(MOFI->getDwarfAccelTypesSection()); |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 307 | auto *SectionBegin = Asm->createTempSymbol("types_begin"); |
Fangrui Song | 3f0f64a | 2020-02-14 19:21:58 -0800 | [diff] [blame] | 308 | Asm->OutStreamer->emitLabel(SectionBegin); |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 309 | emitAppleAccelTable(Asm.get(), Table, "types", SectionBegin); |
| 310 | } |
| 311 | |
| 312 | /// Emit the swift_ast section stored in \p Buffers. |
| 313 | void DwarfStreamer::emitSwiftAST(StringRef Buffer) { |
| 314 | MCSection *SwiftASTSection = MOFI->getDwarfSwiftASTSection(); |
Guillaume Chatelet | 549dc0a | 2019-09-27 12:54:21 +0000 | [diff] [blame] | 315 | SwiftASTSection->setAlignment(Align(32)); |
Fangrui Song | 5cd8d2a | 2022-06-10 22:50:55 -0700 | [diff] [blame] | 316 | MS->switchSection(SwiftASTSection); |
Fangrui Song | 297d076 | 2020-02-14 18:16:24 -0800 | [diff] [blame] | 317 | MS->emitBytes(Buffer); |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 318 | } |
| 319 | |
Shubham Sandeep Rastogi | 2721597 | 2021-11-17 15:05:58 -0800 | [diff] [blame] | 320 | void DwarfStreamer::emitSwiftReflectionSection( |
Shubham Sandeep Rastogi | 0d13278 | 2022-02-01 10:30:28 -0800 | [diff] [blame] | 321 | llvm::binaryformat::Swift5ReflectionSectionKind ReflSectionKind, |
| 322 | StringRef Buffer, uint32_t Alignment, uint32_t Size) { |
Shubham Sandeep Rastogi | 2721597 | 2021-11-17 15:05:58 -0800 | [diff] [blame] | 323 | MCSection *ReflectionSection = |
| 324 | MOFI->getSwift5ReflectionSection(ReflSectionKind); |
| 325 | if (ReflectionSection == nullptr) |
| 326 | return; |
| 327 | ReflectionSection->setAlignment(Align(Alignment)); |
Fangrui Song | 5cd8d2a | 2022-06-10 22:50:55 -0700 | [diff] [blame] | 328 | MS->switchSection(ReflectionSection); |
Shubham Sandeep Rastogi | 2721597 | 2021-11-17 15:05:58 -0800 | [diff] [blame] | 329 | MS->emitBytes(Buffer); |
| 330 | } |
| 331 | |
Alexey Lapshin | eb2dd7ba | 2023-01-20 16:48:13 +0100 | [diff] [blame] | 332 | void DwarfStreamer::emitDwarfDebugArangesTable( |
| 333 | const CompileUnit &Unit, const AddressRanges &LinkedRanges) { |
| 334 | unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize(); |
| 335 | |
| 336 | // Make .debug_aranges to be current section. |
| 337 | MS->switchSection(MC->getObjectFileInfo()->getDwarfARangesSection()); |
| 338 | |
| 339 | // Emit Header. |
| 340 | MCSymbol *BeginLabel = Asm->createTempSymbol("Barange"); |
| 341 | MCSymbol *EndLabel = Asm->createTempSymbol("Earange"); |
| 342 | |
| 343 | unsigned HeaderSize = |
| 344 | sizeof(int32_t) + // Size of contents (w/o this field |
| 345 | sizeof(int16_t) + // DWARF ARange version number |
| 346 | sizeof(int32_t) + // Offset of CU in the .debug_info section |
| 347 | sizeof(int8_t) + // Pointer Size (in bytes) |
| 348 | sizeof(int8_t); // Segment Size (in bytes) |
| 349 | |
| 350 | unsigned TupleSize = AddressSize * 2; |
| 351 | unsigned Padding = offsetToAlignment(HeaderSize, Align(TupleSize)); |
| 352 | |
| 353 | Asm->emitLabelDifference(EndLabel, BeginLabel, 4); // Arange length |
| 354 | Asm->OutStreamer->emitLabel(BeginLabel); |
| 355 | Asm->emitInt16(dwarf::DW_ARANGES_VERSION); // Version number |
| 356 | Asm->emitInt32(Unit.getStartOffset()); // Corresponding unit's offset |
| 357 | Asm->emitInt8(AddressSize); // Address size |
| 358 | Asm->emitInt8(0); // Segment size |
| 359 | |
| 360 | Asm->OutStreamer->emitFill(Padding, 0x0); |
| 361 | |
| 362 | // Emit linked ranges. |
| 363 | for (const AddressRange &Range : LinkedRanges) { |
| 364 | MS->emitIntValue(Range.start(), AddressSize); |
| 365 | MS->emitIntValue(Range.end() - Range.start(), AddressSize); |
| 366 | } |
| 367 | |
| 368 | // Emit terminator. |
| 369 | Asm->OutStreamer->emitIntValue(0, AddressSize); |
| 370 | Asm->OutStreamer->emitIntValue(0, AddressSize); |
| 371 | Asm->OutStreamer->emitLabel(EndLabel); |
| 372 | } |
| 373 | |
| 374 | void DwarfStreamer::emitDwarfDebugRangesTableFragment( |
Alexey Lapshin | 7ddf4ce | 2023-02-26 18:57:50 +0100 | [diff] [blame] | 375 | const CompileUnit &Unit, const AddressRanges &LinkedRanges, |
| 376 | PatchLocation Patch) { |
| 377 | Patch.set(RangesSectionSize); |
Alexey Lapshin | eb2dd7ba | 2023-01-20 16:48:13 +0100 | [diff] [blame] | 378 | |
| 379 | // Make .debug_ranges to be current section. |
Fangrui Song | 5cd8d2a | 2022-06-10 22:50:55 -0700 | [diff] [blame] | 380 | MS->switchSection(MC->getObjectFileInfo()->getDwarfRangesSection()); |
Alexey Lapshin | 7ddf4ce | 2023-02-26 18:57:50 +0100 | [diff] [blame] | 381 | unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize(); |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 382 | |
Alexey Lapshin | eb2dd7ba | 2023-01-20 16:48:13 +0100 | [diff] [blame] | 383 | // Emit ranges. |
| 384 | uint64_t BaseAddress = 0; |
| 385 | if (std::optional<uint64_t> LowPC = Unit.getLowPc()) |
| 386 | BaseAddress = *LowPC; |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 387 | |
Alexey Lapshin | eb2dd7ba | 2023-01-20 16:48:13 +0100 | [diff] [blame] | 388 | for (const AddressRange &Range : LinkedRanges) { |
| 389 | MS->emitIntValue(Range.start() - BaseAddress, AddressSize); |
| 390 | MS->emitIntValue(Range.end() - BaseAddress, AddressSize); |
| 391 | |
| 392 | RangesSectionSize += AddressSize; |
| 393 | RangesSectionSize += AddressSize; |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 394 | } |
| 395 | |
| 396 | // Add the terminator entry. |
Fangrui Song | 9c6c616 | 2020-02-14 22:40:47 -0800 | [diff] [blame] | 397 | MS->emitIntValue(0, AddressSize); |
| 398 | MS->emitIntValue(0, AddressSize); |
Alexey Lapshin | eb2dd7ba | 2023-01-20 16:48:13 +0100 | [diff] [blame] | 399 | |
| 400 | RangesSectionSize += AddressSize; |
| 401 | RangesSectionSize += AddressSize; |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 402 | } |
| 403 | |
Alexey Lapshin | 7ddf4ce | 2023-02-26 18:57:50 +0100 | [diff] [blame] | 404 | MCSymbol * |
| 405 | DwarfStreamer::emitDwarfDebugRangeListHeader(const CompileUnit &Unit) { |
| 406 | if (Unit.getOrigUnit().getVersion() < 5) |
| 407 | return nullptr; |
Alexey Lapshin | 39c1831 | 2022-07-19 18:11:07 +0300 | [diff] [blame] | 408 | |
Alexey Lapshin | 7ddf4ce | 2023-02-26 18:57:50 +0100 | [diff] [blame] | 409 | // Make .debug_rnglists to be current section. |
| 410 | MS->switchSection(MC->getObjectFileInfo()->getDwarfRnglistsSection()); |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 411 | |
Alexey Lapshin | 7ddf4ce | 2023-02-26 18:57:50 +0100 | [diff] [blame] | 412 | MCSymbol *BeginLabel = Asm->createTempSymbol("Brnglists"); |
| 413 | MCSymbol *EndLabel = Asm->createTempSymbol("Ernglists"); |
| 414 | unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize(); |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 415 | |
Alexey Lapshin | 7ddf4ce | 2023-02-26 18:57:50 +0100 | [diff] [blame] | 416 | // Length |
| 417 | Asm->emitLabelDifference(EndLabel, BeginLabel, sizeof(uint32_t)); |
| 418 | Asm->OutStreamer->emitLabel(BeginLabel); |
| 419 | RngListsSectionSize += sizeof(uint32_t); |
| 420 | |
| 421 | // Version. |
| 422 | MS->emitInt16(5); |
| 423 | RngListsSectionSize += sizeof(uint16_t); |
| 424 | |
| 425 | // Address size. |
| 426 | MS->emitInt8(AddressSize); |
| 427 | RngListsSectionSize++; |
| 428 | |
| 429 | // Seg_size |
| 430 | MS->emitInt8(0); |
| 431 | RngListsSectionSize++; |
| 432 | |
| 433 | // Offset entry count |
| 434 | MS->emitInt32(0); |
| 435 | RngListsSectionSize += sizeof(uint32_t); |
| 436 | |
| 437 | return EndLabel; |
| 438 | } |
| 439 | |
| 440 | void DwarfStreamer::emitDwarfDebugRangeListFragment( |
| 441 | const CompileUnit &Unit, const AddressRanges &LinkedRanges, |
| 442 | PatchLocation Patch) { |
| 443 | if (Unit.getOrigUnit().getVersion() < 5) { |
| 444 | emitDwarfDebugRangesTableFragment(Unit, LinkedRanges, Patch); |
| 445 | return; |
| 446 | } |
| 447 | |
| 448 | emitDwarfDebugRngListsTableFragment(Unit, LinkedRanges, Patch); |
| 449 | } |
| 450 | |
| 451 | void DwarfStreamer::emitDwarfDebugRangeListFooter(const CompileUnit &Unit, |
| 452 | MCSymbol *EndLabel) { |
| 453 | if (Unit.getOrigUnit().getVersion() < 5) |
| 454 | return; |
| 455 | |
| 456 | // Make .debug_rnglists to be current section. |
| 457 | MS->switchSection(MC->getObjectFileInfo()->getDwarfRnglistsSection()); |
| 458 | |
| 459 | if (EndLabel != nullptr) |
| 460 | Asm->OutStreamer->emitLabel(EndLabel); |
| 461 | } |
| 462 | |
| 463 | void DwarfStreamer::emitDwarfDebugRngListsTableFragment( |
| 464 | const CompileUnit &Unit, const AddressRanges &LinkedRanges, |
| 465 | PatchLocation Patch) { |
| 466 | Patch.set(RngListsSectionSize); |
| 467 | |
| 468 | // Make .debug_rnglists to be current section. |
| 469 | MS->switchSection(MC->getObjectFileInfo()->getDwarfRnglistsSection()); |
| 470 | |
| 471 | unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize(); |
| 472 | |
| 473 | for (const AddressRange &Range : LinkedRanges) { |
| 474 | // Emit type of entry. |
| 475 | MS->emitInt8(dwarf::DW_RLE_start_length); |
| 476 | RngListsSectionSize += 1; |
| 477 | |
| 478 | // Emit start address. |
| 479 | MS->emitIntValue(Range.start(), AddressSize); |
| 480 | RngListsSectionSize += AddressSize; |
| 481 | |
| 482 | // Emit length of the range. |
| 483 | RngListsSectionSize += MS->emitSLEB128IntValue(Range.end() - Range.start()); |
| 484 | } |
| 485 | |
| 486 | // Emit the terminator entry. |
| 487 | MS->emitInt8(dwarf::DW_RLE_end_of_list); |
| 488 | RngListsSectionSize += 1; |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 489 | } |
| 490 | |
Alexey Lapshin | 70c9be6 | 2023-02-27 17:59:30 +0100 | [diff] [blame] | 491 | /// Emit debug locations(.debug_loc, .debug_loclists) header. |
| 492 | MCSymbol *DwarfStreamer::emitDwarfDebugLocListHeader(const CompileUnit &Unit) { |
| 493 | if (Unit.getOrigUnit().getVersion() < 5) |
| 494 | return nullptr; |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 495 | |
Alexey Lapshin | 70c9be6 | 2023-02-27 17:59:30 +0100 | [diff] [blame] | 496 | // Make .debug_loclists the current section. |
| 497 | MS->switchSection(MC->getObjectFileInfo()->getDwarfLoclistsSection()); |
| 498 | |
| 499 | MCSymbol *BeginLabel = Asm->createTempSymbol("Bloclists"); |
| 500 | MCSymbol *EndLabel = Asm->createTempSymbol("Eloclists"); |
| 501 | unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize(); |
| 502 | |
| 503 | // Length |
| 504 | Asm->emitLabelDifference(EndLabel, BeginLabel, sizeof(uint32_t)); |
| 505 | Asm->OutStreamer->emitLabel(BeginLabel); |
| 506 | LocListsSectionSize += sizeof(uint32_t); |
| 507 | |
| 508 | // Version. |
| 509 | MS->emitInt16(5); |
| 510 | LocListsSectionSize += sizeof(uint16_t); |
| 511 | |
| 512 | // Address size. |
| 513 | MS->emitInt8(AddressSize); |
| 514 | LocListsSectionSize++; |
| 515 | |
| 516 | // Seg_size |
| 517 | MS->emitInt8(0); |
| 518 | LocListsSectionSize++; |
| 519 | |
| 520 | // Offset entry count |
| 521 | MS->emitInt32(0); |
| 522 | LocListsSectionSize += sizeof(uint32_t); |
| 523 | |
| 524 | return EndLabel; |
| 525 | } |
| 526 | |
| 527 | /// Emit debug locations(.debug_loc, .debug_loclists) fragment. |
| 528 | void DwarfStreamer::emitDwarfDebugLocListFragment( |
| 529 | const CompileUnit &Unit, |
| 530 | const DWARFLocationExpressionsVector &LinkedLocationExpression, |
| 531 | PatchLocation Patch) { |
| 532 | if (Unit.getOrigUnit().getVersion() < 5) { |
| 533 | emitDwarfDebugLocTableFragment(Unit, LinkedLocationExpression, Patch); |
| 534 | return; |
| 535 | } |
| 536 | |
| 537 | emitDwarfDebugLocListsTableFragment(Unit, LinkedLocationExpression, Patch); |
| 538 | } |
| 539 | |
| 540 | /// Emit debug locations(.debug_loc, .debug_loclists) footer. |
| 541 | void DwarfStreamer::emitDwarfDebugLocListFooter(const CompileUnit &Unit, |
| 542 | MCSymbol *EndLabel) { |
| 543 | if (Unit.getOrigUnit().getVersion() < 5) |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 544 | return; |
| 545 | |
Alexey Lapshin | 70c9be6 | 2023-02-27 17:59:30 +0100 | [diff] [blame] | 546 | // Make .debug_loclists the current section. |
| 547 | MS->switchSection(MC->getObjectFileInfo()->getDwarfLoclistsSection()); |
| 548 | |
| 549 | if (EndLabel != nullptr) |
| 550 | Asm->OutStreamer->emitLabel(EndLabel); |
| 551 | } |
| 552 | |
| 553 | /// Emit piece of .debug_loc for \p LinkedLocationExpression. |
| 554 | void DwarfStreamer::emitDwarfDebugLocTableFragment( |
| 555 | const CompileUnit &Unit, |
| 556 | const DWARFLocationExpressionsVector &LinkedLocationExpression, |
| 557 | PatchLocation Patch) { |
| 558 | Patch.set(LocSectionSize); |
| 559 | |
| 560 | // Make .debug_loc to be current section. |
Fangrui Song | 5cd8d2a | 2022-06-10 22:50:55 -0700 | [diff] [blame] | 561 | MS->switchSection(MC->getObjectFileInfo()->getDwarfLocSection()); |
Alexey Lapshin | 70c9be6 | 2023-02-27 17:59:30 +0100 | [diff] [blame] | 562 | unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize(); |
| 563 | |
| 564 | // Emit ranges. |
| 565 | uint64_t BaseAddress = 0; |
| 566 | if (std::optional<uint64_t> LowPC = Unit.getLowPc()) |
| 567 | BaseAddress = *LowPC; |
| 568 | |
| 569 | for (const DWARFLocationExpression &LocExpression : |
| 570 | LinkedLocationExpression) { |
| 571 | if (LocExpression.Range) { |
| 572 | MS->emitIntValue(LocExpression.Range->LowPC - BaseAddress, AddressSize); |
| 573 | MS->emitIntValue(LocExpression.Range->HighPC - BaseAddress, AddressSize); |
| 574 | |
| 575 | LocSectionSize += AddressSize; |
| 576 | LocSectionSize += AddressSize; |
| 577 | } |
| 578 | |
| 579 | Asm->OutStreamer->emitIntValue(LocExpression.Expr.size(), 2); |
| 580 | Asm->OutStreamer->emitBytes(StringRef( |
| 581 | (const char *)LocExpression.Expr.data(), LocExpression.Expr.size())); |
| 582 | LocSectionSize += LocExpression.Expr.size() + 2; |
| 583 | } |
| 584 | |
| 585 | // Add the terminator entry. |
| 586 | MS->emitIntValue(0, AddressSize); |
| 587 | MS->emitIntValue(0, AddressSize); |
| 588 | |
| 589 | LocSectionSize += AddressSize; |
| 590 | LocSectionSize += AddressSize; |
| 591 | } |
| 592 | |
| 593 | /// Emit piece of .debug_loclists for \p LinkedLocationExpression. |
| 594 | void DwarfStreamer::emitDwarfDebugLocListsTableFragment( |
| 595 | const CompileUnit &Unit, |
| 596 | const DWARFLocationExpressionsVector &LinkedLocationExpression, |
| 597 | PatchLocation Patch) { |
| 598 | Patch.set(LocListsSectionSize); |
| 599 | |
| 600 | // Make .debug_loclists the current section. |
| 601 | MS->switchSection(MC->getObjectFileInfo()->getDwarfLoclistsSection()); |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 602 | |
| 603 | unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize(); |
Alexey Lapshin | 70c9be6 | 2023-02-27 17:59:30 +0100 | [diff] [blame] | 604 | |
| 605 | for (const DWARFLocationExpression &LocExpression : |
| 606 | LinkedLocationExpression) { |
| 607 | if (LocExpression.Range) { |
| 608 | // Emit type of entry. |
| 609 | MS->emitInt8(dwarf::DW_LLE_start_length); |
| 610 | LocListsSectionSize += 1; |
| 611 | |
| 612 | // Emit start address. |
| 613 | MS->emitIntValue(LocExpression.Range->LowPC, AddressSize); |
| 614 | LocListsSectionSize += AddressSize; |
| 615 | |
| 616 | // Emit length of the range. |
| 617 | LocListsSectionSize += MS->emitSLEB128IntValue( |
| 618 | LocExpression.Range->HighPC - LocExpression.Range->LowPC); |
| 619 | } else { |
| 620 | // Emit type of entry. |
| 621 | MS->emitInt8(dwarf::DW_LLE_default_location); |
| 622 | LocListsSectionSize += 1; |
| 623 | } |
| 624 | |
| 625 | LocListsSectionSize += MS->emitULEB128IntValue(LocExpression.Expr.size()); |
| 626 | Asm->OutStreamer->emitBytes(StringRef( |
| 627 | (const char *)LocExpression.Expr.data(), LocExpression.Expr.size())); |
| 628 | LocListsSectionSize += LocExpression.Expr.size(); |
Alexey Lapshin | eb2dd7ba | 2023-01-20 16:48:13 +0100 | [diff] [blame] | 629 | } |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 630 | |
Alexey Lapshin | 70c9be6 | 2023-02-27 17:59:30 +0100 | [diff] [blame] | 631 | // Emit the terminator entry. |
| 632 | MS->emitInt8(dwarf::DW_LLE_end_of_list); |
| 633 | LocListsSectionSize += 1; |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 634 | } |
| 635 | |
Alexey Lapshin | e1d1493 | 2023-05-11 19:09:47 +0200 | [diff] [blame] | 636 | void DwarfStreamer::emitLineTableForUnit( |
| 637 | const DWARFDebugLine::LineTable &LineTable, const CompileUnit &Unit, |
| 638 | OffsetsStringPool &DebugStrPool, OffsetsStringPool &DebugLineStrPool) { |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 639 | // Switch to the section where the table will be emitted into. |
Fangrui Song | 5cd8d2a | 2022-06-10 22:50:55 -0700 | [diff] [blame] | 640 | MS->switchSection(MC->getObjectFileInfo()->getDwarfLineSection()); |
Alexey Lapshin | e1d1493 | 2023-05-11 19:09:47 +0200 | [diff] [blame] | 641 | |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 642 | MCSymbol *LineStartSym = MC->createTempSymbol(); |
| 643 | MCSymbol *LineEndSym = MC->createTempSymbol(); |
| 644 | |
Alexey Lapshin | e1d1493 | 2023-05-11 19:09:47 +0200 | [diff] [blame] | 645 | // unit_length. |
| 646 | if (LineTable.Prologue.FormParams.Format == dwarf::DwarfFormat::DWARF64) { |
| 647 | MS->emitInt32(dwarf::DW_LENGTH_DWARF64); |
| 648 | LineSectionSize += 4; |
| 649 | } |
| 650 | emitLabelDifference(LineEndSym, LineStartSym, |
| 651 | LineTable.Prologue.FormParams.Format, LineSectionSize); |
Fangrui Song | 3f0f64a | 2020-02-14 19:21:58 -0800 | [diff] [blame] | 652 | Asm->OutStreamer->emitLabel(LineStartSym); |
Alexey Lapshin | e1d1493 | 2023-05-11 19:09:47 +0200 | [diff] [blame] | 653 | |
| 654 | // Emit prologue. |
| 655 | emitLineTablePrologue(LineTable.Prologue, DebugStrPool, DebugLineStrPool); |
| 656 | |
| 657 | // Emit rows. |
| 658 | emitLineTableRows(LineTable, LineEndSym, |
| 659 | Unit.getOrigUnit().getAddressByteSize()); |
| 660 | } |
| 661 | |
| 662 | void DwarfStreamer::emitLineTablePrologue(const DWARFDebugLine::Prologue &P, |
| 663 | OffsetsStringPool &DebugStrPool, |
| 664 | OffsetsStringPool &DebugLineStrPool) { |
| 665 | MCSymbol *PrologueStartSym = MC->createTempSymbol(); |
| 666 | MCSymbol *PrologueEndSym = MC->createTempSymbol(); |
| 667 | |
| 668 | // version (uhalf). |
| 669 | MS->emitInt16(P.getVersion()); |
| 670 | LineSectionSize += 2; |
| 671 | if (P.getVersion() == 5) { |
| 672 | // address_size (ubyte). |
| 673 | MS->emitInt8(P.getAddressSize()); |
| 674 | LineSectionSize += 1; |
| 675 | |
| 676 | // segment_selector_size (ubyte). |
| 677 | MS->emitInt8(P.SegSelectorSize); |
| 678 | LineSectionSize += 1; |
| 679 | } |
| 680 | |
| 681 | // header_length. |
| 682 | emitLabelDifference(PrologueEndSym, PrologueStartSym, P.FormParams.Format, |
| 683 | LineSectionSize); |
| 684 | |
| 685 | Asm->OutStreamer->emitLabel(PrologueStartSym); |
| 686 | emitLineTableProloguePayload(P, DebugStrPool, DebugLineStrPool); |
| 687 | Asm->OutStreamer->emitLabel(PrologueEndSym); |
| 688 | } |
| 689 | |
| 690 | void DwarfStreamer::emitLineTablePrologueV2IncludeAndFileTable( |
| 691 | const DWARFDebugLine::Prologue &P, OffsetsStringPool &DebugStrPool, |
| 692 | OffsetsStringPool &DebugLineStrPool) { |
| 693 | // include_directories (sequence of path names). |
| 694 | for (const DWARFFormValue &Include : P.IncludeDirectories) |
| 695 | emitLineTableString(P, Include, DebugStrPool, DebugLineStrPool); |
| 696 | // The last entry is followed by a single null byte. |
| 697 | MS->emitInt8(0); |
| 698 | LineSectionSize += 1; |
| 699 | |
| 700 | // file_names (sequence of file entries). |
| 701 | for (const DWARFDebugLine::FileNameEntry &File : P.FileNames) { |
| 702 | // A null-terminated string containing the full or relative path name of a |
| 703 | // source file. |
| 704 | emitLineTableString(P, File.Name, DebugStrPool, DebugLineStrPool); |
| 705 | // An unsigned LEB128 number representing the directory index of a directory |
| 706 | // in the include_directories section. |
| 707 | LineSectionSize += MS->emitULEB128IntValue(File.DirIdx); |
| 708 | // An unsigned LEB128 number representing the (implementation-defined) time |
| 709 | // of last modification for the file, or 0 if not available. |
| 710 | LineSectionSize += MS->emitULEB128IntValue(File.ModTime); |
| 711 | // An unsigned LEB128 number representing the length in bytes of the file, |
| 712 | // or 0 if not available. |
| 713 | LineSectionSize += MS->emitULEB128IntValue(File.Length); |
| 714 | } |
| 715 | // The last entry is followed by a single null byte. |
| 716 | MS->emitInt8(0); |
| 717 | LineSectionSize += 1; |
| 718 | } |
| 719 | |
| 720 | void DwarfStreamer::emitLineTablePrologueV5IncludeAndFileTable( |
| 721 | const DWARFDebugLine::Prologue &P, OffsetsStringPool &DebugStrPool, |
| 722 | OffsetsStringPool &DebugLineStrPool) { |
| 723 | if (P.IncludeDirectories.empty()) { |
| 724 | // directory_entry_format_count(ubyte). |
| 725 | MS->emitInt8(0); |
| 726 | LineSectionSize += 1; |
| 727 | } else { |
| 728 | // directory_entry_format_count(ubyte). |
| 729 | MS->emitInt8(1); |
| 730 | LineSectionSize += 1; |
| 731 | |
| 732 | // directory_entry_format (sequence of ULEB128 pairs). |
| 733 | LineSectionSize += MS->emitULEB128IntValue(dwarf::DW_LNCT_path); |
| 734 | LineSectionSize += |
| 735 | MS->emitULEB128IntValue(P.IncludeDirectories[0].getForm()); |
| 736 | } |
| 737 | |
| 738 | // directories_count (ULEB128). |
| 739 | LineSectionSize += MS->emitULEB128IntValue(P.IncludeDirectories.size()); |
| 740 | // directories (sequence of directory names). |
| 741 | for (auto Include : P.IncludeDirectories) |
| 742 | emitLineTableString(P, Include, DebugStrPool, DebugLineStrPool); |
| 743 | |
| 744 | if (P.FileNames.empty()) { |
| 745 | // file_name_entry_format_count (ubyte). |
| 746 | MS->emitInt8(0); |
| 747 | LineSectionSize += 1; |
| 748 | } else { |
| 749 | // file_name_entry_format_count (ubyte). |
| 750 | MS->emitInt8(2); |
| 751 | LineSectionSize += 1; |
| 752 | |
| 753 | // file_name_entry_format (sequence of ULEB128 pairs). |
| 754 | LineSectionSize += MS->emitULEB128IntValue(dwarf::DW_LNCT_path); |
| 755 | LineSectionSize += MS->emitULEB128IntValue(P.FileNames[0].Name.getForm()); |
| 756 | |
| 757 | LineSectionSize += MS->emitULEB128IntValue(dwarf::DW_LNCT_directory_index); |
| 758 | LineSectionSize += MS->emitULEB128IntValue(dwarf::DW_FORM_data1); |
| 759 | } |
| 760 | |
| 761 | // file_names_count (ULEB128). |
| 762 | LineSectionSize += MS->emitULEB128IntValue(P.FileNames.size()); |
| 763 | |
| 764 | // file_names (sequence of file name entries). |
| 765 | for (auto File : P.FileNames) { |
| 766 | emitLineTableString(P, File.Name, DebugStrPool, DebugLineStrPool); |
| 767 | MS->emitInt8(File.DirIdx); |
| 768 | LineSectionSize += 1; |
| 769 | } |
| 770 | } |
| 771 | |
| 772 | void DwarfStreamer::emitLineTableString(const DWARFDebugLine::Prologue &P, |
| 773 | const DWARFFormValue &String, |
| 774 | OffsetsStringPool &DebugStrPool, |
| 775 | OffsetsStringPool &DebugLineStrPool) { |
| 776 | std::optional<const char *> StringVal = dwarf::toString(String); |
| 777 | if (!StringVal) { |
| 778 | warn("Cann't read string from line table."); |
| 779 | return; |
| 780 | } |
| 781 | |
| 782 | switch (String.getForm()) { |
| 783 | case dwarf::DW_FORM_string: { |
| 784 | StringRef TranslatedString = |
| 785 | (Translator) ? Translator(*StringVal) : *StringVal; |
| 786 | Asm->OutStreamer->emitBytes(TranslatedString.data()); |
| 787 | Asm->emitInt8(0); |
| 788 | LineSectionSize += TranslatedString.size() + 1; |
| 789 | } break; |
| 790 | case dwarf::DW_FORM_strp: |
| 791 | case dwarf::DW_FORM_line_strp: { |
| 792 | DwarfStringPoolEntryRef StringRef = |
| 793 | String.getForm() == dwarf::DW_FORM_strp |
| 794 | ? DebugStrPool.getEntry(*StringVal) |
| 795 | : DebugLineStrPool.getEntry(*StringVal); |
| 796 | |
| 797 | emitIntOffset(StringRef.getOffset(), P.FormParams.Format, LineSectionSize); |
| 798 | } break; |
| 799 | default: |
| 800 | warn("Unsupported string form inside line table."); |
| 801 | break; |
| 802 | }; |
| 803 | } |
| 804 | |
| 805 | void DwarfStreamer::emitLineTableProloguePayload( |
| 806 | const DWARFDebugLine::Prologue &P, OffsetsStringPool &DebugStrPool, |
| 807 | OffsetsStringPool &DebugLineStrPool) { |
| 808 | // minimum_instruction_length (ubyte). |
| 809 | MS->emitInt8(P.MinInstLength); |
| 810 | LineSectionSize += 1; |
| 811 | if (P.FormParams.Version >= 4) { |
| 812 | // maximum_operations_per_instruction (ubyte). |
| 813 | MS->emitInt8(P.MaxOpsPerInst); |
| 814 | LineSectionSize += 1; |
| 815 | } |
| 816 | // default_is_stmt (ubyte). |
| 817 | MS->emitInt8(P.DefaultIsStmt); |
| 818 | LineSectionSize += 1; |
| 819 | // line_base (sbyte). |
| 820 | MS->emitInt8(P.LineBase); |
| 821 | LineSectionSize += 1; |
| 822 | // line_range (ubyte). |
| 823 | MS->emitInt8(P.LineRange); |
| 824 | LineSectionSize += 1; |
| 825 | // opcode_base (ubyte). |
| 826 | MS->emitInt8(P.OpcodeBase); |
| 827 | LineSectionSize += 1; |
| 828 | |
| 829 | // standard_opcode_lengths (array of ubyte). |
| 830 | for (auto Length : P.StandardOpcodeLengths) { |
| 831 | MS->emitInt8(Length); |
| 832 | LineSectionSize += 1; |
| 833 | } |
| 834 | |
| 835 | if (P.FormParams.Version < 5) |
| 836 | emitLineTablePrologueV2IncludeAndFileTable(P, DebugStrPool, |
| 837 | DebugLineStrPool); |
| 838 | else |
| 839 | emitLineTablePrologueV5IncludeAndFileTable(P, DebugStrPool, |
| 840 | DebugLineStrPool); |
| 841 | } |
| 842 | |
| 843 | void DwarfStreamer::emitLineTableRows( |
| 844 | const DWARFDebugLine::LineTable &LineTable, MCSymbol *LineEndSym, |
| 845 | unsigned AddressByteSize) { |
| 846 | |
| 847 | MCDwarfLineTableParams Params; |
| 848 | Params.DWARF2LineOpcodeBase = LineTable.Prologue.OpcodeBase; |
| 849 | Params.DWARF2LineBase = LineTable.Prologue.LineBase; |
| 850 | Params.DWARF2LineRange = LineTable.Prologue.LineRange; |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 851 | |
| 852 | SmallString<128> EncodingBuffer; |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 853 | |
Alexey Lapshin | e1d1493 | 2023-05-11 19:09:47 +0200 | [diff] [blame] | 854 | if (LineTable.Rows.empty()) { |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 855 | // We only have the dummy entry, dsymutil emits an entry with a 0 |
| 856 | // address in that case. |
Fangrui Song | 62edcc6 | 2023-05-07 16:26:52 -0700 | [diff] [blame] | 857 | MCDwarfLineAddr::encode(*MC, Params, std::numeric_limits<int64_t>::max(), 0, |
| 858 | EncodingBuffer); |
| 859 | MS->emitBytes(EncodingBuffer); |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 860 | LineSectionSize += EncodingBuffer.size(); |
Fangrui Song | 3f0f64a | 2020-02-14 19:21:58 -0800 | [diff] [blame] | 861 | MS->emitLabel(LineEndSym); |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 862 | return; |
| 863 | } |
| 864 | |
| 865 | // Line table state machine fields |
| 866 | unsigned FileNum = 1; |
| 867 | unsigned LastLine = 1; |
| 868 | unsigned Column = 0; |
| 869 | unsigned IsStatement = 1; |
| 870 | unsigned Isa = 0; |
| 871 | uint64_t Address = -1ULL; |
| 872 | |
| 873 | unsigned RowsSinceLastSequence = 0; |
| 874 | |
Alexey Lapshin | e1d1493 | 2023-05-11 19:09:47 +0200 | [diff] [blame] | 875 | for (const DWARFDebugLine::Row &Row : LineTable.Rows) { |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 876 | int64_t AddressDelta; |
| 877 | if (Address == -1ULL) { |
Fangrui Song | 9c6c616 | 2020-02-14 22:40:47 -0800 | [diff] [blame] | 878 | MS->emitIntValue(dwarf::DW_LNS_extended_op, 1); |
Alexey Lapshin | e1d1493 | 2023-05-11 19:09:47 +0200 | [diff] [blame] | 879 | MS->emitULEB128IntValue(AddressByteSize + 1); |
Fangrui Song | 9c6c616 | 2020-02-14 22:40:47 -0800 | [diff] [blame] | 880 | MS->emitIntValue(dwarf::DW_LNE_set_address, 1); |
Alexey Lapshin | e1d1493 | 2023-05-11 19:09:47 +0200 | [diff] [blame] | 881 | MS->emitIntValue(Row.Address.Address, AddressByteSize); |
| 882 | LineSectionSize += |
| 883 | 2 + AddressByteSize + getULEB128Size(AddressByteSize + 1); |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 884 | AddressDelta = 0; |
| 885 | } else { |
Alexey Lapshin | e1d1493 | 2023-05-11 19:09:47 +0200 | [diff] [blame] | 886 | AddressDelta = |
| 887 | (Row.Address.Address - Address) / LineTable.Prologue.MinInstLength; |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 888 | } |
| 889 | |
| 890 | // FIXME: code copied and transformed from MCDwarf.cpp::EmitDwarfLineTable. |
| 891 | // We should find a way to share this code, but the current compatibility |
| 892 | // requirement with classic dsymutil makes it hard. Revisit that once this |
| 893 | // requirement is dropped. |
| 894 | |
| 895 | if (FileNum != Row.File) { |
| 896 | FileNum = Row.File; |
Fangrui Song | 9c6c616 | 2020-02-14 22:40:47 -0800 | [diff] [blame] | 897 | MS->emitIntValue(dwarf::DW_LNS_set_file, 1); |
Fangrui Song | 962b960 | 2020-02-13 13:26:21 -0800 | [diff] [blame] | 898 | MS->emitULEB128IntValue(FileNum); |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 899 | LineSectionSize += 1 + getULEB128Size(FileNum); |
| 900 | } |
| 901 | if (Column != Row.Column) { |
| 902 | Column = Row.Column; |
Fangrui Song | 9c6c616 | 2020-02-14 22:40:47 -0800 | [diff] [blame] | 903 | MS->emitIntValue(dwarf::DW_LNS_set_column, 1); |
Fangrui Song | 962b960 | 2020-02-13 13:26:21 -0800 | [diff] [blame] | 904 | MS->emitULEB128IntValue(Column); |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 905 | LineSectionSize += 1 + getULEB128Size(Column); |
| 906 | } |
| 907 | |
| 908 | // FIXME: We should handle the discriminator here, but dsymutil doesn't |
| 909 | // consider it, thus ignore it for now. |
| 910 | |
| 911 | if (Isa != Row.Isa) { |
| 912 | Isa = Row.Isa; |
Fangrui Song | 9c6c616 | 2020-02-14 22:40:47 -0800 | [diff] [blame] | 913 | MS->emitIntValue(dwarf::DW_LNS_set_isa, 1); |
Fangrui Song | 962b960 | 2020-02-13 13:26:21 -0800 | [diff] [blame] | 914 | MS->emitULEB128IntValue(Isa); |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 915 | LineSectionSize += 1 + getULEB128Size(Isa); |
| 916 | } |
| 917 | if (IsStatement != Row.IsStmt) { |
| 918 | IsStatement = Row.IsStmt; |
Fangrui Song | 9c6c616 | 2020-02-14 22:40:47 -0800 | [diff] [blame] | 919 | MS->emitIntValue(dwarf::DW_LNS_negate_stmt, 1); |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 920 | LineSectionSize += 1; |
| 921 | } |
| 922 | if (Row.BasicBlock) { |
Fangrui Song | 9c6c616 | 2020-02-14 22:40:47 -0800 | [diff] [blame] | 923 | MS->emitIntValue(dwarf::DW_LNS_set_basic_block, 1); |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 924 | LineSectionSize += 1; |
| 925 | } |
| 926 | |
| 927 | if (Row.PrologueEnd) { |
Fangrui Song | 9c6c616 | 2020-02-14 22:40:47 -0800 | [diff] [blame] | 928 | MS->emitIntValue(dwarf::DW_LNS_set_prologue_end, 1); |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 929 | LineSectionSize += 1; |
| 930 | } |
| 931 | |
| 932 | if (Row.EpilogueBegin) { |
Fangrui Song | 9c6c616 | 2020-02-14 22:40:47 -0800 | [diff] [blame] | 933 | MS->emitIntValue(dwarf::DW_LNS_set_epilogue_begin, 1); |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 934 | LineSectionSize += 1; |
| 935 | } |
| 936 | |
| 937 | int64_t LineDelta = int64_t(Row.Line) - LastLine; |
| 938 | if (!Row.EndSequence) { |
Alexey Lapshin | e1d1493 | 2023-05-11 19:09:47 +0200 | [diff] [blame] | 939 | MCDwarfLineAddr::encode(*MC, Params, LineDelta, AddressDelta, |
| 940 | EncodingBuffer); |
Fangrui Song | 62edcc6 | 2023-05-07 16:26:52 -0700 | [diff] [blame] | 941 | MS->emitBytes(EncodingBuffer); |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 942 | LineSectionSize += EncodingBuffer.size(); |
| 943 | EncodingBuffer.resize(0); |
Alexey Lapshin | eeb854d | 2019-02-27 13:17:36 +0000 | [diff] [blame] | 944 | Address = Row.Address.Address; |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 945 | LastLine = Row.Line; |
| 946 | RowsSinceLastSequence++; |
| 947 | } else { |
| 948 | if (LineDelta) { |
Fangrui Song | 9c6c616 | 2020-02-14 22:40:47 -0800 | [diff] [blame] | 949 | MS->emitIntValue(dwarf::DW_LNS_advance_line, 1); |
Fangrui Song | 962b960 | 2020-02-13 13:26:21 -0800 | [diff] [blame] | 950 | MS->emitSLEB128IntValue(LineDelta); |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 951 | LineSectionSize += 1 + getSLEB128Size(LineDelta); |
| 952 | } |
| 953 | if (AddressDelta) { |
Fangrui Song | 9c6c616 | 2020-02-14 22:40:47 -0800 | [diff] [blame] | 954 | MS->emitIntValue(dwarf::DW_LNS_advance_pc, 1); |
Fangrui Song | 962b960 | 2020-02-13 13:26:21 -0800 | [diff] [blame] | 955 | MS->emitULEB128IntValue(AddressDelta); |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 956 | LineSectionSize += 1 + getULEB128Size(AddressDelta); |
| 957 | } |
Fangrui Song | 62edcc6 | 2023-05-07 16:26:52 -0700 | [diff] [blame] | 958 | MCDwarfLineAddr::encode(*MC, Params, std::numeric_limits<int64_t>::max(), |
| 959 | 0, EncodingBuffer); |
| 960 | MS->emitBytes(EncodingBuffer); |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 961 | LineSectionSize += EncodingBuffer.size(); |
| 962 | EncodingBuffer.resize(0); |
| 963 | Address = -1ULL; |
| 964 | LastLine = FileNum = IsStatement = 1; |
| 965 | RowsSinceLastSequence = Column = Isa = 0; |
| 966 | } |
| 967 | } |
| 968 | |
| 969 | if (RowsSinceLastSequence) { |
Fangrui Song | 62edcc6 | 2023-05-07 16:26:52 -0700 | [diff] [blame] | 970 | MCDwarfLineAddr::encode(*MC, Params, std::numeric_limits<int64_t>::max(), 0, |
| 971 | EncodingBuffer); |
| 972 | MS->emitBytes(EncodingBuffer); |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 973 | LineSectionSize += EncodingBuffer.size(); |
| 974 | EncodingBuffer.resize(0); |
| 975 | } |
| 976 | |
Fangrui Song | 3f0f64a | 2020-02-14 19:21:58 -0800 | [diff] [blame] | 977 | MS->emitLabel(LineEndSym); |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 978 | } |
| 979 | |
Alexey Lapshin | e1d1493 | 2023-05-11 19:09:47 +0200 | [diff] [blame] | 980 | void DwarfStreamer::emitIntOffset(uint64_t Offset, dwarf::DwarfFormat Format, |
| 981 | uint64_t &SectionSize) { |
| 982 | uint8_t Size = dwarf::getDwarfOffsetByteSize(Format); |
| 983 | MS->emitIntValue(Offset, Size); |
| 984 | SectionSize += Size; |
| 985 | } |
Jonas Devlieghere | cebf42d | 2019-01-07 23:27:25 +0000 | [diff] [blame] | 986 | |
Alexey Lapshin | e1d1493 | 2023-05-11 19:09:47 +0200 | [diff] [blame] | 987 | void DwarfStreamer::emitLabelDifference(const MCSymbol *Hi, const MCSymbol *Lo, |
| 988 | dwarf::DwarfFormat Format, |
| 989 | uint64_t &SectionSize) { |
| 990 | uint8_t Size = dwarf::getDwarfOffsetByteSize(Format); |
| 991 | Asm->emitLabelDifference(Hi, Lo, Size); |
| 992 | SectionSize += Size; |
Jonas Devlieghere | cebf42d | 2019-01-07 23:27:25 +0000 | [diff] [blame] | 993 | } |
| 994 | |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 995 | /// Emit the pubnames or pubtypes section contribution for \p |
| 996 | /// Unit into \p Sec. The data is provided in \p Names. |
| 997 | void DwarfStreamer::emitPubSectionForUnit( |
| 998 | MCSection *Sec, StringRef SecName, const CompileUnit &Unit, |
| 999 | const std::vector<CompileUnit::AccelInfo> &Names) { |
| 1000 | if (Names.empty()) |
| 1001 | return; |
| 1002 | |
| 1003 | // Start the dwarf pubnames section. |
Fangrui Song | 5cd8d2a | 2022-06-10 22:50:55 -0700 | [diff] [blame] | 1004 | Asm->OutStreamer->switchSection(Sec); |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 1005 | MCSymbol *BeginLabel = Asm->createTempSymbol("pub" + SecName + "_begin"); |
| 1006 | MCSymbol *EndLabel = Asm->createTempSymbol("pub" + SecName + "_end"); |
| 1007 | |
| 1008 | bool HeaderEmitted = false; |
| 1009 | // Emit the pubnames for this compilation unit. |
| 1010 | for (const auto &Name : Names) { |
| 1011 | if (Name.SkipPubSection) |
| 1012 | continue; |
| 1013 | |
| 1014 | if (!HeaderEmitted) { |
| 1015 | // Emit the header. |
Fangrui Song | 962b960 | 2020-02-13 13:26:21 -0800 | [diff] [blame] | 1016 | Asm->emitLabelDifference(EndLabel, BeginLabel, 4); // Length |
Fangrui Song | 3f0f64a | 2020-02-14 19:21:58 -0800 | [diff] [blame] | 1017 | Asm->OutStreamer->emitLabel(BeginLabel); |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 1018 | Asm->emitInt16(dwarf::DW_PUBNAMES_VERSION); // Version |
| 1019 | Asm->emitInt32(Unit.getStartOffset()); // Unit offset |
| 1020 | Asm->emitInt32(Unit.getNextUnitOffset() - Unit.getStartOffset()); // Size |
| 1021 | HeaderEmitted = true; |
| 1022 | } |
| 1023 | Asm->emitInt32(Name.Die->getOffset()); |
| 1024 | |
| 1025 | // Emit the string itself. |
Fangrui Song | 297d076 | 2020-02-14 18:16:24 -0800 | [diff] [blame] | 1026 | Asm->OutStreamer->emitBytes(Name.Name.getString()); |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 1027 | // Emit a null terminator. |
| 1028 | Asm->emitInt8(0); |
| 1029 | } |
| 1030 | |
| 1031 | if (!HeaderEmitted) |
| 1032 | return; |
| 1033 | Asm->emitInt32(0); // End marker. |
Fangrui Song | 3f0f64a | 2020-02-14 19:21:58 -0800 | [diff] [blame] | 1034 | Asm->OutStreamer->emitLabel(EndLabel); |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 1035 | } |
| 1036 | |
| 1037 | /// Emit .debug_pubnames for \p Unit. |
| 1038 | void DwarfStreamer::emitPubNamesForUnit(const CompileUnit &Unit) { |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 1039 | emitPubSectionForUnit(MC->getObjectFileInfo()->getDwarfPubNamesSection(), |
| 1040 | "names", Unit, Unit.getPubnames()); |
| 1041 | } |
| 1042 | |
| 1043 | /// Emit .debug_pubtypes for \p Unit. |
| 1044 | void DwarfStreamer::emitPubTypesForUnit(const CompileUnit &Unit) { |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 1045 | emitPubSectionForUnit(MC->getObjectFileInfo()->getDwarfPubTypesSection(), |
| 1046 | "types", Unit, Unit.getPubtypes()); |
| 1047 | } |
| 1048 | |
| 1049 | /// Emit a CIE into the debug_frame section. |
| 1050 | void DwarfStreamer::emitCIE(StringRef CIEBytes) { |
Fangrui Song | 5cd8d2a | 2022-06-10 22:50:55 -0700 | [diff] [blame] | 1051 | MS->switchSection(MC->getObjectFileInfo()->getDwarfFrameSection()); |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 1052 | |
Fangrui Song | 297d076 | 2020-02-14 18:16:24 -0800 | [diff] [blame] | 1053 | MS->emitBytes(CIEBytes); |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 1054 | FrameSectionSize += CIEBytes.size(); |
| 1055 | } |
| 1056 | |
| 1057 | /// Emit a FDE into the debug_frame section. \p FDEBytes |
| 1058 | /// contains the FDE data without the length, CIE offset and address |
| 1059 | /// which will be replaced with the parameter values. |
| 1060 | void DwarfStreamer::emitFDE(uint32_t CIEOffset, uint32_t AddrSize, |
Alessandro Arzilli | 3ceb59b | 2022-12-17 13:22:05 +0100 | [diff] [blame] | 1061 | uint64_t Address, StringRef FDEBytes) { |
Fangrui Song | 5cd8d2a | 2022-06-10 22:50:55 -0700 | [diff] [blame] | 1062 | MS->switchSection(MC->getObjectFileInfo()->getDwarfFrameSection()); |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 1063 | |
Fangrui Song | 9c6c616 | 2020-02-14 22:40:47 -0800 | [diff] [blame] | 1064 | MS->emitIntValue(FDEBytes.size() + 4 + AddrSize, 4); |
| 1065 | MS->emitIntValue(CIEOffset, 4); |
| 1066 | MS->emitIntValue(Address, AddrSize); |
Fangrui Song | 297d076 | 2020-02-14 18:16:24 -0800 | [diff] [blame] | 1067 | MS->emitBytes(FDEBytes); |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 1068 | FrameSectionSize += FDEBytes.size() + 8 + AddrSize; |
| 1069 | } |
| 1070 | |
Alexey Lapshin | 8a11d4e | 2022-09-23 09:34:26 +0300 | [diff] [blame] | 1071 | void DwarfStreamer::emitMacroTables(DWARFContext *Context, |
| 1072 | const Offset2UnitMap &UnitMacroMap, |
| 1073 | OffsetsStringPool &StringPool) { |
| 1074 | assert(Context != nullptr && "Empty DWARF context"); |
| 1075 | |
| 1076 | // Check for .debug_macinfo table. |
| 1077 | if (const DWARFDebugMacro *Table = Context->getDebugMacinfo()) { |
| 1078 | MS->switchSection(MC->getObjectFileInfo()->getDwarfMacinfoSection()); |
| 1079 | emitMacroTableImpl(Table, UnitMacroMap, StringPool, MacInfoSectionSize); |
| 1080 | } |
| 1081 | |
| 1082 | // Check for .debug_macro table. |
| 1083 | if (const DWARFDebugMacro *Table = Context->getDebugMacro()) { |
| 1084 | MS->switchSection(MC->getObjectFileInfo()->getDwarfMacroSection()); |
| 1085 | emitMacroTableImpl(Table, UnitMacroMap, StringPool, MacroSectionSize); |
| 1086 | } |
| 1087 | } |
| 1088 | |
| 1089 | void DwarfStreamer::emitMacroTableImpl(const DWARFDebugMacro *MacroTable, |
| 1090 | const Offset2UnitMap &UnitMacroMap, |
| 1091 | OffsetsStringPool &StringPool, |
| 1092 | uint64_t &OutOffset) { |
| 1093 | bool DefAttributeIsReported = false; |
| 1094 | bool UndefAttributeIsReported = false; |
| 1095 | bool ImportAttributeIsReported = false; |
| 1096 | for (const DWARFDebugMacro::MacroList &List : MacroTable->MacroLists) { |
| 1097 | Offset2UnitMap::const_iterator UnitIt = UnitMacroMap.find(List.Offset); |
| 1098 | if (UnitIt == UnitMacroMap.end()) { |
| 1099 | warn(formatv( |
| 1100 | "couldn`t find compile unit for the macro table with offset = {0:x}", |
| 1101 | List.Offset)); |
| 1102 | continue; |
| 1103 | } |
| 1104 | |
| 1105 | // Skip macro table if the unit was not cloned. |
| 1106 | DIE *OutputUnitDIE = UnitIt->second->getOutputUnitDIE(); |
| 1107 | if (OutputUnitDIE == nullptr) |
| 1108 | continue; |
| 1109 | |
| 1110 | // Update macro attribute of cloned compile unit with the proper offset to |
| 1111 | // the macro table. |
| 1112 | bool hasDWARFv5Header = false; |
| 1113 | for (auto &V : OutputUnitDIE->values()) { |
| 1114 | if (V.getAttribute() == dwarf::DW_AT_macro_info) { |
| 1115 | V = DIEValue(V.getAttribute(), V.getForm(), DIEInteger(OutOffset)); |
| 1116 | break; |
| 1117 | } else if (V.getAttribute() == dwarf::DW_AT_macros) { |
| 1118 | hasDWARFv5Header = true; |
| 1119 | V = DIEValue(V.getAttribute(), V.getForm(), DIEInteger(OutOffset)); |
| 1120 | break; |
| 1121 | } |
| 1122 | } |
| 1123 | |
| 1124 | // Write DWARFv5 header. |
| 1125 | if (hasDWARFv5Header) { |
| 1126 | // Write header version. |
| 1127 | MS->emitIntValue(List.Header.Version, sizeof(List.Header.Version)); |
| 1128 | OutOffset += sizeof(List.Header.Version); |
| 1129 | |
| 1130 | uint8_t Flags = List.Header.Flags; |
| 1131 | |
| 1132 | // Check for OPCODE_OPERANDS_TABLE. |
| 1133 | if (Flags & |
| 1134 | DWARFDebugMacro::HeaderFlagMask::MACRO_OPCODE_OPERANDS_TABLE) { |
| 1135 | Flags &= ~DWARFDebugMacro::HeaderFlagMask::MACRO_OPCODE_OPERANDS_TABLE; |
| 1136 | warn("opcode_operands_table is not supported yet."); |
| 1137 | } |
| 1138 | |
| 1139 | // Check for DEBUG_LINE_OFFSET. |
| 1140 | std::optional<uint64_t> StmtListOffset; |
| 1141 | if (Flags & DWARFDebugMacro::HeaderFlagMask::MACRO_DEBUG_LINE_OFFSET) { |
| 1142 | // Get offset to the line table from the cloned compile unit. |
| 1143 | for (auto &V : OutputUnitDIE->values()) { |
| 1144 | if (V.getAttribute() == dwarf::DW_AT_stmt_list) { |
| 1145 | StmtListOffset = V.getDIEInteger().getValue(); |
| 1146 | break; |
| 1147 | } |
| 1148 | } |
| 1149 | |
| 1150 | if (!StmtListOffset) { |
| 1151 | Flags &= ~DWARFDebugMacro::HeaderFlagMask::MACRO_DEBUG_LINE_OFFSET; |
| 1152 | warn("couldn`t find line table for macro table."); |
| 1153 | } |
| 1154 | } |
| 1155 | |
| 1156 | // Write flags. |
| 1157 | MS->emitIntValue(Flags, sizeof(Flags)); |
| 1158 | OutOffset += sizeof(Flags); |
| 1159 | |
| 1160 | // Write offset to line table. |
| 1161 | if (StmtListOffset) { |
| 1162 | MS->emitIntValue(*StmtListOffset, List.Header.getOffsetByteSize()); |
| 1163 | OutOffset += List.Header.getOffsetByteSize(); |
| 1164 | } |
| 1165 | } |
| 1166 | |
| 1167 | // Write macro entries. |
| 1168 | for (const DWARFDebugMacro::Entry &MacroEntry : List.Macros) { |
| 1169 | if (MacroEntry.Type == 0) { |
| 1170 | OutOffset += MS->emitULEB128IntValue(MacroEntry.Type); |
| 1171 | continue; |
| 1172 | } |
| 1173 | |
| 1174 | uint8_t MacroType = MacroEntry.Type; |
| 1175 | switch (MacroType) { |
| 1176 | default: { |
| 1177 | bool HasVendorSpecificExtension = |
| 1178 | (!hasDWARFv5Header && MacroType == dwarf::DW_MACINFO_vendor_ext) || |
| 1179 | (hasDWARFv5Header && (MacroType >= dwarf::DW_MACRO_lo_user && |
| 1180 | MacroType <= dwarf::DW_MACRO_hi_user)); |
| 1181 | |
| 1182 | if (HasVendorSpecificExtension) { |
| 1183 | // Write macinfo type. |
| 1184 | MS->emitIntValue(MacroType, 1); |
| 1185 | OutOffset++; |
| 1186 | |
| 1187 | // Write vendor extension constant. |
| 1188 | OutOffset += MS->emitULEB128IntValue(MacroEntry.ExtConstant); |
| 1189 | |
| 1190 | // Write vendor extension string. |
| 1191 | StringRef String = MacroEntry.ExtStr; |
| 1192 | MS->emitBytes(String); |
| 1193 | MS->emitIntValue(0, 1); |
| 1194 | OutOffset += String.size() + 1; |
| 1195 | } else |
| 1196 | warn("unknown macro type. skip."); |
| 1197 | } break; |
| 1198 | // debug_macro and debug_macinfo share some common encodings. |
| 1199 | // DW_MACRO_define == DW_MACINFO_define |
| 1200 | // DW_MACRO_undef == DW_MACINFO_undef |
| 1201 | // DW_MACRO_start_file == DW_MACINFO_start_file |
| 1202 | // DW_MACRO_end_file == DW_MACINFO_end_file |
| 1203 | // For readibility/uniformity we are using DW_MACRO_*. |
| 1204 | case dwarf::DW_MACRO_define: |
| 1205 | case dwarf::DW_MACRO_undef: { |
| 1206 | // Write macinfo type. |
| 1207 | MS->emitIntValue(MacroType, 1); |
| 1208 | OutOffset++; |
| 1209 | |
| 1210 | // Write source line. |
| 1211 | OutOffset += MS->emitULEB128IntValue(MacroEntry.Line); |
| 1212 | |
| 1213 | // Write macro string. |
| 1214 | StringRef String = MacroEntry.MacroStr; |
| 1215 | MS->emitBytes(String); |
| 1216 | MS->emitIntValue(0, 1); |
| 1217 | OutOffset += String.size() + 1; |
| 1218 | } break; |
| 1219 | case dwarf::DW_MACRO_define_strp: |
| 1220 | case dwarf::DW_MACRO_undef_strp: |
| 1221 | case dwarf::DW_MACRO_define_strx: |
| 1222 | case dwarf::DW_MACRO_undef_strx: { |
| 1223 | assert(UnitIt->second->getOrigUnit().getVersion() >= 5); |
| 1224 | |
| 1225 | // DW_MACRO_*_strx forms are not supported currently. |
| 1226 | // Convert to *_strp. |
| 1227 | switch (MacroType) { |
| 1228 | case dwarf::DW_MACRO_define_strx: { |
| 1229 | MacroType = dwarf::DW_MACRO_define_strp; |
| 1230 | if (!DefAttributeIsReported) { |
| 1231 | warn("DW_MACRO_define_strx unsupported yet. Convert to " |
| 1232 | "DW_MACRO_define_strp."); |
| 1233 | DefAttributeIsReported = true; |
| 1234 | } |
| 1235 | } break; |
| 1236 | case dwarf::DW_MACRO_undef_strx: { |
| 1237 | MacroType = dwarf::DW_MACRO_undef_strp; |
| 1238 | if (!UndefAttributeIsReported) { |
| 1239 | warn("DW_MACRO_undef_strx unsupported yet. Convert to " |
| 1240 | "DW_MACRO_undef_strp."); |
| 1241 | UndefAttributeIsReported = true; |
| 1242 | } |
| 1243 | } break; |
| 1244 | default: |
| 1245 | // Nothing to do. |
| 1246 | break; |
| 1247 | } |
| 1248 | |
| 1249 | // Write macinfo type. |
| 1250 | MS->emitIntValue(MacroType, 1); |
| 1251 | OutOffset++; |
| 1252 | |
| 1253 | // Write source line. |
| 1254 | OutOffset += MS->emitULEB128IntValue(MacroEntry.Line); |
| 1255 | |
| 1256 | // Write macro string. |
| 1257 | DwarfStringPoolEntryRef EntryRef = |
| 1258 | StringPool.getEntry(MacroEntry.MacroStr); |
| 1259 | MS->emitIntValue(EntryRef.getOffset(), List.Header.getOffsetByteSize()); |
| 1260 | OutOffset += List.Header.getOffsetByteSize(); |
| 1261 | break; |
| 1262 | } |
| 1263 | case dwarf::DW_MACRO_start_file: { |
| 1264 | // Write macinfo type. |
| 1265 | MS->emitIntValue(MacroType, 1); |
| 1266 | OutOffset++; |
| 1267 | // Write source line. |
| 1268 | OutOffset += MS->emitULEB128IntValue(MacroEntry.Line); |
| 1269 | // Write source file id. |
| 1270 | OutOffset += MS->emitULEB128IntValue(MacroEntry.File); |
| 1271 | } break; |
| 1272 | case dwarf::DW_MACRO_end_file: { |
| 1273 | // Write macinfo type. |
| 1274 | MS->emitIntValue(MacroType, 1); |
| 1275 | OutOffset++; |
| 1276 | } break; |
| 1277 | case dwarf::DW_MACRO_import: |
| 1278 | case dwarf::DW_MACRO_import_sup: { |
| 1279 | if (!ImportAttributeIsReported) { |
| 1280 | warn("DW_MACRO_import and DW_MACRO_import_sup are unsupported yet. " |
| 1281 | "remove."); |
| 1282 | ImportAttributeIsReported = true; |
| 1283 | } |
| 1284 | } break; |
| 1285 | } |
| 1286 | } |
| 1287 | } |
| 1288 | } |
| 1289 | |
Jonas Devlieghere | b4b2f07 | 2018-06-27 16:13:40 +0000 | [diff] [blame] | 1290 | } // namespace llvm |