⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ksym.c

📁 linux下获取一些环境信息的代码
💻 C
📖 第 1 页 / 共 2 页
字号:
    }  }  if(0){bad_alloc:    fprintf(stderr, "Warning: not enough memory available\n");  }  if(0){bad_parse:    fprintf(stderr, "Warning: "KSYMS_FILENAME" not normal\n");  }quiet_goodbye:  idx_room = 0;  if(ksyms_data) free(ksyms_data) , ksyms_data = NULL;  ksyms_room = 0;  if(ksyms_index) free(ksyms_index) , ksyms_index = NULL;  ksyms_count = 0;  return 0;}/*********************************/#define VCNT 16static int sysmap_mmap(const char *restrict const filename, message_fn message) {  struct stat sbuf;  char *endp;  int fd;  char Version[32];  fd = open(filename, O_RDONLY|O_NOCTTY|O_NONBLOCK);  if(fd<0) return 0;  if(fstat(fd, &sbuf) < 0) goto bad_open;  if(!S_ISREG(sbuf.st_mode)) goto bad_open;  if(sbuf.st_size < 5000) goto bad_open;  /* if way too small */  /* Would be shared read-only, but we want '\0' after each name. */  endp = mmap(0, sbuf.st_size + 1, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);  sysmap_data = endp;  while(*endp==' '){  /* damn Alpha machine types */    if(strncmp(endp,"                 w ", 19)) goto bad_parse;    endp += 19;    endp = strchr(endp,'\n');    if(!endp) goto bad_parse;   /* no newline */    if(strncmp(endp-3, "_mv\n", 4)) goto bad_parse;    endp++;  }  if(sysmap_data == (caddr_t) -1) goto bad_open;  close(fd);  fd = -1;  sprintf(Version, "Version_%d", linux_version_code);  sysmap_room = 512;  for(;;){    void *vp;    sysmap_room *= 2;    vp = realloc(sysmap_index, sizeof(symb)*sysmap_room);    if(!vp) goto bad_alloc;    sysmap_index = vp;    for(;;){      char *vstart;      if(endp - sysmap_data >= sbuf.st_size){   /* if we reached the end */        int i = VCNT;            /* check VCNT times to verify this file */        if(*Version) goto bad_version;        if(!ksyms_index) return 1; /* if can not verify, assume success */        while(i--){#if 1          const symb *findme;          const symb *map_symb;          /* Choose VCNT entries from /proc/ksyms to test */          findme = ksyms_index + (ksyms_count*i/VCNT);          /* Search for them in the System.map */          map_symb = search(findme->addr, sysmap_index, sysmap_count);          if(map_symb){            if(map_symb->addr != findme->addr) continue;            /* backup to first matching address */            while (map_symb != sysmap_index){              if (map_symb->addr != (map_symb-1)->addr) break;              map_symb--;            }            /* search for name in symbols with same address */            while (map_symb != (sysmap_index+sysmap_count)){              if (map_symb->addr != findme->addr) break;              if (!strcmp(map_symb->name,findme->name)) goto good_match;              map_symb++;            }            map_symb--; /* backup to last symbol with matching address */            message("{%s} {%s}\n",map_symb->name,findme->name);            goto bad_match;          }good_match:;#endif        }        return 1; /* success */      }      sysmap_index[sysmap_count].addr = STRTOUKL(endp, &endp, 16);      if(*endp != ' ') goto bad_parse;      endp++;      if(!strchr(SYMBOL_TYPE_CHARS, *endp)) goto bad_parse;      endp++;      if(*endp != ' ') goto bad_parse;      endp++;      vstart = endp;      endp = strchr(endp,'\n');      if(!endp) goto bad_parse;   /* no newline */      *endp = '\0';      ++endp;      vstart = chop_version(vstart);      sysmap_index[sysmap_count].name = vstart;      if(*vstart=='V' && *Version && !strcmp(Version,vstart)) *Version='\0';      if(++sysmap_count >= sysmap_room) break;  /* need more space */    }  }  if(0){bad_match:    message("Warning: %s does not match kernel data.\n", filename);  }  if(0){bad_version:    message("Warning: %s has an incorrect kernel version.\n", filename);  }  if(0){bad_alloc:    message("Warning: not enough memory available\n");  }  if(0){bad_parse:    message("Warning: %s not parseable as a System.map\n", filename);  }  if(0){bad_open:    message("Warning: %s could not be opened as a System.map\n", filename);  }  sysmap_room=0;  sysmap_count=0;  if(sysmap_index) free(sysmap_index);  sysmap_index = NULL;  if(fd>=0) close(fd);  if(sysmap_data) munmap(sysmap_data, sbuf.st_size + 1);  sysmap_data = NULL;  return 0;}/*********************************/static void read_and_parse(void){  static time_t stamp;    /* after data gets old, load /proc/ksyms again */  if(time(NULL) != stamp){    read_file(KSYMS_FILENAME, &ksyms_data, &ksyms_room);    parse_ksyms();    memset((void*)hashtable,0,sizeof(hashtable)); /* invalidate cache */    stamp = time(NULL);  }}/*********************************/static void default_message(const char *restrict format, ...) __attribute__((format(printf,1,2)));static void default_message(const char *restrict format, ...) {    va_list arg;    va_start (arg, format);    vfprintf (stderr, format, arg);    va_end (arg);}/*********************************/static int use_wchan_file;int open_psdb_message(const char *restrict override, message_fn message) {  static const char *sysmap_paths[] = {    "/boot/System.map-%s",    "/boot/System.map",    "/lib/modules/%s/System.map",    "/usr/src/linux/System.map",    "/System.map",    NULL  };  struct stat sbuf;  struct utsname uts;  char path[128];  const char **fmt = sysmap_paths;  const char *sm;#ifdef SYSMAP_FILENAME    /* debug feature */  override = SYSMAP_FILENAME;#endif  // first allow for a user-selected System.map file  if(    (sm=override)    ||    (sm=getenv("PS_SYSMAP"))    ||    (sm=getenv("PS_SYSTEM_MAP"))  ){    if(!have_privs){      read_and_parse();      if(sysmap_mmap(sm, message)) return 0;    }    /* failure is better than ignoring the user & using bad data */    return -1;           /* ought to return "Namelist not found." */  }  // next try the Linux 2.5.xx method  if(!stat("/proc/self/wchan", &sbuf)){    use_wchan_file = 1; // hack    return 0;  }  // finally, search for the System.map file  uname(&uts);  path[sizeof path - 1] = '\0';  do{    int did_ksyms = 0;    snprintf(path, sizeof path - 1, *fmt, uts.release);    if(!stat(path, &sbuf)){      if (did_ksyms++) read_and_parse();      if (sysmap_mmap(path, message)) return 0;    }  }while(*++fmt);  /* TODO: Without System.map, no need to keep ksyms loaded. */  return -1;}/***************************************/int open_psdb(const char *restrict override) {    return open_psdb_message(override, default_message);}/***************************************/static const char * read_wchan_file(unsigned pid){  static char buf[64];  const char *ret = buf;  ssize_t num;  int fd;  snprintf(buf, sizeof buf, "/proc/%d/wchan", pid);  fd = open(buf, O_RDONLY);  if(fd==-1) return "?";  num = read(fd, buf, sizeof buf - 1);  close(fd);  if(num<1) return "?"; // allow for "0"  buf[num] = '\0';  if(buf[0]=='0' && buf[1]=='\0') return "-";  // would skip over numbers if they existed -- but no  // lame ppc64 has a '.' in front of every name  if(*ret=='.') ret++;  switch(*ret){    case 's': if(!strncmp(ret, "sys_", 4)) ret += 4;   break;    case 'd': if(!strncmp(ret, "do_",  3)) ret += 3;   break;    case '_': while(*ret=='_') ret++;                  break;  }  return ret;}/***************************************/static const symb fail = { .name = "?" };static const char dash[] = "-";static const char star[] = "*";#define MAX_OFFSET (0x1000*sizeof(long))  /* past this is generally junk *//* return pointer to temporary static buffer with function name */const char * lookup_wchan(unsigned KLONG address, unsigned pid) {  const symb *mod_symb;  const symb *map_symb;  const symb *good_symb;  const char *ret;  unsigned hash;  // can't cache it due to a race condition :-(  if(use_wchan_file) return read_wchan_file(pid);  if(!address)  return dash;  if(!~address) return star;  read_and_parse();  hash = (address >> 4) & 0xff;  /* got 56/63 hits & 7/63 misses */  if(hashtable[hash].addr == address) return hashtable[hash].name;  mod_symb = search(address, ksyms_index,  ksyms_count);  if(!mod_symb) mod_symb = &fail;  map_symb = search(address, sysmap_index, sysmap_count);  if(!map_symb) map_symb = &fail;  /* which result is closest? */  good_symb = (mod_symb->addr > map_symb->addr)            ? mod_symb            : map_symb  ;  if(address > good_symb->addr + MAX_OFFSET) good_symb = &fail;  /* good_symb->name has the data, but needs to be trimmed */  ret = good_symb->name;  // lame ppc64 has a '.' in front of every name  if(*ret=='.') ret++;  switch(*ret){    case 's': if(!strncmp(ret, "sys_", 4)) ret += 4;   break;    case 'd': if(!strncmp(ret, "do_",  3)) ret += 3;   break;    case '_': while(*ret=='_') ret++;                  break;  }  /* if(!*ret) ret = fail.name; */  /* not likely (name was "sys_", etc.) */  /* cache name after abbreviation */  hashtable[hash].addr = address;  hashtable[hash].name = ret;  return ret;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -