| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283 | {    Copyright (c) 2018 by Nikolay Nikolov    This units contains support for Microsoft CodeView debug info generation    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. ****************************************************************************}{ documentation for the format, available on the internet:  earlier versions:    http://pagesperso-orange.fr/pierrelib/exec_formats/MS_Symbol_Type_v1.0.pdf    http://ftp.openwatcom.org/devel/docs/CodeView.pdf  modern versions:    https://llvm.org/docs/PDB/index.html    https://llvm.org/devmtg/2016-11/Slides/Kleckner-CodeViewInLLVM.pdf}unit dbgcodeview;{$i fpcdefs.inc}interface    uses      aasmdata,      dbgbase;    type      TSymbolIndex = (        S_COMPILE    = $0001, { Compile flags symbol }        S_REGISTER   = $0002, { Register variable }        S_CONSTANT   = $0003, { Constant symbol }        S_UDT        = $0004, { User-defined Type }        S_SSEARCH    = $0005, { Start search }        S_END        = $0006, { End block, procedure, with, or thunk }        S_SKIP       = $0007, { Skip - Reserve symbol space }        S_CVRESERVE  = $0008, { Reserved for internal use by the Microsoft debugger }        S_OBJNAME    = $0009, { Specify name of object file }        S_ENDARG     = $000a, { Specify end of arguments in function symbols }        S_COBOLUDT   = $000b, { Microfocus COBOL user-defined type }        S_MANYREG    = $000c, { Many register symbol }        S_RETURN     = $000d, { Function return description }        S_ENTRYTHIS  = $000e, { Description of this pointer at entry }        S_BPREL16    = $0100, { BP relative 16:16 }        S_LDATA16    = $0101, { Local data 16:16 }        S_GDATA16    = $0102, { Global data 16:16 }        S_PUB16      = $0103, { Public symbol 16:16 }        S_LPROC16    = $0104, { Local procedure start 16:16 }        S_GPROC16    = $0105, { Global procedure start 16:16 }        S_THUNK16    = $0106, { Thunk start 16:16 }        S_BLOCK16    = $0107, { Block start 16:16 }        S_WITH16     = $0108, { With start 16:16 }        S_LABEL16    = $0109, { Code label 16:16 }        S_CEXMODEL16 = $010a, { Change execution model 16:16 }        S_VFTPATH16  = $010b, { Virtual function table path descriptor 16:16 }        S_REGREL16   = $010c, { Specify 16:16 offset relative to arbitrary register }        S_BPREL32    = $0200, { BP relative 16:32 }        S_LDATA32    = $0201, { Local data 16:32 }        S_GDATA32    = $0202, { Global data 16:32 }        S_PUB32      = $0203, { Public symbol 16:32 }        S_LPROC32    = $0204, { Local procedure start 16:32 }        S_GPROC32    = $0205, { Global procedure start 16:32 }        S_THUNK32    = $0206, { Thunk start 16:32 }        S_BLOCK32    = $0207, { Block start 16:32 }        S_VFTPATH32  = $020b, { Virtual function table path descriptor 16:32 }        S_REGREL32   = $020c, { 16:32 offset relative to arbitrary register }        S_LTHREAD32  = $020d, { Local Thread Storage data }        S_GTHREAD32  = $020e, { Global Thread Storage data }        S_LPROCMIPS  = $0300, { Local procedure start MIPS }        S_GPROCMIPS  = $0301, { Global procedure start MIPS }        S_PROCREF    = $0400, { Reference to a procedure }        S_DATAREF    = $0401, { Reference to data }        S_ALIGN      = $0402  { Page align symbols }      );      TLeafIndex=(        LF_MODIFIER   = $0001, { Type Modifier (const, volatile, unaligned) }        LF_POINTER    = $0002, { Pointer }        LF_ARRAY      = $0003, { Simple Array }        LF_CLASS      = $0004, { Class (C++ class declaration) }        LF_STRUCTURE  = $0005, { Structure (C and C++ struct declaration) }        LF_UNION      = $0006, { Union }        LF_ENUM       = $0007, { Enumeration }        LF_PROCEDURE  = $0008, { Procedure }        LF_MFUNCTION  = $0009, { Member Function }        LF_VTSHAPE    = $000a, { Virtual Function Table Shape }        LF_COBOL0     = $000b, { reserved for Microfocus COBOL }        LF_COBOL1     = $000c, { reserved for Microfocus COBOL }        LF_BARRAY     = $000d, { Basic Array }        LF_LABEL      = $000e, { Label }        LF_NULL       = $000f, { Null }        LF_NOTTRAN    = $0010, { Not Translated }        LF_DIMARRAY   = $0011, { Multiply Dimensioned Array }        LF_VFTPATH    = $0012, { Path to Virtual Function Table }        LF_PRECOMP    = $0013, { Reference Precompiled Types }        LF_ENDPRECOMP = $0014, { End of Precompiled Types }        LF_OEM        = $0015, { OEM Generic Type }        LF_Reserved   = $0016, { Reserved }        LF_PAD0       = $f0,        LF_PAD1       = $f1,        LF_PAD2       = $f2,        LF_PAD3       = $f3,        LF_PAD4       = $f4,        LF_PAD5       = $f5,        LF_PAD6       = $f6,        LF_PAD7       = $f7,        LF_PAD8       = $f8,        LF_PAD9       = $f9,        LF_PAD10      = $fa,        LF_PAD11      = $fb,        LF_PAD12      = $fc,        LF_PAD13      = $fd,        LF_PAD14      = $fe,        LF_PAD15      = $ff,        LF_SKIP       = $0200, { Skip (used by incremental compilers to reserve space for future indexes) }        LF_ARGLIST    = $0201, { Argument List }        LF_DEFARG     = $0202, { Default Argument }        LF_LIST       = $0203, { Arbitrary List }        LF_FIELDLIST  = $0204, { Field List }        LF_DERIVED    = $0205, { Derived Classes }        LF_BITFIELD   = $0206, { Bit Fields }        LF_METHODLIST = $0207, { Method List }        LF_DIMCONU    = $0208, { Dimensioned Array with Constant Upper Bound }        LF_DIMCONLU   = $0209, { Dimensioned Array with Constant Lower and Upper Bounds }        LF_DIMVARU    = $020a, { Dimensioned Array with Variable Upper Bound }        LF_DIMVARLU   = $020b, { Dimensioned Array with Variable Lower and Upper Bounds }        LF_REFSYM     = $020c, { Referenced Symbol }        LF_BCLASS     = $0400, { Real Base Class }        LF_VBCLASS    = $0401, { Direct Virtual Base Class }        LF_IVBCLASS   = $0402, { Indirect Virtual Base Class }        LF_ENUMERATE  = $0403, { Enumeration Name and Value }        LF_FRIENDFCN  = $0404, { Friend Function }        LF_INDEX      = $0405, { Index to Another Type Record }        LF_MEMBER     = $0406, { Data Member }        LF_STMEMBER   = $0407, { Static Data Member }        LF_METHOD     = $0408, { Method }        LF_NESTTYPE   = $0409, { Nested Type Definition }        LF_VFUNCTAB   = $040a, { Virtual Function Table Pointer }        LF_FRIENDCLS  = $040b, { Friend Class }        LF_ONEMETHOD  = $040c, { One Method }        LF_VFUNCOFF   = $040d, { Virtual Function Offset }        LF_CHAR       = $8000, { Signed Char (8-bit value) }        LF_SHORT      = $8001, { Signed Short (16-bit signed value) }        LF_USHORT     = $8002, { Unsigned Short (16-bit unsigned value) }        LF_LONG       = $8003, { Signed Long (32-bit signed value) }        LF_ULONG      = $8004, { Unsigned Long (32-bit unsigned value) }        LF_REAL32     = $8005, { 32-bit Float }        LF_REAL64     = $8006, { 64-bit Float }        LF_REAL80     = $8007, { 80-bit Float }        LF_REAL128    = $8008, { 128-bit Float }        LF_QUADWORD   = $8009, { Signed Quad Word (64-bit signed value) }        LF_UQUADWORD  = $800a, { Unsigned Quad Word (64-bit unsigned value) }        LF_REAL48     = $800b, { 48-bit Float }        LF_COMPLEX32  = $800c, { 32-bit Complex }        LF_COMPLEX64  = $800d, { 64-bit Complex }        LF_COMPLEX80  = $800e, { 80-bit Complex }        LF_COMPLEX128 = $800f, { 128-bit Complex }        LF_VARSTRING  = $8010  { Variable-length String }      );    const      LF_NUMERIC = LF_CHAR;    type      { TDebugInfoCodeView }      TDebugInfoCodeView = class(TDebugInfo)      public        procedure insertlineinfo(list:TAsmList);override;      end;    procedure InsertLineInfo_OMF_LINNUM_MsLink(list: TAsmList);implementation    uses      globtype,      cutils,      aasmtai,      fmodule,      systems;    procedure InsertLineInfo_OMF_LINNUM_MsLink(list: TAsmList);      var        currfileinfo,        lastfileinfo : tfileposinfo;        nolineinfolevel : Integer;        currfuncname : pshortstring;        hp : tai;      begin        FillChar(lastfileinfo,sizeof(lastfileinfo),0);        hp:=Tai(list.first);        nolineinfolevel:=0;        while assigned(hp) do          begin            case hp.typ of              ait_function_name :                begin                  currfuncname:=tai_function_name(hp).funcname;                  list.concat(tai_comment.Create(strpnew('function: '+currfuncname^)));                end;              ait_force_line :                begin                  lastfileinfo.line:=-1;                end;              ait_marker :                begin                  case tai_marker(hp).kind of                    mark_NoLineInfoStart:                      inc(nolineinfolevel);                    mark_NoLineInfoEnd:                      dec(nolineinfolevel);                    else                      ;                  end;                end;              else                ;            end;            { OMF LINNUM records do not support multiple source files }            if (hp.typ=ait_instruction) and               (nolineinfolevel=0) and               (tailineinfo(hp).fileinfo.fileindex=main_module.unit_index) then              begin                currfileinfo:=tailineinfo(hp).fileinfo;                { line changed ? }                if (lastfileinfo.line<>currfileinfo.line) and (currfileinfo.line<>0) then                  begin                    { line directive }                    list.insertbefore(tai_directive.Create(asd_omf_linnum_line,tostr(currfileinfo.line)),hp);                  end;                lastfileinfo:=currfileinfo;              end;            hp:=tai(hp.next);          end;      end;{****************************************************************************                             TDebugInfoCodeView****************************************************************************}    procedure TDebugInfoCodeView.insertlineinfo(list: TAsmList);      begin        InsertLineInfo_OMF_LINNUM_MsLink(list);      end;{********************************************************************************************************************************************************}    const      dbg_codeview_info : tdbginfo =         (           id     : dbg_codeview;           idtxt  : 'CODEVIEW';         );initialization  RegisterDebugInfo(dbg_codeview_info,TDebugInfoCodeView);end.
 |