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