mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-28 13:30:33 +02:00
+ Encode(U/S)leb128 take now a third parameter to force that the constant has a certain minimum size
+ tai_const has a new field fixed_size which is used to fix the size of an s/uleb128. This is needed to ensure convergence during assembling when calculating offsets git-svn-id: branches/debug_eh@42255 -
This commit is contained in:
parent
adb8e1b76c
commit
1ed0000ae8
@ -653,6 +653,9 @@ interface
|
||||
symofs,
|
||||
value : int64;
|
||||
consttype : taiconst_type;
|
||||
{ sleb128 and uleb128 values have a varying length, by calling FixSize their size can be fixed
|
||||
to avoid that other offsets need to be changed. The value to write is stored in fixed_size }
|
||||
fixed_size : byte;
|
||||
{ we use for the 128bit int64/qword for now because I can't imagine a
|
||||
case where we need 128 bit now (FK) }
|
||||
constructor Create(_typ:taiconst_type;_value : int64);
|
||||
@ -707,6 +710,9 @@ interface
|
||||
procedure derefimpl;override;
|
||||
function getcopy:tlinkedlistitem;override;
|
||||
function size:longint;
|
||||
{ sleb128 and uleb128 values have a varying length, by calling FixSize their size can be fixed
|
||||
to avoid that other offsets need to be changed. The value to write is stored in fixed_size }
|
||||
Procedure FixSize;
|
||||
end;
|
||||
|
||||
{ floating point const }
|
||||
@ -2002,9 +2008,31 @@ implementation
|
||||
else
|
||||
result:=sizeof(pint);
|
||||
aitconst_uleb128bit :
|
||||
result:=LengthUleb128(qword(value));
|
||||
begin
|
||||
if fixed_size>0 then
|
||||
result:=fixed_size
|
||||
else if sym=nil then
|
||||
begin
|
||||
FixSize;
|
||||
result:=fixed_size;
|
||||
end
|
||||
else
|
||||
{ worst case }
|
||||
result:=sizeof(pint)+2;
|
||||
end;
|
||||
aitconst_sleb128bit :
|
||||
result:=LengthSleb128(value);
|
||||
begin
|
||||
if fixed_size>0 then
|
||||
result:=fixed_size
|
||||
else if sym=nil then
|
||||
begin
|
||||
FixSize;
|
||||
result:=fixed_size;
|
||||
end
|
||||
else
|
||||
{ worst case }
|
||||
result:=sizeof(pint)+2;
|
||||
end;
|
||||
aitconst_half16bit,
|
||||
aitconst_gs:
|
||||
result:=2;
|
||||
@ -2024,6 +2052,19 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
procedure tai_const.FixSize;
|
||||
begin
|
||||
case consttype of
|
||||
aitconst_uleb128bit:
|
||||
fixed_size:=LengthUleb128(qword(value));
|
||||
aitconst_sleb128bit:
|
||||
fixed_size:=LengthSleb128(value);
|
||||
else
|
||||
Internalerror(2019030301);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
{****************************************************************************
|
||||
TAI_realconst
|
||||
****************************************************************************}
|
||||
|
@ -1,4 +1,4 @@
|
||||
{
|
||||
{
|
||||
Copyright (c) 1998-2006 by the Free Pascal team
|
||||
|
||||
This unit implements the generic part of the GNU assembler
|
||||
@ -586,7 +586,7 @@ implementation
|
||||
i,len : longint;
|
||||
buf : array[0..63] of byte;
|
||||
begin
|
||||
len:=EncodeUleb128(a,buf);
|
||||
len:=EncodeUleb128(a,buf,0);
|
||||
for i:=0 to len-1 do
|
||||
begin
|
||||
if (i > 0) then
|
||||
@ -634,7 +634,7 @@ implementation
|
||||
i,len : longint;
|
||||
buf : array[0..255] of byte;
|
||||
begin
|
||||
len:=EncodeSleb128(a,buf);
|
||||
len:=EncodeSleb128(a,buf,0);
|
||||
for i:=0 to len-1 do
|
||||
begin
|
||||
if (i > 0) then
|
||||
|
@ -1767,6 +1767,8 @@ Implementation
|
||||
else
|
||||
Tai_const(hp).value:=objsymend.address-objsym.address+Tai_const(hp).symofs;
|
||||
end;
|
||||
if (Tai_const(hp).consttype in [aitconst_uleb128bit,aitconst_sleb128bit]) then
|
||||
Tai_const(hp).fixsize;
|
||||
ObjData.alloc(tai_const(hp).size);
|
||||
end;
|
||||
ait_section:
|
||||
@ -2035,11 +2037,13 @@ Implementation
|
||||
aitconst_uleb128bit,
|
||||
aitconst_sleb128bit :
|
||||
begin
|
||||
if Tai_const(hp).fixed_size=0 then
|
||||
Internalerror(2019030302);
|
||||
if tai_const(hp).consttype=aitconst_uleb128bit then
|
||||
leblen:=EncodeUleb128(qword(Tai_const(hp).value),lebbuf)
|
||||
leblen:=EncodeUleb128(qword(Tai_const(hp).value),lebbuf,Tai_const(hp).fixed_size)
|
||||
else
|
||||
leblen:=EncodeSleb128(Tai_const(hp).value,lebbuf);
|
||||
if leblen<>tai_const(hp).size then
|
||||
leblen:=EncodeSleb128(Tai_const(hp).value,lebbuf,Tai_const(hp).fixed_size);
|
||||
if leblen<>tai_const(hp).fixed_size then
|
||||
internalerror(200709271);
|
||||
ObjData.writebytes(lebbuf,leblen);
|
||||
end;
|
||||
|
@ -182,8 +182,8 @@ interface
|
||||
|
||||
function LengthUleb128(a: qword) : byte;
|
||||
function LengthSleb128(a: int64) : byte;
|
||||
function EncodeUleb128(a: qword;out buf) : byte;
|
||||
function EncodeSleb128(a: int64;out buf) : byte;
|
||||
function EncodeUleb128(a: qword;out buf;len: byte) : byte;
|
||||
function EncodeSleb128(a: int64;out buf;len: byte) : byte;
|
||||
|
||||
{ hide Sysutils.ExecuteProcess in units using this one after SysUtils}
|
||||
const
|
||||
@ -1672,7 +1672,7 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
function EncodeUleb128(a: qword;out buf) : byte;
|
||||
function EncodeUleb128(a: qword;out buf;len : byte) : byte;
|
||||
var
|
||||
b: byte;
|
||||
pbuf : pbyte;
|
||||
@ -1687,13 +1687,13 @@ implementation
|
||||
pbuf^:=b;
|
||||
inc(pbuf);
|
||||
inc(result);
|
||||
if a=0 then
|
||||
if (a=0) and (result>=len) then
|
||||
break;
|
||||
until false;
|
||||
end;
|
||||
|
||||
|
||||
function EncodeSleb128(a: int64;out buf) : byte;
|
||||
function EncodeSleb128(a: int64;out buf;len : byte) : byte;
|
||||
var
|
||||
b, size: byte;
|
||||
more: boolean;
|
||||
@ -1707,7 +1707,7 @@ implementation
|
||||
b := a and $7f;
|
||||
a := SarInt64(a, 7);
|
||||
|
||||
if (
|
||||
if (result+1>=len) and (
|
||||
((a = 0) and (b and $40 = 0)) or
|
||||
((a = -1) and (b and $40 <> 0))
|
||||
) then
|
||||
|
Loading…
Reference in New Issue
Block a user