Changeset 41


Ignore:
Timestamp:
Jun 5, 2006, 12:41:56 AM (18 years ago)
Author:
rainer
Message:

Use mmap() if read() fails for /dev/kmem

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/docs/Changelog

    r40 r41  
    112.2.1:
     2        * sh_kern.c: fall back on mmap() if read() fails on /dev/kmem
    23        * fix Solaris package creation
    34        * recognize Solaris doors and event ports
  • trunk/src/kern_head.c

    r9 r41  
    4646#include <limits.h>
    4747#include <sys/utsname.h>
     48#include <sys/mman.h>
    4849
    4950/* number of system calls */
     
    7273static unsigned char system_call_code[SYS_CODE_SIZE];
    7374
     75static int kmem_read (int fd, unsigned long addr, unsigned char * buf, int len)
     76{
     77  if (lseek(fd, addr, SEEK_SET) == (off_t) (-1))
     78    {
     79      if (verbose)
     80        perror("kmem_read: lseek");
     81      return -1;
     82    }
     83  if (read(fd, buf, len) < 0)
     84    {
     85      if (verbose)
     86        perror("kmem_read: read");
     87      return -1;
     88    }
     89  return 0;
     90}
     91
     92static int kmem_mmap (int fd, unsigned long addr, unsigned char * buf, int len)
     93{
     94  size_t    moff, roff;
     95  size_t    sz;
     96  char    * kmap;
     97
     98
     99  /* first, try read()
     100   */
     101  int  ret_old = kmem_read (fd, addr, buf, len);
     102
     103  if (ret_old == 0)
     104    return ret_old;
     105
     106  if (verbose)
     107    fprintf(stderr,
     108            "kmem_mmap: read() from /dev/kmem failed, now trying mmap()\n");
     109
     110  sz = getpagesize(); /* unistd.h */
     111
     112  moff = ((size_t)(addr/sz)) * sz;                 /* lower page boundary */
     113  roff = addr - moff;    /* off relative to lower address of mmapped area */
     114  kmap = mmap(0, len+sz, PROT_READ, MAP_PRIVATE, fd, moff);/* sys/mman.h */
     115
     116  if (kmap == MAP_FAILED)
     117    {
     118      perror("kmem_mmap: mmap");
     119      return -1;
     120    }
     121  memcpy (buf, &kmap[roff], len);
     122     
     123  if (munmap(kmap, len+sz) != 0)
     124    {
     125      perror("kmem_mmap: munmap");
     126      return -1;
     127    }
     128
     129  return 0;
     130}
     131
    74132int read_kcode (unsigned long addr, unsigned char * buf, int len)
    75133{
     
    88146      return -1;
    89147    }
    90   if (lseek(fd, addr, SEEK_SET) == (off_t) (-1))
    91     {
    92       perror("read_kcode: lseek");
    93       return -1;
    94     }
    95   if (read(fd, buf, len) < 0)
    96     {
    97       perror("read_kcode: read");
    98       return -1;
    99     }
     148  if (kmem_mmap(fd, addr, buf, len) < 0)
     149    {
     150      close (fd);
     151      return -1;
     152    }
     153  close (fd);
    100154  return 0;
    101155}
  • trunk/src/sh_kern.c

    r34 r41  
    3939#include <sys/wait.h>
    4040#include <signal.h>
     41#include <sys/mman.h>
    4142
    4243
     
    475476#endif
    476477
     478static int sh_kern_kmem_read (int fd, unsigned long addr,
     479                              unsigned char * buf, int len)
     480{
     481  if (lseek(fd, addr, SEEK_SET) == (off_t) (-1))
     482    {
     483      return -1;
     484    }
     485  if (read(fd, buf, len) < 0)
     486    {
     487      return -1;
     488    }
     489  return 0;
     490}
     491
     492static int sh_kern_read_data (int fd, unsigned long addr,
     493                              unsigned char * buf, size_t len)
     494{
     495  size_t    moff, roff;
     496  size_t    sz;
     497  char    * kmap;
     498
     499  /* first, try read()
     500   */
     501  if (0 == sh_kern_kmem_read (fd, addr, buf, len))
     502    return 0;
     503
     504  /* next, try mmap()
     505   */
     506  sz = getpagesize(); /* unistd.h */
     507
     508  moff = ((size_t)(addr/sz)) * sz;                 /* lower page boundary */
     509  roff = addr - moff;    /* off relative to lower address of mmapped area */
     510
     511  kmap = mmap(0, len+sz, PROT_READ, MAP_PRIVATE, fd, moff);/* sys/mman.h */
     512
     513  if (kmap == MAP_FAILED)
     514    {
     515      return -1;
     516    }
     517  memcpy (buf, &kmap[roff], len);
     518  return munmap(kmap, len+sz);
     519}
     520
    477521int sh_kern_check_internal ()
    478522{
     
    617661          if(status == 0)
    618662            {
    619               if(lseek(kd, (off_t)kaddr, SEEK_SET) == -1)
     663              retry_msleep (0, ShKernDelay); /* milliseconds */
     664             
     665              if (sh_kern_read_data (kd, kaddr,
     666                                     (unsigned char *) &kmem_call_table,
     667                                     sizeof(kmem_call_table)))
    620668                {
    621669                  status = -2;
    622                 }
    623             }
    624           if(status == 0)
    625             {
    626               retry_msleep (0, ShKernDelay); /* milliseconds */
    627               if (sizeof(kmem_call_table) !=
    628                   read(kd, &kmem_call_table, sizeof(kmem_call_table)))
    629                 {
    630                   status = -3;
    631670                }
    632671            }
     
    655694                      (sh.flag.update == S_TRUE))
    656695                    {
    657                       lseek (kd, kmem_call_table[j], SEEK_SET);
     696                      sh_kern_read_data (kd, kmem_call_table[j],
     697                                         (unsigned char *) &(kmem_code_table[j][0]),
     698                                         2 * sizeof(unsigned int));
    658699                    }
    659700                  else
    660701                    {
    661                       lseek (kd, sh_syscalls[j].addr, SEEK_SET);
     702                      sh_kern_read_data (kd, sh_syscalls[j].addr,
     703                                         (unsigned char *) &(kmem_code_table[j][0]),
     704                                         2 * sizeof(unsigned int));
    662705                    }
    663                   read  (kd, &(kmem_code_table[j][0]),
    664                          2 * sizeof(unsigned int));
    665706                }
    666707            }
     
    683724
    684725              memset(sh_idt_table, '\0', SH_MAXIDT*8);
    685               lseek (kd, idt_addr, SEEK_SET);
    686               read  (kd, sh_idt_table, idt_size*8);
     726              sh_kern_read_data (kd, idt_addr,
     727                                 (unsigned char *) sh_idt_table, idt_size*8);
    687728            }
    688729#endif
     
    696737          if(status == 0)
    697738            {
    698               lseek (kd, system_call_addr, SEEK_SET);
    699               read  (kd, new_system_call_code, 256);
     739              sh_kern_read_data (kd, system_call_addr,
     740                                 (unsigned char *) new_system_call_code, 256);
    700741            }
    701742
     
    708749          if(status == 0)
    709750            {
    710               lseek (kd, proc_root, SEEK_SET);
    711               read  (kd, &proc_root_dir, sizeof(proc_root_dir));
    712               lseek (kd, proc_root_iops, SEEK_SET);
    713               read  (kd, &proc_root_inode, sizeof(proc_root_inode));
     751              sh_kern_read_data (kd, proc_root,
     752                                 (unsigned char *) &proc_root_dir,
     753                                 sizeof(proc_root_dir));
     754              sh_kern_read_data (kd, proc_root_iops,
     755                                 (unsigned char *) &proc_root_inode,
     756                                 sizeof(proc_root_inode));
    714757            }
    715758#endif
Note: See TracChangeset for help on using the changeset viewer.