[WebAssembly] MC: Don't allow zero sized data segments

This ensures that each segment has a unique address.
Without this, consecutive zero sized symbols would
end up with the same address and the linker cannot
map symbols to unique data segments.

Differential Revision: https://reviews.llvm.org/D39107

llvm-svn: 316717
This commit is contained in:
Sam Clegg 2017-10-27 00:08:55 +00:00
parent ed55e6c64f
commit c55d13f461
2 changed files with 81 additions and 2 deletions

View File

@ -510,6 +510,7 @@ static void addData(SmallVectorImpl<char> &DataBytes,
DataBytes.resize(alignTo(DataBytes.size(), DataSection.getAlignment()));
size_t LastFragmentSize = 0;
for (const MCFragment &Frag : DataSection) {
if (Frag.hasInstructions())
report_fatal_error("only data supported in data sections");
@ -531,9 +532,16 @@ static void addData(SmallVectorImpl<char> &DataBytes,
const SmallVectorImpl<char> &Contents = DataFrag.getContents();
DataBytes.insert(DataBytes.end(), Contents.begin(), Contents.end());
LastFragmentSize = Contents.size();
}
}
// Don't allow empty segments, or segments that end with zero-sized
// fragment, otherwise the linker cannot map symbols to a unique
// data segment. This can be triggered by zero-sized structs
// See: test/MC/WebAssembly/bss.ll
if (LastFragmentSize == 0)
DataBytes.resize(DataBytes.size() + 1);
DEBUG(dbgs() << "addData -> " << DataBytes.size() << "\n");
}

View File

@ -1,8 +1,49 @@
; RUN: llc -mtriple wasm32-unknown-unknown-wasm -filetype=obj %s -o - | obj2yaml | FileCheck %s
@g0 = global i8* null, align 4
@g1 = global i32 0, align 4
; CHECK: - Type: DATA
%union.u1 = type {}
@foo = global %union.u1 zeroinitializer, align 1
@bar = global %union.u1 zeroinitializer, align 1
; CHECK: - Type: GLOBAL
; CHECK-NEXT: Globals:
; CHECK-NEXT: - Type: I32
; CHECK-NEXT: Mutable: false
; CHECK-NEXT: InitExpr:
; CHECK-NEXT: Opcode: I32_CONST
; CHECK-NEXT: Value: 0
; CHECK-NEXT: - Type: I32
; CHECK-NEXT: Mutable: false
; CHECK-NEXT: InitExpr:
; CHECK-NEXT: Opcode: I32_CONST
; CHECK-NEXT: Value: 4
; CHECK-NEXT: - Type: I32
; CHECK-NEXT: Mutable: false
; CHECK-NEXT: InitExpr:
; CHECK-NEXT: Opcode: I32_CONST
; CHECK-NEXT: Value: 8
; CHECK-NEXT: - Type: I32
; CHECK-NEXT: Mutable: false
; CHECK-NEXT: InitExpr:
; CHECK-NEXT: Opcode: I32_CONST
; CHECK-NEXT: Value: 9
; CHECK-NEXT: - Type: EXPORT
; CHECK-NEXT: Exports:
; CHECK-NEXT: - Name: g0
; CHECK-NEXT: Kind: GLOBAL
; CHECK-NEXT: Index: 0
; CHECK-NEXT: - Name: g1
; CHECK-NEXT: Kind: GLOBAL
; CHECK-NEXT: Index: 1
; CHECK-NEXT: - Name: foo
; CHECK-NEXT: Kind: GLOBAL
; CHECK-NEXT: Index: 2
; CHECK-NEXT: - Name: bar
; CHECK-NEXT: Kind: GLOBAL
; CHECK-NEXT: Index: 3
; CHECK-NEXT: - Type: DATA
; CHECK-NEXT: Segments:
; CHECK-NEXT: - SectionOffset: 6
; CHECK-NEXT: MemoryIndex: 0
@ -10,12 +51,42 @@
; CHECK-NEXT: Opcode: I32_CONST
; CHECK-NEXT: Value: 0
; CHECK-NEXT: Content: '00000000'
; CHECK-NEXT: - SectionOffset: 15
; CHECK-NEXT: MemoryIndex: 0
; CHECK-NEXT: Offset:
; CHECK-NEXT: Opcode: I32_CONST
; CHECK-NEXT: Value: 4
; CHECK-NEXT: Content: '00000000'
; CHECK-NEXT: - SectionOffset: 24
; CHECK-NEXT: MemoryIndex: 0
; CHECK-NEXT: Offset:
; CHECK-NEXT: Opcode: I32_CONST
; CHECK-NEXT: Value: 8
; CHECK-NEXT: Content: '00'
; CHECK-NEXT: - SectionOffset: 30
; CHECK-NEXT: MemoryIndex: 0
; CHECK-NEXT: Offset:
; CHECK-NEXT: Opcode: I32_CONST
; CHECK-NEXT: Value: 9
; CHECK-NEXT: Content: '00'
; CHECK-NEXT: - Type: CUSTOM
; CHECK-NEXT: Name: linking
; CHECK-NEXT: DataSize: 4
; CHECK-NEXT: DataSize: 10
; CHECK-NEXT: SegmentInfo:
; CHECK-NEXT: - Index: 0
; CHECK-NEXT: Name: .bss.g0
; CHECK-NEXT: Alignment: 4
; CHECK-NEXT: Flags: 0
; CHECK-NEXT: - Index: 1
; CHECK-NEXT: Name: .bss.g1
; CHECK-NEXT: Alignment: 4
; CHECK-NEXT: Flags: 0
; CHECK-NEXT: - Index: 2
; CHECK-NEXT: Name: .bss.foo
; CHECK-NEXT: Alignment: 1
; CHECK-NEXT: Flags: 0
; CHECK-NEXT: - Index: 3
; CHECK-NEXT: Name: .bss.bar
; CHECK-NEXT: Alignment: 1
; CHECK-NEXT: Flags: 0
; CHECK-NEXT: ...