[rtems commit] libdl: Allocator does not unlock and lock memory on loading.

Chris Johns chrisj at rtems.org
Thu Feb 14 23:06:18 UTC 2019


Module:    rtems
Branch:    master
Commit:    e309f7769fab9eed69079445a3f7f2354ea993c3
Changeset: http://git.rtems.org/rtems/commit/?id=e309f7769fab9eed69079445a3f7f2354ea993c3

Author:    Chris Johns <chrisj at rtems.org>
Date:      Thu Feb 14 14:00:05 2019 +1100

libdl: Allocator does not unlock and lock memory on loading.

Close #3692

---

 cpukit/include/rtems/rtl/rtl-allocator.h | 70 +++++++++++++++++++++++++-
 cpukit/libdl/rtl-alloc-heap.c            |  6 +--
 cpukit/libdl/rtl-alloc-heap.h            |  4 +-
 cpukit/libdl/rtl-allocator.c             | 84 ++++++++++++++++++++++++++++----
 cpukit/libdl/rtl-obj.c                   | 11 +++++
 5 files changed, 158 insertions(+), 17 deletions(-)

diff --git a/cpukit/include/rtems/rtl/rtl-allocator.h b/cpukit/include/rtems/rtl/rtl-allocator.h
index c5b3d4e..1a5d615 100644
--- a/cpukit/include/rtems/rtl/rtl-allocator.h
+++ b/cpukit/include/rtems/rtl/rtl-allocator.h
@@ -45,6 +45,21 @@ enum rtems_rtl_alloc_tags {
 typedef enum rtems_rtl_alloc_tags rtems_rtl_alloc_tag;
 
 /**
+ * Define the allocation command the loader requires.
+ */
+enum rtems_rtl_alloc_cmd {
+  RTEMS_RTL_ALLOC_NEW,        /**< Allocate new memory. */
+  RTEMS_RTL_ALLOC_DEL,        /**< Delete allocated memory. */
+  RTEMS_RTL_ALLOC_WR_ENABLE,  /**< Enable writes to the memory. */
+  RTEMS_RTL_ALLOC_WR_DISABLE, /**< Disable writes to the memory. */
+};
+
+/**
+ * The allocator command type.
+ */
+typedef enum rtems_rtl_alloc_cmd rtems_rtl_alloc_cmd;
+
+/**
  * The number of tags.
  */
 #define RTEMS_RTL_ALLOC_TAGS ((size_t) (RTEMS_RTL_ALLOC_READ_EXEC + 1))
@@ -53,7 +68,7 @@ typedef enum rtems_rtl_alloc_tags rtems_rtl_alloc_tag;
  * Allocator handler handles all RTL allocations. It can be hooked and
  * overridded for customised allocation schemes or memory maps.
  *
- * @param allocation If true the request is to allocate memory else free.
+ * @param allocation The request command.
  * @param tag The type of allocation request.
  * @param address Pointer to the memory address. If an allocation the value is
  *                unspecific on entry and the allocated address or NULL on
@@ -63,7 +78,7 @@ typedef enum rtems_rtl_alloc_tags rtems_rtl_alloc_tag;
  * @param size The size of the allocation if an allocation request and
  *             not used if deleting or freeing a previous allocation.
  */
-typedef void (*rtems_rtl_allocator)(bool                allocate,
+typedef void (*rtems_rtl_allocator)(rtems_rtl_alloc_cmd cmd,
                                     rtems_rtl_alloc_tag tag,
                                     void**              address,
                                     size_t              size);
@@ -107,6 +122,22 @@ void* rtems_rtl_alloc_new (rtems_rtl_alloc_tag tag, size_t size, bool zero);
 void rtems_rtl_alloc_del (rtems_rtl_alloc_tag tag, void* address);
 
 /**
+ * The Runtime Loader allocator enable write on a bloc of allocated memory.
+ *
+ * @param tag The type of allocation request. Must match the address.
+ * @param address The memory address to write enable. A NULL is ignored.
+ */
+void rtems_rtl_alloc_wr_enable (rtems_rtl_alloc_tag tag, void* address);
+
+/**
+ * The Runtime Loader allocator disable write on a bloc of allocated memory.
+ *
+ * @param tag The type of allocation request. Must match the address.
+ * @param address The memory address to write disable. A NULL is ignored.
+ */
+void rtems_rtl_alloc_wr_disable (rtems_rtl_alloc_tag tag, void* address);
+
+/**
  * Hook the Runtime Loader allocatior. A handler can call the previous handler
  * in the chain to use it for specific tags. The default handler uses the
  * system heap. Do not unhook your handler if memory it allocates has not been
@@ -138,6 +169,41 @@ void rtems_rtl_alloc_indirect_del (rtems_rtl_alloc_tag tag,
                                    rtems_rtl_ptr*      handle);
 
 /**
+ * Return the default tag for text sections.
+ *
+ * @return The text tag.
+ */
+rtems_rtl_alloc_tag rtems_rtl_alloc_text_tag (void);
+
+/**
+ * Return the default tag for const sections.
+ *
+ * @return The const tag.
+ */
+rtems_rtl_alloc_tag rtems_rtl_alloc_const_tag (void);
+
+/**
+ * Return the default tag for exception sections.
+ *
+ * @return The eh tag.
+ */
+rtems_rtl_alloc_tag rtems_rtl_alloc_eh_tag (void);
+
+/**
+ * Return the default tag for data sections.
+ *
+ * @return The data tag.
+ */
+rtems_rtl_alloc_tag rtems_rtl_alloc_data_tag (void);
+
+/**
+ * Return the default tag for bss sections.
+ *
+ * @return The bss tag.
+ */
+rtems_rtl_alloc_tag rtems_rtl_alloc_bss_tag (void);
+
+/**
  * Allocate the memory for a module given the size of the text, const, data and
  * bss sections. If any part of the allocation fails the no memory is
  * allocated.
diff --git a/cpukit/libdl/rtl-alloc-heap.c b/cpukit/libdl/rtl-alloc-heap.c
index 2483e89..4ffdaf2 100644
--- a/cpukit/libdl/rtl-alloc-heap.c
+++ b/cpukit/libdl/rtl-alloc-heap.c
@@ -18,14 +18,14 @@
 #include "rtl-alloc-heap.h"
 
 void
-rtems_rtl_alloc_heap (bool                allocate,
+rtems_rtl_alloc_heap (rtems_rtl_alloc_cmd cmd,
                       rtems_rtl_alloc_tag tag,
                       void**              address,
                       size_t              size)
 {
-  if (allocate)
+  if (cmd == RTEMS_RTL_ALLOC_NEW)
     *address = malloc (size);
-  else
+  else if (cmd == RTEMS_RTL_ALLOC_DEL)
   {
     free (*address);
     *address = NULL;
diff --git a/cpukit/libdl/rtl-alloc-heap.h b/cpukit/libdl/rtl-alloc-heap.h
index befcad1..6b7018b 100644
--- a/cpukit/libdl/rtl-alloc-heap.h
+++ b/cpukit/libdl/rtl-alloc-heap.h
@@ -25,7 +25,7 @@ extern "C" {
 /**
  * Allocator handler for the standard libc heap.
  *
- * @param allocation If true the request is to allocate memory else free.
+ * @param cmd The allocation command.
  * @param tag The type of allocation request.
  * @param address Pointer to the memory address. If an allocation the value is
  *                unspecific on entry and the allocated address or NULL on
@@ -35,7 +35,7 @@ extern "C" {
  * @param size The size of the allocation if an allocation request and
  *             not used if deleting or freeing a previous allocation.
  */
-void rtems_rtl_alloc_heap(bool                allocate,
+void rtems_rtl_alloc_heap(rtems_rtl_alloc_cmd cmd,
                           rtems_rtl_alloc_tag tag,
                           void**              address,
                           size_t              size);
diff --git a/cpukit/libdl/rtl-allocator.c b/cpukit/libdl/rtl-allocator.c
index 605cdbd..01ce9e5 100644
--- a/cpukit/libdl/rtl-allocator.c
+++ b/cpukit/libdl/rtl-allocator.c
@@ -57,8 +57,8 @@ rtems_rtl_alloc_new (rtems_rtl_alloc_tag tag, size_t size, bool zero)
    * Obtain memory from the allocator. The address field is set by the
    * allocator.
    */
-  if (rtl)
-    rtl->allocator.allocator (true, tag, &address, size);
+  if (rtl != NULL)
+    rtl->allocator.allocator (RTEMS_RTL_ALLOC_NEW, tag, &address, size);
 
   rtems_rtl_unlock ();
 
@@ -69,7 +69,7 @@ rtems_rtl_alloc_new (rtems_rtl_alloc_tag tag, size_t size, bool zero)
   /*
    * Only zero the memory if asked to and the allocation was successful.
    */
-  if (address && zero)
+  if (address != NULL && zero)
     memset (address, 0, size);
 
   return address;
@@ -84,8 +84,42 @@ rtems_rtl_alloc_del (rtems_rtl_alloc_tag tag, void* address)
     printf ("rtl: alloc: del: %s addr=%p\n",
             rtems_rtl_trace_tag_label (tag), address);
 
-  if (rtl && address)
-    rtl->allocator.allocator (false, tag, &address, 0);
+  if (rtl != NULL && address != NULL)
+    rtl->allocator.allocator (RTEMS_RTL_ALLOC_DEL, tag, &address, 0);
+
+  rtems_rtl_unlock ();
+}
+
+void
+rtems_rtl_alloc_wr_enable (rtems_rtl_alloc_tag tag, void* address)
+{
+  rtems_rtl_data* rtl = rtems_rtl_lock ();
+
+  if (rtems_rtl_trace (RTEMS_RTL_TRACE_ALLOCATOR))
+    printf ("rtl: alloc: wr-enable: addr=%p\n", address);
+
+  if (rtl != NULL && address != NULL)
+    rtl->allocator.allocator (RTEMS_RTL_ALLOC_WR_ENABLE,
+                              tag,
+                              address,
+                              0);
+
+  rtems_rtl_unlock ();
+}
+
+void
+rtems_rtl_alloc_wr_disable (rtems_rtl_alloc_tag tag, void* address)
+{
+  rtems_rtl_data* rtl = rtems_rtl_lock ();
+
+  if (rtems_rtl_trace (RTEMS_RTL_TRACE_ALLOCATOR))
+    printf ("rtl: alloc: wr-enable: addr=%p\n", address);
+
+  if (rtl != NULL && address != NULL)
+    rtl->allocator.allocator (RTEMS_RTL_ALLOC_WR_DISABLE,
+                              tag,
+                              address,
+                              0);
 
   rtems_rtl_unlock ();
 }
@@ -150,6 +184,36 @@ rtems_rtl_alloc_indirect_del (rtems_rtl_alloc_tag tag,
   }
 }
 
+rtems_rtl_alloc_tag
+rtems_rtl_alloc_text_tag (void)
+{
+  return RTEMS_RTL_ALLOC_READ_EXEC;
+}
+
+rtems_rtl_alloc_tag
+rtems_rtl_alloc_const_tag (void)
+{
+  return RTEMS_RTL_ALLOC_READ;
+}
+
+rtems_rtl_alloc_tag
+rtems_rtl_alloc_eh_tag (void)
+{
+  return RTEMS_RTL_ALLOC_READ;
+}
+
+rtems_rtl_alloc_tag
+rtems_rtl_alloc_data_tag (void)
+{
+  return RTEMS_RTL_ALLOC_READ_WRITE;
+}
+
+rtems_rtl_alloc_tag
+rtems_rtl_alloc_bss_tag (void)
+{
+  return RTEMS_RTL_ALLOC_READ_WRITE;
+}
+
 bool
 rtems_rtl_alloc_module_new (void** text_base, size_t text_size,
                             void** const_base, size_t const_size,
@@ -161,7 +225,7 @@ rtems_rtl_alloc_module_new (void** text_base, size_t text_size,
 
   if (text_size)
   {
-    *text_base = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_READ_EXEC,
+    *text_base = rtems_rtl_alloc_new (rtems_rtl_alloc_text_tag (),
                                       text_size, false);
     if (!*text_base)
     {
@@ -171,7 +235,7 @@ rtems_rtl_alloc_module_new (void** text_base, size_t text_size,
 
   if (const_size)
   {
-    *const_base = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_READ,
+    *const_base = rtems_rtl_alloc_new (rtems_rtl_alloc_const_tag (),
                                        const_size, false);
     if (!*const_base)
     {
@@ -183,7 +247,7 @@ rtems_rtl_alloc_module_new (void** text_base, size_t text_size,
 
   if (eh_size)
   {
-    *eh_base = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_READ,
+    *eh_base = rtems_rtl_alloc_new (rtems_rtl_alloc_eh_tag (),
                                     eh_size, false);
     if (!*eh_base)
     {
@@ -195,7 +259,7 @@ rtems_rtl_alloc_module_new (void** text_base, size_t text_size,
 
   if (data_size)
   {
-    *data_base = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_READ_WRITE,
+    *data_base = rtems_rtl_alloc_new (rtems_rtl_alloc_data_tag (),
                                       data_size, false);
     if (!*data_base)
     {
@@ -207,7 +271,7 @@ rtems_rtl_alloc_module_new (void** text_base, size_t text_size,
 
   if (bss_size)
   {
-    *bss_base = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_READ_WRITE,
+    *bss_base = rtems_rtl_alloc_new (rtems_rtl_alloc_bss_tag (),
                                      bss_size, false);
     if (!*bss_base)
     {
diff --git a/cpukit/libdl/rtl-obj.c b/cpukit/libdl/rtl-obj.c
index 15e5bf1..3786784 100644
--- a/cpukit/libdl/rtl-obj.c
+++ b/cpukit/libdl/rtl-obj.c
@@ -1000,6 +1000,7 @@ rtems_rtl_obj_sections_link_order (uint32_t mask, rtems_rtl_obj* obj)
 
 static bool
 rtems_rtl_obj_sections_loader (uint32_t                   mask,
+                               rtems_rtl_alloc_tag        tag,
                                rtems_rtl_obj*             obj,
                                int                        fd,
                                uint8_t*                   base,
@@ -1014,6 +1015,8 @@ rtems_rtl_obj_sections_loader (uint32_t                   mask,
   if (rtems_rtl_trace (RTEMS_RTL_TRACE_LOAD_SECT))
     printf ("rtl: loading section: mask:%08" PRIx32 " base:%p\n", mask, base);
 
+  rtems_rtl_alloc_wr_enable (tag, base);
+
   while (!rtems_chain_is_tail (sections, node))
   {
     rtems_rtl_obj_sect* sect = (rtems_rtl_obj_sect*) node;
@@ -1039,6 +1042,7 @@ rtems_rtl_obj_sections_loader (uint32_t                   mask,
           if (!handler (obj, fd, sect, data))
           {
             sect->base = 0;
+            rtems_rtl_alloc_wr_disable (tag, base);
             return false;
           }
         }
@@ -1067,6 +1071,8 @@ rtems_rtl_obj_sections_loader (uint32_t                   mask,
     node = rtems_chain_next (node);
   }
 
+  rtems_rtl_alloc_wr_disable (tag, base);
+
   return true;
 }
 
@@ -1168,14 +1174,19 @@ rtems_rtl_obj_load_sections (rtems_rtl_obj*             obj,
    * sections.
    */
   if (!rtems_rtl_obj_sections_loader (RTEMS_RTL_OBJ_SECT_TEXT,
+                                      rtems_rtl_alloc_text_tag (),
                                       obj, fd, obj->text_base, handler, data) ||
       !rtems_rtl_obj_sections_loader (RTEMS_RTL_OBJ_SECT_CONST,
+                                      rtems_rtl_alloc_const_tag (),
                                       obj, fd, obj->const_base, handler, data) ||
       !rtems_rtl_obj_sections_loader (RTEMS_RTL_OBJ_SECT_EH,
+                                      rtems_rtl_alloc_eh_tag (),
                                       obj, fd, obj->eh_base, handler, data) ||
       !rtems_rtl_obj_sections_loader (RTEMS_RTL_OBJ_SECT_DATA,
+                                      rtems_rtl_alloc_data_tag (),
                                       obj, fd, obj->data_base, handler, data) ||
       !rtems_rtl_obj_sections_loader (RTEMS_RTL_OBJ_SECT_BSS,
+                                      rtems_rtl_alloc_bss_tag (),
                                       obj, fd, obj->bss_base, handler, data))
   {
     rtems_rtl_alloc_module_del (&obj->text_base, &obj->const_base, &obj->eh_base,




More information about the vc mailing list