Skip to content

Commit 0b9ab84

Browse files
author
Alex B
committed
[MC] Add .loc_label instruction
1 parent f56cdd4 commit 0b9ab84

File tree

7 files changed

+148
-4
lines changed

7 files changed

+148
-4
lines changed

llvm/include/llvm/MC/MCDwarf.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,11 +194,17 @@ class MCDwarfLineEntry : public MCDwarfLoc {
194194

195195
public:
196196
// Constructor to create an MCDwarfLineEntry given a symbol and the dwarf loc.
197-
MCDwarfLineEntry(MCSymbol *label, const MCDwarfLoc loc)
198-
: MCDwarfLoc(loc), Label(label) {}
197+
MCDwarfLineEntry(MCSymbol *label, const MCDwarfLoc loc,
198+
MCSymbol *lineStreamLabel = nullptr)
199+
: MCDwarfLoc(loc), Label(label), LineStreamLabel(lineStreamLabel) {}
199200

200201
MCSymbol *getLabel() const { return Label; }
201202

203+
// This is the label that is to be emmited into the line stream. If this is
204+
// non-null and we need to emit a label, also make sure to restart the current
205+
// line sequence.
206+
MCSymbol *LineStreamLabel;
207+
202208
// This indicates the line entry is synthesized for an end entry.
203209
bool IsEndEntry = false;
204210

llvm/include/llvm/MC/MCStreamer.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -912,6 +912,9 @@ class MCStreamer {
912912
unsigned Isa, unsigned Discriminator,
913913
StringRef FileName);
914914

915+
/// This implements the '.loc_label Name' directive.
916+
virtual void emitDwarfLocLabelDirective(SMLoc Loc, StringRef Name);
917+
915918
/// Associate a filename with a specified logical file number, and also
916919
/// specify that file's checksum information. This implements the '.cv_file 4
917920
/// "foo.c"' assembler directive. Returns true on success.

llvm/lib/MC/MCAsmStreamer.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,8 @@ class MCAsmStreamer final : public MCStreamer {
285285
unsigned Flags, unsigned Isa,
286286
unsigned Discriminator,
287287
StringRef FileName) override;
288+
virtual void emitDwarfLocLabelDirective(SMLoc Loc, StringRef Name) override;
289+
288290
MCSymbol *getDwarfLineTableSymbol(unsigned CUID) override;
289291

290292
bool emitCVFileDirective(unsigned FileNo, StringRef Filename,
@@ -1751,6 +1753,12 @@ void MCAsmStreamer::emitDwarfLocDirective(unsigned FileNo, unsigned Line,
17511753
Discriminator, FileName);
17521754
}
17531755

1756+
void MCAsmStreamer::emitDwarfLocLabelDirective(SMLoc Loc, StringRef Name) {
1757+
MCStreamer::emitDwarfLocLabelDirective(Loc, Name);
1758+
OS << "\t.loc_label " << Name;
1759+
EmitEOL();
1760+
}
1761+
17541762
MCSymbol *MCAsmStreamer::getDwarfLineTableSymbol(unsigned CUID) {
17551763
// Always use the zeroth line table, since asm syntax only supports one line
17561764
// table for now.

llvm/lib/MC/MCDwarf.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ void MCDwarfLineTable::emitOne(
172172
const MCLineSection::MCDwarfLineEntryCollection &LineEntries) {
173173

174174
unsigned FileNum, LastLine, Column, Flags, Isa, Discriminator;
175+
bool IsAtStartSeq;
175176
MCSymbol *LastLabel;
176177
auto init = [&]() {
177178
FileNum = 1;
@@ -181,6 +182,7 @@ void MCDwarfLineTable::emitOne(
181182
Isa = 0;
182183
Discriminator = 0;
183184
LastLabel = nullptr;
185+
IsAtStartSeq = true;
184186
};
185187
init();
186188

@@ -189,11 +191,24 @@ void MCDwarfLineTable::emitOne(
189191
for (const MCDwarfLineEntry &LineEntry : LineEntries) {
190192
MCSymbol *Label = LineEntry.getLabel();
191193
const MCAsmInfo *asmInfo = MCOS->getContext().getAsmInfo();
194+
195+
if (LineEntry.LineStreamLabel) {
196+
if (!IsAtStartSeq) {
197+
MCOS->emitDwarfLineEndEntry(Section, LastLabel);
198+
init();
199+
}
200+
MCOS->emitLabel(LineEntry.LineStreamLabel);
201+
202+
IsAtStartSeq = true;
203+
continue;
204+
}
205+
192206
if (LineEntry.IsEndEntry) {
193207
MCOS->emitDwarfAdvanceLineAddr(INT64_MAX, LastLabel, Label,
194208
asmInfo->getCodePointerSize());
195209
init();
196210
EndEntryEmitted = true;
211+
IsAtStartSeq = true;
197212
continue;
198213
}
199214

@@ -243,14 +258,15 @@ void MCDwarfLineTable::emitOne(
243258
Discriminator = 0;
244259
LastLine = LineEntry.getLine();
245260
LastLabel = Label;
261+
IsAtStartSeq = false;
246262
}
247263

248264
// Generate DWARF line end entry.
249265
// We do not need this for DwarfDebug that explicitly terminates the line
250266
// table using ranges whenever CU or section changes. However, the MC path
251267
// does not track ranges nor terminate the line table. In that case,
252268
// conservatively use the section end symbol to end the line table.
253-
if (!EndEntryEmitted)
269+
if (!EndEntryEmitted && !IsAtStartSeq)
254270
MCOS->emitDwarfLineEndEntry(Section, LastLabel);
255271
}
256272

llvm/lib/MC/MCParser/AsmParser.cpp

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,7 @@ class AsmParser : public MCAsmParser {
485485
DK_FILE,
486486
DK_LINE,
487487
DK_LOC,
488+
DK_LOC_LABEL,
488489
DK_STABS,
489490
DK_CV_FILE,
490491
DK_CV_FUNC_ID,
@@ -580,10 +581,11 @@ class AsmParser : public MCAsmParser {
580581
// ".align{,32}", ".p2align{,w,l}"
581582
bool parseDirectiveAlign(bool IsPow2, unsigned ValueSize);
582583

583-
// ".file", ".line", ".loc", ".stabs"
584+
// ".file", ".line", ".loc", ".loc_label", ".stabs"
584585
bool parseDirectiveFile(SMLoc DirectiveLoc);
585586
bool parseDirectiveLine();
586587
bool parseDirectiveLoc();
588+
bool parseDirectiveLocLabel(SMLoc DirectiveLoc);
587589
bool parseDirectiveStabs();
588590

589591
// ".cv_file", ".cv_func_id", ".cv_inline_site_id", ".cv_loc", ".cv_linetable",
@@ -2156,6 +2158,8 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
21562158
return parseDirectiveLine();
21572159
case DK_LOC:
21582160
return parseDirectiveLoc();
2161+
case DK_LOC_LABEL:
2162+
return parseDirectiveLocLabel(IDLoc);
21592163
case DK_STABS:
21602164
return parseDirectiveStabs();
21612165
case DK_CV_FILE:
@@ -3737,6 +3741,19 @@ bool AsmParser::parseDirectiveLoc() {
37373741
return false;
37383742
}
37393743

3744+
/// parseDirectiveLoc
3745+
/// ::= .loc_label label
3746+
bool AsmParser::parseDirectiveLocLabel(SMLoc DirectiveLoc) {
3747+
StringRef Name;
3748+
DirectiveLoc = Lexer.getLoc();
3749+
if (parseIdentifier(Name))
3750+
return TokError("expected identifier");
3751+
if (parseEOL())
3752+
return true;
3753+
getStreamer().emitDwarfLocLabelDirective(DirectiveLoc, Name);
3754+
return false;
3755+
}
3756+
37403757
/// parseDirectiveStabs
37413758
/// ::= .stabs string, number, number, number
37423759
bool AsmParser::parseDirectiveStabs() {
@@ -5549,6 +5566,7 @@ void AsmParser::initializeDirectiveKindMap() {
55495566
DirectiveKindMap[".file"] = DK_FILE;
55505567
DirectiveKindMap[".line"] = DK_LINE;
55515568
DirectiveKindMap[".loc"] = DK_LOC;
5569+
DirectiveKindMap[".loc_label"] = DK_LOC_LABEL;
55525570
DirectiveKindMap[".stabs"] = DK_STABS;
55535571
DirectiveKindMap[".cv_file"] = DK_CV_FILE;
55545572
DirectiveKindMap[".cv_func_id"] = DK_CV_FUNC_ID;

llvm/lib/MC/MCStreamer.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,25 @@ void MCStreamer::emitDwarfLocDirective(unsigned FileNo, unsigned Line,
267267
Discriminator);
268268
}
269269

270+
void MCStreamer::emitDwarfLocLabelDirective(SMLoc Loc, StringRef Name) {
271+
auto &ctx = getContext();
272+
273+
auto *LineStreamLabel = ctx.getOrCreateSymbol(Name);
274+
275+
auto *LineSym = ctx.createTempSymbol();
276+
const MCDwarfLoc &DwarfLoc = ctx.getCurrentDwarfLoc();
277+
278+
// Create a 'fake' line entry by having LineStreamLabel be non-null. This
279+
// won't actually emit any line information, it will reset the line table
280+
// sequence and emit a label at the start of the new line table sequence.
281+
MCDwarfLineEntry LineEntry(LineSym, DwarfLoc, LineStreamLabel);
282+
283+
// Add the line entry to this section's entries.
284+
ctx.getMCDwarfLineTable(ctx.getDwarfCompileUnitID())
285+
.getMCLineSections()
286+
.addLineEntry(LineEntry, getCurrentSectionOnly());
287+
}
288+
270289
MCSymbol *MCStreamer::getDwarfLineTableSymbol(unsigned CUID) {
271290
MCDwarfLineTable &Table = getContext().getMCDwarfLineTable(CUID);
272291
if (!Table.getLabel()) {

llvm/test/MC/ELF/debug-loc-label.s

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
// Verify that the .loc_label instruction resets the line sequence and generates
2+
// the requested label at the correct position in the line stream
3+
4+
// RUN: llvm-mc -filetype obj -triple x86_64-linux-elf %s -o %t.o
5+
// RUN: llvm-objdump -d %t.o | FileCheck %s --check-prefix=CHECK-ASM
6+
// RUN: llvm-dwarfdump -v --debug-line %t.o | FileCheck %s --check-prefix=CHECK-LINE-TABLE
7+
8+
# CHECK-ASM: <foo>:
9+
# CHECK-ASM-NEXT: movq %rdx, 0x33
10+
# CHECK-ASM-NEXT: movq %rax, 0x3b
11+
# CHECK-ASM-NEXT: movq %rbx, 0x4e
12+
# CHECK-ASM-NEXT: movq %rcx, 0x60
13+
# CHECK-ASM-NEXT: retq
14+
15+
# CHECK-LINE-TABLE: Address Line Column File ISA Discriminator OpIndex Flags
16+
# CHECK-LINE-TABLE-NEXT: ------------------ ------ ------ ------ --- ------------- ------- -------------
17+
# CHECK-LINE-TABLE-NEXT: 0x00000028: 05 DW_LNS_set_column (1)
18+
# CHECK-LINE-TABLE-NEXT: 0x0000002a: 00 DW_LNE_set_address (0x0000000000000000)
19+
# CHECK-LINE-TABLE-NEXT: 0x00000035: 01 DW_LNS_copy
20+
# CHECK-LINE-TABLE-NEXT: 0x0000000000000000 1 1 1 0 0 0 is_stmt
21+
# CHECK-LINE-TABLE-NEXT: 0x00000036: 02 DW_LNS_advance_pc (addr += 33, op-index += 0)
22+
# CHECK-LINE-TABLE-NEXT: 0x00000038: 00 DW_LNE_end_sequence
23+
# CHECK-LINE-TABLE-NEXT: 0x0000000000000021 1 1 1 0 0 0 is_stmt end_sequence
24+
# CHECK-LINE-TABLE-NEXT: 0x0000003b: 05 DW_LNS_set_column (2)
25+
# CHECK-LINE-TABLE-NEXT: 0x0000003d: 00 DW_LNE_set_address (0x0000000000000008)
26+
# CHECK-LINE-TABLE-NEXT: 0x00000048: 01 DW_LNS_copy
27+
# CHECK-LINE-TABLE-NEXT: 0x0000000000000008 1 2 1 0 0 0 is_stmt
28+
# CHECK-LINE-TABLE-NEXT: 0x00000049: 02 DW_LNS_advance_pc (addr += 25, op-index += 0)
29+
# CHECK-LINE-TABLE-NEXT: 0x0000004b: 00 DW_LNE_end_sequence
30+
# CHECK-LINE-TABLE-NEXT: 0x0000000000000021 1 2 1 0 0 0 is_stmt end_sequence
31+
# CHECK-LINE-TABLE-NEXT: 0x0000004e: 05 DW_LNS_set_column (3)
32+
# CHECK-LINE-TABLE-NEXT: 0x00000050: 00 DW_LNE_set_address (0x0000000000000010)
33+
# CHECK-LINE-TABLE-NEXT: 0x0000005b: 01 DW_LNS_copy
34+
# CHECK-LINE-TABLE-NEXT: 0x0000000000000010 1 3 1 0 0 0 is_stmt
35+
# CHECK-LINE-TABLE-NEXT: 0x0000005c: 08 DW_LNS_const_add_pc (addr += 0x0000000000000011, op-index += 0)
36+
# CHECK-LINE-TABLE-NEXT: 0x0000005d: 00 DW_LNE_end_sequence
37+
# CHECK-LINE-TABLE-NEXT: 0x0000000000000021 1 3 1 0 0 0 is_stmt end_sequence
38+
# CHECK-LINE-TABLE-NEXT: 0x00000060: 05 DW_LNS_set_column (4)
39+
# CHECK-LINE-TABLE-NEXT: 0x00000062: 00 DW_LNE_set_address (0x0000000000000018)
40+
# CHECK-LINE-TABLE-NEXT: 0x0000006d: 01 DW_LNS_copy
41+
# CHECK-LINE-TABLE-NEXT: 0x0000000000000018 1 4 1 0 0 0 is_stmt
42+
# CHECK-LINE-TABLE-NEXT: 0x0000006e: 05 DW_LNS_set_column (5)
43+
# CHECK-LINE-TABLE-NEXT: 0x00000070: 01 DW_LNS_copy
44+
# CHECK-LINE-TABLE-NEXT: 0x0000000000000018 1 5 1 0 0 0 is_stmt
45+
# CHECK-LINE-TABLE-NEXT: 0x00000071: 02 DW_LNS_advance_pc (addr += 9, op-index += 0)
46+
# CHECK-LINE-TABLE-NEXT: 0x00000073: 00 DW_LNE_end_sequence
47+
# CHECK-LINE-TABLE-NEXT: 0x0000000000000021 1 5 1 0 0 0 is_stmt end_sequence
48+
.text
49+
.file "test.c"
50+
.globl foo
51+
.align 16, 0x90
52+
.type foo,@function
53+
foo:
54+
.Lfunc_begin0:
55+
.file 1 "test.c"
56+
.cfi_startproc
57+
.loc 1 1 1
58+
mov %rdx, 0x33
59+
.loc_label my_label_02
60+
.loc 1 1 2
61+
movq %rax, my_label_02-.Lline_table_start0
62+
.loc 1 1 3
63+
.loc_label my_label_03
64+
.loc_label my_label_03.1
65+
movq %rbx, my_label_03-.Lline_table_start0
66+
.loc 1 1 4
67+
.loc_label my_label_05
68+
.loc 1 1 5
69+
movq %rcx, my_label_05-.Lline_table_start0
70+
ret
71+
.cfi_endproc
72+
73+
.section .debug_line,"",@progbits
74+
.Lline_table_start0:

0 commit comments

Comments
 (0)