diff options
author | Sam Clegg <sbc@chromium.org> | 2017-10-27 00:08:55 +0000 |
---|---|---|
committer | Sam Clegg <sbc@chromium.org> | 2017-10-27 00:08:55 +0000 |
commit | c55d13f4610ec5ef3ea4d59583f97b9148383f52 (patch) | |
tree | 022fad23a4cf23a788965882b34dd5f2daf6fc35 /llvm | |
parent | ed55e6c64f9b09fd60143deccb4147dc0f714b27 (diff) | |
download | bcm5719-llvm-c55d13f4610ec5ef3ea4d59583f97b9148383f52.tar.gz bcm5719-llvm-c55d13f4610ec5ef3ea4d59583f97b9148383f52.zip |
[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
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/lib/MC/WasmObjectWriter.cpp | 8 | ||||
-rw-r--r-- | llvm/test/MC/WebAssembly/bss.ll | 75 |
2 files changed, 81 insertions, 2 deletions
diff --git a/llvm/lib/MC/WasmObjectWriter.cpp b/llvm/lib/MC/WasmObjectWriter.cpp index 44f2ba6ed7d..229708425b1 100644 --- a/llvm/lib/MC/WasmObjectWriter.cpp +++ b/llvm/lib/MC/WasmObjectWriter.cpp @@ -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"); } diff --git a/llvm/test/MC/WebAssembly/bss.ll b/llvm/test/MC/WebAssembly/bss.ll index d975fa7374f..9ac83c49cdb 100644 --- a/llvm/test/MC/WebAssembly/bss.ll +++ b/llvm/test/MC/WebAssembly/bss.ll @@ -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: ... |