o patch by Sergei Gorelkin which basically resolves #14308 (still misses some tests):

* constant widestrings must be allocated and copied at program start up through an api call else they couldn't be passed between progam/dlls

git-svn-id: trunk@14432 -
This commit is contained in:
florian 2009-12-13 10:03:30 +00:00
parent a6f673082e
commit b5e7b3e1e7
8 changed files with 327 additions and 191 deletions

1
.gitattributes vendored
View File

@ -74,6 +74,7 @@ compiler/arm/rarmsta.inc svneol=native#text/plain
compiler/arm/rarmstd.inc svneol=native#text/plain
compiler/arm/rarmsup.inc svneol=native#text/plain
compiler/arm/rgcpu.pas svneol=native#text/plain
compiler/asmutils.pas svneol=native#text/plain
compiler/assemble.pas svneol=native#text/plain
compiler/avr/aasmcpu.pas svneol=native#text/plain
compiler/avr/agavrgas.pas svneol=native#text/plain

View File

@ -152,6 +152,7 @@ interface
{ Assembler lists }
AsmLists : array[TAsmListType] of TAsmList;
CurrAsmList : TAsmList;
WideInits : TLinkedList;
{ hash tables for reusing constant storage }
ConstPools : array[TConstPoolType] of THashSet;
constructor create(const n:string);
@ -174,6 +175,13 @@ interface
property AsmCFI:TAsmCFI read FAsmCFI;
end;
TTCInitItem = class(TLinkedListItem)
sym: tsym;
offset: aint;
datalabel: TAsmLabel;
constructor Create(asym: tsym; aoffset: aint; alabel: TAsmLabel);
end;
var
CAsmCFI : TAsmCFIClass;
current_asmdata : TAsmData;
@ -241,6 +249,18 @@ implementation
begin
end;
{*****************************************************************************
TTCInitItem
*****************************************************************************}
constructor TTCInitItem.Create(asym: tsym; aoffset: aint; alabel: TAsmLabel);
begin
inherited Create;
sym:=asym;
offset:=aoffset;
datalabel:=alabel;
end;
{*****************************************************************************
TAsmList
@ -311,6 +331,7 @@ implementation
CurrAsmList:=TAsmList.create;
for hal:=low(TAsmListType) to high(TAsmListType) do
AsmLists[hal]:=TAsmList.create;
WideInits :=TLinkedList.create;
{ PIC data }
if (target_info.system in [system_powerpc_darwin,system_powerpc64_darwin,system_i386_darwin,system_arm_darwin]) then
AsmLists[al_picdata].concat(tai_section.create(sec_data_nonlazy,'',sizeof(pint)));
@ -345,6 +366,7 @@ implementation
{$ifdef MEMDEBUG}
memasmlists.start;
{$endif}
WideInits.free;
for hal:=low(TAsmListType) to high(TAsmListType) do
AsmLists[hal].free;
CurrAsmList.free;

118
compiler/asmutils.pas Normal file
View File

@ -0,0 +1,118 @@
{
Copyright (c) 1998-2006 by Florian Klaempfl
This unit contains utility functions for assembler output
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
****************************************************************************
}
unit asmutils;
interface
{$i fpcdefs.inc}
uses
aasmbase,
aasmdata;
function emit_ansistring_const(list:TAsmList;data:PChar;len:LongInt;NewSection:Boolean=True):TAsmLabel;
function emit_unicodestring_const(list:TAsmList;data:Pointer;Winlike:Boolean):TAsmLabel;
implementation
uses
globals,
globtype,
systems,
verbose,
aasmtai,
widestr,
symdef;
function emit_ansistring_const(list:TAsmList;data:PChar;len:LongInt;NewSection:Boolean): TAsmLabel;
var
referencelab: TAsmLabel;
s: PChar;
begin
current_asmdata.getdatalabel(result);
if NewSection then
new_section(list,sec_rodata,result.name,const_align(sizeof(pint)));
referencelab := nil;
if target_info.system in systems_darwin then
begin
current_asmdata.getdatalabel(referencelab);
list.concat(tai_label.create(referencelab));
end;
list.concat(tai_const.create_pint(-1));
list.concat(tai_const.create_pint(len));
{ make sure the string doesn't get dead stripped if the header is referenced }
if target_info.system in systems_darwin then
list.concat(tai_directive.create(asd_reference,result.name));
list.concat(tai_label.create(result));
{ and vice versa }
if target_info.system in systems_darwin then
list.concat(tai_directive.create(asd_reference,referencelab.name));
getmem(s,len+1);
move(data^,s^,len);
s[len]:=#0;
list.concat(tai_string.create_pchar(s,len+1)); { terminating zero included }
end;
function emit_unicodestring_const(list:TAsmList;data:Pointer;Winlike:Boolean):TAsmLabel;
var
referencelab: TAsmLabel;
i, strlength: SizeInt;
begin
current_asmdata.getdatalabel(result);
new_section(list,sec_rodata,result.name,const_align(sizeof(pint)));
referencelab := nil;
if target_info.system in systems_darwin then
begin
current_asmdata.getdatalabel(referencelab);
list.concat(tai_label.create(referencelab));
end;
strlength := getlengthwidestring(pcompilerwidestring(data));
if Winlike then
list.concat(Tai_const.Create_32bit(strlength*cwidechartype.size))
else
begin
list.concat(Tai_const.Create_pint(-1));
list.concat(Tai_const.Create_pint(strlength*cwidechartype.size));
end;
{ make sure the string doesn't get dead stripped if the header is referenced }
if (target_info.system in systems_darwin) then
list.concat(tai_directive.create(asd_reference,result.name));
list.concat(Tai_label.Create(result));
{ ... and vice versa }
if (target_info.system in systems_darwin) then
list.concat(tai_directive.create(asd_reference,referencelab.name));
if cwidechartype.size = 2 then
begin
for i:=0 to strlength-1 do
list.concat(Tai_const.Create_16bit(pcompilerwidestring(data)^.data[i]));
{ ending #0 }
list.concat(Tai_const.Create_16bit(0));
end
else
InternalError(200904271); { codegeneration for other sizes must be written }
end;
end.

View File

@ -37,7 +37,7 @@ uses
symconst,symtype,symdef,symsym,
verbose,fmodule,ppu,
aasmbase,aasmtai,aasmdata,
aasmcpu;
aasmcpu,asmutils;
Type
{ These are used to form a singly-linked list, ordered by hash value }
@ -127,31 +127,6 @@ uses
procedure Tresourcestrings.CreateResourceStringData;
function WriteValueString(p:pchar;len:longint):TasmLabel;
var
s : pchar;
referencelab: TAsmLabel;
begin
if (target_info.system in systems_darwin) then
begin
current_asmdata.getdatalabel(referencelab);
current_asmdata.asmlists[al_const].concat(tai_label.create(referencelab));
end;
current_asmdata.getdatalabel(result);
current_asmdata.asmlists[al_const].concat(tai_align.create(const_align(sizeof(pint))));
current_asmdata.asmlists[al_const].concat(tai_const.create_pint(-1));
current_asmdata.asmlists[al_const].concat(tai_const.create_pint(len));
current_asmdata.asmlists[al_const].concat(tai_label.create(result));
if (target_info.system in systems_darwin) then
current_asmdata.asmlists[al_const].concat(tai_directive.create(asd_reference,referencelab.name));
getmem(s,len+1);
move(p^,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;
Var
namelab,
valuelab : tasmlabel;
@ -163,13 +138,15 @@ uses
makes the linking too dependent on the linker script requiring a SORT(*) for
the data sections }
maybe_new_object_file(current_asmdata.asmlists[al_const]);
new_section(current_asmdata.asmlists[al_const],sec_data,make_mangledname('RESSTRTABLE',current_module.localsymtable,''),sizeof(pint));
maybe_new_object_file(current_asmdata.asmlists[al_resourcestrings]);
new_section(current_asmdata.asmlists[al_resourcestrings],sec_data,make_mangledname('RESSTR',current_module.localsymtable,'1_START'),sizeof(pint));
current_asmdata.AsmLists[al_resourcestrings].concat(tai_symbol.createname_global(
make_mangledname('RESSTR',current_module.localsymtable,'START'),AT_DATA,0));
{ Write unitname entry }
namelab:=WriteValueString(@current_module.localsymtable.name^[1],length(current_module.localsymtable.name^));
namelab:=emit_ansistring_const(current_asmdata.asmlists[al_const],@current_module.localsymtable.name^[1],length(current_module.localsymtable.name^),False);
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(nil));
@ -185,11 +162,12 @@ uses
new_section(current_asmdata.asmlists[al_const],sec_rodata,make_mangledname('RESSTR',current_module.localsymtable,'d_'+r.name),sizeof(pint));
{ Write default value }
if assigned(R.value) and (R.len<>0) then
valuelab:=WriteValueString(R.Value,R.Len)
valuelab:=emit_ansistring_const(current_asmdata.asmlists[al_const],R.Value,R.Len,False)
else
valuelab:=nil;
{ Append the name as a ansistring. }
namelab:=WriteValueString(@R.Name[1],length(R.name));
current_asmdata.asmlists[al_const].concat(cai_align.Create(const_align(sizeof(pint))));
namelab:=emit_ansistring_const(current_asmdata.asmlists[al_const],@R.Name[1],length(R.name),False);
{
Resourcestring index:

View File

@ -71,7 +71,7 @@ implementation
symconst,symdef,aasmbase,aasmtai,aasmdata,aasmcpu,defutil,
cpuinfo,cpubase,
cgbase,cgobj,cgutils,
ncgutil, cclasses
ncgutil, cclasses,asmutils
;
@ -306,41 +306,13 @@ implementation
{ :-(, we must generate a new entry }
if not assigned(entry^.Data) then
begin
current_asmdata.getdatalabel(lastlabel);
lab_str:=lastlabel;
entry^.Data := lastlabel;
maybe_new_object_file(current_asmdata.asmlists[al_typedconsts]);
if (len=0) or
not(cst_type in [cst_ansistring,cst_widestring,cst_unicodestring]) then
new_section(current_asmdata.asmlists[al_typedconsts],sec_rodata_norel,lastlabel.name,const_align(sizeof(pint)))
else
new_section(current_asmdata.asmlists[al_typedconsts],sec_rodata,lastlabel.name,const_align(sizeof(pint)));
{ generate an ansi string ? }
case cst_type of
cst_ansistring:
begin
if len=0 then
InternalError(2008032301) { empty string should be handled above }
else
begin
current_asmdata.getdatalabel(l1);
current_asmdata.asmlists[al_typedconsts].concat(Tai_label.Create(l1));
current_asmdata.asmlists[al_typedconsts].concat(Tai_const.Create_pint(-1));
current_asmdata.asmlists[al_typedconsts].concat(Tai_const.Create_pint(len));
{ make sure the string doesn't get dead stripped if the header is referenced }
if (target_info.system in systems_darwin) then
current_asmdata.asmlists[al_typedconsts].concat(tai_directive.create(asd_reference,lastlabel.name));
current_asmdata.asmlists[al_typedconsts].concat(Tai_label.Create(lastlabel));
{ ... and vice versa }
if (target_info.system in systems_darwin) then
current_asmdata.asmlists[al_typedconsts].concat(tai_directive.create(asd_reference,l1.name));
{ include also terminating zero }
getmem(pc,len+1);
move(value_str^,pc^,len);
pc[len]:=#0;
current_asmdata.asmlists[al_typedconsts].concat(Tai_string.Create_pchar(pc,len+1));
end;
lastlabel:=emit_ansistring_const(current_asmdata.AsmLists[al_typedconsts],value_str,len);
end;
cst_unicodestring,
cst_widestring:
@ -348,35 +320,16 @@ implementation
if len=0 then
InternalError(2008032302) { empty string should be handled above }
else
begin
current_asmdata.getdatalabel(l1);
current_asmdata.asmlists[al_typedconsts].concat(Tai_label.Create(l1));
{ we use always UTF-16 coding for constants }
{ at least for now }
{ Consts.concat(Tai_const.Create_8bit(2)); }
if (cst_type=cst_widestring) and (tf_winlikewidestring in target_info.flags) then
current_asmdata.asmlists[al_typedconsts].concat(Tai_const.Create_32bit(len*cwidechartype.size))
else
begin
current_asmdata.asmlists[al_typedconsts].concat(Tai_const.Create_pint(-1));
current_asmdata.asmlists[al_typedconsts].concat(Tai_const.Create_pint(len*cwidechartype.size));
end;
{ make sure the string doesn't get dead stripped if the header is referenced }
if (target_info.system in systems_darwin) then
current_asmdata.asmlists[al_typedconsts].concat(tai_directive.create(asd_reference,lastlabel.name));
current_asmdata.asmlists[al_typedconsts].concat(Tai_label.Create(lastlabel));
{ ... and vice versa }
if (target_info.system in systems_darwin) then
current_asmdata.asmlists[al_typedconsts].concat(tai_directive.create(asd_reference,l1.name));
for i:=0 to len-1 do
current_asmdata.asmlists[al_typedconsts].concat(Tai_const.Create_16bit(pcompilerwidestring(value_str)^.data[i]));
{ terminating zero }
current_asmdata.asmlists[al_typedconsts].concat(Tai_const.Create_16bit(0));
end;
lastlabel := emit_unicodestring_const(current_asmdata.AsmLists[al_typedconsts],
value_str,
(cst_type=cst_widestring) and (tf_winlikewidestring in target_info.flags));
end;
cst_shortstring:
begin
current_asmdata.getdatalabel(lastlabel);
maybe_new_object_file(current_asmdata.asmlists[al_typedconsts]);
new_section(current_asmdata.asmlists[al_typedconsts],sec_rodata_norel,lastlabel.name,const_align(sizeof(pint)));
current_asmdata.asmlists[al_typedconsts].concat(Tai_label.Create(lastlabel));
{ truncate strings larger than 255 chars }
if len>255 then
@ -392,6 +345,10 @@ implementation
end;
cst_conststring:
begin
current_asmdata.getdatalabel(lastlabel);
maybe_new_object_file(current_asmdata.asmlists[al_typedconsts]);
new_section(current_asmdata.asmlists[al_typedconsts],sec_rodata_norel,lastlabel.name,const_align(sizeof(pint)));
current_asmdata.asmlists[al_typedconsts].concat(Tai_label.Create(lastlabel));
{ include terminating zero }
getmem(pc,len+1);
@ -400,6 +357,8 @@ implementation
current_asmdata.asmlists[al_typedconsts].concat(Tai_string.Create_pchar(pc,len+1));
end;
end;
lab_str:=lastlabel;
entry^.Data:=lastlabel;
end;
end;
if cst_type in [cst_ansistring, cst_widestring, cst_unicodestring] then

View File

@ -236,6 +236,66 @@ implementation
ltvTable.Free;
end;
procedure InsertWideInits;
var
s: string;
item: TTCInitItem;
begin
item:=TTCInitItem(current_asmdata.WideInits.First);
if item=nil then
exit;
s:=make_mangledname('WIDEINITS',current_module.localsymtable,'');
maybe_new_object_file(current_asmdata.asmlists[al_globals]);
new_section(current_asmdata.asmlists[al_globals],sec_data,s,sizeof(pint));
current_asmdata.asmlists[al_globals].concat(Tai_symbol.Createname_global(s,AT_DATA,0));
repeat
{ address to initialize }
current_asmdata.asmlists[al_globals].concat(Tai_const.createname(item.sym.mangledname, item.offset));
{ value with which to initialize }
current_asmdata.asmlists[al_globals].concat(Tai_const.Create_sym(item.datalabel));
item:=TTCInitItem(item.Next);
until item=nil;
{ end-of-list marker }
current_asmdata.asmlists[al_globals].concat(Tai_const.Create_sym(nil));
current_asmdata.asmlists[al_globals].concat(Tai_symbol_end.Createname(s));
current_module.flags:=current_module.flags or uf_wideinits;
end;
procedure InsertWideInitsTablesTable;
var
hp: tused_unit;
lwiTables: TAsmList;
count: longint;
begin
lwiTables:=TAsmList.Create;
count:=0;
hp:=tused_unit(usedunits.first);
while assigned(hp) do
begin
if (hp.u.flags and uf_wideinits)=uf_wideinits then
begin
lwiTables.concat(Tai_const.Createname(make_mangledname('WIDEINITS',hp.u.globalsymtable,''),0));
inc(count);
end;
hp:=tused_unit(hp.next);
end;
{ Add program widestring consts, if any }
if (current_module.flags and uf_wideinits)=uf_wideinits then
begin
lwiTables.concat(Tai_const.Createname(make_mangledname('WIDEINITS',current_module.localsymtable,''),0));
inc(count);
end;
{ Insert TableCount at start }
lwiTables.insert(Tai_const.Create_32bit(count));
{ insert in data segment }
maybe_new_object_file(current_asmdata.asmlists[al_globals]);
new_section(current_asmdata.asmlists[al_globals],sec_data,'FPC_WIDEINITTABLES',sizeof(pint));
current_asmdata.asmlists[al_globals].concat(Tai_symbol.Createname_global('FPC_WIDEINITTABLES',AT_DATA,0));
current_asmdata.asmlists[al_globals].concatlist(lwiTables);
current_asmdata.asmlists[al_globals].concat(Tai_symbol_end.Createname('FPC_WIDEINITTABLES'));
lwiTables.free;
end;
Function CheckResourcesUsed : boolean;
var
@ -1225,6 +1285,9 @@ implementation
{ Resource strings }
GenerateResourceStrings;
{ Widestring typed constants }
InsertWideInits;
{ generate debuginfo }
if (cs_debuginfo in current_settings.moduleswitches) then
current_debuginfo.inserttypeinfo;
@ -2193,10 +2256,14 @@ implementation
{ Resource strings }
GenerateResourceStrings;
{ Windows widestring needing initialization }
InsertWideInits;
{ insert Tables and StackLength }
insertinitfinaltable;
InsertThreadvarTablesTable;
InsertResourceTablesTable;
InsertWideInitsTablesTable;
insertmemorysizes;
{ Insert symbol to resource info }

View File

@ -43,7 +43,7 @@ type
{$endif Test_Double_checksum}
const
CurrentPPUVersion = 106;
CurrentPPUVersion = 107;
{ buffer sizes }
maxentrysize = 1024;
@ -156,6 +156,7 @@ const
uf_has_resourcefiles = $80000; { this unit has external resources (using $R directive)}
uf_has_exports = $100000; { this module or a used unit has exports }
uf_has_dwarf_debuginfo = $200000; { this unit has dwarf debuginfo generated }
uf_wideinits = $400000; { this unit has winlike widestring typed constants }
type

View File

@ -45,7 +45,7 @@ implementation
pbase,pexpr,pdecvar,
{ codegen }
cpuinfo,cgbase,dbgbase,
wpobase
wpobase,asmutils
;
{$maxfpuregisters 0}
@ -166,9 +166,16 @@ implementation
read typed const
*****************************************************************************}
type
{ context used for parsing complex types (arrays/records/objects) }
threc = record
list : tasmlist;
origsym: tstaticvarsym;
offset: aint;
end;
{ this procedure reads typed constants }
procedure read_typed_const_data(list:tasmlist;def:tdef);
procedure read_typed_const_data(var hr:threc;def:tdef); forward;
procedure parse_orddef(list:tasmlist;def:torddef);
var
@ -408,7 +415,7 @@ implementation
else
varalign:=0;
varalign:=const_align(varalign);
current_asmdata.asmlists[al_const].concat(Tai_align.Create(varalign));
new_section(current_asmdata.asmlists[al_const], sec_rodata, ll.name, varalign);
current_asmdata.asmlists[al_const].concat(Tai_label.Create(ll));
if p.nodetype=stringconstn then
begin
@ -635,15 +642,15 @@ implementation
end;
procedure parse_stringdef(list:tasmlist;def:tstringdef);
procedure parse_stringdef(const hr:threc;def:tstringdef);
var
n : tnode;
i : longint;
strlength : aint;
strval : pchar;
strch : char;
ll,ll2 : tasmlabel;
ll : tasmlabel;
ca : pchar;
winlike : boolean;
begin
n:=comp_expr(true);
{ load strval and strlength of the constant tree }
@ -690,12 +697,12 @@ implementation
message2(parser_w_string_too_long,strpas(strval),tostr(def.size-1));
strlength:=def.size-1;
end;
list.concat(Tai_const.Create_8bit(strlength));
hr.list.concat(Tai_const.Create_8bit(strlength));
{ this can also handle longer strings }
getmem(ca,strlength+1);
move(strval^,ca^,strlength);
ca[strlength]:=#0;
list.concat(Tai_string.Create_pchar(ca,strlength));
hr.list.concat(Tai_string.Create_pchar(ca,strlength));
{ fillup with spaces if size is shorter }
if def.size>strlength then
begin
@ -705,69 +712,41 @@ implementation
fillchar(ca[0],def.size-strlength-1,' ');
ca[def.size-strlength-1]:=#0;
{ this can also handle longer strings }
list.concat(Tai_string.Create_pchar(ca,def.size-strlength-1));
hr.list.concat(Tai_string.Create_pchar(ca,def.size-strlength-1));
end;
end;
st_ansistring:
begin
{ an empty ansi string is nil! }
if (strlength=0) then
list.concat(Tai_const.Create_sym(nil))
ll := nil
else
begin
current_asmdata.getdatalabel(ll);
list.concat(Tai_const.Create_sym(ll));
current_asmdata.getdatalabel(ll2);
current_asmdata.asmlists[al_const].concat(tai_align.create(const_align(sizeof(pint))));
current_asmdata.asmlists[al_const].concat(Tai_label.Create(ll2));
current_asmdata.asmlists[al_const].concat(Tai_const.Create_pint(-1));
current_asmdata.asmlists[al_const].concat(Tai_const.Create_pint(strlength));
{ make sure the string doesn't get dead stripped if the header is referenced }
if (target_info.system in systems_darwin) then
current_asmdata.asmlists[al_const].concat(tai_directive.create(asd_reference,ll.name));
current_asmdata.asmlists[al_const].concat(Tai_label.Create(ll));
{ ... and vice versa }
if (target_info.system in systems_darwin) then
current_asmdata.asmlists[al_const].concat(tai_directive.create(asd_reference,ll2.name));
getmem(ca,strlength+1);
move(strval^,ca^,strlength);
{ The terminating #0 to be stored in the .data section (JM) }
ca[strlength]:=#0;
current_asmdata.asmlists[al_const].concat(Tai_string.Create_pchar(ca,strlength+1));
end;
ll := emit_ansistring_const(current_asmdata.asmlists[al_const],strval,strlength);
hr.list.concat(Tai_const.Create_sym(ll));
end;
st_unicodestring,
st_widestring:
begin
{ an empty ansi string is nil! }
{ an empty wide/unicode string is nil! }
if (strlength=0) then
list.concat(Tai_const.Create_sym(nil))
ll := nil
else
begin
winlike := (def.stringtype=st_widestring) and (tf_winlikewidestring in target_info.flags);
ll := emit_unicodestring_const(current_asmdata.asmlists[al_const],
strval,
winlike);
{ collect global Windows widestrings }
if winlike and (hr.origsym.owner.symtablelevel <= main_program_level) then
begin
current_asmdata.getdatalabel(ll);
list.concat(Tai_const.Create_sym(ll));
current_asmdata.getdatalabel(ll2);
current_asmdata.asmlists[al_const].concat(tai_align.create(const_align(sizeof(pint))));
current_asmdata.asmlists[al_const].concat(Tai_label.Create(ll2));
if (def.stringtype=st_widestring) and (tf_winlikewidestring in target_info.flags) then
current_asmdata.asmlists[al_const].concat(Tai_const.Create_32bit(strlength*cwidechartype.size))
else
begin
current_asmdata.asmlists[al_const].concat(Tai_const.Create_pint(-1));
current_asmdata.asmlists[al_const].concat(Tai_const.Create_pint(strlength*cwidechartype.size));
end;
{ make sure the string doesn't get dead stripped if the header is referenced }
if (target_info.system in systems_darwin) then
current_asmdata.asmlists[al_const].concat(tai_directive.create(asd_reference,ll.name));
current_asmdata.asmlists[al_const].concat(Tai_label.Create(ll));
{ ... and vice versa }
if (target_info.system in systems_darwin) then
current_asmdata.asmlists[al_const].concat(tai_directive.create(asd_reference,ll2.name));
for i:=0 to strlength-1 do
current_asmdata.asmlists[al_const].concat(Tai_const.Create_16bit(pcompilerwidestring(strval)^.data[i]));
{ ending #0 }
current_asmdata.asmlists[al_const].concat(Tai_const.Create_16bit(0))
current_asmdata.WideInits.Concat(
TTCInitItem.Create(hr.origsym, hr.offset, ll)
);
ll := nil;
end;
end;
hr.list.concat(Tai_const.Create_sym(ll));
end;
else
internalerror(200107081);
@ -838,7 +817,7 @@ implementation
end;
procedure parse_arraydef(list:tasmlist;def:tarraydef);
procedure parse_arraydef(hr:threc;def:tarraydef);
var
n : tnode;
i : longint;
@ -851,24 +830,26 @@ implementation
begin
{ Only allow nil initialization }
consume(_NIL);
list.concat(Tai_const.Create_sym(nil));
hr.list.concat(Tai_const.Create_sym(nil));
end
{ packed array constant }
else if is_packed_array(def) and
((def.elepackedbitsize mod 8 <> 0) or
not ispowerof2(def.elepackedbitsize div 8,i)) then
begin
parse_packed_array_def(list,def);
parse_packed_array_def(hr.list,def);
end
{ normal array const between brackets }
else if try_to_consume(_LKLAMMER) then
begin
hr.offset:=0;
for i:=def.lowrange to def.highrange-1 do
begin
read_typed_const_data(list,def.elementdef);
read_typed_const_data(hr,def.elementdef);
Inc(hr.offset,def.elementdef.size);
consume(_COMMA);
end;
read_typed_const_data(list,def.elementdef);
read_typed_const_data(hr,def.elementdef);
consume(_RKLAMMER);
end
{ if array of char then we allow also a string }
@ -902,12 +883,12 @@ implementation
begin
if i+1-def.lowrange<=len then
begin
list.concat(Tai_const.Create_8bit(byte(ca^)));
hr.list.concat(Tai_const.Create_8bit(byte(ca^)));
inc(ca);
end
else
{Fill the remaining positions with #0.}
list.concat(Tai_const.Create_8bit(0));
hr.list.concat(Tai_const.Create_8bit(0));
end;
n.free;
end
@ -983,7 +964,7 @@ implementation
n.free;
end;
procedure parse_recorddef(list:tasmlist;def:trecorddef);
procedure parse_recorddef(hr:threc;def:trecorddef);
var
n : tnode;
symidx : longint;
@ -997,6 +978,7 @@ implementation
bp : tbitpackedval;
error,
is_packed: boolean;
startoffset: aint;
procedure handle_stringconstn;
var
@ -1005,11 +987,11 @@ implementation
hs:=strpas(tstringconstnode(n).value_str);
if string2guid(hs,tmpguid) then
begin
list.concat(Tai_const.Create_32bit(longint(tmpguid.D1)));
list.concat(Tai_const.Create_16bit(tmpguid.D2));
list.concat(Tai_const.Create_16bit(tmpguid.D3));
hr.list.concat(Tai_const.Create_32bit(longint(tmpguid.D1)));
hr.list.concat(Tai_const.Create_16bit(tmpguid.D2));
hr.list.concat(Tai_const.Create_16bit(tmpguid.D3));
for i:=Low(tmpguid.D4) to High(tmpguid.D4) do
list.concat(Tai_const.Create_8bit(tmpguid.D4[i]));
hr.list.concat(Tai_const.Create_8bit(tmpguid.D4[i]));
end
else
Message(parser_e_improper_guid_syntax);
@ -1031,11 +1013,11 @@ implementation
if n.nodetype=guidconstn then
begin
tmpguid:=tguidconstnode(n).value;
list.concat(Tai_const.Create_32bit(longint(tmpguid.D1)));
list.concat(Tai_const.Create_16bit(tmpguid.D2));
list.concat(Tai_const.Create_16bit(tmpguid.D3));
hr.list.concat(Tai_const.Create_32bit(longint(tmpguid.D1)));
hr.list.concat(Tai_const.Create_16bit(tmpguid.D2));
hr.list.concat(Tai_const.Create_16bit(tmpguid.D3));
for i:=Low(tmpguid.D4) to High(tmpguid.D4) do
list.concat(Tai_const.Create_8bit(tmpguid.D4[i]));
hr.list.concat(Tai_const.Create_8bit(tmpguid.D4[i]));
end
else
Message(parser_e_illegal_expression);
@ -1071,6 +1053,7 @@ implementation
sorg:='';
srsym:=tsym(def.symtable.SymList[symidx]);
recsym := nil;
startoffset:=hr.offset;
while token<>_RKLAMMER do
begin
s:=pattern;
@ -1136,14 +1119,14 @@ implementation
fillbytes:=tfieldvarsym(srsym).fieldoffset-curroffset
else
begin
flush_packed_value(list,bp);
flush_packed_value(hr.list,bp);
{ curoffset is now aligned to the next byte }
curroffset:=align(curroffset,8);
{ offsets are in bits in this case }
fillbytes:=(tfieldvarsym(srsym).fieldoffset-curroffset) div 8;
end;
for i:=1 to fillbytes do
list.concat(Tai_const.Create_8bit(0))
hr.list.concat(Tai_const.Create_8bit(0))
end;
{ new position }
@ -1160,15 +1143,16 @@ implementation
begin
if is_packed then
begin
flush_packed_value(list,bp);
flush_packed_value(hr.list,bp);
curroffset:=align(curroffset,8);
end;
read_typed_const_data(list,tfieldvarsym(srsym).vardef);
hr.offset:=startoffset+tfieldvarsym(srsym).fieldoffset;
read_typed_const_data(hr,tfieldvarsym(srsym).vardef);
end
else
begin
bp.packedbitsize:=tfieldvarsym(srsym).vardef.packedbitsize;
parse_single_packed_const(list,tfieldvarsym(srsym).vardef,bp);
parse_single_packed_const(hr.list,tfieldvarsym(srsym).vardef,bp);
end;
{ keep previous field for checking whether whole }
@ -1201,18 +1185,18 @@ implementation
fillbytes:=def.size-curroffset
else
begin
flush_packed_value(list,bp);
flush_packed_value(hr.list,bp);
curroffset:=align(curroffset,8);
fillbytes:=def.size-(curroffset div 8);
end;
for i:=1 to fillbytes do
list.concat(Tai_const.Create_8bit(0));
hr.list.concat(Tai_const.Create_8bit(0));
consume(_RKLAMMER);
end;
procedure parse_objectdef(list:tasmlist;def:tobjectdef);
{ note: hr is passed by value }
procedure parse_objectdef(hr:threc;def:tobjectdef);
var
n : tnode;
i : longint;
@ -1222,6 +1206,7 @@ implementation
curroffset : aint;
s,sorg : TIDString;
vmtwritten : boolean;
startoffset:aint;
begin
{ no support for packed object }
if is_packed_record_or_object(def) then
@ -1240,7 +1225,7 @@ implementation
consume_all_until(_SEMICOLON);
end
else
list.concat(Tai_const.Create_sym(nil));
hr.list.concat(Tai_const.Create_sym(nil));
n.free;
exit;
end;
@ -1254,6 +1239,7 @@ implementation
end;
consume(_LKLAMMER);
startoffset:=hr.offset;
curroffset:=0;
vmtwritten:=false;
while token<>_RKLAMMER do
@ -1295,8 +1281,8 @@ implementation
(def.vmt_offset<fieldoffset) then
begin
for i:=1 to def.vmt_offset-curroffset do
list.concat(tai_const.create_8bit(0));
list.concat(tai_const.createname(def.vmt_mangledname,0));
hr.list.concat(tai_const.create_8bit(0));
hr.list.concat(tai_const.createname(def.vmt_mangledname,0));
{ this is more general }
curroffset:=def.vmt_offset + sizeof(pint);
vmtwritten:=true;
@ -1305,13 +1291,14 @@ implementation
{ if needed fill }
if fieldoffset>curroffset then
for i:=1 to fieldoffset-curroffset do
list.concat(Tai_const.Create_8bit(0));
hr.list.concat(Tai_const.Create_8bit(0));
{ new position }
curroffset:=fieldoffset+vardef.size;
{ read the data }
read_typed_const_data(list,vardef);
hr.offset:=startoffset+fieldoffset;
read_typed_const_data(hr,vardef);
if not try_to_consume(_SEMICOLON) then
break;
@ -1322,16 +1309,17 @@ implementation
(def.vmt_offset>=curroffset) then
begin
for i:=1 to def.vmt_offset-curroffset do
list.concat(tai_const.create_8bit(0));
list.concat(tai_const.createname(def.vmt_mangledname,0));
hr.list.concat(tai_const.create_8bit(0));
hr.list.concat(tai_const.createname(def.vmt_mangledname,0));
{ this is more general }
curroffset:=def.vmt_offset + sizeof(pint);
end;
for i:=1 to def.size-curroffset do
list.concat(Tai_const.Create_8bit(0));
hr.list.concat(Tai_const.Create_8bit(0));
consume(_RKLAMMER);
end;
procedure read_typed_const_data(var hr:threc;def:tdef);
var
old_block_type : tblock_type;
begin
@ -1339,27 +1327,27 @@ implementation
block_type:=bt_const;
case def.typ of
orddef :
parse_orddef(list,torddef(def));
parse_orddef(hr.list,torddef(def));
floatdef :
parse_floatdef(list,tfloatdef(def));
parse_floatdef(hr.list,tfloatdef(def));
classrefdef :
parse_classrefdef(list,tclassrefdef(def));
parse_classrefdef(hr.list,tclassrefdef(def));
pointerdef :
parse_pointerdef(list,tpointerdef(def));
parse_pointerdef(hr.list,tpointerdef(def));
setdef :
parse_setdef(list,tsetdef(def));
parse_setdef(hr.list,tsetdef(def));
enumdef :
parse_enumdef(list,tenumdef(def));
parse_enumdef(hr.list,tenumdef(def));
stringdef :
parse_stringdef(list,tstringdef(def));
parse_stringdef(hr,tstringdef(def));
arraydef :
parse_arraydef(list,tarraydef(def));
parse_arraydef(hr,tarraydef(def));
procvardef:
parse_procvardef(list,tprocvardef(def));
parse_procvardef(hr.list,tprocvardef(def));
recorddef:
parse_recorddef(list,trecorddef(def));
parse_recorddef(hr,trecorddef(def));
objectdef:
parse_objectdef(list,tobjectdef(def));
parse_objectdef(hr,tobjectdef(def));
errordef:
begin
{ try to consume something useful }
@ -1380,7 +1368,7 @@ implementation
var
storefilepos : tfileposinfo;
cursectype : TAsmSectionType;
valuelist : tasmlist;
hrec : threc;
begin
{ mark the staticvarsym as typedconst }
include(sym.varoptions,vo_is_typed_const);
@ -1397,8 +1385,10 @@ implementation
else
cursectype:=sec_data;
maybe_new_object_file(list);
valuelist:=tasmlist.create;
read_typed_const_data(valuelist,sym.vardef);
hrec.list:=tasmlist.create;
hrec.origsym:=sym;
hrec.offset:=0;
read_typed_const_data(hrec,sym.vardef);
{ Parse hints }
try_consume_hintdirective(sym.symoptions,sym.deprecatedmsg);
@ -1435,8 +1425,8 @@ implementation
list.concat(Tai_symbol.Createname(sym.mangledname,AT_DATA,0));
{ add the parsed value }
list.concatlist(valuelist);
valuelist.free;
list.concatlist(hrec.list);
hrec.list.free;
list.concat(tai_symbol_end.Createname(sym.mangledname));
current_filepos:=storefilepos;
end;