From a613bcb7cb43b08fd489a5f44f852153722c27de Mon Sep 17 00:00:00 2001 From: anjiahao Date: Tue, 9 Jul 2024 23:38:38 +0800 Subject: [PATCH] modlib:add new dump api to modlib Signed-off-by: anjiahao --- include/nuttx/lib/modlib.h | 34 ++++++++++ libs/libc/modlib/modlib_insert.c | 104 +++++++++++++++++++++++++++++-- 2 files changed, 133 insertions(+), 5 deletions(-) diff --git a/include/nuttx/lib/modlib.h b/include/nuttx/lib/modlib.h index 4889c6c0c870c..a18a224ba24f5 100644 --- a/include/nuttx/lib/modlib.h +++ b/include/nuttx/lib/modlib.h @@ -562,6 +562,40 @@ int modlib_registry_foreach(mod_callback_t callback, FAR void *arg); void modlib_freesymtab(FAR struct module_s *modp); +/**************************************************************************** + * Name: modlib_dumploadinfo + * + * Description: + * Dump the load information to debug output. + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_BINFMT_INFO +void modlib_dumploadinfo(FAR struct mod_loadinfo_s *loadinfo); +#else +# define modlib_dumploadinfo(i) +#endif + +/**************************************************************************** + * Name: modlib_dumpmodule + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_BINFMT_INFO +void modlib_dumpmodule(FAR struct module_s *modp); +#else +# define modlib_dumpmodule(m) +#endif + +/**************************************************************************** + * Name: elf_dumpentrypt + ****************************************************************************/ + +#ifdef CONFIG_MODLIB_DUMPBUFFER +void modlib_dumpentrypt(FAR struct mod_loadinfo_s *loadinfo); +#else +# define modlib_dumpentrypt(l) +#endif + /**************************************************************************** * Name: modlib_insert * diff --git a/libs/libc/modlib/modlib_insert.c b/libs/libc/modlib/modlib_insert.c index 7056f47fccf92..bfaaca3e305e6 100644 --- a/libs/libc/modlib/modlib_insert.c +++ b/libs/libc/modlib/modlib_insert.c @@ -32,15 +32,19 @@ #include /**************************************************************************** - * Private Functions + * Public Functions ****************************************************************************/ /**************************************************************************** * Name: modlib_dumploadinfo + * + * Description: + * Dump the load information to debug output. + * ****************************************************************************/ #ifdef CONFIG_DEBUG_BINFMT_INFO -static void modlib_dumploadinfo(FAR struct mod_loadinfo_s *loadinfo) +void modlib_dumploadinfo(FAR struct mod_loadinfo_s *loadinfo) { int i; @@ -101,14 +105,104 @@ static void modlib_dumploadinfo(FAR struct mod_loadinfo_s *loadinfo) } } } -#else -# define modlib_dumploadinfo(i) + +/**************************************************************************** + * Name: modlib_dumpmodule + ****************************************************************************/ + +void modlib_dumpmodule(FAR struct module_s *modp) +{ + binfo("Module:\n"); + binfo(" modname: %s\n", modp->modname); + binfo(" textalloc: %08lx\n", (long)modp->textalloc); +#if defined(CONFIG_FS_PROCFS) && !defined(CONFIG_FS_PROCFS_EXCLUDE_MODULE) + binfo(" dataalloc: %08lx\n", (long)modp->dataalloc); + binfo(" textsize: %ld\n", (long)modp->textsize); +#endif + +#ifdef CONFIG_ARCH_USE_SEPARATED_SECTION + binfo(" sectalloc: %p\n", modp->sectalloc); + binfo(" nsect: %ld\n", (long)modp->nsect); + for (int i = 0; i < modp->nsect; i++) + { + binfo(" sectalloc[%d]: %p\n", i, modp->sectalloc[i]); + } + +#endif + +#if CONFIG_MODLIB_MAXDEPEND > 0 + binfo(" dependents: %d\n", modp->dependents); + for (int i = 0; i < modp->dependents; i++) + { + binfo("%d %s\n", i, modp->dependencies[i]->modname); + modlib_dumpmodule(modp->dependencies[i]); + } #endif + binfo(" finiarr: %08lx\n", (long)modp->finiarr); + binfo(" nfini: %d\n", modp->nfini); +} + +#endif /**************************************************************************** - * Public Functions + * Name: elf_dumpentrypt ****************************************************************************/ +#ifdef CONFIG_MODLIB_DUMPBUFFER +void modlib_dumpentrypt(FAR struct mod_loadinfo_s *loadinfo) +{ + FAR const uint8_t *entry; +#ifdef CONFIG_ARCH_ADDRENV + int ret; + + /* If CONFIG_ARCH_ADDRENV=y, then the loaded ELF lies in a virtual address + * space that may not be in place now. modlib_addrenv_select() will + * temporarily instantiate that address space. + */ + + if (loadinfo->addrenv != NULL) + { + ret = modlib_addrenv_select(loadinfo); + if (ret < 0) + { + berr("ERROR: modlib_addrenv_select() failed: %d\n", ret); + return; + } + } +#endif + + if (loadinfo->ehdr.e_type == ET_REL) + { + entry = (FAR const uint8_t *) + ((uintptr_t)loadinfo->textalloc + loadinfo->ehdr.e_entry); + } + else if (loadinfo->ehdr.e_type == ET_EXEC) + { + entry = (FAR const uint8_t *)loadinfo->ehdr.e_entry; + } + else + { + entry = (FAR const uint8_t *)loadinfo->textalloc; + } + + modlib_dumpbuffer("Entry code", entry, + MIN(loadinfo->textsize - loadinfo->ehdr.e_entry, 512)); + +#ifdef CONFIG_ARCH_ADDRENV + /* Restore the original address environment */ + + if (loadinfo->addrenv != NULL) + { + ret = modlib_addrenv_restore(loadinfo); + if (ret < 0) + { + berr("ERROR: modlib_addrenv_restore() failed: %d\n", ret); + } + } +#endif +} +#endif + /**************************************************************************** * Name: modlib_insert *