* fixed length calculation of leb128 constants

git-svn-id: trunk@8666 -
This commit is contained in:
peter 2007-09-27 22:40:38 +00:00
parent c19217f846
commit b5fb7120b8
4 changed files with 64 additions and 129 deletions

View File

@ -376,6 +376,9 @@ interface
tai_const = class(tai) tai_const = class(tai)
sym, sym,
endsym : tasmsymbol; endsym : tasmsymbol;
{ if symbols and offset are provided the symofs is used,
the value is calculated during assembling }
symofs,
value : int64; value : int64;
consttype : taiconst_type; consttype : taiconst_type;
{ we use for the 128bit int64/qword for now because I can't imagine a { we use for the 128bit int64/qword for now because I can't imagine a
@ -396,7 +399,6 @@ interface
constructor Create_rva_sym(_sym:tasmsymbol); constructor Create_rva_sym(_sym:tasmsymbol);
constructor Create_indirect_sym(_sym:tasmsymbol); constructor Create_indirect_sym(_sym:tasmsymbol);
constructor Createname(const name:string;ofs:aint); constructor Createname(const name:string;ofs:aint);
constructor Createname_rva(const name:string);
constructor ppuload(t:taitype;ppufile:tcompilerppufile);override; constructor ppuload(t:taitype;ppufile:tcompilerppufile);override;
procedure ppuwrite(ppufile:tcompilerppufile);override; procedure ppuwrite(ppufile:tcompilerppufile);override;
procedure derefimpl;override; procedure derefimpl;override;
@ -1141,16 +1143,7 @@ implementation
constructor tai_const.Create_sym(_sym:tasmsymbol); constructor tai_const.Create_sym(_sym:tasmsymbol);
begin begin
inherited Create; self.create_sym_offset(_sym,0);
typ:=ait_const;
consttype:=aitconst_ptr;
{ sym is allowed to be nil, this is used to write nil pointers }
sym:=_sym;
endsym:=nil;
value:=0;
{ update sym info }
if assigned(sym) then
sym.increfs;
end; end;
@ -1159,79 +1152,45 @@ implementation
inherited Create; inherited Create;
typ:=ait_const; typ:=ait_const;
consttype:=aitconst_ptr; consttype:=aitconst_ptr;
if not assigned(_sym) then { sym is allowed to be nil, this is used to write nil pointers }
internalerror(200404121);
sym:=_sym; sym:=_sym;
endsym:=nil; endsym:=nil;
{ store the original offset in symofs so that we can recalculate the
value field in the assembler }
symofs:=ofs;
value:=ofs; value:=ofs;
{ update sym info } { update sym info }
if assigned(sym) then
sym.increfs; sym.increfs;
end; end;
constructor tai_const.Create_rel_sym(_typ:taiconst_type;_sym,_endsym:tasmsymbol); constructor tai_const.Create_rel_sym(_typ:taiconst_type;_sym,_endsym:tasmsymbol);
begin begin
inherited Create; self.create_sym_offset(_sym,0);
typ:=ait_const;
consttype:=_typ; consttype:=_typ;
sym:=_sym;
endsym:=_endsym; endsym:=_endsym;
value:=0;
{ update sym info }
sym.increfs;
endsym.increfs; endsym.increfs;
end; end;
constructor tai_const.Create_rva_sym(_sym:tasmsymbol); constructor tai_const.Create_rva_sym(_sym:tasmsymbol);
begin begin
inherited Create; self.create_sym_offset(_sym,0);
typ:=ait_const;
consttype:=aitconst_rva_symbol; consttype:=aitconst_rva_symbol;
sym:=_sym;
endsym:=nil;
value:=0;
{ update sym info }
sym.increfs;
end; end;
constructor tai_const.Create_indirect_sym(_sym:tasmsymbol); constructor tai_const.Create_indirect_sym(_sym:tasmsymbol);
begin begin
inherited Create; self.create_sym_offset(_sym,0);
typ:=ait_const;
consttype:=aitconst_indirect_symbol; consttype:=aitconst_indirect_symbol;
sym:=_sym;
endsym:=nil;
value:=0;
{ update sym info }
sym.increfs;
end; end;
constructor tai_const.Createname(const name:string;ofs:aint); constructor tai_const.Createname(const name:string;ofs:aint);
begin begin
inherited Create; self.create_sym_offset(current_asmdata.RefAsmSymbol(name),ofs);
typ:=ait_const;
consttype:=aitconst_ptr;
sym:=current_asmdata.RefAsmSymbol(name);
endsym:=nil;
value:=ofs;
{ update sym info }
sym.increfs;
end;
constructor tai_const.Createname_rva(const name:string);
begin
inherited Create;
typ:=ait_const;
consttype:=aitconst_rva_symbol;
sym:=current_asmdata.RefAsmSymbol(name);
endsym:=nil;
value:=0;
{ update sym info }
sym.increfs;
end; end;

View File

@ -914,6 +914,9 @@ Implementation
function TInternalAssembler.TreePass0(hp:Tai):Tai; function TInternalAssembler.TreePass0(hp:Tai):Tai;
var
objsym,
objsymend : TObjSymbol;
begin begin
while assigned(hp) do while assigned(hp) do
begin begin
@ -945,7 +948,22 @@ Implementation
ait_comp_64bit : ait_comp_64bit :
ObjData.alloc(8); ObjData.alloc(8);
ait_const: ait_const:
begin
{ if symbols are provided we can calculate the value for relative symbols.
This is required for length calculation of leb128 constants }
if assigned(tai_const(hp).sym) then
begin
objsym:=Objdata.SymbolRef(tai_const(hp).sym);
if assigned(tai_const(hp).endsym) then
begin
objsymend:=Objdata.SymbolRef(tai_const(hp).endsym);
if objsymend.objsection<>objsym.objsection then
internalerror(200404124);
Tai_const(hp).value:=objsymend.address-objsym.address+Tai_const(hp).symofs;
end;
end;
ObjData.alloc(tai_const(hp).size); ObjData.alloc(tai_const(hp).size);
end;
ait_section: ait_section:
begin begin
ObjData.CreateSection(Tai_section(hp).sectype,Tai_section(hp).name^,Tai_section(hp).secorder); ObjData.CreateSection(Tai_section(hp).sectype,Tai_section(hp).name^,Tai_section(hp).secorder);
@ -975,10 +993,9 @@ Implementation
function TInternalAssembler.TreePass1(hp:Tai):Tai; function TInternalAssembler.TreePass1(hp:Tai):Tai;
var var
InlineLevel : longint; objsym,
objsym : TObjSymbol; objsymend : TObjSymbol;
begin begin
inlinelevel:=0;
while assigned(hp) do while assigned(hp) do
begin begin
case hp.typ of case hp.typ of
@ -1017,11 +1034,15 @@ Implementation
ObjData.alloc(8); ObjData.alloc(8);
ait_const: ait_const:
begin begin
{ Recalculate relative symbols, all checks are done in treepass0 }
if assigned(tai_const(hp).sym) and
assigned(tai_const(hp).endsym) then
begin
objsym:=Objdata.SymbolRef(tai_const(hp).sym);
objsymend:=Objdata.SymbolRef(tai_const(hp).endsym);
Tai_const(hp).value:=objsymend.address-objsym.address+Tai_const(hp).symofs;
end;
ObjData.alloc(tai_const(hp).size); ObjData.alloc(tai_const(hp).size);
if assigned(Tai_const(hp).sym) then
ObjData.SymbolRef(Tai_const(hp).sym);
if assigned(Tai_const(hp).endsym) then
ObjData.SymbolRef(Tai_const(hp).endsym);
end; end;
ait_section: ait_section:
begin begin
@ -1049,11 +1070,6 @@ Implementation
ait_cutobject : ait_cutobject :
if SmartAsm then if SmartAsm then
break; break;
ait_marker :
if tai_marker(hp).kind=mark_InlineStart then
inc(InlineLevel)
else if tai_marker(hp).kind=mark_InlineEnd then
dec(InlineLevel);
end; end;
hp:=Tai(hp.next); hp:=Tai(hp.next);
end; end;
@ -1064,17 +1080,12 @@ Implementation
function TInternalAssembler.TreePass2(hp:Tai):Tai; function TInternalAssembler.TreePass2(hp:Tai):Tai;
var var
fillbuffer : tfillbuffer; fillbuffer : tfillbuffer;
InlineLevel,
v : int64;
{$ifdef x86} {$ifdef x86}
co : comp; co : comp;
{$endif x86} {$endif x86}
objsym,
objsymend : TObjSymbol;
leblen : byte; leblen : byte;
lebbuf : array[0..63] of byte; lebbuf : array[0..63] of byte;
begin begin
inlinelevel:=0;
{ main loop } { main loop }
while assigned(hp) do while assigned(hp) do
begin begin
@ -1127,20 +1138,9 @@ Implementation
aitconst_16bit, aitconst_16bit,
aitconst_8bit : aitconst_8bit :
begin begin
if assigned(tai_const(hp).sym) then if assigned(tai_const(hp).sym) and
begin not assigned(tai_const(hp).endsym) then
objsym:=Objdata.SymbolRef(tai_const(hp).sym); ObjData.writereloc(Tai_const(hp).symofs,tai_const(hp).size,Objdata.SymbolRef(tai_const(hp).sym),RELOC_ABSOLUTE)
if assigned(tai_const(hp).endsym) then
begin
objsymend:=Objdata.SymbolRef(tai_const(hp).endsym);
if objsymend.objsection<>objsym.objsection then
internalerror(200404124);
v:=objsymend.address-objsym.address+Tai_const(hp).value;
ObjData.writebytes(v,tai_const(hp).size);
end
else
ObjData.writereloc(Tai_const(hp).value,Tai_const(hp).size,objsym,RELOC_ABSOLUTE);
end
else else
ObjData.writebytes(Tai_const(hp).value,tai_const(hp).size); ObjData.writebytes(Tai_const(hp).value,tai_const(hp).size);
end; end;
@ -1148,34 +1148,24 @@ Implementation
begin begin
{ PE32+? } { PE32+? }
if target_info.system=system_x86_64_win64 then if target_info.system=system_x86_64_win64 then
ObjData.writereloc(Tai_const(hp).value,sizeof(longint),Objdata.SymbolRef(tai_const(hp).sym),RELOC_RVA) ObjData.writereloc(Tai_const(hp).symofs,sizeof(longint),Objdata.SymbolRef(tai_const(hp).sym),RELOC_RVA)
else else
ObjData.writereloc(Tai_const(hp).value,sizeof(aint),Objdata.SymbolRef(tai_const(hp).sym),RELOC_RVA); ObjData.writereloc(Tai_const(hp).symofs,sizeof(aint),Objdata.SymbolRef(tai_const(hp).sym),RELOC_RVA);
end; end;
aitconst_secrel32_symbol : aitconst_secrel32_symbol :
begin begin
{ Required for DWARF2 support under Windows } { Required for DWARF2 support under Windows }
ObjData.writereloc(Tai_const(hp).value,sizeof(longint),Objdata.SymbolRef(tai_const(hp).sym),RELOC_SECREL32); ObjData.writereloc(Tai_const(hp).symofs,sizeof(longint),Objdata.SymbolRef(tai_const(hp).sym),RELOC_SECREL32);
end; end;
aitconst_uleb128bit, aitconst_uleb128bit,
aitconst_sleb128bit : aitconst_sleb128bit :
begin begin
if assigned(tai_const(hp).sym) then
begin
if not assigned(tai_const(hp).endsym) then
internalerror(200703291);
objsym:=Objdata.SymbolRef(tai_const(hp).sym);
objsymend:=Objdata.SymbolRef(tai_const(hp).endsym);
if objsymend.objsection<>objsym.objsection then
internalerror(200703292);
v:=objsymend.address-objsym.address+Tai_const(hp).value;
end
else
v:=Tai_const(hp).value;
if tai_const(hp).consttype=aitconst_uleb128bit then if tai_const(hp).consttype=aitconst_uleb128bit then
leblen:=EncodeUleb128(qword(v),lebbuf) leblen:=EncodeUleb128(qword(Tai_const(hp).value),lebbuf)
else else
leblen:=EncodeSleb128(v,lebbuf); leblen:=EncodeSleb128(Tai_const(hp).value,lebbuf);
if leblen<>tai_const(hp).size then
internalerror(200709271);
ObjData.writebytes(lebbuf,leblen); ObjData.writebytes(lebbuf,leblen);
end; end;
else else
@ -1197,11 +1187,6 @@ Implementation
ait_cutobject : ait_cutobject :
if SmartAsm then if SmartAsm then
break; break;
ait_marker :
if tai_marker(hp).kind=mark_InlineStart then
inc(InlineLevel)
else if tai_marker(hp).kind=mark_InlineEnd then
dec(InlineLevel);
end; end;
hp:=Tai(hp.next); hp:=Tai(hp.next);
end; end;

View File

@ -2568,15 +2568,9 @@ implementation
(target_info.system in systems_darwin) then (target_info.system in systems_darwin) then
begin begin
asmline.concat(tai_const.create_8bit(DW_LNS_extended_op)); asmline.concat(tai_const.create_8bit(DW_LNS_extended_op));
{$ifdef cpu64bit} asmline.concat(tai_const.create_uleb128bit(1+sizeof(aint)));
asmline.concat(tai_const.create_uleb128bit(9)); { 1 + 8 }
asmline.concat(tai_const.create_8bit(DW_LNE_set_address)); asmline.concat(tai_const.create_8bit(DW_LNE_set_address));
asmline.concat(tai_const.create_type_sym(aitconst_64bit, currlabel)); asmline.concat(tai_const.create_sym(currlabel));
{$else cpu64bit}
asmline.concat(tai_const.create_uleb128bit(5)); { 1 + 4 }
asmline.concat(tai_const.create_8bit(DW_LNE_set_address));
asmline.concat(tai_const.create_type_sym(aitconst_32bit, currlabel));
{$endif cpu64bit}
end end
else else
begin begin
@ -2648,15 +2642,9 @@ implementation
asmline.concat(tai_const.create_uleb128bit(get_file_index(infile))); asmline.concat(tai_const.create_uleb128bit(get_file_index(infile)));
asmline.concat(tai_const.create_8bit(DW_LNS_extended_op)); asmline.concat(tai_const.create_8bit(DW_LNS_extended_op));
{$ifdef cpu64bit} asmline.concat(tai_const.create_uleb128bit(1+sizeof(aint)));
asmline.concat(tai_const.create_uleb128bit(9)); { 1 + 8 }
asmline.concat(tai_const.create_8bit(DW_LNE_set_address)); asmline.concat(tai_const.create_8bit(DW_LNE_set_address));
asmline.concat(tai_const.create_64bit(0)); asmline.concat(tai_const.create_sym(nil));
{$else cpu64bit}
asmline.concat(tai_const.create_uleb128bit(5)); { 1 + 4 }
asmline.concat(tai_const.create_8bit(DW_LNE_set_address));
asmline.concat(tai_const.create_32bit(0));
{$endif cpu64bit}
asmline.concat(tai_const.create_8bit(DW_LNS_extended_op)); asmline.concat(tai_const.create_8bit(DW_LNS_extended_op));
asmline.concat(tai_const.Create_8bit(1)); asmline.concat(tai_const.Create_8bit(1));
asmline.concat(tai_const.Create_8bit(DW_LNE_end_sequence)); asmline.concat(tai_const.Create_8bit(DW_LNE_end_sequence));

View File

@ -689,7 +689,7 @@ implementation
name_table,ordinal_table : TAsmList; name_table,ordinal_table : TAsmList;
i,autoindex,ni_high : longint; i,autoindex,ni_high : longint;
hole : boolean; hole : boolean;
asmsym : TAsmSymbol;
begin begin
Gl_DoubleIndex:=false; Gl_DoubleIndex:=false;
ELIst_indexed.Sort(@IdxCompare); ELIst_indexed.Sort(@IdxCompare);
@ -858,10 +858,13 @@ implementation
end; end;
case hp.sym.typ of case hp.sym.typ of
staticvarsym : staticvarsym :
address_table.concat(Tai_const.Createname_rva(tstaticvarsym(hp.sym).mangledname)); asmsym:=current_asmdata.RefAsmSymbol(tstaticvarsym(hp.sym).mangledname);
procsym : procsym :
address_table.concat(Tai_const.Createname_rva(tprocdef(tprocsym(hp.sym).ProcdefList[0]).mangledname)); asmsym:=current_asmdata.RefAsmSymbol(tprocdef(tprocsym(hp.sym).ProcdefList[0]).mangledname);
else
internalerror(200709272);
end; end;
address_table.concat(Tai_const.Create_rva_sym(asmsym));
inc(current_index); inc(current_index);
hp:=texported_item(hp.next); hp:=texported_item(hp.next);
end; end;