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

Проектирование экзоскелета. Монография

.pdf
Скачиваний:
0
Добавлен:
08.09.2026
Размер:
2 Мб
Скачать
☆
161
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) { if (current->fnaddr) {
162
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) {
163
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);
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; }
164
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) { 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;
165
}
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) {
166
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(); }
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]; } }
167
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];
}
return 0;
}
/************** * Lookup map *
168
**************/
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])
169
delete_mem(s,1); } }
}
/************************************** * 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;
}
170
/****************************** * Return from local function * ******************************/
static inline void fn_ret(void) {
if (current->fntop>0) { dump_memchg(0); invalidate_mem(); current->fntop--; return; }
}
/****************************** * 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();
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]