1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278 |
- {
- $Id$
- Copyright (c) 1998 by Peter Vreman
- Lowlevel GDB interface which communicates directly with libgdb
- See the file COPYING.FPC, included in this distribution,
- for details about the copyright.
- 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.
- **********************************************************************}
- unit GdbInt;
- interface
- { this is not needed (PM) $output_format as}
- {.$define Debug}
- {.$define DebugCommand}
- {$define NotImplemented}
- {$ifdef go32v2}
- {$undef NotImplemented}
- { ifdef GDB_V418 changed to ifndef GDB_V416}
- {$ifdef USE_GDB_OBJS}
- {$include gdbobjs.inc}
- {$else USE_GDB_OBJS}
- {$LINKLIB gdb}
- {$endif ndef USE_GDB_OBJS}
- {$LINKLIB dbg}
- {$LINKLIB c}
- {$endif go32v2}
- {$ifdef linux}
- {$undef NotImplemented}
- {$LINKLIB ncurses}
- {$LINKLIB gdb}
- {$LINKLIB c}
- {$LINKLIB gcc}
- {$endif linux}
- {$ifdef win32}
- {$undef NotImplemented}
- {$LINKLIB cygwin}
- {$LINKLIB gdb}
- {$ifdef USE_TERMCAP}
- {$LINKLIB termcap}
- {$else not USE_TERMCAP}
- {$LINKLIB ncurses}
- {$endif not USE_TERMCAP}
- {$LINKLIB gcc}
- {$LINKLIB c}
- {$LINKLIB cygwin}
- { all those are maybe not necessary
- but at least user32 is required
- because of clipboard handling PM }
- {$LINKLIB kernel32}
- {$LINKLIB user32}
- {$endif win32}
- {$ifdef go32v2}
- {$define supportexceptions}
- {$endif go32v2}
- {$ifdef linux}
- {$define supportexceptions}
- {$endif linux}
- {$ifdef NotImplemented}
- {$fatal This OS is not yet supported !!!}
- {$endif NotImplemented}
- type
- psyminfo=^tsyminfo;
- tsyminfo=record
- address : longint;
- fname : pchar;
- line : longint;
- funcname : pchar;
- offset : longint;
- end;
- tframeentry = object
- file_name : pchar;
- function_name : pchar;
- args : pchar;
- line_number : longint;
- address : longint;
- level : longint;
- constructor init;
- destructor done;
- procedure reset;
- procedure clear;
- end;
- pframeentry=^tframeentry;
- ppframeentry=^pframeentry;
- {$ifndef GDB_V416}
- { needed for handles }
- {not anymore I textrec.inc}
- { GDB_FILE type }
- type
- streamtype = (afile,astring);
- C_FILE = longint; { at least under DJGPP }
- P_C_FILE = ^C_FILE;
- PGDB_FILE = ^TGDB_FILE;
- TGDB_FILE = record
- ts_streamtype : streamtype;
- ts_filestream : P_C_FILE;
- ts_strbuf : pchar;
- ts_buflen : longint;
- end;
- {$ifdef win32}
- { from sys/reent.h
- real structure is bigger but only std.. are wanted here PM }
- REENT = record
- err : longint;
- stdin,stdout,stderr : P_C_FILE;
- end;
- PREENT = ^REENT;
- var _impure_ptr : PREENT;cvar;external;
- {$endif win32}
- {$endif not GDB_V416}
- type
- tgdbbuffer=object
- buf : pchar;
- size,
- idx : longint;
- {$ifndef GDB_V416}
- link : pgdb_file;
- {$endif not GDB_V416}
- constructor Init;
- destructor Done;
- procedure Reset;
- procedure Resize(nsize : longint);
- procedure Append(p:pchar);
- end;
- pgdbinterface=^tgdbinterface;
- tgdbinterface=object
- gdberrorbuf,
- gdboutputbuf : tgdbbuffer;
- got_error,
- reset_command,
- call_reset,
- Debuggee_started : boolean;
- { frames and frame info while recording a frame }
- frames : ppframeentry;
- frame_size,
- frame_count : longint;
- record_frames,
- frame_begin_seen : boolean;
- frame_level,
- command_level,
- stop_breakpoint_number,
- current_address,
- current_line_number,
- signal_start,
- signal_end,
- error_start,
- error_end,
- function_start,
- function_end,
- args_start,
- args_end,
- file_start,
- file_end,
- line_start,
- line_end : longint;
- { breakpoint }
- last_breakpoint_number,
- last_breakpoint_address,
- last_breakpoint_line : longint;
- last_breakpoint_file : pchar;
- invalid_breakpoint_line : boolean;
- { init }
- constructor init;
- destructor done;
- { Lowlevel }
- function error:boolean;
- function error_num:longint;
- procedure gdb_command(const s:string);
- procedure gdb__init;
- procedure gdb_done;
- procedure resize_frames;
- function add_frameentry:pframeentry;
- function get_frameentry(level : longint):pframeentry;
- function get_current_frame : longint;
- function set_current_frame(level : longint) : boolean;
- procedure clear_frames;
- { Highlevel }
- user_screen_shown,
- switch_to_user : boolean;
- procedure GetAddrSyminfo(addr:longint;var si:tsyminfo);
- procedure SelectSourceline(fn:pchar;line:longint);
- procedure StartSession;
- procedure BreakSession;
- procedure EndSession(code:longint);
- procedure DebuggerScreen;
- procedure UserScreen;
- { Hooks }
- procedure DoSelectSourceline(const fn:string;line:longint);virtual;
- procedure DoStartSession;virtual;
- procedure DoBreakSession;virtual;
- procedure DoEndSession(code:longint);virtual;
- procedure DoDebuggerScreen;virtual;
- procedure DoUserScreen;virtual;
- function AllowQuit : boolean;virtual;
- end;
- function GDBVersion : string;
- var
- curr_gdb : pgdbinterface;
- const
- use_gdb_file : boolean = false;
- var
- gdb_file : text;
- {$ifdef go32v2}
- { needed to be sure %fs contains the DOS memory selector
- used in Mem[] code PM }
- procedure reload_fs;
- {$endif go32v2}
- implementation
- uses
- {$ifdef win32}
- initc,
- {$endif win32}
- {$ifdef linux}
- linux,
- {$endif}
- {$ifdef go32v2}
- go32,
- dpmiexcp,
- initc,
- {$endif}
- strings;
- {*****************************************************************************
- Types used by libgdb.a
- *****************************************************************************}
- {$ifdef go32v2}
- type
- jmp_buf = dpmi_jmp_buf;
- pjmp_buf = pdpmi_jmp_buf;
- function setjmp(var rec : jmp_buf) : longint;cdecl;external;
- procedure longjmp(var rec : jmp_buf;return_value : longint);cdecl;external;
- procedure reload_fs;assembler;
- asm
- movw dosmemselector,%ax
- movw %ax,%fs
- end['EAX'];
- {$endif}
- {$ifdef win32}
- function setjmp(var rec : jmp_buf) : longint;cdecl;external;
- procedure longjmp(var rec : jmp_buf;return_value : longint);cdecl;external;
- {$ifndef supportexceptions}
- type
- { I don't think FPC would accept that
- the funcvar return type is the funcvar type itself ! PM }
- SignalHandler = Procedure(Sig : LongInt);cdecl;
- function signal(sig : longint;new_signal : SignalHandler) : SignalHandler;cdecl;external;
- {define supportexceptions not yet working }
- {$endif now exceptions are supported for win32}
- {$endif win32}
- type
- CORE_ADDR = longint;
- pCORE_ADDR = ^CORE_ADDR;
- pblock = ^block;
- tlanguage = (language_unknown,language_auto,language_c,
- language_cplus,language_java,language_chill,
- language_fortran,language_m2,language_asm,
- language_scm,language_pascal,language_objc);
- bptype = (bp_breakpoint,bp_hardware_breakpoint,
- bp_until,bp_finish,bp_watchpoint,bp_hardware_watchpoint,
- bp_read_watchpoint,bp_access_watchpoint,
- bp_longjmp,bp_longjmp_resume,bp_step_resume,
- bp_through_sigtramp,bp_watchpoint_scope,
- bp_call_dummy,bp_shlib_event);
- tenable = (disabled,enabled,shlib_disabled);
- bpdisp = (del,del_at_next_stop,disable,donttouch);
- {$PACKRECORDS 4}
- pbreakpoint = ^breakpoint;
- breakpoint = record
- next : pbreakpoint;
- typ : bptype;
- enable : tenable;
- disposition : bpdisp;
- number : longint;
- address : CORE_ADDR;
- line_number : longint;
- source_file : pchar;
- silent : byte;
- ignore_count : longint;
- shadow_contents : array[0..15] of char;
- inserted : char;
- duplicate : char;
- commands : pointer; {^command_line}
- frame : CORE_ADDR;
- cond : pointer; {^expression}
- addr_string : ^char;
- language : tlanguage;
- input_radix : longint;
- cond_string : ^char;
- exp_string : ^char;
- exp : pointer; {^expression}
- exp_valid_block : pblock; {^block;}
- val : pointer; {value_ptr;}
- val_chain : pointer; {value_ptr;}
- related_breakpoint : pbreakpoint;
- watchpoint_frame : CORE_ADDR;
- thread : longint;
- hit_count : longint;
- section : pointer; {^asection}
- end;
- tfreecode=(free_nothing,free_contents,free_linetable);
- psymtab = ^symtab;
- symtab = record
- next : psymtab;
- blockvector : pointer; {^blockvector;}
- linetable : pointer; {^linetable;}
- block_line_section : longint;
- primary : longint;
- filename : pchar;
- dirname : pchar;
- free_code : tfreecode;
- free_ptr : pchar;
- nlines : longint;
- line_charpos : ^longint;
- language : tlanguage;
- Debugformat : pchar;
- version : pchar;
- fullname : pchar;
- objfile : pointer; {^objfile;}
- end;
- psymtab_and_line = ^symtab_and_line;
- symtab_and_line = record
- symtab : psymtab;
- {$ifndef GDB_V416}
- { v4.16 does not have the section field !! }
- section : pointer; {^asection;}
- {$endif GDB_V416}
- line : longint;
- pc : CORE_ADDR;
- _end : CORE_ADDR;
- end;
- symtabs_and_lines = record
- sals : ^symtab_and_line;
- nelts : longint;
- end;
- psymbol = ^symbol;
- pminimal_symbol = ^minimal_symbol;
- general_symbol_info = record
- (* Name of the symbol. This is a required field. Storage for the name is
- allocated on the psymbol_obstack or symbol_obstack for the associated
- objfile. *)
- _name : pchar;
- (* Value of the symbol. Which member of this union to use, and what
- it means, depends on what kind of symbol this is and its
- SYMBOL_CLASS. See comments there for more details. All of these
- are in host byte order (though what they point to might be in
- target byte order, e.g. LOC_CONST_BYTES). *)
- value : record
- case integer of
- (* The fact that this is a long not a LONGEST mainly limits the
- range of a LOC_CONST. Since LOC_CONST_BYTES exists, I'm not
- sure that is a big deal. *)
- 0 : (ivalue : longint;);
- 1 : (block : pblock;);
- 2 : (bytes : pchar;);
- 3 : (address : CORE_ADDR;);
- (* for opaque typedef struct chain *)
- 4 : (chain : psymbol;);
- end;
- (* Since one and only one language can apply, wrap the language specific
- information inside a union. *)
- (* union
- {
- struct cplus_specific /* For C++ */
- /* and Java */
- {
- char *demangled_name;
- } cplus_specific;
- struct chill_specific /* For Chill */
- {
- char *demangled_name;
- } chill_specific;
- } language_specific; *)
- demangled_name : pchar;
- (* Record the source code language that applies to this symbol.
- This is used to select one of the fields from the language specific
- union above. *)
- language : tlanguage;
- (* Which section is this symbol in? This is an index into
- section_offsets for this objfile. Negative means that the symbol
- does not get relocated relative to a section.
- Disclaimer: currently this is just used for xcoff, so don't
- expect all symbol-reading code to set it correctly (the ELF code
- also tries to set it correctly). *)
- section : word;
- (* The bfd section associated with this symbol. *)
- bfd_section : pointer {^asection};
- end; { of general_symbol_info record declaration }
- tminimal_symbol_type =
- (
- mst_unknown := 0, (* Unknown type, the default *)
- mst_text, (* Generally executable instructions *)
- mst_data, (* Generally initialized data *)
- mst_bss, (* Generally uninitialized data *)
- mst_abs, (* Generally absolute (nonrelocatable) *)
- (* GDB uses mst_solib_trampoline for the start address of a shared
- library trampoline entry. Breakpoints for shared library functions
- are put there if the shared library is not yet loaded.
- After the shared library is loaded, lookup_minimal_symbol will
- prefer the minimal symbol from the shared library (usually
- a mst_text symbol) over the mst_solib_trampoline symbol, and the
- breakpoints will be moved to their true address in the shared
- library via breakpoint_re_set. *)
- mst_solib_trampoline, (* Shared library trampoline code *)
- (* For the mst_file* types, the names are only guaranteed to be unique
- within a given .o file. *)
- mst_file_text, (* Static version of mst_text *)
- mst_file_data, (* Static version of mst_data *)
- mst_file_bss (* Static version of mst_bss *)
- );
- namespace_enum = (
- (* UNDEF_NAMESPACE is used when a namespace has not been discovered or
- none of the following apply. This usually indicates an error either
- in the symbol information or in gdb's handling of symbols. *)
- UNDEF_NAMESPACE,
- (* VAR_NAMESPACE is the usual namespace. In C, this contains variables,
- function names, typedef names and enum type values. *)
- VAR_NAMESPACE,
- (* STRUCT_NAMESPACE is used in C to hold struct, union and enum type names.
- Thus, if `struct foo' is used in a C program, it produces a symbol named
- `foo' in the STRUCT_NAMESPACE. *)
- STRUCT_NAMESPACE,
- (* LABEL_NAMESPACE may be used for names of labels (for gotos);
- currently it is not used and labels are not recorded at all. *)
- LABEL_NAMESPACE,
- (* Searching namespaces. These overlap with VAR_NAMESPACE, providing
- some granularity with the search_symbols function. *)
- (* Everything in VAR_NAMESPACE minus FUNCTIONS_-, TYPES_-, and
- METHODS_NAMESPACE *)
- VARIABLES_NAMESPACE,
- (* All functions -- for some reason not methods, though. *)
- FUNCTIONS_NAMESPACE,
- (* All defined types *)
- TYPES_NAMESPACE,
- (* All class methods -- why is this separated out? *)
- METHODS_NAMESPACE
- );
- address_class = (
- (* Not used; catches errors *)
- LOC_UNDEF,
- (* Value is constant int SYMBOL_VALUE, host byteorder *)
- LOC_CONST,
- (* Value is at fixed address SYMBOL_VALUE_ADDRESS *)
- LOC_STATIC,
- (* Value is in register. SYMBOL_VALUE is the register number. *)
- LOC_REGISTER,
- (* It's an argument; the value is at SYMBOL_VALUE offset in arglist. *)
- LOC_ARG,
- (* Value address is at SYMBOL_VALUE offset in arglist. *)
- LOC_REF_ARG,
- (* Value is in register number SYMBOL_VALUE. Just like LOC_REGISTER
- except this is an argument. Probably the cleaner way to handle
- this would be to separate address_class (which would include
- separate ARG and LOCAL to deal with FRAME_ARGS_ADDRESS versus
- FRAME_LOCALS_ADDRESS), and an is_argument flag.
- For some symbol formats (stabs, for some compilers at least),
- the compiler generates two symbols, an argument and a register.
- In some cases we combine them to a single LOC_REGPARM in symbol
- reading, but currently not for all cases (e.g. it's passed on the
- stack and then loaded into a register). *)
- LOC_REGPARM,
- (* Value is in specified register. Just like LOC_REGPARM except the
- register holds the address of the argument instead of the argument
- itself. This is currently used for the passing of structs and unions
- on sparc and hppa. It is also used for call by reference where the
- address is in a register, at least by mipsread.c. *)
- LOC_REGPARM_ADDR,
- (* Value is a local variable at SYMBOL_VALUE offset in stack frame. *)
- LOC_LOCAL,
- (* Value not used; definition in SYMBOL_TYPE. Symbols in the namespace
- STRUCT_NAMESPACE all have this class. *)
- LOC_TYPEDEF,
- (* Value is address SYMBOL_VALUE_ADDRESS in the code *)
- LOC_LABEL,
- (* In a symbol table, value is SYMBOL_BLOCK_VALUE of a `struct block'.
- In a partial symbol table, SYMBOL_VALUE_ADDRESS is the start address
- of the block. Function names have this class. *)
- LOC_BLOCK,
- (* Value is a constant byte-sequence pointed to by SYMBOL_VALUE_BYTES, in
- target byte order. *)
- LOC_CONST_BYTES,
- (* Value is arg at SYMBOL_VALUE offset in stack frame. Differs from
- LOC_LOCAL in that symbol is an argument; differs from LOC_ARG in
- that we find it in the frame (FRAME_LOCALS_ADDRESS), not in the
- arglist (FRAME_ARGS_ADDRESS). Added for i960, which passes args
- in regs then copies to frame. *)
- LOC_LOCAL_ARG,
- (* Value is at SYMBOL_VALUE offset from the current value of
- register number SYMBOL_BASEREG. This exists mainly for the same
- things that LOC_LOCAL and LOC_ARG do; but we need to do this
- instead because on 88k DWARF gives us the offset from the
- frame/stack pointer, rather than the offset from the "canonical
- frame address" used by COFF, stabs, etc., and we don't know how
- to convert between these until we start examining prologues.
- Note that LOC_BASEREG is much less general than a DWARF expression.
- We don't need the generality (at least not yet), and storing a general
- DWARF expression would presumably take up more space than the existing
- scheme. *)
- LOC_BASEREG,
- (* Same as LOC_BASEREG but it is an argument. *)
- LOC_BASEREG_ARG,
- (* Value is at fixed address, but the address of the variable has
- to be determined from the minimal symbol table whenever the
- variable is referenced.
- This happens if debugging information for a global symbol is
- emitted and the corresponding minimal symbol is defined
- in another object file or runtime common storage.
- The linker might even remove the minimal symbol if the global
- symbol is never referenced, in which case the symbol remains
- unresolved. *)
- LOC_UNRESOLVED,
- (* Value is at a thread-specific location calculated by a
- target-specific method. *)
- LOC_THREAD_LOCAL_STATIC,
- (* The variable does not actually exist in the program.
- The value is ignored. *)
- LOC_OPTIMIZED_OUT,
- (* The variable is static, but actually lives at * (address).
- * I.e. do an extra indirection to get to it.
- * This is used on HP-UX to get at globals that are allocated
- * in shared libraries, where references from images other
- * than the one where the global was allocated are done
- * with a level of indirection.
- *)
- LOC_INDIRECT
- );
- minimal_symbol = record
- (* The general symbol info required for all types of symbols.
- The SYMBOL_VALUE_ADDRESS contains the address that this symbol
- corresponds to. *)
- ginfo : general_symbol_info;
- (* The info field is available for caching machine-specific information
- so it doesn't have to rederive the info constantly (over a serial line).
- It is initialized to zero and stays that way until target-dependent code
- sets it. Storage for any data pointed to by this field should be allo-
- cated on the symbol_obstack for the associated objfile.
- The type would be "void *" except for reasons of compatibility with older
- compilers. This field is optional.
- Currently, the AMD 29000 tdep.c uses it to remember things it has decoded
- from the instructions in the function header, and the MIPS-16 code uses
- it to identify 16-bit procedures. *)
- info : pchar;
- {$ifdef SOFUN_ADDRESS_MAYBE_MISSING}
- (* Which source file is this symbol in? Only relevant for mst_file_*. *)
- filename : pchar;
- {$endif}
- (* Classification types for this symbol. These should be taken as "advisory
- only", since if gdb can't easily figure out a classification it simply
- selects mst_unknown. It may also have to guess when it can't figure out
- which is a better match between two types (mst_data versus mst_bss) for
- example. Since the minimal symbol info is sometimes derived from the
- BFD library's view of a file, we need to live with what information bfd
- supplies. *)
- minimal_symbol_type : tminimal_symbol_type;
- end{ of minimal_symbol};
- block = record
- (* Addresses in the executable code that are in this block. *)
- startaddr,
- endaddr : CORE_ADDR ;
- (* The symbol that names this block, if the block is the body of a
- function; otherwise, zero. *)
- _function : psymbol;
- (* The `struct block' for the containing block, or 0 if none.
- The superblock of a top-level local block (i.e. a function in the
- case of C) is the STATIC_BLOCK. The superblock of the
- STATIC_BLOCK is the GLOBAL_BLOCK. *)
- superblock : pblock;
- (* Version of GCC used to compile the function corresponding
- to this block, or 0 if not compiled with GCC. When possible,
- GCC should be compatible with the native compiler, or if that
- is not feasible, the differences should be fixed during symbol
- reading. As of 16 Apr 93, this flag is never used to distinguish
- between gcc2 and the native compiler.
- If there is no function corresponding to this block, this meaning
- of this flag is undefined. *)
- gcc_compile_flag : byte;
- (* Number of local symbols. *)
- nsyms : longint;
- (* The symbols. If some of them are arguments, then they must be
- in the order in which we would like to print them. *)
- sym : array [0..0] of psymbol;
- end { of block definition };
- symbol = record
- (* The general symbol info required for all types of symbols. *)
- ginfo : general_symbol_info;
- (* Data type of value *)
- _type : pointer{ptype};
- (* Name space code. *)
- namespace : namespace_enum;
- (* Address class *)
- aclass : address_class;
- (* Line number of definition. FIXME: Should we really make the assumption
- that nobody will try to debug files longer than 64K lines? What about
- machine generated programs? *)
- line : word;
- (* Some symbols require an additional value to be recorded on a per-
- symbol basis. Stash those values here. *)
- (*union
- {
- /* Used by LOC_BASEREG and LOC_BASEREG_ARG. */
- short basereg;
- } *)
- aux_value_base_reg : word;
- (* Link to a list of aliases for this symbol.
- Only a "primary/main symbol may have aliases. *)
- aliases : pointer{palias_list};
- (* List of ranges where this symbol is active. This is only
- used by alias symbols at the current time. *)
- ranges : pointer{prange_list};
- end;
- target_signal = (TARGET_SIGNAL_FIRST := 0,
- TARGET_SIGNAL_HUP := 1,TARGET_SIGNAL_INT := 2,
- TARGET_SIGNAL_QUIT := 3,TARGET_SIGNAL_ILL := 4,
- TARGET_SIGNAL_TRAP := 5,TARGET_SIGNAL_ABRT := 6,
- TARGET_SIGNAL_EMT := 7,TARGET_SIGNAL_FPE := 8,
- TARGET_SIGNAL_KILL := 9,TARGET_SIGNAL_BUS := 10,
- TARGET_SIGNAL_SEGV := 11,TARGET_SIGNAL_SYS := 12,
- TARGET_SIGNAL_PIPE := 13,TARGET_SIGNAL_ALRM := 14,
- TARGET_SIGNAL_TERM := 15,TARGET_SIGNAL_URG := 16,
- TARGET_SIGNAL_STOP := 17,TARGET_SIGNAL_TSTP := 18,
- TARGET_SIGNAL_CONT := 19,TARGET_SIGNAL_CHLD := 20,
- TARGET_SIGNAL_TTIN := 21,TARGET_SIGNAL_TTOU := 22,
- TARGET_SIGNAL_IO := 23,TARGET_SIGNAL_XCPU := 24,
- TARGET_SIGNAL_XFSZ := 25,TARGET_SIGNAL_VTALRM := 26,
- TARGET_SIGNAL_PROF := 27,TARGET_SIGNAL_WINCH := 28,
- TARGET_SIGNAL_LOST := 29,TARGET_SIGNAL_USR1 := 30,
- TARGET_SIGNAL_USR2 := 31,TARGET_SIGNAL_PWR := 32,
- TARGET_SIGNAL_POLL := 33,TARGET_SIGNAL_WIND := 34,
- TARGET_SIGNAL_PHONE := 35,TARGET_SIGNAL_WAITING := 36,
- TARGET_SIGNAL_LWP := 37,TARGET_SIGNAL_DANGER := 38,
- TARGET_SIGNAL_GRANT := 39,TARGET_SIGNAL_RETRACT := 40,
- TARGET_SIGNAL_MSG := 41,TARGET_SIGNAL_SOUND := 42,
- TARGET_SIGNAL_SAK := 43,TARGET_SIGNAL_PRIO := 44,
- TARGET_SIGNAL_REALTIME_33 := 45,TARGET_SIGNAL_REALTIME_34 := 46,
- TARGET_SIGNAL_REALTIME_35 := 47,TARGET_SIGNAL_REALTIME_36 := 48,
- TARGET_SIGNAL_REALTIME_37 := 49,TARGET_SIGNAL_REALTIME_38 := 50,
- TARGET_SIGNAL_REALTIME_39 := 51,TARGET_SIGNAL_REALTIME_40 := 52,
- TARGET_SIGNAL_REALTIME_41 := 53,TARGET_SIGNAL_REALTIME_42 := 54,
- TARGET_SIGNAL_REALTIME_43 := 55,TARGET_SIGNAL_REALTIME_44 := 56,
- TARGET_SIGNAL_REALTIME_45 := 57,TARGET_SIGNAL_REALTIME_46 := 58,
- TARGET_SIGNAL_REALTIME_47 := 59,TARGET_SIGNAL_REALTIME_48 := 60,
- TARGET_SIGNAL_REALTIME_49 := 61,TARGET_SIGNAL_REALTIME_50 := 62,
- TARGET_SIGNAL_REALTIME_51 := 63,TARGET_SIGNAL_REALTIME_52 := 64,
- TARGET_SIGNAL_REALTIME_53 := 65,TARGET_SIGNAL_REALTIME_54 := 66,
- TARGET_SIGNAL_REALTIME_55 := 67,TARGET_SIGNAL_REALTIME_56 := 68,
- TARGET_SIGNAL_REALTIME_57 := 69,TARGET_SIGNAL_REALTIME_58 := 70,
- TARGET_SIGNAL_REALTIME_59 := 71,TARGET_SIGNAL_REALTIME_60 := 72,
- TARGET_SIGNAL_REALTIME_61 := 73,TARGET_SIGNAL_REALTIME_62 := 74,
- TARGET_SIGNAL_REALTIME_63 := 75,TARGET_SIGNAL_UNKNOWN,
- TARGET_SIGNAL_DEFAULT,TARGET_SIGNAL_LAST
- );
- strata = (dummy_stratum,file_stratum,core_stratum,download_stratum,process_stratum);
- ptarget_ops = ^target_ops;
- target_ops = record
- to_shortname : pchar;
- to_longname : pchar;
- to_doc : pchar;
- to_open : procedure (_para1:pchar; _para2:longint);
- to_close : procedure (_para1:longint);
- to_attach : procedure (_para1:pchar; _para2:longint);
- to_detach : procedure (_para1:pchar; _para2:longint);
- to_resume : procedure (_para1:longint; _para2:longint; _para3:target_signal);
- to_wait : pointer; {function (_para1:longint; _para2:ptarget_waitstatus):longint;}
- to_fetch_registers : procedure (_para1:longint);
- to_store_registers : procedure (_para1:longint);
- to_prepare_to_store : procedure ;
- to_xfer_memory : function (memaddr:CORE_ADDR; myaddr:pchar; len:longint; write:longint; target:ptarget_ops):longint;
- to_files_info : procedure (_para1:ptarget_ops);
- to_insert_breakpoint : function (_para1:CORE_ADDR; _para2:pchar):longint;
- to_remove_breakpoint : function (_para1:CORE_ADDR; _para2:pchar):longint;
- to_terminal_init : procedure ;
- to_terminal_inferior : procedure ;
- to_terminal_ours_for_output : procedure ;
- to_terminal_ours : procedure ;
- to_terminal_info : procedure (_para1:pchar; _para2:longint);
- to_kill : procedure ;
- to_load : procedure (_para1:pchar; _para2:longint);
- to_lookup_symbol : function (_para1:pchar; _para2:pCORE_ADDR):longint;
- to_create_inferior : procedure (_para1:pchar; _para2:pchar; _para3:ppchar);
- to_mourn_inferior : procedure ;
- to_can_run : function :longint;
- to_notice_signals : procedure (pid:longint);
- to_thread_alive : function (pid:longint):longint;
- to_stop : procedure ;
- to_stratum : strata;
- DONT_USE : pointer;
- to_has_all_memory : longint;
- to_has_memory : longint;
- to_has_stack : longint;
- to_has_registers : longint;
- to_has_execution : longint;
- to_sections : pointer; {^section_table}
- to_sections_end : pointer; {^section_table}
- to_magic : longint;
- end;
- {$PACKRECORDS NORMAL}
- {*****************************************************************************
- Define external calls to libgdb.a
- *****************************************************************************}
- var
- { external variables }
- error_return : jmp_buf;cvar;external;
- quit_return : jmp_buf;cvar;external;
- inferior_pid : longint;cvar;external;
- create_breakpoint_hook : pointer;cvar;external;
- current_target : target_ops;cvar;external;
- stop_pc : CORE_ADDR;cvar;external;
- { we need also to declare some vars }
- watchdog : longint;cvar;public;
- gdb_error : longint;cvar;public;
- display_time : longbool;cvar;public;
- display_space : longbool;cvar;public;
- {$ifndef GDB_V416}
- { the following are also needed from version 4.18 }
- { Whether this is the command line version or not }
- tui_version : longint;cvar;public;
- { Whether xdb commands will be handled }
- xdb_commands : longint;cvar;public;
- { Whether dbx commands will be handled }
- dbx_commands : longint;cvar;public;
- var
- gdb_stdout : PGDB_FILE;cvar;public;
- gdb_stderr : PGDB_FILE;cvar;public;
- { used for gdb_stdout and gdb_stderr }
- function xmalloc(size : longint) : pointer;cdecl;external;
- {$endif not GDB_V416}
- function find_pc_line(i:CORE_ADDR;l:longint):symtab_and_line;cdecl;external;
- function find_pc_function(i:CORE_ADDR):psymbol;cdecl;external;
- function lookup_minimal_symbol_by_pc(i : CORE_ADDR):pminimal_symbol;cdecl;external;
- procedure gdb_init;cdecl;external;
- procedure execute_command(p:pchar;i:longint);cdecl;external;
- procedure target_kill;cdecl;external;
- procedure target_close(i:longint);cdecl;external;
- {*****************************************************************************
- Helpers
- *****************************************************************************}
- procedure Debug(const s:string);
- begin
- if use_gdb_file then
- Writeln(gdb_file,s)
- else
- Writeln(s);
- end;
- {*****************************************************************************
- TFrameEntry
- *****************************************************************************}
- constructor tframeentry.init;
- begin
- Reset;
- end;
- destructor tframeentry.done;
- begin
- Clear;
- end;
- procedure tframeentry.reset;
- begin
- file_name:=nil;
- function_name:=nil;
- args:=nil;
- line_number:=0;
- address:=0;
- end;
- procedure tframeentry.clear;
- begin
- if assigned(file_name) then
- strdispose(file_name);
- if assigned(function_name) then
- strdispose(function_name);
- if assigned(args) then
- strdispose(args);
- reset;
- end;
- {*****************************************************************************
- tgdbbuffer
- *****************************************************************************}
- const
- blocksize=2048;
- constructor tgdbbuffer.init;
- begin
- Buf:=nil;
- {$ifndef GDB_V416}
- link:=nil;
- {$endif not GDB_V416}
- Size:=0;
- Resize(blocksize);
- Reset;
- end;
- destructor tgdbbuffer.done;
- begin
- if assigned(buf) then
- freemem(buf,size);
- {$ifndef GDB_V416}
- if assigned(link) then
- begin
- link^.ts_streamtype:=afile;
- link^.ts_strbuf:=nil;
- link^.ts_buflen:=0;
- end;
- {$endif not GDB_V416}
- end;
- procedure tgdbbuffer.reset;
- begin
- idx:=0;
- Buf[0]:=#0;
- end;
- procedure tgdbbuffer.append(p:pchar);
- var
- len : longint;
- begin
- if not assigned(p) then
- exit;
- len:=Strlen(p);
- if len+idx>size then
- Resize(len+idx);
- Move(p^,buf[idx],len);
- inc(idx,len);
- buf[idx]:=#0;
- end;
- procedure tgdbbuffer.resize(nsize : longint);
- var
- np : pchar;
- begin
- nsize:=((nsize+blocksize-1) div blocksize)*blocksize;
- getmem(np,nsize);
- if assigned(buf) then
- begin
- move(buf^,np^,size);
- freemem(buf,size);
- end;
- buf:=np;
- size:=nsize;
- {$ifndef GDB_V416}
- if assigned(link) then
- begin
- link^.ts_strbuf:=buf;
- link^.ts_buflen:=size;
- end;
- {$endif not GDB_V416}
- end;
- {*****************************************************************************
- Hook calls from libgdb.a
- *****************************************************************************}
- {$ifdef go32v2}
- procedure gdbpas_prev_exception_handler;cdecl;public;
- begin
- end;
- {$endif go32v2}
- procedure init_proc;cdecl;public;
- begin
- end;
- procedure annotate_signalled;cdecl;public;
- begin
- {$ifdef Debug}
- Debug('|signalled|');
- {$endif}
- end;
- procedure annotate_signal_name;cdecl;public;
- begin
- {$ifdef Debug}
- Debug('|signal_name|');
- with curr_gdb^ do
- signal_start:=gdboutputbuf.idx;
- {$endif}
- end;
- procedure annotate_signal_name_end;cdecl;public;
- begin
- {$ifdef Debug}
- Debug('|signal_name_end|');
- {$endif}
- end;
- procedure annotate_signal_string;cdecl;public;
- begin
- {$ifdef Debug}
- Debug('|signal_string|');
- {$endif}
- end;
- procedure annotate_signal_string_end;cdecl;public;
- begin
- {$ifdef Debug}
- Debug('|signal_string_end|');
- {$endif}
- with curr_gdb^ do
- begin
- signal_end:=gdboutputbuf.idx;
- {
- signal = (char *)alloca(signal_end-signal_start+1);
- strncpy(signal,gdb_output_buffer+signal_start,signal_end-signal_start);
- signal[signal_end-signal_start] = 0;
- if (user_screen_shown)
- __DebuggerScreen();
- _UserWarning(WARN_SIGNALED,signal);
- __UserScreen();
- else
- _UserWarning(WARN_SIGNALED,signal); }
- call_reset:=true;
- end;
- end;
- procedure annotate_signal;cdecl;public;
- begin
- {$ifdef Debug}
- Debug('|signal|');
- {$endif}
- end;
- procedure annotate_exited(exitstatus:longint);cdecl;public;
- begin
- {$ifdef Debug}
- Debug('|exited|');
- {$endif}
- {#ifdef __DJGPP__
- /* this is very important. The exit code of a djgpp program
- disables interrupts and after this there is no other interrupt
- called, which enables interrupts with the iret. */
- __dpmi_get_and_enable_virtual_interrupt_state();
- #endif }
- {$ifdef go32v2}
- {$asmmode att}
- asm
- movw $0x901,%ax
- int $0x31
- end;
- {$asmmode default}
- reload_fs;
- {$endif def go32v2}
- curr_gdb^.DebuggerScreen;
- { DeleteBreakPoints; }
- curr_gdb^.EndSession(exitstatus);
- end;
- procedure annotate_error;cdecl;public;
- begin
- {$ifdef Debug}
- Debug('|error|');
- {$endif}
- end;
- procedure annotate_error_begin;cdecl;public;
- begin
- {$ifdef Debug}
- Debug('|error begin|');
- {$endif}
- with curr_gdb^ do
- begin
- error_start:=gdboutputbuf.idx+strlen(gdboutputbuf.buf);
- got_error:=true;
- end;
- {$ifdef Debug}
- Debug('|end of error begin|');
- {$endif}
- end;
- procedure annotate_starting;cdecl;public;
- begin
- {$ifdef Debug}
- Debug('|starting|');
- {$endif}
- {$ifdef go32v2}
- reload_fs;
- {$endif go32v2}
- curr_gdb^.UserScreen;
- end;
- procedure annotate_stopped;cdecl;public;
- var
- sym : symtab_and_line;
- fname : pchar;
- begin
- {$ifdef Debug}
- Debug('|stopped|');
- {$endif}
- with curr_gdb^ do
- begin
- {$ifdef go32v2}
- reload_fs;
- {$endif go32v2}
- DebuggerScreen;
- Debuggee_started:=inferior_pid<>0;
- if not Debuggee_started then exit;
- if reset_command then exit;
- sym:=find_pc_line(stop_pc,0);
- if assigned(sym.symtab) then
- fname:=sym.symtab^.filename
- else
- fname:=nil;
- SelectSourceLine(fname,sym.line);
- end;
- end;
- procedure proc_remove_foreign(pid:longint);cdecl;public;
- begin
- end;
- procedure breakpoints_changed;cdecl;public;
- begin
- {$ifdef Debug}
- Debug('|breakpoints_changed|');
- {$endif}
- end;
- procedure annotate_breakpoint(num:longint);cdecl;public;
- begin
- {$ifdef Debug}
- Debug('|breakpoint(%d)|');
- {$endif}
- With Curr_gdb^ do
- stop_breakpoint_number:=num;
- end;
- procedure annotate_watchpoint(num:longint);cdecl;public;
- begin
- {$ifdef Debug}
- Debug('|watchpoint(%d)|');
- {$endif}
- With Curr_gdb^ do
- stop_breakpoint_number:=num;
- end;
- procedure annotate_catchpoint(num:longint);cdecl;public;
- begin
- {$ifdef Debug}
- Debug('|catchpoint(%d)|');
- {$endif}
- With Curr_gdb^ do
- stop_breakpoint_number:=num;
- end;
- procedure annotate_breakpoints_headers;cdecl;public;
- begin
- {$ifdef Debug}
- Debug('|breakpoints_headers|');
- {$endif}
- end;
- procedure annotate_breakpoints_table;cdecl;public;
- begin
- {$ifdef Debug}
- Debug('|breakpoints_table|');
- {$endif}
- end;
- procedure annotate_record;cdecl;public;
- begin
- {$ifdef Debug}
- Debug('|record|');
- {$endif}
- end;
- procedure annotate_breakpoints_table_end;cdecl;public;
- begin
- {$ifdef Debug}
- Debug('|breakpoints_table_end|');
- {$endif}
- end;
- procedure annotate_frames_invalid;cdecl;public;
- begin
- {$ifdef Debug}
- Debug('|frames_invalid|');
- {$endif}
- end;
- procedure annotate_frame_begin(level:longint;pc:CORE_ADDR);cdecl;public;
- begin
- {$ifdef Debug}
- Debug('|frame_begin(%d,%ld)|');
- {$endif}
- with curr_gdb^ do
- begin
- frame_begin_seen:=true;
- frame_level:=level;
- current_address:=pc;
- current_line_number:=-1;
- function_start:=-1;
- function_end:=-1;
- args_start:=-1;
- args_end:=-1;
- file_start:=-1;
- file_end:=-1;
- line_start:=-1;
- line_end:=-1;
- end;
- end;
- procedure annotate_frame_address;cdecl;public;
- begin
- {$ifdef Debug}
- Debug('|frame_address|');
- {$endif}
- end;
- procedure annotate_frame_address_end;cdecl;public;
- begin
- {$ifdef Debug}
- Debug('|frame_address_end|');
- {$endif}
- end;
- procedure annotate_frame_function_name;cdecl;public;
- begin
- {$ifdef Debug}
- Debug('|frame_function_name|');
- {$endif}
- with curr_gdb^ do
- function_start:=gdboutputbuf.idx;
- end;
- procedure annotate_frame_args;cdecl;public;
- begin
- {$ifdef Debug}
- Debug('|frame_args|');
- {$endif}
- with curr_gdb^ do
- begin
- function_end:=gdboutputbuf.idx;
- args_start:=gdboutputbuf.idx;
- end;
- end;
- procedure annotate_frame_source_begin;cdecl;public;
- begin
- {$ifdef Debug}
- Debug('|frame_source_begin|');
- {$endif}
- with curr_gdb^ do
- args_end:=gdboutputbuf.idx;
- end;
- procedure annotate_frame_source_file;cdecl;public;
- begin
- {$ifdef Debug}
- Debug('|frame_source_file|');
- {$endif}
- with curr_gdb^ do
- file_start:=gdboutputbuf.idx;
- end;
- procedure annotate_frame_source_file_end;cdecl;public;
- begin
- {$ifdef Debug}
- Debug('|frame_source_file_end|');
- {$endif}
- with curr_gdb^ do
- file_end:=gdboutputbuf.idx;
- end;
- procedure annotate_frame_source_line;cdecl;public;
- begin
- {$ifdef Debug}
- Debug('|frame_source_line|');
- {$endif}
- with curr_gdb^ do
- line_start:=gdboutputbuf.idx;
- end;
- procedure annotate_frame_source_end;cdecl;public;
- begin
- {$ifdef Debug}
- Debug('|frame_source_end|');
- {$endif}
- with curr_gdb^ do
- line_end:=gdboutputbuf.idx;
- end;
- procedure annotate_frame_where;cdecl;public;
- begin
- {$ifdef Debug}
- Debug('|frame_where|');
- {$endif}
- end;
- procedure annotate_frame_end;cdecl;public;
- var
- fe : pframeentry;
- c : char;
- err : integer;
- begin
- {$ifdef Debug}
- Debug('|frame_end|');
- {$endif}
- with curr_gdb^ do
- begin
- if (not record_frames) or (not frame_begin_seen) then
- exit;
- { This can happen, when the function has no Debugging information }
- if (args_start >= 0) and (args_end < 0) then
- args_end:=gdboutputbuf.idx;
- frame_begin_seen:=false;
- fe:=get_frameentry(frame_level);
- fe^.address:=current_address;
- fe^.level:=frame_level;
- if (function_start>=0) then
- begin
- c:=gdboutputbuf.buf[function_end];
- gdboutputbuf.buf[function_end]:=#0;
- fe^.function_name:=strnew(gdboutputbuf.buf+function_start);
- gdboutputbuf.buf[function_end]:=c;
- end;
- if (file_start>=0) then
- begin
- c:=gdboutputbuf.buf[file_end];
- gdboutputbuf.buf[file_end]:=#0;
- fe^.file_name:=strnew(gdboutputbuf.buf+file_start);
- gdboutputbuf.buf[file_end]:=c;
- end;
- if (args_start>=0) then
- begin
- if (gdboutputbuf.buf[args_end-1]=#10) then
- dec(args_end);
- c:=gdboutputbuf.buf[args_end];
- gdboutputbuf.buf[args_end]:=#0;
- fe^.args:=strnew(gdboutputbuf.buf+args_start);
- gdboutputbuf.buf[args_end]:=c;
- end;
- if (line_start>=0) then
- begin
- c:=gdboutputbuf.buf[line_end];
- gdboutputbuf.buf[line_end]:=#0;
- { sscanf(gdb_output_buffer+line_start,'%d',&fe^.line_number); }
- val(strpas(pchar(@gdboutputbuf.buf[line_start])),fe^.line_number,err);
- gdboutputbuf.buf[line_end]:=c;
- end;
- end;
- end;
- procedure annotate_quit;cdecl;public;
- begin
- {$ifdef Debug}
- Debug('|quit|');
- {$endif}
- end;
- procedure annotate_arg_begin;cdecl;public;
- begin
- {$ifdef Debug}
- Debug('|arg_begin|');
- {$endif}
- end;
- procedure annotate_arg_name_end;cdecl;public;
- begin
- {$ifdef Debug}
- Debug('|arg_name_end|');
- {$endif}
- end;
- procedure annotate_arg_value(typ:pointer);cdecl;public;
- begin
- {$ifdef Debug}
- Debug('|arg_value|');
- {$endif}
- end;
- procedure annotate_arg_end;cdecl;public;
- begin
- {$ifdef Debug}
- Debug('|arg_end|');
- {$endif}
- end;
- procedure annotate_source(filename:pchar;line,character,mid:longint;pc:CORE_ADDR);cdecl;public;
- begin
- {$ifdef Debug}
- Debug('|source|');
- {$endif}
- end;
- procedure annotate_function_call;cdecl;public;
- begin
- {$ifdef Debug}
- Debug('|function_call|');
- {$endif}
- end;
- procedure annotate_signal_handler_caller;cdecl;public;
- begin
- {$ifdef Debug}
- Debug('|signal_handler_caller|');
- {$endif}
- end;
- procedure annotate_array_section_begin(index:longint;elttype:pointer);cdecl;public;
- begin
- {$ifdef Debug}
- Debug('|array_section_begin()|');
- {$endif}
- end;
- procedure annotate_elt_rep(repcount:longint);cdecl;public;
- begin
- {$ifdef Debug}
- Debug('|elt_rep()|');
- {$endif}
- end;
- procedure annotate_elt_rep_end;cdecl;public;
- begin
- {$ifdef Debug}
- Debug('|elt_rep_end|');
- {$endif}
- end;
- procedure annotate_elt;cdecl;public;
- begin
- {$ifdef Debug}
- Debug('|elt|');
- {$endif}
- end;
- procedure annotate_array_section_end;cdecl;public;
- begin
- {$ifdef Debug}
- Debug('|array_section_end|');
- {$endif}
- end;
- procedure annotate_display_begin;cdecl;public;
- begin
- {$ifdef Debug}
- Debug('|display_begin|');
- {$endif}
- end;
- procedure annotate_display_number_end;cdecl;public;
- begin
- {$ifdef Debug}
- Debug('|display_number_end|');
- {$endif}
- end;
- procedure annotate_display_format;cdecl;public;
- begin
- {$ifdef Debug}
- Debug('|display_format|');
- {$endif}
- end;
- procedure annotate_display_expression;cdecl;public;
- begin
- {$ifdef Debug}
- Debug('|display_expression|');
- {$endif}
- end;
- procedure annotate_display_expression_end;cdecl;public;
- begin
- {$ifdef Debug}
- Debug('|display_expression_end|');
- {$endif}
- end;
- procedure annotate_display_value;cdecl;public;
- begin
- {$ifdef Debug}
- Debug('|display_value|');
- {$endif}
- end;
- procedure annotate_display_end;cdecl;public;
- begin
- {$ifdef Debug}
- Debug('|display_end|');
- {$endif}
- end;
- procedure annotate_field (num:longint);cdecl;public;
- begin
- {$ifdef Debug}
- Debug('a_field(%d)');
- {$endif}
- end;
- procedure annotate_field_begin(typ:pointer);cdecl;public;
- begin
- {$ifdef Debug}
- Debug('a_field_begin\n');
- {$endif}
- end;
- procedure annotate_field_name_end;cdecl;public;
- begin
- {$ifdef Debug}
- Debug('a_field_name_end\n');
- {$endif}
- end;
- procedure annotate_field_value;cdecl;public;
- begin
- {$ifdef Debug}
- Debug('a_field_value\n');
- {$endif}
- end;
- procedure annotate_field_end;cdecl;public;
- begin
- {$ifdef Debug}
- Debug('a_field_end\n');
- {$endif}
- end;
- procedure annotate_value_history_begin (histindex:longint;typ:pointer);cdecl;public;
- begin
- {$ifdef Debug}
- Debug('a_value_history_begin(%d)\n');
- {$endif}
- end;
- procedure annotate_value_begin (typ:pointer);cdecl;public;
- begin
- {$ifdef Debug}
- Debug('a_value_begin\n');
- {$endif}
- end;
- procedure annotate_value_history_value;cdecl;public;
- begin
- {$ifdef Debug}
- Debug('a_value_history_value\n');
- {$endif}
- end;
- procedure annotate_value_history_end;cdecl;public;
- begin
- {$ifdef Debug}
- Debug('a_value_history_end\n');
- {$endif}
- end;
- procedure annotate_value_end;cdecl;public;
- begin
- {$ifdef Debug}
- Debug('a_value_end\n');
- {$endif}
- end;
- procedure _initialize_annotate;cdecl;public;
- begin
- end;
- procedure fputs_unfiltered(linebuffer:pchar;stream:pointer);cdecl;public;
- begin
- with curr_gdb^ do
- {$ifndef gdb_v416}
- if stream = gdb_stderr then
- gdberrorbuf.append(linebuffer)
- else
- {$endif not gdb_v416}
- gdboutputbuf.append(linebuffer);
- end;
- procedure CreateBreakPointHook(var b:breakpoint);cdecl;
- var
- sym : symtab_and_line;
- begin
- sym:=find_pc_line(b.address,0);
- with curr_gdb^ do
- begin
- last_breakpoint_number:=b.number;
- { function breakpoints have zero as file and as line !!
- but they are valid !! }
- invalid_breakpoint_line:=(b.line_number<>sym.line) and (b.line_number<>0);
- last_breakpoint_address:=b.address;
- last_breakpoint_line:=sym.line;
- if assigned(sym.symtab) then
- last_breakpoint_file:=sym.symtab^.filename
- else
- last_breakpoint_file:=nil;
- end;
- end;
- {*****************************************************************************
- tgdbinterface
- *****************************************************************************}
- constructor tgdbinterface.init;
- begin
- gdboutputbuf.init;
- gdberrorbuf.init;
- record_frames:=true;
- {$ifndef GDB_V416}
- (* GDB_FILE *
- gdb_file_init_astring (n)
- int n;
- should we use xmalloc ?
- gdb could resize the buffer => crash,
- but normally it should not if unfiltered !! PM *)
- gdb_stdout^.ts_streamtype := astring;
- gdb_stdout^.ts_strbuf := gdboutputbuf.buf;
- gdb_stdout^.ts_buflen := gdboutputbuf.size;
- gdboutputbuf.link:=gdb_stdout;
- gdb_stderr^.ts_streamtype := astring;
- gdb_stderr^.ts_strbuf := gdberrorbuf.buf;
- gdb_stderr^.ts_buflen := gdberrorbuf.size;
- gdberrorbuf.link:=gdb_stderr;
- {$endif not GDB_V416}
- gdb__init;
- curr_gdb:=@self;
- command_level:=0;
- { set output mode for GDB }
- { only these values disable filtering
- DONT CHANGE THEM !!! PM }
- gdb_command('set width 0xffffffff');
- gdb_command('set height 0xffffffff');
- { other standard commands used for fpc debugging }
- gdb_command('set print demangle off');
- gdb_command('set gnutarget auto');
- gdb_command('set language auto');
- gdb_command('set print vtbl on');
- gdb_command('set print object on');
- gdb_command('set print null-stop');
- end;
- destructor tgdbinterface.done;
- begin
- clear_frames;
- gdb_done;
- gdboutputbuf.done;
- gdberrorbuf.done;
- end;
- procedure tgdbinterface.gdb__init;
- begin
- gdboutputbuf.reset;
- gdberrorbuf.reset;
- create_breakpoint_hook:=@CreateBreakPointHook;
- end;
- procedure tgdbinterface.gdb_done;
- begin
- if debuggee_started then
- begin
- current_target.to_kill;
- current_target.to_close(1);
- end;
- create_breakpoint_hook:=nil;
- end;
- function tgdbinterface.error:boolean;
- begin
- error:=got_error;
- end;
- function tgdbinterface.error_num:longint;
- begin
- error_num:=gdb_error;
- end;
- var
- top_level_val : longint;
- procedure tgdbinterface.gdb_command(const s:string);
- var
- command : array[0..256] of char;
- s2 : string;
- old_quit_return,
- old_error_return : jmp_buf;
- begin
- inc(command_level);
- move(s[1],command,length(s));
- command[length(s)]:=#0;
- old_quit_return:=quit_return;
- old_error_return:=error_return;
- gdb_error:=0;
- got_error:=false;
- stop_breakpoint_number:=0;
- { Trap quit commands }
- s2:=s;
- while (length(s2)>0) and ((s2[1]=' ') or (s2[1]=#9)) do
- s2:=copy(s2,2,255);
- if (length(s2)>0) and
- (UpCase(s2[1])='Q') and
- ((length(s2)=1) or
- (s2[2]=' ') or
- ((UpCase(s2[2])='U') and
- ((length(s2)=2) or
- (s2[3]=' ') or
- ((UpCase(s2[3])='I') and
- ((length(s2)=3) or
- (s2[4]=' ') or
- ((UpCase(s2[4])='T') and
- ((length(s2)=4) or
- (s2[5]=' ')
- ))))))) then
- begin
- if not AllowQuit then
- exit;
- end;
- {$ifdef DebugCommand}
- Debug('start of handle_gdb_command ('+s+')');
- {$endif}
- top_level_val:=setjmp(error_return);
- if top_level_val=0 then
- begin
- quit_return:=error_return;
- execute_command(@command,0);
- {$ifdef go32v2}
- reload_fs;
- {$endif go32v2}
- end
- else
- {$ifdef Debug}
- Debug('error longjmp in handle_gdb_command ('+s+')');
- {$endif}
- ;
- {$ifdef DebugCommand}
- Debug('end of handle_gdb_command ('+s+')');
- {$endif}
- quit_return:=old_quit_return;
- error_return:=old_error_return;
- dec(command_level);
- end;
- procedure tgdbinterface.resize_frames;
- var
- i : longint;
- new_frames : ppframeentry;
- begin
- if (frame_count>=frame_size) then
- begin
- getmem(new_frames,sizeof(pointer)*(frame_count+1));
- for i:=0 to frame_size-1 do
- new_frames[i]:=frames[i];
- if assigned(frames) then
- freemem(frames,sizeof(pointer)*frame_size);
- frames:=new_frames;
- frame_size:=frame_count+1;
- for i:=frame_count to frame_size-1 do
- frames[i]:=new(pframeentry,init);
- end;
- end;
- function tgdbinterface.add_frameentry:pframeentry;
- begin
- resize_frames;
- add_frameentry:=frames[frame_count];
- inc(frame_count);
- end;
- function tgdbinterface.get_frameentry(level : longint) : pframeentry;
- begin
- { only climb values one by one PM }
- if level>=frame_count then
- resize_frames;
- get_frameentry:=frames[level];
- frames[level]^.clear;
- if level>=frame_count then
- inc(frame_count);
- end;
- procedure tgdbinterface.clear_frames;
- var
- i : longint;
- begin
- for i:=0 to frame_size-1 do
- dispose(frames[i],done);
- freemem(frames,sizeof(pointer)*Frame_size);
- frame_count:=0;
- frame_size:=0;
- end;
- function tgdbinterface.get_current_frame : longint;
- begin
- record_frames:=false;
- gdb_command('f');
- get_current_frame:=frame_level;
- record_frames:=true;
- end;
- function tgdbinterface.set_current_frame(level : longint) : boolean;
- var
- s : string;
- begin
- record_frames:=false;
- str(level,s);
- gdb_command('f '+s);
- if level=frame_level then
- set_current_frame:=true
- else
- set_current_frame:=false;
- record_frames:=true;
- end;
- {*****************************************************************************
- Highlevel tgdbinterface
- *****************************************************************************}
- procedure tgdbinterface.GetAddrSyminfo(addr:longint;var si:tsyminfo);
- var
- sym : symtab_and_line;
- symbol : psymbol;
- begin
- sym:=find_pc_line(addr,1);
- fillchar(si,sizeof(tsyminfo),0);
- si.address:=addr;
- si.offset:=addr-sym.pc;
- if assigned(sym.symtab) then
- si.fname:=sym.symtab^.filename
- else
- si.fname:=nil;
- si.line:=sym.line;
- symbol:=find_pc_function(addr);
- if assigned(symbol) then
- si.funcname:=symbol^.ginfo._name
- else
- si.funcname:=nil;
- end;
- procedure tgdbinterface.SelectSourceLine(fn:pchar;line:longint);
- begin
- if assigned(fn) then
- DoSelectSourceLine(StrPas(fn),line);
- end;
- procedure tgdbinterface.StartSession;
- begin
- DoStartSession;
- end;
- procedure tgdbinterface.BreakSession;
- begin
- DoBreakSession;
- end;
- procedure tgdbinterface.EndSession(code:longint);
- begin
- Debuggee_started:=false;
- {$ifdef Go32v2}
- inferior_pid:=0;
- {$endif}
- DoEndSession(code);
- end;
- procedure tgdbinterface.DebuggerScreen;
- begin
- {$ifdef Debug}
- Debug('|DebuggerScreen|');
- {$endif}
- if user_screen_shown then
- DoDebuggerScreen;
- user_screen_shown:=false;
- end;
- procedure tgdbinterface.UserScreen;
- begin
- {$ifdef Debug}
- Debug('|UserScreen|');
- {$endif}
- if switch_to_user then
- begin
- if (not user_screen_shown) then
- DoUserScreen;
- user_screen_shown:=true;
- end;
- end;
- {---------------------------------------
- Default Hooks
- ---------------------------------------}
- procedure tgdbinterface.DoSelectSourceLine(const fn:string;line:longint);
- {$ifdef Debug}
- var
- s : string;
- {$endif}
- begin
- {$ifdef Debug}
- Str(line,S);
- Debug('|SelectSource '+fn+':'+s+'|');
- {$endif}
- end;
- procedure tgdbinterface.DoStartSession;
- begin
- end;
- procedure tgdbinterface.DoBreakSession;
- begin
- end;
- procedure tgdbinterface.DoEndSession(code:longint);
- begin
- end;
- procedure tgdbinterface.DoDebuggerScreen;
- begin
- end;
- procedure tgdbinterface.DoUserScreen;
- begin
- end;
- function tgdbinterface.AllowQuit : boolean;
- begin
- AllowQuit:=true;
- end;
- var
- version : pchar;cvar;
- function GDBVersion : string;
- begin
- GDBVersion:='GDB '+StrPas(version);
- end;
- const next_exit : pointer = nil;
- procedure DoneLibGDB;
- begin
- exitproc:=next_exit;
- {$ifndef GDB_V416}
- if assigned(gdb_stdout) then
- dispose(gdb_stdout);
- gdb_stdout:=nil;
- if assigned(gdb_stderr) then
- dispose(gdb_stderr);
- gdb_stderr:=nil;
- {$endif not GDB_V416}
- end;
- {$ifndef GDB_V416}
- {$ifndef go32v2}
- {$ifndef win32}
- var
- stdout : p_c_file;cvar;external;
- stderr : p_c_file;cvar;external;
- {$endif win32}
- {$else go32v2}
- { the type is not really important
- for external cvars PM
- but the main problem is that stdout and stderr
- and defined as macros under DJGPP !! }
- var
- __dj_stdout : c_file;cvar;external;
- __dj_stderr : c_file;cvar;external;
- {$endif go32v2}
- {$endif not GDB_V416}
- procedure InitLibGDB;
- {$ifdef supportexceptions}
- var
- OldSigInt : SignalHandler;
- {$endif supportexceptions}
- begin
- {$ifdef supportexceptions}
- {$ifdef go32v2}
- OldSigInt:=Signal(SIGINT,SignalHandler(@SIG_DFL));
- {$else}
- OldSigInt:=Signal(SIGINT,SignalHandler(SIG_DFL));
- {$endif}
- {$endif supportexceptions}
- {$ifndef GDB_V416}
- new(gdb_stdout);
- gdb_stdout^.ts_streamtype := afile;
- {$ifndef go32v2}
- {$ifdef win32}
- gdb_stdout^.ts_filestream := _impure_ptr^.stdout;
- {$else not win32 }
- gdb_stdout^.ts_filestream := stdout;{p_c_file(textrec(output).handle); was wrong PM }
- {$endif not win32 }
- {$else go32v2}
- gdb_stdout^.ts_filestream := @__dj_stdout;
- {$endif go32v2}
- gdb_stdout^.ts_strbuf := nil;
- gdb_stdout^.ts_buflen := 0;
- new(gdb_stderr);
- gdb_stderr^.ts_streamtype := afile;
- {$ifndef go32v2}
- {$ifdef win32}
- gdb_stderr^.ts_filestream := _impure_ptr^.stderr;
- {$else not win32 }
- gdb_stderr^.ts_filestream := stderr;
- {$endif not win32 }
- {$else go32v2}
- gdb_stderr^.ts_filestream := @__dj_stderr;
- {$endif go32v2}
- gdb_stderr^.ts_strbuf := nil;
- gdb_stderr^.ts_buflen := 0;
- {$endif not GDB_V416}
- next_exit:=exitproc;
- exitproc:=@DoneLibGDB;
- gdb_init;
- {$ifdef supportexceptions}
- Signal(SIGINT,OldSigInt);
- {$endif supportexceptions}
- if setjmp(error_return)=0 then
- begin
- quit_return:=error_return;
- exit;
- end
- else
- begin
- {$ifdef Debug}
- Debug('|LongJump to Init|');
- {$endif}
- {$ifdef go32v2}
- RunError(99);
- {$endif def go32v2}
- end;
- WatchDog:=0;
- end;
- begin
- InitLibGDB;
- end.
- {
- $Log$
- Revision 1.4 2000-02-06 22:32:45 pierre
- + Get_current_frame and Set_current_frame
- Revision 1.3 2000/01/10 11:14:42 peter
- * fixed crash in getaddrsyminfo with symfync=nil
- Revision 1.2 1999/11/26 14:50:40 pierre
- * shell32 lib is not needed in gdbint unit
- Revision 1.1 1999/11/24 23:36:32 peter
- * moved to packages dir
- Revision 1.16 1999/11/09 22:58:08 pierre
- + symbol structure for function name
- Revision 1.15 1999/11/03 09:35:06 peter
- * linux updates
- Revision 1.14 1999/10/08 15:22:53 pierre
- * library order fixes
- + GDB 4.18 default now
- Revision 1.13 1999/10/04 21:26:05 pierre
- * Conditional stuff clarified
- Revision 1.12 1999/09/28 23:42:06 pierre
- + win32 support changes
- Revision 1.11 1999/09/07 09:17:52 pierre
- * frames better recorded
- * some v4.18 specific suff changed
- Revision 1.10 1999/08/31 16:16:14 pierre
- * setting height and width to unlimited was wrong
- Revision 1.9 1999/08/24 21:29:29 pierre
- + reload_fs after C code calling
- Revision 1.8 1999/08/23 09:17:22 pierre
- + Errors to gdberrorbuf
- Revision 1.7 1999/07/12 14:52:57 peter
- * ifdef 418 added
- Revision 1.6 1999/07/12 13:08:18 pierre
- + added GDBVersion function
- * tries to intercept quit command from GDB Window
- + AllowQuit method
- Revision 1.5 1999/07/11 00:16:29 pierre
- + stuff for v4.18 for DJGPP
- Revision 1.4 1999/07/07 13:12:59 peter
- * @sig_fdl for go32v2
- Revision 1.3 1999/07/05 13:05:49 michael
- + Fixed default handler
- Revision 1.2 1999/06/29 12:18:34 pierre
- * new procvar syntax fix
- Revision 1.1 1999/05/22 13:43:00 peter
- * moved
- Revision 1.16 1999/02/11 13:03:26 pierre
- Problem with last commit
- + added virtuals CommandBegin and CommandEnd
- + added command_level for TGDBInterface
- Revision 1.15 1999/02/10 09:00:41 pierre
- * duplicate call_reset removed
- * frames allocation and freeing corrected
- + GetError and GetOutput pchar function added
- + stop_breakpoint_number to know why the program stopped
- (used for watches)
- Revision 1.14 1999/02/08 17:35:08 pierre
- + added Run made TraceStep TraceNext Continue virtual
- Revision 1.13 1999/02/08 13:59:59 pierre
- - removed second debugger_started in TGDBController
- + StartTrace and Reset made virtual to be able to
- change CmResetDebugger state in IDE
- Revision 1.12 1999/02/08 11:37:11 pierre
- + added procargs var and SetArgs method
- Revision 1.11 1999/02/05 17:17:45 pierre
- * invalid_line renamed invalid_breakpoint_line
- Revision 1.10 1999/02/05 08:35:38 pierre
- * removed libgdb for cond USE_GDB_OBJS
- Revision 1.9 1999/02/04 16:33:35 pierre
- + gdb_file and use_gdb_file added for debug writing
- Revision 1.8 1999/02/04 14:35:00 pierre
- * small go32v2 fixes
- Revision 1.7 1999/02/03 15:57:38 pierre
- * typo error
- Revision 1.6 1999/02/03 15:03:07 pierre
- + added error_num function
- Revision 1.5 1999/02/03 15:01:00 pierre
- * a symtab_and_line record changes from v4.16 to v4.17
- Revision 1.4 1999/01/22 18:05:41 pierre
- * change dir sep from to / for dos
- Revision 1.3 1999/01/22 10:23:50 peter
- * small update to get it working with the IDE
- Revision 1.2 1999/01/18 11:00:34 pierre
- * frames was not initialized
- Revision 1.1 1998/10/07 15:57:38 peter
- * initial version
- Revision 1.1 1998/10/07 15:48:20 peter
- * initial version
- }
|