mirror of
				https://gitlab.com/freepascal.org/fpc/source.git
				synced 2025-11-04 11:39:40 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			484 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			ObjectPascal
		
	
	
	
	
	
			
		
		
	
	
			484 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			ObjectPascal
		
	
	
	
	
	
{
 | 
						|
    $Id$
 | 
						|
    Copyright (c) 1998-2002 by Florian Klaempfl, Pierre Muller
 | 
						|
 | 
						|
    Implementation of the reading of PPU Files for the symtable
 | 
						|
 | 
						|
    This program is free software; you can redistribute it and/or modify
 | 
						|
    it under the terms of the GNU General Public License as published by
 | 
						|
    the Free Software Foundation; either version 2 of the License, or
 | 
						|
    (at your option) any later version.
 | 
						|
 | 
						|
    This program is distributed in the hope that it will be useful,
 | 
						|
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
						|
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
						|
    GNU General Public License for more details.
 | 
						|
 | 
						|
    You should have received a copy of the GNU General Public License
 | 
						|
    along with this program; if not, write to the Free Software
 | 
						|
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 | 
						|
 ****************************************************************************
 | 
						|
}
 | 
						|
unit symppu;
 | 
						|
 | 
						|
{$i fpcdefs.inc}
 | 
						|
 | 
						|
interface
 | 
						|
 | 
						|
    uses
 | 
						|
       cclasses,
 | 
						|
       globtype,globals,
 | 
						|
       cpuinfo,aasmbase,
 | 
						|
       symbase,symtype,
 | 
						|
       ppu;
 | 
						|
 | 
						|
    type
 | 
						|
       tcompilerppufile=class(tppufile)
 | 
						|
       public
 | 
						|
         procedure checkerror;
 | 
						|
         procedure getguid(var g: tguid);
 | 
						|
         function  getexprint:tconstexprint;
 | 
						|
         function  getptruint:TConstPtrUInt;
 | 
						|
         procedure getposinfo(var p:tfileposinfo);
 | 
						|
         procedure getderef(var d:tderef);
 | 
						|
         function  getsymlist:tsymlist;
 | 
						|
         procedure gettype(var t:ttype);
 | 
						|
         function  getasmsymbol:tasmsymbol;
 | 
						|
         procedure putguid(const g: tguid);
 | 
						|
         procedure putexprint(v:tconstexprint);
 | 
						|
         procedure PutPtrUInt(v:TConstPtrUInt);
 | 
						|
         procedure putposinfo(const p:tfileposinfo);
 | 
						|
         procedure putderef(const d:tderef);
 | 
						|
         procedure putsymlist(p:tsymlist);
 | 
						|
         procedure puttype(const t:ttype);
 | 
						|
         procedure putasmsymbol(s:tasmsymbol);
 | 
						|
       end;
 | 
						|
 | 
						|
 | 
						|
