Move "local commons" to the end of .bss to match the gnu as behavior.

llvm-svn: 115037
This commit is contained in:
Rafael Espindola 2010-09-29 14:52:01 +00:00
parent 1b3d55417c
commit 96509a5550
2 changed files with 50 additions and 9 deletions

View File

@ -111,6 +111,13 @@ public:
virtual void Finish();
private:
struct LocalCommon {
MCSymbolData *SD;
uint64_t Size;
unsigned ByteAlignment;
};
std::vector<LocalCommon> LocalCommons;
SmallPtrSet<MCSymbol *, 16> BindingExplicitlySet;
/// @}
void SetSection(StringRef Section, unsigned Type, unsigned Flags,
@ -343,17 +350,10 @@ void MCELFStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
MCSectionELF::SHF_WRITE |
MCSectionELF::SHF_ALLOC,
SectionKind::getBSS());
MCSectionData &SectData = getAssembler().getOrCreateSectionData(*Section);
new MCAlignFragment(ByteAlignment, 0, 1, ByteAlignment, &SectData);
MCFragment *F = new MCFillFragment(0, 0, Size, &SectData);
SD.setFragment(F);
Symbol->setSection(*Section);
// Update the maximum alignment of the section if necessary.
if (ByteAlignment > SectData.getAlignment())
SectData.setAlignment(ByteAlignment);
struct LocalCommon L = {&SD, Size, ByteAlignment};
LocalCommons.push_back(L);
} else {
SD.setCommon(Size, ByteAlignment);
}
@ -499,6 +499,26 @@ void MCELFStreamer::EmitInstruction(const MCInst &Inst) {
}
void MCELFStreamer::Finish() {
for (std::vector<LocalCommon>::const_iterator i = LocalCommons.begin(),
e = LocalCommons.end();
i != e; ++i) {
MCSymbolData *SD = i->SD;
uint64_t Size = i->Size;
unsigned ByteAlignment = i->ByteAlignment;
const MCSymbol &Symbol = SD->getSymbol();
const MCSection &Section = Symbol.getSection();
MCSectionData &SectData = getAssembler().getOrCreateSectionData(Section);
new MCAlignFragment(ByteAlignment, 0, 1, ByteAlignment, &SectData);
MCFragment *F = new MCFillFragment(0, 0, Size, &SectData);
SD->setFragment(F);
// Update the maximum alignment of the section if necessary.
if (ByteAlignment > SectData.getAlignment())
SectData.setAlignment(ByteAlignment);
}
// FIXME: We create more atoms than it is necessary. Some relocations to
// merge sections can be implemented with section address + offset,
// figure out which ones and why.

21
test/MC/ELF/common2.s Normal file
View File

@ -0,0 +1,21 @@
// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o - | elf-dump | FileCheck %s
// Test that the common symbols are placed at the end of .bss. In this example
// it causes .bss to have size 9 instead of 8.
.local vimvardict
.comm vimvardict,1,8
.bss
.zero 1
.align 8
// CHECK: (('sh_name', 13) # '.bss'
// CHECK-NEXT: ('sh_type',
// CHECK-NEXT: ('sh_flags'
// CHECK-NEXT: ('sh_addr',
// CHECK-NEXT: ('sh_offset',
// CHECK-NEXT: ('sh_size', 9)
// CHECK-NEXT: ('sh_link',
// CHECK-NEXT: ('sh_info',
// CHECK-NEXT: ('sh_addralign',
// CHECK-NEXT: ('sh_entsize',