Skip to content

Commit 0b06727

Browse files
committed
[MC] Reject CFI advance_loc separated by a non-private label for Mach-O
Due to Mach-O's .subsections_via_symbols mechanism, non-private labels cannot appear between .cfi_startproc/.cfi_endproc. Compilers do not produce such labels, but hand-written assembly may. Give an error. Unfortunately, emitDwarfAdvanceFrameAddr generated MCExpr doesn't have location informatin. Note: evaluateKnownAbsolute is to force folding A-B to a constant even if A and B are separate by a non-private label. The function is a workaround for some Mach-O assembler issues and should generally be avoided. Reviewed By: efriedma Differential Revision: https://reviews.llvm.org/D153167
1 parent 5a1cdcb commit 0b06727

File tree

2 files changed

+31
-6
lines changed

2 files changed

+31
-6
lines changed

llvm/lib/MC/MCAssembler.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1110,16 +1110,20 @@ bool MCAssembler::relaxDwarfCallFrameFragment(MCAsmLayout &Layout,
11101110
return WasRelaxed;
11111111

11121112
MCContext &Context = Layout.getAssembler().getContext();
1113-
uint64_t OldSize = DF.getContents().size();
1114-
int64_t AddrDelta;
1115-
bool Abs = DF.getAddrDelta().evaluateKnownAbsolute(AddrDelta, Layout);
1116-
assert(Abs && "We created call frame with an invalid expression");
1117-
(void) Abs;
1113+
int64_t Value;
1114+
bool Abs = DF.getAddrDelta().evaluateAsAbsolute(Value, Layout);
1115+
if (!Abs) {
1116+
getContext().reportError(DF.getAddrDelta().getLoc(),
1117+
"invalid CFI advance_loc expression");
1118+
return false;
1119+
}
1120+
11181121
SmallVectorImpl<char> &Data = DF.getContents();
1122+
uint64_t OldSize = Data.size();
11191123
Data.clear();
11201124
DF.getFixups().clear();
11211125

1122-
MCDwarfFrameEmitter::encodeAdvanceLoc(Context, AddrDelta, Data);
1126+
MCDwarfFrameEmitter::encodeAdvanceLoc(Context, Value, Data);
11231127
return OldSize != Data.size();
11241128
}
11251129

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# RUN: not llvm-mc -filetype=obj -triple=x86_64-apple-darwin %s -o /dev/null 2>&1 | FileCheck %s --implicit-check-not=error:
2+
3+
# CHECK-COUNT-4: <unknown>:0: error: invalid CFI advance_loc expression
4+
5+
.section __TEXT,__text
6+
.globl _foo
7+
_foo:
8+
.cfi_startproc
9+
subq $8, %rsp
10+
.cfi_adjust_cfa_offset 8
11+
subq $8, %rsp
12+
.cfi_adjust_cfa_offset 8
13+
14+
tmp0: # non-private label cannot appear here
15+
addq $8, %rsp
16+
.cfi_adjust_cfa_offset -8
17+
.tmp1: # non-private label cannot appear here
18+
addq $8, %rsp
19+
.cfi_adjust_cfa_offset -8
20+
retq
21+
.cfi_endproc

0 commit comments

Comments
 (0)