]> granicus.if.org Git - llvm/commitdiff
[WebAssembly] MC: Don't allow zero sized data segments
authorSam Clegg <sbc@chromium.org>
Fri, 27 Oct 2017 00:08:55 +0000 (00:08 +0000)
committerSam Clegg <sbc@chromium.org>
Fri, 27 Oct 2017 00:08:55 +0000 (00:08 +0000)
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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@316717 91177308-0d34-0410-b5e6-96231b3b80d8

lib/MC/WasmObjectWriter.cpp
test/MC/WebAssembly/bss.ll

index 44f2ba6ed7d91de234dc911e082c29249a17d705..229708425b174e99cb8ebecbf2ba59d683bcf601 100644 (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");
 }
 
index d975fa7374f05af1d093b024ce598920be2647b5..9ac83c49cdbd72412aaa56642008a1aebee9f7b3 100644 (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
 ; 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: ...