* 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)
sym,
endsym : tasmsymbol;
{ if symbols and offset are provided the symofs is used,
the value is calculated during assembling }
symofs,
value : int64;
consttype : taiconst_type;
{ 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_indirect_sym(_sym:tasmsymbol);
constructor Createname(const name:string;ofs:aint);
constructor Createname_rva(const name:string);
constructor ppuload(t:taitype;ppufile:tcompilerppufile);override;
procedure ppuwrite(ppufile:tcompilerppufile);override;
procedure derefimpl;override;
@ -1141,16 +1143,7 @@ implementation
constructor tai_const.Create_sym(_sym:tasmsymbol);
begin
inherited Create;
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;
self.create_sym_offset(_sym,0);
end;
@ -1159,79 +1152,45 @@ implementation
inherited Create;
typ:=ait_const;
consttype:=aitconst_ptr;
if not assigned(_sym) then
internalerror(200404121);
{ sym is allowed to be nil, this is used to write nil pointers }
sym:=_sym;
endsym:=nil;
{ store the original offset in symofs so that we can recalculate the
value field in the assembler }
symofs:=ofs;
value:=ofs;
{ update sym info }
sym.increfs;
if assigned(sym) then
sym.increfs;
end;
constructor tai_const.Create_rel_sym(_typ:taiconst_type;_sym,_endsym:tasmsymbol);
begin
inherited Create;
typ:=ait_const;
self.create_sym_offset(_sym,0);
consttype:=_typ;
sym:=_sym;
endsym:=_endsym;
value:=0;
{ update sym info }
sym.increfs;
endsym.increfs;
end;
constructor tai_const.Create_rva_sym(_sym:tasmsymbol);
begin
inherited Create;
typ:=ait_const;
self.create_sym_offset(_sym,0);
consttype:=aitconst_rva_symbol;
sym:=_sym;
endsym:=nil;
value:=0;
{ update sym info }
sym.increfs;
end;
constructor tai_const.Create_indirect_sym(_sym:tasmsymbol);
begin
inherited Create;
typ:=ait_const;
self.create_sym_offset(_sym,0);
consttype:=aitconst_indirect_symbol;
sym:=_sym;
endsym:=nil;
value:=0;
{ update sym info }
sym.increfs;
end;
constructor tai_const.Createname(const name:string;ofs:aint);
begin
inherited Create;
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;
self.create_sym_offset(current_asmdata.RefAsmSymbol(name),ofs);
end;

View File

@ -914,6 +914,9 @@ Implementation
function TInternalAssembler.TreePass0(hp:Tai):Tai;
var
objsym,
objsymend : TObjSymbol;
begin
while assigned(hp) do
begin
@ -945,7 +948,22 @@ Implementation
ait_comp_64bit :
ObjData.alloc(8);
ait_const:
ObjData.alloc(tai_const(hp).size);
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);
end;
ait_section:
begin
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;
var
InlineLevel : longint;
objsym : TObjSymbol;
objsym,
objsymend : TObjSymbol;
begin
inlinelevel:=0;
while assigned(hp) do
begin
case hp.typ of
@ -1017,11 +1034,15 @@ Implementation
ObjData.alloc(8);
ait_const:
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);
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;
ait_section:
begin
@ -1049,11 +1070,6 @@ Implementation
ait_cutobject :
if SmartAsm then
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;
hp:=Tai(hp.next);
end;
@ -1064,17 +1080,12 @@ Implementation
function TInternalAssembler.TreePass2(hp:Tai):Tai;
var
fillbuffer : tfillbuffer;
InlineLevel,
v : int64;
{$ifdef x86}
co : comp;
{$endif x86}
objsym,
objsymend : TObjSymbol;
leblen : byte;
lebbuf : array[0..63] of byte;
begin
inlinelevel:=0;
{ main loop }
while assigned(hp) do
begin
@ -1127,20 +1138,9 @@ Implementation
aitconst_16bit,
aitconst_8bit :
begin
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);
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
if assigned(tai_const(hp).sym) and
not assigned(tai_const(hp).endsym) then
ObjData.writereloc(Tai_const(hp).symofs,tai_const(hp).size,Objdata.SymbolRef(tai_const(hp).sym),RELOC_ABSOLUTE)
else
ObjData.writebytes(Tai_const(hp).value,tai_const(hp).size);
end;
@ -1148,34 +1148,24 @@ Implementation
begin
{ PE32+? }
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
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;
aitconst_secrel32_symbol :
begin
{ 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;
aitconst_uleb128bit,
aitconst_sleb128bit :
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
leblen:=EncodeUleb128(qword(v),lebbuf)
leblen:=EncodeUleb128(qword(Tai_const(hp).value),lebbuf)
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);
end;
else
@ -1197,11 +1187,6 @@ Implementation
ait_cutobject :
if SmartAsm then
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;
hp:=Tai(hp.next);
end;

View File

@ -29,7 +29,7 @@
The easiest way to debug dwarf debug info generation is the usage of
readelf --debug-dump <executable>
This works only with elf targets though.
There is a similar utility called dwarfdump which is not elf-specific and
which has been ported to most systems.
}
@ -2568,15 +2568,9 @@ implementation
(target_info.system in systems_darwin) then
begin
asmline.concat(tai_const.create_8bit(DW_LNS_extended_op));
{$ifdef cpu64bit}
asmline.concat(tai_const.create_uleb128bit(9)); { 1 + 8 }
asmline.concat(tai_const.create_uleb128bit(1+sizeof(aint)));
asmline.concat(tai_const.create_8bit(DW_LNE_set_address));
asmline.concat(tai_const.create_type_sym(aitconst_64bit, 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}
asmline.concat(tai_const.create_sym(currlabel));
end
else
begin
@ -2648,15 +2642,9 @@ implementation
asmline.concat(tai_const.create_uleb128bit(get_file_index(infile)));
asmline.concat(tai_const.create_8bit(DW_LNS_extended_op));
{$ifdef cpu64bit}
asmline.concat(tai_const.create_uleb128bit(9)); { 1 + 8 }
asmline.concat(tai_const.create_uleb128bit(1+sizeof(aint)));
asmline.concat(tai_const.create_8bit(DW_LNE_set_address));
asmline.concat(tai_const.create_64bit(0));
{$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_sym(nil));
asmline.concat(tai_const.create_8bit(DW_LNS_extended_op));
asmline.concat(tai_const.Create_8bit(1));
asmline.concat(tai_const.Create_8bit(DW_LNE_end_sequence));

View File

@ -689,7 +689,7 @@ implementation
name_table,ordinal_table : TAsmList;
i,autoindex,ni_high : longint;
hole : boolean;
asmsym : TAsmSymbol;
begin
Gl_DoubleIndex:=false;
ELIst_indexed.Sort(@IdxCompare);
@ -858,10 +858,13 @@ implementation
end;
case hp.sym.typ of
staticvarsym :
address_table.concat(Tai_const.Createname_rva(tstaticvarsym(hp.sym).mangledname));
asmsym:=current_asmdata.RefAsmSymbol(tstaticvarsym(hp.sym).mangledname);
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;
address_table.concat(Tai_const.Create_rva_sym(asmsym));
inc(current_index);
hp:=texported_item(hp.next);
end;