Index: include/llvm/MC/MCObjectStreamer.h =================================================================== --- include/llvm/MC/MCObjectStreamer.h +++ include/llvm/MC/MCObjectStreamer.h @@ -82,9 +82,7 @@ /// If any labels have been emitted but not assigned fragments, ensure that /// they get assigned, either to F if possible or to a new data fragment. - /// Optionally, it is also possible to provide an offset \p FOffset, which - /// will be used as a symbol offset within the fragment. - void flushPendingLabels(MCFragment *F, uint64_t FOffset = 0); + void flushPendingLabels(MCFragment *F); public: void visitUsedSymbol(const MCSymbol &Sym) override; Index: lib/MC/MCELFStreamer.cpp =================================================================== --- lib/MC/MCELFStreamer.cpp +++ lib/MC/MCELFStreamer.cpp @@ -72,12 +72,18 @@ VecOS.flush(); delete OW; + // Push any symbols which are on the fragment boundary below the padding. + size_t Offset = DF->getContents().size(); + for (const MCSymbol &Symbol : Assembler.symbols()) { + MCSymbolData &SD = Symbol.getData(); + if (SD.getFragment() == DF && SD.getOffset() == Offset) { + SD.setOffset(SD.getOffset() + Code.size()); + } + } DF->getContents().append(Code.begin(), Code.end()); } } - flushPendingLabels(DF, DF->getContents().size()); - for (unsigned i = 0, e = EF->getFixups().size(); i != e; ++i) { EF->getFixups()[i].setOffset(EF->getFixups()[i].getOffset() + DF->getContents().size()); Index: lib/MC/MCObjectStreamer.cpp =================================================================== --- lib/MC/MCObjectStreamer.cpp +++ lib/MC/MCObjectStreamer.cpp @@ -38,7 +38,7 @@ delete Assembler; } -void MCObjectStreamer::flushPendingLabels(MCFragment *F, uint64_t FOffset) { +void MCObjectStreamer::flushPendingLabels(MCFragment *F) { if (PendingLabels.size()) { if (!F) { F = new MCDataFragment(); @@ -47,7 +47,6 @@ } for (MCSymbolData *SD : PendingLabels) { SD->setFragment(F); - SD->setOffset(FOffset); } PendingLabels.clear(); } @@ -168,9 +167,7 @@ // If there is a current fragment, mark the symbol as pointing into it. // Otherwise queue the label and set its fragment pointer when we emit the // next fragment. - auto *F = dyn_cast_or_null(getCurrentFragment()); - if (F && !(getAssembler().isBundlingEnabled() && - getAssembler().getRelaxAll())) { + if (auto *F = dyn_cast_or_null(getCurrentFragment())) { SD.setFragment(F); SD.setOffset(F->getContents().size()); } else { Index: test/MC/X86/AlignedBundling/rodata-section.s =================================================================== --- /dev/null +++ test/MC/X86/AlignedBundling/rodata-section.s @@ -0,0 +1,40 @@ +# 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 + .globl foo + .align 32, 0x90 + .type foo,@function +foo: + subl $12, %esp +# CHECK: 3: movl $14, 8(%esp) + movl $.str2, 8(%esp) +# CHECK: b: movl $7, 4(%esp) + movl $.str1, 4(%esp) +# CHECK: 13: movl $0, (%esp) + movl $.str, (%esp) + calll bar +# CHECK: 1f: nop + addl $12, %esp + popl %ecx + jmp *%ecx + + + .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