302 lines
6.8 KiB
C++
302 lines
6.8 KiB
C++
I64 HasLower(U8 *src)
|
|
{
|
|
I64 ch;
|
|
while (ch=*src++)
|
|
if ('a'<=ch<='z')
|
|
return TRUE;
|
|
return FALSE;
|
|
}
|
|
|
|
CHash *PSectFind(U8 *addr,I64 *_offset)
|
|
{//See $LK,"::/Kernel/KHashA.CPP",A="FL:::/Kernel/KHashA.CPP,1"$.
|
|
CHash *result=NULL;
|
|
CHashExport *tempex;
|
|
Bool has_lower=FALSE;
|
|
CHashTable *h=Fs->hash_table;
|
|
U64 i,j,best=0xFFFF;
|
|
if (!ChkCodePtr(addr)) {
|
|
*_offset=best;
|
|
return NULL;
|
|
}
|
|
while (h) {
|
|
for (i=0;i<=h->mask;i++) {
|
|
tempex=h->body[i];
|
|
while (tempex) {
|
|
j=0;
|
|
if (tempex->type&HTT_FUN) {
|
|
if (!Bt(&tempex(CHashFun *)->flags,Cf_EXTERN) &&
|
|
!Bt(&tempex(CHashFun *)->flags,Ff_INTERNAL))
|
|
j=tempex(CHashFun *)->executable_addr;
|
|
} else if (tempex->type&HTT_EXPORT_SYS_SYM)
|
|
j=tempex->val;
|
|
if (j) {
|
|
j=addr(I64)-j;
|
|
if (0<=j<=best) {
|
|
if (tempex->type&HTT_EXPORT_SYS_SYM) {
|
|
if (j<best || j==best && !has_lower) {
|
|
has_lower=HasLower(tempex->str);
|
|
best=j;
|
|
result=tempex;
|
|
}
|
|
} else if (tempex->type&HTT_FUN) {
|
|
if (j<best || j==best &&
|
|
(result && result->type&HTT_EXPORT_SYS_SYM||!has_lower)) {
|
|
has_lower=HasLower(tempex->str);
|
|
best=j;
|
|
result=tempex;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
tempex=tempex->next;
|
|
}
|
|
}
|
|
h=h->next;
|
|
}
|
|
*_offset=best;
|
|
return result;
|
|
}
|
|
|
|
U0 PSectCacheAdd(CHash *temps,U8 *addr)
|
|
{
|
|
I64 i;
|
|
CDbgInfo *dbg_info;
|
|
Bool old_preempt;
|
|
CPSectCache *temppc;
|
|
if (temps && temps->type&HTT_FUN &&
|
|
(dbg_info=temps(CHashFun *)->dbg_info)) {
|
|
old_preempt=Preempt(OFF);
|
|
lock {i=dbg.psect_cache_index++;}
|
|
temppc=&dbg.psect_cache[i&(PSECT_CACHE_SIZE-1)];
|
|
temppc->base=dbg_info->body[0];
|
|
if (addr<temppc->base)
|
|
temppc->base=addr;
|
|
temppc->limit=dbg_info->body[dbg_info->max_line+1-dbg_info->min_line];
|
|
if (addr>=temppc->limit)
|
|
temppc->limit=addr+1;
|
|
i=MinI64(StrLen(temps->str),PSECT_CACHE_STR_LEN-1);
|
|
MemCpy(temppc->str,temps->str,i);
|
|
temppc->str[i]=0;
|
|
temppc->time_stamp=tS;
|
|
Preempt(old_preempt);
|
|
}
|
|
}
|
|
|
|
U8 *PSectCacheFind(U8 *addr,I64 *_offset)
|
|
{
|
|
I64 i;
|
|
F64 timeout;
|
|
CPSectCache *temppc=dbg.psect_cache;
|
|
if (addr==SYS_IDLE_PT) {
|
|
*_offset=0;
|
|
return "SYS_IDLE_PT";
|
|
} else {
|
|
timeout=tS+8.0;
|
|
for (i=0;i<PSECT_CACHE_SIZE;i++,temppc++)
|
|
if (temppc->base<=addr<temppc->limit &&
|
|
temppc->time_stamp>timeout) {
|
|
*_offset=addr-temppc->base;
|
|
return temppc->str;
|
|
}
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
U0 StrPrintPSect(U8 *buf,I64 addr,I64 field_len)
|
|
{
|
|
I64 offset;
|
|
CHashExport *tempex;
|
|
U8 *str,*str2;
|
|
Bool is_fun=FALSE;
|
|
if (addr) {
|
|
if (str=PSectCacheFind(addr,&offset)) {
|
|
if (addr!=SYS_IDLE_PT)
|
|
is_fun=TRUE;
|
|
} else {
|
|
if (tempex=PSectFind(addr,&offset)) {
|
|
if (tempex->type&HTT_FUN)
|
|
is_fun=TRUE;
|
|
PSectCacheAdd(tempex,addr);
|
|
str=tempex->str;
|
|
}
|
|
}
|
|
if (str) {
|
|
if (offset>0xFFFF) offset=0xFFFF;
|
|
if (is_fun) {
|
|
str2=MStrPrint("&%s",str);
|
|
if (field_len>7)
|
|
StrPrint(buf,"%*ts+0x%04X",field_len-7,str2,offset);
|
|
else
|
|
StrPrint(buf,"%s+0x%04X",str2,offset);
|
|
Free(str2);
|
|
} else {
|
|
if (field_len>7)
|
|
StrPrint(buf,"%*ts+0x%04X",field_len-7,str,offset);
|
|
else
|
|
StrPrint(buf,"%s+0x%04X",str,offset);
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
if (field_len)
|
|
StrPrint(buf,"%*tX",field_len,addr);
|
|
else
|
|
StrPrint(buf,"%X",addr);
|
|
}
|
|
|
|
I64 SrcLineNum(U8 *addr,I64 cnt=1)
|
|
{//linenum for src of addr.
|
|
CHashSrcSym *temph;
|
|
I64 cur_line,first_line,last_line,num_lines,offset;
|
|
CDbgInfo *dbg_info;
|
|
U32 *body;
|
|
U8 *src,*src2;
|
|
if (temph=PSectFind(addr,&offset)) {
|
|
if (temph->type&(HTT_FUN|HTT_EXPORT_SYS_SYM)) {
|
|
if (dbg_info=temph->dbg_info) {
|
|
num_lines=dbg_info->max_line-dbg_info->min_line+1;
|
|
body=dbg_info->body;
|
|
|
|
//find first nonzero
|
|
first_line=0;
|
|
while (!body[first_line]) {
|
|
first_line++;
|
|
if (first_line>=num_lines)
|
|
return -1;
|
|
}
|
|
|
|
//find last nonzero
|
|
last_line=num_lines-1;
|
|
while (!body[last_line] && last_line>first_line)
|
|
last_line--;
|
|
|
|
//interpolate to guess line num
|
|
cur_line=ClampI64(ToF64(addr-body[first_line])*(last_line-first_line+1)/
|
|
(body[last_line]-body[first_line]+1),first_line,last_line);
|
|
|
|
//retreat while too high
|
|
while ((!body[cur_line] || body[cur_line]>=addr) && cur_line>first_line)
|
|
cur_line--;
|
|
|
|
//advance while to low
|
|
while ((!body[cur_line] || body[cur_line]<addr) && cur_line<last_line)
|
|
cur_line++;
|
|
|
|
if (addr<body[cur_line]+cnt)
|
|
return cur_line+dbg_info->min_line;
|
|
|
|
} else if (temph->src_link) {
|
|
src =StrNew(temph->src_link);
|
|
src2=StrNew(temph->src_link);
|
|
StrLastRem(src,",",src2);
|
|
cur_line=Str2I64(src2);
|
|
Free(src);
|
|
Free(src2);
|
|
return cur_line;
|
|
}
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
U8 *SrcFileName(U8 *addr,I64 cnt=1,CTask *mem_task=NULL)
|
|
{//MAlloc filename for src of addr.
|
|
CHashSrcSym *temph;
|
|
I64 i,j,ii,offset,best=NULL,d,best_d;
|
|
U32 *body;
|
|
CDbgInfo *dbg_info;
|
|
U8 *src;
|
|
if ((temph=PSectFind(addr,&offset)) &&
|
|
temph->type&(HTT_FUN|HTT_EXPORT_SYS_SYM)) {
|
|
if (dbg_info=temph->dbg_info) {
|
|
j=dbg_info->max_line-dbg_info->min_line+1;
|
|
body=dbg_info->body;
|
|
best_d=MAX_I64;
|
|
for (i=0;i<j;i++) {
|
|
if (0<body[i]<=addr<body[i]+cnt) {
|
|
ii=i+1;
|
|
while (!body[ii])
|
|
ii++;
|
|
if (addr<body[ii]) {
|
|
d=addr(I64)-body[i];
|
|
if (d<best_d) {
|
|
best_d=d;
|
|
best=temph->src_link;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} else
|
|
best=temph->src_link;
|
|
}
|
|
if (best) {
|
|
src=StrNew(best,mem_task);
|
|
StrFirstRem(src,":");
|
|
StrLastRem(src,",");
|
|
return src;
|
|
} else
|
|
return NULL;
|
|
}
|
|
|
|
U8 *SrcEdLink(U8 *addr,I64 cnt=1,CTask *mem_task=NULL)
|
|
{//MAlloc file,line link to src of addr.
|
|
U8 *filename,*st,*st2;
|
|
I64 linenum;
|
|
if (filename=SrcFileName(addr,cnt)) {
|
|
linenum=SrcLineNum(addr,cnt);
|
|
if (linenum<1)
|
|
linenum=1;
|
|
st2=MStrPrint("FL:%s,%d",filename,linenum);
|
|
Free(filename);
|
|
st=StrNew(st2,mem_task);
|
|
Free(st2);
|
|
return st;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
Bool PutSrcLink(U8 *addr,I64 cnt=1,U8 *buf=NULL)
|
|
{//Put to StdOut a $LK,"DolDoc",A="FI:::/Doc/DolDocOverview.TXT"$ file,line link to src of addr.
|
|
U8 *src;
|
|
if (src=SrcEdLink(addr,cnt)) {
|
|
if (buf)
|
|
StrPrint(buf,"$$LK,\"%p\",A=\"%s\"$$",addr,src);
|
|
else
|
|
"$$LK,\"%p\",A=\"%s\"$$",addr,src;
|
|
Free(src);
|
|
return TRUE;
|
|
} else if (buf)
|
|
*buf=0;
|
|
return FALSE;
|
|
}
|
|
|
|
Bool E(U8 *addr,I64 cnt=512,I64 edf_dof_flags=0)
|
|
{//Edit src at addr.
|
|
U8 *st;
|
|
Bool result=FALSE;
|
|
if (st=SrcEdLink(addr,cnt)) {
|
|
if (IsRaw)
|
|
result=EdLiteFileLine(st,edf_dof_flags);
|
|
else
|
|
result=Ed(st,edf_dof_flags);
|
|
Free(st);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
Bool Man(U8 *st,I64 edf_dof_flags=0)
|
|
{//Owner's manual for symbol. Edit src code for symbol.
|
|
Bool result=FALSE;
|
|
U8 **st2;
|
|
CHashSrcSym *temph;
|
|
if (IsRaw) {
|
|
if ((temph=HashFind(st,Fs->hash_table,HTG_SRC_SYM)) && temph->src_link)
|
|
result=EdLiteFileLine(temph->src_link,edf_dof_flags);
|
|
} else {
|
|
st2=MStrPrint("MN:%s",st);
|
|
result=Ed(st2,edf_dof_flags);
|
|
Free(st2);
|
|
}
|
|
return result;
|
|
}
|