xiaoxiang781216 commented on code in PR #19942:
URL: https://github.com/apache/nuttx/pull/19942#discussion_r3915098777
##########
libs/libc/elf/elf_load.c:
##########
@@ -539,10 +547,113 @@ static inline int libelf_loadfile(FAR struct
mod_loadinfo_s *loadinfo)
return OK;
}
+/****************************************************************************
+ * Name: libelf_xipacquire
+ *
+ * Description:
+ * Ask the filesystem for the address of this file on its media, so the
+ * read-only part of the object can run where it lies. Ask for a pin
+ * first: a compacting filesystem is not safe without one. Do not ask at
+ * all if this build cannot hold a pin.
+ *
+ * Returned Value:
+ * Zero if an address was obtained, a negated errno otherwise. Callers
+ * that can live without one may ignore the failure.
+ *
+ ****************************************************************************/
+
+#ifdef HAVE_LIBC_ELF_PIN
+static int libelf_pinhold(FAR struct mod_loadinfo_s *loadinfo)
+{
+ FAR struct file *filep;
+ int ret;
+
+ /* The descriptor belongs to the task that called the loader, and the
+ * unload runs on another task. Hold the file instead.
+ */
+
+ loadinfo->pinfile = lib_zalloc(sizeof(struct file));
+ if (loadinfo->pinfile == NULL)
+ {
+ return -ENOMEM;
+ }
+
+ ret = file_get(loadinfo->filfd, &filep);
+ if (ret >= 0)
+ {
+ ret = file_dup2(filep, loadinfo->pinfile);
+ file_put(filep);
+ }
+
+ if (ret < 0)
+ {
+ lib_free(loadinfo->pinfile);
+ loadinfo->pinfile = NULL;
+ }
+
+ return ret;
+}
+
+#endif
+
+static int libelf_xipacquire(FAR struct mod_loadinfo_s *loadinfo)
+{
+ uintptr_t base = 0;
+
+#ifdef HAVE_LIBC_ELF_PIN
+ if (ioctl(loadinfo->filfd, XIPFSIOC_PIN, (unsigned long)&base) >= 0)
+ {
+ int ret = libelf_pinhold(loadinfo);
+
+ if (ret < 0)
+ {
+ berr("ERROR: Failed to hold the pinned file: %d\n", ret);
+ ioctl(loadinfo->filfd, XIPFSIOC_UNPIN, 0);
+ return ret;
+ }
+
+ loadinfo->xipbase = base;
+ binfo("pinned xipbase %zx\n", (size_t)loadinfo->xipbase);
Review Comment:
remove the cast
##########
libs/libc/elf/elf_load.c:
##########
@@ -260,6 +260,20 @@ static void libelf_elfsize(FAR struct mod_loadinfo_s
*loadinfo, bool alloc)
}
}
+ /* A library also publishes a descriptor per exported function, for
+ * dlsym(). The dynamic symbol table bounds how many.
+ */
+
+ for (i = 0; i < loadinfo->ehdr.e_shnum; i++)
+ {
+ FAR Elf_Shdr *shdr = &loadinfo->shdr[i];
+
+ if (shdr->sh_type == SHT_DYNSYM && shdr->sh_entsize != 0)
Review Comment:
merge to line 257
##########
libs/libc/elf/elf_load.c:
##########
@@ -539,10 +547,113 @@ static inline int libelf_loadfile(FAR struct
mod_loadinfo_s *loadinfo)
return OK;
}
+/****************************************************************************
+ * Name: libelf_xipacquire
+ *
+ * Description:
+ * Ask the filesystem for the address of this file on its media, so the
+ * read-only part of the object can run where it lies. Ask for a pin
+ * first: a compacting filesystem is not safe without one. Do not ask at
+ * all if this build cannot hold a pin.
+ *
+ * Returned Value:
+ * Zero if an address was obtained, a negated errno otherwise. Callers
+ * that can live without one may ignore the failure.
+ *
+ ****************************************************************************/
+
+#ifdef HAVE_LIBC_ELF_PIN
+static int libelf_pinhold(FAR struct mod_loadinfo_s *loadinfo)
+{
+ FAR struct file *filep;
+ int ret;
+
+ /* The descriptor belongs to the task that called the loader, and the
+ * unload runs on another task. Hold the file instead.
+ */
+
+ loadinfo->pinfile = lib_zalloc(sizeof(struct file));
+ if (loadinfo->pinfile == NULL)
+ {
+ return -ENOMEM;
+ }
+
+ ret = file_get(loadinfo->filfd, &filep);
+ if (ret >= 0)
+ {
+ ret = file_dup2(filep, loadinfo->pinfile);
+ file_put(filep);
+ }
+
+ if (ret < 0)
+ {
+ lib_free(loadinfo->pinfile);
+ loadinfo->pinfile = NULL;
+ }
+
+ return ret;
+}
+
+#endif
+
+static int libelf_xipacquire(FAR struct mod_loadinfo_s *loadinfo)
+{
+ uintptr_t base = 0;
+
+#ifdef HAVE_LIBC_ELF_PIN
+ if (ioctl(loadinfo->filfd, XIPFSIOC_PIN, (unsigned long)&base) >= 0)
+ {
+ int ret = libelf_pinhold(loadinfo);
+
+ if (ret < 0)
+ {
+ berr("ERROR: Failed to hold the pinned file: %d\n", ret);
+ ioctl(loadinfo->filfd, XIPFSIOC_UNPIN, 0);
+ return ret;
+ }
+
+ loadinfo->xipbase = base;
+ binfo("pinned xipbase %zx\n", (size_t)loadinfo->xipbase);
+ return OK;
+ }
+#endif
+
+ if (ioctl(loadinfo->filfd, FIOC_XIPBASE, (unsigned long)&base) >= 0)
+ {
+ loadinfo->xipbase = base;
+ binfo("can use xipbase %zx\n", (size_t)loadinfo->xipbase);
Review Comment:
ditto
--
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]