mirror of
				https://gitlab.com/freepascal.org/fpc/source.git
				synced 2025-10-29 07:01:44 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			481 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			ObjectPascal
		
	
	
	
	
	
			
		
		
	
	
			481 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(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;
 | |
| 
 | |
| 
 | |
|     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.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%
 | |
| 
 | |
| }
 | 
