view src/codeview/debuginfo.d @ 1:4a9dcbd9e54f

-files of 0.13 beta -fixes so that it now compiles with the current dmd version
author marton@basel.hu
date Tue, 05 Apr 2011 20:44:01 +0200
parents
children
line wrap: on
line source

/*  Ddbg - Win32 Debugger for the D programming language
 *  Copyright (c) 2007 Jascha Wetzel
 *  All rights reserved. See LICENSE.TXT for details.
 */

module codeview.debuginfo;

import container;
import util;
import codeview.coff;
import codeview.codeview;

import std.string;

class SourceModule
{
    SourceFile[]        files;
}

class SourceFile
{
    SourceModule        source_module;
    string              name;
    SourceSegment[]     segments;
    CodeBlock[][uint]   blocks_by_line;
    uint[]              lines;
}

class SourceSegment
{
    SourceFile  file;
    size_t      start,
                end;
}

class CodeBlock
{
    size_t          start,
                    end;
    uint            line;
    SourceSegment   segment;

    this(size_t s, uint l, SourceSegment seg)
    {
        start = s;
        line = l;
        segment = seg;
    }

    /**********************************************************************************************
        Check if block contains offset
    **********************************************************************************************/
    int opCmp(size_t offset)
    {
        if ( start > offset )
            return 1;
        if ( end <= offset )
            return -1;
        return 0;
    }

    /**********************************************************************************************
        Compare by start address.
    **********************************************************************************************/
    int opCmp(ref CodeBlock cb)
    {
        if ( start > cb.start )
            return 1;
        if ( start < cb.start )
            return -1;
        return 0;
    }

    string toString()
    {
        return format("%s:%d 0x%x-0x%x in 0x%x-0x%x", segment.file.name, line, start, end, segment.start, segment.end);
    }
}

/**************************************************************************************************

**************************************************************************************************/
abstract class DebugInfo
{
    SourceModule[]      source_modules;
    AVLTree!(CodeBlock) codeblocks; /// contains all blocks from all modules

    this()
    {
        codeblocks = new AVLTree!(CodeBlock);
    }

    size_t getCodeBase();
    
    void updateCodeblocks()
    {
        bool findEnd(AVLNode!(CodeBlock) n)
        {
            AVLNode!(CodeBlock) n2;
            if ( n.findNext(n2) && (n2.value.segment is n.value.segment || n.value.segment.end == n.value.start) )
                n.value.end = n2.value.start;
            else
                n.value.end = n.value.segment.end;
            return true;
        }
        codeblocks.traverseDepthLeft(&findEnd);
    }

	/**********************************************************************************************

    **********************************************************************************************/
    CodeBlock findCodeBlockRel(uint address)
    {
        CodeBlock cb;
        if ( !codeblocks.find(address, cb) )
            return null;
        return cb;
    }

    CodeBlock findCodeBlockAbs(uint address)
    {
        CodeBlock cb;
        if ( !codeblocks.find(address-getCodeBase, cb) )
            return null;
        return cb;
    }

	/**********************************************************************************************
        Find the source files that correspond to the given filepath.
        That path can be relative to one of the search_paths.
    **********************************************************************************************/
	SourceFile[] findSrcFiles(string filepath, string[] search_paths)
	{
		string fullpath = getFullPath(filepath);
		if ( fullpath is null )
			return null;

        SourceFile[] sfs;
        foreach ( sm; source_modules )
        {
            foreach ( sf; sm.files )
            {
                foreach ( sp; search_paths )
                {
                    string path = getFullPath(sp~sf.name);
                    if ( path !is null && icmp(path, fullpath) == 0 )
                        sfs ~= sf;
                }
            }
        }

		return sfs;
	}

