Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

The design of the exoskeleton. Monograph

.pdf
Скачиваний:
0
Добавлен:
07.09.2026
Размер:
2 Мб
Скачать
131
f=lookup_mem(start);
if (!f) {
// Oh man. if (!U) { indent(0); debug("- remap: non-existing buffer %x -> %x:%d\n",start,newaddr,len); } else { sprintf(b2,"- remap: non-existing buffer %x -> %x:%d\n",start,newaddr,len); nappend(pdescr,b2,MAXDESCR); }
if (!current->memtop) { current->memtop=TABINC; current->mem=malloc(sizeof(struct fenris_mem)*TABINC); }
for (i=0;i<current->memtop;i++) if (!(*current->mem)[i].descr) break;
if (i==current->memtop) { current->memtop+=TABINC; current->mem=realloc(current->mem,sizeof(struct fenris_mem)*(current->memtop+1)); }
snprintf(buf,MAXDESCR,"from hell, resized in %s",who); (*current->mem)[i].descr=strdup(buf); (*current->mem)[i].addr=newaddr; (*current->mem)[i].len=len; (*current->mem)[i].owner=current->fntop; return;
}
if ( (f->addr != start) ) { if (!U) { indent(0); debug("- remap: %x -> %x:%d, but nearest is: %x:%d (%s)\n",start,newaddr,len,f->addr,f->len,f-
>descr);
} else { sprintf(b2,"- remap: %x -> %x:%d, but nearest is: %x:%d (%s)\n",start,newaddr,len,f->addr,f-
>len,f->descr);
nappend(pdescr,b2,MAXDESCR); } return;
132
}
if (!U) { indent(0); debug("\\ remap: %x:%d -> %x:%d\n",f->addr,f->len,newaddr,len); } else { sprintf(b2,"\\ remap: %x:%d -> %x:%d\n",f->addr,f->len,newaddr,len); nappend(pdescr,b2,MAXDESCR); }
snprintf(buf,MAXDESCR,"resized from %d in %s",f->len,who); free(f->descr); f->descr=strdup(buf); f->len = len; f->addr=newaddr; f->auth=auth;
} else {
mergeloop:
f=lookup_inrange(start,len);
if (f) { if (!T_nodesc) { if (f->auth) { if (!U) { indent(0); debug("\\ UNEXPECTED is-within: %x:%d in %x:%d (%s)\n",f->addr,f->len,start,len,f->descr); } else { sprintf(b2,"\\ UNEXPECTED is-within: %x:%d in %x:%d (%s)\n",f->addr,f->len,start,len,f->descr); nappend(pdescr,b2,MAXDESCR); } } if (!U) { indent(0); debug("\\ discard: mem %x:%d (%s) [is within %x:%d]\n",f->addr,f->len,f->descr,start,len); } else { sprintf(b2,"\\ discard: mem %x:%d (%s) [is within %x:%d]\n",f->addr,f->len,f->descr,start,len); nappend(pdescr,b2,MAXDESCR); } }
f->addr=0; free(f->descr); if (f->lasti) free(f->lasti);
133
f->lasti=0; f->descr=0; f->len=0;
f=0; goto mergeloop; }
if (!auth) f=lookup_mem(start+len+1); else f=0; if (!f) f=lookup_mem(start+len);
if (f) { if (f->addr <= start) {
// So, we have a buffer that starts before ours and ends // past our buffer. It looks like there is no need to do anything, // unless this is an authoritative attempt.
if (auth && (!T_nodesc)) { if (!U) { indent(0); debug("\\ UNEXPECTED already-have: %x:%d in %x:%d (%s)\n",start,len,f->addr,f->len,f->descr); } else { sprintf(b2,"\\ UNEXPECTED already-have: %x:%d in %x:%d (%s)\n",start,len,f->addr,f->len,f-
>descr);
nappend(pdescr,b2,MAXDESCR); } }
if (doingmerge) free(doingmerge); return;
} else {
// We have something that starts in our buffer and ends past // our buffer. Adjust current length and discard the old one.
if (auth) if (start + len + 1 == f->addr) goto nojoin;
if (!T_nodesc) { if (!U) { if (!(auth|f->auth) && !be_silent) { indent(0);
134
debug("\\ %smerge [EA]: %x:%d %x:%d (%s) -> ",(auth|f->auth)?"UNEXPECTED ":"",start,len,f-
>addr,f->len,f->descr);
} } else { sprintf(b2,"\\ %smerge [EA]: %x:%d %x:%d (%s) -> ",(auth|f->auth)?"UNEXPECTED ":"",start,len,f-
>addr,f->len,f->descr);
nappend(pdescr,b2,MAXDESCR); } }
len=f->len; len+=(f->addr-start); if (f->auth) auth=1; if (doingmerge) free(doingmerge); doingmerge=f->descr; owner=f->owner; f->addr=f->len=0; f->descr=0; f->auth=0;
if (!T_nodesc) { if (!U) { if (!(auth|f->auth) && !be_silent) debug("%x:%d\n",start,len); } else { sprintf(b2,"%x:%d\n",start,len); nappend(pdescr,b2,MAXDESCR); } }
// Retry, we might have more things like that. goto mergeloop;
}
}
if (!auth) f=lookup_mem(start-1); else f=0; if (!f) f=lookup_mem(start);
if (f) { // Ok, so we have a buffer that contains our start point. // Check where would it end.
if ( (f->addr+f->len) >= (start + len) ) {
// Ah, so this buffer starts before ours and ends past this // point.
135
if (auth && (!T_nodesc)) { if (!U) { indent(0); debug("\\ UNEXPECTED already-have: %x:%d in %x:%d (%s)\n",start,len,f->addr,f->len,f->descr); } else { sprintf(b2,"\\ UNEXPECTED already-have: %x:%d in %x:%d (%s)\n",start,len,f->addr,f->len,f-
>descr);
nappend(pdescr,b2,MAXDESCR); } }
if (doingmerge) free(doingmerge); return;
} else {
// The buffer starts before ours and ends inside ours. // Resize our, discard the old one.
if (auth) if (f->addr + f->len + 1 == start) goto nojoin;
if (!T_nodesc) { if (!U) { if (!(auth|f->auth) && !be_silent) { indent(0); debug("\\ %smerge [SB]: %x:%d %x:%d (%s) -> ",(auth|f->auth)?"UNEXPECTED ":"",start,len,f-
>addr,f->len,f->descr);
} } else { sprintf(b2,"\\ %smerge [SB]: %x:%d %x:%d (%s) -> ",(auth|f->auth)?"UNEXPECTED ":"",start,len,f-
>addr,f->len,f->descr);
nappend(pdescr,b2,MAXDESCR); } }
len=f->len+len-((f->addr+f->len)-start); start=f->addr; if (f->auth) auth=1; if (doingmerge) free(doingmerge); doingmerge=f->descr; owner=f->owner; f->addr=f->len=0; f->descr=0; f->auth=0;
if (!T_nodesc) { if (!U) {
136
if (!(auth|f->auth) && !be_silent) debug("%x:%d\n",start,len); } else { sprintf(b2,"%x:%d\n",start,len); nappend(pdescr,b2,MAXDESCR); } }
goto mergeloop;
} }
nojoin:
if (!current->memtop) { current->memtop=TABINC; current->mem=malloc(sizeof(struct fenris_mem)*TABINC); }
for (i=0;i<current->memtop;i++) if (!(*current->mem)[i].descr) break;
if (i==current->memtop) { current->memtop+=TABINC; current->mem=realloc(current->mem,sizeof(struct fenris_mem)*current->memtop); }
if (!doingmerge) { snprintf(buf,MAXDESCR,"first seen in %s",who); (*current->mem)[i].descr=strdup(buf); (*current->mem)[i].owner=current->fntop; } else { (*current->mem)[i].descr=doingmerge; (*current->mem)[i].owner=owner; }
(*current->mem)[i].addr=start; (*current->mem)[i].len=len; (*current->mem)[i].auth=auth;
if (!doingmerge && !T_nodesc) { if (!U) { char* x=lookup_fnct(start,0,0); if (!x) x=find_name_ex(start,2,1);
if (!be_silent) {
137
indent(0); if ((x=lookup_fnct(start,0,0))) debug("\\ new %sbuffer candidate: %x:%d (%s)\n",auth?"authoritative ":"",start,len,x); else debug("\\ new %sbuffer candidate: %x:%d\n",auth?"authoritative ":"",start,len); } } else { char* x=lookup_fnct(start,0,0); if (!x) x=find_name_ex(start,2,1);
if (x) sprintf(b2,"\\ new %sbuffer candidate: %x:%d (%s)\n",auth?"authoritative ":"",start,len,x); else sprintf(b2,"\\ new %sbuffer candidate: %x:%d\n",auth?"authoritative ":"",start,len); nappend(pdescr,b2,MAXDESCR); } } }
}
/***************************** * Add something to writelog * *****************************/
static inline void append_wlog(const char* what) { int curlen=0;
if (T_wnow) { if (strchr(what,'*')) indent(0); debug("%s",what); return; }
if (current->wlog[current->fntop]) { curlen=strlen(current->wlog[current->fntop]); if (strstr(current->wlog[current->fntop],what)) return; } current->wlog[current->fntop]=realloc(current->wlog[current->fntop],curlen+strlen(what)+4); strcat(current->wlog[current->fntop],what); }
138
/************************ * Lookup function name * ************************/
inline char* lookup_fnct(unsigned int c, unsigned int add,char prec) { int i; int mindif=100000000, best=-1; int addplus=0;
if (add==123456) { add=0; addplus=1; }
if (add) find_id(c,1);
if (!current->b) {
int size; bfd* b;
if (current->symfail || T_nosym) { // Do not retry. if (!find_id(c,0)) return 0; sprintf(fnm_buf,"fnct_%d",find_id(c,0)); return fnm_buf; }
sprintf(fnm_buf,"/proc/%d/exe",pid); b = bfd_openr(fnm_buf,0);
if (!b) { current->symfail=1; if (!find_id(c,0)) return 0; sprintf(fnm_buf,"fnct_%d",find_id(c,0)); return fnm_buf; }
if (bfd_check_format(b,bfd_archive)) { current->symfail=1; if (!find_id(c,0)) return 0; sprintf(fnm_buf,"fnct_%d",find_id(c,0)); bfd_close(b); return fnm_buf; }
bfd_check_format_matches(b,bfd_object,0);
139
if ((bfd_get_file_flags(b) & HAS_SYMS) == 0) { current->symfail=1; if (!find_id(c,0)) return 0; sprintf(fnm_buf,"fnct_%d",find_id(c,0)); bfd_close(b); return fnm_buf; }
size = bfd_get_symtab_upper_bound(b);
if (size <= 0) { current->symfail=1; if (!find_id(c,0)) return 0; sprintf(fnm_buf,"fnct_%d",find_id(c,0)); bfd_close(b); return fnm_buf; }
current->syms=(asymbol**)malloc(size);
if (!current->syms) { current->symfail=1; if (!find_id(c,0)) return 0; sprintf(fnm_buf,"fnct_%d",find_id(c,0)); bfd_close(b); return fnm_buf; }
if ((current->symcnt=bfd_canonicalize_symtab(b,current->syms))<0) fatal("bfd_canonicalize_symtab failed",0);
current->b=b;
}
for (i=0;i<current->symcnt;i++) if (current->syms[i] && (current->syms[i]->flags!=1) ) { if (prec) { if (bfd_asymbol_value(current->syms[i])!=c) continue; if (!bfd_asymbol_name(current->syms[i]) || !strlen(bfd_asymbol_name(current->syms[i])))
continue;
} else { int dif; dif=c-(bfd_asymbol_value(current->syms[i])); if (dif<0) continue;
140
if (!bfd_asymbol_name(current->syms[i]) || !strlen(bfd_asymbol_name(current->syms[i])))
continue;
if (dif<=mindif) { mindif=dif; best=i; } if (dif) continue; }
strcpy(fnm_buf,bfd_asymbol_name(current->syms[i]));
if (fnm_buf[0]) return fnm_buf;
}
if ((!prec) && (best>0)) { strcpy(fnm_buf,bfd_asymbol_name(current->syms[best])); if (addplus) sprintf(&fnm_buf[strlen(fnm_buf)],"+%d",mindif); return fnm_buf; }
if (!find_id(c,0)) return 0; sprintf(fnm_buf,"fnct_%d",find_id(c,0)); return fnm_buf;
}
void* libc_sym;
// Used only for debugging. Be careless. inline int lookup_fnname(char* name) { int i; char fnm_buf[1000]; char* fifi; int add=0;
fifi=strchr(name,'+');
if (fifi) { *fifi=0; fifi++; sscanf(fifi,"%d",&add); }
// First, try the simpliest solution. if (sscanf(name,"fnct_%d",&i)==1) {