[MC] Ensure that pending labels are flushed when -mc-relax-all flag is used
authorPetr Hosek <phosek@chromium.org>
Sat, 27 Jun 2015 01:54:17 +0000 (01:54 +0000)
committerPetr Hosek <phosek@chromium.org>
Sat, 27 Jun 2015 01:54:17 +0000 (01:54 +0000)
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
test/MC/X86/AlignedBundling/rodata-section.s [new file with mode: 0644]

index a73c171bd1c08ce9b300cd9651f68c07bfb9a855..0a637775d4eecdc94ff4e7500fbd6aa5439b44bd 100644 (file)
@@ -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 (file)
index 0000000..21f2c73
--- /dev/null
@@ -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