]> Zhao Yanbai Git Server - minix.git/commitdiff
swifi: modernize a bit
authorDavid van Moolenbroek <david@minix3.org>
Sun, 4 Mar 2012 19:13:55 +0000 (20:13 +0100)
committerDavid van Moolenbroek <david@minix3.org>
Mon, 5 Mar 2012 21:41:49 +0000 (22:41 +0100)
- ELF support
- update of one example script
- warning fixes

commands/swifi/Makefile
commands/swifi/extra.c
commands/swifi/extra.h
commands/swifi/fault_model.c
commands/swifi/read_nlist.c
commands/swifi/run_swifi

index 7e5ed483bb6d04ecd2755a7c2d7a0e222e041960..88d14b3a75e8a58912c485ddb89a15386e82d957 100644 (file)
@@ -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 <bsd.prog.mk>
index 87e1e4a2d2c6601f23edbeb38b0db982d0f03a35..a71a53a250d79943d4078dab043b39e0e6e956a5 100644 (file)
@@ -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; i<exe_nlist_n; i++)
        {
-               if ((exe_nlist[i].n_sclass & N_SECT) != N_TEXT)
+               if (exe_nlist[i].n_type != N_TEXT)
                        continue;
                if (exe_nlist[i].n_value <= off)
                {
@@ -99,13 +99,11 @@ int kallsyms_address_to_symbol(db_expr_t off,
 #if 0
        if (below)
        {
-               printf("found '%.*s' at 0x%x\n", sizeof(below->n_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<exe_nlist_n; i++)
        {
-               if ((exe_nlist[i].n_sclass & N_SECT) != N_TEXT)
+               if (exe_nlist[i].n_type != N_TEXT)
                        continue;
                if (exe_nlist[i].n_value < btext)
                        btext= exe_nlist[i].n_value;
@@ -235,7 +233,7 @@ unsigned long *etextp;
 
        if (btext >= 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);
        }
index f00c410e091209e4b42e35adb5dda2db8f38eaa6..89e40743c0229807627540b1724239e5ce8f449c 100644 (file)
@@ -2,7 +2,7 @@
 Compatibility with the linux kernel environment 
 */
 
-#include <a.out.h>
+#include <nlist.h>
 #include <errno.h>
 #include <string.h>
 #include <sys/types.h>
index c6c7e7b054a701798aba5457f0c0aa7d0e28b799..98afd115eb49f676c33b3aa48defe886c125c37b 100644 (file)
@@ -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++)
index 1c50df36fab82a4cdf3f2af2c9c4c75b3ddc871e..9c0335dc3883f77502d65215e2007e7e156bf2c4 100644 (file)
-/*
-read_nlist.c
-
-Read the symbol table of an executable into memory. 
-
-Created:       Mar 6, 1992 by Philip Homburg
-*/
-
-#include <sys/types.h>
-#include <assert.h>
-#include <a.out.h>
-#include <errno.h>
-#include <fcntl.h>
+/* 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 <stdlib.h>
+#include <stdio.h>
 #include <string.h>
 #include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <libelf.h>
+#include <nlist.h>
 
-#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;
+}
index 0d5ae99e3ec38bb0e209c4d01baafdcab8cc743d..1836e4af24a7f5e545c644e0cb1ec9c17673c0e1 100644 (file)
@@ -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