From 23cb2164359b58bf03746cf48a6bb19331cca7e0 Mon Sep 17 00:00:00 2001 From: sergei Date: Thu, 23 May 2013 16:03:42 +0000 Subject: [PATCH] * RTTI fix for alignment-sensitive targets: * typinfo.pp: the newly introduced records were added into {$PACKRECORDS 1} area of effect, which effectively made all records packed, entirely defeating FPC_REQUIRES_PROPER_ALIGNMENT purpose. * added alignment between TProcedureParam records, adjusted TProcedureSignature.GetParam() appropriately. * ncgrtti.pas: added two missing alignments and removed a redundant one. * tests/test/trtti9.pp: modified to use TProcedureSignature.GetParam() and endian-independent check for parameter flags. git-svn-id: trunk@24562 - --- compiler/ncgrtti.pas | 11 ++++++++--- rtl/objpas/typinfo.pp | 4 ++-- tests/test/trtti9.pp | 14 +++++++------- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/compiler/ncgrtti.pas b/compiler/ncgrtti.pas index 13b2e968df..2783f7567d 100644 --- a/compiler/ncgrtti.pas +++ b/compiler/ncgrtti.pas @@ -612,6 +612,8 @@ implementation else break; end; + if (tf_requires_proper_alignment in target_info.flags) then + current_asmdata.asmlists[al_rtti].InsertAfter(cai_align.Create(sizeof(TConstPtrUInt)),lastai); { dimension count } current_asmdata.asmlists[al_rtti].InsertAfter(Tai_const.Create_8bit(dimcount),lastai); { last dimension element type } @@ -738,6 +740,7 @@ implementation begin { write flags for current parameter } write_param_flag(parasym); + maybe_write_align; { write param type } write_rtti_reference(parasym.vardef,fullrtti); { write name of current parameter } @@ -814,7 +817,7 @@ implementation { flags } current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(0)); - maybe_write_align; + //maybe_write_align; // aligning between bytes is not necessary { write calling convention } current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(ProcCallOptionToCallConv[def.proccalloption])); maybe_write_align; @@ -822,9 +825,11 @@ implementation write_rtti_reference(def.returndef,fullrtti); { write parameter count } current_asmdata.asmlists[al_rtti].concat(Tai_const.Create_8bit(def.maxparacount)); - maybe_write_align; for i:=0 to def.paras.count-1 do - write_procedure_param(tparavarsym(def.paras[i])); + begin + maybe_write_align; + write_procedure_param(tparavarsym(def.paras[i])); + end; end; end; diff --git a/rtl/objpas/typinfo.pp b/rtl/objpas/typinfo.pp index f10493a287..07ddf276ad 100644 --- a/rtl/objpas/typinfo.pp +++ b/rtl/objpas/typinfo.pp @@ -113,6 +113,7 @@ unit typinfo; PTypeInfo = ^TTypeInfo; PPTypeInfo = ^PTypeInfo; +{$PACKRECORDS C} // members of TTypeData TArrayTypeData = {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT} @@ -160,7 +161,6 @@ unit typinfo; function GetParam(ParamIndex: Integer): PProcedureParam; end; -{$PACKRECORDS C} PTypeData = ^TTypeData; TTypeData = {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT} @@ -2056,7 +2056,7 @@ begin Result := PProcedureParam(PByte(@Flags) + SizeOf(Self)); while ParamIndex > 0 do begin - Result := PProcedureParam(PByte(@Result^.Name) + (Length(Result^.Name) + 1) * SizeOf(AnsiChar)); + Result := PProcedureParam(aligntoptr((PByte(@Result^.Name) + (Length(Result^.Name) + 1) * SizeOf(AnsiChar)))); dec(ParamIndex); end; end; diff --git a/tests/test/trtti9.pp b/tests/test/trtti9.pp index b2450b9566..769d3fe9e6 100644 --- a/tests/test/trtti9.pp +++ b/tests/test/trtti9.pp @@ -9,9 +9,9 @@ type PProcedureParam = ^TProcedureParam; TProc = procedure(var A: Integer; S: String); stdcall; -function TestParam(Param: PProcedureParam; Flags: Byte; ParamType: Pointer; Name: ShortString): Boolean; +function TestParam(Param: PProcedureParam; Flags: TParamFlags; ParamType: Pointer; Name: ShortString): Boolean; begin - Result := (Param^.Flags = Flags) and (Param^.ParamType = ParamType) and (Param^.Name = Name); + Result := (Param^.Flags = PByte(@Flags)^) and (Param^.ParamType = ParamType) and (Param^.Name = Name); end; var @@ -29,10 +29,10 @@ begin halt(3); if Data^.ProcSig.ParamCount <> 2 then halt(4); - Param := PProcedureParam(PAnsiChar(@Data^.ProcSig.Flags) + SizeOf(TProcedureSignature)); - if not TestParam(Param, 1, TypeInfo(Integer), 'A') then + Param := Data^.ProcSig.GetParam(0); + if not TestParam(Param, [pfVar], TypeInfo(Integer), 'A') then halt(5); - Param := PProcedureParam(PAnsiChar(@Param^.Name) + (Length(Param^.Name) + 1) * SizeOf(AnsiChar)); - if not TestParam(Param, 0, TypeInfo(String), 'S') then + Param := Data^.ProcSig.GetParam(1); + if not TestParam(Param, [], TypeInfo(String), 'S') then halt(6); -end. \ No newline at end of file +end.