Browse Source

* Adapt margins of list of symbols within a unit, so that it works with
symbols which are smart-linked away
* Added a new section type 'extrtti', because some linkers could
re-arrange the sections that are part of the symbol-list when they are
placed in .const_data.

git-svn-id: branches/joost/classattributes@24654 -

joost 12 years ago
parent
commit
402ef1bbe5

+ 1 - 0
compiler/aasmbase.pas

@@ -97,6 +97,7 @@ interface
                   "If special .fpc section cannot be used on some target,
                   .text can be used instead." }
          sec_fpc,
+         sec_extrtti,
          { Table of contents section }
          sec_toc,
          sec_init,

+ 9 - 1
compiler/aggas.pas

@@ -279,6 +279,7 @@ implementation
           '.eh_frame',
           '.debug_frame','.debug_info','.debug_line','.debug_abbrev',
           '.fpc',
+          '.extrtti',
           '.toc',
           '.init',
           '.fini',
@@ -336,6 +337,7 @@ implementation
           '.eh_frame',
           '.debug_frame','.debug_info','.debug_line','.debug_abbrev',
           '.fpc',
+          '.extrtti',
           '.toc',
           '.init',
           '.fini',
@@ -441,7 +443,7 @@ implementation
             result:='d';
 
           { TODO: these need a fix to become read-only }
-          sec_rodata, sec_rodata_norel:
+          sec_rodata, sec_rodata_norel, sec_extrtti:
             result:='d';
 
           sec_bss:
@@ -1629,6 +1631,11 @@ implementation
                 result := '.section __TEXT, .fpc, regular, no_dead_strip';
                 exit;
               end;
+            sec_extrtti:
+              begin
+                result := '.section __FPC, .extrtti, regular';
+                exit;
+              end;
             sec_code:
               begin
                 if (aname='fpc_geteipasebx') or
@@ -1817,6 +1824,7 @@ implementation
          sec_debug_abbrev,
          { ELF resources (+ references to stabs debug information sections) }
          sec_code (* sec_fpc *),
+         sec_data (* sec_extrtti *),
          { Table of contents section }
          sec_code (* sec_toc *),
          sec_code (* sec_init *),

+ 44 - 8
compiler/ncgrtti.pas

@@ -58,6 +58,7 @@ interface
         function  get_rtti_label(def:tdef;rt:trttitype):tasmsymbol;
         function  get_rtti_label_ord2str(def:tdef;rt:trttitype):tasmsymbol;
         function  get_rtti_label_str2ord(def:tdef;rt:trttitype):tasmsymbol;
+        procedure start_write_unit_extrtti_info;
         procedure after_write_unit_extrtti_info(st: TSymtable);
       end;
 
@@ -108,9 +109,14 @@ implementation
       var
         extrttilab : tasmsymbol;
       begin
+        if def.owner.ExtRttiCount=0 then
+          start_write_unit_extrtti_info;
+
         extrttilab:=current_asmdata.DefineAsmSymbol(tstoreddef(def).rtti_mangledname(extrtti),AB_GLOBAL,AT_DATA);
 
-        new_section(current_asmdata.asmlists[al_ext_rtti],sec_rodata,extrttilab.name,const_align(sizeof(pint)));
+        { Create a sec_extrtti section, because a normal data section could be
+          re-ordered by the linker }
+        new_section(current_asmdata.asmlists[al_ext_rtti],sec_extrtti,extrttilab.name,const_align(sizeof(pint)));
         current_asmdata.asmlists[al_ext_rtti].concat(Tai_symbol.Create_global(extrttilab,0));
 
         // Write reference to 'normal' typedata
@@ -1335,19 +1341,49 @@ implementation
         result:=current_asmdata.RefAsmSymbol(def.rtti_mangledname(rt)+'_s2o');
       end;
 
+    procedure TRTTIWriter.start_write_unit_extrtti_info;
+      begin
+        new_section(current_asmdata.asmlists[al_ext_rtti],sec_extrtti,make_mangledname('EXTR',current_module.localsymtable,''),const_align(sizeof(pint)));
+      end;
+
+
     procedure TRTTIWriter.after_write_unit_extrtti_info(st: TSymtable);
       var
-        startrtti  : TAsmSymbol;
-        s          : string;
+        start_extrtti_symbollist,
+        end_extrtti_symbollist    : TAsmSymbol;
+        first_item,
+        unitinfosize_item,
+        start_extrtti_item,
+        unitnamelength_item,
+        unitname_item             : TLinkedListItem;
+        s                         : string;
     begin
       if st.extrtticount>0 then
         begin
