Repository: davidlattimore/wild (rust)

Issue:
Some of Rust proc-macro tests cause compiler to crash
Failing tests:
- tests/ui/proc-macro/meta-macro.rs
- tests/ui/proc-macro/meta-macro-hygiene.rs

They both crash when calling `free` when rustc is linked with wild:
```
--- stdout -------------------------------
Def site: /home/mateusz/Projects/rust/tests/ui/proc-macro/auxiliary/make-macro.rs:7:9: 7:56 (#3)
Input: TokenStream []
Respanned: TokenStream []
------------------------------------------
--- stderr -------------------------------
free(): invalid pointer
------------------------------------------
```
It's not a crash in the test binary, but a crash inside stage1 rustc executable, likely making the debugging harder.

Pull request description:
Fix tls_start_address when TDATA is absent
Fixes #614

Patch:
diff --git a/libwild/src/layout.rs b/libwild/src/layout.rs
index bb62fa9..20d91d9 100644
--- a/libwild/src/layout.rs
+++ b/libwild/src/layout.rs
@@ -1447,8 +1447,8 @@ impl<'data> Layout<'data> {
     }
 
     pub(crate) fn tls_start_address(&self) -> u64 {
-        let tdata = self.section_layouts.get(output_section_id::TDATA);
-        tdata.mem_offset
+        // If we don't have a TLS segment then the value we return won't really matter.
+        self.segment_layouts.tls_start_address.unwrap_or(0)
     }
 
     /// Returns the memory address of the end of the TLS segment including any padding required to


Test patch:
diff --git a/wild/tests/integration_tests.rs b/wild/tests/integration_tests.rs
index 69a916f..5c2c36f 100644
--- a/wild/tests/integration_tests.rs
+++ b/wild/tests/integration_tests.rs
@@ -2170,6 +2170,7 @@ fn integration_test(
         "tls-local-exec.c",
         "undefined_symbols.c",
         "whole_archive.c",
+        "dynamic-bss-only.c",
         "shared.c",
         "duplicate_strong_symbols.c"
     )]
diff --git a/wild/tests/sources/dynamic-bss-only.c b/wild/tests/sources/dynamic-bss-only.c
new file mode 100644
index 0000000..6abfa5d
--- /dev/null
+++ b/wild/tests/sources/dynamic-bss-only.c
@@ -0,0 +1,22 @@
+// This test sets up the scenario where we have TBSS, but not TDATA. We then have a TLSGD relocation
+// for a local TLS variable in TBSS. We hope to verify that the TLSGD entry gets the correct offset.
+
+//#CompArgs:-fPIC -ftls-model=global-dynamic
+//#LinkArgs:-shared -z now
+//#RunEnabled:false
+//#DiffIgnore:.dynamic.DT_RELAENT
+//#DiffIgnore:.dynamic.DT_RELA
+
+// We use a large alignment here so that it's almost certain that padding will need to be added
+// before our TLS segment, which could cause us to compute incorrect offsets if we used the address
+// of the non-existent TDATA section as the start of TLS.
+__attribute__ ((aligned(256)))
+static __thread long int tvar1;
+
+long int get_tvar1(void) {
+    return tvar1;
+}
+
+void set_tvar1(long int value) {
+    tvar1 = value;
+}