lkcd
[Top] [All Lists]

Re: module traceback working

To: Dave Craft <dcraft@xxxxxxxxxxxxxx>
Subject: Re: module traceback working
From: Tom Morano <tjm@xxxxxxx>
Date: Thu, 25 Jan 2001 14:15:58 -0800
Cc: lkcd@xxxxxxxxxxx
References: <200101252157.PAA18134@xxxxxxxxxxxxxxxxxxxx>
Sender: owner-lkcd@xxxxxxxxxxx
Hi Dave,

Actually, I am VERY interested in this (since I develop the lcrash utility)
and had started taking a look and then got distracted. I apologize for not,
at least, responding to your original post. I will take a look at the diffs
you've provided with the idea of incorporating them in the tool.

Thanks again for looking further into this and reporting back on your
findings.

Tom

Dave Craft wrote:
> 
> The other day I posted a query regarding how to get trace backs
> in kernel module code with lkcd on the i386.  I'm not sure if anyone is
> interested in this (since I didn't get any responses) but I have
> made a couple of fixes to the baseline code as well as a minor addition
> to get this function to work.  Note this work is just posted herein
> and doesn't represent any work by a lkcd maintainer.  I'm not even saying
> it's suitable for anything other than my own educational purposes.
> 
> I will also append the diff file to the end of this note.  Note that
> this diff is just a rough first stab for my own benefit.  The maintainers
> of lkcd (given that they know the structure better than I) would
> probably want this done differently.
> 
> Basically the changes fall into a couple of categories.
> 
> 1) Bug fixes for page table lookup on the i386:  The KL_PGDIR_SHIFT
>    and KL_PMDIR_SHIFT were wrong for the two level page directory
>    case on the i386.  The pmd_offset() function was also wrong for
>    this case.
> 
> 2) Enhancements to kl_virtop() to understand the vmalloc area:
>    Essentially linux copies an inserted module to the vmalloc area which
>    has an address above the PAGE_OFFSET line (0xc000000 on my machine)
>    but it is also above physical memory.  Thus to get the real physical
>    address for these pages you must use the page directory hung off
>    the "init_mm" memory map struct.  So the changes in this area
>    are just to get the range of the vmalloc area and use the "init_mm"
>    info.
> 
> After you fix this in lcrash you have to run it with a System.map
> that has the additional symbols from your module.  You can get your
> modules symbol table at load time by using the -m option on insmod.
> Note you have to strip out all the extraneous stuff out of this map.
> 
>   cat <module>.map | awk '/ [TtDd] / {print $0}' >> tmp.map
> 
> Then append this to a new COPY of the /boot/System.map and do
> (sort -u) on the file.   You can give lcrash this file as an
> option or just link /boot/System.map to your new symbol file.
> 
> At that point you should be able to do a "bt" on a task that
> has a traceback into module routines.
> 
> If anyone wants to discuss my poor attempt at getting this working
> or the defect fixes, just send me a note.
> 
> Enjoy,
> Dave Craft
> 
> -----------cut here for patch file----------
> diff -Naur lkcd/lkcdutils/libklib/arch/i386/kl_kern.c 
> lkcdmod/lkcdutils/libklib/arch/i386/kl_kern.c
> --- lkcd/lkcdutils/libklib/arch/i386/kl_kern.c  Tue Jan 16 13:52:56 2001
> +++ lkcdmod/lkcdutils/libklib/arch/i386/kl_kern.c       Thu Jan 25 14:29:27 
> 2001
> @@ -11,6 +11,7 @@
>  #ifndef __KERNEL__
>  #define __KERNEL__
>  #include <asm/page.h>
> +#include <asm/fixmap.h>
>  #undef __KERNEL__
>  #else
>  #endif
> @@ -28,6 +29,16 @@
>  #endif
>  kaddr_t MEM_MAP;
> 
> +kaddr_t INIT_MM;
> +kaddr_t KL_VMALLOC_START = 0xFFFFFFFF;
> +kaddr_t KL_VMALLOC_END   = 0xFFFFFFFF;
> +
> +#define VMALLOC_OFFSET  (8*1024*1024)
> +#define VMALLOC_START   (((unsigned long) high_memory + 2*VMALLOC_OFFSET-1) 
> & \
> +                                                ~(VMALLOC_OFFSET-1))
> +#define VMALLOC_END     (FIXADDR_START)
> +
> +
>  /*
>   * kl_init_kern_info()
>   */
> @@ -35,6 +46,7 @@
>  kl_init_kern_info()
>  {
>         syment_t *sp;
> +       kaddr_t high_memory;
> 
>         kl_reset_error();
>         if (!(sp = kl_lkup_symname("num_physpages"))) {
> @@ -51,6 +63,19 @@
>                 return(1);
>         }
>         GET_BLOCK(sp->s_addr, 4, (void*)&MEM_MAP);
> +
> +       if (!(sp = kl_lkup_symname("init_mm"))) {
> +               return(1);
> +       }
> +        /* init_mm is a structure offset and not a pointer */
> +        INIT_MM = sp->s_addr;
> +
> +       if (!(sp = kl_lkup_symname("high_memory"))) {
> +               return(1);
> +       }
> +       GET_BLOCK(sp->s_addr, 4, (void*)&high_memory);
> +       KL_VMALLOC_START = VMALLOC_START;
> +       KL_VMALLOC_END = VMALLOC_END;
> 
>         if (!(sp = kl_lkup_symname("__locore_lmabegin"))) {
>                 return(1);
> diff -Naur lkcd/lkcdutils/libklib/arch/i386/kl_page.c 
> lkcdmod/lkcdutils/libklib/arch/i386/kl_page.c
> --- lkcd/lkcdutils/libklib/arch/i386/kl_page.c  Thu Nov 30 20:53:44 2000
> +++ lkcdmod/lkcdutils/libklib/arch/i386/kl_page.c       Thu Jan 25 14:20:39 
> 2001
> @@ -23,8 +23,8 @@
> 
>  #else /* CONFIG_X86_PAE */
> 
> -#define KL_PGDIR_SHIFT (KL_PAGE_SHIFT+(KL_PAGE_SHIFT-3)*1)
> -#define KL_PMD_SHIFT   (KL_PAGE_SHIFT+(KL_PAGE_SHIFT-3)*1)
> +#define KL_PGDIR_SHIFT (KL_PAGE_SHIFT+(KL_PAGE_SHIFT-2)*1)
> +#define KL_PMD_SHIFT   (KL_PAGE_SHIFT+(KL_PAGE_SHIFT-2)*1)
>  #define KL_PTRS_PER_PGD (1UL<<(KL_PAGE_SHIFT-2))
>  #define KL_PTRS_PER_PMD 1
>  #define KL_PTRS_PER_PTE (1UL<<(KL_PAGE_SHIFT-2))
> @@ -56,7 +56,10 @@
> 
>         return pte_base;
>  #else /* CONFIG_X86_PAE */
> -       return pmd_base;
> +        /* higher level routines are expecting a non virtual address
> +         * offset, which they will add KL_PAGE_OFFSET to.
> +         */
> +       return pmd_base - KL_PAGE_OFFSET;
>  #endif /* CONFIG_X86_PAE */
>  }
> 
> diff -Naur lkcd/lkcdutils/libklib/include/klib.h 
> lkcdmod/lkcdutils/libklib/include/klib.h
> --- lkcd/lkcdutils/libklib/include/klib.h       Wed Dec  6 15:08:13 2000
> +++ lkcdmod/lkcdutils/libklib/include/klib.h    Thu Jan 25 14:34:38 2001
> @@ -84,6 +84,15 @@
>  extern kaddr_t MEM_MAP;
>  extern kaddr_t deftask;
> 
> +#ifdef DEBUG
> +#define DPRINTF(x) fprintf x
> +#else
> +#define DPRINTF(x)
> +#endif
> +extern kaddr_t INIT_MM;
> +extern kaddr_t KL_VMALLOC_START;
> +extern kaddr_t KL_VMALLOC_END;
> +
>  #define KL_ARCH                 lkcdinfo.arch
>  #define KL_PTRSZ                lkcdinfo.ptrsz
>  #define KL_NBPW                 (KL_PTRSZ/8)
> diff -Naur lkcd/lkcdutils/libklib/kl_mem.c lkcdmod/lkcdutils/libklib/kl_mem.c
> --- lkcd/lkcdutils/libklib/kl_mem.c     Thu Nov 30 20:52:16 2000
> +++ lkcdmod/lkcdutils/libklib/kl_mem.c  Thu Jan 25 14:33:52 2001
> @@ -108,9 +108,19 @@
>         if ((KL_ARCH == ARCH_I386) && (vaddr >= KL_LOCORE_START)) {
>                 paddr = (KL_LOCORE_ADDR - KL_PAGE_OFFSET) +
>                                 (vaddr - KL_LOCORE_START);
> -       } else if (vaddr >= KL_PAGE_OFFSET) {
> +       } else if ((vaddr >= KL_PAGE_OFFSET) && (vaddr < KL_VMALLOC_START)) {
>                 paddr = (vaddr - KL_PAGE_OFFSET);
>         } else {
> +               if ((vaddr >= KL_VMALLOC_START) && (vaddr < KL_VMALLOC_END)) {
> +                       mmp = kl_alloc_block(MM_STRUCT_SZ, K_TEMP);
> +                       GET_BLOCK(INIT_MM, MM_STRUCT_SZ, mmp);
> +                       if (KL_ERROR) {
> +                               kl_free_block(mmp);
> +                               mmp = NULL;
> +                       } else {
> +                               mm_alloced++;
> +                       }
> +               }
>                 if (!mmp && deftask) {
>                         tsp = kl_alloc_block(TASK_STRUCT_SZ, K_TEMP);
>                         if (tsp) {
> @@ -149,5 +159,8 @@
>         if (mm_alloced) {
>                 kl_free_block(mmp);
>         }
> +
> +        DPRINTF((KL_ERRORFP, "kl_virtop: vaddr 0x%X paddr 0x%X error 0x%X\n",
> +                vaddr, paddr, KL_ERROR));
>         return(paddr);
>  }

<Prev in Thread] Current Thread [Next in Thread>