File tree Expand file tree Collapse file tree 5 files changed +26
-13
lines changed Expand file tree Collapse file tree 5 files changed +26
-13
lines changed Original file line number Diff line number Diff line change 4444
4545# RUN: wasm-ld --no-gc-sections --no-entry -o %t.wasm %t.o
4646# RUN: obj2yaml %t.wasm | FileCheck %s
47+ # RUN: llvm-objdump --disassemble-symbols=get_tls1 --no-show-raw-insn --no-leading-addr %t.wasm | FileCheck %s --check-prefixes DIS
4748
4849# RUN: wasm-ld --experimental-pic -shared -o %t.so %t.o
4950# RUN: obj2yaml %t.so | FileCheck %s --check-prefixes=SHARED,PIC
9798# CHECK-NEXT: Content: 2A000000
9899# CHECK-NEXT: - Type: CUSTOM
99100
101+ # The constant value here which we add to `__tls_base` should not be absolute
102+ # but relative to `__tls_base`, in this case zero rather than 1024.
103+ # DIS: <get_tls1>:
104+ # DIS-EMPTY:
105+ # DIS-NEXT: global.get 1
106+ # DIS-NEXT: i32.const 0
107+ # DIS-NEXT: i32.add
108+ # DIS-NEXT: end
100109
101110# In PIC mode we expect TLS data and non-TLS data to be merged into
102111# a single segment which is initialized via the __memory_base import
Original file line number Diff line number Diff line change @@ -122,16 +122,16 @@ void scanRelocations(InputChunk *chunk) {
122122 " cannot be used against an undefined symbol `" + toString (*sym) +
123123 " `" );
124124 }
125+ if (!sym->isTLS ()) {
126+ error (toString (file) + " : relocation " +
127+ relocTypeToString (reloc.Type ) +
128+ " cannot be used against non-TLS symbol `" + toString (*sym) +
129+ " `" );
130+ }
125131 // In single-threaded builds TLS is lowered away and TLS data can be
126132 // merged with normal data and allowing TLS relocation in non-TLS
127133 // segments.
128134 if (config->sharedMemory ) {
129- if (!sym->isTLS ()) {
130- error (toString (file) + " : relocation " +
131- relocTypeToString (reloc.Type ) +
132- " cannot be used against non-TLS symbol `" + toString (*sym) +
133- " `" );
134- }
135135 if (auto *D = dyn_cast<DefinedData>(sym)) {
136136 if (!D->segment ->outputSeg ->isTLS ()) {
137137 error (toString (file) + " : relocation " +
Original file line number Diff line number Diff line change @@ -310,12 +310,11 @@ uint32_t DefinedFunction::getExportedFunctionIndex() const {
310310 return function->getFunctionIndex ();
311311}
312312
313- uint64_t DefinedData::getVA () const {
313+ uint64_t DefinedData::getVA (bool absolute ) const {
314314 LLVM_DEBUG (dbgs () << " getVA: " << getName () << " \n " );
315- // In the shared memory case, TLS symbols are relative to the start of the TLS
316- // output segment (__tls_base). When building without shared memory, TLS
317- // symbols absolute, just like non-TLS.
318- if (isTLS () && config->sharedMemory )
315+ // TLS symbols (by default) are relative to the start of the TLS output
316+ // segment (__tls_base).
317+ if (isTLS () && !absolute)
319318 return getOutputSegmentOffset ();
320319 if (segment)
321320 return segment->getVA (value);
Original file line number Diff line number Diff line change @@ -315,7 +315,9 @@ class DefinedData : public DataSymbol {
315315 static bool classof (const Symbol *s) { return s->kind () == DefinedDataKind; }
316316
317317 // Returns the output virtual address of a defined data symbol.
318- uint64_t getVA () const ;
318+ // For TLS symbols, by default (unless absolute is set), this returns an
319+ // address relative the `__tls_base`.
320+ uint64_t getVA (bool absolute = false ) const ;
319321 void setVA (uint64_t va);
320322
321323 // Returns the offset of a defined data symbol within its OutputSegment.
Original file line number Diff line number Diff line change @@ -514,7 +514,10 @@ void GlobalSection::writeBody() {
514514 } else {
515515 WasmInitExpr initExpr;
516516 if (auto *d = dyn_cast<DefinedData>(sym))
517- initExpr = intConst (d->getVA (), is64);
517+ // In the sharedMemory case `__wasm_apply_global_tls_relocs` is used
518+ // to set the final value of this globel, but in the non-shared case
519+ // we know the absolute value at link time.
520+ initExpr = intConst (d->getVA (/* absolute=*/ !config->sharedMemory ), is64);
518521 else if (auto *f = dyn_cast<FunctionSymbol>(sym))
519522 initExpr = intConst (f->isStub ? 0 : f->getTableIndex (), is64);
520523 else {
You can’t perform that action at this time.
0 commit comments