-          startrtti := current_asmdata.DefineAsmSymbol(make_mangledname('EXTR',current_module.localsymtable,''),AB_GLOBAL,AT_DATA);
+          { Make symbols for the start and the end of the unit-info, so that
+            the linker can calculate the size of the structure. This because
+            some types could be omitted due to smart-linking }
+          start_extrtti_symbollist := current_asmdata.DefineAsmSymbol(make_mangledname('EXTR',current_module.localsymtable,''),AB_GLOBAL,AT_DATA);
+          end_extrtti_symbollist := current_asmdata.DefineAsmSymbol(make_mangledname('EXTRE_',current_module.localsymtable,''),AB_GLOBAL,AT_DATA);
           s := current_module.realmodulename^;
-          current_asmdata.asmlists[al_ext_rtti].insert(Tai_string.Create(s));
-          current_asmdata.asmlists[al_ext_rtti].insert(Tai_const.Create_8bit(length(s)));
-          current_asmdata.asmlists[al_ext_rtti].insert(Tai_const.Create_aint(st.ExtRttiCount));
-          current_asmdata.asmlists[al_ext_rtti].insert(Tai_symbol.Create_global(startrtti,0));
+
+          { Insert the TUnitInfo structure after the section-start, which is
+            added in start_write_unit_extrtti_info }
+          first_item := current_asmdata.asmlists[al_ext_rtti].First.Next;
+          start_extrtti_item := Tai_symbol.Create_global(start_extrtti_symbollist,0);
+          unitinfosize_item := Tai_const.Create_rel_sym(aitconst_aint, start_extrtti_symbollist, end_extrtti_symbollist);
+          unitnamelength_item := Tai_const.Create_8bit(length(s));
+          unitname_item := Tai_string.Create(s);
+
+          current_asmdata.asmlists[al_ext_rtti].InsertAfter(start_extrtti_item, first_item);
+          current_asmdata.asmlists[al_ext_rtti].InsertAfter(unitinfosize_item, start_extrtti_item);
+          current_asmdata.asmlists[al_ext_rtti].InsertAfter(unitnamelength_item, unitinfosize_item);
+          current_asmdata.asmlists[al_ext_rtti].InsertAfter(unitname_item, unitnamelength_item);
+
+          { Write the symbol to mark the end of the structure }
+          current_asmdata.asmlists[al_ext_rtti].concat(Tai_symbol.Create_global(end_extrtti_symbollist,0));
+          current_asmdata.asmlists[al_ext_rtti].concat(Tai_const.Create_8bit(0));
+
           current_module.flags:=current_module.flags+uf_extrtti;
         end;
     end;

+ 2 - 0
compiler/ogbase.pas

@@ -846,6 +846,7 @@ implementation
           'eh_frame',
           'debug_frame','debug_info','debug_line','debug_abbrev',
           'fpc',
+          'extrtti',
           'toc',
           'init',
           'fini',
@@ -940,6 +941,7 @@ implementation
           {debug_line} [oso_Data,oso_noload,oso_debug],
           {debug_abbrev} [oso_Data,oso_noload,oso_debug],
           {fpc} [oso_Data,oso_load,oso_write,oso_keep],
+          {extrtti} [oso_Data,oso_load,oso_write,oso_keep],
           {toc} [oso_Data,oso_load,oso_readonly],
           {init} [oso_Data,oso_load,oso_readonly,oso_executable,oso_keep],
           {fini} [oso_Data,oso_load,oso_readonly,oso_executable,oso_keep],

+ 1 - 0
compiler/ogcoff.pas

@@ -495,6 +495,7 @@ implementation
           '.eh_frame',
           '.debug_frame','.debug_info','.debug_line','.debug_abbrev',
           '.fpc',
+          '.extrtti',
           '',
           '.init',
           '.fini',

+ 2 - 0
compiler/ogelf.pas

@@ -766,6 +766,7 @@ implementation
           '.eh_frame',
           '.debug_frame','.debug_info','.debug_line','.debug_abbrev',
           '.fpc',
+          '.extrtti',
           '.toc',
           '.init',
           '.fini',
@@ -823,6 +824,7 @@ implementation
           '.eh_frame',
           '.debug_frame','.debug_info','.debug_line','.debug_abbrev',
           '.fpc',
+          '.extrtti',
           '.toc',
           '.init',
           '.fini',

+ 1 - 0
compiler/powerpc/agppcmpw.pas

@@ -115,6 +115,7 @@ interface
         '',
         '',
         '',
+        '',
         ''
       );
 

+ 2 - 0
compiler/x86/agx86int.pas

@@ -106,6 +106,7 @@ implementation
         '',
         '',
         '',
+        '',
         ''
       );
 
@@ -156,6 +157,7 @@ implementation
         '',
         '',
         '',
+        '',
         ''
       );
 

+ 1 - 0
compiler/x86/agx86nsm.pas

@@ -440,6 +440,7 @@ interface
           '.eh_frame',
           '.debug_frame','.debug_info','.debug_line','.debug_abbrev',
           '.fpc',
+          '.extrtti',
           '',
           '.init',
           '.fini',