mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-07 16:28:22 +02:00
Merged revisions 2827,2831,2837,2932-2980 via svnmerge from
svn+ssh://peter@www.freepascal.org/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 -
This commit is contained in:
parent
ddfa0bd1dd
commit
37c81492ad
@ -232,7 +232,7 @@ implementation
|
||||
|
||||
function TGNUAssembler.sectionname(atype:TAsmSectiontype;const aname:string):string;
|
||||
const
|
||||
secnames : array[TAsmSectiontype] of string[13] = ('',
|
||||
secnames : array[TAsmSectiontype] of string[17] = ('',
|
||||
'.text',
|
||||
'.data',
|
||||
{$warning TODO .rodata not yet working}
|
||||
@ -248,7 +248,7 @@ implementation
|
||||
'fpc.resptrs',
|
||||
'.toc'
|
||||
);
|
||||
secnames_pic : array[TAsmSectiontype] of string[13] = ('',
|
||||
secnames_pic : array[TAsmSectiontype] of string[17] = ('',
|
||||
'.text',
|
||||
'.data.rel',
|
||||
'.data.rel',
|
||||
|
@ -25,270 +25,291 @@ unit cresstr;
|
||||
|
||||
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
|
||||
|
||||
uses
|
||||
cclasses,
|
||||
cutils,globtype,globals,
|
||||
symdef,
|
||||
verbose,fmodule,
|
||||
symconst,symtype,symdef,symsym,
|
||||
verbose,fmodule,ppu,
|
||||
aasmbase,aasmtai,aasmdata,
|
||||
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
|
||||
---------------------------------------------------------------------}
|
||||
|
||||
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
|
||||
hash:=hash xor (g shr 24);
|
||||
hash:=hash xor g;
|
||||
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
|
||||
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;
|
||||
If Hash=0 then
|
||||
Hash:=$ffffffff;
|
||||
end;
|
||||
|
||||
|
||||
{ ---------------------------------------------------------------------
|
||||
Tresourcestrings
|
||||
---------------------------------------------------------------------}
|
||||
|
||||
Constructor Tresourcestrings.Create;
|
||||
begin
|
||||
List:=TStringList.Create;
|
||||
ResStrCount:=0;
|
||||
end;
|
||||
|
||||
|
||||
Destructor Tresourcestrings.Destroy;
|
||||
begin
|
||||
List.Free;
|
||||
end;
|
||||
|
||||
|
||||
{ ---------------------------------------------------------------------
|
||||
Create the full asmlist for resourcestrings.
|
||||
---------------------------------------------------------------------}
|
||||
|
||||
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;
|
||||
|
||||
|
||||
{ ---------------------------------------------------------------------
|
||||
Insert 1 resource string in all tables.
|
||||
---------------------------------------------------------------------}
|
||||
|
||||
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
|
||||
Constructor Tresourcestrings.Create;
|
||||
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;
|
||||
List:=TLinkedList.Create;
|
||||
end;
|
||||
if mode=quoted then
|
||||
writeln (f,'''');
|
||||
Writeln(f);
|
||||
R:=TResourceStringItem(R.Next);
|
||||
end;
|
||||
close(f);
|
||||
end;
|
||||
|
||||
|
||||
Destructor Tresourcestrings.Destroy;
|
||||
begin
|
||||
List.Free;
|
||||
end;
|
||||
|
||||
|
||||
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.WriteResourceFile;
|
||||
Type
|
||||
TMode = (quoted,unquoted);
|
||||
Var
|
||||
F : Text;
|
||||
Mode : TMode;
|
||||
R : TResourceStringItem;
|
||||
C : char;
|
||||
Col,i : longint;
|
||||
ResFileName : string;
|
||||
|
||||
Procedure Add(Const S : String);
|
||||
begin
|
||||
Write(F,S);
|
||||
inc(Col,length(s));
|
||||
end;
|
||||
|
||||
begin
|
||||
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;
|
||||
|
||||
|
||||
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.
|
||||
|
@ -356,10 +356,10 @@ interface
|
||||
|
||||
{# Routine to get the required alignment for size of data, which will
|
||||
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
|
||||
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}
|
||||
|
||||
@ -2107,14 +2107,14 @@ end;
|
||||
end;
|
||||
|
||||
|
||||
function var_align(siz: longint): longint;
|
||||
function var_align(siz: shortint): shortint;
|
||||
begin
|
||||
siz := size_2_align(siz);
|
||||
var_align := used_align(siz,aktalignment.varalignmin,aktalignment.varalignmax);
|
||||
end;
|
||||
|
||||
|
||||
function const_align(siz: longint): longint;
|
||||
function const_align(siz: shortint): shortint;
|
||||
begin
|
||||
siz := size_2_align(siz);
|
||||
const_align := used_align(siz,aktalignment.constalignmin,aktalignment.constalignmax);
|
||||
|
@ -99,7 +99,7 @@ interface
|
||||
function single2str(d : single) : string;
|
||||
var
|
||||
hs : string;
|
||||
p : byte;
|
||||
p : longint;
|
||||
begin
|
||||
str(d,hs);
|
||||
{ nasm expects a lowercase e }
|
||||
@ -115,7 +115,7 @@ interface
|
||||
function double2str(d : double) : string;
|
||||
var
|
||||
hs : string;
|
||||
p : byte;
|
||||
p : longint;
|
||||
begin
|
||||
str(d,hs);
|
||||
{ nasm expects a lowercase e }
|
||||
@ -131,7 +131,7 @@ interface
|
||||
function extended2str(e : extended) : string;
|
||||
var
|
||||
hs : string;
|
||||
p : byte;
|
||||
p : longint;
|
||||
begin
|
||||
str(e,hs);
|
||||
{ nasm expects a lowercase e }
|
||||
@ -354,7 +354,7 @@ interface
|
||||
|
||||
procedure T386NasmAssembler.WriteSection(atype:TAsmSectiontype;const aname:string);
|
||||
const
|
||||
secnames : array[TAsmSectiontype] of string[13] = ('',
|
||||
secnames : array[TAsmSectiontype] of string[17] = ('',
|
||||
'.text',
|
||||
'.data',
|
||||
'.rodata',
|
||||
@ -394,7 +394,6 @@ interface
|
||||
i,j,l : longint;
|
||||
InlineLevel : longint;
|
||||
consttype : taiconst_type;
|
||||
found,
|
||||
do_line,
|
||||
quoted : boolean;
|
||||
begin
|
||||
|
@ -901,6 +901,8 @@ end;
|
||||
else
|
||||
Comment(V_Error,'DLL not found: '+s);
|
||||
end;
|
||||
{ Fill external symbols data }
|
||||
exeoutput.FixupSymbols;
|
||||
if ErrorCount>0 then
|
||||
goto myexit;
|
||||
|
||||
@ -913,7 +915,6 @@ end;
|
||||
|
||||
{ Calc positions in mem and file }
|
||||
ParseScript_CalcPos;
|
||||
exeoutput.FixupSymbols;
|
||||
exeoutput.FixupRelocations;
|
||||
exeoutput.PrintMemoryMap;
|
||||
if ErrorCount>0 then
|
||||
|
@ -125,6 +125,7 @@ unit cgcpu;
|
||||
topcg2tasmop: Array[topcg] of tasmop =
|
||||
(
|
||||
A_NONE,
|
||||
A_MOVE,
|
||||
A_ADD,
|
||||
A_AND,
|
||||
A_DIVU,
|
||||
@ -404,13 +405,18 @@ unit cgcpu;
|
||||
opcode : tasmop;
|
||||
r,r2 : Tregister;
|
||||
begin
|
||||
optimize_op_const_reg(list, op, a, reg);
|
||||
optimize_op_const(op, a);
|
||||
opcode := topcg2tasmop[op];
|
||||
case op of
|
||||
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 :
|
||||
begin
|
||||
if (a >= 1) and (a <= 8) then
|
||||
|
@ -115,8 +115,16 @@ implementation
|
||||
if tconstsym(symtableentry).consttyp=constresourcestring then
|
||||
begin
|
||||
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
|
||||
else
|
||||
internalerror(22798);
|
||||
|
@ -663,7 +663,7 @@ implementation
|
||||
|
||||
function TObjData.sectionname(atype:TAsmSectiontype;const aname:string):string;
|
||||
const
|
||||
secnames : array[TAsmSectiontype] of string[13] = ('',
|
||||
secnames : array[TAsmSectiontype] of string[16] = ('',
|
||||
'code',
|
||||
'data',
|
||||
'rodata',
|
||||
@ -690,7 +690,7 @@ implementation
|
||||
secoptions : array[TAsmSectiontype] of TObjSectionOptions = ([],
|
||||
{code} [oso_data,oso_load,oso_readonly,oso_executable,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],
|
||||
{bss} [oso_load,oso_write,oso_keep],
|
||||
{threadvar} [oso_load,oso_write],
|
||||
|
@ -97,7 +97,7 @@ interface
|
||||
function writedata(data:TObjData):boolean;override;
|
||||
public
|
||||
constructor createcoff(AWriter:TObjectWriter;awin32:boolean);
|
||||
destructor destroy;
|
||||
destructor destroy;override;
|
||||
end;
|
||||
|
||||
TDJCoffObjOutput = class(TCoffObjOutput)
|
||||
@ -423,7 +423,7 @@ implementation
|
||||
symbolresize = 200*sizeof(coffsymbol);
|
||||
strsresize = 8192;
|
||||
|
||||
coffsecnames : array[TAsmSectiontype] of string[16] = ('',
|
||||
coffsecnames : array[TAsmSectiontype] of string[17] = ('',
|
||||
'.text','.data','.data','.bss','.tls',
|
||||
'.text',
|
||||
'.stab','.stabstr',
|
||||
@ -431,7 +431,7 @@ implementation
|
||||
'.eh_frame',
|
||||
'.debug_frame','.debug_info','.debug_line','.debug_abbrev',
|
||||
'.fpc',
|
||||
''
|
||||
''
|
||||
);
|
||||
|
||||
const go32v2stub : array[0..2047] of byte=(
|
||||
|
@ -1869,6 +1869,7 @@ begin
|
||||
def_system_macro('FPC_DARWIN_JMP_MAIN');
|
||||
def_system_macro('COMPPROCINLINEFIXED');
|
||||
def_system_macro('PARAOUTFILE');
|
||||
def_system_macro('RESSTRSECTIONS');
|
||||
|
||||
if pocall_default = pocall_register then
|
||||
def_system_macro('REGCALL');
|
||||
@ -2180,6 +2181,11 @@ begin
|
||||
Message1(option_asm_forced,target_asm.idtxt);
|
||||
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 }
|
||||
if (cs_debuginfo in initmoduleswitches) or
|
||||
(cs_profile in initmoduleswitches) then
|
||||
|
@ -270,8 +270,6 @@ implementation
|
||||
oldaktprocsym : tprocsym;
|
||||
{ cg }
|
||||
oldparse_only : boolean;
|
||||
{ al_resourcestrings }
|
||||
Oldresourcestrings : tresourcestrings;
|
||||
{ akt.. things }
|
||||
oldaktlocalswitches : tlocalswitches;
|
||||
oldaktmoduleswitches : tmoduleswitches;
|
||||
@ -321,7 +319,6 @@ implementation
|
||||
oldsourcecodepage:=aktsourcecodepage;
|
||||
{ save cg }
|
||||
oldparse_only:=parse_only;
|
||||
Oldresourcestrings:=resourcestrings;
|
||||
{ save akt... state }
|
||||
{ handle the postponed case first }
|
||||
if localswitcheschanged then
|
||||
@ -399,8 +396,6 @@ implementation
|
||||
aktasmmode:=initasmmode;
|
||||
aktinterfacetype:=initinterfacetype;
|
||||
|
||||
resourcestrings:=Tresourcestrings.Create;
|
||||
|
||||
{ load current asmdata from current_module }
|
||||
current_asmdata:=TAsmData(current_module.asmdata);
|
||||
|
||||
@ -452,9 +447,6 @@ implementation
|
||||
tppumodule(current_module).ppufile:=nil;
|
||||
end;
|
||||
|
||||
resourcestrings.free;
|
||||
resourcestrings:=nil;
|
||||
|
||||
{ free asmdata }
|
||||
if assigned(current_module.asmdata) then
|
||||
begin
|
||||
@ -496,7 +488,6 @@ implementation
|
||||
block_type:=old_block_type;
|
||||
{ restore cg }
|
||||
parse_only:=oldparse_only;
|
||||
resourcestrings:=oldresourcestrings;
|
||||
{ asm data }
|
||||
if assigned(old_compiled_module) then
|
||||
current_asmdata:=tasmdata(old_compiled_module.asmdata)
|
||||
|
@ -155,6 +155,8 @@ implementation
|
||||
ltvTables : TAsmList;
|
||||
count : longint;
|
||||
begin
|
||||
if (tf_section_threadvars in target_info.flags) then
|
||||
exit;
|
||||
ltvTables:=TAsmList.Create;
|
||||
count:=0;
|
||||
hp:=tused_unit(usedunits.first);
|
||||
@ -205,6 +207,8 @@ implementation
|
||||
s : string;
|
||||
ltvTable : TAsmList;
|
||||
begin
|
||||
if (tf_section_threadvars in target_info.flags) then
|
||||
exit;
|
||||
ltvTable:=TAsmList.create;
|
||||
if assigned(current_module.globalsymtable) then
|
||||
current_module.globalsymtable.foreach_static(@AddToThreadvarList,ltvTable);
|
||||
@ -273,32 +277,28 @@ implementation
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
Procedure InsertResourceTablesTable;
|
||||
var
|
||||
hp : tused_unit;
|
||||
hp : tmodule;
|
||||
ResourceStringTables : tasmlist;
|
||||
count : longint;
|
||||
begin
|
||||
ResourceStringTables:=tasmlist.Create;
|
||||
count:=0;
|
||||
hp:=tused_unit(usedunits.first);
|
||||
hp:=tmodule(loaded_units.first);
|
||||
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 }
|
||||
ResourceStringTables.insert(Tai_const.Create_32bit(count));
|
||||
ResourceStringTables.insert(Tai_const.Create_aint(count));
|
||||
{ Add to data segment }
|
||||
maybe_new_object_file(current_asmdata.AsmLists[al_globals]);
|
||||
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 }
|
||||
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
|
||||
begin
|
||||
{ tests, if all (interface) forwards are resolved }
|
||||
@ -1100,9 +1090,11 @@ implementation
|
||||
{ generate pic helpers to load eip if necessary }
|
||||
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 }
|
||||
if current_module.uses_imports then
|
||||
@ -1330,14 +1322,6 @@ implementation
|
||||
((current_module.flags and uf_has_exports)<>0) then
|
||||
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? }
|
||||
if token=_FINALIZATION then
|
||||
begin
|
||||
@ -1397,16 +1381,14 @@ implementation
|
||||
if (cs_debuginfo in aktmoduleswitches) then
|
||||
debuginfo.inserttypeinfo;
|
||||
|
||||
InsertThreadvars;
|
||||
|
||||
{ generate wrappers for interfaces }
|
||||
gen_intf_wrappers(current_asmdata.asmlists[al_procedures],current_module.localsymtable);
|
||||
|
||||
{ generate pic helpers to load eip if necessary }
|
||||
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 }
|
||||
if current_module.uses_imports then
|
||||
importlib.generatelib;
|
||||
@ -1414,15 +1396,16 @@ implementation
|
||||
if islibrary or (target_info.system in system_unit_program_exports) then
|
||||
exportlib.generatelib;
|
||||
|
||||
{ Resource strings }
|
||||
GenerateResourceStrings;
|
||||
|
||||
{ insert Tables and StackLength }
|
||||
if not(tf_section_threadvars in target_info.flags) then
|
||||
insertThreadVarTablesTable;
|
||||
|
||||
insertResourceTablesTable;
|
||||
insertinitfinaltable;
|
||||
InsertThreadvarTablesTable;
|
||||
InsertResourceTablesTable;
|
||||
insertmemorysizes;
|
||||
{ Insert symbol to resource info }
|
||||
|
||||
{ Insert symbol to resource info }
|
||||
InsertResourceInfo;
|
||||
|
||||
{ create dwarf debuginfo }
|
||||
|
@ -137,7 +137,7 @@ const
|
||||
uf_local_browser = $200;
|
||||
uf_no_link = $400; { unit has no .o generated, but can still have
|
||||
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_release = $2000; { unit was compiled with -Ur option }
|
||||
uf_threadvars = $4000; { unit has threadvars }
|
||||
|
@ -62,8 +62,8 @@ implementation
|
||||
var
|
||||
len,base : longint;
|
||||
p,hp : tnode;
|
||||
i,j,l,
|
||||
varalign : longint;
|
||||
i,j,l : longint;
|
||||
varalign : shortint;
|
||||
offset,
|
||||
strlength : aint;
|
||||
ll : tasmlabel;
|
||||
@ -85,7 +85,6 @@ implementation
|
||||
storefilepos : tfileposinfo;
|
||||
cursectype : TAsmSectiontype;
|
||||
cural : tasmlisttype;
|
||||
sizelabel : tasmlabel;
|
||||
|
||||
procedure check_range(def:torddef);
|
||||
begin
|
||||
|
@ -369,7 +369,7 @@ implementation
|
||||
{ aasm }
|
||||
aasmtai,aasmdata,
|
||||
{ codegen }
|
||||
paramgr,cresstr,
|
||||
paramgr,
|
||||
procinfo
|
||||
;
|
||||
|
||||
@ -1837,8 +1837,6 @@ implementation
|
||||
value.valueptr:=str;
|
||||
consttype.reset;
|
||||
value.len:=l;
|
||||
if t=constresourcestring then
|
||||
ResStrIndex:=resourcestrings.Register(name,pchar(value.valueptr),value.len);
|
||||
end;
|
||||
|
||||
|
||||
|
@ -323,7 +323,7 @@ Var
|
||||
found2,
|
||||
linklibc : boolean;
|
||||
begin
|
||||
WriteResponseFile:=False;
|
||||
result:=False;
|
||||
{ set special options for some targets }
|
||||
linklibc:=(SharedLibFiles.Find('c')<>nil);
|
||||
if isdll then
|
||||
@ -367,205 +367,207 @@ begin
|
||||
|
||||
{ Open link.res file }
|
||||
LinkRes:=TLinkRes.Create(outputexedir+Info.ResName);
|
||||
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;
|
||||
|
||||
{ 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('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(')');
|
||||
|
||||
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
|
||||
Add('GROUP(');
|
||||
While not StaticLibFiles.Empty do
|
||||
begin
|
||||
S:=StaticLibFiles.GetFirst;
|
||||
AddFileName(maybequoted(s))
|
||||
end;
|
||||
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 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;
|
||||
|
||||
{ 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
|
||||
Add('INPUT(');
|
||||
if found1 then
|
||||
AddFileName(s1);
|
||||
if found2 then
|
||||
AddFileName(s2);
|
||||
Add(')');
|
||||
end;
|
||||
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)');
|
||||
{Entry point.}
|
||||
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}
|
||||
{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 }
|
||||
LinkRes.writetodisk;
|
||||
LinkRes.Free;
|
||||
{ Write and Close response }
|
||||
writetodisk;
|
||||
Free;
|
||||
end;
|
||||
|
||||
WriteResponseFile:=True;
|
||||
end;
|
||||
@ -593,6 +595,8 @@ begin
|
||||
StaticStr:='-static';
|
||||
if (cs_link_strip in aktglobalswitches) then
|
||||
StripStr:='-s';
|
||||
if (cs_link_map in aktglobalswitches) then
|
||||
StripStr:='-Map '+maybequoted(ForceExtension(current_module.exefilename^,'.map'));
|
||||
if use_smartlink_section then
|
||||
GCSectionsStr:='--gc-sections';
|
||||
If (cs_profile in aktmoduleswitches) or
|
||||
|
@ -932,94 +932,204 @@ begin
|
||||
end;
|
||||
|
||||
{ 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
|
||||
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)));
|
||||
{ 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;
|
||||
|
||||
while not ObjectFiles.Empty do
|
||||
{ add objectfiles, start with prt0 always }
|
||||
{ profiling of shared libraries is currently not supported }
|
||||
if not ObjectFiles.Empty then
|
||||
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;
|
||||
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
|
||||
LinkRes.Add(MaybeQuoted(s2));
|
||||
continue;
|
||||
S:=StaticLibFiles.GetFirst;
|
||||
AddFileName(MaybeQuoted(s));
|
||||
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;
|
||||
end;
|
||||
@ -1069,6 +1179,8 @@ begin
|
||||
ImageBaseStr:='--image-base=0x'+DLLImageBase^;
|
||||
if (cs_link_strip in aktglobalswitches) then
|
||||
StripStr:='-s';
|
||||
if (cs_link_map in aktglobalswitches) then
|
||||
StripStr:='-Map '+maybequoted(ForceExtension(current_module.exefilename^,'.map'));
|
||||
|
||||
{ Write used files and libraries }
|
||||
WriteResponseFile(false);
|
||||
|
@ -76,8 +76,8 @@ interface
|
||||
OT_REG16 = $00201002;
|
||||
OT_REG32 = $00201004;
|
||||
OT_REG64 = $00201008;
|
||||
OT_MMXREG = $00201008; { MMX registers }
|
||||
OT_XMMREG = $00201010; { Katmai registers }
|
||||
OT_MMXREG = $00201020; { MMX registers }
|
||||
OT_MEMORY = $00204000; { register number in 'basereg' }
|
||||
OT_MEM8 = $00204001;
|
||||
OT_MEM16 = $00204002;
|
||||
@ -776,11 +776,9 @@ implementation
|
||||
if (ot and OT_BITS32)<>0 then
|
||||
s:=s+'32'
|
||||
else
|
||||
{$ifdef x86_64}
|
||||
if (ot and OT_BITS32)<>0 then
|
||||
if (ot and OT_BITS64)<>0 then
|
||||
s:=s+'64'
|
||||
else
|
||||
{$endif x86_64}
|
||||
s:=s+'??';
|
||||
{ signed }
|
||||
if (ot and OT_SIGNED)<>0 then
|
||||
|
@ -65,7 +65,7 @@ implementation
|
||||
'',
|
||||
'','','','',
|
||||
'',
|
||||
''
|
||||
''
|
||||
);
|
||||
|
||||
secnamesml64 : array[TAsmSectiontype] of string[7] = ('',
|
||||
|
Loading…
Reference in New Issue
Block a user