Browse Source

+ aggas.pas: Write section attributes when long section names are used for smart linking (enabled for win32 and win64). It is needed because GAS does not understand that '.text.something' is part of '.text' and assigns default attributes (writable data) to all such sections, which is not the desired behavior.

git-svn-id: trunk@17989 -
sergei 14 years ago
parent
commit
ae4cdf25f8
1 changed files with 68 additions and 10 deletions
  1. 68 10
      compiler/aggas.pas

+ 68 - 10
compiler/aggas.pas

@@ -45,6 +45,7 @@ interface
       TGNUAssembler=class(texternalassembler)
       TGNUAssembler=class(texternalassembler)
       protected
       protected
         function sectionname(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder):string;virtual;
         function sectionname(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder):string;virtual;
+        function sectionattrs_coff(atype:TAsmSectiontype):string;virtual;
         procedure WriteSection(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder);
         procedure WriteSection(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder);
         procedure WriteExtraHeader;virtual;
         procedure WriteExtraHeader;virtual;
         procedure WriteInstruction(hp: tai);
         procedure WriteInstruction(hp: tai);
@@ -238,6 +239,19 @@ implementation
         result := target_asm.labelprefix+'$set$'+tostr(setcount);
         result := target_asm.labelprefix+'$set$'+tostr(setcount);
       end;
       end;
 
 
+    function is_smart_section(atype:TAsmSectiontype):boolean;
+      begin
+        { For bss we need to set some flags that are target dependent,
+          it is easier to disable it for smartlinking. It doesn't take up
+          filespace }
+        result:=not(target_info.system in systems_darwin) and
+           create_smartlink_sections and
+           (atype<>sec_toc) and
+           (atype<>sec_user) and
+           { on embedded systems every byte counts, so smartlink bss too }
+           ((atype<>sec_bss) or (target_info.system in systems_embedded));
+      end;
+
     function TGNUAssembler.sectionname(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder):string;
     function TGNUAssembler.sectionname(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder):string;
       const
       const
         secnames : array[TAsmSectiontype] of string[length('__DATA, __datacoal_nt,coalesced')] = ('','',
         secnames : array[TAsmSectiontype] of string[length('__DATA, __datacoal_nt,coalesced')] = ('','',
@@ -404,16 +418,7 @@ implementation
         if atype=sec_user then
         if atype=sec_user then
           secname:=aname;
           secname:=aname;
 
 
-        { For bss we need to set some flags that are target dependent,
-          it is easier to disable it for smartlinking. It doesn't take up
-          filespace }
-        if not(target_info.system in systems_darwin) and
-           create_smartlink_sections and
-           (aname<>'') and
-           (atype<>sec_toc) and
-           (atype<>sec_user) and
-           { on embedded systems every byte counts, so smartlink bss too }
-           ((atype<>sec_bss) or (target_info.system in systems_embedded)) then
+        if is_smart_section(atype) and (aname<>'') then
           begin
           begin
             case aorder of
             case aorder of
               secorder_begin :
               secorder_begin :
@@ -430,6 +435,45 @@ implementation
       end;
       end;
 
 
 
 
+    function TGNUAssembler.sectionattrs_coff(atype:TAsmSectiontype):string;
+      begin
+        case atype of
+          sec_code, sec_init, sec_fini, sec_stub:
+            result:='x';
+
+          { TODO: must be individual for each section }
+          sec_user:
+            result:='d';
+
+          sec_data, sec_data_lazy, sec_data_nonlazy, sec_fpc,
+          sec_idata2, sec_idata4, sec_idata5, sec_idata6, sec_idata7:
+            result:='d';
+
+          { TODO: these need a fix to become read-only }
+          sec_rodata, sec_rodata_norel:
+            result:='d';
+
+          sec_bss:
+            result:='b';
+
+          { TODO: Somewhat questionable. FPC does not allow initialized threadvars,
+            so no sense to mark it as containing data. But Windows allows it to
+            contain data, and Linux even has .tdata and .tbss }
+          sec_threadvar:
+            result:='b';
+
+          sec_pdata, sec_edata, sec_eh_frame, sec_toc:
+            result:='r';
+
+          sec_stab,sec_stabstr,
+          sec_debug_frame,sec_debug_info,sec_debug_line,sec_debug_abbrev:
+            result:='n';
+        else
+          result:='';  { defaults to data+load }
+        end;
+      end;
+
+
     procedure TGNUAssembler.WriteSection(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder);
     procedure TGNUAssembler.WriteSection(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder);
       var
       var
         s : string;
         s : string;
@@ -484,6 +528,20 @@ implementation
                   internalerror(2006031101);
                   internalerror(2006031101);
               end;
               end;
             end;
             end;
+        else
+          { GNU AS won't recognize '.text.n_something' section name as belonging
+            to '.text' and assigns default attributes to it, which is not
+            always correct. We have to fix it.
+
+            TODO: This likely applies to all systems which smartlink without
+            creating libraries }
+          if (target_info.system in [system_i386_win32,system_x86_64_win64]) and
+            is_smart_section(atype) and (aname<>'') then
+            begin
+              s:=sectionattrs_coff(atype);
+              if (s<>'') then
+                AsmWrite(',"'+s+'"');
+            end;
         end;
         end;
         AsmLn;
         AsmLn;
         LastSecType:=atype;
         LastSecType:=atype;