implementation
 | 
						|
 | 
						|
    uses
 | 
						|
       symconst,
 | 
						|
       verbose;
 | 
						|
 | 
						|
{*****************************************************************************
 | 
						|
                            TCompilerPPUFile
 | 
						|
*****************************************************************************}
 | 
						|
 | 
						|
    procedure tcompilerppufile.checkerror;
 | 
						|
      begin
 | 
						|
        if error then
 | 
						|
         Message(unit_f_ppu_read_error);
 | 
						|
      end;
 | 
						|
 | 
						|
 | 
						|
    procedure tcompilerppufile.getguid(var g: tguid);
 | 
						|
      begin
 | 
						|
        getdata(g,sizeof(g));
 | 
						|
      end;
 | 
						|
 | 
						|
 | 
						|
    function tcompilerppufile.getexprint:tconstexprint;
 | 
						|
      var
 | 
						|
        l1,l2 : longint;
 | 
						|
      begin
 | 
						|
        if sizeof(tconstexprint)=8 then
 | 
						|
          begin
 | 
						|
            l1:=getlongint;
 | 
						|
            l2:=getlongint;
 | 
						|
{$ifopt R+}
 | 
						|
  {$define Range_check_on}
 | 
						|
{$endif opt R+}
 | 
						|
{$R- needed here }
 | 
						|
{$ifdef Delphi}
 | 
						|
            result:=int64(l1)+(int64(l2) shl 32);
 | 
						|
{$else}
 | 
						|
            result:=qword(l1)+(int64(l2) shl 32);
 | 
						|
{$endif}
 | 
						|
{$ifdef Range_check_on}
 | 
						|
  {$R+}
 | 
						|
  {$undef Range_check_on}
 | 
						|
{$endif Range_check_on}
 | 
						|
          end
 | 
						|
        else
 | 
						|
          result:=getlongint;
 | 
						|
      end;
 | 
						|
 | 
						|
 | 
						|
    function tcompilerppufile.getPtrUInt:TConstPtrUInt;
 | 
						|
      var
 | 
						|
        l1,l2 : longint;
 | 
						|
      begin
 | 
						|
        if sizeof(TConstPtrUInt)=8 then
 | 
						|
          begin
 | 
						|
            l1:=getlongint;
 | 
						|
            l2:=getlongint;
 | 
						|
{$ifopt R+}
 | 
						|
  {$define Range_check_on}
 | 
						|
{$endif opt R+}
 | 
						|
{$R- needed here }
 | 
						|
{$ifdef Delphi}
 | 
						|
            result:=int64(l1)+(int64(l2) shl 32);
 | 
						|
{$else}
 | 
						|
            result:=qword(l1)+(int64(l2) shl 32);
 | 
						|
{$endif}
 | 
						|
{$ifdef Range_check_on}
 | 
						|
  {$R+}
 | 
						|
  {$undef Range_check_on}
 | 
						|
{$endif Range_check_on}
 | 
						|
          end
 | 
						|
        else
 | 
						|
          result:=getlongint;
 | 
						|
      end;
 | 
						|
 | 
						|
 | 
						|
    procedure tcompilerppufile.getposinfo(var p:tfileposinfo);
 | 
						|
      var
 | 
						|
        info : byte;
 | 
						|
      begin
 | 
						|
        {
 | 
						|
          info byte layout in bits:
 | 
						|
          0-1 - amount of bytes for fileindex
 | 
						|
          2-3 - amount of bytes for line
 | 
						|
          4-5 - amount of bytes for column
 | 
						|
        }
 | 
						|
        info:=getbyte;
 | 
						|
        case (info and $03) of
 | 
						|
         0 : p.fileindex:=getbyte;
 | 
						|
         1 : p.fileindex:=getword;
 | 
						|
         2 : p.fileindex:=(getbyte shl 16) or getword;
 | 
						|
         3 : p.fileindex:=getlongint;
 | 
						|
        end;
 | 
						|
        case ((info shr 2) and $03) of
 | 
						|
         0 : p.line:=getbyte;
 | 
						|
         1 : p.line:=getword;
 | 
						|
         2 : p.line:=(getbyte shl 16) or getword;
 | 
						|
         3 : p.line:=getlongint;
 | 
						|
        end;
 | 
						|
        case ((info shr 4) and $03) of
 | 
						|
         0 : p.column:=getbyte;
 | 
						|
         1 : p.column:=getword;
 | 
						|
         2 : p.column:=(getbyte shl 16) or getword;
 | 
						|
         3 : p.column:=getlongint;
 | 
						|
        end;
 | 
						|
      end;
 | 
						|
 | 
						|
 | 
						|
    procedure tcompilerppufile.getderef(var d:tderef);
 | 
						|
      begin
 | 
						|
        d.dataidx:=getlongint;
 | 
						|
      end;
 | 
						|
 | 
						|
 | 
						|
    function tcompilerppufile.getsymlist:tsymlist;
 | 
						|
      var
 | 
						|
        symderef : tderef;
 | 
						|
        tt  : ttype;
 | 
						|
        slt : tsltype;
 | 
						|
        idx : longint;
 | 
						|
        p   : tsymlist;
 | 
						|
      begin
 | 
						|
        p:=tsymlist.create;
 | 
						|
        getderef(p.procdefderef);
 | 
						|
        repeat
 | 
						|
          slt:=tsltype(getbyte);
 | 
						|
          case slt of
 | 
						|
            sl_none :
 | 
						|
              break;
 | 
						|
            sl_call,
 | 
						|
            sl_load,
 | 
						|
            sl_subscript :
 | 
						|
              begin
 | 
						|
                getderef(symderef);
 | 
						|
                p.addsymderef(slt,symderef);
 | 
						|
              end;
 | 
						|
            sl_typeconv :
 | 
						|
              begin
 | 
						|
                gettype(tt);
 | 
						|
                p.addtype(slt,tt);
 | 
						|
              end;
 | 
						|
            sl_vec :
 | 
						|
              begin
 | 
						|
                idx:=getlongint;
 | 
						|
                p.addconst(slt,idx);
 | 
						|
              end;
 | 
						|
            else
 | 
						|
              internalerror(200110204);
 | 
						|
          end;
 | 
						|
        until false;
 | 
						|
        getsymlist:=tsymlist(p);
 | 
						|
      end;
 | 
						|
 | 
						|
 | 
						|
    procedure tcompilerppufile.gettype(var t:ttype);
 | 
						|
      begin
 | 
						|
        getderef(t.deref);
 | 
						|
        t.def:=nil;
 | 
						|
        t.sym:=nil;
 | 
						|
      end;
 | 
						|
 | 
						|
 | 
						|
    function  tcompilerppufile.getasmsymbol:tasmsymbol;
 | 
						|
      begin
 | 
						|
        getasmsymbol:=tasmsymbol(pointer(getlongint));
 | 
						|
      end;
 | 
						|
 | 
						|
 | 
						|
    procedure tcompilerppufile.putposinfo(const p:tfileposinfo);
 | 
						|
      var
 | 
						|
        oldcrc : boolean;
 | 
						|
        info   : byte;
 | 
						|
      begin
 | 
						|
        { posinfo is not relevant for changes in PPU }
 | 
						|
        oldcrc:=do_crc;
 | 
						|
        do_crc:=false;
 | 
						|
        {
 | 
						|
          info byte layout in bits:
 | 
						|
          0-1 - amount of bytes for fileindex
 | 
						|
          2-3 - amount of bytes for line
 | 
						|
          4-5 - amount of bytes for column
 | 
						|
        }
 | 
						|
        info:=0;
 | 
						|
        { calculate info byte }
 | 
						|
        if (p.fileindex>$ff) then
 | 
						|
         begin
 | 
						|
           if (p.fileindex<=$ffff) then
 | 
						|
            info:=info or $1
 | 
						|
           else
 | 
						|
            if (p.fileindex<=$ffffff) then
 | 
						|
             info:=info or $2
 | 
						|
           else
 | 
						|
            info:=info or $3;
 | 
						|
          end;
 | 
						|
        if (p.line>$ff) then
 | 
						|
         begin
 | 
						|
           if (p.line<=$ffff) then
 | 
						|
            info:=info or $4
 | 
						|
           else
 | 
						|
            if (p.line<=$ffffff) then
 | 
						|
             info:=info or $8
 | 
						|
           else
 | 
						|
            info:=info or $c;
 | 
						|
          end;
 | 
						|
        if (p.column>$ff) then
 | 
						|
         begin
 | 
						|
           if (p.column<=$ffff) then
 | 
						|
            info:=info or $10
 | 
						|
           else
 | 
						|
            if (p.column<=$ffffff) then
 | 
						|
             info:=info or $20
 | 
						|
           else
 | 
						|
            info:=info or $30;
 | 
						|
          end;
 | 
						|
        { write data }
 | 
						|
        putbyte(info);
 | 
						|
        case (info and $03) of
 | 
						|
         0 : putbyte(p.fileindex);
 | 
						|
         1 : putword(p.fileindex);
 | 
						|
         2 : begin
 | 
						|
               putbyte(p.fileindex shr 16);
 | 
						|
               putword(p.fileindex and $ffff);
 | 
						|
             end;
 | 
						|
         3 : putlongint(p.fileindex);
 | 
						|
        end;
 | 
						|
        case ((info shr 2) and $03) of
 | 
						|
         0 : putbyte(p.line);
 | 
						|
         1 : putword(p.line);
 | 
						|
         2 : begin
 | 
						|
               putbyte(p.line shr 16);
 | 
						|
               putword(p.line and $ffff);
 | 
						|
             end;
 | 
						|
         3 : putlongint(p.line);
 | 
						|
        end;
 | 
						|
        case ((info shr 4) and $03) of
 | 
						|
         0 : putbyte(p.column);
 | 
						|
         1 : putword(p.column);
 | 
						|
         2 : begin
 | 
						|
               putbyte(p.column shr 16);
 | 
						|
               putword(p.column and $ffff);
 | 
						|
             end;
 | 
						|
         3 : putlongint(p.column);
 | 
						|
        end;
 | 
						|
        do_crc:=oldcrc;
 | 
						|
      end;
 | 
						|
 | 
						|
 | 
						|
    procedure tcompilerppufile.putguid(const g: tguid);
 | 
						|
      begin
 | 
						|
        putdata(g,sizeof(g));
 | 
						|
      end;
 | 
						|
 | 
						|
 | 
						|
    procedure tcompilerppufile.putexprint(v:tconstexprint);
 | 
						|
      begin
 | 
						|
        if sizeof(TConstExprInt)=8 then
 | 
						|
          begin
 | 
						|
             putlongint(longint(lo(v)));
 | 
						|
             putlongint(longint(hi(v)));
 | 
						|
          end
 | 
						|
        else if sizeof(TConstExprInt)=4 then
 | 
						|
          putlongint(longint(v))
 | 
						|
        else
 | 
						|
          internalerror(2002082601);
 | 
						|
      end;
 | 
						|
 | 
						|
 | 
						|
    procedure tcompilerppufile.PutPtrUInt(v:TConstPtrUInt);
 | 
						|
      begin
 | 
						|
        if sizeof(TConstPtrUInt)=8 then
 | 
						|
          begin
 | 
						|
             putlongint(longint(lo(v)));
 | 
						|
             putlongint(longint(hi(v)));
 | 
						|
          end
 | 
						|
        else if sizeof(TConstPtrUInt)=4 then
 | 
						|
          putlongint(longint(v))
 | 
						|
        else
 | 
						|
          internalerror(2002082601);
 | 
						|
      end;
 | 
						|
 | 
						|
 | 
						|
    procedure tcompilerppufile.putderef(const d:tderef);
 | 
						|
      var
 | 
						|
        oldcrc : boolean;
 | 
						|
      begin
 | 
						|
        oldcrc:=do_crc;
 | 
						|
        do_crc:=false;
 | 
						|
        putlongint(d.dataidx);
 | 
						|
        do_crc:=oldcrc;
 | 
						|
      end;
 | 
						|
 | 
						|
 | 
						|
    procedure tcompilerppufile.putsymlist(p:tsymlist);
 | 
						|
      var
 | 
						|
        hp : psymlistitem;
 | 
						|
      begin
 | 
						|
        putderef(p.procdefderef);
 | 
						|
        hp:=p.firstsym;
 | 
						|
        while assigned(hp) do
 | 
						|
         begin
 | 
						|
           putbyte(byte(hp^.sltype));
 | 
						|
           case hp^.sltype of
 | 
						|
             sl_call,
 | 
						|
             sl_load,
 | 
						|
             sl_subscript :
 | 
						|
               putderef(hp^.symderef);
 | 
						|
             sl_typeconv :
 | 
						|
               puttype(hp^.tt);
 | 
						|
             sl_vec :
 | 
						|
               putlongint(hp^.value);
 | 
						|
             else
 | 
						|
              internalerror(200110205);
 | 
						|
           end;
 | 
						|
           hp:=hp^.next;
 | 
						|
         end;
 | 
						|
        putbyte(byte(sl_none));
 | 
						|
      end;
 | 
						|
 | 
						|
 | 
						|
    procedure tcompilerppufile.puttype(const t:ttype);
 | 
						|
      begin
 | 
						|
        putderef(t.deref);
 | 
						|
      end;
 | 
						|
 | 
						|
 | 
						|
    procedure tcompilerppufile.putasmsymbol(s:tasmsymbol);
 | 
						|
      begin
 | 
						|
        if assigned(s) then
 | 
						|
         begin
 | 
						|
           if s.ppuidx=-1 then
 | 
						|
            begin
 | 
						|
              inc(objectlibrary.asmsymbolppuidx);
 | 
						|
              s.ppuidx:=objectlibrary.asmsymbolppuidx;
 | 
						|
            end;
 | 
						|
           putlongint(s.ppuidx);
 | 
						|
         end
 | 
						|
        else
 | 
						|
         putlongint(0);
 | 
						|
      end;
 | 
						|
 | 
						|
 | 
						|
