Jelajahi Sumber

* Use public/global name 'name' section 'section' without semicolon for Windows TLS support

git-svn-id: trunk@17909 -
pierre 14 tahun lalu
induk
melakukan
cfdc7c861d
4 mengubah file dengan 51 tambahan dan 31 penghapusan
  1. 24 6
      compiler/pdecvar.pas
  2. 18 0
      compiler/ptconst.pas
  3. 0 25
      compiler/symsym.pas
  4. 9 0
      compiler/systems.pas

+ 24 - 6
compiler/pdecvar.pas

@@ -41,6 +41,8 @@ interface
 
     procedure read_public_and_external(vs: tabstractvarsym);
 
+    procedure try_consume_sectiondirective(var asection: ansistring);
+
 implementation
 
     uses
@@ -925,7 +927,7 @@ implementation
       is_external_var,
       is_weak_external,
       is_public_var  : boolean;
-      dll_name,
+      dll_name,section_name,
       C_name,mangledname      : string;
     begin
       { only allowed for one var }
@@ -940,6 +942,7 @@ implementation
       is_cdecl:=false;
       is_external_var:=false;
       is_public_var:=false;
+      section_name := '';
       C_name:=vs.realname;
 
       { macpas specific handling due to some switches}
@@ -992,6 +995,10 @@ implementation
             is_public_var:=true;
           if try_to_consume(_NAME) then
             C_name:=get_stringconst;
+          if (target_info.system in systems_allow_section_no_semicolon) and
+             (vs.typ=staticvarsym) and
+             try_to_consume (_SECTION) then
+            section_name:=get_stringconst;
           consume(_SEMICOLON);
         end;
 
@@ -1000,6 +1007,14 @@ implementation
          (target_info.system in systems_all_windows) then
         include(vs.varoptions,vo_is_dll_var);
 
+      { This can only happen if vs.typ=staticvarsym }
+      if section_name<>'' then
+        begin
+          tstaticvarsym(vs).section:=section_name;
+          include(vs.varoptions,vo_has_section);
+        end;
+
+
       { Add C _ prefix }
       if is_cdecl or
          (
@@ -1272,7 +1287,7 @@ implementation
          hintsymoptions  : tsymoptions;
          deprecatedmsg   : pshortstring;
          old_block_type  : tblock_type;
-         section : ansistring;
+         sectionname : ansistring;
       begin
          old_block_type:=block_type;
          block_type:=bt_var;
@@ -1415,10 +1430,12 @@ implementation
                read_public_and_external_sc(sc);
 
              { try to parse a section directive }
-             if (target_info.system in systems_embedded) and (idtoken=_SECTION) then
+             if (target_info.system in systems_allow_section) and
+                (symtablestack.top.symtabletype in [staticsymtable,globalsymtable]) and
+                (idtoken=_SECTION) then
                begin
-                 try_consume_sectiondirective(section);
-                 if section<>'' then
+                 try_consume_sectiondirective(sectionname);
+                 if sectionname<>'' then
                    begin
                      for i:=0 to sc.count-1 do
                        begin
@@ -1427,7 +1444,8 @@ implementation
                            Message(parser_e_externals_no_section);
                          if vs.typ<>staticvarsym then
                            Message(parser_e_section_no_locals);
-                         tstaticvarsym(vs).section:=section;
+                         tstaticvarsym(vs).section:=sectionname;
+                         include(vs.varoptions, vo_has_section);
                        end;
                    end;
                end;

+ 18 - 0
compiler/ptconst.pas

@@ -1437,6 +1437,7 @@ implementation
         storefilepos : tfileposinfo;
         cursectype   : TAsmSectionType;
         hrec         : threc;
+        section : ansistring;
       begin
         { mark the staticvarsym as typedconst }
         include(sym.varoptions,vo_is_typed_const);
@@ -1481,6 +1482,23 @@ implementation
            ) then
           read_public_and_external(sym);
 
+         { try to parse a section directive }
+        if not in_structure and (target_info.system in systems_allow_section) and
+          (symtablestack.top.symtabletype in [staticsymtable,globalsymtable]) and
+           (idtoken=_SECTION) then
+               begin
+                 try_consume_sectiondirective(section);
+                 if section<>'' then
+                   begin
+                     if (sym.varoptions *[vo_is_external,vo_is_weak_external])<>[] then
+                       Message(parser_e_externals_no_section);
+                     if sym.typ<>staticvarsym then
+                       Message(parser_e_section_no_locals);
+                     tstaticvarsym(sym).section:=section;
+                     include(sym.varoptions, vo_has_section);
+                   end;
+               end;
+
         { only now add items based on the symbolname, because it may }
         { have been modified by the directives parsed above          }
         if vo_has_section in sym.varoptions then

+ 0 - 25
compiler/symsym.pas

@@ -1366,33 +1366,8 @@ implementation
 
 
     procedure tstaticvarsym.set_mangledname(const s:string);
-{$ifdef TEST_TLS_DIRECTORY}
-     { TLS directory requires some labels in specific sections
-       I implemented this by allowing '.section sec_name mangled_name'
-       for name 'xxxx'; specifier PM 2011-07-01 }
-      var
-        newmangledname : string;
-        p : longint;
-{$endif TEST_TLS_DIRECTORY}
       begin
         stringdispose(_mangledname);
-{$ifdef TEST_TLS_DIRECTORY}
-        if copy(s,1,length('.section '))='.section ' then
-           begin
-             newmangledname:=copy(s,length('.section ')+1,length(s));
-             p:=pos(' ',newmangledname);
-             if p<2 then
-               Comment(V_Error,'Invalid C var name '+s)
-             else
-               begin
-                 section:=copy(newmangledname,1,p-1);
-                 include(varoptions,vo_has_section);
-                 newmangledname:=copy(newmangledname,p+1,length(newmangledname));
-                 set_mangledname(newmangledname);
-               end;
-           end
-         else
-{$endif TEST_TLS_DIRECTORY}
       {$ifdef compress}
         _mangledname:=stringdup(minilzw_encode(s));
       {$else}

+ 9 - 0
compiler/systems.pas

@@ -239,6 +239,15 @@ interface
                            system_mips_embedded,system_arm_embedded,
                            system_powerpc64_embedded];
 
+       { all systems that allow section directive }
+       systems_allow_section = systems_embedded;
+
+       systems_allow_section_no_semicolon = systems_allow_section
+{$ifdef TEST_TLS_DIRECTORY}
+       + systems_windows
+{$endif TEST_TLS_DIRECTORY}
+       ;
+
        { all symbian systems }
        systems_symbian = [system_i386_symbian,system_arm_symbian];