* automatically generate necessary indirect symbols when a new assembler

symbol is defined
   o removed all places where AB_INDIRECT symbols were explicitly generated
   o only generate AB_INDIRECT symbols for AT_DATA on systems_indirect_var_imports
   o for some symbols an indirect symbol is always required (because they are
     dereferenced by code in RTL units) -> use new AT_DATA_FORCEINDIRECT type

git-svn-id: trunk@34165 -
This commit is contained in:
Jonas Maebe 2016-07-20 20:53:03 +00:00
parent 1cb8c0d00c
commit a0efde8167
23 changed files with 126 additions and 95 deletions

1
.gitattributes vendored
View File

@ -49,6 +49,7 @@ compiler/aarch64/symcpu.pas svneol=native#text/plain
compiler/aasmbase.pas svneol=native#text/plain
compiler/aasmcnst.pas svneol=native#text/plain
compiler/aasmdata.pas svneol=native#text/plain
compiler/aasmdef.pas svneol=native#text/plain
compiler/aasmsym.pas svneol=native#text/plain
compiler/aasmtai.pas svneol=native#text/plain
compiler/aggas.pas svneol=native#text/plain

View File

@ -35,6 +35,7 @@ implementation
{ this not really a node }
rgcpu,
{ symtable }
symcpu;
symcpu,
aasmdef;
end.

View File

@ -56,6 +56,11 @@ interface
AT_ADDR,
{ Label for debug or other non-program information }
AT_METADATA,
{ label for data that must always be accessed indirectly, because it
is handled explcitely in the system unit or (e.g. RTTI and threadvar
tables) -- never seen in an assembler/assembler writer, always
changed to AT_DATA }
AT_DATA_FORCEINDIRECT,
{ Thread-local symbol (ELF targets) }
AT_TLS,
{ GNU indirect function (ELF targets) }

View File

@ -210,8 +210,8 @@ interface
constructor Create(asym: tsym; aoffset: aint; alabel: TAsmSymbol);
end;
const
casmdata: TAsmDataClass = TAsmData;
var
casmdata: TAsmDataClass;
var
@ -352,6 +352,10 @@ implementation
hp : TAsmSymbol;
namestr : TSymStr;
begin
{ this difference is only necessary to determine whether we always need
indirect references or not }
if _typ=AT_DATA_FORCEINDIRECT then
_typ:=AT_DATA;
namestr:=s;
if _bind in asmsymbindindirect then
namestr:=namestr+suffix_indirect;

83
compiler/aasmdef.pas Normal file
View File

