瀏覽代碼

+ 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 年之前
父節點
當前提交
ae4cdf25f8
共有 1 個文件被更改,包括 68 次插入10 次删除
  1. 68 10
      compiler/aggas.pas

+ 68 - 10
compiler/aggas.pas

@@ -45,6 +45,7 @@ interface
       TGNUAssembler=class(texternalassembler)
       protected
         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 WriteExtraHeader;virtual;
         procedure WriteInstruction(hp: tai);
@@ -238,6 +239,19 @@ implementation
         result := target_asm.labelprefix+'$set$'+tostr(setcount);
       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;
       const
         secnames : array[TAsmSectiontype] of string[length('__DATA, __datacoal_nt,coalesced')] = ('','',
@@ -404,16 +418,7 @@ implementation
         if atype=sec_user then
           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
             case aorder of
               secorder_begin :
@@ -430,6 +435,45 @@ implementation
       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);
       var
         s : string;
@@ -484,6 +528,20 @@ implementation
                   internalerror(2006031101);
               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;
         AsmLn;
         LastSecType:=atype;