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

📄 ksym.c

📁 linux下获取一些环境信息的代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright 1998-2003 by Albert Cahalan; all rights reserved. * This file may be used subject to the terms and conditions of the * GNU Library General Public License Version 2, or any later version * at your option, as published by the Free Software Foundation. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <time.h>#include <stdarg.h>#include <fcntl.h>#include <errno.h>#include <unistd.h>#include <sys/stat.h>#include <sys/mman.h>#include <sys/utsname.h>#include "procps.h"#include "version.h"#include "sysinfo.h" /* smp_num_cpus */#include "wchan.h"  // to verify prototypes#define KSYMS_FILENAME "/proc/ksyms"#if 0#undef KSYMS_FILENAME#define KSYMS_FILENAME  "/would/be/nice/to/have/this/file"#define SYSMAP_FILENAME "/home/albert/ps/45621/System.map-hacked"#define linux_version_code 131598 /* ? */#define smp_num_cpus 2#endif#if 0#undef KSYMS_FILENAME#define KSYMS_FILENAME  "/home/albert/ps/45621/ksyms-2.3.12"#define SYSMAP_FILENAME "/home/albert/ps/45621/System.map-2.3.12"#define linux_version_code 131852 /* 2.3.12 */#define smp_num_cpus 2#endif#if 0#undef KSYMS_FILENAME#define KSYMS_FILENAME  "/home/albert/ps/45621/ksyms-2.3.18ac8-MODVERS"#define SYSMAP_FILENAME "/home/albert/ps/45621/System.map-2.3.18ac8-MODVERS"#define linux_version_code 131858 /* 2.3.18ac8 */#define smp_num_cpus 2#endif#if 0#undef KSYMS_FILENAME#define KSYMS_FILENAME  "/home/albert/ps/45621/ksyms-2.3.18ac8-NOMODVERS"#define SYSMAP_FILENAME "/home/albert/ps/45621/System.map-2.3.18ac8-NOMODVERS"#define linux_version_code 131858 /* 2.3.18ac8 */#define smp_num_cpus 2#endif/* These are the symbol types, with relative popularity: *     ? w  machine type junk for Alpha -- odd syntax *     ? S  not for i386 *     4 W  not for i386 *    60 R *   100 A *   125 r *   363 s  not for i386 *   858 B *   905 g  generated by modutils? *   929 G  generated by modutils? *  1301 b *  2750 D *  4481 d * 11417 ? * 13666 t * 15442 T * * For i386, that is: "RArBbDd?tT" */#define SYMBOL_TYPE_CHARS "Tt?dDbBrARGgsWS"/* * '?' is a symbol type * '.' is part of a name (versioning?) * "\t[]" are for the module name in /proc/ksyms */#define LEGAL_SYSMAP_CHARS "0123456789_ ?.\n\t[]" \                     "abcdefghijklmnopqrstuvwxyz" \                     "ABCDEFGHIJKLMNOPQRSTUVWXYZ"/* System.map lines look like: * hex num, space, one of SYMBOL_TYPE_CHARS, space, LEGAL_SYSMAP_CHARS, \n * * Alpha systems can start with a few lines that have the address replaced * by space padding and a 'w' for the type. For those lines, the last space * is followed by something like: mikasa_primo_mv p2k_mv sable_gamma_mv * (just one of those, always with a "_mv", then the newline) * * The /proc/ksyms lines are like System.map lines w/o the symbol type char. * When odd features are used, the name part contains: * "(.*)_R(smp_|smp2gig_|2gig_)?[0-9a-fA-F]{8,}" * It is likely that more crap will be added... */typedef struct symb {  unsigned KLONG addr;  const char *name;} symb;/* These mostly rely on POSIX to make them zero. */static symb hashtable[256];static char       *sysmap_data;static unsigned    sysmap_room;static symb       *sysmap_index;static unsigned    sysmap_count;static char       *ksyms_data;static unsigned    ksyms_room     = 4096;static symb       *ksyms_index;static unsigned    ksyms_count;static unsigned    idx_room;/*********************************//* Kill this:  _R(smp_?|smp2gig_?|2gig_?)?[0-9a-f]{8,}$ * We kill:    (_R[^A-Z]*[0-9a-f]{8,})+$ * * The loop should almost never be taken, but it has to be there. * It gets rid of anything that _looks_ like a version code, even * if a real version code has already been found. This is because * the inability to perfectly recognize a version code may lead to * symbol mangling, which in turn leads to mismatches between the * /proc/ksyms and System.map data files. */#if 0static char *chop_version(char *arg){  char *cp;  cp = strchr(arg,'\t');  if(cp) *cp = '\0';  /* kill trailing module name first */  for(;;){    char *p;    int len = 0;    cp = strrchr(arg, 'R');    if(!cp || cp<=arg+1 || cp[-1]!='_') break;    for(p=cp; *++p; ){      switch(*p){      default:        goto out;      case '0' ... '9':      case 'a' ... 'f':        len++;        continue;      case 'g' ... 'z':      case '_':        len=0;        continue;      }    }    if(len<8) break;    cp[-1] = '\0';  }out:  if(*arg=='G'){    int len = strlen(arg);    while( len>8 && !memcmp(arg,"GPLONLY_",8) ){      arg += 8;      len -= 8;    }  }  return arg;}#endifstatic char *chop_version(char *arg){  char *cp;  cp = strchr(arg,'\t');  if(cp) *cp = '\0';  /* kill trailing module name first */  for(;;){    int len;    cp = strrchr(arg, 'R');    if(!cp || cp<=arg+1 || cp[-1]!='_') break;    len=strlen(cp);    if(len<9) break;    if(strpbrk(cp+1,"ABCDEFGHIJKLMNOPQRSTUVWXYZ")) break;    if(strspn(cp+len-8,"0123456789abcdef")!=8) break;    cp[-1] = '\0';  }  if(*arg=='G'){    int len = strlen(arg);    while( len>8 && !memcmp(arg,"GPLONLY_",8) ){      arg += 8;      len -= 8;    }  }  return arg;}/***********************************/static const symb *search(unsigned KLONG address, symb *idx, unsigned count){  unsigned left;  unsigned mid;  unsigned right;  if(!idx) return NULL;   /* maybe not allocated */  if(address < idx[0].addr) return NULL;  if(address >= idx[count-1].addr) return idx+count-1;  left  = 0;  right = count-1;  for(;;){    mid = (left + right) / 2;    if(address >= idx[mid].addr) left  = mid;    if(address <= idx[mid].addr) right = mid;    if(right-left <= 1) break;  }  if(address == idx[right].addr) return idx+right;  return idx+left;}/*********************************//* allocate if needed, read, and return buffer size */static void read_file(const char *restrict filename, char **bufp, unsigned *restrict roomp) {  int fd = 0;  ssize_t done;  char *buf = *bufp;  ssize_t total = 0;  unsigned room = *roomp;  if(!room) goto hell;     /* failed before */  if(!buf) buf = malloc(room);  if(!buf) goto hell;open_again:  fd = open(filename, O_RDONLY|O_NOCTTY|O_NONBLOCK);  if(fd<0){    switch(errno){    case EINTR:  goto open_again;    default:     _exit(101);    case EACCES:   /* somebody screwing around? */      /* FIXME: set a flag to disable symbol lookup? */    case ENOENT:;  /* no module support */    }    goto hell;  }  for(;;){    done = read(fd, buf+total, room-total-1);    if(done==0) break;  /* nothing left */    if(done==-1){      if(errno==EINTR) continue;  /* try again */      perror("");      goto hell;    }    if(done==(ssize_t)room-total-1){      char *tmp;      total += done;      /* more to go, but no room in buffer */      room *= 2;      tmp = realloc(buf, room);      if(!tmp) goto hell;      buf = tmp;      continue;    }    if(done>0 && done<(ssize_t)room-total-1){      total += done;       continue;   /* OK, we read some. Go do more. */    }    fprintf(stderr,"%ld can't happen\n", (long)done);    /* FIXME: memory leak */    _exit(42);  }  buf[total] = '\0';   // parse_ksyms() expects NUL-terminated file  *bufp = buf;  *roomp = room;  close(fd);  return;hell:  if(buf) free(buf);  *bufp = NULL;  *roomp = 0;   /* this function will never work again */  total = 0;  if(fd>0) close(fd);  return;}/*********************************/static int parse_ksyms(void) {  char *endp;  if(!ksyms_room || !ksyms_data) goto quiet_goodbye;  endp = ksyms_data;  ksyms_count = 0;  if(idx_room) goto bypass;  /* some space already allocated */  idx_room = 512;  for(;;){    void *vp;    idx_room *= 2;    vp = realloc(ksyms_index, sizeof(symb)*idx_room);    if(!vp) goto bad_alloc;    ksyms_index = vp;bypass:    for(;;){      char *saved;      if(!*endp) return 1;      saved = endp;      ksyms_index[ksyms_count].addr = STRTOUKL(endp, &endp, 16);      if(endp==saved || *endp != ' ') goto bad_parse;      endp++;      saved = endp;      endp = strchr(endp,'\n');      if(!endp) goto bad_parse;   /* no newline */      *endp = '\0';      ksyms_index[ksyms_count].name = chop_version(saved);      ++endp;      if(++ksyms_count >= idx_room) break;  /* need more space */

⌨️ 快捷键说明

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