@ -0,0 +1,83 @@
{
Copyright (c) 2016 by Jonas Maebe, member of the Free Pascal
development team
Contains asmsymbol functionality that depends on symdef (to avoid creating
circular dependencies between symdef and aasmdata via aasmtai)
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 aasmdef;
{$i fpcdefs.inc}
interface
uses
globtype,
aasmbase,aasmdata,
symtype;
type
TAsmDataDef = class(TAsmData)
function DefineAsmSymbolByClass(symclass: TAsmSymbolClass; const s : TSymStr;_bind:TAsmSymBind;_typ:Tasmsymtype; def: tdef) : TAsmSymbol; override;
end;
implementation
uses
globals,cutils,systems,
aasmtai,aasmcnst,
symdef;
function TAsmDataDef.DefineAsmSymbolByClass(symclass: TAsmSymbolClass; const s: TSymStr; _bind: TAsmSymBind; _typ: Tasmsymtype; def: tdef): TAsmSymbol;
var
symind: tasmsymbol;
ptrdef: tdef;
tcb: ttai_typedconstbuilder;
wasdefined: boolean;
begin
result:=DefineAsmSymbolByClassBase(symclass,s,_bind,_typ,def,wasdefined);
{ define the indirect asmsymbol if necessary }
if not wasdefined and
(_bind in [AB_GLOBAL,AB_COMMON]) and
(((_typ=AT_DATA) and
(tf_supports_packages in target_info.flags) and
(target_info.system in systems_indirect_var_imports)
) or
(_typ=AT_DATA_FORCEINDIRECT)
) then
begin
ptrdef:=cpointerdef.getreusable(def);
symind:=current_asmdata.DefineAsmSymbol(s,AB_INDIRECT,AT_DATA,ptrdef);
tcb:=ctai_typedconstbuilder.create([tcalo_make_dead_strippable,tcalo_new_section]);
tcb.emit_tai(Tai_const.Create_sym_offset(result,0),ptrdef);
current_asmdata.AsmLists[al_exports].concatlist(tcb.get_final_asmlist(
symind,ptrdef,
sec_rodata,
lower(symind.name),
const_align(ptrdef.alignment)));
tcb.free;
end;
end;
begin
casmdata:=TAsmDataDef;
end.

View File

@ -43,7 +43,8 @@ unit cpunode;
narmset,
narmmem,
{ symtable }
symcpu
symcpu,
aasmdef
;

View File

@ -39,7 +39,8 @@ unit cpunode;
,navrcnv
,navrutil,
{ symtable }
symcpu
symcpu,
aasmdef
;

View File

@ -60,7 +60,8 @@ unit cpunode;
{$endif TEST_WIN32_SEH}
n386mat,
{ symtable }
symcpu
symcpu,
aasmdef
;
end.

View File

@ -59,7 +59,8 @@ unit cpunode;
{ these are not really nodes }
n8086util,n8086tcon,tgcpu,
{ symtable }
symcpu
symcpu,
aasmdef
;
end.

View File

@ -297,4 +297,5 @@ implementation
begin
cai_cpu:=taicpu;
cai_align:=tai_align;
casmdata:=TAsmData;
end.

View File

@ -38,5 +38,6 @@ implementation
,rgcpu,tgcpu,njvmutil,njvmtcon,
{ symtable }
symcpu;
{ no aasmdef, the jvm uses the base TAsmData class (set in init code of aasmcpu) }
end.

View File

@ -51,8 +51,7 @@ implementation
class procedure tllvmnodeutils.insertbsssym(list: tasmlist; sym: tstaticvarsym; size: asizeint; varalign: shortint);
var
asmsym,
symind: tasmsymbol;
asmsym: tasmsymbol;
field1, field2: tsym;
tcb: ttai_typedconstbuilder;
begin
@ -68,15 +67,6 @@ implementation
list.concat(taillvmdecl.createdef(asmsym,
get_threadvar_record(sym.vardef,field1,field2),
nil,sec_data,varalign));
symind:=current_asmdata.DefineAsmSymbol(sym.mangledname,AB_INDIRECT,AT_DATA,cpointerdef.getreusable(sym.vardef));
tcb:=ctai_typedconstbuilder.create([tcalo_make_dead_strippable,tcalo_new_section]);
tcb.emit_tai(Tai_const.Create_sym_offset(asmsym,0),cpointerdef.getreusable(sym.vardef));
list.concatlist(tcb.get_final_asmlist(
symind,cpointerdef.getreusable(sym.vardef),
sec_rodata,
lower(sym.mangledname),
const_align(sym.vardef.alignment)));
tcb.free;
end;

View File

@ -47,7 +47,8 @@ unit cpunode;
n68kmat,
n68kcnv,
{ symtable }
symcpu
symcpu,
aasmdef
;
end.

View File

@ -39,7 +39,8 @@ implementation
ncpuadd,ncpucall,ncpumat,ncpuinln,
ncpuld,ncpucnv,ncpuset,
{ symtable }
symcpu
symcpu,
aasmdef
;
end.

View File

@ -582,7 +582,6 @@ implementation
)
);
tcb.free;
// todo: indirect?
if variantdispatch then
begin

View File

