From bc245c01bff943b39162504fc8e9b7480ddb965c Mon Sep 17 00:00:00 2001 From: Petr Hosek Date: Sat, 27 Jun 2015 01:54:17 +0000 Subject: [PATCH] [MC] Ensure that pending labels are flushed when -mc-relax-all flag is used Summary: The current implementation doesn't always flush all pending labels beforeemitting data which can result in an incorrectly placed labels in case when when instruction bundling is enabled and -mc-relax-all flag is being used. To address this issue, we always flush pending labels before emitting data. The change was tested by running PNaCl toolchain trybots with -mc-relax-all flag set. Fixes https://code.google.com/p/nativeclient/issues/detail?id=4063 Test Plan: Regression test attached Reviewers: mseaborn Subscribers: jfb, llvm-commits Differential Revision: http://reviews.llvm.org/D10325 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@240870 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/MC/MCObjectStreamer.cpp | 11 +++++-- test/MC/X86/AlignedBundling/rodata-section.s | 30 ++++++++++++++++++++ 2 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 test/MC/X86/AlignedBundling/rodata-section.s diff --git a/lib/MC/MCObjectStreamer.cpp b/lib/MC/MCObjectStreamer.cpp index a73c171bd1c..0a637775d4e 100644 --- a/lib/MC/MCObjectStreamer.cpp +++ b/lib/MC/MCObjectStreamer.cpp @@ -124,6 +124,7 @@ void MCObjectStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, const SMLoc &Loc) { MCStreamer::EmitValueImpl(Value, Size, Loc); MCDataFragment *DF = getOrCreateDataFragment(); + flushPendingLabels(DF, DF->getContents().size()); MCLineEntry::Make(this, getCurrentSection().first); @@ -362,7 +363,9 @@ void MCObjectStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel, void MCObjectStreamer::EmitBytes(StringRef Data) { MCLineEntry::Make(this, getCurrentSection().first); - getOrCreateDataFragment()->getContents().append(Data.begin(), Data.end()); + MCDataFragment *DF = getOrCreateDataFragment(); + flushPendingLabels(DF, DF->getContents().size()); + DF->getContents().append(Data.begin(), Data.end()); } void MCObjectStreamer::EmitValueToAlignment(unsigned ByteAlignment, @@ -410,6 +413,7 @@ bool MCObjectStreamer::EmitValueToOffset(const MCExpr *Offset, // Associate GPRel32 fixup with data and resize data area void MCObjectStreamer::EmitGPRel32Value(const MCExpr *Value) { MCDataFragment *DF = getOrCreateDataFragment(); + flushPendingLabels(DF, DF->getContents().size()); DF->getFixups().push_back(MCFixup::create(DF->getContents().size(), Value, FK_GPRel_4)); @@ -419,6 +423,7 @@ void MCObjectStreamer::EmitGPRel32Value(const MCExpr *Value) { // Associate GPRel32 fixup with data and resize data area void MCObjectStreamer::EmitGPRel64Value(const MCExpr *Value) { MCDataFragment *DF = getOrCreateDataFragment(); + flushPendingLabels(DF, DF->getContents().size()); DF->getFixups().push_back(MCFixup::create(DF->getContents().size(), Value, FK_GPRel_4)); @@ -428,7 +433,9 @@ void MCObjectStreamer::EmitGPRel64Value(const MCExpr *Value) { void MCObjectStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue) { // FIXME: A MCFillFragment would be more memory efficient but MCExpr has // problems evaluating expressions across multiple fragments. - getOrCreateDataFragment()->getContents().append(NumBytes, FillValue); + MCDataFragment *DF = getOrCreateDataFragment(); + flushPendingLabels(DF, DF->getContents().size()); + DF->getContents().append(NumBytes, FillValue); } void MCObjectStreamer::EmitZeros(uint64_t NumBytes) { diff --git a/test/MC/X86/AlignedBundling/rodata-section.s b/test/MC/X86/AlignedBundling/rodata-section.s new file mode 100644 index 00000000000..21f2c735f8c --- /dev/null +++ b/test/MC/X86/AlignedBundling/rodata-section.s @@ -0,0 +1,30 @@ +# RUN: llvm-mc -triple=i686-nacl -filetype=obj %s -o - \ +# RUN: | llvm-objdump -disassemble -no-show-raw-insn - | FileCheck %s +# RUN: llvm-mc -triple=i686-nacl -filetype=obj -mc-relax-all %s -o - \ +# RUN: | llvm-objdump -disassemble -no-show-raw-insn - | FileCheck %s + + .bundle_align_mode 5 + .text + .align 32, 0x90 +# CHECK: 0: movl $14, 8(%esp) + movl $.str2, 8(%esp) +# CHECK: 8: movl $7, 4(%esp) + movl $.str1, 4(%esp) +# CHECK: 10: movl $0, (%esp) + movl $.str, (%esp) + + .type .str,@object + .section .rodata,"a",@progbits +.str: + .asciz "hello1" + .size .str, 7 + + .type .str1,@object +.str1: + .asciz "hello2" + .size .str1, 7 + + .type .str2,@object +.str2: + .asciz "hello3" + .size .str2, 7 -- 2.34.1