end.
 | 
						|
{
 | 
						|
  $Log$
 | 
						|
  Revision 1.24  2003-12-22 22:15:13  peter
 | 
						|
    * fix write pointerconst
 | 
						|
 | 
						|
  Revision 1.23  2003/10/28 15:36:01  peter
 | 
						|
    * absolute to object field supported, fixes tb0458
 | 
						|
 | 
						|
  Revision 1.22  2003/10/23 14:44:07  peter
 | 
						|
    * splitted buildderef and buildderefimpl to fix interface crc
 | 
						|
      calculation
 | 
						|
 | 
						|
  Revision 1.21  2003/10/22 20:40:00  peter
 | 
						|
    * write derefdata in a separate ppu entry
 | 
						|
 | 
						|
  Revision 1.20  2003/10/07 16:06:30  peter
 | 
						|
    * tsymlist.def renamed to tsymlist.procdef
 | 
						|
    * tsymlist.procdef is now only used to store the procdef
 | 
						|
 | 
						|
  Revision 1.19  2003/06/07 20:26:32  peter
 | 
						|
    * re-resolving added instead of reloading from ppu
 | 
						|
    * tderef object added to store deref info for resolving
 | 
						|
 | 
						|
  Revision 1.18  2002/12/21 13:07:34  peter
 | 
						|
    * type redefine fix for tb0437
 | 
						|
 | 
						|
  Revision 1.17  2002/10/05 12:43:29  carl
 | 
						|
    * fixes for Delphi 6 compilation
 | 
						|
     (warning : Some features do not work under Delphi)
 | 
						|
 | 
						|
  Revision 1.16  2002/08/26 14:05:57  pierre
 | 
						|
   * fixed compilation cycle with -Cr option by adding explicit
 | 
						|
     longint typecast in PutPtrUInt and putexprint methods.
 | 
						|
   + added checks for sizeof and internalerros if size is not handled.
 | 
						|
 | 
						|
  Revision 1.15  2002/08/18 20:06:26  peter
 | 
						|
    * inlining is now also allowed in interface
 | 
						|
    * renamed write/load to ppuwrite/ppuload
 | 
						|
    * tnode storing in ppu
 | 
						|
    * nld,ncon,nbas are already updated for storing in ppu
 | 
						|
 | 
						|
  Revision 1.14  2002/08/11 14:32:28  peter
 | 
						|
    * renamed current_library to objectlibrary
 | 
						|
 | 
						|
  Revision 1.13  2002/08/11 13:24:14  peter
 | 
						|
    * saving of asmsymbols in ppu supported
 | 
						|
    * asmsymbollist global is removed and moved into a new class
 | 
						|
      tasmlibrarydata that will hold the info of a .a file which
 | 
						|
      corresponds with a single module. Added librarydata to tmodule
 | 
						|
      to keep the library info stored for the module. In the future the
 | 
						|
      objectfiles will also be stored to the tasmlibrarydata class
 | 
						|
    * all getlabel/newasmsymbol and friends are moved to the new class
 | 
						|
 | 
						|
  Revision 1.12  2002/05/18 13:34:18  peter
 | 
						|
    * readded missing revisions
 | 
						|
 | 
						|
  Revision 1.11  2002/05/16 19:46:45  carl
 | 
						|
  + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
 | 
						|
  + try to fix temp allocation (still in ifdef)
 | 
						|
  + generic constructor calls
 | 
						|
  + start of tassembler / tmodulebase class cleanup
 | 
						|
 | 
						|
  Revision 1.9  2002/05/12 16:53:15  peter
 | 
						|
    * moved entry and exitcode to ncgutil and cgobj
 | 
						|
    * foreach gets extra argument for passing local data to the
 | 
						|
      iterator function
 | 
						|
    * -CR checks also class typecasts at runtime by changing them
 | 
						|
      into as
 | 
						|
    * fixed compiler to cycle with the -CR option
 | 
						|
    * fixed stabs with elf writer, finally the global variables can
 | 
						|
      be watched
 | 
						|
    * removed a lot of routines from cga unit and replaced them by
 | 
						|
      calls to cgobj
 | 
						|
    * u32bit-s32bit updates for and,or,xor nodes. When one element is
 | 
						|
      u32bit then the other is typecasted also to u32bit without giving
 | 
						|
      a rangecheck warning/error.
 | 
						|
    * fixed pascal calling method with reversing also the high tree in
 | 
						|
      the parast, detected by tcalcst3 test
 | 
						|
 | 
						|
  Revision 1.8  2002/04/19 15:40:40  peter
 | 
						|
    * optimize tfileposinfo writing, this reduces the ppu size with 20%
 | 
						|
 | 
						|
}
 |