@ -1054,7 +1054,7 @@ implementation
if not is_objectpascal_helper(def) then
if (oo_has_vmt in def.objectoptions) then
tcb.emit_tai(
Tai_const.Createname(def.vmt_mangledname,AT_DATA,0),
Tai_const.Createname(def.vmt_mangledname,AT_DATA_FORCEINDIRECT,0),
cpointerdef.getreusable(def.vmt_def))
else
tcb.emit_tai(Tai_const.Create_nil_dataptr,voidpointertype);
@ -1268,7 +1268,7 @@ implementation
in sstrings.inc. }
procedure enumdef_rtti_ord2stringindex(rttidef: trecorddef; const syms: tfplist);
var rttilab,rttilabind:Tasmsymbol;
var rttilab:Tasmsymbol;
h,i,o,prev_value:longint;
mode:(lookup,search); {Modify with care, ordinal value of enum is written.}
r:single; {Must be real type because of integer overflow risk.}
@ -1366,19 +1366,11 @@ implementation
tcb.end_anonymous_record;
tabledef:=tcb.end_anonymous_record;
rttilab:=current_asmdata.DefineAsmSymbol(Tstoreddef(def).rtti_mangledname(rt)+'_o2s',AB_GLOBAL,AT_DATA,tabledef);
rttilab:=current_asmdata.DefineAsmSymbol(Tstoreddef(def).rtti_mangledname(rt)+'_o2s',AB_GLOBAL,AT_DATA_FORCEINDIRECT,tabledef);
current_asmdata.asmlists[al_rtti].concatlist(tcb.get_final_asmlist(
rttilab,tabledef,sec_rodata,
rttilab.name,const_align(sizeof(pint))));
tcb.free;
{ write indirect symbol }
tcb:=ctai_typedconstbuilder.create([tcalo_make_dead_strippable]);
rttilabind:=current_asmdata.DefineAsmSymbol(Tstoreddef(def).rtti_mangledname(rt)+'_o2s',AB_INDIRECT,AT_DATA,cpointerdef.getreusable(tabledef));
tcb.emit_tai(Tai_const.Createname(rttilab.name,AT_DATA,0),voidpointertype);
current_asmdata.AsmLists[al_rtti].concatList(
tcb.get_final_asmlist(rttilabind,voidpointertype,sec_rodata,rttilabind.name,const_align(sizeof(pint))));
tcb.free;
end;
@ -1389,8 +1381,7 @@ implementation
var
tcb: ttai_typedconstbuilder;
rttilab,
rttilabind : Tasmsymbol;
rttilab: Tasmsymbol;
i:longint;
tabledef: tdef;
begin
@ -1420,18 +1411,11 @@ implementation
end;
tcb.end_anonymous_record;
tabledef:=tcb.end_anonymous_record;
rttilab:=current_asmdata.DefineAsmSymbol(Tstoreddef(def).rtti_mangledname(rt)+'_s2o',AB_GLOBAL,AT_DATA,tabledef);
rttilab:=current_asmdata.DefineAsmSymbol(Tstoreddef(def).rtti_mangledname(rt)+'_s2o',AB_GLOBAL,AT_DATA_FORCEINDIRECT,tabledef);
current_asmdata.asmlists[al_rtti].concatlist(tcb.get_final_asmlist(
rttilab,tabledef,sec_rodata,
rttilab.name,const_align(sizeof(pint))));
tcb.free;
{ write indirect symbol }
tcb:=ctai_typedconstbuilder.create([tcalo_make_dead_strippable]);
rttilabind:=current_asmdata.DefineAsmSymbol(Tstoreddef(def).rtti_mangledname(rt)+'_s2o',AB_INDIRECT,AT_DATA,cpointerdef.getreusable(tabledef));
tcb.emit_tai(Tai_const.Createname(rttilab.name,AT_DATA,0),voidpointertype);
current_asmdata.AsmLists[al_rtti].concatList(
tcb.get_final_asmlist(rttilabind,voidpointertype,sec_rodata,rttilabind.name,const_align(sizeof(pint))));
tcb.free;
end;
procedure enumdef_rtti_extrasyms(def:Tenumdef);
@ -1545,8 +1529,7 @@ implementation
procedure TRTTIWriter.write_rtti(def:tdef;rt:trttitype);
var
tcb: ttai_typedconstbuilder;
rttilab,
rttilabind : tasmsymbol;
rttilab: tasmsymbol;
rttidef: tdef;
begin
{ only write rtti of definitions from the current module }
@ -1571,17 +1554,10 @@ implementation
);
write_rtti_data(tcb,def,rt);
rttidef:=tcb.end_anonymous_record;
rttilab:=current_asmdata.DefineAsmSymbol(tstoreddef(def).rtti_mangledname(rt),AB_GLOBAL,AT_DATA,rttidef);
rttilab:=current_asmdata.DefineAsmSymbol(tstoreddef(def).rtti_mangledname(rt),AB_GLOBAL,AT_DATA_FORCEINDIRECT,rttidef);
current_asmdata.AsmLists[al_rtti].concatList(
tcb.get_final_asmlist(rttilab,rttidef,sec_rodata,rttilab.name,const_align(sizeof(pint))));
tcb.free;
{ write indirect symbol }
tcb:=ctai_typedconstbuilder.create([tcalo_make_dead_strippable]);
rttilabind:=current_asmdata.DefineAsmSymbol(tstoreddef(def).rtti_mangledname(rt),AB_INDIRECT,AT_DATA,cpointerdef.getreusable(rttidef));
tcb.emit_tai(Tai_const.Createname(rttilab.name,AT_DATA,0),voidpointertype);
current_asmdata.AsmLists[al_rtti].concatList(
tcb.get_final_asmlist(rttilabind,voidpointertype,sec_rodata,rttilabind.name,const_align(sizeof(pint))));
tcb.free;
{ write additional data }
write_rtti_extrasyms(def,rt,rttilab);
end;

View File

