Explorar o código

* allocate .bss entries manual so we can take care of alignment
* disable COMMON symbol code, it might be needed again for ELF package
support (.comm for ELF supports alignment)

git-svn-id: trunk@10549 -

peter %!s(int64=17) %!d(string=hai) anos
pai
achega
52722b2cab
Modificáronse 5 ficheiros con 147 adicións e 19 borrados
  1. 2 0
      .gitattributes
  2. 43 16
      compiler/aggas.pas
  3. 13 3
      compiler/assemble.pas
  4. 45 0
      tests/webtbs/tw11039a.pp
  5. 44 0
      tests/webtbs/tw11039b.pp

+ 2 - 0
.gitattributes

@@ -8108,6 +8108,8 @@ tests/webtbs/tw11006.pp svneol=native#text/plain
 tests/webtbs/tw11027.pp svneol=native#text/plain
 tests/webtbs/tw1103.pp svneol=native#text/plain
 tests/webtbs/tw11033.pp svneol=native#text/plain
+tests/webtbs/tw11039a.pp svneol=native#text/plain
+tests/webtbs/tw11039b.pp svneol=native#text/plain
 tests/webtbs/tw1104.pp svneol=native#text/plain
 tests/webtbs/tw1111.pp svneol=native#text/plain
 tests/webtbs/tw1117.pp svneol=native#text/plain

+ 43 - 16
compiler/aggas.pas

@@ -250,7 +250,7 @@ implementation
 { vtable for a class called Window:                                       }
 { .section .data.rel.ro._ZTV6Window,"awG",@progbits,_ZTV6Window,comdat    }
 {$warning TODO .data.ro not yet working}
-{$if defined(arm) or defined(powerpc)} 
+{$if defined(arm) or defined(powerpc)}
           '.rodata',
 {$else arm}
           '.data',
