hschumann2/TempleOS-Source-Code
0838
1 2I64 HasLower(U8 *src)3{4 I64 ch;5 while (ch=*src++)6 if ('a'<=ch<='z')7 return TRUE;8 return FALSE;9}10 11U0 HashFunSegFind(CHashTable *h,U8 *addr,12 Bool *_has_lower,U64 *_best,CHash **_res)13{14 Bool *has_lower=*_has_lower;15 CHashExport *tmpex;16 U64 i,j,best=*_best;17 CHash *res=*_res;18 for (i=0;i<=h->mask;i++) {19 tmpex=h->body[i];20 while (tmpex) {21 j=0;22 if (tmpex->type&HTT_FUN) {23 if (!Bt(&tmpex(CHashFun *)->flags,Cf_EXTERN) &&24 !Bt(&tmpex(CHashFun *)->flags,Ff_INTERNAL))25 j=tmpex(CHashFun *)->exe_addr;26 } else if (tmpex->type&HTT_EXPORT_SYS_SYM)27 j=tmpex->val;28 if (j) {29 j=addr(I64)-j;30 if (0<=j<=best) {31 if (tmpex->type&HTT_EXPORT_SYS_SYM) {32 if (j<best || j==best && !has_lower) {33 has_lower=HasLower(tmpex->str);34 best=j;35 res=tmpex;36 }37 } else if (tmpex->type&HTT_FUN) {38 if (j<best || j==best &&39 (res && res->type&HTT_EXPORT_SYS_SYM||!has_lower)) {40 has_lower=HasLower(tmpex->str);41 best=j;42 res=tmpex;43 }44 }45 }46 }47 tmpex=tmpex->next;48 }49 }50 *_has_lower=has_lower;51 *_best=best;52 *_res =res;53}54 55CHash *FunSegFind(U8 *addr,I64 *_offset)56{//See Hash.57 CHash *res=NULL;58 Bool has_lower=FALSE;59 CTask *task;60 CHashTable *h;61 CCPU *c;62 U64 i,best=0xFFFF;63 if (!ChkCodePtr(addr)) {64 *_offset=best;65 return NULL;66 }67 if (IsDbgMode)68 for (i=0;i<mp_cnt;i++) {69 c=&cpu_structs[i];70 task=c->seth_task;71 do {72 if (!TaskValidate(task)) goto fs_abort_task;73 h=task->hash_table;74 while (h) {75 HashFunSegFind(h,addr,&has_lower,&best,&res);76 h=h->next;77 }78 task=task->next_task;79 } while (task!=c->seth_task);80fs_abort_task:81 }82 else {83 h=Fs->hash_table;84 while (h) {85 HashFunSegFind(h,addr,&has_lower,&best,&res);86 h=h->next;87 }88 }89 *_offset=best;90 return res;91}92 93U0 FunSegCacheAdd(CHash *tmps,U8 *addr)94{95 I64 i;96 CDbgInfo *dbg_info;97 CFunSegCache *tmpfsc;98 if (tmps && tmps->type&HTT_FUN &&99 (dbg_info=tmps(CHashFun *)->dbg_info)) {100 lock i=dbg.fun_seg_cache_index++;101 tmpfsc=&dbg.fun_seg_cache[i&(FUN_SEG_CACHE_SIZE-1)];102 tmpfsc->base=dbg_info->body[0];103 if (addr<tmpfsc->base)104 tmpfsc->base=addr;105 tmpfsc->limit=dbg_info->body[dbg_info->max_line+1-dbg_info->min_line];106 if (addr>=tmpfsc->limit)107 tmpfsc->limit=addr+1;108 i=MinI64(StrLen(tmps->str),FUN_SEG_CACHE_STR_LEN-1);109 MemCpy(tmpfsc->str,tmps->str,i);110 tmpfsc->str[i]=0;111 tmpfsc->time_stamp=tS;112 }113}114 115U8 *FunSegCacheFind(U8 *addr,I64 *_offset)116{117 I64 i;118 F64 timeout;119 CFunSegCache *tmpfsc=dbg.fun_seg_cache;120 if (addr==SYS_IDLE_PT) {121 *_offset=0;122 return "SYS_IDLE_PT";123 } else {124 timeout=tS+8.0;125 for (i=0;i<FUN_SEG_CACHE_SIZE;i++,tmpfsc++)126 if (tmpfsc->base<=addr<tmpfsc->limit &&127 tmpfsc->time_stamp>timeout) {128 *_offset=addr-tmpfsc->base;129 return tmpfsc->str;130 }131 return NULL;132 }133}134 135U0 StrPrintFunSeg(U8 *buf,I64 addr,I64 field_len,I64 flags)136{137 I64 offset;138 CHashExport *tmpex;139 U8 *str,*str2;140 Bool is_fun=FALSE;141 if (!(flags&PRTF_TRUNCATE))142 field_len=0;143 if (addr) {144 if (str=FunSegCacheFind(addr,&offset)) {145 if (addr!=SYS_IDLE_PT)146 is_fun=TRUE;147 } else {148 if (tmpex=FunSegFind(addr,&offset)) {149 if (tmpex->type&HTT_FUN)150 is_fun=TRUE;151 FunSegCacheAdd(tmpex,addr);152 str=tmpex->str;153 }154 }155 if (str) {156 if (offset>0xFFFF) offset=0xFFFF;157 if (flags&PRTF_COMMA) {158 if (is_fun) {159 str2=MStrPrint("&%s",str);160 if (!field_len)161 StrCpy(buf,str2);162 else if (flags&PRTF_LEFT_JUSTIFY && StrLen(str2)<field_len)163 StrCpy(buf,str2);164 else165 StrPrint(buf,"%*ts",field_len,str2);166 Free(str2);167 } else {168 if (!field_len)169 StrCpy(buf,str);170 else if (flags&PRTF_LEFT_JUSTIFY && StrLen(str)<field_len)171 StrCpy(buf,str);172 else173 StrPrint(buf,"%*ts",field_len,str);174 }175 } else {176 if (is_fun) {177 str2=MStrPrint("&%s",str);178 if (field_len && field_len>7) {179 if (flags&PRTF_LEFT_JUSTIFY && StrLen(str2)<field_len-7)180 StrPrint(buf,"%s+0x%04X",str2,offset);181 else182 StrPrint(buf,"%*ts+0x%04X",field_len-7,str2,offset);183 } else184 StrPrint(buf,"%s+0x%04X",str2,offset);185 Free(str2);186 } else {187 if (field_len && field_len>7) {188 if (flags&PRTF_LEFT_JUSTIFY && StrLen(str)<field_len-7)189 StrPrint(buf,"%s+0x%04X",str,offset);190 else191 StrPrint(buf,"%*ts+0x%04X",field_len-7,str,offset);192 } else193 StrPrint(buf,"%s+0x%04X",str,offset);194 }195 }196 return;197 }198 }199 if (flags&PRTF_COMMA)200 StrCpy(buf,".");201 else if (flags&PRTF_TRUNCATE && field_len)202 StrPrint(buf,"%*tX",field_len,addr);203 else204 StrPrint(buf,"%X",addr);205}206 207I64 SrcLineNum(U8 *addr,I64 cnt=1)208{//linenum for src of addr.209 CHashSrcSym *tmph;210 I64 cur_line,first_line,last_line,num_lines,offset;211 CDbgInfo *dbg_info;212 U32 *body;213 U8 *src,*src2;214 if (tmph=FunSegFind(addr,&offset)) {215 if (tmph->type&(HTT_FUN|HTT_EXPORT_SYS_SYM)) {216 if (dbg_info=tmph->dbg_info) {217 num_lines=dbg_info->max_line-dbg_info->min_line+1;218 body=dbg_info->body;219 220 //find first nonzero221 first_line=0;222 while (!body[first_line]) {223 first_line++;224 if (first_line>=num_lines)225 return -1;226 }227 228 //find last nonzero229 last_line=num_lines-1;230 while (!body[last_line] && last_line>first_line)231 last_line--;232 233 //interpolate to guess line num234 cur_line=ClampI64(ToF64(addr-body[first_line])*(last_line-first_line+1)/235 (body[last_line]-body[first_line]+1),first_line,last_line);236 237 //retreat while too high238 while ((!body[cur_line] || body[cur_line]>=addr) && cur_line>first_line)239 cur_line--;240 241 //advance while to low242 while ((!body[cur_line] || body[cur_line]<addr) && cur_line<last_line)243 cur_line++;244 245 if (addr<body[cur_line]+cnt)246 return cur_line+dbg_info->min_line;247 248 } else if (tmph->src_link) {249 src =StrNew(tmph->src_link);250 src2=StrNew(tmph->src_link);251 StrLastRem(src,",",src2);252 cur_line=Str2I64(src2);253 Free(src);254 Free(src2);255 return cur_line;256 }257 }258 }259 return -1;260}261 262U8 *SrcFileName(U8 *addr,I64 cnt=1,CTask *mem_task=NULL)263{//MAlloc filename for src of addr.264 CHashSrcSym *tmph;265 I64 i,j,ii,offset,best=NULL,d,best_d;266 U32 *body;267 CDbgInfo *dbg_info;268 U8 *src;269 if ((tmph=FunSegFind(addr,&offset)) &&270 tmph->type&(HTT_FUN|HTT_EXPORT_SYS_SYM)) {271 if (dbg_info=tmph->dbg_info) {272 j=dbg_info->max_line-dbg_info->min_line+1;273 body=dbg_info->body;274 best_d=I64_MAX;275 for (i=0;i<j;i++) {276 if (0<body[i]<=addr<body[i]+cnt) {277 ii=i+1;278 while (!body[ii])279 ii++;280 if (addr<body[ii]) {281 d=addr(I64)-body[i];282 if (d<best_d) {283 best_d=d;284 best=tmph->src_link;285 }286 }287 }288 }289 } else290 best=tmph->src_link;291 }292 if (best) {293 src=StrNew(best,mem_task);294 StrFirstRem(src,":");295 StrLastRem(src,",");296 return src;297 } else298 return NULL;299}300 301U8 *SrcEdLink(U8 *addr,I64 cnt=1,CTask *mem_task=NULL)302{//MAlloc file,line link to src of addr.303 U8 *filename,*st,*st2;304 I64 linenum;305 if (filename=SrcFileName(addr,cnt)) {306 linenum=SrcLineNum(addr,cnt);307 if (linenum<1)308 linenum=1;309 st2=MStrPrint("FL:%s,%d",filename,linenum);310 Free(filename);311 st=StrNew(st2,mem_task);312 Free(st2);313 return st;314 }315 return NULL;316}317 318Bool PutSrcLink(U8 *addr,I64 cnt=1,U8 *buf=NULL)319{//Put to StdOut a DolDoc file,line link to src of addr.320 U8 *src;321 if (src=SrcEdLink(addr,cnt)) {322 if (buf)323 StrPrint(buf,"$LK,\"%p\",A=\"%s\"$",addr,src);324 else325 "$LK,\"%p\",A=\"%s\"$",addr,src;326 Free(src);327 return TRUE;328 } else if (buf)329 *buf=0;330 return FALSE;331}332 333Bool E(U8 *addr,I64 cnt=512,I64 edf_dof_flags=0)334{//Edit src at addr.335 U8 *st;336 Bool res=FALSE;337 if (st=SrcEdLink(addr,cnt)) {338 if (IsRaw)339 res=EdLiteFileLine(st,edf_dof_flags);340 else341 res=Ed(st,edf_dof_flags);342 Free(st);343 }344 return res;345}346 347Bool Man(U8 *st,I64 edf_dof_flags=0)348{//Owner's manual for symbol. Edit src code for symbol.349 Bool res=FALSE;350 U8 **st2;351 CHashSrcSym *tmph;352 if (IsRaw) {353 if ((tmph=HashFind(st,Fs->hash_table,HTG_SRC_SYM)) && tmph->src_link)354 res=EdLiteFileLine(tmph->src_link,edf_dof_flags);355 } else {356 st2=MStrPrint("MN:%s",st);357 res=Ed(st2,edf_dof_flags);358 Free(st2);359 }360 return res;361}362 