swifi: modernize a bit

- ELF support
- update of one example script
- warning fixes
This commit is contained in:
David van Moolenbroek 2012-03-04 20:13:55 +01:00
parent 1512dc5c23
commit c8b892d835
6 changed files with 118 additions and 336 deletions

View 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>

View 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);
}

View 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>

View 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++)

View file

@ -1,329 +1,104 @@
/*
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;
static int get_syms(Elf *elf, Elf_Scn *scn, Elf32_Shdr *shdr,
struct nlist **nlistp)
{
return (((u8_t *)word_p)[0] << 0) | (((u8_t *)word_p)[1] << 8);
}
Elf_Data *data;
Elf32_Sym *sym;
unsigned long nsyms;
struct nlist *nlp;
char *name;
size_t size;
int i;
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;
{
return le16(&((u16_t *)dword_p)[0]) |
((u32_t)le16(&((u16_t *)dword_p)[1]) << 16);
}
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);
}
#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;
};
/* 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) */
/* 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
int read_nlist(filename, nlist_table)
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 */
{
if ((data = elf_getdata(scn, NULL)) == NULL) {
errno = ENOEXEC;
return -1;
}
r= read(exec_fd, (char *)&exec_header, A_MINHDR);
if (r != A_MINHDR)
{
if (r != -1)
errno= ENOEXEC;
nsyms = data->d_size / sizeof(Elf32_Sym);
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;
}
name = elf_strptr(elf, shdr->sh_link, (size_t) sym->st_name);
if ((nlp->n_name = strdup(name ? name : "")) == NULL) {
free(*nlistp);
return -1;
}
}
return nsyms;
}
int read_nlist(const char *filename, struct nlist **nlist_table)
{
/* 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;
}
if (BADMAG(exec_header))
{
errno= ENOEXEC;
if ((fd = open(filename, O_RDONLY)) < 0)
return -1;
elf = elf_begin(fd, ELF_C_READ, NULL);
if (elf == NULL) {
errno = ENOEXEC;
close(fd);
return -1;
}
switch(exec_header.a_cpu & 3)
{
case 0: /* little endian */
cnv32= le32;
cnv16= le16;
scn = NULL;
res = 0;
while ((scn = elf_nextscn(elf, scn)) != NULL) {
if ((shdr = elf32_getshdr(scn)) == NULL)
continue;
if (shdr->sh_type != SHT_SYMTAB)
continue;
res = get_syms(elf, scn, shdr, nlist_table);
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;
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;
}
elf_end(elf);
close(fd);
*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;
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;
}
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
}
return res;
}
/*
* $PchId: read_nlist.c,v 1.5 1996/04/11 07:47:38 philip Exp $
*/

View 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