From de918497efab81845071e7e1946691e2377f78ce Mon Sep 17 00:00:00 2001
From: peter <peter@freepascal.org>
Date: Sun, 20 Jan 2008 12:12:15 +0000
Subject: [PATCH]   * support -Xg under linux

git-svn-id: trunk@9811 -
---
 compiler/finput.pas          |  5 +++++
 compiler/link.pas            |  3 ++-
 compiler/systems/t_linux.pas | 24 ++++++++++++++++++++++--
 3 files changed, 29 insertions(+), 3 deletions(-)

diff --git a/compiler/finput.pas b/compiler/finput.pas
index c848a5a06f..c440c20c94 100644
--- a/compiler/finput.pas
+++ b/compiler/finput.pas
@@ -150,6 +150,7 @@ interface
           sharedlibfilename,        { fullname of the shared libraryfile }
           mapfilename,              { fullname of the mapfile }
           exefilename,              { fullname of the exefile }
+          dbgfilename,              { fullname of the debug info file }
           mainsource   : pshortstring;   { name of the main sourcefile }
           constructor create(const s:string);
           destructor destroy;override;
@@ -615,6 +616,7 @@ uses
          stringdispose(sharedlibfilename);
          stringdispose(mapfilename);
          stringdispose(exefilename);
+         stringdispose(dbgfilename);
          stringdispose(outputpath);
          stringdispose(path);
          stringdispose(paramfn);
@@ -669,6 +671,7 @@ uses
              sharedlibfilename:=stringdup(p+prefix+n+suffix+target_info.sharedlibext);
            end;
          mapfilename:=stringdup(p+n+'.map');
+         dbgfilename:=stringdup(p+n+'.dbg');
       end;
 
 
@@ -684,6 +687,7 @@ uses
         staticlibfilename:=nil;
         sharedlibfilename:=nil;
         exefilename:=nil;
+        dbgfilename:=nil;
         mapfilename:=nil;
         outputpath:=nil;
         paramfn:=nil;
@@ -710,6 +714,7 @@ uses
         stringdispose(staticlibfilename);
         stringdispose(sharedlibfilename);
         stringdispose(exefilename);
+        stringdispose(dbgfilename);
         stringdispose(mapfilename);
         stringdispose(outputpath);
         stringdispose(path);
diff --git a/compiler/link.pas b/compiler/link.pas
index b91ab7344a..92867b3be9 100644
--- a/compiler/link.pas
+++ b/compiler/link.pas
@@ -37,7 +37,8 @@ interface
     Type
       TLinkerInfo=record
         ExeCmd,
-        DllCmd        : array[1..3] of string;
+        DllCmd,
+        ExtDbgCmd     : array[1..3] of string;
         ResName       : string[100];
         ScriptName    : string[100];
         ExtraOptions  : TCmdStr;
diff --git a/compiler/systems/t_linux.pas b/compiler/systems/t_linux.pas
index 71358f0ba6..effa9a7a0d 100644
--- a/compiler/systems/t_linux.pas
+++ b/compiler/systems/t_linux.pas
@@ -242,6 +242,9 @@ begin
      ExeCmd[1]:=ExeCmd[1]+' $RES';
      DllCmd[1]:='ld '+platform_select+' $OPT $INIT $FINI $SONAME -shared -L. -o $EXE $RES -E';
      DllCmd[2]:='strip --strip-unneeded $EXE';
+     ExtDbgCmd[1]:='objcopy --only-keep-debug $EXE $DBG';
+     ExtDbgCmd[2]:='objcopy --add-gnu-debuglink=$DBG $EXE';
+     ExtDbgCmd[3]:='strip --strip-unneeded $EXE';
 
 {$ifdef m68k}
      { experimental, is this correct? }
@@ -1006,6 +1009,7 @@ end;
 
 function TLinkerLinux.MakeExecutable:boolean;
 var
+  i : longint;
   binstr,
   cmdstr  : TCmdStr;
   success : boolean;
@@ -1024,7 +1028,8 @@ begin
   DynLinkStr:='';
   if (cs_link_staticflag in current_settings.globalswitches) then
    StaticStr:='-static';
-  if (cs_link_strip in current_settings.globalswitches) then
+  if (cs_link_strip in current_settings.globalswitches) and
+     not(cs_link_separate_dbg_file in current_settings.globalswitches) then
    StripStr:='-s';
   if (cs_link_map in current_settings.globalswitches) then
    StripStr:='-Map '+maybequoted(ChangeFileExt(current_module.exefilename^,'.map'));
@@ -1059,7 +1064,22 @@ begin
 
   success:=DoExec(FindUtil(utilsprefix+BinStr),CmdStr,true,false);
 
-{ Remove ReponseFile }
+  { Create external .dbg file with debuginfo }
+  if success and (cs_link_separate_dbg_file in current_settings.globalswitches) then
+    begin
+      for i:=1 to 3 do
+        begin
+          SplitBinCmd(Info.ExtDbgCmd[i],binstr,cmdstr);
+          Replace(cmdstr,'$EXE',maybequoted(current_module.exefilename^));
+          Replace(cmdstr,'$DBGFN',maybequoted(extractfilename(current_module.dbgfilename^)));
+          Replace(cmdstr,'$DBG',maybequoted(current_module.dbgfilename^));
+          success:=DoExec(FindUtil(utilsprefix+BinStr),CmdStr,true,false);
+          if not success then
+            break;
+        end;
+    end;
+
+  { Remove ReponseFile }
   if (success) and not(cs_link_nolink in current_settings.globalswitches) then
    DeleteFile(outputexedir+Info.ResName);