From: David van Moolenbroek Date: Sun, 4 Mar 2012 19:13:55 +0000 (+0100) Subject: swifi: modernize a bit X-Git-Tag: v3.2.1~675 X-Git-Url: http://zhaoyanbai.com/repos/%22http:/www.isc.org/icons/zpipe.c?a=commitdiff_plain;h=c8b892d8358b49508fb2bf9300e03f11d3d89e56;p=minix.git swifi: modernize a bit - ELF support - update of one example script - warning fixes --- diff --git a/commands/swifi/Makefile b/commands/swifi/Makefile index 7e5ed483b..88d14b3a7 100644 --- a/commands/swifi/Makefile +++ b/commands/swifi/Makefile @@ -4,6 +4,8 @@ PROG= swifi SRCS= systest.c fault_model.c extra.c db_sym.c db_disasm.c \ db_access.c read_nlist.c CPPFLAGS+= -DCONFIG_SWIFI +DPADD+= ${LIBELF} +LDADD+= -lelf MAN= .include diff --git a/commands/swifi/extra.c b/commands/swifi/extra.c index 87e1e4a2d..a71a53a25 100644 --- a/commands/swifi/extra.c +++ b/commands/swifi/extra.c @@ -26,14 +26,14 @@ void free_page(unsigned long page) { assert(0); } void vfree(void *mem) { assert(0); } size_t strncpy_from_user(char *addr, const char *user_name, size_t size) -{ assert(0); } +{ assert(0); return 0; } /* void lock_kernel(void) { assert(0); } */ /* void unlock_kernel(void) { assert(0); } */ /* void __asm__(char *str) { assert(0); } */ extern void *__vmalloc(unsigned long size, int gfp_mask, pgprot_t prot) -{ assert(0); } +{ assert(0); return NULL; } #if 0 void kallsyms_sections(void *infop, @@ -43,9 +43,9 @@ void kallsyms_sections(void *infop, #endif unsigned long __generic_copy_to_user(void *x, const void *y, unsigned long z) -{ assert(0); } +{ assert(0); return -1; } unsigned long __generic_copy_from_user(void *x, const void *y, unsigned long z) -{ assert(0); } +{ assert(0); return -1; } /* void read_lock(struct lock *lock) { assert(0); } */ /* void read_unlock(struct lock *lock) { assert(0); } */ @@ -72,7 +72,7 @@ int kallsyms_address_to_symbol(db_expr_t off, const char * *sec_name, unsigned long *sec_start, unsigned long *sec_end, const char * *sym_name, unsigned long *sym_start, unsigned long *sym_end) { - static char name[sizeof(((struct nlist *)0)->n_name)+1]; + static char name[64]; int i; unsigned long btext, etext; @@ -83,7 +83,7 @@ int kallsyms_address_to_symbol(db_expr_t off, below= above= NULL; for (i= 0; in_name), - below->n_name, below->n_value); + printf("found '%s' at 0x%x\n", below->n_name, below->n_value); } if (above) { - printf("found '%.*s' at 0x%x\n", sizeof(above->n_name), - above->n_name, above->n_value); + printf("found '%s' at 0x%x\n", above->n_name, above->n_value); } #endif @@ -121,8 +119,8 @@ int kallsyms_address_to_symbol(db_expr_t off, assert(below && above); - memcpy(name, below->n_name, sizeof(below->n_name)); - name[sizeof(below->n_name)]= '\0'; + strncpy(name, below->n_name, sizeof(name)-1); + name[sizeof(name)-1]= '\0'; *sym_name= name; *sym_start= below->n_value | TRAP_BIT; @@ -158,7 +156,7 @@ unsigned char text_read_ub(void *addr) if (v < 0) { fprintf(stderr, - "text_read_ub: trace T_READB_INS failed on pid %d, addr 0x%x: %s\n", + "text_read_ub: trace T_READB_INS failed on pid %d, addr 0x%lx: %s\n", victim_pid, vaddr, strerror(errno)); exit(1); } @@ -186,7 +184,7 @@ void text_write_ub(void *addr, unsigned char value) if (v < 0) { fprintf(stderr, - "text_read_ub: trace T_WRITEB_INS failed on pid %d, addr 0x%x: %s\n", + "text_read_ub: trace T_WRITEB_INS failed on pid %d, addr 0x%lx: %s\n", victim_pid, vaddr, strerror(errno)); exit(1); } @@ -225,7 +223,7 @@ unsigned long *etextp; btext= (unsigned long)-1; for (i= 0; i= etext) { - fprintf(stderr, "Bad btext (0x%x) or etext (0x%x) in %d\n", + fprintf(stderr, "Bad btext (0x%lx) or etext (0x%lx) in %s\n", btext, etext, exe_name); exit(1); } diff --git a/commands/swifi/extra.h b/commands/swifi/extra.h index f00c410e0..89e40743c 100644 --- a/commands/swifi/extra.h +++ b/commands/swifi/extra.h @@ -2,7 +2,7 @@ Compatibility with the linux kernel environment */ -#include +#include #include #include #include diff --git a/commands/swifi/fault_model.c b/commands/swifi/fault_model.c index c6c7e7b05..98afd115e 100644 --- a/commands/swifi/fault_model.c +++ b/commands/swifi/fault_model.c @@ -148,8 +148,8 @@ sys_inject_fault(char * module_name, char * kern_name = NULL; #if 0 struct module * mod = NULL; -#endif int found = 0; +#endif pswifi_result_t res = NULL; if (argNumFaults > SWIFI_MAX_FAULTS) { @@ -1058,7 +1058,7 @@ if (len == 0) int i; printf( - "text_fault: bad length at address 0x%x, c = 0x%x, fault type %d\n", + "text_fault: bad length at address %p, c = %p, fault type %ld\n", addr, c, faultType); printf("bytes:"); for (i= 0; i<16; i++) diff --git a/commands/swifi/read_nlist.c b/commands/swifi/read_nlist.c index 1c50df36f..9c0335dc3 100644 --- a/commands/swifi/read_nlist.c +++ b/commands/swifi/read_nlist.c @@ -1,329 +1,104 @@ -/* -read_nlist.c - -Read the symbol table of an executable into memory. - -Created: Mar 6, 1992 by Philip Homburg -*/ - -#include -#include -#include -#include -#include +/* ELF functions-only symbol table extractor by David van Moolenbroek. + * Replaces generic a.out version by Philip Homburg. + * Temporary solution until libc's nlist(3) becomes usable. + */ #include +#include #include #include +#include +#include +#include +#include -#include "extra.h" - -#define USE_OLD_NLIST 1 - -static u16_t le16 _ARGS(( u16_t *word_p )); -static u32_t le32 _ARGS(( u32_t *word_p )); -static u16_t be16 _ARGS(( u16_t *word_p )); -static u32_t be32 _ARGS(( u32_t *word_p )); - -static u16_t le16(word_p) -u16_t *word_p; -{ - return (((u8_t *)word_p)[0] << 0) | (((u8_t *)word_p)[1] << 8); -} - -static u16_t be16(word_p) -u16_t *word_p; -{ - return (((u8_t *)word_p)[1] << 0) | (((u8_t *)word_p)[0] << 8); -} - -static u32_t le32(dword_p) -u32_t *dword_p; +static int get_syms(Elf *elf, Elf_Scn *scn, Elf32_Shdr *shdr, + struct nlist **nlistp) { - return le16(&((u16_t *)dword_p)[0]) | - ((u32_t)le16(&((u16_t *)dword_p)[1]) << 16); -} + Elf_Data *data; + Elf32_Sym *sym; + unsigned long nsyms; + struct nlist *nlp; + char *name; + size_t size; + int i; + + if ((data = elf_getdata(scn, NULL)) == NULL) { + errno = ENOEXEC; + return -1; + } -static u32_t be32(dword_p) -u32_t *dword_p; -{ - return be16(&((u16_t *)dword_p)[1]) | - ((u32_t)be16(&((u16_t *)dword_p)[0]) << 16); -} + nsyms = data->d_size / sizeof(Elf32_Sym); -#ifndef USE_OLD_NLIST -struct old_nlist -{ - char n_name[8]; - long n_value; - unsigned char n_sclass; - unsigned char n_numaux; - unsigned char n_type; -}; + size = sizeof(struct nlist) * nsyms; + if ((*nlistp = nlp = malloc(size)) == NULL) + return -1; + memset(nlp, 0, size); + + sym = (Elf32_Sym *) data->d_buf; + for (i = 0; i < nsyms; i++, sym++, nlp++) { + nlp->n_value = sym->st_value; + + /* The caller only cares about N_TEXT. Properly setting other + * types would involve crosschecking with section types. + */ + switch (ELF32_ST_TYPE(sym->st_info)) { + case STT_FUNC: nlp->n_type = N_TEXT; break; + default: nlp->n_type = N_UNDF; break; + } -/* Low bits of storage class (section). */ -#define O_N_SECT 07 /* section mask */ -#define O_N_UNDF 00 /* undefined */ -#define O_N_ABS 01 /* absolute */ -#define O_N_TEXT 02 /* text */ -#define O_N_DATA 03 /* data */ -#define O_N_BSS 04 /* bss */ -#define O_N_COMM 05 /* (common) */ + name = elf_strptr(elf, shdr->sh_link, (size_t) sym->st_name); + if ((nlp->n_name = strdup(name ? name : "")) == NULL) { + free(*nlistp); + return -1; + } + } -/* High bits of storage class. */ -#define O_N_CLASS 0370 /* storage class mask */ -#define O_C_NULL -#define O_C_EXT 0020 /* external symbol */ -#define O_C_STAT 0030 /* static */ -#endif + return nsyms; +} -int read_nlist(filename, nlist_table) -const char *filename; -struct nlist **nlist_table; +int read_nlist(const char *filename, struct nlist **nlist_table) { - int r, n_entries, save_err; - u32_t (*cnv32) _ARGS(( u32_t *addr )); - u16_t (*cnv16) _ARGS(( u16_t *addr )); - struct nlist *nlist_p, *nlist_ptr; - int exec_fd; - struct exec exec_header; -#ifndef USE_OLD_NLIST - struct old_nlist *old_nlist, *old_nlist_p; - void *old_nlist_end; -#endif - char *str_tab, *str_base, *str_null; - u32_t string_siz; - - exec_fd= open(filename, O_RDONLY); - if (exec_fd == -1) /* No executable present */ - { + /* Read in the symbol table of 'filename'. Return the resulting symbols + * as an array, with 'nlist_table' set to point to it, and the number + * of elements as the return value. The caller has no way to free the + * results. Return 0 if the executable contains no symbols. Upon error, + * return -1 and set errno to an appropriate value. + */ + Elf *elf; + Elf_Scn *scn; + Elf32_Shdr *shdr; + int res, fd; + + if (elf_version(EV_CURRENT) == EV_NONE) { + errno = EINVAL; return -1; } - r= read(exec_fd, (char *)&exec_header, A_MINHDR); - if (r != A_MINHDR) - { - if (r != -1) - errno= ENOEXEC; + if ((fd = open(filename, O_RDONLY)) < 0) return -1; - } - if (BADMAG(exec_header)) - { - errno= ENOEXEC; - return -1; - } - switch(exec_header.a_cpu & 3) - { - case 0: /* little endian */ - cnv32= le32; - cnv16= le16; - break; - case 3: /* big endian */ - cnv32= be32; - cnv16= be16; - break; - default: - errno= ENOEXEC; - return -1; - } - exec_header.a_version= cnv16((u16_t *)&exec_header.a_version); - exec_header.a_text= cnv32((u32_t *)&exec_header.a_text); - exec_header.a_data= cnv32((u32_t *)&exec_header.a_data); - exec_header.a_bss= cnv32((u32_t *)&exec_header.a_bss); - exec_header.a_entry= cnv32((u32_t *)&exec_header.a_entry); - exec_header.a_total= cnv32((u32_t *)&exec_header.a_total); - exec_header.a_syms= cnv32((u32_t *)&exec_header.a_syms); - exec_header.a_trsize= cnv32((u32_t *)&exec_header.a_trsize); - exec_header.a_drsize= cnv32((u32_t *)&exec_header.a_drsize); - exec_header.a_tbase= cnv32((u32_t *)&exec_header.a_tbase); - exec_header.a_dbase= cnv32((u32_t *)&exec_header.a_dbase); - if (!exec_header.a_syms) - return 0; - - if (exec_header.a_flags & A_NSYM) - { -#if USE_OLD_NLIST - errno= EINVAL; + elf = elf_begin(fd, ELF_C_READ, NULL); + if (elf == NULL) { + errno = ENOEXEC; + close(fd); return -1; -#else - r= lseek(exec_fd, A_SYMPOS(exec_header)+exec_header.a_syms, - SEEK_SET); - if (r == -1) - { - return -1; - } - r= read(exec_fd, (char *)&string_siz, 4); - if (r != 4) - return -1; - string_siz= cnv32(&string_siz)-4; - nlist_p= malloc(exec_header.a_syms + string_siz+1); - if (!nlist_p) - { - errno= ENOMEM; - return -1; - } - r= lseek(exec_fd, A_SYMPOS(exec_header)+exec_header.a_syms+4, - SEEK_SET); - if (r == -1) - { - save_err= errno; - free(nlist_p); - errno= save_err; - return -1; - } - r= read(exec_fd, ((char *)nlist_p)+exec_header.a_syms, - string_siz); - if (r != string_siz) - { - save_err= errno; - free(nlist_p); - errno= save_err; - return -1; - } - r= lseek(exec_fd, A_SYMPOS(exec_header), SEEK_SET); - if (r == -1) - { - save_err= errno; - free(nlist_p); - errno= save_err; - return -1; - } - r= read(exec_fd, ((char *)nlist_p), exec_header.a_syms); - if (r != exec_header.a_syms) - { - save_err= errno; - free(nlist_p); - errno= save_err; - return -1; - } - str_base= ((char *)nlist_p) + exec_header.a_syms -4; - str_null= (char *)nlist_p + exec_header.a_syms + string_siz; - *str_null= '\0'; - for (nlist_ptr= nlist_p; (char *)nlist_ptr+1 <= str_base+4; - nlist_ptr++) - { - nlist_ptr->n_desc= le16((u16_t *)&nlist_ptr->n_desc); - nlist_ptr->n_value= le32(&nlist_ptr->n_value); - if (nlist_ptr->n_un.n_strx) - nlist_ptr->n_un.n_name= str_base+ - cnv32((u32_t *)&nlist_ptr->n_un.n_strx); - else - nlist_ptr->n_un.n_name= str_null; - } - *nlist_table= nlist_p; - return nlist_ptr-nlist_p; -#endif } - else - { - r= lseek(exec_fd, A_SYMPOS(exec_header), SEEK_SET); - if (r == -1) - { - return -1; - } - -#if USE_OLD_NLIST - n_entries= exec_header.a_syms/sizeof(struct nlist); - nlist_p= malloc(exec_header.a_syms); - if (!nlist_p) - { - free(nlist_p); - errno= ENOMEM; - return -1; - } - r= read(exec_fd, (char *)nlist_p, exec_header.a_syms); - if (r != exec_header.a_syms) - { - save_err= errno; - free(nlist_p); - errno= save_err; - return -1; - } - *nlist_table= nlist_p; - return n_entries; -#else - n_entries= exec_header.a_syms/sizeof(struct old_nlist)+1; - nlist_p= NULL; - old_nlist= NULL; + scn = NULL; + res = 0; + while ((scn = elf_nextscn(elf, scn)) != NULL) { + if ((shdr = elf32_getshdr(scn)) == NULL) + continue; - nlist_p= malloc(n_entries * (sizeof(struct nlist)+ - sizeof(old_nlist->n_name)+1)); - old_nlist= malloc(exec_header.a_syms); - if (!old_nlist || !nlist_p) - { - if (nlist_p) - free(nlist_p); - if (old_nlist) - free(old_nlist); - errno= ENOMEM; - return -1; - } - r= read(exec_fd, (char *)old_nlist, exec_header.a_syms); - if (r != exec_header.a_syms) - { - save_err= errno; - free(nlist_p); - free(old_nlist); - errno= save_err; - return -1; - } + if (shdr->sh_type != SHT_SYMTAB) + continue; - old_nlist_end= (char *)old_nlist+exec_header.a_syms; - str_tab= (char *)&nlist_p[n_entries]; - n_entries= 0; - for (old_nlist_p= old_nlist; - (void *)(old_nlist_p+1)<=old_nlist_end; old_nlist_p++) - { - switch(old_nlist_p->n_sclass & O_N_SECT) - { - case O_N_UNDF: - nlist_p[n_entries].n_type= N_UNDF; - break; - case O_N_ABS: - nlist_p[n_entries].n_type= N_ABS; - break; - case O_N_TEXT: - nlist_p[n_entries].n_type= N_TEXT; - break; - case O_N_DATA: - nlist_p[n_entries].n_type= N_DATA; - break; - case O_N_BSS: - nlist_p[n_entries].n_type= N_BSS; - break; - case O_N_COMM: - nlist_p[n_entries].n_type= N_COMM; - break; - default: - continue; - } - switch(old_nlist_p->n_sclass & O_N_CLASS) - { - case O_C_EXT: - nlist_p[n_entries].n_type |= N_EXT; - case O_C_STAT: - break; - default: - continue; - } - nlist_p[n_entries].n_value= - cnv32((u32_t *)&old_nlist_p->n_value); - nlist_p[n_entries].n_un.n_name= str_tab; - memcpy(str_tab, old_nlist_p->n_name, - sizeof(old_nlist_p->n_name)); - str_tab += sizeof(old_nlist_p->n_name); - *str_tab++= '\0'; - n_entries++; - } - free(old_nlist); - nlist_p= realloc(nlist_p, str_tab-(char *)nlist_p); - *nlist_table= nlist_p; - return n_entries; -#endif + res = get_syms(elf, scn, shdr, nlist_table); + break; } -} -/* - * $PchId: read_nlist.c,v 1.5 1996/04/11 07:47:38 philip Exp $ - */ + elf_end(elf); + close(fd); + + return res; +} diff --git a/commands/swifi/run_swifi b/commands/swifi/run_swifi index 0d5ae99e3..1836e4af2 100644 --- a/commands/swifi/run_swifi +++ b/commands/swifi/run_swifi @@ -1,18 +1,24 @@ #!/bin/sh -LABEL=dp8390 -EXEDIR=/usr/build/drivers/dp8390 -EXE=$EXEDIR/$LABEL +LABEL=e1000_0 +NAME=e1000 +EXEDIR=/usr/src/drivers/$NAME +EXE=$EXEDIR/$NAME :>log +start_driver() +{ + service up $EXE -label $LABEL -script /etc/rs.single -period 3HZ +} + do_one() { # $1 = test-nr, $2 = count, $3 = seed pid='' while [ X"$pid" = X ] do - pid=`ps ax | grep $LABEL | grep -v grep | + pid=`ps ax | grep $NAME | grep -v grep | sed 's,^[ ]*,,;s,[ ].*,,` if [ X"$pid" != X ] then @@ -24,7 +30,8 @@ do_one() ./swifi -f $EXE $pid $1 $2 $3 >/tmp/out sleep 1 kill -0 $pid && - echo "driver failed to die, params: test $1, count $2, seed $3" + echo "driver survived, params: test $1, count $2, seed $3" || + start_driver } one_round() @@ -46,7 +53,7 @@ one_round() # Start our own driver. service down $LABEL sleep 10 # Allow driver to die -service up $EXE -script `pwd`/rs.restart_imm -period 3HZ +start_driver i=0 i=4000