Provide basic facilities to handle indirect symbols that are needed for proper dynamic packages support.

symconst.pas:
  + new constant suffix_indirect which will be used to denote indirect symbols
aasmbase.pas:
  * TAsmsymbind: extend by AB_INDIRECT (which is used to define an indirect symbol) and AB_EXTERNAL_INDIRECT (which is used when an unknown indirect symbol is requested)
  * asmsymbindname: adjust for TAsmsymbind changes
  + new constant asmsymbindindirect which is a set of both indirect asm symbol binds
aasmdata.pas, TAsmData:
  * DefineAsmSymbolByClass: adjust to correctly declare an indirect symbol (with suffix_indirect) if one of the indirect asm symbol binds is used
  * RefAsmSymbol: extend by a boolean parameter which is used to request an indirect symbol (usually AB_EXTERNAL_INDIRECT instead of AB_EXTERNAL)

git-svn-id: trunk@33278 -
This commit is contained in:
svenbarth 2016-03-18 21:34:17 +00:00
parent 77ede2ac9f
commit 3971ba7898
3 changed files with 37 additions and 11 deletions

View File

@ -42,7 +42,10 @@ interface
{ global in the current program/library, but not visible outside it }
AB_PRIVATE_EXTERN,AB_LAZY,AB_IMPORT,
{ a symbol that's internal to the compiler and used as a temp }
AB_TEMP);
AB_TEMP,
{ a global symbol that points to another global symbol and is only used
to allow indirect loading in case of packages and indirect imports }
AB_INDIRECT,AB_EXTERNAL_INDIRECT);
TAsmsymtype=(
AT_NONE,AT_FUNCTION,AT_DATA,AT_SECTION,AT_LABEL,
@ -65,7 +68,9 @@ interface
const
asmlabeltypeprefix : array[TAsmLabeltype] of char = ('j','a','d','l','f','t','c');
asmsymbindname : array[TAsmsymbind] of string[23] = ('none', 'external','common',
'local','global','weak external','private external','lazy','import','internal temp');
'local','global','weak external','private external','lazy','import','internal temp',
'indirect','external indirect');
asmsymbindindirect = [AB_INDIRECT,AB_EXTERNAL_INDIRECT];
type
TAsmSectiontype=(sec_none,

View File

@ -169,7 +169,7 @@ interface
function DefineAsmSymbolByClass(symclass: TAsmSymbolClass; const s : TSymStr;_bind:TAsmSymBind;_typ:Tasmsymtype) : TAsmSymbol;
function DefineAsmSymbol(const s : TSymStr;_bind:TAsmSymBind;_typ:Tasmsymtype) : TAsmSymbol;
function WeakRefAsmSymbol(const s : TSymStr;_typ:Tasmsymtype=AT_NONE) : TAsmSymbol;
function RefAsmSymbol(const s : TSymStr;_typ:Tasmsymtype=AT_NONE) : TAsmSymbol;
function RefAsmSymbol(const s : TSymStr;_typ:Tasmsymtype=AT_NONE;indirect:boolean=false) : TAsmSymbol;
function GetAsmSymbol(const s : TSymStr) : TAsmSymbol;
{ create new assembler label }
procedure getlabel(out l : TAsmLabel;alt:TAsmLabeltype);
@ -217,6 +217,7 @@ implementation
uses
verbose,
symconst,
aasmtai;
{$ifdef MEMDEBUG}
@ -406,8 +407,12 @@ implementation
function TAsmData.DefineAsmSymbolByClass(symclass: TAsmSymbolClass; const s : TSymStr;_bind:TAsmSymBind;_typ:Tasmsymtype) : TAsmSymbol;
var
hp : TAsmSymbol;
namestr : TSymStr;
begin
hp:=TAsmSymbol(FAsmSymbolDict.Find(s));
namestr:=s;
if _bind in asmsymbindindirect then
namestr:=namestr+suffix_indirect;
hp:=TAsmSymbol(FAsmSymbolDict.Find(namestr));
if assigned(hp) then
begin
{ Redefine is allowed, but the types must be the same. The redefine
@ -429,9 +434,9 @@ implementation
should be ignored; a used cannot change anything about this,
so printing a warning/hint is not useful }
if (_bind=AB_LOCAL) then
Message3(asmw_w_changing_bind_type,s,asmsymbindname[hp.bind],asmsymbindname[_bind])
Message3(asmw_w_changing_bind_type,namestr,asmsymbindname[hp.bind],asmsymbindname[_bind])
else
Message3(asmw_h_changing_bind_type,s,asmsymbindname[hp.bind],asmsymbindname[_bind]);
Message3(asmw_h_changing_bind_type,namestr,asmsymbindname[hp.bind],asmsymbindname[_bind]);
{$endif extdebug}
end;
hp.bind:=_bind;
@ -439,7 +444,7 @@ implementation
else
begin
{ Not found, insert it. }
hp:=symclass.create(AsmSymbolDict,s,_bind,_typ);
hp:=symclass.create(AsmSymbolDict,namestr,_bind,_typ);
end;
result:=hp;
end;
@ -451,14 +456,27 @@ implementation
end;
function TAsmData.RefAsmSymbol(const s : TSymStr;_typ:Tasmsymtype=AT_NONE) : TAsmSymbol;
function TAsmData.RefAsmSymbol(const s : TSymStr;_typ:Tasmsymtype;indirect:boolean) : TAsmSymbol;
var
namestr : TSymStr;
bind : tasmsymbind;
begin
result:=TAsmSymbol(FAsmSymbolDict.Find(s));
namestr:=s;
if indirect then
begin
namestr:=namestr+suffix_indirect;
bind:=AB_EXTERNAL_INDIRECT;
end
else
begin
bind:=AB_EXTERNAL;
end;
result:=TAsmSymbol(FAsmSymbolDict.Find(namestr));
if not assigned(result) then
result:=TAsmSymbol.create(AsmSymbolDict,s,AB_EXTERNAL,_typ)
result:=TAsmSymbol.create(AsmSymbolDict,namestr,bind,_typ)
{ one normal reference removes the "weak" character of a symbol }
else if (result.bind=AB_WEAK_EXTERNAL) then
result.bind:=AB_EXTERNAL;
result.bind:=bind;
end;

View File

@ -887,6 +887,9 @@ inherited_objectoptions : tobjectoptions = [oo_has_virtual,oo_has_private,oo_has
{ blocks-related constants }
blocks_procvar_invoke_type_name = '__FPC_invoke_pvtype';
{ suffix for indirect symbols (AB_INDIRECT) }
suffix_indirect = '$indirect';
implementation
end.