diff --git a/compiler/aggas.pas b/compiler/aggas.pas index 98e1703f23..7c1919b91e 100644 --- a/compiler/aggas.pas +++ b/compiler/aggas.pas @@ -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', diff --git a/compiler/cresstr.pas b/compiler/cresstr.pas index 79b232c1a8..c4e483286c 100644 --- a/compiler/cresstr.pas +++ b/compiler/cresstr.pas @@ -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. diff --git a/compiler/globals.pas b/compiler/globals.pas index 1caf56114c..cb1abf445b 100644 --- a/compiler/globals.pas +++ b/compiler/globals.pas @@ -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); diff --git a/compiler/i386/ag386nsm.pas b/compiler/i386/ag386nsm.pas index 33d5650f68..8d9e980d61 100644 --- a/compiler/i386/ag386nsm.pas +++ b/compiler/i386/ag386nsm.pas @@ -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 diff --git a/compiler/link.pas b/compiler/link.pas index c7e3a001b9..262987ea81 100644 --- a/compiler/link.pas +++ b/compiler/link.pas @@ -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 diff --git a/compiler/m68k/cgcpu.pas b/compiler/m68k/cgcpu.pas index 448b4d21c2..34c8e08982 100644 --- a/compiler/m68k/cgcpu.pas +++ b/compiler/m68k/cgcpu.pas @@ -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 diff --git a/compiler/ncgld.pas b/compiler/ncgld.pas index 800ce128bd..52cffae7d8 100644 --- a/compiler/ncgld.pas +++ b/compiler/ncgld.pas @@ -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); diff --git a/compiler/ogbase.pas b/compiler/ogbase.pas index 76acfead3d..a6d4909f3d 100644 --- a/compiler/ogbase.pas +++ b/compiler/ogbase.pas @@ -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], diff --git a/compiler/ogcoff.pas b/compiler/ogcoff.pas index eb362c3f8c..c5f6d991e4 100644 --- a/compiler/ogcoff.pas +++ b/compiler/ogcoff.pas @@ -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=( diff --git a/compiler/options.pas b/compiler/options.pas index 986567fe68..844d8e9485 100644 --- a/compiler/options.pas +++ b/compiler/options.pas @@ -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 diff --git a/compiler/parser.pas b/compiler/parser.pas index fc81f85df9..318b30b0a1 100644 --- a/compiler/parser.pas +++ b/compiler/parser.pas @@ -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) diff --git a/compiler/pmodules.pas b/compiler/pmodules.pas index 51fef40875..824379bd48 100644 --- a/compiler/pmodules.pas +++ b/compiler/pmodules.pas @@ -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 } diff --git a/compiler/ppu.pas b/compiler/ppu.pas index b7e2c78a77..7b5296468c 100644 --- a/compiler/ppu.pas +++ b/compiler/ppu.pas @@ -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 } diff --git a/compiler/ptconst.pas b/compiler/ptconst.pas index 361df8efa4..25b850856b 100644 --- a/compiler/ptconst.pas +++ b/compiler/ptconst.pas @@ -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 diff --git a/compiler/symsym.pas b/compiler/symsym.pas index 12ba3e00df..da3d2a92d5 100644 --- a/compiler/symsym.pas +++ b/compiler/symsym.pas @@ -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; diff --git a/compiler/systems/t_linux.pas b/compiler/systems/t_linux.pas index bcf5559aba..15707b5b2b 100644 --- a/compiler/systems/t_linux.pas +++ b/compiler/systems/t_linux.pas @@ -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, 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, 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 diff --git a/compiler/systems/t_win.pas b/compiler/systems/t_win.pas index 1018c575d2..ea6b3d095f 100644 --- a/compiler/systems/t_win.pas +++ b/compiler/systems/t_win.pas @@ -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); diff --git a/compiler/x86/aasmcpu.pas b/compiler/x86/aasmcpu.pas index 9a6ae9cdf7..31b68de834 100644 --- a/compiler/x86/aasmcpu.pas +++ b/compiler/x86/aasmcpu.pas @@ -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 diff --git a/compiler/x86/agx86int.pas b/compiler/x86/agx86int.pas index b3d03fbec7..fb63c485c0 100644 --- a/compiler/x86/agx86int.pas +++ b/compiler/x86/agx86int.pas @@ -65,7 +65,7 @@ implementation '', '','','','', '', - '' + '' ); secnamesml64 : array[TAsmSectiontype] of string[7] = ('',