xiaoxiang781216 commented on code in PR #20368:
URL: https://github.com/apache/nuttx/pull/20368#discussion_r4130097709
##########
libs/libc/machine/arm/armv7-m/arch_elf.c:
##########
@@ -210,28 +210,36 @@ int up_relocate(const Elf32_Rel *rel, const Elf32_Sym
*sym, uintptr_t addr,
"at addr=%08" PRIxPTR " to sym=%p st_value=%08" PRIx32 "\n",
addr, sym, sym->st_value);
- if (data->pltrel)
+ if (data->symisdesc)
+ {
+ /* Resolved to a function in another object, which published a
+ * descriptor of its own. Take both words: the callee has to
+ * run with its own data base, not ours.
+ */
+
+ *desc = *(FAR struct fdpic_desc_s *)sym->st_value;
Review Comment:
ditto
##########
libs/libc/machine/arm/armv8-m/arch_elf.c:
##########
@@ -210,28 +210,36 @@ int up_relocate(const Elf32_Rel *rel, const Elf32_Sym
*sym, uintptr_t addr,
"at addr=%08" PRIxPTR " to sym=%p st_value=%08" PRIx32 "\n",
addr, sym, sym->st_value);
- if (data->pltrel)
+ if (data->symisdesc)
+ {
+ /* Resolved to a function in another object, which published a
+ * descriptor of its own. Take both words: the callee has to
+ * run with its own data base, not ours.
+ */
+
+ *desc = *(FAR struct fdpic_desc_s *)sym->st_value;
Review Comment:
remove FAR from arm specific code
##########
libs/libc/elf/elf_bind.c:
##########
@@ -674,6 +748,15 @@ static int libelf_relocatedyn(FAR struct module_s *modp,
int i;
int idx_rel;
int idx_sym;
+#if CONFIG_LIBC_ELF_MAXDEPEND > 0
+ int j;
+#endif
+#ifdef LIBELF_NEEDED
Review Comment:
remove line 753-754
##########
libs/libc/elf/elf_bind.c:
##########
@@ -46,6 +47,14 @@
* Pre-processor Definitions
****************************************************************************/
+/* With an address environment the program lives in its own address space,
+ * which a library loaded by libelf_insert() cannot reach.
Review Comment:
but still can reach as per task list, so let's remove LIBELF_NEEDED and use
CONFIG_LIBC_ELF_MAXDEPEND directly
##########
libs/libc/elf/elf_bind.c:
##########
@@ -734,6 +817,28 @@ static int libelf_relocatedyn(FAR struct module_s *modp,
case DT_PLTRELSZ:
reldata.relsz[I_PLT] = dyn[i].d_un.d_val;
break;
+ case DT_NEEDED:
+
+ /* Remember it; the name lives in the string table, which is
+ * not located until the loop has seen DT_STRTAB.
+ */
+
+ if (nlibs >= CONFIG_LIBC_ELF_MAXDEPEND)
+ {
+ berr("ERROR: More than %d DT_NEEDED entries\n",
+ CONFIG_LIBC_ELF_MAXDEPEND);
+ lib_free(sym);
+ lib_free(rels);
+ lib_free(dyn);
+ return -ENOEXEC;
+ }
+
+#ifdef LIBELF_NEEDED
+ libs[nlibs] = dyn[i].d_un.d_val;
+#endif
+ nlibs++;
Review Comment:
merge into line 837
##########
libs/libc/elf/elf_bind.c:
##########
@@ -812,9 +917,91 @@ static int libelf_relocatedyn(FAR struct module_s *modp,
loadinfo->gotbase);
}
- /* After the loop, because DT_PLTGOT is read there. Both relocation
- * tables are walked under this one arch_data, so the pool cursor
- * survives from one to the next.
+ /* Load whatever the object names in DT_NEEDED. This is what dlopen()
+ * does, through the same libelf_insert(), but the loader is also the
+ * kernel's module loader, which has no dlfcn.
+ */
+
+#ifdef LIBELF_NEEDED
+
+ symhdr = &loadinfo->shdr[loadinfo->dsymtabidx];
+
+ for (i = 0; i < nlibs; i++)
+ {
+ Elf_Sym namesym;
+ FAR void *handle;
+
+ /* The name is a string table offset, which is what st_name is, so
+ * the existing reader can fetch it.
+ */
+
+ memset(&namesym, 0, sizeof(namesym));
+ namesym.st_name = libs[i];
+
+ ret = libelf_symname(loadinfo, &namesym,
+ loadinfo->shdr[symhdr->sh_link].sh_offset);
+ if (ret < 0)
+ {
+ berr("ERROR: DT_NEEDED %d has no name\n", i);
+ lib_free(sym);
+ lib_free(rels);
+ lib_free(dyn);
+ return ret;
+ }
+
+ handle = libelf_insertneeded((FAR const char *)loadinfo->iobuffer);
+ if (handle == NULL)
+ {
+ berr("ERROR: Cannot open needed library %s\n",
+ (FAR char *)loadinfo->iobuffer);
+ lib_free(sym);
+ lib_free(rels);
+ lib_free(dyn);
+ return -ELIBACC;
+ }
+
+ binfo("Opened needed library %s\n", (FAR char *)loadinfo->iobuffer);
+
+ /* The dependency holds the library from now on, in place of the
+ * reference libelf_insert() took, so libelf_undepend() lets it go.
+ */
+
+ libelf_registry_lock();
+ ret = libelf_depend(modp, handle);
+ if (ret >= 0)
+ {
+ ((FAR struct module_s *)handle)->nopen--;
+ }
+
+ libelf_registry_unlock();
+
+ if (ret < 0)
+ {
+ berr("ERROR: Cannot depend on %s: %d\n",
+ (FAR char *)loadinfo->iobuffer, ret);
+ libelf_remove(handle);
+ lib_free(sym);
+ lib_free(rels);
+ lib_free(dyn);
+ return ret;
+ }
+ }
+
+#else
+ if (nlibs > 0)
Review Comment:
why not fail directly at the collection phase
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]