1 /* 2 Declaration for Linux kernel compatibility 3 */ 4 5 #include <assert.h> 6 #include <stdarg.h> 7 #include <stdio.h> 8 #include <stdlib.h> 9 #include <sys/types.h> 10 #include <sys/ptrace.h> 11 12 #include "extra.h" 13 14 pid_t victim_pid= -1; 15 char *victim_exe= NULL; 16 17 #define TRAP_BIT (0x80000000) 18 19 static struct nlist *exe_nlist; 20 static int exe_nlist_n; 21 22 void printk(char *fmt, ...) 23 { 24 va_list ap; 25 26 va_start(ap, fmt); 27 vfprintf(stderr, fmt, ap); 28 va_end(ap); 29 } 30 31 int kallsyms_address_to_symbol(db_expr_t off, 32 const char * *mod_name, unsigned long *mod_start, unsigned long *mod_end, 33 const char * *sec_name, unsigned long *sec_start, unsigned long *sec_end, 34 const char * *sym_name, unsigned long *sym_start, unsigned long *sym_end) 35 { 36 static char name[64]; 37 38 int i; 39 unsigned long btext, etext; 40 struct nlist *below, *above; 41 42 off &= ~TRAP_BIT; 43 load_nlist(victim_exe, &btext, &etext); 44 below= above= NULL; 45 for (i= 0; i<exe_nlist_n; i++) 46 { 47 if (exe_nlist[i].n_type != N_TEXT) 48 continue; 49 if (exe_nlist[i].n_value <= off) 50 { 51 if (!below || exe_nlist[i].n_value > below->n_value) 52 below= &exe_nlist[i]; 53 } 54 if (exe_nlist[i].n_value > off) 55 { 56 if (!above || exe_nlist[i].n_value < above->n_value) 57 above= &exe_nlist[i]; 58 } 59 } 60 61 btext |= TRAP_BIT; 62 etext |= TRAP_BIT; 63 64 *mod_name = victim_exe; 65 *mod_start = btext; 66 *mod_end = etext; 67 *sec_name = ".text"; 68 *sec_start = btext; 69 *sec_end = etext; 70 71 assert(below && above); 72 73 strncpy(name, below->n_name, sizeof(name)-1); 74 name[sizeof(name)-1]= '\0'; 75 *sym_name= name; 76 77 *sym_start= below->n_value | TRAP_BIT; 78 *sym_end= above->n_value | TRAP_BIT; 79 80 return 1; 81 } 82 83 unsigned long text_read_ul(void *addr) 84 { 85 int i; 86 unsigned long value; 87 88 for (i= 0; i<sizeof(value); i++) 89 { 90 ((unsigned char *)&value)[i]= text_read_ub((char *)addr+i); 91 } 92 return value; 93 } 94 95 unsigned char text_read_ub(void *addr) 96 { 97 int v; 98 unsigned long vaddr; 99 100 vaddr= (unsigned long)addr; 101 vaddr &= ~TRAP_BIT; 102 v= ptrace(T_READB_INS, victim_pid, (void *)vaddr, 0); 103 if (v < 0) 104 { 105 fprintf(stderr, 106 "text_read_ub: trace T_READB_INS failed on pid %d, addr 0x%lx: %s\n", 107 victim_pid, vaddr, strerror(errno)); 108 exit(1); 109 } 110 return v; 111 } 112 113 void text_write_ul(void *addr, unsigned long value) 114 { 115 int i; 116 117 for (i= 0; i<sizeof(value); i++) 118 { 119 text_write_ub((char *)addr+i, ((unsigned char *)&value)[i]); 120 } 121 } 122 123 void text_write_ub(void *addr, unsigned char value) 124 { 125 int v; 126 unsigned long vaddr; 127 128 vaddr= (unsigned long)addr; 129 vaddr &= ~TRAP_BIT; 130 v= ptrace(T_WRITEB_INS, victim_pid, (void *)vaddr, value); 131 if (v < 0) 132 { 133 fprintf(stderr, 134 "text_read_ub: trace T_WRITEB_INS failed on pid %d, addr 0x%lx: %s\n", 135 victim_pid, vaddr, strerror(errno)); 136 exit(1); 137 } 138 } 139 140 void load_nlist(exe_name, btextp, etextp) 141 char *exe_name; 142 unsigned long *btextp; 143 unsigned long *etextp; 144 { 145 int i; 146 unsigned long btext, etext; 147 148 if (!exe_nlist) 149 { 150 exe_nlist_n= read_nlist(exe_name, &exe_nlist); 151 if (exe_nlist_n <= 0) 152 { 153 if (exe_nlist_n == -1) 154 { 155 fprintf(stderr, 156 "error reading name list from '%s': %s\n", 157 exe_name, strerror(errno)); 158 } 159 else 160 fprintf(stderr, "no name list in '%s'\n", 161 exe_name); 162 exit(1); 163 } 164 } 165 166 if (!btextp && !etextp) 167 return; 168 169 etext= 0; 170 btext= (unsigned long)-1; 171 for (i= 0; i<exe_nlist_n; i++) 172 { 173 if (exe_nlist[i].n_type != N_TEXT) 174 continue; 175 if (exe_nlist[i].n_value < btext) 176 btext= exe_nlist[i].n_value; 177 if (exe_nlist[i].n_value > etext) 178 etext= exe_nlist[i].n_value; 179 } 180 181 if (btext >= etext) 182 { 183 fprintf(stderr, "Bad btext (0x%lx) or etext (0x%lx) in %s\n", 184 btext, etext, exe_name); 185 exit(1); 186 } 187 188 btext |= TRAP_BIT; 189 etext |= TRAP_BIT; 190 191 if (btextp) 192 *btextp= btext; 193 if (etextp) 194 *etextp= etext; 195 } 196