	/**********************************************************************************************
        Find source files that contain the given substring in it's path.
    **********************************************************************************************/
	SourceFile[] findSrcFiles(string filename_substring)
	{
        SourceFile[] sfs;
        foreach ( sm; source_modules )
        {
            foreach ( sf; sm.files )
            {
                if ( find(sf.name, filename_substring) >= 0 )
                    sfs ~= sf;
            }
        }
		return sfs;
	}
}

/**************************************************************************************************

**************************************************************************************************/
class ImageSet
{
	COFFImage[] images;
    
    void opCatAssign(COFFImage image)
    {
        images ~= image;
    }

    void remove(COFFImage image)
    {
        foreach ( i, img; images )
        {
            if ( img is image )
            {
                images = images[0..i]~images[i+1..$];
                break;
            }
        }
    }
    
	Location findLocation(uint vaddress)
    {
        foreach ( img; images )
        {
            if ( img.codeView !is null )
            {
                auto loc = img.codeView.findLocation(vaddress);
                if ( loc !is null )
                    return loc;
            }
        }
        return null;
    }

    CodeBlock findCodeBlockAbs(uint address, out CodeView cv)
    {
        foreach ( img; images )
        {
            if ( img.codeView !is null )
            {
                auto cb = img.codeView.findCodeBlockAbs(address);
                if ( cb !is null ) {
                    cv = img.codeView;
                    return cb;
                }
            }
        }
        return null;
    }

    CodeBlock findCodeBlockRel(uint address, out CodeView cv)
    {
        foreach ( img; images )
        {
            if ( img.codeView !is null )
            {
                auto cb = img.codeView.findCodeBlockRel(address);
                if ( cb !is null ) {
                    cv = img.codeView;
                    return cb;
                }
            }
        }
        return null;
    }

	Module findModule(uint vaddress, out uint segment)
    {
        foreach ( img; images )
        {
            if ( img.codeView !is null )
            {
                auto mod = img.codeView.findModule(vaddress, segment);
                if ( mod !is null )
                    return mod;
            }
        }
        return null;
    }

	string mangleCVtype(ushort cvtype)
    {
        foreach ( img; images )
        {
            if ( img.codeView !is null )
            {
                auto t = img.codeView.mangleCVtype(cvtype);
                if ( t !is null )
                    return t;
            }
        }
        return null;
    }

	SourceFile[] findSrcFiles(string filename_substring)
    {
        foreach ( img; images )
        {
            if ( img.codeView !is null )
            {
                auto t = img.codeView.findSrcFiles(filename_substring);
                if ( t !is null )
                    return t;
            }
        }
        return null;
    }

  	SourceFile[] findSrcFiles(string filepath, string[] search_paths)
    {
        foreach ( img; images )
        {
            if ( img.codeView !is null )
            {
                auto t = img.codeView.findSrcFiles(filepath, search_paths);
                if ( t !is null )
                    return t;
            }
        }
        return null;
    }

	Location findSrcLine(SourceFile sf, uint min_line, size_t min_start=0)
    {
        foreach ( img; images )
        {
            if ( img.codeView !is null )
            {
                auto t = img.codeView.findSrcLine(sf, min_line, min_start);
                if ( t !is null )
                    return t;
            }
        }
        return null;
    }

	Location findNextSrcLine(Location loc)
    {
        foreach ( img; images )
        {
            if ( img.codeView !is null )
            {
                auto t = img.codeView.findNextSrcLine(loc);
                if ( t !is null )
                    return t;
            }
        }
        return null;
    }

	Location findPrevSrcLine(Location loc)
    {
        foreach ( img; images )
        {
            if ( img.codeView !is null )
            {
                auto t = img.codeView.findPrevSrcLine(loc);
                if ( t !is null )
                    return t;
            }
        }
        return null;
    }

	ProcedureSymbol findProcedureSymbol(uint vaddress)
    {
        foreach ( img; images )
        {
            if ( img.codeView !is null )
            {
                auto t = img.codeView.findProcedureSymbol(vaddress);
                if ( t !is null )
                    return t;
            }
        }
        return null;
    }
}