Добавил:
ivanov666
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:The design of the exoskeleton. Monograph
.pdf
141
if (current->fnaddr) {
i-=1;
if (i>=0 && i<current->idtop) return (*current->fnaddr)[i]+add;
}
return 0;
}
if (T_nosym) return 0;
// Then, try libc...
if (!libc_sym) {
if (!is_static)
libc_sym = dlopen("/lib/libc.so.6",RTLD_LAZY|RTLD_GLOBAL);
if (!libc_sym) goto no_libc;
}
i=(int)dlsym(libc_sym,name);
if (i) return i+add;
no_libc:
// Nope. Try local symbols
if (!current->b) {
int size;
bfd* b;
if (current->symfail) return 0;
sprintf(fnm_buf,"/proc/%d/exe",pid);
b = bfd_openr(fnm_buf,0);
if (!b) {
current->symfail=1;
return 0;
}
if (bfd_check_format(b,bfd_archive)) {
current->symfail=1;
bfd_close(b);
return 0;
}
bfd_check_format_matches(b,bfd_object,0);

142
if ((bfd_get_file_flags(b) & HAS_SYMS) == 0) {
current->symfail=1;
bfd_close(b);
return 0;
}
size = bfd_get_symtab_upper_bound(b);
if (size <= 0) {
current->symfail=1;
bfd_close(b);
return 0;
}
current->syms=(asymbol**)malloc(size);
if (!current->syms) {
current->symfail=1;
bfd_close(b);
return 0;
}
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])
if (bfd_asymbol_name(current->syms[i]))
if (!strcmp(bfd_asymbol_name(current->syms[i]),name))
return bfd_asymbol_value(current->syms[i])+add;
return 0;
}
/***********************
* Remove memory block *
***********************/
static void delete_mem(unsigned int start,char auth) {

143
struct fenris_mem* f;
f=lookup_mem(start);
if (!f) {
if (!auth) return;
indent(0);
debug("- discard on non-existing block %x\n",start);
return;
}
if (!T_nodesc) {
indent(0);
debug("\\ discard: mem %x:%d (%s)\n",f->addr,f->len,f->descr);
}
f->addr=0;
free(f->descr);
if (f->lasti) free(f->lasti);
f->lasti=0;
f->descr=0;
f->len=0;
}
/********************
* Die mysteriously *
********************/
static void segfault(int x) {
write(2,spell,strlen(spell));
debug("Fatal exception occured. Fenris will terminate now. If you feel\n"
"this should not happen, please use fenris-bug application to\n"
"report this problem to the maintainer. Thank you :-)\n\n");
if (current) {
debug("Fault parameters: pid:%d eip:%x esp:%x nest:%d memtop:%d\n"
"\tidtop:%d mtop:%d memtop:%d fntop:%d symcnt:%d\n\n",
current->pid,(int)r.eip,(int)r.esp,current->nest,current->memtop,
current->idtop,current->mtop,current->memtop,current->fntop,current->symcnt);
}
abort();

144
}
static void pipefault(int x) {
fatal("connection dropped? terminal disappeared?",-1);
}
/*************************
* Lookup memory address *
*************************/
static inline struct fenris_mem* lookup_mem(const unsigned int addr) {
int i;
for (i=0;i<current->memtop;i++) {
if (!(*current->mem)[i].descr) continue;
if ((*current->mem)[i].addr <= addr)
if (((*current->mem)[i].addr + (*current->mem)[i].len) > addr) {
return &(*current->mem)[i];
}
}
return 0;
}
/****************************************
* Lookup any buffer inside given range *
****************************************/
static inline struct fenris_mem* lookup_inrange(const unsigned int addr,const unsigned int len) {
unsigned int end=addr+len;
int i;
for (i=0;i<current->memtop;i++) {
if (!(*current->mem)[i].descr) continue;
if ((*current->mem)[i].addr >= addr)
if ((*current->mem)[i].addr < end)
if ((*current->mem)[i].addr + (*current->mem)[i].len >= addr)
if ((*current->mem)[i].addr + (*current->mem)[i].len < end)
return &(*current->mem)[i];

145
}
return 0;
}
/**************
* Lookup map *
**************/
static inline struct fenris_map* lookup_map(const unsigned int addr) {
int i;
for (i=0;i<current->mtop+1;i++) {
if (!(*current->map)[i].name) continue;
if ((*current->map)[i].addr <= addr)
if (((*current->map)[i].addr + (*current->map)[i].len) > addr)
return &(*current->map)[i];
}
return 0;
}
/******************************
* Mark local regions invalid *
******************************/
static inline void invalidate_mem(void) {
int i;
unsigned int s;
for (i=0;i<current->memtop;i++) {
if ((s=(*current->mem)[i].addr)) {
if ((s>>24) != STACKSEG) continue;
// if (s >= current->frstart[current->fntop])
if (s < current->frend[current->fntop])
delete_mem(s,1);
}
}
}

