From 72be688a8c4c671a36f86eda9bd8fd5a565c5af4 Mon Sep 17 00:00:00 2001
From: svenbarth <pascaldragon@googlemail.com>
Date: Fri, 1 Jul 2016 14:18:28 +0000
Subject: [PATCH] A unit's threadvar list needs to be indirectly referenced by
 the THREADVARLIST as well.

compiler/ngenutil.pas, tnodeutils:
  * InsertThreadvarTablesTable: reference a unit's (and the program's) threadvar table using a indirect symbol
  * InsertThreadvars: generate an indirect symbol for the threadvar table
rtl/inc/threadvr.inc:
  * TltvInitTablesTable: add an additional indirection for the tables field

git-svn-id: trunk@34043 -
---
 compiler/ngenutil.pas | 24 ++++++++++++++++++++----
 rtl/inc/threadvr.inc  |  7 ++++---
 2 files changed, 24 insertions(+), 7 deletions(-)

diff --git a/compiler/ngenutil.pas b/compiler/ngenutil.pas
index b39e36130c..f9b99149aa 100644
--- a/compiler/ngenutil.pas
+++ b/compiler/ngenutil.pas
@@ -1037,8 +1037,9 @@ implementation
        begin
          if (hp.u.flags and uf_threadvars)=uf_threadvars then
            begin
+             sym:=current_asmdata.RefAsmSymbol(make_mangledname('THREADVARLIST',hp.u.globalsymtable,''),AT_DATA,true);
              tcb.emit_tai(
-               tai_const.Createname(make_mangledname('THREADVARLIST',hp.u.globalsymtable,''),0),
+               tai_const.Create_sym(sym),
                voidpointertype);
              inc(count);
            end;
@@ -1047,8 +1048,9 @@ implementation
       { Add program threadvars, if any }
       if (current_module.flags and uf_threadvars)=uf_threadvars then
         begin
+          sym:=current_asmdata.RefAsmSymbol(make_mangledname('THREADVARLIST',current_module.localsymtable,''),AT_DATA,true);
           tcb.emit_tai(
-            Tai_const.Createname(make_mangledname('THREADVARLIST',current_module.localsymtable,''),0),
+            Tai_const.Create_sym(sym),
             voidpointertype);
           inc(count);
         end;
@@ -1094,6 +1096,7 @@ implementation
       tcb: ttai_typedconstbuilder;
       sym: tasmsymbol;
       tabledef: trecorddef;
+      add : boolean;
     begin
        if (tf_section_threadvars in target_info.flags) then
          exit;
@@ -1108,15 +1111,28 @@ implementation
          { terminator }
          tcb.emit_tai(tai_const.Create_nil_dataptr,voidpointertype);
        tcb.end_anonymous_record;
-       if trecordsymtable(tabledef.symtable).datasize<>0 then
+       add:=trecordsymtable(tabledef.symtable).datasize<>0;
+       if add then
          begin
            s:=make_mangledname('THREADVARLIST',current_module.localsymtable,'');
            sym:=current_asmdata.DefineAsmSymbol(s,AB_GLOBAL,AT_DATA);
            current_asmdata.asmlists[al_globals].concatlist(
              tcb.get_final_asmlist(sym,tabledef,sec_data,s,sizeof(pint)));
            current_module.flags:=current_module.flags or uf_threadvars;
-         end;
+         end
+       else
+         s:='';
        tcb.Free;
+       if add then
+         begin
+           { write indirect symbol }
+           tcb:=ctai_typedconstbuilder.create([tcalo_make_dead_strippable,tcalo_new_section]);
+           sym:=current_asmdata.DefineAsmSymbol(s,AB_INDIRECT,AT_DATA);
+           tcb.emit_tai(Tai_const.Create_sym(current_asmdata.RefAsmSymbol(s,AT_DATA,false)),voidpointertype);
+           current_asmdata.AsmLists[al_globals].concatList(
+             tcb.get_final_asmlist(sym,voidpointertype,sec_rodata,sym.name,const_align(sizeof(pint))));
+           tcb.free;
+         end;
     end;
 
 
diff --git a/rtl/inc/threadvr.inc b/rtl/inc/threadvr.inc
index 0d1285ebc7..0ebc663e93 100644
--- a/rtl/inc/threadvr.inc
+++ b/rtl/inc/threadvr.inc
@@ -22,6 +22,7 @@
 
 type
   pltvInitEntry = ^ltvInitEntry;
+  ppltvInitEntry = ^pltvInitEntry;
   ltvInitEntry = packed record
      varaddr : {$ifdef cpu16}pword{$else}pdword{$endif};
      size    : longint;
@@ -29,7 +30,7 @@ type
 
   TltvInitTablesTable = packed record
     count  : dword;
-    tables : packed array [1..{$ifdef cpu16}16{$else}32767{$endif}] of pltvInitEntry;
+    tables : packed array [1..{$ifdef cpu16}16{$else}32767{$endif}] of {$ifdef ver3_0}pltvInitEntry{$else}ppltvInitEntry{$endif};
   end;
   PltvInitTablesTable = ^TltvInitTablesTable;
 
@@ -62,7 +63,7 @@ begin
     WriteLn ('init_all_unit_threadvars (',count,') units');
 {$endif}
     for i := 1 to count do
-      init_unit_threadvars (tables[i]);
+      init_unit_threadvars (tables[i]{$ifndef ver3_0}^{$endif});
   end;
 end;
 
@@ -96,7 +97,7 @@ begin
     WriteLn ('copy_all_unit_threadvars (',count,') units');
 {$endif}
     for i := 1 to count do
-      copy_unit_threadvars (tables[i]);
+      copy_unit_threadvars (tables[i]{$ifndef ver3_0}^{$endif});
   end;
 end;