Добавил:
ivanov666
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:The design of the exoskeleton. Monograph
.pdf
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) {
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
