mdebug.c 4.47 KB
/*==============================================================================
    mdebug.c
    $Revision: 1.1.1.2 $
    $Date: 2002/10/29 08:07:15 $
    $Author: blythe $
    $Source: /root/leakn64/depot/rf/sw/n64os20l/tools/gcord/com/mdebug.c,v $

    mdebug related procedures.
==============================================================================*/
#include <stdio.h>
#include <filehdr.h>
#include <sym.h>
#include <stsupport.h>
#include <ldfcn.h>

#include "global.h"
#include "option.h"
#include "update.h"
#include "mdebug.h"

/*------------------------------------------------------------------------------
  mdebug_interface:
  - read the MDEBUG symbol table.
  - fill in the proc internal table.
------------------------------------------------------------------------------*/
void mdebug_interface(void)
{
    int f;
    LDFILE *ldptr;
    pCHDRR st;
    pFDR pfd;
    pPDR ppd;

    Proc *proc;

    if ( option.debug )
            printf( "mdebug_interface\n" );

    /*------------------
      open binary
    ------------------*/
    ldptr = (LDFILE *) ldopen(option.in_file, NULL);
    ASSERT(ldptr);

    st = PSYMTAB(ldptr);
    ASSERT(st);
    ldreadst(ldptr, ST_PPDS|ST_PFDS|ST_PLINES);
    pfd = st->pfd;
    ppd = st->ppd;

    bin.libstub = proc = new_proc();
    proc->begin = bin.text_lo;
    proc->file_name = ".libstub";
    proc->name = ".libstub";

    /*------------------
      loop thru the files
    ------------------*/
    for (f = 0; f < st->hdr.ifdMax; f++) 
    {
    	int 	p, first_p, last_p;
	static  last_ipd = 0;		/* the last ipd (low 16 bits) */
	static  ipdFirstMSBits = 0;	/* current MSB (shifted <<16) */
    	SYMR 	sym;
	Uint32 file_lowpc = 0;
	char	*file_name;

		/* first proc in this file */
	first_p = BIG_PROCEDURE_IPDFIRST(pfd+f);

		/* handles the 16 bit ipd overflow when -B not set */
	if (option.big_procedure_list == FALSE)
	{
	    if(BIG_PROCEDURE_CPD(pfd+f) && (last_ipd > first_p) 
		&& pfd[f].ipdFirstMSBits == 0)
	    {
		ipdFirstMSBits += 0x10000;
	    }
	    last_ipd = first_p;
	    first_p  += ipdFirstMSBits;
	}

		/* last proc in this file */
	last_p = first_p + BIG_PROCEDURE_CPD(pfd+f);

    	/*------------------
    	  get file name
    	------------------*/
	file_name = pfd[f].rss + pfd[f].issBase + st->pss;
	if (!file_name) {
	    file_name = "noname_file";
	    error("Stripped binary? File[%d] has no name", f);
	}else{
	    file_name = strdup(file_name);
	}
    	
    	/*------------------
    	  loop thru procedures
    	------------------*/
    	for (p = first_p; p < last_p; p++) 
	{
	    pAUXU great;

    	    /* Check for alternative entry point.  Skip them. */
    	    if (ppd[p].lnLow > 0 && ppd[p].lnHigh == -1)
	    {
    		continue;
    	    }


    	    if ((ppd[p].isym != isymNil) && pfd[f].csym > 0 
    		&& (ldtbread(ldptr, pfd[f].isymBase + ppd[p].isym, &sym) 
			!= FAILURE)) 
	    {

    		char *name = ldgetname(ldptr, &sym);

    		if (!name) 
    		    error("stripped binary");
    		proc = new_proc();
		proc->file_name = file_name;
    		proc->name = name;
    		proc->begin = sym.value;
		if ( sym.index ) {
		    great = ldgetaux( ldptr, sym.index );
		    ldtbread( ldptr, pfd[f].isymBase + great->isym - 1, &sym );
		    proc->size = sym.value;
		}


				/*------------------
				  determine the lowest pc for the file
				------------------*/
				if (!file_lowpc || proc->begin < file_lowpc) {
					file_lowpc = proc->begin;
				}

    	    }
	    else
	    {
    		error("stripped binary");
    	    }

    	    if (option.debug & DEBUG_DEBUG)
	    {
    	        dump("\tSubprogram: %s lowpc(%#llx)", 
    		    proc->name, (Uint64) proc->begin);
    	    }

    	}

	/*------------------
	  update the file structure
	------------------*/
	if (!file_lowpc) {
	    file_lowpc = pfd[f].adr;
	}
    }
#if 0	/* TO_DO: resolve strdup core dump and add this back */
    ldclose(ldptr);
#endif

#if 0           /* We have done this the "better" way - looking in the end_proc
sym */
        mdebug_derive_proc_highpc();
#endif

}

/*------------------------------------------------------------------------------
    move mdebug by offset in elf.
------------------------------------------------------------------------------*/
void move_mdebug(void* mdebug, Uint32 len, Uint32 file_offset)
{
    pHDRR     phdr;

    phdr = (pHDRR) mdebug;
    ASSERT( len >= sizeof(HDRR));
    ASSERT( phdr->magic == magicSym);
    
#if 0
    phdr->cbLineOffset
    phdr->cbLine
    if (phdr->ilineMax > 0)
    {
	phdr->cbLineOffset += bin.text_expand_offset;
    }
#endif
}