@ -1217,16 +1217,6 @@ implementation
current_asmdata.asmlists[al_globals].concat(tai_symbol.CreateName(hs,AT_DATA,0,voidpointerdef));
{$endif vtentry}
symtablestack.pop(current_module.localsymtable);
{ write indirect symbol }
tcb:=ctai_typedconstbuilder.create([tcalo_make_dead_strippable]);
hs:=_class.vmt_mangledname;
tcb.emit_tai(Tai_const.Createname(hs,AT_DATA,0),voidpointertype);
current_asmdata.AsmLists[al_globals].concatList(
tcb.get_final_asmlist(
current_asmdata.DefineAsmSymbol(hs,AB_INDIRECT,AT_DATA,cpointerdef.getreusable(vmtdef)),
cpointerdef.getreusable(vmtdef),sec_rodata,hs,const_align(sizeof(pint))));
tcb.free;
end;

View File

@ -737,15 +737,6 @@ implementation
end
else
list.concat(Tai_datablock.create(sym.mangledname,size,sym.vardef));
if (tf_supports_packages in target_info.flags) then
begin
{ add the indirect symbol if needed }
new_section(list,sec_rodata,lower(sym.mangledname),const_align(sym.vardef.alignment));
symind:=current_asmdata.DefineAsmSymbol(sym.mangledname,AB_INDIRECT,AT_DATA,cpointerdef.getreusable(sym.vardef));
list.concat(Tai_symbol.Create_Global(symind,0));
list.concat(Tai_const.Createname(sym.mangledname,AT_DATA,0));
list.concat(tai_symbol_end.Create(symind));
end;
end;
@ -1118,7 +1109,7 @@ implementation
if add then
begin
s:=make_mangledname('THREADVARLIST',current_module.localsymtable,'');
sym:=current_asmdata.DefineAsmSymbol(s,AB_GLOBAL,AT_DATA,tabledef);
sym:=current_asmdata.DefineAsmSymbol(s,AB_GLOBAL,AT_DATA_FORCEINDIRECT,tabledef);
current_asmdata.asmlists[al_globals].concatlist(
tcb.get_final_asmlist(sym,tabledef,sec_data,s,sizeof(pint)));
current_module.flags:=current_module.flags or uf_threadvars;
@ -1126,16 +1117,6 @@ implementation
else
s:='';
tcb.Free;
if add then
begin
{ write indirect symbol }
tcb:=ctai_typedconstbuilder.create([tcalo_make_dead_strippable,tcalo_new_section]);
tcb.emit_tai(Tai_const.Create_sym(current_asmdata.RefAsmSymbol(s,AT_DATA,false)),cpointerdef.getreusable(tabledef));
sym:=current_asmdata.DefineAsmSymbol(s,AB_INDIRECT,AT_DATA,voidpointertype);
current_asmdata.AsmLists[al_globals].concatList(
tcb.get_final_asmlist(sym,cpointerdef.getreusable(tabledef),sec_rodata,sym.name,const_align(sizeof(pint))));
tcb.free;
end;
end;

View File

@ -47,7 +47,8 @@ unit cpunode;
nppccnv,
// nppcld
{ symtable }
symcpu
symcpu,
aasmdef
;
end.

View File

@ -33,6 +33,7 @@ uses
ncgobjc,
{ symtable }
symcpu,
aasmdef,
{ to be able to only parts of the generic code,
the processor specific nodes must be included
after the generic one (FK)

View File

@ -134,17 +134,6 @@ implementation
{ and pointed data, if any }
current_asmdata.asmlists[al_const].concatlist(datalist);
{ the (empty) lists themselves are freed by tcbuilder }
if (tf_supports_packages in target_info.flags) then
begin
{ add indirect symbol }
{ ToDo: do we also need this for the else part? }
new_section(list,sec_rodata,lower(sym.mangledname),const_align(sym.vardef.alignment));
symind:=current_asmdata.DefineAsmSymbol(sym.mangledname,AB_INDIRECT,AT_DATA,cpointerdef.getreusable(sym.vardef));
list.concat(Tai_symbol.Create_Global(symind,0));
list.concat(Tai_const.Createname(sym.mangledname,AT_DATA,0));
list.concat(tai_symbol_end.Create(symind));
end;
end
else
begin

View File

@ -35,6 +35,7 @@ implementation
{ this not really a node }
rgcpu,
{ symtable }
symcpu;
symcpu,
aasmdef;
end.

View File

@ -45,6 +45,7 @@ unit cpunode;
ncgobjc,
{ symtable }
symcpu,
aasmdef,
{$ifndef llvm}
{ the cpu specific node units must be used after the generic ones to
get the correct class pointer }