146
/**************************************
* Push local function entry to stack *
**************************************/
static inline void push_fnid(const unsigned int id) {
if (current->fntop>=MAXNEST) {
if (T_noskip) {
debug("* WARNING: fntop MAXNEST exceeded at 0x%x, pretending that nothing
happened.\n",(int)r.eip);
current->fntop--;
} else fatal("fntop MAXNEST exceeded",0);
}
current->frstart[current->fntop] = r.esp + current->curpcnt * 4;
current->fntop++;
current->fnid[current->fntop]=id;
current->fneip[current->fntop]=r.eip;
current->frstart[current->fntop]=0;
current->frend[current->fntop]=r.esp + 4;
}
/******************************
* Return from local function *
******************************/
static inline void fn_ret(void) {
if (current->fntop>0) {
dump_memchg(0);
invalidate_mem();
current->fntop--;
return;
}
}
/******************************

147
* Add new pupils to ps table *
******************************/
static void add_process(const int mpid) {
int i;
for (i=0;i<MAXCHILDREN;i++)
if (!ps[i].pid) {
bzero(&ps[i],sizeof(struct fenris_process));
ps[i].pid=mpid;
ps[i].nest=innest;
ps[i].is_static=is_static;
current=&ps[i];
add_ldmap();
return;
}
fatal("too many child processes (table overflow)",0);
}
/********************************
* Describe function parameters *
********************************/
static inline void display_value(const unsigned int q,const char* where) {
if ((q >> 24) == CODESEG) debug("g/%x",q); // global
else if ((q >> 24) == STACKSEG) debug("l/%x",q); // local
else if (INLIBC(q)) debug("s/%x",q); // shared
else debug("%d",q);
add_pdescr(q);
print_string(q,where);
}
/*********************************************
* Modify last input parameter for SOMETHING *
*********************************************/

148
static inline void modify_lasti(unsigned int sth,char* where,int fd,unsigned int map,char* what) {
char buf[MAXDESCR*2];
struct fenris_map* ma=0;
struct fenris_mem* me=0;
if (!sth || (sth>0xffffff00)) return;
strncpy(buf,where,MAXDESCR);
if (map) sprintf(&buf[strlen(buf)]," on map %x",map);
else if (fd) sprintf(&buf[strlen(buf)]," on file \"%s\"",get_fname(fd));
else if (what && what[0]) snprintf(&buf[strlen(buf)],MAXDESCR," on %s",what);
me=lookup_mem(sth);
if (me) {
if (me->lasti) free(me->lasti);
me->lasti=strdup(buf);
if (current->nest>=0 && !be_silent) {
indent(0);
debug("\\ buffer %x modified.\n",me->addr);
}
return;
}
ma=lookup_map(sth);
if (ma) {
if (ma->lasti) free(ma->lasti);
ma->lasti=strdup(buf);
if (current->nest>=0 && !be_silent) {
indent(0);
debug("\\ buffer %x modified.\n",ma->addr);
}
return;
}
// Doh. Nothing.
}
/**************************************
* Some fast-action debug() functions *

149
**************************************/
static inline unsigned int Xv(const unsigned int q) {
if (q) add_pdescr(q);
return q;
}
static inline int Xf(int q) {
if (q>=0) add_fd_pdescr(q);
return q;
}
static inline unsigned int Wv(const unsigned int q) {
if (q) add_wdescr(q,1);
return q;
}
/*******************************
* Add something to pdescr log *
*******************************/
static inline void add_pdescr(const unsigned int q) {
int miau=0;
char tmp[MAXDESCR];
struct fenris_map* ma=0;
struct fenris_mem* me=0;
if (T_dostep) {
if ((q >> 24) == CODESEG) break_memread(q); else
if ((q >> 24) == STACKSEG) break_memread(q); else
if (INLIBC(q)) break_memread(q);
}
if (T_nodesc) return;
if ((q >> 24) == CODESEG) miau=1; // global
else if ((q >> 24) == STACKSEG) miau=2; // local
else if (INLIBC(q)) miau=3; // shared
else return;
tmp[0]=0;

150
// First of all, it might be a local function. Look for extact
// match.
if (miau==1) {
if (lookup_fnct(q,0,1)) {
sprintf(tmp,"+ g/%x = local %s\n",q,lookup_fnct(q,0,1));
nappend(pdescr,tmp,MAXPDESC);
}
}
// Then, it can be a library function. Check for extact match, again.
else if (miau==3) {
char* x;
current->lentry=q;
x=find_name_ex(q,1,1);
if (x) {
snprintf(tmp,MAXDESCR,"+ s/%x = %s\n",q,x);
nappend(pdescr,tmp,MAXPDESC);
}
}
// Hmm, look for unspecific stuff - is this a buffer? Or a map?
if (miau) {
me=lookup_mem(q);
if (me) {
if (!tmp[0]) {
snprintf(tmp,MAXDESCR,"+ %x = %x:%d <off %d> (%s)\n",q,
me->addr,me->len,q-me->addr,me->descr);
nappend(pdescr,tmp,MAXPDESC);
} else {
sprintf(tmp,":%d\n",me->len);
pdescr[strlen(pdescr)-1]=0;
nappend(pdescr,tmp,MAXPDESC);
}
if (me->lasti) {
snprintf(tmp,MAXDESCR," last input: %s\n",me->lasti);
nappend(pdescr,tmp,MAXPDESC);
}
return;
}
if (!me) ma=lookup_map(q);
if (ma) {
if (!tmp[0]) {
snprintf(tmp,MAXDESCR,"+ %x = map %x:%d <off %d> (%s)\n",q,
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
