Browse Source

Merged revisions 2827,2831,2837,2932-2980 via svnmerge from
svn+ssh://[email protected]/FPC/svn/fpc/branches/linker/compiler

r2827 (peter)
* smartlinking of resourcestrings


r2831 (peter)
* process_ea 64bit fixes


r2837 (peter)
* linker script

git-svn-id: trunk@2981 -

peter 19 years ago
parent
commit
37c81492ad

+ 2 - 2
compiler/aggas.pas

@@ -232,7 +232,7 @@ implementation
 
 
     function TGNUAssembler.sectionname(atype:TAsmSectiontype;const aname:string):string;
     function TGNUAssembler.sectionname(atype:TAsmSectiontype;const aname:string):string;
       const
       const
-        secnames : array[TAsmSectiontype] of string[13] = ('',
+        secnames : array[TAsmSectiontype] of string[17] = ('',
           '.text',
           '.text',
           '.data',
           '.data',
 {$warning TODO .rodata not yet working}
 {$warning TODO .rodata not yet working}
@@ -248,7 +248,7 @@ implementation
           'fpc.resptrs',
           'fpc.resptrs',
           '.toc'
           '.toc'
         );
         );
-        secnames_pic : array[TAsmSectiontype] of string[13] = ('',
+        secnames_pic : array[TAsmSectiontype] of string[17] = ('',
           '.text',
           '.text',
           '.data.rel',
           '.data.rel',
           '.data.rel',
           '.data.rel',

+ 252 - 231
compiler/cresstr.pas

@@ -25,270 +25,291 @@ unit cresstr;
 
 
 interface
 interface
 
 
-uses
-  cclasses;
-
-Type
-  { These are used to form a singly-linked list, ordered by hash value }
-  TResourceStringItem = class(TLinkedListItem)
-    Name  : String;
-    Value : Pchar;
-    Len   : Longint;
-    hash  : Cardinal;
-    constructor Create(const AName:string;AValue:pchar;ALen:longint);
-    destructor  Destroy;override;
-    procedure CalcHash;
-  end;
-
-  Tresourcestrings=class
-  private
-    List : TLinkedList;
-  public
-    ResStrCount : longint;
-    constructor Create;
-    destructor  Destroy;override;
-    function  Register(Const name : string;p : pchar;len : longint) : longint;
-    procedure CreateResourceStringList;
-    Procedure WriteResourceFile(const FileName : String);
-  end;
-
-var
-  resourcestrings : Tresourcestrings;
+    Procedure GenerateResourceStrings;
 
 
 
 
 implementation
 implementation
 
 
 uses
 uses
+   cclasses,
    cutils,globtype,globals,
    cutils,globtype,globals,
-   symdef,
-   verbose,fmodule,
+   symconst,symtype,symdef,symsym,
+   verbose,fmodule,ppu,
    aasmbase,aasmtai,aasmdata,
    aasmbase,aasmtai,aasmdata,
    aasmcpu;
    aasmcpu;
 
 
+    Type
+      { These are used to form a singly-linked list, ordered by hash value }
+      TResourceStringItem = class(TLinkedListItem)
+        Sym   : TConstSym;
+        Name  : String;
+        Value : Pchar;
+        Len   : Longint;
+        hash  : Cardinal;
+        constructor Create(asym:TConstsym);
+        destructor  Destroy;override;
+        procedure CalcHash;
+      end;
+
+      Tresourcestrings=class
+      private
+        List : TLinkedList;
+        procedure ConstSym_Register(p:tnamedindexitem;arg:pointer);
+      public
+        constructor Create;
+        destructor  Destroy;override;
+        procedure CreateResourceStringData;
+        Procedure WriteResourceFile;
+        procedure RegisterResourceStrings;
+      end;
+
 
 
-{ ---------------------------------------------------------------------
-   Calculate hash value, based on the string
-  ---------------------------------------------------------------------}
 
 
 { ---------------------------------------------------------------------
 { ---------------------------------------------------------------------
                           TRESOURCESTRING_ITEM
                           TRESOURCESTRING_ITEM
   ---------------------------------------------------------------------}
   ---------------------------------------------------------------------}
 
 
-constructor TResourceStringItem.Create(const AName:string;AValue:pchar;ALen:longint);
-begin
-  inherited Create;
-  Name:=AName;
-  Len:=ALen;
-  GetMem(Value,Len);
-  Move(AValue^,Value^,Len);
-  CalcHash;
-end;
-
-
-destructor TResourceStringItem.Destroy;
-begin
-  FreeMem(Value,Len);
-end;
-
-procedure TResourceStringItem.CalcHash;
-Var
-  g : Cardinal;
-  I : longint;
-begin
-  hash:=0;
-  For I:=0 to Len-1 do { 0 terminated }
-   begin
-     hash:=hash shl 4;
-     inc(Hash,Ord(Value[i]));
-     g:=hash and ($f shl 28);
-     if g<>0 then
+    constructor TResourceStringItem.Create(asym:TConstsym);
+      begin
+        inherited Create;
+        Sym:=Asym;
+        Name:=lower(asym.owner.name^+'.'+asym.Name);
+        Len:=asym.value.len;
+        GetMem(Value,Len);
+        Move(asym.value.valueptr^,Value^,Len);
+        CalcHash;
+      end;
+
+
+    destructor TResourceStringItem.Destroy;
+      begin
+        FreeMem(Value);
+      end;
+
+
+    procedure TResourceStringItem.CalcHash;
+      Var
+        g : Cardinal;
+        I : longint;
       begin
       begin
-        hash:=hash xor (g shr 24);
-        hash:=hash xor g;
+        hash:=0;
+        For I:=0 to Len-1 do { 0 terminated }
+         begin
+           hash:=hash shl 4;
+           inc(Hash,Ord(Value[i]));
+           g:=hash and ($f shl 28);
+           if g<>0 then
+            begin
+              hash:=hash xor (g shr 24);
+              hash:=hash xor g;
+            end;
+         end;
+        If Hash=0 then
+          Hash:=$ffffffff;
       end;
       end;
-   end;
-  If Hash=0 then
-    Hash:=$ffffffff;
-end;
 
 
 
 
 { ---------------------------------------------------------------------
 { ---------------------------------------------------------------------
                           Tresourcestrings
                           Tresourcestrings
   ---------------------------------------------------------------------}
   ---------------------------------------------------------------------}
 
 
-Constructor Tresourcestrings.Create;
-begin
-  List:=TStringList.Create;
-  ResStrCount:=0;
-end;
+    Constructor Tresourcestrings.Create;
+      begin
+        List:=TLinkedList.Create;
+      end;
 
 
 
 
-Destructor Tresourcestrings.Destroy;
-begin
-  List.Free;
-end;
+    Destructor Tresourcestrings.Destroy;
+      begin
+        List.Free;
+      end;
 
 
 
 
-{ ---------------------------------------------------------------------
-    Create the full asmlist for resourcestrings.
-  ---------------------------------------------------------------------}
+    procedure Tresourcestrings.CreateResourceStringData;
+      Var
+        namelab,
+        valuelab : tasmlabel;
+        resstrlab : tasmsymbol;
+        s : pchar;
+        l : longint;
+        R : TResourceStringItem;
+      begin
+        { This is only smartlinkable using section smartlinking. Using objects there is
+          no garantuee that  }
+        current_asmdata.asmlists[al_resourcestrings].concat(Tai_cutobject.Create_begin);
+        new_section(current_asmdata.asmlists[al_resourcestrings],sec_data,'resstridx_'+current_module.localsymtable.name^+'_start',sizeof(aint));
+        current_asmdata.AsmLists[al_resourcestrings].concat(tai_symbol.createname_global(
+          make_mangledname('RESSTR',current_module.localsymtable,'START'),AT_DATA,0));
+        R:=TResourceStringItem(List.First);
+        while assigned(R) do
+          begin
+            maybe_new_object_file(current_asmdata.asmlists[al_const]);
+            new_section(current_asmdata.asmlists[al_const],sec_rodata,'resstrdata_'+R.name,sizeof(aint));
+            { Write default value }
+            if assigned(R.value) and (R.len<>0) then
+              begin
+                 current_asmdata.getdatalabel(valuelab);
+                 current_asmdata.asmlists[al_const].concat(tai_align.Create(const_align(sizeof(aint))));
+                 current_asmdata.asmlists[al_const].concat(tai_const.create_aint(-1));
+                 current_asmdata.asmlists[al_const].concat(tai_const.create_aint(R.len));
+                 current_asmdata.asmlists[al_const].concat(tai_label.create(valuelab));
+                 getmem(s,R.len+1);
+                 move(R.value^,s^,R.len);
+                 s[R.len]:=#0;
+                 current_asmdata.asmlists[al_const].concat(tai_string.create_pchar(s,R.len));
+                 current_asmdata.asmlists[al_const].concat(tai_const.create_8bit(0));
+              end
+            else
+              valuelab:=nil;
+            { Append the name as a ansistring. }
+            current_asmdata.getdatalabel(namelab);
+            l:=length(R.name);
+            current_asmdata.asmlists[al_const].concat(tai_align.create(const_align(sizeof(aint))));
+            current_asmdata.asmlists[al_const].concat(tai_const.create_aint(-1));
+            current_asmdata.asmlists[al_const].concat(tai_const.create_aint(l));
+            current_asmdata.asmlists[al_const].concat(tai_label.create(namelab));
+            getmem(s,l+1);
+            move(R.Name[1],s^,l);
+            s[l]:=#0;
+            current_asmdata.asmlists[al_const].concat(tai_string.create_pchar(s,l));
+            current_asmdata.asmlists[al_const].concat(tai_const.create_8bit(0));
+
+            {
+              Resourcestring index:
+                  TResourceStringRecord = Packed Record
+                     Name,
+                     CurrentValue,
+                     DefaultValue : AnsiString;
+                     HashValue    : LongWord;
+                   end;
+            }
+            current_asmdata.asmlists[al_resourcestrings].concat(Tai_cutobject.Create);
+            new_section(current_asmdata.asmlists[al_resourcestrings],sec_data,'resstridx_'+r.name,sizeof(aint));
+            resstrlab:=current_asmdata.newasmsymbol(make_mangledname('RESSTR',R.Sym.owner,R.Sym.name),AB_GLOBAL,AT_DATA);
+            current_asmdata.asmlists[al_resourcestrings].concat(tai_symbol.Create_global(resstrlab,0));
+            current_asmdata.asmlists[al_resourcestrings].concat(tai_const.create_sym(namelab));
+            current_asmdata.asmlists[al_resourcestrings].concat(tai_const.create_sym(nil));
+            current_asmdata.asmlists[al_resourcestrings].concat(tai_const.create_sym(valuelab));
+            current_asmdata.asmlists[al_resourcestrings].concat(tai_const.create_32bit(longint(R.Hash)));
+{$ifdef cpu64bit}
+            current_asmdata.asmlists[al_resourcestrings].concat(tai_const.create_32bit(0));
+{$endif cpu64bit}
+            current_asmdata.asmlists[al_resourcestrings].concat(tai_symbol_end.create(resstrlab));
+            R:=TResourceStringItem(R.Next);
+          end;
+        current_asmdata.asmlists[al_resourcestrings].concat(Tai_cutobject.Create_end);
+        new_section(current_asmdata.asmlists[al_resourcestrings],sec_data,'resstridx_'+current_module.localsymtable.name^+'_end',sizeof(aint));
+        current_asmdata.AsmLists[al_resourcestrings].concat(tai_symbol.createname_global(
+          make_mangledname('RESSTR',current_module.localsymtable,'END'),AT_DATA,0));
+      end;
 
 
-procedure Tresourcestrings.CreateResourceStringList;
-
-  Procedure AppendToAsmResList (P : TResourceStringItem);
-  Var
-    l1 : tasmlabel;
-    s : pchar;
-    l : longint;
-  begin
-    with p Do
-     begin
-       if (Value=nil) or (len=0) then
-         current_asmdata.AsmLists[al_resourcestrings].concat(tai_const.create_sym(nil))
-       else
-         begin
-            current_asmdata.getdatalabel(l1);
-            current_asmdata.AsmLists[al_resourcestrings].concat(tai_const.create_sym(l1));
-            maybe_new_object_file(current_asmdata.AsmLists[al_const]);
-            current_asmdata.AsmLists[al_const].concat(tai_align.Create(const_align(sizeof(aint))));
-            current_asmdata.AsmLists[al_const].concat(tai_const.create_aint(-1));
-            current_asmdata.AsmLists[al_const].concat(tai_const.create_aint(len));
-            current_asmdata.AsmLists[al_const].concat(tai_label.create(l1));
-            getmem(s,len+1);
-            move(value^,s^,len);
-            s[len]:=#0;
-            current_asmdata.AsmLists[al_const].concat(tai_string.create_pchar(s,len));
-            current_asmdata.AsmLists[al_const].concat(tai_const.create_8bit(0));
-         end;
-       { append Current value (nil) and hash...}
-       current_asmdata.AsmLists[al_resourcestrings].concat(tai_const.create_sym(nil));
-       current_asmdata.AsmLists[al_resourcestrings].concat(tai_const.create_32bit(longint(hash)));
-       { Append the name as a ansistring. }
-       current_asmdata.getdatalabel(l1);
-       l:=length(name);
-       current_asmdata.AsmLists[al_resourcestrings].concat(tai_const.create_sym(l1));
-       maybe_new_object_file(current_asmdata.AsmLists[al_const]);
-       current_asmdata.AsmLists[al_const].concat(tai_align.create(const_align(sizeof(aint))));
-       current_asmdata.AsmLists[al_const].concat(tai_const.create_aint(-1));
-       current_asmdata.AsmLists[al_const].concat(tai_const.create_aint(l));
-       current_asmdata.AsmLists[al_const].concat(tai_label.create(l1));
-       getmem(s,l+1);
-       move(Name[1],s^,l);
-       s[l]:=#0;
-       current_asmdata.AsmLists[al_const].concat(tai_string.create_pchar(s,l));
-       current_asmdata.AsmLists[al_const].concat(tai_const.create_8bit(0));
-     end;
-  end;
-
-Var
-  R : tresourceStringItem;
-begin
-  if current_asmdata.AsmLists[al_resourcestrings]=nil then
-    current_asmdata.AsmLists[al_resourcestrings]:=tasmlist.create;
-  maybe_new_object_file(current_asmdata.AsmLists[al_resourcestrings]);
-  new_section(current_asmdata.AsmLists[al_resourcestrings],sec_data,'',4);
-  current_asmdata.AsmLists[al_resourcestrings].concat(tai_align.create(const_align(sizeof(aint))));
-  current_asmdata.AsmLists[al_resourcestrings].concat(tai_symbol.createname_global(
-    make_mangledname('RESOURCESTRINGLIST',current_module.localsymtable,''),AT_DATA,0));
-  current_asmdata.AsmLists[al_resourcestrings].concat(tai_const.create_32bit(resstrcount));
-  R:=TResourceStringItem(List.First);
-  while assigned(R) do
-   begin
-     AppendToAsmResList(R);
-     R:=TResourceStringItem(R.Next);
-   end;
-  current_asmdata.AsmLists[al_resourcestrings].concat(tai_symbol_end.createname(
-    make_mangledname('RESOURCESTRINGLIST',current_module.localsymtable,'')));
-end;
 
 
+    Procedure Tresourcestrings.WriteResourceFile;
+      Type
+        TMode = (quoted,unquoted);
+      Var
+        F : Text;
+        Mode : TMode;
+        R : TResourceStringItem;
+        C : char;
+        Col,i : longint;
+        ResFileName : string;
 
 
-{ ---------------------------------------------------------------------
-    Insert 1 resource string in all tables.
-  ---------------------------------------------------------------------}
+        Procedure Add(Const S : String);
+        begin
+          Write(F,S);
+          inc(Col,length(s));
+        end;
 
 
-function  Tresourcestrings.Register(const name : string;p : pchar;len : longint) : longint;
-begin
-  List.Concat(tResourceStringItem.Create(lower(current_module.modulename^+'.'+Name),p,len));
-  Register:=ResStrCount;
-  inc(ResStrCount);
-end;
-
-
-Procedure Tresourcestrings.WriteResourceFile(const FileName : String);
-Type
-  TMode = (quoted,unquoted);
-Var
-  F : Text;
-  Mode : TMode;
-  R : TResourceStringItem;
-  C : char;
-  Col,i : longint;
-
-  Procedure Add(Const S : String);
-  begin
-    Write(F,S);
-    Col:=Col+length(s);
-  end;
-
-begin
-  If List.Empty then
-    exit;
-  message1 (general_i_writingresourcefile,SplitFileName(filename));
-  Assign(F,Filename);
-  {$i-}
-  Rewrite(f);
-  {$i+}
-  If IOresult<>0 then
-    begin
-      message1(general_e_errorwritingresourcefile,filename);
-      exit;
-    end;
-  R:=TResourceStringItem(List.First);
-  While assigned(R) do
-   begin
-     writeln(f);
-     Writeln(f,'# hash value = ',R.hash);
-     col:=0;
-     Add(R.Name+'=');
-     Mode:=unquoted;
-     For I:=0 to R.Len-1 do
       begin
       begin
-        C:=R.Value[i];
-        If (ord(C)>31) and (Ord(c)<=128) and (c<>'''') then
-         begin
-           If mode=Quoted then
-            Add(c)
-           else
-            begin
-              Add(''''+c);
-              mode:=quoted
-            end;
-         end
-        else
-         begin
-           If Mode=quoted then
-            begin
-              Add('''');
-              mode:=unquoted;
-            end;
-           Add('#'+tostr(ord(c)));
-         end;
-        If Col>72 then
-         begin
-           if mode=quoted then
-            Write (F,'''');
-           Writeln(F,'+');
-           Col:=0;
-           Mode:=unQuoted;
-         end;
+        ResFileName:=ForceExtension(current_module.ppufilename^,'.rst');
+        message1 (general_i_writingresourcefile,SplitFileName(ResFileName));
+        Assign(F,ResFileName);
+        {$i-}
+        Rewrite(f);
+        {$i+}
+        If IOresult<>0 then
+          begin
+            message1(general_e_errorwritingresourcefile,ResFileName);
+            exit;
+          end;
+        R:=TResourceStringItem(List.First);
+        while assigned(R) do
+          begin
+            writeln(f);
+            Writeln(f,'# hash value = ',R.Hash);
+            col:=0;
+            Add(R.Name+'=');
+            Mode:=unquoted;
+            For I:=0 to R.Len-1 do
+             begin
+               C:=R.Value[i];
+               If (ord(C)>31) and (Ord(c)<=128) and (c<>'''') then
+                begin
+                  If mode=Quoted then
+                   Add(c)
+                  else
+                   begin
+                     Add(''''+c);
+                     mode:=quoted
+                   end;
+                end
+               else
+                begin
+                  If Mode=quoted then
+                   begin
+                     Add('''');
+                     mode:=unquoted;
+                   end;
+                  Add('#'+tostr(ord(c)));
+                end;
+               If Col>72 then
+                begin
+                  if mode=quoted then
+                   Write (F,'''');
+                  Writeln(F,'+');
+                  Col:=0;
+                  Mode:=unQuoted;
+                end;
+             end;
+            if mode=quoted then
+             writeln (f,'''');
+            Writeln(f);
+            R:=TResourceStringItem(R.Next);
+          end;
+        close(f);
+      end;
+
+
+    procedure Tresourcestrings.ConstSym_Register(p:tnamedindexitem;arg:pointer);
+      begin
+        if (tsym(p).typ=constsym) and
+           (tconstsym(p).consttyp=constresourcestring) then
+          List.Concat(tResourceStringItem.Create(TConstsym(p)));
+      end;
+
+
+    procedure Tresourcestrings.RegisterResourceStrings;
+      begin
+        if assigned(current_module.globalsymtable) then
+          current_module.globalsymtable.foreach(@ConstSym_Register,nil);
+        current_module.localsymtable.foreach(@ConstSym_Register,nil);
       end;
       end;
-     if mode=quoted then
-      writeln (f,'''');
-     Writeln(f);
-     R:=TResourceStringItem(R.Next);
-   end;
-  close(f);
-end;
 
 
 
 
+    Procedure GenerateResourceStrings;
+      var
+        resstrs : Tresourcestrings;
+      begin
+        resstrs:=Tresourcestrings.Create;
+        resstrs.RegisterResourceStrings;
+        if not resstrs.List.Empty then
+          begin
+            current_module.flags:=current_module.flags or uf_has_resourcestrings;
+            resstrs.CreateResourceStringData;
+            resstrs.WriteResourceFile;
+          end;
+        resstrs.Free;
+      end;
+
 end.
 end.

+ 4 - 4
compiler/globals.pas

@@ -356,10 +356,10 @@ interface
 
 
     {# Routine to get the required alignment for size of data, which will
     {# Routine to get the required alignment for size of data, which will
        be placed in bss segment, according to the current alignment requirements }
        be placed in bss segment, according to the current alignment requirements }
-    function var_align(siz: longint): longint;
+    function var_align(siz: shortint): shortint;
     {# Routine to get the required alignment for size of data, which will
     {# Routine to get the required alignment for size of data, which will
        be placed in data/const segment, according to the current alignment requirements }
        be placed in data/const segment, according to the current alignment requirements }
-    function const_align(siz: longint): longint;
+    function const_align(siz: shortint): shortint;
 
 
 {$IFDEF MACOS_USE_FAKE_SYSUTILS}
 {$IFDEF MACOS_USE_FAKE_SYSUTILS}
 
 
@@ -2107,14 +2107,14 @@ end;
       end;
       end;
 
 
 
 
-    function var_align(siz: longint): longint;
+    function var_align(siz: shortint): shortint;
       begin
       begin
         siz := size_2_align(siz);
         siz := size_2_align(siz);
         var_align := used_align(siz,aktalignment.varalignmin,aktalignment.varalignmax);
         var_align := used_align(siz,aktalignment.varalignmin,aktalignment.varalignmax);
       end;
       end;
 
 
 
 
-    function const_align(siz: longint): longint;
+    function const_align(siz: shortint): shortint;
       begin
       begin
         siz := size_2_align(siz);
         siz := size_2_align(siz);
         const_align := used_align(siz,aktalignment.constalignmin,aktalignment.constalignmax);
         const_align := used_align(siz,aktalignment.constalignmin,aktalignment.constalignmax);

+ 4 - 5
compiler/i386/ag386nsm.pas

@@ -99,7 +99,7 @@ interface
     function single2str(d : single) : string;
     function single2str(d : single) : string;
       var
       var
          hs : string;
          hs : string;
-         p : byte;
+         p : longint;
       begin
       begin
          str(d,hs);
          str(d,hs);
       { nasm expects a lowercase e }
       { nasm expects a lowercase e }
@@ -115,7 +115,7 @@ interface
     function double2str(d : double) : string;
     function double2str(d : double) : string;
       var
       var
          hs : string;
          hs : string;
-         p : byte;
+         p : longint;
       begin
       begin
          str(d,hs);
          str(d,hs);
       { nasm expects a lowercase e }
       { nasm expects a lowercase e }
@@ -131,7 +131,7 @@ interface
     function extended2str(e : extended) : string;
     function extended2str(e : extended) : string;
       var
       var
          hs : string;
          hs : string;
-         p : byte;
+         p : longint;
       begin
       begin
          str(e,hs);
          str(e,hs);
       { nasm expects a lowercase e }
       { nasm expects a lowercase e }
@@ -354,7 +354,7 @@ interface
 
 
     procedure T386NasmAssembler.WriteSection(atype:TAsmSectiontype;const aname:string);
     procedure T386NasmAssembler.WriteSection(atype:TAsmSectiontype;const aname:string);
       const
       const
-        secnames : array[TAsmSectiontype] of string[13] = ('',
+        secnames : array[TAsmSectiontype] of string[17] = ('',
           '.text',
           '.text',
           '.data',
           '.data',
           '.rodata',
           '.rodata',
@@ -394,7 +394,6 @@ interface
       i,j,l    : longint;
       i,j,l    : longint;
       InlineLevel : longint;
       InlineLevel : longint;
       consttype : taiconst_type;
       consttype : taiconst_type;
-      found,
       do_line,
       do_line,
       quoted   : boolean;
       quoted   : boolean;
     begin
     begin

+ 2 - 1
compiler/link.pas

@@ -901,6 +901,8 @@ end;
             else
             else
               Comment(V_Error,'DLL not found: '+s);
               Comment(V_Error,'DLL not found: '+s);
           end;
           end;
+        { Fill external symbols data }
+        exeoutput.FixupSymbols;
         if ErrorCount>0 then
         if ErrorCount>0 then
           goto myexit;
           goto myexit;
 
 
@@ -913,7 +915,6 @@ end;
 
 
         { Calc positions in mem and file }
         { Calc positions in mem and file }
         ParseScript_CalcPos;
         ParseScript_CalcPos;
-        exeoutput.FixupSymbols;
         exeoutput.FixupRelocations;
         exeoutput.FixupRelocations;
         exeoutput.PrintMemoryMap;
         exeoutput.PrintMemoryMap;
         if ErrorCount>0 then
         if ErrorCount>0 then

+ 10 - 4
compiler/m68k/cgcpu.pas

@@ -125,6 +125,7 @@ unit cgcpu;
       topcg2tasmop: Array[topcg] of tasmop =
       topcg2tasmop: Array[topcg] of tasmop =
       (
       (
        A_NONE,
        A_NONE,
+       A_MOVE,
        A_ADD,
        A_ADD,
        A_AND,
        A_AND,
        A_DIVU,
        A_DIVU,
@@ -404,13 +405,18 @@ unit cgcpu;
        opcode : tasmop;
        opcode : tasmop;
        r,r2 : Tregister;
        r,r2 : Tregister;
       begin
       begin
-        optimize_op_const_reg(list, op, a, reg);
+        optimize_op_const(op, a);
         opcode := topcg2tasmop[op];
         opcode := topcg2tasmop[op];
         case op of
         case op of
           OP_NONE :
           OP_NONE :
-              begin
-                { Opcode is optimized away }
-              end;
+            begin
+              { Opcode is optimized away }
+            end;
+          OP_MOVE :
+            begin
+              { Optimized, replaced with a simple load }
+              a_load_const_reg(list,size,a,reg);
+            end;
           OP_ADD :
           OP_ADD :
               begin
               begin
                 if (a >= 1) and (a <= 8) then
                 if (a >= 1) and (a <= 8) then

+ 10 - 2
compiler/ncgld.pas

@@ -115,8 +115,16 @@ implementation
                  if tconstsym(symtableentry).consttyp=constresourcestring then
                  if tconstsym(symtableentry).consttyp=constresourcestring then
                    begin
                    begin
                       location_reset(location,LOC_CREFERENCE,OS_ADDR);
                       location_reset(location,LOC_CREFERENCE,OS_ADDR);
-                      location.reference.symbol:=current_asmdata.newasmsymbol(make_mangledname('RESOURCESTRINGLIST',tconstsym(symtableentry).owner,''),AB_EXTERNAL,AT_DATA);
-                      location.reference.offset:=tconstsym(symtableentry).resstrindex*(4+sizeof(aint)*3)+4+sizeof(aint);
+                      location.reference.symbol:=current_asmdata.newasmsymbol(make_mangledname('RESSTR',symtableentry.owner,symtableentry.name),AB_EXTERNAL,AT_DATA);
+                      { Resourcestring layout:
+                          TResourceStringRecord = Packed Record
+                             Name,
+                             CurrentValue,
+                             DefaultValue : AnsiString;
+                             HashValue    : LongWord;
+                           end;
+                      }
+                      location.reference.offset:=sizeof(aint);
                    end
                    end
                  else
                  else
                    internalerror(22798);
                    internalerror(22798);

+ 2 - 2
compiler/ogbase.pas

@@ -663,7 +663,7 @@ implementation
 
 
     function TObjData.sectionname(atype:TAsmSectiontype;const aname:string):string;
     function TObjData.sectionname(atype:TAsmSectiontype;const aname:string):string;
       const
       const
-        secnames : array[TAsmSectiontype] of string[13] = ('',
+        secnames : array[TAsmSectiontype] of string[16] = ('',
           'code',
           'code',
           'data',
           'data',
           'rodata',
           'rodata',
@@ -690,7 +690,7 @@ implementation
         secoptions : array[TAsmSectiontype] of TObjSectionOptions = ([],
         secoptions : array[TAsmSectiontype] of TObjSectionOptions = ([],
           {code} [oso_data,oso_load,oso_readonly,oso_executable,oso_keep],
           {code} [oso_data,oso_load,oso_readonly,oso_executable,oso_keep],
           {data} [oso_data,oso_load,oso_write,oso_keep],
           {data} [oso_data,oso_load,oso_write,oso_keep],
-{$warning TODO Fix rodata be really read-only}
+{$warning TODO Fix rodata be read-only}
           {rodata} [oso_data,oso_load,oso_write,oso_keep],
           {rodata} [oso_data,oso_load,oso_write,oso_keep],
           {bss} [oso_load,oso_write,oso_keep],
           {bss} [oso_load,oso_write,oso_keep],
           {threadvar} [oso_load,oso_write],
           {threadvar} [oso_load,oso_write],

+ 3 - 3
compiler/ogcoff.pas

@@ -97,7 +97,7 @@ interface
          function writedata(data:TObjData):boolean;override;
          function writedata(data:TObjData):boolean;override;
        public
        public
          constructor createcoff(AWriter:TObjectWriter;awin32:boolean);
          constructor createcoff(AWriter:TObjectWriter;awin32:boolean);
-         destructor destroy;
+         destructor destroy;override;
        end;
        end;
 
 
        TDJCoffObjOutput = class(TCoffObjOutput)
        TDJCoffObjOutput = class(TCoffObjOutput)
@@ -423,7 +423,7 @@ implementation
        symbolresize = 200*sizeof(coffsymbol);
        symbolresize = 200*sizeof(coffsymbol);
        strsresize   = 8192;
        strsresize   = 8192;
 
 
-       coffsecnames : array[TAsmSectiontype] of string[16] = ('',
+       coffsecnames : array[TAsmSectiontype] of string[17] = ('',
           '.text','.data','.data','.bss','.tls',
           '.text','.data','.data','.bss','.tls',
           '.text',
           '.text',
           '.stab','.stabstr',
           '.stab','.stabstr',
@@ -431,7 +431,7 @@ implementation
           '.eh_frame',
           '.eh_frame',
           '.debug_frame','.debug_info','.debug_line','.debug_abbrev',
           '.debug_frame','.debug_info','.debug_line','.debug_abbrev',
           '.fpc',
           '.fpc',
-                  ''
+          ''
         );
         );
 
 
 const go32v2stub : array[0..2047] of byte=(
 const go32v2stub : array[0..2047] of byte=(

+ 6 - 0
compiler/options.pas

@@ -1869,6 +1869,7 @@ begin
   def_system_macro('FPC_DARWIN_JMP_MAIN');
   def_system_macro('FPC_DARWIN_JMP_MAIN');
   def_system_macro('COMPPROCINLINEFIXED');
   def_system_macro('COMPPROCINLINEFIXED');
   def_system_macro('PARAOUTFILE');
   def_system_macro('PARAOUTFILE');
+  def_system_macro('RESSTRSECTIONS');
 
 
   if pocall_default = pocall_register then
   if pocall_default = pocall_register then
     def_system_macro('REGCALL');
     def_system_macro('REGCALL');
@@ -2180,6 +2181,11 @@ begin
      Message1(option_asm_forced,target_asm.idtxt);
      Message1(option_asm_forced,target_asm.idtxt);
    end;
    end;
 
 
+  { disable internal linker if it is not registered }
+  if not assigned(target_info.link) and
+     (cs_link_internal in initglobalswitches) then
+    exclude(initglobalswitches,cs_link_internal);
+
   { turn off stripping if compiling with debuginfo or profile }
   { turn off stripping if compiling with debuginfo or profile }
   if (cs_debuginfo in initmoduleswitches) or
   if (cs_debuginfo in initmoduleswitches) or
      (cs_profile in initmoduleswitches) then
      (cs_profile in initmoduleswitches) then

+ 0 - 9
compiler/parser.pas

@@ -270,8 +270,6 @@ implementation
           oldaktprocsym    : tprocsym;
           oldaktprocsym    : tprocsym;
         { cg }
         { cg }
           oldparse_only  : boolean;
           oldparse_only  : boolean;
-        { al_resourcestrings }
-          Oldresourcestrings : tresourcestrings;
         { akt.. things }
         { akt.. things }
           oldaktlocalswitches  : tlocalswitches;
           oldaktlocalswitches  : tlocalswitches;
           oldaktmoduleswitches : tmoduleswitches;
           oldaktmoduleswitches : tmoduleswitches;
@@ -321,7 +319,6 @@ implementation
             oldsourcecodepage:=aktsourcecodepage;
             oldsourcecodepage:=aktsourcecodepage;
           { save cg }
           { save cg }
             oldparse_only:=parse_only;
             oldparse_only:=parse_only;
-            Oldresourcestrings:=resourcestrings;
           { save akt... state }
           { save akt... state }
           { handle the postponed case first }
           { handle the postponed case first }
            if localswitcheschanged then
            if localswitcheschanged then
@@ -399,8 +396,6 @@ implementation
          aktasmmode:=initasmmode;
          aktasmmode:=initasmmode;
          aktinterfacetype:=initinterfacetype;
          aktinterfacetype:=initinterfacetype;
 
 
-         resourcestrings:=Tresourcestrings.Create;
-
          { load current asmdata from current_module }
          { load current asmdata from current_module }
          current_asmdata:=TAsmData(current_module.asmdata);
          current_asmdata:=TAsmData(current_module.asmdata);
 
 
@@ -452,9 +447,6 @@ implementation
                    tppumodule(current_module).ppufile:=nil;
                    tppumodule(current_module).ppufile:=nil;
                  end;
                  end;
 
 
-               resourcestrings.free;
-               resourcestrings:=nil;
-
                { free asmdata }
                { free asmdata }
                if assigned(current_module.asmdata) then
                if assigned(current_module.asmdata) then
                  begin
                  begin
@@ -496,7 +488,6 @@ implementation
                 block_type:=old_block_type;
                 block_type:=old_block_type;
                 { restore cg }
                 { restore cg }
                 parse_only:=oldparse_only;
                 parse_only:=oldparse_only;
-                resourcestrings:=oldresourcestrings;
                 { asm data }
                 { asm data }
                 if assigned(old_compiled_module) then
                 if assigned(old_compiled_module) then
                   current_asmdata:=tasmdata(old_compiled_module.asmdata)
                   current_asmdata:=tasmdata(old_compiled_module.asmdata)

+ 30 - 47
compiler/pmodules.pas

@@ -155,6 +155,8 @@ implementation
         ltvTables : TAsmList;
         ltvTables : TAsmList;
         count : longint;
         count : longint;
       begin
       begin
+        if (tf_section_threadvars in target_info.flags) then
+          exit;
         ltvTables:=TAsmList.Create;
         ltvTables:=TAsmList.Create;
         count:=0;
         count:=0;
         hp:=tused_unit(usedunits.first);
         hp:=tused_unit(usedunits.first);
@@ -205,6 +207,8 @@ implementation
         s : string;
         s : string;
         ltvTable : TAsmList;
         ltvTable : TAsmList;
       begin
       begin
+         if (tf_section_threadvars in target_info.flags) then
+           exit;
          ltvTable:=TAsmList.create;
          ltvTable:=TAsmList.create;
          if assigned(current_module.globalsymtable) then
          if assigned(current_module.globalsymtable) then
            current_module.globalsymtable.foreach_static(@AddToThreadvarList,ltvTable);
            current_module.globalsymtable.foreach_static(@AddToThreadvarList,ltvTable);
@@ -273,32 +277,28 @@ implementation
         end;
         end;
     end;
     end;
 
 
+
     Procedure InsertResourceTablesTable;
     Procedure InsertResourceTablesTable;
       var
       var
-        hp : tused_unit;
+        hp : tmodule;
         ResourceStringTables : tasmlist;
         ResourceStringTables : tasmlist;
         count : longint;
         count : longint;
       begin
       begin
         ResourceStringTables:=tasmlist.Create;
         ResourceStringTables:=tasmlist.Create;
         count:=0;
         count:=0;
-        hp:=tused_unit(usedunits.first);
+        hp:=tmodule(loaded_units.first);
         while assigned(hp) do
         while assigned(hp) do
-         begin
-           If (hp.u.flags and uf_has_resources)=uf_has_resources then
-            begin
-              ResourceStringTables.concat(Tai_const.Createname(make_mangledname('RESOURCESTRINGLIST',hp.u.globalsymtable,''),AT_DATA,0));
-              inc(count);
-            end;
-           hp:=tused_unit(hp.next);
-         end;
-        { Add program resources, if any }
-        If resourcestrings.ResStrCount>0 then
-         begin
-           ResourceStringTables.concat(Tai_const.Createname(make_mangledname('RESOURCESTRINGLIST',current_module.localsymtable,''),AT_DATA,0));
-           Inc(Count);
-         end;
+          begin
+            If (hp.flags and uf_has_resourcestrings)=uf_has_resourcestrings then
+              begin
+                ResourceStringTables.concat(Tai_const.Createname(make_mangledname('RESSTR',hp.localsymtable,'START'),AT_DATA,0));
+                ResourceStringTables.concat(Tai_const.Createname(make_mangledname('RESSTR',hp.localsymtable,'END'),AT_DATA,0));
+                inc(count);
+              end;
+            hp:=tmodule(hp.next);
+          end;
         { Insert TableCount at start }
         { Insert TableCount at start }
-        ResourceStringTables.insert(Tai_const.Create_32bit(count));
+        ResourceStringTables.insert(Tai_const.Create_aint(count));
         { Add to data segment }
         { Add to data segment }
         maybe_new_object_file(current_asmdata.AsmLists[al_globals]);
         maybe_new_object_file(current_asmdata.AsmLists[al_globals]);
         new_section(current_asmdata.AsmLists[al_globals],sec_data,'FPC_RESOURCESTRINGTABLES',sizeof(aint));
         new_section(current_asmdata.AsmLists[al_globals],sec_data,'FPC_RESOURCESTRINGTABLES',sizeof(aint));
@@ -1048,16 +1048,6 @@ implementation
          { the last char should always be a point }
          { the last char should always be a point }
          consume(_POINT);
          consume(_POINT);
 
 
-         { Generate resoucestrings }
-         If resourcestrings.ResStrCount>0 then
-          begin
-            resourcestrings.CreateResourceStringList;
-            current_module.flags:=current_module.flags or uf_has_resources;
-            { only write if no errors found }
-            if (Errorcount=0) then
-             resourcestrings.WriteResourceFile(ForceExtension(current_module.ppufilename^,'.rst'));
-          end;
-
          if (Errorcount=0) then
          if (Errorcount=0) then
            begin
            begin
              { tests, if all (interface) forwards are resolved }
              { tests, if all (interface) forwards are resolved }
@@ -1100,9 +1090,11 @@ implementation
          { generate pic helpers to load eip if necessary }
          { generate pic helpers to load eip if necessary }
          gen_pic_helpers(current_asmdata.asmlists[al_procedures]);
          gen_pic_helpers(current_asmdata.asmlists[al_procedures]);
 
 
-         { generate a list of threadvars }
-         if not(tf_section_threadvars in target_info.flags) then
-           InsertThreadvars;
+         { Tables }
+         insertThreadVars;
+
+         { Resource strings }
+         GenerateResourceStrings;
 
 
          { generate imports }
          { generate imports }
          if current_module.uses_imports then
          if current_module.uses_imports then
@@ -1330,14 +1322,6 @@ implementation
             ((current_module.flags and uf_has_exports)<>0) then
             ((current_module.flags and uf_has_exports)<>0) then
            current_asmdata.asmlists[al_procedures].concat(tai_const.create_sym(exportlib.edatalabel));
            current_asmdata.asmlists[al_procedures].concat(tai_const.create_sym(exportlib.edatalabel));
 
 
-         If resourcestrings.ResStrCount>0 then
-          begin
-            resourcestrings.CreateResourceStringList;
-            { only write if no errors found }
-            if (Errorcount=0) then
-             resourcestrings.WriteResourceFile(ForceExtension(current_module.ppufilename^,'.rst'));
-          end;
-
          { finalize? }
          { finalize? }
          if token=_FINALIZATION then
          if token=_FINALIZATION then
            begin
            begin
@@ -1397,16 +1381,14 @@ implementation
          if (cs_debuginfo in aktmoduleswitches) then
          if (cs_debuginfo in aktmoduleswitches) then
            debuginfo.inserttypeinfo;
            debuginfo.inserttypeinfo;
 
 
+         InsertThreadvars;
+
          { generate wrappers for interfaces }
          { generate wrappers for interfaces }
          gen_intf_wrappers(current_asmdata.asmlists[al_procedures],current_module.localsymtable);
          gen_intf_wrappers(current_asmdata.asmlists[al_procedures],current_module.localsymtable);
 
 
          { generate pic helpers to load eip if necessary }
          { generate pic helpers to load eip if necessary }
          gen_pic_helpers(current_asmdata.asmlists[al_procedures]);
          gen_pic_helpers(current_asmdata.asmlists[al_procedures]);
 
 
-         { generate a list of threadvars }
-         if not(tf_section_threadvars in target_info.flags) then
-           InsertThreadvars;
-
          { generate imports }
          { generate imports }
          if current_module.uses_imports then
          if current_module.uses_imports then
            importlib.generatelib;
            importlib.generatelib;
@@ -1414,15 +1396,16 @@ implementation
          if islibrary or (target_info.system in system_unit_program_exports) then
          if islibrary or (target_info.system in system_unit_program_exports) then
            exportlib.generatelib;
            exportlib.generatelib;
 
 
-         { insert Tables and StackLength }
-         if not(tf_section_threadvars in target_info.flags) then
-           insertThreadVarTablesTable;
+         { Resource strings }
+         GenerateResourceStrings;
 
 
-         insertResourceTablesTable;
+         { insert Tables and StackLength }
          insertinitfinaltable;
          insertinitfinaltable;
+         InsertThreadvarTablesTable;
+         InsertResourceTablesTable;
          insertmemorysizes;
          insertmemorysizes;
-         { Insert symbol to resource info }
 
 
+         { Insert symbol to resource info }
          InsertResourceInfo;
          InsertResourceInfo;
 
 
          { create dwarf debuginfo }
          { create dwarf debuginfo }

+ 1 - 1
compiler/ppu.pas

@@ -137,7 +137,7 @@ const
   uf_local_browser = $200;
   uf_local_browser = $200;
   uf_no_link       = $400;    { unit has no .o generated, but can still have
   uf_no_link       = $400;    { unit has no .o generated, but can still have
                                 external linking! }
                                 external linking! }
-  uf_has_resources = $800;    { unit has resource string section }
+  uf_has_resourcestrings = $800;    { unit has resource string section }
   uf_little_endian = $1000;
   uf_little_endian = $1000;
   uf_release       = $2000;   { unit was compiled with -Ur option }
   uf_release       = $2000;   { unit was compiled with -Ur option }
   uf_threadvars    = $4000;   { unit has threadvars }
   uf_threadvars    = $4000;   { unit has threadvars }

+ 2 - 3
compiler/ptconst.pas

@@ -62,8 +62,8 @@ implementation
       var
       var
          len,base  : longint;
          len,base  : longint;
          p,hp      : tnode;
          p,hp      : tnode;
-         i,j,l,
-         varalign  : longint;
+         i,j,l     : longint;
+         varalign  : shortint;
          offset,
          offset,
          strlength : aint;
          strlength : aint;
          ll        : tasmlabel;
          ll        : tasmlabel;
@@ -85,7 +85,6 @@ implementation
          storefilepos : tfileposinfo;
          storefilepos : tfileposinfo;
          cursectype : TAsmSectiontype;
          cursectype : TAsmSectiontype;
          cural : tasmlisttype;
          cural : tasmlisttype;
-         sizelabel : tasmlabel;
 
 
          procedure check_range(def:torddef);
          procedure check_range(def:torddef);
            begin
            begin

+ 1 - 3
compiler/symsym.pas

@@ -369,7 +369,7 @@ implementation
        { aasm }
        { aasm }
        aasmtai,aasmdata,
        aasmtai,aasmdata,
        { codegen }
        { codegen }
-       paramgr,cresstr,
+       paramgr,
        procinfo
        procinfo
        ;
        ;
 
 
@@ -1837,8 +1837,6 @@ implementation
          value.valueptr:=str;
          value.valueptr:=str;
          consttype.reset;
          consttype.reset;
          value.len:=l;
          value.len:=l;
-         if t=constresourcestring then
-           ResStrIndex:=resourcestrings.Register(name,pchar(value.valueptr),value.len);
       end;
       end;
 
 
 
 

+ 204 - 200
compiler/systems/t_linux.pas

@@ -323,7 +323,7 @@ Var
   found2,
   found2,
   linklibc     : boolean;
   linklibc     : boolean;
 begin
 begin
-  WriteResponseFile:=False;
+  result:=False;
 { set special options for some targets }
 { set special options for some targets }
   linklibc:=(SharedLibFiles.Find('c')<>nil);
   linklibc:=(SharedLibFiles.Find('c')<>nil);
   if isdll then
   if isdll then
@@ -367,205 +367,207 @@ begin
 
 
   { Open link.res file }
   { Open link.res file }
   LinkRes:=TLinkRes.Create(outputexedir+Info.ResName);
   LinkRes:=TLinkRes.Create(outputexedir+Info.ResName);
-
-  { Write path to search libraries }
-  HPath:=TStringListItem(current_module.locallibrarysearchpath.First);
-  while assigned(HPath) do
-   begin
-     LinkRes.Add('SEARCH_DIR('+maybequoted(HPath.Str)+')');
-     HPath:=TStringListItem(HPath.Next);
-   end;
-  HPath:=TStringListItem(LibrarySearchPath.First);
-  while assigned(HPath) do
-   begin
-     LinkRes.Add('SEARCH_DIR('+maybequoted(HPath.Str)+')');
-     HPath:=TStringListItem(HPath.Next);
-   end;
-
-  LinkRes.Add('INPUT(');
-  { add objectfiles, start with prt0 always }
-  if prtobj<>'' then
-   LinkRes.AddFileName(maybequoted(FindObjectFile(prtobj,'',false)));
-  { try to add crti and crtbegin if linking to C }
-  if linklibc then
-   begin
-     if librarysearchpath.FindFile('crtbegin.o',s) then
-      LinkRes.AddFileName(s);
-     if librarysearchpath.FindFile('crti.o',s) then
-      LinkRes.AddFileName(s);
-   end;
-  { main objectfiles }
-  while not ObjectFiles.Empty do
-   begin
-     s:=ObjectFiles.GetFirst;
-     if s<>'' then
-      LinkRes.AddFileName(maybequoted(s));
-   end;
-  LinkRes.Add(')');
-
-  { Write staticlibraries }
-  if not StaticLibFiles.Empty then
-   begin
-     LinkRes.Add('GROUP(');
-     While not StaticLibFiles.Empty do
-      begin
-        S:=StaticLibFiles.GetFirst;
-        LinkRes.AddFileName(maybequoted(s))
-      end;
-     LinkRes.Add(')');
-   end;
-
-  { Write sharedlibraries like -l<lib>, also add the needed dynamic linker
-    here to be sure that it gets linked this is needed for glibc2 systems (PFV) }
-  if not SharedLibFiles.Empty then
-   begin
-     LinkRes.Add('INPUT(');
-     While not SharedLibFiles.Empty do
-      begin
-        S:=SharedLibFiles.GetFirst;
-        if s<>'c' then
-         begin
-           i:=Pos(target_info.sharedlibext,S);
-           if i>0 then
-            Delete(S,i,255);
-           LinkRes.Add('-l'+s);
-         end
-        else
-         begin
-           linklibc:=true;
-         end;
-      end;
-     { be sure that libc is the last lib }
-     if linklibc then
-      LinkRes.Add('-lc');
-     { when we have -static for the linker the we also need libgcc }
-     if (cs_link_staticflag in aktglobalswitches) then
-      LinkRes.Add('-lgcc');
-     LinkRes.Add(')');
-   end;
-
-  { objects which must be at the end }
-  if linklibc and (libctype<>uclibc) then
-   begin
-     found1:=librarysearchpath.FindFile('crtend.o',s1);
-     found2:=librarysearchpath.FindFile('crtn.o',s2);
-     if found1 or found2 then
-      begin
-        LinkRes.Add('INPUT(');
-        if found1 then
-         LinkRes.AddFileName(s1);
-        if found2 then
-         LinkRes.AddFileName(s2);
-        LinkRes.Add(')');
-      end;
-   end;
-  {Entry point.}
-  linkres.add('ENTRY(_start)');
-
-  {Sections.}
-{$ifdef OwnLDScript}
-  commented out because it cause problems on several machines with different ld versions (FK)
-  linkres.add('SECTIONS');
-  linkres.add('{');
-  {Read-only sections, merged into text segment:}
-  linkres.add('  PROVIDE (__executable_start = 0x010000); . = 0x010000 +0x100;');
-  linkres.add('  .interp         : { *(.interp) }');
-  linkres.add('  .hash           : { *(.hash) }');
-  linkres.add('  .dynsym         : { *(.dynsym) }');
-  linkres.add('  .dynstr         : { *(.dynstr) }');
-  linkres.add('  .gnu.version    : { *(.gnu.version) }');
-  linkres.add('  .gnu.version_d  : { *(.gnu.version_d) }');
-  linkres.add('  .gnu.version_r  : { *(.gnu.version_r) }');
-  linkres.add('  .rel.dyn        :');
-  linkres.add('    {');
-  linkres.add('      *(.rel.init)');
-  linkres.add('      *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*)');
-  linkres.add('      *(.rel.fini)');
-  linkres.add('      *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*)');
-  linkres.add('      *(.rel.data.rel.ro*)');
-  linkres.add('      *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*)');
-  linkres.add('      *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*)');
-  linkres.add('      *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*)');
-  linkres.add('      *(.rel.got)');
-  linkres.add('      *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*)');
-  linkres.add('    }');
-  linkres.add('  .rela.dyn       :');
-  linkres.add('    {');
-  linkres.add('      *(.rela.init)');
-  linkres.add('      *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)');
-  linkres.add('      *(.rela.fini)');
-  linkres.add('      *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)');
-  linkres.add('      *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)');
-  linkres.add('      *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)');
-  linkres.add('      *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)');
-  linkres.add('      *(.rela.got)');
-  linkres.add('      *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)');
-  linkres.add('    }');
-  linkres.add('  .rel.plt        : { *(.rel.plt) }');
-  linkres.add('  .rela.plt       : { *(.rela.plt) }');
-  linkres.add('  .init           :');
-  linkres.add('  {');
-  linkres.add('    KEEP (*(.init))');
-  linkres.add('  } =0x90909090');
-  linkres.add('  .plt            : { *(.plt) }');
-  linkres.add('  .text           :');
-  linkres.add('  {');
-  linkres.add('    *(.text .stub .text.* .gnu.linkonce.t.*)');
-  linkres.add('    KEEP (*(.text.*personality*))');
-                   {.gnu.warning sections are handled specially by elf32.em.}
-  linkres.add('    *(.gnu.warning)');
-  linkres.add('  } =0x90909090');
-  linkres.add('  .fini           :');
-  linkres.add('  {');
-  linkres.add('    KEEP (*(.fini))');
-  linkres.add('  } =0x90909090');
-  linkres.add('  PROVIDE (_etext = .);');
-  linkres.add('  .rodata         : { *(.rodata .rodata.* .gnu.linkonce.r.*) }');
-  {Adjust the address for the data segment.  We want to adjust up to
-   the same address within the page on the next page up.}
-  linkres.add('  . = ALIGN (0x1000) - ((0x1000 - .) & (0x1000 - 1)); . = DATA_SEGMENT_ALIGN (0x1000, 0x1000);');
-  linkres.add('  .dynamic        : { *(.dynamic) }');
-  linkres.add('  .got            : { *(.got) }');
-  linkres.add('  .got.plt        : { *(.got.plt) }');
-  linkres.add('  .data           :');
-  linkres.add('  {');
-  linkres.add('    *(.data .data.* .gnu.linkonce.d.*)');
-  linkres.add('    KEEP (*(.gnu.linkonce.d.*personality*))');
-  linkres.add('  }');
-  linkres.add('  _edata = .;');
-  linkres.add('  PROVIDE (edata = .);');
-{$ifdef zsegment_threadvars}
-  linkres.add('  _z = .;');
-  linkres.add('  .threadvar 0 : AT (_z) { *(.threadvar .threadvar.* .gnu.linkonce.tv.*) }');
-  linkres.add('  PROVIDE (_threadvar_size = SIZEOF(.threadvar));');
-  linkres.add('  . = _z + SIZEOF (.threadvar);');
-{$else}
-  linkres.add('  .threadvar : { *(.threadvar .threadvar.* .gnu.linkonce.tv.*) }');
-{$endif}
-  linkres.add('  __bss_start = .;');
-  linkres.add('  .bss            :');
-  linkres.add('  {');
-  linkres.add('   *(.dynbss)');
-  linkres.add('   *(.bss .bss.* .gnu.linkonce.b.*)');
-  linkres.add('   *(COMMON)');
-  {Align here to ensure that the .bss section occupies space up to
-   _end.  Align after .bss to ensure correct alignment even if the
-   .bss section disappears because there are no input sections.}
-  linkres.add('   . = ALIGN(32 / 8);');
-  linkres.add('  }');
-  linkres.add('  . = ALIGN(32 / 8);');
-  linkres.add('  _end = .;');
-  linkres.add('  PROVIDE (end = .);');
-  linkres.add('  . = DATA_SEGMENT_END (.);');
-  {Stabs debugging sections.}
-  linkres.add('  .stab          0 : { *(.stab) }');
-  linkres.add('  .stabstr       0 : { *(.stabstr) }');
-  linkres.add('}');
-{$endif OwnLDScript}
-
-{ Write and Close response }
-  LinkRes.writetodisk;
-  LinkRes.Free;
+  with linkres do
+    begin
+      { Write path to search libraries }
+      HPath:=TStringListItem(current_module.locallibrarysearchpath.First);
+      while assigned(HPath) do
+       begin
+         Add('SEARCH_DIR('+maybequoted(HPath.Str)+')');
+         HPath:=TStringListItem(HPath.Next);
+       end;
+      HPath:=TStringListItem(LibrarySearchPath.First);
+      while assigned(HPath) do
+       begin
+         Add('SEARCH_DIR('+maybequoted(HPath.Str)+')');
+         HPath:=TStringListItem(HPath.Next);
+       end;
+
+      Add('INPUT(');
+      { add objectfiles, start with prt0 always }
+      if prtobj<>'' then
+       AddFileName(maybequoted(FindObjectFile(prtobj,'',false)));
+      { try to add crti and crtbegin if linking to C }
+      if linklibc then
+       begin
+         if librarysearchpath.FindFile('crtbegin.o',s) then
+          AddFileName(s);
+         if librarysearchpath.FindFile('crti.o',s) then
+          AddFileName(s);
+       end;
+      { main objectfiles }
+      while not ObjectFiles.Empty do
+       begin
+         s:=ObjectFiles.GetFirst;
+         if s<>'' then
+          AddFileName(maybequoted(s));
+       end;
+      Add(')');
+
+      { Write staticlibraries }
+      if not StaticLibFiles.Empty then
+       begin
+         Add('GROUP(');
+         While not StaticLibFiles.Empty do
+          begin
+            S:=StaticLibFiles.GetFirst;
+            AddFileName(maybequoted(s))
+          end;
+         Add(')');
+       end;
+
+      { Write sharedlibraries like -l<lib>, also add the needed dynamic linker
+        here to be sure that it gets linked this is needed for glibc2 systems (PFV) }
+      if not SharedLibFiles.Empty then
+       begin
+         Add('INPUT(');
+         While not SharedLibFiles.Empty do
+          begin
+            S:=SharedLibFiles.GetFirst;
+            if s<>'c' then
+             begin
+               i:=Pos(target_info.sharedlibext,S);
+               if i>0 then
+                Delete(S,i,255);
+               Add('-l'+s);
+             end
+            else
+             begin
+               linklibc:=true;
+             end;
+          end;
+         { be sure that libc is the last lib }
+         if linklibc then
+          Add('-lc');
+         { when we have -static for the linker the we also need libgcc }
+         if (cs_link_staticflag in aktglobalswitches) then
+          Add('-lgcc');
+         Add(')');
+       end;
+
+      { objects which must be at the end }
+      if linklibc and (libctype<>uclibc) then
+       begin
+         found1:=librarysearchpath.FindFile('crtend.o',s1);
+         found2:=librarysearchpath.FindFile('crtn.o',s2);
+         if found1 or found2 then
+          begin
+            Add('INPUT(');
+            if found1 then
+             AddFileName(s1);
+            if found2 then
+             AddFileName(s2);
+            Add(')');
+          end;
+       end;
+
+      {Entry point.}
+      add('ENTRY(_start)');
+
+      {Sections.}
+      add('SECTIONS');
+      add('{');
+      {Read-only sections, merged into text segment:}
+      add('  PROVIDE (__executable_start = 0x010000); . = 0x010000 +0x100;');
+      add('  .interp         : { *(.interp) }');
+      add('  .hash           : { *(.hash) }');
+      add('  .dynsym         : { *(.dynsym) }');
+      add('  .dynstr         : { *(.dynstr) }');
+      add('  .gnu.version    : { *(.gnu.version) }');
+      add('  .gnu.version_d  : { *(.gnu.version_d) }');
+      add('  .gnu.version_r  : { *(.gnu.version_r) }');
+      add('  .rel.dyn        :');
+      add('    {');
+      add('      *(.rel.init)');
+      add('      *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*)');
+      add('      *(.rel.fini)');
+      add('      *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*)');
+      add('      *(.rel.data.rel.ro*)');
+      add('      *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*)');
+      add('      *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*)');
+      add('      *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*)');
+      add('      *(.rel.got)');
+      add('      *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*)');
+      add('    }');
+      add('  .rela.dyn       :');
+      add('    {');
+      add('      *(.rela.init)');
+      add('      *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)');
+      add('      *(.rela.fini)');
+      add('      *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)');
+      add('      *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)');
+      add('      *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)');
+      add('      *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)');
+      add('      *(.rela.got)');
+      add('      *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)');
+      add('    }');
+      add('  .rel.plt        : { *(.rel.plt) }');
+      add('  .rela.plt       : { *(.rela.plt) }');
+      add('  .init           :');
+      add('  {');
+      add('    KEEP (*(.init))');
+      add('  } =0x90909090');
+      add('  .plt            : { *(.plt) }');
+      add('  .text           :');
+      add('  {');
+      add('    *(.text .stub .text.* .gnu.linkonce.t.*)');
+      add('    KEEP (*(.text.*personality*))');
+      {.gnu.warning sections are handled specially by elf32.em.}
+      add('    *(.gnu.warning)');
+      add('  } =0x90909090');
+      add('  .fini           :');
+      add('  {');
+      add('    KEEP (*(.fini))');
+      add('  } =0x90909090');
+      add('  PROVIDE (_etext = .);');
+      add('  .rodata         :');
+      add('  {');
+      add('    *(.rodata .rodata.* .gnu.linkonce.r.*)');
+      add('  }');
+      {Adjust the address for the data segment.  We want to adjust up to
+       the same address within the page on the next page up.}
+      add('  . = ALIGN (0x1000) - ((0x1000 - .) & (0x1000 - 1));');
+      add('  .dynamic        : { *(.dynamic) }');
+      add('  .got            : { *(.got) }');
+      add('  .got.plt        : { *(.got.plt) }');
+      add('  .data           :');
+      add('  {');
+      add('    *(.data .data.* .gnu.linkonce.d.*)');
+      add('    KEEP (*(.gnu.linkonce.d.*personality*))');
+      add('  }');
+      add('  _edata = .;');
+      add('  PROVIDE (edata = .);');
+    {$ifdef zsegment_threadvars}
+      add('  _z = .;');
+      add('  .threadvar 0 : AT (_z) { *(.threadvar .threadvar.* .gnu.linkonce.tv.*) }');
+      add('  PROVIDE (_threadvar_size = SIZEOF(.threadvar));');
+      add('  . = _z + SIZEOF (.threadvar);');
+    {$else}
+      add('  .threadvar : { *(.threadvar .threadvar.* .gnu.linkonce.tv.*) }');
+    {$endif}
+      add('  __bss_start = .;');
+      add('  .bss            :');
+      add('  {');
+      add('   *(.dynbss)');
+      add('   *(.bss .bss.* .gnu.linkonce.b.*)');
+      add('   *(COMMON)');
+      {Align here to ensure that the .bss section occupies space up to
+       _end.  Align after .bss to ensure correct alignment even if the
+       .bss section disappears because there are no input sections.}
+      add('   . = ALIGN(32 / 8);');
+      add('  }');
+      add('  . = ALIGN(32 / 8);');
+      add('  _end = .;');
+      add('  PROVIDE (end = .);');
+      {Stabs debugging sections.}
+      add('  .stab          0 : { *(.stab) }');
+      add('  .stabstr       0 : { *(.stabstr) }');
+      add('}');
+
+      { Write and Close response }
+      writetodisk;
+      Free;
+    end;
 
 
   WriteResponseFile:=True;
   WriteResponseFile:=True;
 end;
 end;
@@ -593,6 +595,8 @@ begin
    StaticStr:='-static';
    StaticStr:='-static';
   if (cs_link_strip in aktglobalswitches) then
   if (cs_link_strip in aktglobalswitches) then
    StripStr:='-s';
    StripStr:='-s';
+  if (cs_link_map in aktglobalswitches) then
+   StripStr:='-Map '+maybequoted(ForceExtension(current_module.exefilename^,'.map'));
   if use_smartlink_section then
   if use_smartlink_section then
    GCSectionsStr:='--gc-sections';
    GCSectionsStr:='--gc-sections';
   If (cs_profile in aktmoduleswitches) or
   If (cs_profile in aktmoduleswitches) or

+ 192 - 80
compiler/systems/t_win.pas

@@ -932,94 +932,204 @@ begin
     end;
     end;
 
 
   { Open link.res file }
   { Open link.res file }
-  LinkRes:=TLinkRes.Create(outputexedir+Info.ResName);
-
-  { Write path to search libraries }
-  HPath:=TStringListItem(current_module.locallibrarysearchpath.First);
-  while assigned(HPath) do
-   begin
-     LinkRes.Add('SEARCH_DIR('+MaybeQuoted(HPath.Str)+')');
-     HPath:=TStringListItem(HPath.Next);
-   end;
-  HPath:=TStringListItem(LibrarySearchPath.First);
-  while assigned(HPath) do
-   begin
-     LinkRes.Add('SEARCH_DIR('+MaybeQuoted(HPath.Str)+')');
-     HPath:=TStringListItem(HPath.Next);
-   end;
-
-  { add objectfiles, start with prt0 always                  }
-  { profiling of shared libraries is currently not supported }
-  if not ObjectFiles.Empty then
+  LinkRes:=TLinkres.Create(outputexedir+Info.ResName);
+  with linkres do
     begin
     begin
-      LinkRes.Add('INPUT(');
-      { For wince external startup file is used and placed first,     }
-      { because ARM prolog structure must be located at the very      }
-      { beginning of code. Otherwise exceptions do not work properly. }
-      if target_info.system in [system_arm_wince,system_i386_wince] then
-        LinkRes.AddFileName(MaybeQuoted(FindObjectFile('wprt0','',false)));
-
-      while not ObjectFiles.Empty do
+      { Write path to search libraries }
+      HPath:=TStringListItem(current_module.locallibrarysearchpath.First);
+      while assigned(HPath) do
+       begin
+         Add('SEARCH_DIR('+MaybeQuoted(HPath.Str)+')');
+         HPath:=TStringListItem(HPath.Next);
+       end;
+      HPath:=TStringListItem(LibrarySearchPath.First);
+      while assigned(HPath) do
+       begin
+         Add('SEARCH_DIR('+MaybeQuoted(HPath.Str)+')');
+         HPath:=TStringListItem(HPath.Next);
+       end;
+
+      { add objectfiles, start with prt0 always                  }
+      { profiling of shared libraries is currently not supported }
+      if not ObjectFiles.Empty then
         begin
         begin
-          s:=ObjectFiles.GetFirst;
-          if s<>'' then
-            LinkRes.AddFileName(MaybeQuoted(s));
+          Add('INPUT(');
+          { For wince external startup file is used and placed first,     }
+          { because ARM prolog structure must be located at the very      }
+          { beginning of code. Otherwise exceptions do not work properly. }
+          if target_info.system in [system_arm_wince,system_i386_wince] then
+            LinkRes.AddFileName(MaybeQuoted(FindObjectFile('wprt0','',false)));
+          while not ObjectFiles.Empty do
+           begin
+             s:=ObjectFiles.GetFirst;
+             if s<>'' then
+              AddFileName(MaybeQuoted(s));
+           end;
+          Add(')');
         end;
         end;
-      LinkRes.Add(')');
-    end;
-
-  { Write staticlibraries }
-  if (not StaticLibFiles.Empty) then
-   begin
-     LinkRes.Add('GROUP(');
-     While not StaticLibFiles.Empty do
-      begin
-        S:=StaticLibFiles.GetFirst;
-        LinkRes.AddFileName(MaybeQuoted(s));
-      end;
-     LinkRes.Add(')');
-   end;
 
 
-  { Write sharedlibraries (=import libraries) }
-  if not SharedLibFiles.Empty then
-   begin
-     LinkRes.Add('INPUT(') ;
-     While not SharedLibFiles.Empty do
-      begin
-        S:=SharedLibFiles.GetFirst;
-        if FindLibraryFile(s,target_info.staticClibprefix,target_info.staticClibext,s2) then
+      { Write staticlibraries }
+      if (not StaticLibFiles.Empty) then
+       begin
+         Add('GROUP(');
+         While not StaticLibFiles.Empty do
           begin
           begin
-            LinkRes.Add(MaybeQuoted(s2));
-            continue;
+            S:=StaticLibFiles.GetFirst;
+            AddFileName(MaybeQuoted(s));
           end;
           end;
-        if pos(target_info.sharedlibprefix,s)=1 then
-          s:=copy(s,length(target_info.sharedlibprefix)+1,255);
-        i:=Pos(target_info.sharedlibext,S);
-        if i>0 then
-         Delete(S,i,255);
-        LinkRes.Add('-l'+s);
-      end;
-     LinkRes.Add(')');
-   end;
+         Add(')');
+       end;
 
 
-  { Write DLLs (=direct DLL linking) }
-  if not DLLFiles.Empty then
-   begin
-     LinkRes.Add('INPUT(') ;
-     While not DLLFiles.Empty do
-      begin
-        s:=DLLFiles.GetFirst;
-        if FindDLL(s,s2) then
-          LinkRes.Add(MaybeQuoted(s2))
-        else
-          LinkRes.Add('-l'+s);
-      end;
-     LinkRes.Add(')');
-   end;
+      { Write sharedlibraries (=import libraries) }
+      if not SharedLibFiles.Empty then
+       begin
+         Add('INPUT(') ;
+         While not SharedLibFiles.Empty do
+          begin
+            S:=SharedLibFiles.GetFirst;
+            if FindLibraryFile(s,target_info.staticClibprefix,target_info.staticClibext,s2) then
+              begin
+                Add(MaybeQuoted(s2));
+                continue;
+              end;
+            if pos(target_info.sharedlibprefix,s)=1 then
+              s:=copy(s,length(target_info.sharedlibprefix)+1,255);
+            i:=Pos(target_info.sharedlibext,S);
+            if i>0 then
+             Delete(S,i,255);
+            Add('-l'+s);
+          end;
+         Add(')');
+       end;
 
 
-{ Write and Close response }
-  linkres.writetodisk;
-  LinkRes.Free;
+      { Write DLLs (=direct DLL linking) }
+      if not DLLFiles.Empty then
+       begin
+         Add('INPUT(') ;
+         While not DLLFiles.Empty do
+          begin
+            s:=DLLFiles.GetFirst;
+            if FindDLL(s,s2) then
+              Add(MaybeQuoted(s2))
+            else
+              Add('-l'+s);
+          end;
+         Add(')');
+       end;
+      Add('SEARCH_DIR("/usr/i686-pc-cygwin/lib"); SEARCH_DIR("/usr/lib"); SEARCH_DIR("/usr/lib/w32api");');
+      Add('OUTPUT_FORMAT(pei-i386)');
+      Add('ENTRY(_mainCRTStartup)');
+      Add('SECTIONS');
+      Add('{');
+      Add('  . = SIZEOF_HEADERS;');
+      Add('  . = ALIGN(__section_alignment__);');
+      Add('  .text  __image_base__ + ( __section_alignment__ < 0x1000 ? . : __section_alignment__ ) :');
+      Add('  {');
+      Add('    *(.init)');
+      Add('    *(.text)');
+      Add('    *(SORT(.text$*))');
+      Add('     ___CTOR_LIST__ = .; __CTOR_LIST__ = . ;');
+      Add('			LONG (-1);*(.ctors); *(.ctor); *(SORT(.ctors.*));  LONG (0);');
+      Add('     ___DTOR_LIST__ = .; __DTOR_LIST__ = . ;');
+      Add('			LONG (-1); *(.dtors); *(.dtor); *(SORT(.dtors.*));  LONG (0);');
+      Add('     *(.fini)');
+      Add('    PROVIDE (etext = .);');
+      Add('    *(.gcc_except_table)');
+      Add('  }');
+      Add('  .data BLOCK(__section_alignment__) :');
+      Add('  {');
+      Add('    __data_start__ = . ;');
+      Add('    *(.data)');
+      Add('    *(.data2)');
+      Add('    *(SORT(.data$*))');
+      Add('    __data_end__ = . ;');
+      Add('    *(.data_cygwin_nocopy)');
+      Add('  }');
+      Add('  .rdata BLOCK(__section_alignment__) :');
+      Add('  {');
+      Add('    *(.rdata)');
+      Add('    *(SORT(.rdata$*))');
+      Add('    *(.eh_frame)');
+      Add('    ___RUNTIME_PSEUDO_RELOC_LIST__ = .;');
+      Add('    __RUNTIME_PSEUDO_RELOC_LIST__ = .;');
+      Add('    *(.rdata_runtime_pseudo_reloc)');
+      Add('    ___RUNTIME_PSEUDO_RELOC_LIST_END__ = .;');
+      Add('    __RUNTIME_PSEUDO_RELOC_LIST_END__ = .;');
+      Add('  }');
+      Add('  .pdata BLOCK(__section_alignment__) : { *(.pdata) }');
+      Add('  .bss BLOCK(__section_alignment__) :');
+      Add('  {');
+      Add('    __bss_start__ = . ;');
+      Add('    *(.bss)');
+      Add('    *(COMMON)');
+      Add('    __bss_end__ = . ;');
+      Add('  }');
+      Add('  .edata BLOCK(__section_alignment__) : { *(.edata) }');
+      Add('  .idata BLOCK(__section_alignment__) :');
+      Add('  {');
+      Add('    SORT(*)(.idata$2)');
+      Add('    SORT(*)(.idata$3)');
+      Add('    /* These zeroes mark the end of the import list.  */');
+      Add('    LONG (0); LONG (0); LONG (0); LONG (0); LONG (0);');
+      Add('    SORT(*)(.idata$4)');
+      Add('    SORT(*)(.idata$5)');
+      Add('    SORT(*)(.idata$6)');
+      Add('    SORT(*)(.idata$7)');
+      Add('  }');
+      Add('  .CRT BLOCK(__section_alignment__) :');
+      Add('  {');
+      Add('    ___crt_xc_start__ = . ;');
+      Add('    *(SORT(.CRT$XC*))  /* C initialization */');
+      Add('    ___crt_xc_end__ = . ;');
+      Add('    ___crt_xi_start__ = . ;');
+      Add('    *(SORT(.CRT$XI*))  /* C++ initialization */');
+      Add('    ___crt_xi_end__ = . ;');
+      Add('    ___crt_xl_start__ = . ;');
+      Add('    *(SORT(.CRT$XL*))  /* TLS callbacks */');
+      Add('    /* ___crt_xl_end__ is defined in the TLS Directory support code */');
+      Add('    ___crt_xp_start__ = . ;');
+      Add('    *(SORT(.CRT$XP*))  /* Pre-termination */');
+      Add('    ___crt_xp_end__ = . ;');
+      Add('    ___crt_xt_start__ = . ;');
+      Add('    *(SORT(.CRT$XT*))  /* Termination */');
+      Add('    ___crt_xt_end__ = . ;');
+      Add('  }');
+      Add('  .tls BLOCK(__section_alignment__) :');
+      Add('  {');
+      Add('    ___tls_start__ = . ;');
+      Add('    *(.tls)');
+      Add('    *(.tls$)');
+      Add('    *(SORT(.tls$*))');
+      Add('    ___tls_end__ = . ;');
+      Add('  }');
+      Add('  .rsrc BLOCK(__section_alignment__) :');
+      Add('  {');
+      Add('    *(.rsrc)');
+      Add('    *(SORT(.rsrc$*))');
+      Add('  }');
+      Add('  .reloc BLOCK(__section_alignment__) : { *(.reloc) }');
+      Add('  .stab BLOCK(__section_alignment__) (NOLOAD) : { *(.stab) }');
+      Add('  .stabstr BLOCK(__section_alignment__) (NOLOAD) : { *(.stabstr) }');
+      Add('  .debug_aranges BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_aranges) }');
+      Add('  .debug_pubnames BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_pubnames) }');
+      Add('  .debug_info BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_info) *(.gnu.linkonce.wi.*) }');
+      Add('  .debug_abbrev BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_abbrev) }');
+      Add('  .debug_line BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_line) }');
+      Add('  .debug_frame BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_frame) }');
+      Add('  .debug_str BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_str) }');
+      Add('  .debug_loc BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_loc) }');
+      Add('  .debug_macinfo BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_macinfo) }');
+      Add('  .debug_weaknames BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_weaknames) }');
+      Add('  .debug_funcnames BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_funcnames) }');
+      Add('  .debug_typenames BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_typenames) }');
+      Add('  .debug_varnames BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_varnames) }');
+      Add('  .debug_ranges BLOCK(__section_alignment__) (NOLOAD) : { *(.debug_ranges) }');
+      Add('}');
+
+      { Write and Close response }
+      writetodisk;
+    end;
+  Free;
 
 
   WriteResponseFile:=True;
   WriteResponseFile:=True;
 end;
 end;
@@ -1069,6 +1179,8 @@ begin
     ImageBaseStr:='--image-base=0x'+DLLImageBase^;
     ImageBaseStr:='--image-base=0x'+DLLImageBase^;
   if (cs_link_strip in aktglobalswitches) then
   if (cs_link_strip in aktglobalswitches) then
     StripStr:='-s';
     StripStr:='-s';
+  if (cs_link_map in aktglobalswitches) then
+    StripStr:='-Map '+maybequoted(ForceExtension(current_module.exefilename^,'.map'));
 
 
 { Write used files and libraries }
 { Write used files and libraries }
   WriteResponseFile(false);
   WriteResponseFile(false);

+ 2 - 4
compiler/x86/aasmcpu.pas

@@ -76,8 +76,8 @@ interface
       OT_REG16     = $00201002;
       OT_REG16     = $00201002;
       OT_REG32     = $00201004;
       OT_REG32     = $00201004;
       OT_REG64     = $00201008;
       OT_REG64     = $00201008;
-      OT_MMXREG    = $00201008;  { MMX registers  }
       OT_XMMREG    = $00201010;  { Katmai registers  }
       OT_XMMREG    = $00201010;  { Katmai registers  }
+      OT_MMXREG    = $00201020;  { MMX registers  }
       OT_MEMORY    = $00204000;  { register number in 'basereg'  }
       OT_MEMORY    = $00204000;  { register number in 'basereg'  }
       OT_MEM8      = $00204001;
       OT_MEM8      = $00204001;
       OT_MEM16     = $00204002;
       OT_MEM16     = $00204002;
@@ -776,11 +776,9 @@ implementation
                    if (ot and OT_BITS32)<>0 then
                    if (ot and OT_BITS32)<>0 then
                     s:=s+'32'
                     s:=s+'32'
                   else
                   else
-{$ifdef x86_64}
-                   if (ot and OT_BITS32)<>0 then
+                   if (ot and OT_BITS64)<>0 then
                     s:=s+'64'
                     s:=s+'64'
                   else
                   else
-{$endif x86_64}
                     s:=s+'??';
                     s:=s+'??';
                   { signed }
                   { signed }
                   if (ot and OT_SIGNED)<>0 then
                   if (ot and OT_SIGNED)<>0 then

+ 1 - 1
compiler/x86/agx86int.pas

@@ -65,7 +65,7 @@ implementation
         '',
         '',
         '','','','',
         '','','','',
         '',
         '',
-	''
+        ''
       );
       );
 
 
       secnamesml64 : array[TAsmSectiontype] of string[7] = ('',
       secnamesml64 : array[TAsmSectiontype] of string[7] = ('',