mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-22 18:29:33 +02:00
* Add -Xg to help pages
* -Xg now produces a .dbg file with debuginfo that can be used by gdb. The main executable gets a debuglink section that references the .dbg file. git-svn-id: trunk@9778 -
This commit is contained in:
parent
bd70396a93
commit
793fd8fc09
@ -25,9 +25,7 @@ Unit fpccrc;
|
|||||||
|
|
||||||
Interface
|
Interface
|
||||||
|
|
||||||
Function Crc32(Const HStr:String):cardinal;
|
|
||||||
Function UpdateCrc32(InitCrc:cardinal;const InBuf;InLen:integer):cardinal;
|
Function UpdateCrc32(InitCrc:cardinal;const InBuf;InLen:integer):cardinal;
|
||||||
Function UpdCrc32(InitCrc:cardinal;b:byte):cardinal;
|
|
||||||
|
|
||||||
|
|
||||||
Implementation
|
Implementation
|
||||||
@ -57,21 +55,6 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
Function Crc32(Const HStr:String):cardinal;
|
|
||||||
var
|
|
||||||
i : integer;
|
|
||||||
InitCrc : cardinal;
|
|
||||||
begin
|
|
||||||
if Crc32Tbl[1]=0 then
|
|
||||||
MakeCrc32Tbl;
|
|
||||||
InitCrc:=cardinal($ffffffff);
|
|
||||||
for i:=1 to Length(Hstr) do
|
|
||||||
InitCrc:=Crc32Tbl[byte(InitCrc) xor ord(Hstr[i])] xor (InitCrc shr 8);
|
|
||||||
Crc32:=InitCrc;
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Function UpdateCrc32(InitCrc:cardinal;const InBuf;InLen:Integer):cardinal;
|
Function UpdateCrc32(InitCrc:cardinal;const InBuf;InLen:Integer):cardinal;
|
||||||
var
|
var
|
||||||
i : integer;
|
i : integer;
|
||||||
@ -80,21 +63,14 @@ begin
|
|||||||
if Crc32Tbl[1]=0 then
|
if Crc32Tbl[1]=0 then
|
||||||
MakeCrc32Tbl;
|
MakeCrc32Tbl;
|
||||||
p:=@InBuf;
|
p:=@InBuf;
|
||||||
|
result:=not InitCrc;
|
||||||
for i:=1 to InLen do
|
for i:=1 to InLen do
|
||||||
begin
|
begin
|
||||||
InitCrc:=Crc32Tbl[byte(InitCrc) xor byte(p^)] xor (InitCrc shr 8);
|
result:=Crc32Tbl[byte(result) xor byte(p^)] xor (result shr 8);
|
||||||
inc(p);
|
inc(p);
|
||||||
end;
|
end;
|
||||||
UpdateCrc32:=InitCrc;
|
result:=not result;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Function UpdCrc32(InitCrc:cardinal;b:byte):cardinal;
|
|
||||||
begin
|
|
||||||
if Crc32Tbl[1]=0 then
|
|
||||||
MakeCrc32Tbl;
|
|
||||||
UpdCrc32:=Crc32Tbl[byte(InitCrc) xor b] xor (InitCrc shr 8);
|
|
||||||
end;
|
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
@ -94,7 +94,8 @@ interface
|
|||||||
procedure Load_ReadStaticLibrary(const para:TCmdStr);
|
procedure Load_ReadStaticLibrary(const para:TCmdStr);
|
||||||
procedure ParseScript_Load;
|
procedure ParseScript_Load;
|
||||||
procedure ParseScript_Order;
|
procedure ParseScript_Order;
|
||||||
procedure ParseScript_CalcPos;
|
procedure ParseScript_MemPos;
|
||||||
|
procedure ParseScript_DataPos;
|
||||||
procedure PrintLinkerScript;
|
procedure PrintLinkerScript;
|
||||||
function RunLinkScript(const outputname:TCmdStr):boolean;
|
function RunLinkScript(const outputname:TCmdStr):boolean;
|
||||||
protected
|
protected
|
||||||
@ -127,8 +128,8 @@ interface
|
|||||||
Implementation
|
Implementation
|
||||||
|
|
||||||
uses
|
uses
|
||||||
cutils,cfileutl,
|
cutils,cfileutl,cstreams,
|
||||||
script,globals,verbose,comphook,ppu,
|
script,globals,verbose,comphook,ppu,fpccrc,
|
||||||
aasmbase,aasmtai,aasmdata,aasmcpu,
|
aasmbase,aasmtai,aasmdata,aasmcpu,
|
||||||
owbase,owar,ogmap;
|
owbase,owar,ogmap;
|
||||||
|
|
||||||
@ -139,6 +140,32 @@ Implementation
|
|||||||
Helpers
|
Helpers
|
||||||
*****************************************************************************}
|
*****************************************************************************}
|
||||||
|
|
||||||
|
function GetFileCRC(const fn:string):cardinal;
|
||||||
|
var
|
||||||
|
fs : TCStream;
|
||||||
|
bufcount,
|
||||||
|
bufsize : Integer;
|
||||||
|
buf : pbyte;
|
||||||
|
begin
|
||||||
|
result:=0;
|
||||||
|
bufsize:=64*1024;
|
||||||
|
fs:=TCFileStream.Create(fn,fmOpenRead or fmShareDenyNone);
|
||||||
|
if CStreamError<>0 then
|
||||||
|
begin
|
||||||
|
fs.Free;
|
||||||
|
Comment(V_Error,'Can''t open file: '+fn);
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
getmem(buf,bufsize);
|
||||||
|
repeat
|
||||||
|
bufcount:=fs.Read(buf^,bufsize);
|
||||||
|
result:=UpdateCrc32(result,buf^,bufcount);
|
||||||
|
until bufcount<bufsize;
|
||||||
|
freemem(buf);
|
||||||
|
fs.Free;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
{ searches an object file }
|
{ searches an object file }
|
||||||
function FindObjectFile(s:TCmdStr;const unitpath:TCmdStr;isunit:boolean) : TCmdStr;
|
function FindObjectFile(s:TCmdStr;const unitpath:TCmdStr;isunit:boolean) : TCmdStr;
|
||||||
var
|
var
|
||||||
@ -913,14 +940,14 @@ Implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TInternalLinker.ParseScript_CalcPos;
|
procedure TInternalLinker.ParseScript_MemPos;
|
||||||
var
|
var
|
||||||
s,
|
s,
|
||||||
para,
|
para,
|
||||||
keyword : String;
|
keyword : String;
|
||||||
hp : TCmdStrListItem;
|
hp : TCmdStrListItem;
|
||||||
begin
|
begin
|
||||||
exeoutput.CalcPos_Start;
|
exeoutput.MemPos_Start;
|
||||||
hp:=TCmdStrListItem(linkscript.first);
|
hp:=TCmdStrListItem(linkscript.first);
|
||||||
while assigned(hp) do
|
while assigned(hp) do
|
||||||
begin
|
begin
|
||||||
@ -930,13 +957,40 @@ Implementation
|
|||||||
keyword:=Upper(GetToken(s,' '));
|
keyword:=Upper(GetToken(s,' '));
|
||||||
para:=GetToken(s,' ');
|
para:=GetToken(s,' ');
|
||||||
if keyword='EXESECTION' then
|
if keyword='EXESECTION' then
|
||||||
ExeOutput.CalcPos_ExeSection(para)
|
ExeOutput.MemPos_ExeSection(para)
|
||||||
else if keyword='ENDEXESECTION' then
|
else if keyword='ENDEXESECTION' then
|
||||||
ExeOutput.CalcPos_EndExeSection
|
ExeOutput.MemPos_EndExeSection
|
||||||
else if keyword='HEADER' then
|
else if keyword='HEADER' then
|
||||||
ExeOutput.CalcPos_Header
|
ExeOutput.MemPos_Header;
|
||||||
|
hp:=TCmdStrListItem(hp.next);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TInternalLinker.ParseScript_DataPos;
|
||||||
|
var
|
||||||
|
s,
|
||||||
|
para,
|
||||||
|
keyword : String;
|
||||||
|
hp : TCmdStrListItem;
|
||||||
|
begin
|
||||||
|
exeoutput.DataPos_Start;
|
||||||
|
hp:=TCmdStrListItem(linkscript.first);
|
||||||
|
while assigned(hp) do
|
||||||
|
begin
|
||||||
|
s:=hp.str;
|
||||||
|
if (s='') or (s[1]='#') then
|
||||||
|
continue;
|
||||||
|
keyword:=Upper(GetToken(s,' '));
|
||||||
|
para:=GetToken(s,' ');
|
||||||
|
if keyword='EXESECTION' then
|
||||||
|
ExeOutput.DataPos_ExeSection(para)
|
||||||
|
else if keyword='ENDEXESECTION' then
|
||||||
|
ExeOutput.DataPos_EndExeSection
|
||||||
|
else if keyword='HEADER' then
|
||||||
|
ExeOutput.DataPos_Header
|
||||||
else if keyword='SYMBOLS' then
|
else if keyword='SYMBOLS' then
|
||||||
ExeOutput.CalcPos_Symbols;
|
ExeOutput.DataPos_Symbols;
|
||||||
hp:=TCmdStrListItem(hp.next);
|
hp:=TCmdStrListItem(hp.next);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -965,6 +1019,7 @@ Implementation
|
|||||||
var
|
var
|
||||||
bsssize : aint;
|
bsssize : aint;
|
||||||
bsssec : TExeSection;
|
bsssec : TExeSection;
|
||||||
|
dbgname : TCmdStr;
|
||||||
begin
|
begin
|
||||||
result:=false;
|
result:=false;
|
||||||
|
|
||||||
@ -999,16 +1054,34 @@ Implementation
|
|||||||
if ErrorCount>0 then
|
if ErrorCount>0 then
|
||||||
goto myexit;
|
goto myexit;
|
||||||
|
|
||||||
{ Calc positions in mem and file }
|
{ Calc positions in mem }
|
||||||
ParseScript_CalcPos;
|
ParseScript_MemPos;
|
||||||
exeoutput.FixupRelocations;
|
exeoutput.FixupRelocations;
|
||||||
exeoutput.PrintMemoryMap;
|
exeoutput.PrintMemoryMap;
|
||||||
if ErrorCount>0 then
|
if ErrorCount>0 then
|
||||||
goto myexit;
|
goto myexit;
|
||||||
|
|
||||||
exeoutput.WriteExeFile(outputname);
|
|
||||||
if cs_link_separate_dbg_file in current_settings.globalswitches then
|
if cs_link_separate_dbg_file in current_settings.globalswitches then
|
||||||
exeoutput.WriteDbgFile(ChangeFileExt(outputname,'.dbg'));
|
begin
|
||||||
|
{ create debuginfo, which is an executable without data on disk }
|
||||||
|
dbgname:=ChangeFileExt(outputname,'.dbg');
|
||||||
|
exeoutput.ExeWriteMode:=ewm_dbgonly;
|
||||||
|
ParseScript_DataPos;
|
||||||
|
exeoutput.WriteExeFile(dbgname);
|
||||||
|
{ create executable with link to just created debuginfo file }
|
||||||
|
exeoutput.ExeWriteMode:=ewm_exeonly;
|
||||||
|
exeoutput.RemoveDebugInfo;
|
||||||
|
exeoutput.GenerateDebugLink(dbgname,GetFileCRC(dbgname));
|
||||||
|
ParseScript_MemPos;
|
||||||
|
ParseScript_DataPos;
|
||||||
|
exeoutput.WriteExeFile(outputname);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
exeoutput.ExeWriteMode:=ewm_exefull;
|
||||||
|
ParseScript_DataPos;
|
||||||
|
exeoutput.WriteExeFile(outputname);
|
||||||
|
end;
|
||||||
|
|
||||||
{$warning TODO fixed section names}
|
{$warning TODO fixed section names}
|
||||||
status.codesize:=exeoutput.findexesection('.text').size;
|
status.codesize:=exeoutput.findexesection('.text').size;
|
||||||
|
@ -2686,6 +2686,7 @@ P*2WT_Specify MPW tool type application (Classic Mac OS)
|
|||||||
**2Xc_Pass --shared/-dynamic to the linker (BeOS, Darwin, FreeBSD, Linux)
|
**2Xc_Pass --shared/-dynamic to the linker (BeOS, Darwin, FreeBSD, Linux)
|
||||||
**2Xd_Do not use standard library search path (needed for cross compile)
|
**2Xd_Do not use standard library search path (needed for cross compile)
|
||||||
**2Xe_Use external linker
|
**2Xe_Use external linker
|
||||||
|
**2Xg_Create debuginfo in a separate file and add a debuglink section to executable
|
||||||
**2XD_Try to link units dynamically (defines FPC_LINK_DYNAMIC)
|
**2XD_Try to link units dynamically (defines FPC_LINK_DYNAMIC)
|
||||||
**2Xi_Use internal linker
|
**2Xi_Use internal linker
|
||||||
**2Xm_Generate link map
|
**2Xm_Generate link map
|
||||||
|
@ -734,7 +734,7 @@ const
|
|||||||
option_info=11024;
|
option_info=11024;
|
||||||
option_help_pages=11025;
|
option_help_pages=11025;
|
||||||
|
|
||||||
MsgTxtSize = 45492;
|
MsgTxtSize = 45576;
|
||||||
|
|
||||||
MsgIdxMax : array[1..20] of longint=(
|
MsgIdxMax : array[1..20] of longint=(
|
||||||
24,86,238,84,63,50,108,22,135,60,
|
24,86,238,84,63,50,108,22,135,60,
|
||||||
|
@ -1071,19 +1071,22 @@ const msgtxt : array[0..000189,1..240] of char=(
|
|||||||
'**2Xd_Do not use standard library search path (needed for cross compil'+
|
'**2Xd_Do not use standard library search path (needed for cross compil'+
|
||||||
'e)'#010+
|
'e)'#010+
|
||||||
'**2Xe_Use external linker'#010+
|
'**2Xe_Use external linker'#010+
|
||||||
'**2XD_Try to link units dynamically (defines FPC_LINK_DYNAMIC)'#010+
|
'**2Xg_Create debuginfo in a separate file and add a debuglink section '+
|
||||||
|
'to executable'#010+
|
||||||
|
'**2XD_Try to link units dynam','ically (defines FPC_LINK_DYNAMIC)'#010+
|
||||||
'**2Xi_Use internal linker'#010+
|
'**2Xi_Use internal linker'#010+
|
||||||
'**2Xm_Generate link',' map'#010+
|
'**2Xm_Generate link map'#010+
|
||||||
'**2XM<x>_Set the name of the '#039'main'#039' program routine (default i'+
|
'**2XM<x>_Set the name of the '#039'main'#039' program routine (default i'+
|
||||||
's '#039'main'#039')'#010+
|
's '#039'main'#039')'#010+
|
||||||
'**2XP<x>_Prepend the binutils names with the prefix <x>'#010+
|
'**2XP<x>_Prepend the binutils names with the prefix <x>'#010+
|
||||||
'**2Xr<x>_Set library search path to <x> (needed for cross compile) (Be'+
|
'**2Xr<x>_Set library se','arch path to <x> (needed for cross compile) ('+
|
||||||
'OS, Linux)'#010+
|
'BeOS, Linux)'#010+
|
||||||
'**2XR<x>_Prepend <x> to al','l linker search paths (BeOS, Darwin, FreeB'+
|
'**2XR<x>_Prepend <x> to all linker search paths (BeOS, Darwin, FreeBSD'+
|
||||||
'SD, Linux, Mac OS, Solaris)'#010+
|
', Linux, Mac OS, Solaris)'#010+
|
||||||
'**2Xs_Strip all symbols from executable'#010+
|
'**2Xs_Strip all symbols from executable'#010+
|
||||||
'**2XS_Try to link units statically (default, defines FPC_LINK_STATIC)'#010+
|
'**2XS_Try to link units statically (default, d','efines FPC_LINK_STATIC'+
|
||||||
'**2Xt_Link with static libraries (-static is passed to linke','r)'#010+
|
')'#010+
|
||||||
|
'**2Xt_Link with static libraries (-static is passed to linker)'#010+
|
||||||
'**2XX_Try to smartlink units (defines FPC_LINK_SMART)'#010+
|
'**2XX_Try to smartlink units (defines FPC_LINK_SMART)'#010+
|
||||||
'**1*_'#010+
|
'**1*_'#010+
|
||||||
'**1?_Show this help'#010+
|
'**1?_Show this help'#010+
|
||||||
|
@ -102,6 +102,9 @@ interface
|
|||||||
N_EXCL = $C2;
|
N_EXCL = $C2;
|
||||||
N_RBRAC = $E0;
|
N_RBRAC = $E0;
|
||||||
|
|
||||||
|
{ GNU extensions }
|
||||||
|
debuglinkname='.gnu_debuglink';
|
||||||
|
|
||||||
type
|
type
|
||||||
TObjSectionOption = (
|
TObjSectionOption = (
|
||||||
{ Has Data available in the file }
|
{ Has Data available in the file }
|
||||||
@ -388,6 +391,8 @@ interface
|
|||||||
property IsVar: boolean read FIsVar;
|
property IsVar: boolean read FIsVar;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
TExeWriteMode = (ewm_exefull,ewm_dbgonly,ewm_exeonly);
|
||||||
|
|
||||||
TExeOutput = class
|
TExeOutput = class
|
||||||
private
|
private
|
||||||
{ ExeSectionList }
|
{ ExeSectionList }
|
||||||
@ -395,7 +400,6 @@ interface
|
|||||||
FCExeSection : TExeSectionClass;
|
FCExeSection : TExeSectionClass;
|
||||||
FCurrExeSec : TExeSection;
|
FCurrExeSec : TExeSection;
|
||||||
FExeSectionList : TFPHashObjectList;
|
FExeSectionList : TFPHashObjectList;
|
||||||
FDebugSectionList : TFPHashObjectList;
|
|
||||||
Fzeronr : longint;
|
Fzeronr : longint;
|
||||||
{ Symbols }
|
{ Symbols }
|
||||||
FExeSymbolList : TFPHashObjectList;
|
FExeSymbolList : TFPHashObjectList;
|
||||||
@ -410,6 +414,7 @@ interface
|
|||||||
FImageBase : aint;
|
FImageBase : aint;
|
||||||
protected
|
protected
|
||||||
{ writer }
|
{ writer }
|
||||||
|
FExeWriteMode : TExeWriteMode;
|
||||||
FWriter : TObjectwriter;
|
FWriter : TObjectwriter;
|
||||||
commonObjSection : TObjSection;
|
commonObjSection : TObjSection;
|
||||||
internalObjData : TObjData;
|
internalObjData : TObjData;
|
||||||
@ -441,11 +446,15 @@ interface
|
|||||||
procedure Order_Symbol(const aname:string);virtual;
|
procedure Order_Symbol(const aname:string);virtual;
|
||||||
procedure Order_EndExeSection;virtual;
|
procedure Order_EndExeSection;virtual;
|
||||||
procedure Order_ObjSection(const aname:string);virtual;
|
procedure Order_ObjSection(const aname:string);virtual;
|
||||||
procedure CalcPos_ExeSection(const aname:string);virtual;
|
procedure MemPos_Start;virtual;
|
||||||
procedure CalcPos_EndExeSection;virtual;
|
procedure MemPos_Header;virtual;
|
||||||
procedure CalcPos_Header;virtual;
|
procedure MemPos_ExeSection(const aname:string);virtual;
|
||||||
procedure CalcPos_Start;virtual;
|
procedure MemPos_EndExeSection;virtual;
|
||||||
procedure CalcPos_Symbols;virtual;
|
procedure DataPos_Start;virtual;
|
||||||
|
procedure DataPos_Header;virtual;
|
||||||
|
procedure DataPos_ExeSection(const aname:string);virtual;
|
||||||
|
procedure DataPos_EndExeSection;virtual;
|
||||||
|
procedure DataPos_Symbols;virtual;
|
||||||
procedure BuildVTableTree(VTInheritList,VTEntryList:TFPObjectList);
|
procedure BuildVTableTree(VTInheritList,VTEntryList:TFPObjectList);
|
||||||
procedure PackUnresolvedExeSymbols(const s:string);
|
procedure PackUnresolvedExeSymbols(const s:string);
|
||||||
procedure ResolveSymbols(StaticLibraryList:TFPHashObjectList);
|
procedure ResolveSymbols(StaticLibraryList:TFPHashObjectList);
|
||||||
@ -455,12 +464,12 @@ interface
|
|||||||
procedure MergeStabs;
|
procedure MergeStabs;
|
||||||
procedure RemoveUnreferencedSections;
|
procedure RemoveUnreferencedSections;
|
||||||
procedure RemoveEmptySections;
|
procedure RemoveEmptySections;
|
||||||
|
procedure RemoveDebugInfo;
|
||||||
procedure GenerateLibraryImports(ImportLibraryList:TFPHashObjectList);virtual;
|
procedure GenerateLibraryImports(ImportLibraryList:TFPHashObjectList);virtual;
|
||||||
function writedbgfile(const fn:string):boolean;
|
procedure GenerateDebugLink(const dbgname:string;dbgcrc:cardinal);
|
||||||
function writeexefile(const fn:string):boolean;
|
function WriteExeFile(const fn:string):boolean;
|
||||||
property Writer:TObjectWriter read FWriter;
|
property Writer:TObjectWriter read FWriter;
|
||||||
property ExeSectionList:TFPHashObjectList read FExeSectionList;
|
property ExeSectionList:TFPHashObjectList read FExeSectionList;
|
||||||
property DebugSectionList:TFPHashObjectList read FDebugSectionList;
|
|
||||||
property ObjDataList:TFPObjectList read FObjDataList;
|
property ObjDataList:TFPObjectList read FObjDataList;
|
||||||
property ExeSymbolList:TFPHashObjectList read FExeSymbolList;
|
property ExeSymbolList:TFPHashObjectList read FExeSymbolList;
|
||||||
property UnresolvedExeSymbols:TFPObjectList read FUnresolvedExeSymbols;
|
property UnresolvedExeSymbols:TFPObjectList read FUnresolvedExeSymbols;
|
||||||
@ -470,6 +479,7 @@ interface
|
|||||||
property EntryName:string read FEntryName write FEntryName;
|
property EntryName:string read FEntryName write FEntryName;
|
||||||
property ImageBase:aint read FImageBase write FImageBase;
|
property ImageBase:aint read FImageBase write FImageBase;
|
||||||
property CurrExeSec:TExeSection read FCurrExeSec;
|
property CurrExeSec:TExeSection read FCurrExeSec;
|
||||||
|
property ExeWriteMode:TExeWriteMode read FExeWriteMode write FExeWriteMode;
|
||||||
end;
|
end;
|
||||||
TExeOutputClass=class of TExeOutput;
|
TExeOutputClass=class of TExeOutput;
|
||||||
|
|
||||||
@ -1384,6 +1394,7 @@ implementation
|
|||||||
begin
|
begin
|
||||||
{ init writer }
|
{ init writer }
|
||||||
FWriter:=TObjectwriter.create;
|
FWriter:=TObjectwriter.create;
|
||||||
|
FExeWriteMode:=ewm_exefull;
|
||||||
{ object files }
|
{ object files }
|
||||||
FObjDataList:=TFPObjectList.Create(true);
|
FObjDataList:=TFPObjectList.Create(true);
|
||||||
{ symbols }
|
{ symbols }
|
||||||
@ -1395,7 +1406,6 @@ implementation
|
|||||||
FEntryName:='start';
|
FEntryName:='start';
|
||||||
{ sections }
|
{ sections }
|
||||||
FExeSectionList:=TFPHashObjectList.Create(true);
|
FExeSectionList:=TFPHashObjectList.Create(true);
|
||||||
FDebugSectionList:=TFPHashObjectList.Create(true);
|
|
||||||
FImageBase:=0;
|
FImageBase:=0;
|
||||||
SectionMemAlign:=$1000;
|
SectionMemAlign:=$1000;
|
||||||
SectionDataAlign:=$200;
|
SectionDataAlign:=$200;
|
||||||
@ -1412,102 +1422,20 @@ implementation
|
|||||||
CommonObjSymbols.free;
|
CommonObjSymbols.free;
|
||||||
ExeVTableList.free;
|
ExeVTableList.free;
|
||||||
FExeSectionList.free;
|
FExeSectionList.free;
|
||||||
FDebugSectionList.free;
|
|
||||||
ObjDatalist.free;
|
ObjDatalist.free;
|
||||||
FWriter.free;
|
FWriter.free;
|
||||||
inherited destroy;
|
inherited destroy;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
function TExeOutput.writedbgfile(const fn:string):boolean;
|
function TExeOutput.WriteExeFile(const fn:string):boolean;
|
||||||
var
|
|
||||||
ObjWriter : TObjectwriter;
|
|
||||||
exesec : TExeSection;
|
|
||||||
objsec : TObjSection;
|
|
||||||
header : string[6];
|
|
||||||
s : string;
|
|
||||||
i,j,
|
|
||||||
seccnt,
|
|
||||||
secstart : longint;
|
|
||||||
begin
|
begin
|
||||||
result:=false;
|
result:=false;
|
||||||
{
|
|
||||||
File layout:
|
|
||||||
<header> 6 bytes
|
|
||||||
<section count> 4 bytes
|
|
||||||
(
|
|
||||||
<section offset> 4 bytes
|
|
||||||
<section name> asciiz
|
|
||||||
...
|
|
||||||
)
|
|
||||||
(
|
|
||||||
<section data>
|
|
||||||
...
|
|
||||||
)
|
|
||||||
}
|
|
||||||
header:='FPCDBG';
|
|
||||||
{ Calculate file offsets }
|
|
||||||
secstart:=length(header)+sizeof(seccnt);
|
|
||||||
for i:=0 to DebugSectionList.Count-1 do
|
|
||||||
begin
|
|
||||||
exesec:=TExeSection(DebugSectionList[i]);
|
|
||||||
inc(secstart,sizeof(secstart)+length(exesec.Name)+1);
|
|
||||||
end;
|
|
||||||
for i:=0 to DebugSectionList.Count-1 do
|
|
||||||
begin
|
|
||||||
exesec:=TExeSection(DebugSectionList[i]);
|
|
||||||
exesec.DataPos:=secstart;
|
|
||||||
for j:=0 to exesec.ObjSectionList.Count-1 do
|
|
||||||
begin
|
|
||||||
objsec:=TObjSection(exesec.ObjSectionList[j]);
|
|
||||||
inc(secstart,objsec.size);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
{ Create file }
|
|
||||||
ObjWriter:=TObjectwriter.Create;
|
|
||||||
if not ObjWriter.createfile(fn) then
|
|
||||||
begin
|
|
||||||
ObjWriter.Free;
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
{ Header }
|
|
||||||
ObjWriter.Write(header[1], Length(header));
|
|
||||||
seccnt:=DebugSectionList.Count;
|
|
||||||
ObjWriter.Write(seccnt,sizeof(seccnt));
|
|
||||||
for i:=0 to DebugSectionList.Count-1 do
|
|
||||||
begin
|
|
||||||
exesec:=TExeSection(DebugSectionList[i]);
|
|
||||||
ObjWriter.Write(exesec.DataPos,sizeof(secstart));
|
|
||||||
s:=exesec.Name;
|
|
||||||
ObjWriter.Write(s[1],length(s));
|
|
||||||
ObjWriter.writezeros(1);
|
|
||||||
end;
|
|
||||||
{ Write section data }
|
|
||||||
for i:=0 to DebugSectionList.Count-1 do
|
|
||||||
begin
|
|
||||||
exesec:=TExeSection(DebugSectionList[i]);
|
|
||||||
if exesec.DataPos<>ObjWriter.ObjSize then
|
|
||||||
internalerror(200702241);
|
|
||||||
for j:=0 to exesec.ObjSectionList.Count-1 do
|
|
||||||
begin
|
|
||||||
objsec:=TObjSection(exesec.ObjSectionList[j]);
|
|
||||||
ObjWriter.writearray(objsec.data);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
ObjWriter.Free;
|
|
||||||
result:=true;
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
function TExeOutput.writeexefile(const fn:string):boolean;
|
|
||||||
begin
|
|
||||||
result:=false;
|
|
||||||
|
|
||||||
if FWriter.createfile(fn) then
|
if FWriter.createfile(fn) then
|
||||||
begin
|
begin
|
||||||
{ Only write the .o if there are no errors }
|
{ Only write the .o if there are no errors }
|
||||||
if errorcount=0 then
|
if errorcount=0 then
|
||||||
result:=writeData
|
result:=writedata
|
||||||
else
|
else
|
||||||
result:=true;
|
result:=true;
|
||||||
{ close the writer }
|
{ close the writer }
|
||||||
@ -1703,7 +1631,18 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TExeOutput.CalcPos_ExeSection(const aname:string);
|
procedure TExeOutput.MemPos_Start;
|
||||||
|
begin
|
||||||
|
CurrMemPos:=0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TExeOutput.MemPos_Header;
|
||||||
|
begin
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TExeOutput.MemPos_ExeSection(const aname:string);
|
||||||
var
|
var
|
||||||
i : longint;
|
i : longint;
|
||||||
objsec : TObjSection;
|
objsec : TObjSection;
|
||||||
@ -1717,6 +1656,51 @@ implementation
|
|||||||
CurrMemPos:=align(CurrMemPos,SectionMemAlign);
|
CurrMemPos:=align(CurrMemPos,SectionMemAlign);
|
||||||
CurrExeSec.MemPos:=CurrMemPos;
|
CurrExeSec.MemPos:=CurrMemPos;
|
||||||
|
|
||||||
|
{ set position of object ObjSections }
|
||||||
|
for i:=0 to CurrExeSec.ObjSectionList.Count-1 do
|
||||||
|
begin
|
||||||
|
objsec:=TObjSection(CurrExeSec.ObjSectionList[i]);
|
||||||
|
objsec.setmempos(CurrMemPos);
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ calculate size of the section }
|
||||||
|
CurrExeSec.Size:=CurrMemPos-CurrExeSec.MemPos;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TExeOutput.MemPos_EndExeSection;
|
||||||
|
begin
|
||||||
|
if not assigned(CurrExeSec) then
|
||||||
|
exit;
|
||||||
|
FCurrExeSec:=nil;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TExeOutput.DataPos_Start;
|
||||||
|
begin
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TExeOutput.DataPos_Header;
|
||||||
|
begin
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TExeOutput.DataPos_ExeSection(const aname:string);
|
||||||
|
var
|
||||||
|
i : longint;
|
||||||
|
objsec : TObjSection;
|
||||||
|
begin
|
||||||
|
{ Section can be removed }
|
||||||
|
FCurrExeSec:=FindExeSection(aname);
|
||||||
|
if not assigned(CurrExeSec) then
|
||||||
|
exit;
|
||||||
|
|
||||||
|
{ don't write normal section if writing only debug info }
|
||||||
|
if (ExeWriteMode=ewm_dbgonly) and
|
||||||
|
not(oso_debug in CurrExeSec.SecOptions) then
|
||||||
|
exit;
|
||||||
|
|
||||||
if (oso_Data in currexesec.SecOptions) then
|
if (oso_Data in currexesec.SecOptions) then
|
||||||
begin
|
begin
|
||||||
CurrDataPos:=align(CurrDataPos,SectionDataAlign);
|
CurrDataPos:=align(CurrDataPos,SectionDataAlign);
|
||||||
@ -1727,26 +1711,19 @@ implementation
|
|||||||
for i:=0 to CurrExeSec.ObjSectionList.Count-1 do
|
for i:=0 to CurrExeSec.ObjSectionList.Count-1 do
|
||||||
begin
|
begin
|
||||||
objsec:=TObjSection(CurrExeSec.ObjSectionList[i]);
|
objsec:=TObjSection(CurrExeSec.ObjSectionList[i]);
|
||||||
|
|
||||||
{ Position in memory }
|
|
||||||
objsec.setmempos(CurrMemPos);
|
|
||||||
{ Position in File }
|
|
||||||
if (oso_Data in objsec.SecOptions) then
|
if (oso_Data in objsec.SecOptions) then
|
||||||
begin
|
begin
|
||||||
if not (oso_Data in currexesec.SecOptions) then
|
if not(oso_Data in currexesec.SecOptions) then
|
||||||
internalerror(200603043);
|
internalerror(200603043);
|
||||||
if not assigned(objsec.Data) then
|
if not assigned(objsec.Data) then
|
||||||
internalerror(200603044);
|
internalerror(200603044);
|
||||||
objsec.setDatapos(CurrDataPos);
|
objsec.setDatapos(CurrDataPos);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ calculate size of the section }
|
|
||||||
CurrExeSec.Size:=CurrMemPos-CurrExeSec.MemPos;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TExeOutput.CalcPos_EndExeSection;
|
procedure TExeOutput.DataPos_EndExeSection;
|
||||||
begin
|
begin
|
||||||
if not assigned(CurrExeSec) then
|
if not assigned(CurrExeSec) then
|
||||||
exit;
|
exit;
|
||||||
@ -1754,19 +1731,7 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TExeOutput.CalcPos_Start;
|
procedure TExeOutput.DataPos_Symbols;
|
||||||
begin
|
|
||||||
CurrMemPos:=0;
|
|
||||||
CurrDataPos:=0;
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
procedure TExeOutput.CalcPos_Header;
|
|
||||||
begin
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
procedure TExeOutput.CalcPos_Symbols;
|
|
||||||
var
|
var
|
||||||
i : longint;
|
i : longint;
|
||||||
sym : TExeSymbol;
|
sym : TExeSymbol;
|
||||||
@ -2067,6 +2032,41 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TExeOutput.GenerateDebugLink(const dbgname:string;dbgcrc:cardinal);
|
||||||
|
var
|
||||||
|
debuglink : array[0..1023] of byte;
|
||||||
|
len : longint;
|
||||||
|
objsec : TObjSection;
|
||||||
|
exesec : TExeSection;
|
||||||
|
begin
|
||||||
|
{ From the gdb manual chapter 15. GDB Files:
|
||||||
|
|
||||||
|
* A filename, with any leading directory components removed, followed by a zero byte,
|
||||||
|
* zero to three bytes of padding, as needed to reach the next four-byte boundary within the section, and
|
||||||
|
* a four-byte CRC checksum, stored in the same endianness used for the executable file itself. The checksum is computed
|
||||||
|
on the debugging information file's full contents by the function given below, passing zero as the crc argument.
|
||||||
|
}
|
||||||
|
fillchar(debuglink,sizeof(debuglink),0);
|
||||||
|
len:=0;
|
||||||
|
move(dbgname[1],debuglink[len],length(dbgname));
|
||||||
|
inc(len,length(dbgname)+1);
|
||||||
|
len:=align(len,4);
|
||||||
|
if source_info.endian<>target_info.endian then
|
||||||
|
SwapEndian(dbgcrc);
|
||||||
|
move(dbgcrc,debuglink[len],sizeof(cardinal));
|
||||||
|
inc(len,4);
|
||||||
|
{ Add section }
|
||||||
|
exesec:=FindExeSection(debuglinkname);
|
||||||
|
if not assigned(exesec) then
|
||||||
|
exesec:=CExeSection.create(ExeSectionList,debuglinkname);
|
||||||
|
exesec.SecOptions:=[oso_data,oso_keep];
|
||||||
|
exesec.SecAlign:=4;
|
||||||
|
objsec:=internalObjData.createsection(exesec.name,0,exesec.SecOptions);
|
||||||
|
internalObjData.writebytes(debuglink,len);
|
||||||
|
exesec.AddObjSection(objsec);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TExeOutput.GenerateLibraryImports(ImportLibraryList:TFPHashObjectList);
|
procedure TExeOutput.GenerateLibraryImports(ImportLibraryList:TFPHashObjectList);
|
||||||
begin
|
begin
|
||||||
end;
|
end;
|
||||||
@ -2184,7 +2184,7 @@ implementation
|
|||||||
(stabexesec.ObjSectionlist.count=0) then
|
(stabexesec.ObjSectionlist.count=0) then
|
||||||
exit;
|
exit;
|
||||||
{ Create new stabsection }
|
{ Create new stabsection }
|
||||||
stabRelocofs:=pointer(@hstab.nvalue)-@hstab;
|
stabRelocofs:=pbyte(@hstab.nvalue)-pbyte(@hstab);
|
||||||
mergedstabsec:=internalObjData.CreateSection(sec_stab,'');
|
mergedstabsec:=internalObjData.CreateSection(sec_stab,'');
|
||||||
mergedstabstrsec:=internalObjData.CreateSection(sec_stabstr,'');
|
mergedstabstrsec:=internalObjData.CreateSection(sec_stabstr,'');
|
||||||
|
|
||||||
@ -2338,22 +2338,12 @@ implementation
|
|||||||
begin
|
begin
|
||||||
exesec:=TExeSection(ExeSectionList[i]);
|
exesec:=TExeSection(ExeSectionList[i]);
|
||||||
|
|
||||||
if (cs_link_separate_dbg_file in current_settings.globalswitches) and
|
|
||||||
(oso_debug in exesec.SecOptions) then
|
|
||||||
begin
|
|
||||||
Comment(V_Debug,'Adding debug section '+exesec.name+' to debugfile');
|
|
||||||
ExeSectionList.OwnsObjects:=false;
|
|
||||||
ExeSectionList[i]:=nil;
|
|
||||||
ExeSectionList.OwnsObjects:=true;
|
|
||||||
DebugSectionList.Add(exesec.Name,exesec);
|
|
||||||
end
|
|
||||||
else
|
|
||||||
begin
|
|
||||||
doremove:=not(oso_keep in exesec.SecOptions) and
|
doremove:=not(oso_keep in exesec.SecOptions) and
|
||||||
(
|
(
|
||||||
(exesec.ObjSectionlist.count=0) or
|
(exesec.ObjSectionlist.count=0) or
|
||||||
(
|
(
|
||||||
(cs_link_strip in current_settings.globalswitches) and
|
(cs_link_strip in current_settings.globalswitches) and
|
||||||
|
not(cs_link_separate_dbg_file in current_settings.globalswitches) and
|
||||||
(oso_debug in exesec.SecOptions)
|
(oso_debug in exesec.SecOptions)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@ -2374,6 +2364,20 @@ implementation
|
|||||||
ExeSectionList[i]:=nil;
|
ExeSectionList[i]:=nil;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
ExeSectionList.Pack;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TExeOutput.RemoveDebugInfo;
|
||||||
|
var
|
||||||
|
i : longint;
|
||||||
|
exesec : TExeSection;
|
||||||
|
begin
|
||||||
|
for i:=0 to ExeSectionList.Count-1 do
|
||||||
|
begin
|
||||||
|
exesec:=TExeSection(ExeSectionList[i]);
|
||||||
|
if (oso_debug in exesec.SecOptions) then
|
||||||
|
ExeSectionList[i]:=nil;
|
||||||
end;
|
end;
|
||||||
ExeSectionList.Pack;
|
ExeSectionList.Pack;
|
||||||
end;
|
end;
|
||||||
@ -2551,16 +2555,14 @@ implementation
|
|||||||
|
|
||||||
|
|
||||||
procedure TExeOutput.FixupRelocations;
|
procedure TExeOutput.FixupRelocations;
|
||||||
|
|
||||||
procedure FixupSectionList(List:TFPHashObjectList);
|
|
||||||
var
|
var
|
||||||
i,j : longint;
|
i,j : longint;
|
||||||
exesec : TExeSection;
|
exesec : TExeSection;
|
||||||
objsec : TObjSection;
|
objsec : TObjSection;
|
||||||
begin
|
begin
|
||||||
for i:=0 to List.Count-1 do
|
for i:=0 to ExeSectionList.Count-1 do
|
||||||
begin
|
begin
|
||||||
exesec:=TExeSection(List[i]);
|
exesec:=TExeSection(ExeSectionList[i]);
|
||||||
if not assigned(exesec) then
|
if not assigned(exesec) then
|
||||||
continue;
|
continue;
|
||||||
for j:=0 to exesec.ObjSectionlist.count-1 do
|
for j:=0 to exesec.ObjSectionlist.count-1 do
|
||||||
@ -2573,11 +2575,6 @@ implementation
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
begin
|
|
||||||
FixupSectionList(ExeSectionList);
|
|
||||||
FixupSectionList(DebugSectionList);
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
{****************************************************************************
|
{****************************************************************************
|
||||||
TObjInput
|
TObjInput
|
||||||
|
@ -227,14 +227,16 @@ interface
|
|||||||
nsects : smallint;
|
nsects : smallint;
|
||||||
nsyms,
|
nsyms,
|
||||||
sympos : aint;
|
sympos : aint;
|
||||||
|
function totalheadersize:longint;
|
||||||
procedure ExeSectionList_pass2_header(p:TObject;arg:pointer);
|
procedure ExeSectionList_pass2_header(p:TObject;arg:pointer);
|
||||||
procedure write_symbol(const name:string;value:aint;section:smallint;typ,aux:byte);
|
procedure write_symbol(const name:string;value:aint;section:smallint;typ,aux:byte);
|
||||||
procedure globalsyms_write_symbol(p:TObject;arg:pointer);
|
procedure globalsyms_write_symbol(p:TObject;arg:pointer);
|
||||||
procedure ExeSectionList_write_header(p:TObject;arg:pointer);
|
procedure ExeSectionList_write_header(p:TObject;arg:pointer);
|
||||||
procedure ExeSectionList_write_data(p:TObject;arg:pointer);
|
procedure ExeSectionList_write_data(p:TObject;arg:pointer);
|
||||||
protected
|
protected
|
||||||
procedure CalcPos_Header;override;
|
procedure MemPos_Header;override;
|
||||||
procedure CalcPos_Symbols;override;
|
procedure DataPos_Header;override;
|
||||||
|
procedure DataPos_Symbols;override;
|
||||||
function writedata:boolean;override;
|
function writedata:boolean;override;
|
||||||
procedure Order_ObjSectionList(ObjSectionList : TFPObjectList);override;
|
procedure Order_ObjSectionList(ObjSectionList : TFPObjectList);override;
|
||||||
public
|
public
|
||||||
@ -253,7 +255,7 @@ interface
|
|||||||
constructor create;override;
|
constructor create;override;
|
||||||
procedure GenerateLibraryImports(ImportLibraryList:TFPHashObjectList);override;
|
procedure GenerateLibraryImports(ImportLibraryList:TFPHashObjectList);override;
|
||||||
procedure Order_End;override;
|
procedure Order_End;override;
|
||||||
procedure CalcPos_ExeSection(const aname:string);override;
|
procedure MemPos_ExeSection(const aname:string);override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
TObjSymbolrec = record
|
TObjSymbolrec = record
|
||||||
@ -1988,17 +1990,13 @@ const pemagic : array[0..3] of byte = (
|
|||||||
sechdr.vsize:=Size
|
sechdr.vsize:=Size
|
||||||
else
|
else
|
||||||
sechdr.vsize:=mempos;
|
sechdr.vsize:=mempos;
|
||||||
|
|
||||||
{ sechdr.dataSize is size of initilized data. For .bss section it must be zero }
|
{ sechdr.dataSize is size of initilized data. For .bss section it must be zero }
|
||||||
if Name <> '.bss' then
|
if (Name <> '.bss') then
|
||||||
begin
|
|
||||||
if oso_data in SecOptions then
|
|
||||||
begin
|
|
||||||
sechdr.dataSize:=Size;
|
sechdr.dataSize:=Size;
|
||||||
|
if (sechdr.dataSize>0) and
|
||||||
|
(oso_data in SecOptions) then
|
||||||
sechdr.datapos:=datapos;
|
sechdr.datapos:=datapos;
|
||||||
end
|
|
||||||
else
|
|
||||||
sechdr.dataSize:=Size;
|
|
||||||
end;
|
|
||||||
sechdr.nrelocs:=0;
|
sechdr.nrelocs:=0;
|
||||||
sechdr.relocpos:=0;
|
sechdr.relocpos:=0;
|
||||||
if win32 then
|
if win32 then
|
||||||
@ -2014,6 +2012,10 @@ const pemagic : array[0..3] of byte = (
|
|||||||
begin
|
begin
|
||||||
with TExeSection(p) do
|
with TExeSection(p) do
|
||||||
begin
|
begin
|
||||||
|
{ The debuginfo sections should already be stripped }
|
||||||
|
{ if (ExeWriteMode=ewm_exeonly) and
|
||||||
|
(oso_debug in SecOptions) then
|
||||||
|
internalerror(200801161); }
|
||||||
inc(plongint(arg)^);
|
inc(plongint(arg)^);
|
||||||
secsymidx:=plongint(arg)^;
|
secsymidx:=plongint(arg)^;
|
||||||
end;
|
end;
|
||||||
@ -2024,9 +2026,15 @@ const pemagic : array[0..3] of byte = (
|
|||||||
var
|
var
|
||||||
objsec : TObjSection;
|
objsec : TObjSection;
|
||||||
i : longint;
|
i : longint;
|
||||||
|
b : boolean;
|
||||||
begin
|
begin
|
||||||
with texesection(p) do
|
with texesection(p) do
|
||||||
begin
|
begin
|
||||||
|
{ don't write normal section if writing only debug info }
|
||||||
|
if (ExeWriteMode=ewm_dbgonly) and
|
||||||
|
not(oso_debug in SecOptions) then
|
||||||
|
exit;
|
||||||
|
|
||||||
if oso_data in secoptions then
|
if oso_data in secoptions then
|
||||||
begin
|
begin
|
||||||
FWriter.Writezeros(Align(FWriter.Size,SectionDataAlign)-FWriter.Size);
|
FWriter.Writezeros(Align(FWriter.Size,SectionDataAlign)-FWriter.Size);
|
||||||
@ -2048,7 +2056,7 @@ const pemagic : array[0..3] of byte = (
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure tcoffexeoutput.CalcPos_Header;
|
function tcoffexeoutput.totalheadersize:longint;
|
||||||
var
|
var
|
||||||
stubsize,
|
stubsize,
|
||||||
optheadersize : longint;
|
optheadersize : longint;
|
||||||
@ -2063,20 +2071,30 @@ const pemagic : array[0..3] of byte = (
|
|||||||
stubsize:=sizeof(go32v2stub);
|
stubsize:=sizeof(go32v2stub);
|
||||||
optheadersize:=sizeof(coffdjoptheader);
|
optheadersize:=sizeof(coffdjoptheader);
|
||||||
end;
|
end;
|
||||||
{ retrieve amount of ObjSections }
|
result:=stubsize+sizeof(tcoffheader)+optheadersize;
|
||||||
nsects:=0;
|
|
||||||
ExeSectionList.ForEachCall(@ExeSectionList_pass2_header,@nsects);
|
|
||||||
{ calculate start positions after the headers }
|
|
||||||
currdatapos:=stubsize+optheadersize+sizeof(tcoffsechdr)*nsects;
|
|
||||||
currmempos:=stubsize+optheadersize+sizeof(tcoffsechdr)*nsects;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure tcoffexeoutput.CalcPos_Symbols;
|
procedure tcoffexeoutput.MemPos_Header;
|
||||||
begin
|
begin
|
||||||
inherited CalcPos_Symbols;
|
{ calculate start positions after the headers }
|
||||||
nsyms:=0;
|
currmempos:=totalheadersize+sizeof(tcoffsechdr)*(ExeSectionList.Count-2);
|
||||||
sympos:=0;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure tcoffexeoutput.DataPos_Header;
|
||||||
|
begin
|
||||||
|
{ retrieve amount of sections }
|
||||||
|
nsects:=0;
|
||||||
|
ExeSectionList.ForEachCall(@ExeSectionList_pass2_header,@nsects);
|
||||||
|
{ calculate start positions after the headers }
|
||||||
|
currdatapos:=totalheadersize+sizeof(tcoffsechdr)*nsects;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure tcoffexeoutput.DataPos_Symbols;
|
||||||
|
begin
|
||||||
|
inherited DataPos_Symbols;
|
||||||
{ Calculating symbols position and size }
|
{ Calculating symbols position and size }
|
||||||
nsyms:=ExeSymbolList.Count;
|
nsyms:=ExeSymbolList.Count;
|
||||||
sympos:=CurrDataPos;
|
sympos:=CurrDataPos;
|
||||||
@ -2093,6 +2111,7 @@ const pemagic : array[0..3] of byte = (
|
|||||||
textExeSec,
|
textExeSec,
|
||||||
dataExeSec,
|
dataExeSec,
|
||||||
bssExeSec : TExeSection;
|
bssExeSec : TExeSection;
|
||||||
|
hassymbols : boolean;
|
||||||
|
|
||||||
procedure UpdateDataDir(const secname:string;idx:longint);
|
procedure UpdateDataDir(const secname:string;idx:longint);
|
||||||
var
|
var
|
||||||
@ -2116,6 +2135,12 @@ const pemagic : array[0..3] of byte = (
|
|||||||
if not assigned(TextExeSec) or
|
if not assigned(TextExeSec) or
|
||||||
not assigned(DataExeSec) then
|
not assigned(DataExeSec) then
|
||||||
internalerror(200602231);
|
internalerror(200602231);
|
||||||
|
{ do we need to write symbols? }
|
||||||
|
hassymbols:=(ExeWriteMode=ewm_dbgonly) or
|
||||||
|
(
|
||||||
|
(ExeWriteMode=ewm_exefull) and
|
||||||
|
not(cs_link_strip in current_settings.globalswitches)
|
||||||
|
);
|
||||||
{ Stub }
|
{ Stub }
|
||||||
if win32 then
|
if win32 then
|
||||||
begin
|
begin
|
||||||
@ -2124,11 +2149,12 @@ const pemagic : array[0..3] of byte = (
|
|||||||
end
|
end
|
||||||
else
|
else
|
||||||
FWriter.write(go32v2stub,sizeof(go32v2stub));
|
FWriter.write(go32v2stub,sizeof(go32v2stub));
|
||||||
{ COFF header }
|
{ Initial header, will be updated later }
|
||||||
fillchar(header,sizeof(header),0);
|
fillchar(header,sizeof(header),0);
|
||||||
header.mach:=COFF_MAGIC;
|
header.mach:=COFF_MAGIC;
|
||||||
header.nsects:=nsects;
|
header.nsects:=nsects;
|
||||||
header.sympos:=sympos;
|
header.sympos:=sympos;
|
||||||
|
if hassymbols then
|
||||||
header.syms:=nsyms;
|
header.syms:=nsyms;
|
||||||
if win32 then
|
if win32 then
|
||||||
header.opthdr:=sizeof(tcoffpeoptheader)
|
header.opthdr:=sizeof(tcoffpeoptheader)
|
||||||
@ -2137,21 +2163,21 @@ const pemagic : array[0..3] of byte = (
|
|||||||
if win32 then
|
if win32 then
|
||||||
begin
|
begin
|
||||||
header.flag:=PE_FILE_EXECUTABLE_IMAGE or PE_FILE_LINE_NUMS_STRIPPED;
|
header.flag:=PE_FILE_EXECUTABLE_IMAGE or PE_FILE_LINE_NUMS_STRIPPED;
|
||||||
|
if target_info.system in [system_i386_win32,system_arm_wince,system_i386_wince] then
|
||||||
|
header.flag:=header.flag or PE_FILE_32BIT_MACHINE;
|
||||||
if IsSharedLibrary then
|
if IsSharedLibrary then
|
||||||
header.flag:=header.flag or PE_FILE_DLL;
|
header.flag:=header.flag or PE_FILE_DLL;
|
||||||
if FindExeSection('.reloc')=nil then
|
if FindExeSection('.reloc')=nil then
|
||||||
header.flag:=header.flag or PE_FILE_RELOCS_STRIPPED;
|
header.flag:=header.flag or PE_FILE_RELOCS_STRIPPED;
|
||||||
if FindExeSection('.stab')=nil then
|
if (FindExeSection('.stab')=nil) and
|
||||||
|
(FindExeSection('.debug_info')=nil) and
|
||||||
|
(FindExeSection('.gnu_debuglink')=nil) then
|
||||||
header.flag:=header.flag or PE_FILE_DEBUG_STRIPPED;
|
header.flag:=header.flag or PE_FILE_DEBUG_STRIPPED;
|
||||||
if (cs_link_strip in current_settings.globalswitches) then
|
if not hassymbols then
|
||||||
header.flag:=header.flag or PE_FILE_LOCAL_SYMS_STRIPPED;
|
header.flag:=header.flag or PE_FILE_LOCAL_SYMS_STRIPPED;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
header.flag:=COFF_FLAG_AR32WR or COFF_FLAG_EXE or COFF_FLAG_NORELOCS or COFF_FLAG_NOLINES;
|
header.flag:=COFF_FLAG_AR32WR or COFF_FLAG_EXE or COFF_FLAG_NORELOCS or COFF_FLAG_NOLINES;
|
||||||
|
|
||||||
if target_info.system in [system_i386_win32,system_arm_wince,system_i386_wince] then
|
|
||||||
header.flag:=header.flag or PE_FILE_32BIT_MACHINE;
|
|
||||||
|
|
||||||
FWriter.write(header,sizeof(header));
|
FWriter.write(header,sizeof(header));
|
||||||
{ Optional COFF Header }
|
{ Optional COFF Header }
|
||||||
if win32 then
|
if win32 then
|
||||||
@ -2224,17 +2250,14 @@ const pemagic : array[0..3] of byte = (
|
|||||||
{ Section data }
|
{ Section data }
|
||||||
ExeSectionList.ForEachCall(@ExeSectionList_write_data,nil);
|
ExeSectionList.ForEachCall(@ExeSectionList_write_data,nil);
|
||||||
{ Optional Symbols }
|
{ Optional Symbols }
|
||||||
if not(cs_link_strip in current_settings.globalswitches) then
|
|
||||||
begin
|
|
||||||
if SymPos<>FWriter.Size then
|
if SymPos<>FWriter.Size then
|
||||||
internalerror(200602252);
|
internalerror(200602252);
|
||||||
{ ObjSymbols }
|
if hassymbols then
|
||||||
ExeSymbolList.ForEachCall(@globalsyms_write_symbol,nil);
|
ExeSymbolList.ForEachCall(@globalsyms_write_symbol,nil);
|
||||||
{ Strings }
|
{ Strings }
|
||||||
i:=FCoffStrs.size+4;
|
i:=FCoffStrs.size+4;
|
||||||
FWriter.write(i,4);
|
FWriter.write(i,4);
|
||||||
FWriter.writearray(FCoffStrs);
|
FWriter.writearray(FCoffStrs);
|
||||||
end;
|
|
||||||
{ Release }
|
{ Release }
|
||||||
FCoffStrs.Free;
|
FCoffStrs.Free;
|
||||||
FCoffSyms.Free;
|
FCoffSyms.Free;
|
||||||
@ -2583,7 +2606,7 @@ const pemagic : array[0..3] of byte = (
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TPECoffexeoutput.CalcPos_ExeSection(const aname:string);
|
procedure TPECoffexeoutput.MemPos_ExeSection(const aname:string);
|
||||||
begin
|
begin
|
||||||
if aname='.reloc' then
|
if aname='.reloc' then
|
||||||
GenerateRelocs;
|
GenerateRelocs;
|
||||||
|
@ -786,8 +786,8 @@ begin
|
|||||||
bufstart:=sizeof(tppuheader);
|
bufstart:=sizeof(tppuheader);
|
||||||
bufidx:=0;
|
bufidx:=0;
|
||||||
{reset}
|
{reset}
|
||||||
crc:=cardinal($ffffffff);
|
crc:=0;
|
||||||
interface_crc:=cardinal($ffffffff);
|
interface_crc:=0;
|
||||||
do_interface_crc:=true;
|
do_interface_crc:=true;
|
||||||
Error:=false;
|
Error:=false;
|
||||||
do_crc:=true;
|
do_crc:=true;
|
||||||
|
@ -774,7 +774,7 @@ implementation
|
|||||||
if (newlen-oldlen>12) and
|
if (newlen-oldlen>12) and
|
||||||
((newlen+length(prefix)>128) or (newlen-oldlen>32)) then
|
((newlen+length(prefix)>128) or (newlen-oldlen>32)) then
|
||||||
begin
|
begin
|
||||||
crc:=$ffffffff;
|
crc:=0;
|
||||||
for i:=0 to tprocdef(st.defowner).paras.count-1 do
|
for i:=0 to tprocdef(st.defowner).paras.count-1 do
|
||||||
begin
|
begin
|
||||||
hp:=tparavarsym(tprocdef(st.defowner).paras[i]);
|
hp:=tparavarsym(tprocdef(st.defowner).paras[i]);
|
||||||
@ -3336,7 +3336,7 @@ implementation
|
|||||||
if (newlen-oldlen>12) and
|
if (newlen-oldlen>12) and
|
||||||
((newlen>128) or (newlen-oldlen>64)) then
|
((newlen>128) or (newlen-oldlen>64)) then
|
||||||
begin
|
begin
|
||||||
crc:=$ffffffff;
|
crc:=0;
|
||||||
for i:=0 to paras.count-1 do
|
for i:=0 to paras.count-1 do
|
||||||
begin
|
begin
|
||||||
hp:=tparavarsym(paras[i]);
|
hp:=tparavarsym(paras[i]);
|
||||||
|
@ -1050,7 +1050,7 @@ implementation
|
|||||||
Concat(' OBJSECTION .idata$6*');
|
Concat(' OBJSECTION .idata$6*');
|
||||||
Concat(' OBJSECTION .idata$7*');
|
Concat(' OBJSECTION .idata$7*');
|
||||||
Concat('ENDEXESECTION');
|
Concat('ENDEXESECTION');
|
||||||
secnames:='.edata,.rsrc,.reloc,'+
|
secnames:='.edata,.rsrc,.reloc,.gnu_debuglink,'+
|
||||||
'.debug_aranges,.debug_pubnames,.debug_info,.debug_abbrev,.debug_line,.debug_frame,.debug_str,.debug_loc,'+
|
'.debug_aranges,.debug_pubnames,.debug_info,.debug_abbrev,.debug_line,.debug_frame,.debug_str,.debug_loc,'+
|
||||||
'.debug_macinfo,.debug_weaknames,.debug_funcnames,.debug_typenames,.debug_varnames,.debug_ranges';
|
'.debug_macinfo,.debug_weaknames,.debug_funcnames,.debug_typenames,.debug_varnames,.debug_ranges';
|
||||||
repeat
|
repeat
|
||||||
|
Loading…
Reference in New Issue
Block a user