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:
peter 2006-03-19 22:12:52 +00:00
parent ddfa0bd1dd
commit 37c81492ad
19 changed files with 728 additions and 602 deletions

View File

@ -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',

View File

@ -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.

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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],

View File

@ -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=(

View File

@ -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

View File

@ -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)

View File

@ -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 }

View File

@ -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 }

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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);

View File

@ -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

View File

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