Sorry for late reply but I'm just back from vacation.

On Thu, Sep 30, 2010 at 10:54:34AM -0400, Dave Anderson wrote:
> 
> ----- "Hu Tao" <[email protected]> wrote:
> 
> > Hi Dave,
> > 
> >    When I was investigating the backtrace problem(crash doesn't show
> >    some functions from backtrace output), I found the reason was that
> >    there was a dead-looping(or anything that would block module init
> >    function) in module init function, in which case kernel had no chance
> >    to update mod->symtab from mod->core_symtab, and mod->symtab was
> >    still referring into the module init section which was not freed
> >    until the end of module init function.
> > 
> >    Since crash never searches module init function for symbols, in the
> >    case we can't see any symbol from module from the backtrace output.
> > 
> >    Following patch makes crash search the module init section for
> >    symbols too if the section is not null.
> 
> This is a pretty adventurous patch, but it looks pretty good.
> 
> Given that your new module init code is pretty much segregated based
> upon the setting of lm->mod_init_size, it shouldn't break the handling
> of normal "post-init" modules.
> 
> A few minor issues:
> 
> # touch symbols.c
> # make warn
> cc -c -g -DX86_64   symbols.c -DGDB_7_0 -I./gdb-7.0/bfd -I./gdb-7.0/include 
> -Wall -O2 -Wstrict-prototypes -Wmissing-prototypes -fstack-protector 
> -Wp,-D_FORTIFY_SOURCE=2 
> symbols.c:3651: warning: no previous prototype for ‘value_search_module’
> symbols.c: In function ‘value_search’:
> symbols.c:3734: warning: unused variable ‘lm’
> symbols.c:3733: warning: unused variable ‘splast’
> symbols.c:3733: warning: unused variable ‘sp_end’
> symbols.c:3732: warning: unused variable ‘i’
> #
> 
> Also, I'm wondering why you felt it necessary to make two
> calls to the new value_search_module() function here in
> value_search():
> 
> check_modules:
>         sp = value_search_module(value, offset, 0);
>         if (!sp)
>                 sp = value_search_module(value, offset, 1);
> 
> What I would suggest is this:
> 
> (1) If during initialization it is seen that a module's init symbols are
>     still in place, then set a new "MOD_INIT" flag in lm->mod_flags.
> (2) Then, if value_search_module() cannot find a symbol in the 
> lm->mod_symtable,
>     it could check lm->mod_flags for the MOD_INIT flag, and then go back and
>     retry the search in the lm->mod_init_symtable.
> 
> If it were done that way, I can envision making value_search_module()
> exportable, and it would not require the caller to make the "0/1" argument
> decision.

Thanks for suggestion. Attached files are two patches that:

1. remove compile warnings.
2. add a flag MOD_INIT if module init symbols are present.

These two patches are in order and on top of previous patch I sent.

