////////////////////////////////////////////////////////////////////// // // // jdevDwarfDebugger.pas: DWARF tree viewer // // Displays the hierarchy of a DWARF segment // // // // The contents of this file are subject to the Bottled Light // // Public License Version 1.0 (the "License"); you may not use this // // file except in compliance with the License. You may obtain a // // copy of the License at http://www.bottledlight.com/BLPL/ // // // // Software distributed under the License is distributed on an // // "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or // // implied. See the License for the specific language governing // // rights and limitations under the License. // // // // The Original Code is the Mappy VM User Interface, released // // April 1st, 2003. The Initial Developer of the Original Code is // // Bottled Light, Inc. Portions created by Bottled Light, Inc. are // // Copyright (C) 2001-2003 Bottled Light, Inc. All Rights Reserved. // // // // Author(s): // // Michael Noland (joat), michael@bottledlight.com // // // // Changelog: // // 1.0: First public release (April 1st, 2003) // // // // Notes: // // This has never been in a release version of MVM and its only // // useful for quick debugging tasks, its not very robust. // // // ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// unit jdevDwarfDebugger; ////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// interface //////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, ComCtrls, dwarfUtils, ExtCtrls, StdCtrls, nexus; ////////////////////////////////////////////////////////////////////// type TjdevDwarfDebug = class(TForm) tree: TTreeView; procedure FormShow(Sender: TObject); procedure Timer1Timer(Sender: TObject); procedure Button1KeyUp(Sender: TObject; var Key: Word; Shift: TShiftState); procedure FormHide(Sender: TObject); procedure treeClick(Sender: TObject); private { Private declarations } doneola: boolean; public { Public declarations } procedure PrintNode(node: PDwarfNode; dnode: TTreeNode); procedure PrintAttributes(node: PDwarfNode; dnode: TTreeNode); end; ////////////////////////////////////////////////////////////////////// var jdevDwarfDebug: TjdevDwarfDebug; ////////////////////////////////////////////////////////////////////// implementation /////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// {$R *.DFM} ////////////////////////////////////////////////////////////////////// procedure TjdevDwarfDebug.PrintNode(node: PDwarfNode; dnode: TTreeNode); var temp: TTreeNode; begin while node <> nil do begin if doneola then Exit; // if node^.tag = DW_TAG_variable then begin temp := tree.Items.AddChild(dnode, DwarfTagToString(node^.tag)); PrintAttributes(node, temp); // end else temp := dnode; if node.hasChildren then PrintNode(node^.kids, temp); node := node^.next; if Random(256) = 0 then Application.ProcessMessages; end; end; ////////////////////////////////////////////////////////////////////// procedure TjdevDwarfDebug.FormShow(Sender: TObject); var i: integer; begin if dwarf = nil then Exit; tree.Items.BeginUpdate; for i := 0 to dwarf.CompUnits.Count - 1 do begin PrintNode(TCompilationUnit(dwarf.CompUnits.Items[i]).rootNode, nil); end; tree.Items.EndUpdate; end; ////////////////////////////////////////////////////////////////////// procedure TjdevDwarfDebug.PrintAttributes(node: PDwarfNode; dnode: TTreeNode); var attrib: PDwarfAttribute; st: string; begin attrib := node^.attribs; while attrib <> nil do begin case attrib^.format of DW_FORM_addr: st := 'address $' + IntToHex(attrib^.address, 8); DW_FORM_block, DW_FORM_block1, DW_FORM_block2, DW_FORM_block4: st := 'block of size ' + IntToStr(attrib^.block.size); DW_FORM_sdata, DW_FORM_udata, DW_FORM_data1, DW_FORM_data2, DW_FORM_data4, DW_FORM_data8: st := 'data $' + IntToHex(attrib^.data, 8); DW_FORM_string, DW_FORM_strp: st := attrib^.st; DW_FORM_flag: if attrib^.flag then st := 'TRUE' else st := 'FALSE'; DW_FORM_ref_addr: st := 'offset FINDME $' + IntToHex(attrib^.offset, 8); DW_FORM_ref_udata, DW_FORM_ref1, DW_FORM_ref2, DW_FORM_ref4, DW_FORM_ref8: st := 'offset $' + IntToHex(attrib^.offset, 8); end; tree.Items.AddChild(dnode, Format('%-30s', [DwarfAttributeToString(attrib^.name)]) + ' ' + st); attrib := attrib^.next; end; end; ////////////////////////////////////////////////////////////////////// procedure TjdevDwarfDebug.Timer1Timer(Sender: TObject); begin doneola := true; end; ////////////////////////////////////////////////////////////////////// procedure TjdevDwarfDebug.Button1KeyUp(Sender: TObject; var Key: Word; Shift: TShiftState); begin doneola := true; end; ////////////////////////////////////////////////////////////////////// procedure TjdevDwarfDebug.FormHide(Sender: TObject); begin doneola := true; end; ////////////////////////////////////////////////////////////////////// procedure TjdevDwarfDebug.treeClick(Sender: TObject); begin doneola := true; end; ////////////////////////////////////////////////////////////////////// end. //////////////////////////////////////////////////////////////////////