@@ -258,7 +258,7 @@ implementation
 {$if defined(m68k)} { Amiga/m68k GNU AS doesn't seem to like .rodata (KB) }
           '.data',
 {$else}
-	  '.rodata',
+    '.rodata',
 {$endif}
           '.bss',
           '.threadvar',
@@ -563,6 +563,7 @@ implementation
 
            ait_align :
              begin
+               last_align := tai_align_abstract(hp).aligntype;
                if tai_align_abstract(hp).aligntype>1 then
                  begin
                    if not(target_info.system in systems_darwin) then
@@ -629,27 +630,53 @@ implementation
                        asmwrite(','+tostr(tai_datablock(hp).size));
                        asmwrite(','+tostr(last_align));
                        asmln;
-                     end
+                     end;
                  end
                else
                  begin
-                   { The .comm is required for COMMON symbols. These are used
-                     in the shared library loading. All the symbols declared in
-                     the .so file need to resolve to the data allocated in the main
-                     program (PFV) }
-                   if Tai_datablock(hp).is_global then
+{$ifdef USE_COMM_IN_BSS}
+                   if writingpackages then
                      begin
-                       asmwrite(#9'.comm'#9);
-                       asmwrite(tai_datablock(hp).sym.name);
-                       asmwrite(','+tostr(tai_datablock(hp).size));
-                       asmln;
+                       { The .comm is required for COMMON symbols. These are used
+                         in the shared library loading. All the symbols declared in
+                         the .so file need to resolve to the data allocated in the main
+                         program (PFV) }
+                       if tai_datablock(hp).is_global then
+                         begin
+                           asmwrite(#9'.comm'#9);
+                           asmwrite(tai_datablock(hp).sym.name);
+                           asmwrite(','+tostr(tai_datablock(hp).size));
+                           asmwrite(','+tostr(last_align));
+                           asmln;
+                         end
+                       else
+                         begin
+                           asmwrite(#9'.lcomm'#9);
+                           asmwrite(tai_datablock(hp).sym.name);
+                           asmwrite(','+tostr(tai_datablock(hp).size));
+                           asmwrite(','+tostr(last_align));
+                           asmln;
+                         end
                      end
                    else
+{$endif USE_COMM_IN_BSS}
                      begin
-                       asmwrite(#9'.lcomm'#9);
-                       asmwrite(tai_datablock(hp).sym.name);
-                       asmwrite(','+tostr(tai_datablock(hp).size));
-                       asmln;
+                       if Tai_datablock(hp).is_global then
+                         begin
+                           asmwrite(#9'.globl ');
+                           asmwriteln(Tai_datablock(hp).sym.name);
+                         end;
+                       if (target_info.system <> system_arm_linux) then
+                         sepChar := '@'
+                       else
+                         sepChar := '%';
+                       if (tf_needs_symbol_type in target_info.flags) then
+                         asmwriteln(#9'.type '+Tai_datablock(hp).sym.name+','+sepChar+'object');
+                       if (tf_needs_symbol_size in target_info.flags) and (tai_datablock(hp).size > 0) then
+                         asmwriteln(#9'.size '+Tai_datablock(hp).sym.name+','+tostr(Tai_datablock(hp).size));
+                       asmwrite(Tai_datablock(hp).sym.name);
+                       asmwriteln(':');
+                       asmwriteln(#9'.zero '+tostr(Tai_datablock(hp).size));
                      end;
                  end;
              end;

+ 13 - 3
compiler/assemble.pas

@@ -943,9 +943,12 @@ Implementation
                end;
              ait_datablock :
                begin
-                 if Tai_datablock(hp).is_global then
+{$ifdef USE_COMM_IN_BSS}
+                 if writingpackages and
+                    Tai_datablock(hp).is_global then
                    ObjData.SymbolDefine(Tai_datablock(hp).sym)
                  else
+{$endif USE_COMM_IN_BSS}
                    begin
                      ObjData.allocalign(used_align(size_2_align(Tai_datablock(hp).size),0,ObjData.CurrObjSec.secalign));
                      ObjData.SymbolDefine(Tai_datablock(hp).sym);
@@ -1026,13 +1029,17 @@ Implementation
                begin
                  if (oso_data in ObjData.CurrObjSec.secoptions) then
                    Message(asmw_e_alloc_data_only_in_bss);
-                 if Tai_datablock(hp).is_global then
+{$ifdef USE_COMM_IN_BSS}
+                 if writingpackages and
+                    Tai_datablock(hp).is_global then
                    begin
                      objsym:=ObjData.SymbolDefine(Tai_datablock(hp).sym);
                      objsym.size:=Tai_datablock(hp).size;
                      objsym.bind:=AB_COMMON;
+                     objsym.alignment:=needtowritealignmentalsoforELF;
                    end
                  else
+{$endif USE_COMM_IN_BSS}
                    begin
                      ObjData.allocalign(used_align(size_2_align(Tai_datablock(hp).size),0,ObjData.CurrObjSec.secalign));
                      objsym:=ObjData.SymbolDefine(Tai_datablock(hp).sym);
@@ -1127,7 +1134,10 @@ Implementation
              ait_datablock :
                begin
                  ObjOutput.exportsymbol(ObjData.SymbolRef(Tai_datablock(hp).sym));
-                 if not Tai_datablock(hp).is_global then
+{$ifdef USE_COMM_IN_BSS}
+                 if not(writingpackages and
+                        Tai_datablock(hp).is_global) then
+{$endif USE_COMM_IN_BSS}
                    begin
                      ObjData.allocalign(used_align(size_2_align(Tai_datablock(hp).size),0,ObjData.CurrObjSec.secalign));
                      ObjData.alloc(Tai_datablock(hp).size);

+ 45 - 0
tests/webtbs/tw11039a.pp

@@ -0,0 +1,45 @@
+{ %opt=-Xe }
+{ %target=win32,win64 }
+
+{$packrecords 16}
+{$codealign varmin=16}
+{$codealign localmin=16}
+
+type
+  rec=record
+    v:array[0..511] of byte;
+  end;
+
+var
+  a,b:longword;
+  x:rec;
+  y: longword;
+
+begin
+  a:=b;
+  y:=1;
+  writeln(hexstr(@a));
+  if ptruint(@a) and $f<>0 then
+    begin
+      writeln('ERROR in alignment of a');
+      halt(1);
+    end;
+  writeln(hexstr(@b));
+  if ptruint(@b) and $f<>0 then
+    begin
+      writeln('ERROR in alignment of b');
+      halt(1);
+    end;
+  writeln(hexstr(@x));
+  if ptruint(@x) and $f<>0 then
+    begin
+      writeln('ERROR in alignment of x');
+      halt(1);
+    end;
+  writeln(hexstr(@y));
+  if ptruint(@y) and $f<>0 then
+    begin
+      writeln('ERROR in alignment of y');
+      halt(1);
+    end;
+end.

+ 44 - 0
tests/webtbs/tw11039b.pp

@@ -0,0 +1,44 @@
+{ %opt=-Xe }
+
+{$packrecords 16}
+{$codealign varmin=16}
+{$codealign localmin=16}
+
+type
+  rec=record
+    v:array[0..511] of byte;
+  end;
+
+var
+  a,b:longword;
+  x:rec;
+  y: longword;
+
+begin
+  a:=b;
+  y:=1;
+  writeln(hexstr(@a));
+  if ptruint(@a) and $f<>0 then
+    begin
+      writeln('ERROR in alignment of a');
+      halt(1);
+    end;
+  writeln(hexstr(@b));
+  if ptruint(@b) and $f<>0 then
+    begin
+      writeln('ERROR in alignment of b');
+      halt(1);
+    end;
+  writeln(hexstr(@x));
+  if ptruint(@x) and $f<>0 then
+    begin
+      writeln('ERROR in alignment of x');
+      halt(1);
+    end;
+  writeln(hexstr(@y));
+  if ptruint(@y) and $f<>0 then
+    begin
+      writeln('ERROR in alignment of y');
+      halt(1);
+    end;
+end.