> 
> Dave
> 
> 
>  
> 
> > 
> > -- 
> > Thanks,
> > Hu Tao
> > 
> > diff --git a/defs.h b/defs.h
> > index d431d6e..0fe9d48 100755
> > --- a/defs.h
> > +++ b/defs.h
> > @@ -1515,6 +1515,7 @@ struct offset_table {                    /*
> > stash of commonly-used offsets */
> >     long mm_struct_rss_stat;
> >     long mm_rss_stat_count;
> >     long module_module_init;
> > +   long module_init_size;
> >     long module_init_text_size;
> >     long cpu_context_save_fp;
> >     long cpu_context_save_sp;
> > @@ -2038,6 +2039,8 @@ struct load_module {
> >          ulong mod_flags;
> >     struct syment *mod_symtable;
> >     struct syment *mod_symend;
> > +   struct syment *mod_init_symtable;
> > +   struct syment *mod_init_symend;
> >          long mod_ext_symcnt;
> >     struct syment *mod_ext_symtable;
> >     struct syment *mod_ext_symend;
> > @@ -2054,6 +2057,7 @@ struct load_module {
> >     ulong mod_bss_start;
> >     int mod_sections;
> >     struct mod_section_data *mod_section_data;
> > +        ulong mod_init_size;
> >          ulong mod_init_text_size;
> >          ulong mod_init_module_ptr;
> >  };
> > @@ -2061,6 +2065,9 @@ struct load_module {
> >  #define IN_MODULE(A,L) \
> >   (((ulong)(A) >= (L)->mod_base) && ((ulong)(A) <
> > ((L)->mod_base+(L)->mod_size)))
> >  
> > +#define IN_MODULE_INIT(A,L) \
> > + (((ulong)(A) >= (L)->mod_init_module_ptr) && ((ulong)(A) <
> > ((L)->mod_init_module_ptr+(L)->mod_init_size)))
> > +
> >  #ifndef GDB_COMMON
> >  
> >  #define KVADDR             (0x1)
> > diff --git a/kernel.c b/kernel.c
> > index 5dc2c45..a50882a 100755
> > --- a/kernel.c
> > +++ b/kernel.c
> > @@ -2691,6 +2691,7 @@ module_init(void)
> >             MEMBER_OFFSET_INIT(module_core_text_size, "module", 
> >                     "core_text_size");
> >             MEMBER_OFFSET_INIT(module_module_init, "module", "module_init");
> > +           MEMBER_OFFSET_INIT(module_init_size, "module", "init_size");
> >             MEMBER_OFFSET_INIT(module_init_text_size, "module", 
> >                     "init_text_size");
> >  
> > diff --git a/symbols.c b/symbols.c
> > index c373668..f1c308e 100755
> > --- a/symbols.c
> > +++ b/symbols.c
> > @@ -884,10 +884,13 @@ symname_hash_search(char *name)
> >   */
> >  
> >  #define MODULE_PSEUDO_SYMBOL(sp) \
> > -    (STRNEQ((sp)->name, "_MODULE_START_") || STRNEQ((sp)->name,
> > "_MODULE_END_"))
> > +    ((STRNEQ((sp)->name, "_MODULE_START_") || STRNEQ((sp)->name,
> > "_MODULE_END_")) || \
> > +    (STRNEQ((sp)->name, "_MODULE_INIT_START_") || STRNEQ((sp)->name,
> > "_MODULE_INIT_END_")))
> >  
> >  #define MODULE_START(sp) (STRNEQ((sp)->name, "_MODULE_START_"))
> >  #define MODULE_END(sp)   (STRNEQ((sp)->name, "_MODULE_END_"))
> > +#define MODULE_INIT_START(sp) (STRNEQ((sp)->name,
> > "_MODULE_INIT_START_"))
> > +#define MODULE_INIT_END(sp)   (STRNEQ((sp)->name,
> > "_MODULE_INIT_END_"))
> >  
> >  static void
> >  symbol_dump(ulong flags, char *module)
> > @@ -927,6 +930,26 @@ symbol_dump(ulong flags, char *module)
> >                     } else
> >                             show_symbol(sp, 0, SHOW_RADIX());
> >                  }
> > +
> > +           if (lm->mod_init_symtable) {
> > +                   sp = lm->mod_init_symtable;
> > +                   sp_end = lm->mod_init_symend;
> > +
> > +                   for ( ; sp <= sp_end; sp++) {
> > +                           if (MODULE_PSEUDO_SYMBOL(sp)) {
> > +                                   if (MODULE_INIT_START(sp)) {
> > +                                           p1 = "MODULE INIT START";
> > +                                           p2 = 
> > sp->name+strlen("_MODULE_INIT_START_");
> > +                                   } else {
> > +                                           p1 = "MODULE INIT END";
> > +                                           p2 = 
> > sp->name+strlen("_MODULE_INIT_END_");
> > +                                   }
> > +                                   fprintf(fp, "%lx %s: %s\n", sp->value, 
> > p1, p2);
> > +                           } else
> > +                                   show_symbol(sp, 0, SHOW_RADIX());
> > +                   }
> > +           }
> > +
> >     }
> >  }
> >  
> > @@ -1244,6 +1267,8 @@ store_module_symbols_v2(ulong total, int
> > mods_installed)
> >     struct load_module *lm;
> >     char buf1[BUFSIZE];
> >     char buf2[BUFSIZE];
> > +   char buf3[BUFSIZE];
> > +   char buf4[BUFSIZE];
> >     char *strbuf, *modbuf, *modsymbuf;
> >     struct syment *sp;
> >     ulong first, last;
> > @@ -1326,11 +1351,15 @@ store_module_symbols_v2(ulong total, int
> > mods_installed)
> >             if (THIS_KERNEL_VERSION >= LINUX(2,6,27)) {
> >                     lm->mod_etext_guess = lm->mod_base +
> >                             UINT(modbuf + OFFSET(module_core_text_size));
> > +                   lm->mod_init_size =
> > +                           UINT(modbuf + OFFSET(module_init_size));
> >                     lm->mod_init_text_size = 
> >                             UINT(modbuf + OFFSET(module_init_text_size));
> >             } else {
> >                     lm->mod_etext_guess = lm->mod_base +
> >                             ULONG(modbuf + OFFSET(module_core_text_size));
> > +                   lm->mod_init_size =
> > +                           ULONG(modbuf + OFFSET(module_init_size));
> >                     lm->mod_init_text_size = 
> >                             ULONG(modbuf + OFFSET(module_init_text_size));
> >             }
> > @@ -1344,6 +1373,18 @@ store_module_symbols_v2(ulong total, int
> > mods_installed)
> >             lm_mcnt = mcnt;
> >             mcnt++;
> >  
> > +           if (lm->mod_init_size > 0) {
> > +                   st->ext_module_symtable[mcnt].value = 
> > lm->mod_init_module_ptr;
> > +                   st->ext_module_symtable[mcnt].type = 'm';
> > +                   sprintf(buf3, "%s%s", "_MODULE_INIT_START_", mod_name);
> > +                   namespace_ctl(NAMESPACE_INSTALL, 
> > +                                   &st->ext_module_namespace,
> > +                                   &st->ext_module_symtable[mcnt], buf3);
> > +                   lm_mcnt = mcnt;
> > +                   mcnt++;
> > +           }
> > +
> > +
> >             if (nsyms && !IN_MODULE(syms, lm)) {
> >                     error(WARNING, 
> >                         "[%s] module.syms outside of module "
> > @@ -1520,6 +1561,16 @@ store_module_symbols_v2(ulong total, int
> > mods_installed)
> >                          &st->ext_module_symtable[mcnt], buf2);
> >             mcnt++;
> >  
> > +           if (lm->mod_init_size > 0) {
> > +                   st->ext_module_symtable[mcnt].value = 
> > lm->mod_init_module_ptr +
> > lm->mod_init_size;
> > +                   st->ext_module_symtable[mcnt].type = 'm';
> > +                   sprintf(buf4, "%s%s", "_MODULE_INIT_END_", mod_name);
> > +                   namespace_ctl(NAMESPACE_INSTALL, 
> > +                                   &st->ext_module_namespace,
> > +                                   &st->ext_module_symtable[mcnt], buf4);
> > +                   mcnt++;
> > +           }
> > +
> >             lm->mod_ext_symcnt = mcnt - lm->mod_ext_symcnt;
> >  
> >             if (!lm->mod_etext_guess)
> > @@ -1545,6 +1596,8 @@ store_module_symbols_v2(ulong total, int
> > mods_installed)
> >                  lm = &st->load_modules[m];
> >             sprintf(buf1, "_MODULE_START_%s", lm->mod_name);
> >             sprintf(buf2, "_MODULE_END_%s", lm->mod_name);
> > +           sprintf(buf3, "_MODULE_INIT_START_%s", lm->mod_name);
> > +           sprintf(buf4, "_MODULE_INIT_END_%s", lm->mod_name);
> >  
> >             for (sp = st->ext_module_symtable; 
> >                  sp < st->ext_module_symend; sp++) {
> > @@ -1556,6 +1609,12 @@ store_module_symbols_v2(ulong total, int
> > mods_installed)
> >                             lm->mod_ext_symend = sp;
> >                             lm->mod_symend = sp;
> >                     }
> > +                   if (STREQ(sp->name, buf3)) {
> > +                           lm->mod_init_symtable = sp;
> > +                   }
> > +                   if (STREQ(sp->name, buf4)) {
> > +                           lm->mod_init_symend = sp;
> > +                   }
> >             }
> >     }
> >  
> > @@ -1750,6 +1809,7 @@ store_module_kallsyms_v2(struct load_module *lm,
> > int start, int curr,
> >     struct namespace *ns;
> >          int mcnt;
> >          int mcnt_idx;
> > +   char *module_buf_init = NULL;
> >  
> >     if (!(kt->flags & KALLSYMS_V2))
> >             return 0;
> > @@ -1772,30 +1832,50 @@ store_module_kallsyms_v2(struct load_module
> > *lm, int start, int curr,
> >                  return 0;
> >          }
> >  
> > +   if (lm->mod_init_size > 0) {
> > +           module_buf_init = GETBUF(lm->mod_init_size);
> > +
> > +           if (!readmem(lm->mod_init_module_ptr, KVADDR, module_buf_init,
> > lm->mod_init_size,
> > +                                   "module init (kallsyms)", 
> > RETURN_ON_ERROR|QUIET)) {
> > +                   error(WARNING,"cannot access module init kallsyms\n");
> > +                   FREEBUF(module_buf_init);
> > +           }
> > +   }
> > +
> >     if (THIS_KERNEL_VERSION >= LINUX(2,6,27))
> >             nksyms = UINT(modbuf + OFFSET(module_num_symtab));
> >     else
> >             nksyms = ULONG(modbuf + OFFSET(module_num_symtab));
> >  
> >     ksymtab = ULONG(modbuf + OFFSET(module_symtab));
> > -   if (!IN_MODULE(ksymtab, lm)) {
> > +   if (!IN_MODULE(ksymtab, lm) && !IN_MODULE_INIT(ksymtab, lm)) {
> >             error(WARNING,
> >                 "%s: module.symtab outside of module address space\n",
> >                     lm->mod_name);
> >             FREEBUF(module_buf);
> > +           if (module_buf_init)
> > +                   FREEBUF(module_buf_init);
> >             return 0;
> >     } 
> > -   locsymtab = module_buf + (ksymtab - lm->mod_base);
> > +   if (IN_MODULE(ksymtab, lm))
> > +           locsymtab = module_buf + (ksymtab - lm->mod_base);
> > +   else
> > +           locsymtab = module_buf_init + (ksymtab - 
> > lm->mod_init_module_ptr);
> >  
> >     kstrtab = ULONG(modbuf + OFFSET(module_strtab));
> > -   if (!IN_MODULE(kstrtab, lm)) {
> > +   if (!IN_MODULE(kstrtab, lm) && !IN_MODULE_INIT(kstrtab, lm)) {
> >             error(WARNING, 
> >                 "%s: module.strtab outside of module address space\n",
> >                     lm->mod_name);
> >             FREEBUF(module_buf);
> > +           if (module_buf_init)
> > +                   FREEBUF(module_buf_init);
> >             return 0;
> >     }
> > -   locstrtab = module_buf + (kstrtab - lm->mod_base);
> > +   if (IN_MODULE(kstrtab, lm))
> > +           locstrtab = module_buf + (kstrtab - lm->mod_base);
> > +   else
> > +           locstrtab = module_buf_init + (kstrtab - 
> > lm->mod_init_module_ptr);
> >  
> >     for (i = 1; i < nksyms; i++) {  /* ELF starts real symbols at 1 */
> >             switch (BITS())
> > @@ -1810,14 +1890,16 @@ store_module_kallsyms_v2(struct load_module
> > *lm, int start, int curr,
> >                     break;
> >             }
> >  
> > -           if ((ec->st_value < lm->mod_base) || 
> > -               (ec->st_value >  (lm->mod_base + lm->mod_size))) 
> > +           if (((ec->st_value < lm->mod_base) ||
> > +               (ec->st_value >  (lm->mod_base + lm->mod_size)))
> > +               && (ec->st_value < lm->mod_init_module_ptr ||
> > +                   ec->st_value > (lm->mod_init_module_ptr + 
> > lm->mod_init_size)))
> >                             continue;
> >  
> >             if (ec->st_shndx == SHN_UNDEF)
> >                          continue;
> >  
> > -           if (!IN_MODULE(kstrtab + ec->st_name, lm)) {
> > +           if (!IN_MODULE(kstrtab + ec->st_name, lm) &&
> > !IN_MODULE_INIT(kstrtab + ec->st_name, lm)) {
> >                     if (CRASHDEBUG(3)) {
> >                             error(WARNING, 
> >                                "%s: bad st_name index: %lx -> %lx\n        "
> > @@ -1869,6 +1951,8 @@ store_module_kallsyms_v2(struct load_module *lm,
> > int start, int curr,
> >  
> >          lm->mod_flags |= MOD_KALLSYMS;
> >          FREEBUF(module_buf);
> > +   if (module_buf_init)
> > +           FREEBUF(module_buf_init);
> >  
> >          return mcnt;
> >  }
> > @@ -2211,7 +2295,7 @@ is_kernel_text(ulong value)
> >          for (i = 0; i < st->mods_installed; i++) {
> >                  lm = &st->load_modules[i];
> >  
> > -           if (!IN_MODULE(value, lm))
> > +           if (!IN_MODULE(value, lm) && !IN_MODULE_INIT(value, lm))
> >                     continue;
> >  
> >             if (lm->mod_flags & MOD_LOAD_SYMS) {
> > @@ -2233,10 +2317,15 @@ is_kernel_text(ulong value)
> >                             start = lm->mod_base + lm->mod_size_of_struct;
> >                             break;
> >                     case KMOD_V2:
> > -                           start = lm->mod_base;
> > +                           if (IN_MODULE(value, lm))
> > +                                   start = lm->mod_base;
> > +                           else
> > +                                   start = lm->mod_init_module_ptr;
> >                             break;
> >                     }
> >                     end = lm->mod_etext_guess;
> > +                   if (IN_MODULE_INIT(value, lm) && end < 
> > lm->mod_init_module_ptr +
> > lm->mod_init_size)
> > +                           end = lm->mod_init_module_ptr + 
> > lm->mod_init_size;
> >  
> >                     if ((value >= start) && (value < end)) 
> >                             return TRUE;
> > @@ -2524,6 +2613,8 @@ dump_symbol_table(void)
> >                          lm->mod_bss_start,
> >                          lm->mod_bss_start ?
> >                          lm->mod_bss_start - lm->mod_base : 0);
> > +           fprintf(fp, "    mod_init_size: %ld\n",
> > +                   lm->mod_init_size);
> >             fprintf(fp, "    mod_init_text_size: %ld\n",
> >                     lm->mod_init_text_size);
> >             fprintf(fp, "   mod_init_module_ptr: %lx\n",
> > @@ -3493,6 +3584,7 @@ module_symbol(ulong value,
> >     long mcnt;
> >     char buf[BUFSIZE];
> >     ulong offs, offset;
> > +   ulong base, end;
> >  
> >     if (NO_MODULES())
> >             return FALSE;
> > @@ -3506,13 +3598,20 @@ module_symbol(ulong value,
> >     for (i = 0; i < st->mods_installed; i++) {
> >             lm = &st->load_modules[i];
> >  
> > -           if ((value >= lm->mod_base) && 
> > -               (value < (lm->mod_base + lm->mod_size))) {
> > +           if (IN_MODULE(value, lm)) {
> > +                   base = lm->mod_base;
> > +                   end = lm->mod_base + lm->mod_size;
> > +           } else {
> > +                   base = lm->mod_init_module_ptr;
> > +                   end = lm->mod_init_module_ptr + lm->mod_init_size;
> > +           }
> > +
> > +           if ((value >= base) && (value < end)) {
> >                     if (lmp) 
> >                             *lmp = lm;
> >  
> >                     if (name) {
> > -                           offs = value - lm->mod_base;
> > +                           offs = value - base;
> >                             if ((sp = value_search(value, &offset))) {
> >                                     if (offset)
> >                                             sprintf(buf, radix == 16 ? 
> > @@ -3541,54 +3640,26 @@ module_symbol(ulong value,
> >     return FALSE;
> >  }
> >  
> > -/*
> > - *  Return the syment of the symbol closest to the value, along with
> > - *  the offset from the symbol value if requested.
> > - */
> >  struct syment *
> > -value_search(ulong value, ulong *offset)
> > +value_search_module(ulong value, ulong *offset, int
> > search_init_section)
> >  {
> >     int i;
> >          struct syment *sp, *sp_end, *spnext, *splast;
> >     struct load_module *lm;
> >  
> > -        if (!in_ksymbol_range(value))
> > -                return((struct syment *)NULL);
> > -
> > -   if ((sp = machdep->value_to_symbol(value, offset)))
> > -           return sp;
> > -
> > -   if (IS_VMALLOC_ADDR(value)) 
> > -           goto check_modules;
> > -
> > -   if ((sp = symval_hash_search(value)) == NULL)
> > -           sp = st->symtable;
> > - 
> > -        for ( ; sp < st->symend; sp++) {
> > -                if (value == sp->value) {
> > -#ifdef GDB_7_0
> > -                   if (STRNEQ(sp->name, ".text.")) {
> > -                           spnext = sp+1;
> > -                           if (spnext->value == value)
> > -                                   sp = spnext;
> > -                   }
> > -#endif
> > -                        if (offset) 
> > -                           *offset = 0;
> > -                        return((struct syment *)sp);
> > -                }
> > -                if (sp->value > value) {
> > -                   if (offset)
> > -                           *offset = value - ((sp-1)->value);
> > -                        return((struct syment *)(sp-1));
> > -                }
> > -        }
> > -
> > -check_modules:
> >          for (i = 0; i < st->mods_installed; i++) {
> >                  lm = &st->load_modules[i];
> > -           sp = lm->mod_symtable;
> > -                sp_end = lm->mod_symend;
> > +
> > +           if (!search_init_section) {
> > +                   sp = lm->mod_symtable;
> > +                   sp_end = lm->mod_symend;
> > +           } else {
> > +                   if (lm->mod_init_symtable) {
> > +                           sp = lm->mod_init_symtable;
> > +                           sp_end = lm->mod_init_symend;
> > +                   } else
> > +                           continue;
> > +           }
> >  
> >             if (sp->value > value)  /* invalid -- between modules */
> >                     break;
> > @@ -3599,7 +3670,7 @@ check_modules:
> >                  *  when they have unique values.
> >             */
> >             splast = NULL;
> > -                for ( ; sp < sp_end; sp++) {
> > +                for ( ; sp <= sp_end; sp++) {
> >                     if (value == sp->value) {
> >                             if (MODULE_START(sp)) {
> >                                     spnext = sp+1;
> > @@ -3644,6 +3715,57 @@ check_modules:
> >          return((struct syment *)NULL);
> >  }
> >  
> > +/*
> > + *  Return the syment of the symbol closest to the value, along with
> > + *  the offset from the symbol value if requested.
> > + */
> > +struct syment *
> > +value_search(ulong value, ulong *offset)
> > +{
> > +   int i;
> > +        struct syment *sp, *sp_end, *spnext, *splast;
> > +   struct load_module *lm;
> > +
> > +        if (!in_ksymbol_range(value))
> > +                return((struct syment *)NULL);
> > +
> > +   if ((sp = machdep->value_to_symbol(value, offset)))
> > +           return sp;
> > +
> > +   if (IS_VMALLOC_ADDR(value)) 
> > +           goto check_modules;
> > +
> > +   if ((sp = symval_hash_search(value)) == NULL)
> > +           sp = st->symtable;
> > + 
> > +        for ( ; sp < st->symend; sp++) {
> > +                if (value == sp->value) {
> > +#ifdef GDB_7_0
> > +                   if (STRNEQ(sp->name, ".text.")) {
> > +                           spnext = sp+1;
> > +                           if (spnext->value == value)
> > +                                   sp = spnext;
> > +                   }
> > +#endif
> > +                        if (offset) 
> > +                           *offset = 0;
> > +                        return((struct syment *)sp);
> > +                }
> > +                if (sp->value > value) {
> > +                   if (offset)
> > +                           *offset = value - ((sp-1)->value);
> > +                        return((struct syment *)(sp-1));
> > +                }
> > +        }
> > +
> > +check_modules:
> > +   sp = value_search_module(value, offset, 0);
> > +   if (!sp)
> > +           sp = value_search_module(value, offset, 1);
> > +
> > +   return sp;
> > +}
> > +
> >  ulong
> >  highest_bss_symbol(void)
> >  {
> > @@ -6536,6 +6658,8 @@ dump_offset_table(char *spec, ulong makestruct)
> >             OFFSET(module_core_size));
> >     fprintf(fp, "         module_core_text_size: %ld\n",
> >             OFFSET(module_core_text_size));
> > +   fprintf(fp, "         module_init_size: %ld\n",
> > +           OFFSET(module_init_size));
> >     fprintf(fp, "         module_init_text_size: %ld\n",
> >             OFFSET(module_init_text_size));
> >     fprintf(fp, "            module_module_init: %ld\n",

-- 
Thanks,
Hu Tao
diff --git a/symbols.c b/symbols.c
index f1c308e..ad3c32d 100755
--- a/symbols.c
+++ b/symbols.c
@@ -3640,7 +3640,7 @@ module_symbol(ulong value,
        return FALSE;
 }
 
-struct syment *
+static struct syment *
 value_search_module(ulong value, ulong *offset, int search_init_section)
 {
        int i;
@@ -3722,9 +3722,7 @@ value_search_module(ulong value, ulong *offset, int 
search_init_section)
 struct syment *
 value_search(ulong value, ulong *offset)
 {
-       int i;
-        struct syment *sp, *sp_end, *spnext, *splast;
-       struct load_module *lm;
+        struct syment *sp, *spnext;
 
         if (!in_ksymbol_range(value))
                 return((struct syment *)NULL);
diff --git a/defs.h b/defs.h
index 0fe9d48..18546eb 100755
--- a/defs.h
+++ b/defs.h
@@ -2014,6 +2014,7 @@ struct symbol_table_data {
 #define MOD_KALLSYMS    (0x8)
 #define MOD_INITRD     (0x10)
 #define MOD_NOPATCH    (0x20)
+#define MOD_INIT       (0x40)
 
 #define SEC_FOUND       (0x10000)
 
diff --git a/symbols.c b/symbols.c
index ad3c32d..ac4ba98 100755
--- a/symbols.c
+++ b/symbols.c
@@ -1950,6 +1950,8 @@ store_module_kallsyms_v2(struct load_module *lm, int 
start, int curr,
        }
 
         lm->mod_flags |= MOD_KALLSYMS;
+       if (lm->mod_init_size > 0)
+                lm->mod_flags |= MOD_INIT;
         FREEBUF(module_buf);
        if (module_buf_init)
                FREEBUF(module_buf_init);
@@ -3641,26 +3643,20 @@ module_symbol(ulong value,
 }
 
 static struct syment *
-value_search_module(ulong value, ulong *offset, int search_init_section)
+value_search_module(ulong value, ulong *offset)
 {
        int i;
+       int retry;
         struct syment *sp, *sp_end, *spnext, *splast;
        struct load_module *lm;
 
         for (i = 0; i < st->mods_installed; i++) {
+               retry = 1;
                 lm = &st->load_modules[i];
 
-               if (!search_init_section) {
-                       sp = lm->mod_symtable;
-                       sp_end = lm->mod_symend;
-               } else {
-                       if (lm->mod_init_symtable) {
-                               sp = lm->mod_init_symtable;
-                               sp_end = lm->mod_init_symend;
-                       } else
-                               continue;
-               }
-
+               sp = lm->mod_symtable;
+               sp_end = lm->mod_symend;
+retry:
                if (sp->value > value)  /* invalid -- between modules */
                        break;
 
@@ -3710,6 +3706,13 @@ value_search_module(ulong value, ulong *offset, int 
search_init_section)
                                        splast = sp;
                        }
                 }
+
+               if (retry && (lm->mod_flags & MOD_INIT)) {
+                       retry = 0;
+                       sp = lm->mod_init_symtable;
+                       sp_end = lm->mod_init_symend;
+                       goto retry;
+               }
         }
 
         return((struct syment *)NULL);
@@ -3731,7 +3734,7 @@ value_search(ulong value, ulong *offset)
                return sp;
 
        if (IS_VMALLOC_ADDR(value)) 
-               goto check_modules;
+               return value_search_module(value, offset);
 
        if ((sp = symval_hash_search(value)) == NULL)
                sp = st->symtable;
@@ -3756,11 +3759,6 @@ value_search(ulong value, ulong *offset)
                 }
         }
 
-check_modules:
-       sp = value_search_module(value, offset, 0);
-       if (!sp)
-               sp = value_search_module(value, offset, 1);
-
        return sp;
 }
 
--
Crash-utility mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/crash-utility

Reply via email to