Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

253 lines
7.9 KiB

/*
* Module: procedure.d
* Author: Mark I. Himelstein, Himelsoft, Inc.
* Purpose: returns values for procedure queries on MIPS COFF symbol table
*/
#include "conv.h"
static pSYMR save_psymend; /* stBlock fetch save ptr to stEnd */
eval_f get_compiler_version;
#define GET_PROC_FIELD(routine_suffix, field_name, const) \
extern data \
get_procedure_##routine_suffix( \
arg_s *parg, /* arg entry causing call */ \
callinfo_s *pinfo, /* info we need to pass around */ \
long *plength) /* for varying length fields */ \
{ \
/* return field for procedure contain symbol we are up \
* to. \
*/ \
\
parg; \
plength; \
\
if (pinfo->ppdr == 0) { \
fatal("tried to retrieve proc field without active procedure\n"); \
} /* if */ \
\
return (data)(pinfo->ppdr->field_name + const); \
} /* GET_PROC_FIELD */
extern data
get_arg_count(
arg_s *parg, /* arg entry causing call */
callinfo_s *pinfo, /* info we need to pass around */
long *plength) /* for varying length fields */
{
/* only for typedefs, function variables, etc. */
parg;
plength;
if (pinfo->psym[-1].st == stProto) {
return pinfo->psym[-1].iss; /* where we stashed arglist count */
} /* if */
return 0;
} /* get_proto_list */
extern data
get_proto_list(
arg_s *parg, /* arg entry causing call */
callinfo_s *pinfo, /* info we need to pass around */
long *plength) /* for varying length fields */
{
unsigned short type_index;
SYMR sym;
/* only for typedefs, function variables, etc. */
parg;
plength;
if (pinfo->psym[-1].st == stProto) {
return pinfo->psym[-1].value; /* where we stashed arglist typeindex */
} /* if */
/* empty list so create one, save&restore sym since list_end modifies it */
sym = *pinfo->psym;
type_index = list_start(parg, pinfo, plength);
list_end(parg, pinfo, plength);
*pinfo->psym = sym;
return type_index;
} /* get_proto_list */
extern data
get_procedure_length(
arg_s *parg, /* arg entry causing call */
callinfo_s *pinfo, /* info we need to pass around */
long *plength) /* for varying length fields */
{
/* return frame register for procedure contain symbol we are up
* to.
*/
pSYMR psymend; /* pointer to end of symbols for procedure */
parg;
plength;
if (pinfo->psym->st != stProc && pinfo->psym->st != stStaticProc) {
fatal("tried to retrieve procedure length for non-proc symbol\n");
} /* if */
if (pinfo->psym->index == indexNil ||
pinfo->pfdr->caux < (long)pinfo->psym->index) {
fatal("tried to retrieve proc length from damaged symbol table\n");
} /* if */
/* get index to end symbol and turn it into a pointer */
psymend = isym_to_psym(pinfo, iaux_to_isym(pinfo, pinfo->psym->index)-1);
return (data)(psymend->value);
} /* get_procedure_length */
extern data
get_procedure_debug_start(
arg_s *parg, /* arg entry causing call */
callinfo_s *pinfo, /* info we need to pass around */
long *plength) /* for varying length fields */
{
/* return offset to first nonprologue byte.
*/
pSYMR psymstop; /* end of procedure stop looking for stBlock */
pSYMR psymend; /* end of block symbol */
pSYMR psym; /* copy of pinfo->psym we can increment */
parg;
plength;
if (save_psymend != 0) {
fatal("tried to get debug start before we cleared last proc\n");
} /* if */
if (pinfo->psym->st != stProc && pinfo->psym->st != stStaticProc) {
fatal("tried to retrieve procedure length for non-proc symbol\n");
} /* if */
if (pinfo->psym->index == indexNil ||
pinfo->pfdr->caux < (long)pinfo->psym->index) {
fatal("tried to retrieve proc length from damaged symbol table\n");
} /* if */
/* get index to end of procedure symbol and turn it into a pointer */
psymstop = isym_to_psym(pinfo, iaux_to_isym(pinfo, pinfo->psym->index)-1);
psym = pinfo->psym;
do {
psym++;
if (psym->st == stProc || psym->st == stStaticProc) {
fatal("unexpected nested procedure\n");
} /* if */
if (psym->st == stBlock) {
/* get pointer to end symbol, if it is not a text block,
* use the end symbol to skip over it.
*/
if (psym->index == indexNil || psym->index == 0) {
fatal("tried to get endsym for inappropriate symbol\n");
} /* if */
psymend = isym_to_psym(pinfo, psym->index - 1);
if (psym->sc != scText) {
/* other type of block like struct definition */
psym = psymend;
continue;
} /* if */
/* got it */
break;
} /* if */
} while (psym < psymstop);
if (psym >= psymstop) {
/* none found, emit warning & return 0 */
warning("returning 0 because we can't find initial stBlock\n");
save_psymend = 0; /* optimization for debug end */
return 0;
} /* if */
save_psymend = psymend; /* optimization for debug end */
/* set st values so we'll ignore this as a block later */
psym->st = stEndParam; /* we still need to emit this symbol */
psymend->st = stIgnore; /* no need to look at this one at all */
return psym->value;
} /* get_procedure_debug_start */
extern data
get_procedure_args(
arg_s *parg, /* arg entry causing call */
callinfo_s *pinfo, /* info we need to pass around */
long *plength) /* for varying length fields */
{
data value;
/* debug did all of my work for me */
parg;
plength;
if (save_psymend == 0) {
return 0;
} /* if */
value = save_psymend->value + pinfo->ppdr->adr;
save_psymend = 0;
generate_relocation(buffer_total(symbol_buf), pinfo->psym->st,
pinfo->psym->sc, value, pinfo->index);
return value;
} /* get_procedure_debug_end */
extern data
get_procedure_debug_end(
arg_s *parg, /* arg entry causing call */
callinfo_s *pinfo, /* info we need to pass around */
long *plength) /* for varying length fields */
{
data value;
/* debug did all of my work for me */
parg;
plength;
if (save_psymend == 0) {
return 0;
} /* if */
value = save_psymend->value;
save_psymend = 0;
return value;
} /* get_procedure_debug_end */
GET_PROC_FIELD(framereg, framereg, 10)
GET_PROC_FIELD(returnreg, pcreg, 10)
GET_PROC_FIELD(saved_regs_mask, regmask, 0)
GET_PROC_FIELD(saved_fpregs_mask, fregmask, 0)
GET_PROC_FIELD(saved_regs_offset, regoffset, 0)
GET_PROC_FIELD(saved_fpregs_offset, fregoffset, 0)
GET_PROC_FIELD(frame_size, frameoffset, 0)