فهرست منبع

* 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 -

sergei 12 سال پیش
والد
کامیت
23cb216435
3فایلهای تغییر یافته به همراه17 افزوده شده و 12 حذف شده
  1. 8 3
      compiler/ncgrtti.pas
  2. 2 2
      rtl/objpas/typinfo.pp
  3. 7 7
      tests/test/trtti9.pp

+ 8 - 3
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;
 

+ 2 - 2
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;

+ 7 - 7
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.
+end.