casaroli commented on code in PR #19942:
URL: https://github.com/apache/nuttx/pull/19942#discussion_r3917700276


##########
include/nuttx/lib/elf.h:
##########
@@ -278,6 +278,20 @@ struct mod_loadinfo_s
   FAR struct file *pinfile;
 #endif
 
+  /* The object's data base, from DT_PLTGOT.  An FDPIC module runs with this
+   * in the PIC base register.
+   */
+
+  uintptr_t     gotaddr;

Review Comment:
   the check runs before `libelf_bind()` reads `DT_PLTGOT`, so a merged field 
is still zero there, and the GOT walk needs sh_size as well as the address, 
which is two fields again



##########
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:
   done



##########
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:
   done



-- 
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]

Reply via email to