[PATCH 2/2] libdl: Realloc text memory if there are trampolines

chrisj at rtems.org chrisj at rtems.org
Sat Aug 26 23:30:36 UTC 2023


From: Chris Johns <chrisj at rtems.org>

- Add resize to the allocator interface

- Rework the trampoline variables in the obj struct
  to make better sense of what is happening

Closes #4944
---
 cpukit/include/rtems/rtl/rtl-allocator.h |  46 +++++-
 cpukit/include/rtems/rtl/rtl-obj.h       | 199 ++++++++++++----------
 cpukit/libdl/rtl-alloc-heap.c            |   5 +-
 cpukit/libdl/rtl-allocator.c             | 135 ++++++++++++---
 cpukit/libdl/rtl-elf.c                   |  35 ++--
 cpukit/libdl/rtl-mdreloc-aarch64.c       |  15 +-
 cpukit/libdl/rtl-mdreloc-arm.c           |   6 +
 cpukit/libdl/rtl-mdreloc-bfin.c          |   6 +
 cpukit/libdl/rtl-mdreloc-i386.c          |   6 +
 cpukit/libdl/rtl-mdreloc-lm32.c          |   6 +
 cpukit/libdl/rtl-mdreloc-m68k.c          |   6 +
 cpukit/libdl/rtl-mdreloc-mips.c          |   6 +
 cpukit/libdl/rtl-mdreloc-moxie.c         |   6 +
 cpukit/libdl/rtl-mdreloc-powerpc.c       |   6 +
 cpukit/libdl/rtl-mdreloc-riscv.c         |   6 +
 cpukit/libdl/rtl-mdreloc-sparc.c         |   6 +
 cpukit/libdl/rtl-mdreloc-v850.c          |   6 +
 cpukit/libdl/rtl-obj.c                   | 202 +++++++++++++++--------
 cpukit/libdl/rtl-shell.c                 |   2 +-
 testsuites/libtests/dl09/dl-load.c       |  16 +-
 20 files changed, 525 insertions(+), 196 deletions(-)

diff --git a/cpukit/include/rtems/rtl/rtl-allocator.h b/cpukit/include/rtems/rtl/rtl-allocator.h
index 8ffaf58c3c..7d291c65f4 100644
--- a/cpukit/include/rtems/rtl/rtl-allocator.h
+++ b/cpukit/include/rtems/rtl/rtl-allocator.h
@@ -1,7 +1,7 @@
 /* SPDX-License-Identifier: BSD-2-Clause */
 
 /*
- *  COPYRIGHT (c) 2012, 2018 Chris Johns <chrisj at rtems.org>
+ *  COPYRIGHT (c) 2012, 2018, 2023 Chris Johns <chrisj at rtems.org>
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -69,6 +69,7 @@ typedef enum rtems_rtl_alloc_tags rtems_rtl_alloc_tag;
 enum rtems_rtl_alloc_cmd {
   RTEMS_RTL_ALLOC_NEW,        /**< Allocate new memory. */
   RTEMS_RTL_ALLOC_DEL,        /**< Delete allocated memory. */
+  RTEMS_RTL_ALLOC_RESIZE,     /**< Resize allocated memory. */
   RTEMS_RTL_ALLOC_LOCK,       /**< Lock the allocator. */
   RTEMS_RTL_ALLOC_UNLOCK,     /**< Unlock the allocator. */
   RTEMS_RTL_ALLOC_WR_ENABLE,  /**< Enable writes to the memory. */
@@ -142,6 +143,25 @@ 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 resize resizes allocated memory.
+ *
+ * This call resizes a previously allocated block of memory. If the
+ * provided address cannot be resized it is deleted and a new block is
+ * allocated and the contents of the existing memory is copied.
+ *
+ *
+ * @param tag The type of allocation request.
+ * @param address The memory address to resize. A NULL is ignored.
+ * @param size The size of the allocation.
+ * @param zero If true the memory is cleared.
+ * @return void* The memory address or NULL is not memory available.
+ */
+void* rtems_rtl_alloc_resize (rtems_rtl_alloc_tag tag,
+                              void*               address,
+                              size_t              size,
+                              bool                zero);
+
 /**
  * The Runtime Loader allocator lock. An allocator that depends on a
  * separate allocation process, for example the heap, may need to be
@@ -266,6 +286,30 @@ bool rtems_rtl_alloc_module_new (void** text_base, size_t text_size,
                                  void** data_base, size_t data_size,
                                  void** bss_base, size_t bss_size);
 
+/**
+ * Resize the allocated memory for a module given the new size of the text,
+ * const, data and bss sections. If any part of the allocation fails the
+ * allocated is deleted.
+ *
+ * @param text_base Pointer to the text base pointer.
+ * @param text_size The size of the read/exec section.
+ * @param const_base Pointer to the const base pointer.
+ * @param const_size The size of the read only section.
+ * @param eh_base Pointer to the eh base pointer.
+ * @param eh_size The size of the eh section.
+ * @param data_base Pointer to the data base pointer.
+ * @param data_size The size of the read/write secton.
+ * @param bss_base Pointer to the bss base pointer.
+ * @param bss_size The size of the read/write.
+ * @retval true The memory has been allocated.
+ * @retval false The allocation of memory has failed.
+ */
+bool rtems_rtl_alloc_module_resize (void** text_base, size_t text_size,
+                                    void** const_base, size_t const_size,
+                                    void** eh_base, size_t eh_size,
+                                    void** data_base, size_t data_size,
+                                    void** bss_base, size_t bss_size);
+
 /**
  * Free the memory allocated to a module.
  *
diff --git a/cpukit/include/rtems/rtl/rtl-obj.h b/cpukit/include/rtems/rtl/rtl-obj.h
index 6b47eb1205..3523958bfd 100644
--- a/cpukit/include/rtems/rtl/rtl-obj.h
+++ b/cpukit/include/rtems/rtl/rtl-obj.h
@@ -198,65 +198,66 @@ typedef bool (*rtems_rtl_obj_depends_iterator) (rtems_rtl_obj* obj,
  */
 struct rtems_rtl_obj
 {
-  rtems_chain_node    link;         /**< The node's link in the chain. */
-  uint32_t            flags;        /**< The status of the object file. */
-  size_t              users;        /**< Users of this object file, number of loads. */
-  size_t              refs;         /**< References to the object file. */
-  int                 format;       /**< The format of the object file. */
-  const char*         fname;        /**< The file name for the object. */
-  const char*         oname;        /**< The object file name. Can be
-                                     *   relative. */
-  const char*         aname;        /**< The archive name containing the
-                                     *   object. NULL means the object is not
-                                     *   in a lib */
-  off_t               ooffset;      /**< The object offset in the archive. */
-  size_t              fsize;        /**< Size of the object file. */
-  rtems_chain_control sections;     /**< The sections of interest in the object
-                                     *   file. */
-  rtems_chain_control dependents;   /**< The dependent object files. */
-  rtems_rtl_obj_sym*  local_table;  /**< Local symbol table. */
-  size_t              local_syms;   /**< Local symbol count. */
-  size_t              local_size;   /**< Local symbol memory usage. */
-  rtems_rtl_obj_sym*  global_table; /**< Global symbol table. */
-  size_t              global_syms;  /**< Global symbol count. */
-  size_t              global_size;  /**< Global symbol memory usage. */
-  size_t              unresolved;   /**< The number of unresolved relocations. */
-  void*               text_base;    /**< The base address of the text section
-                                     *   in memory. */
-  size_t              text_size;    /**< The size of the text section. */
-  void*               const_base;   /**< The base address of the const section
-                                     *   in memory. */
-  size_t              const_size;   /**< The size of the const section. */
-  void*               eh_base;      /**< The base address of the eh section in
-                                     *   memory. */
-  size_t              eh_size;      /**< The size of the eh section. */
-  void*               data_base;    /**< The base address of the data section
-                                     *   in memory. */
-  size_t              data_size;    /**< The size of the data section. */
-  void*               bss_base;     /**< The base address of the bss section in
-                                     *   memory. */
-  size_t              bss_size;     /**< The size of the bss section. */
-  size_t              exec_size;    /**< The amount of executable memory
-                                     *   allocated */
-  void*               entry;        /**< The entry point of the module. */
-  uint32_t            checksum;     /**< The checksum of the text sections. A
-                                     *   zero means do not checksum. */
-  uint32_t*           sec_num;      /**< The sec nums of each obj. */
-  uint32_t            obj_num;      /**< The count of elf files in an rtl
-                                     *   obj. */
-  void*               trampoline;   /**< Trampoline memory. Used for fixups or
-                                     *   veneers */
-  size_t              tramp_size;   /**< Size of a tramopline slot. */
-  size_t              tramps_size;  /**< Size of the trampoline memory. */
-  void*               tramp_brk;    /**< Trampoline memory allocator. MD
-                                     *   relocators can take memory from the
-                                     *   break up to the size. */
-  size_t              tramp_relocs; /**< Number of slots reserved for
-                                     *   relocs. The remainder are for
-                                     *   unresolved symbols. */
-  struct link_map*    linkmap;      /**< For GDB. */
-  void*               loader;       /**< The file details specific to a
-                                     *   loader. */
+  rtems_chain_node    link;            /**< The node's link in the chain. */
+  uint32_t            flags;           /**< The status of the object file. */
+  size_t              users;           /**< Users of this object file, number of loads. */
+  size_t              refs;            /**< References to the object file. */
+  int                 format;          /**< The format of the object file. */
+  const char*         fname;           /**< The file name for the object. */
+  const char*         oname;           /**< The object file name. Can be
+                                        *   relative. */
+  const char*         aname;           /**< The archive name containing the
+                                        *   object. NULL means the object is not
+                                        *   in a lib */
+  off_t               ooffset;         /**< The object offset in the archive. */
+  size_t              fsize;           /**< Size of the object file. */
+  rtems_chain_control sections;        /**< The sections of interest in the object
+                                        *   file. */
+  rtems_chain_control dependents;      /**< The dependent object files. */
+  rtems_rtl_obj_sym*  local_table;     /**< Local symbol table. */
+  size_t              local_syms;      /**< Local symbol count. */
+  size_t              local_size;      /**< Local symbol memory usage. */
+  rtems_rtl_obj_sym*  global_table;    /**< Global symbol table. */
+  size_t              global_syms;     /**< Global symbol count. */
+  size_t              global_size;     /**< Global symbol memory usage. */
+  size_t              unresolved;      /**< The number of unresolved relocations. */
+  void*               text_base;       /**< The base address of the text section
+                                        *   in memory. */
+  size_t              text_size;       /**< The size of the text section. */
+  void*               const_base;      /**< The base address of the const section
+                                        *   in memory. */
+  size_t              const_size;      /**< The size of the const section. */
+  void*               eh_base;         /**< The base address of the eh section in
+                                        *   memory. */
+  size_t              eh_size;         /**< The size of the eh section. */
+  void*               data_base;       /**< The base address of the data section
+                                        *   in memory. */
+  size_t              data_size;       /**< The size of the data section. */
+  void*               bss_base;        /**< The base address of the bss section in
+                                        *   memory. */
+  size_t              bss_size;        /**< The size of the bss section. */
+  size_t              exec_size;       /**< The amount of executable memory
+                                        *   allocated */
+  void*               entry;           /**< The entry point of the module. */
+  uint32_t            checksum;        /**< The checksum of the text sections. A
+                                        *   zero means do not checksum. */
+  uint32_t*           sec_num;         /**< The sec nums of each obj. */
+  uint32_t            obj_num;         /**< The count of elf files in an rtl
+                                        *   obj. */
+  void*               tramp_base;      /**< Trampoline memory. Used for fixups or
+                                        *   veneers */
+  size_t              tramp_size;      /**< Size of a trampoline memory. */
+  size_t              tramp_slots;     /**< The number of tampoline slots. */
+  size_t              tramp_slot_size; /**< The number of tampoline slots. */
+  void*               tramp_brk;       /**< Trampoline memory allocator. MD
+                                        *   relocators can take memory from the
+                                        *   break up to the size. */
+  size_t              tramp_relocs;    /**< Number of slots reserved for
+                                        *   relocs. The remainder are for
+                                        *   unresolved symbols. */
+  struct link_map*    linkmap;         /**< For GDB. */
+  void*               loader;          /**< The file details specific to a
+                                        *   loader. */
 };
 
 /**
@@ -386,6 +387,17 @@ static inline bool rtems_rtl_obj_has_symbol (const rtems_rtl_obj*     obj,
           sym < (obj->global_table + obj->global_syms));
 }
 
+/**
+ * Does the object file have any trampolines?
+ *
+ * @param obj The object file's descriptor to check for available space.
+ * @retval bool Returns @true if the object file has trampolines
+ */
+static inline size_t rtems_rtl_obj_has_trampolines (const rtems_rtl_obj* obj)
+{
+  return obj->tramp_slot_size != 0 && obj->tramp_slots != 0;
+}
+
 /**
  * Is there space in the trampoline memory for a trapoline.
  *
@@ -395,7 +407,7 @@ static inline bool rtems_rtl_obj_has_symbol (const rtems_rtl_obj*     obj,
  */
 static inline size_t rtems_rtl_obj_tramp_avail_space (const rtems_rtl_obj* obj)
 {
-  return (char*) obj->tramp_brk - (char*) obj->trampoline;
+  return (char*) obj->tramp_brk - (char*) obj->tramp_base;
 }
 
 /**
@@ -408,8 +420,8 @@ static inline size_t rtems_rtl_obj_tramp_avail_space (const rtems_rtl_obj* obj)
 static inline bool rtems_rtl_obj_has_tramp_space (const rtems_rtl_obj* obj,
                                                   const size_t         size)
 {
-  return (obj->trampoline != NULL &&
-          (rtems_rtl_obj_tramp_avail_space (obj) + size) <= obj->tramps_size);
+  return (obj->tramp_base != NULL &&
+          (rtems_rtl_obj_tramp_avail_space (obj) + size) <= obj->tramp_size);
 }
 
 /**
@@ -420,20 +432,19 @@ static inline bool rtems_rtl_obj_has_tramp_space (const rtems_rtl_obj* obj,
  */
 static inline size_t rtems_rtl_obj_trampoline_slots (const rtems_rtl_obj* obj)
 {
-  return obj->trampoline == NULL || obj->tramp_size == 0 ?
-    0 : obj->tramps_size / obj->tramp_size;
+  return obj->tramp_slots;
 }
 
 /**
- * Number of trampolines.
+ * Number of trampoline slot available.
  *
  * @param obj The object file's descriptor.
- * @retval size_t The number of trampolines.
+ * @retval size_t The number of trampoline slots available.
  */
 static inline size_t rtems_rtl_obj_trampolines (const rtems_rtl_obj* obj)
 {
-  return obj->trampoline == NULL || obj->tramp_size == 0 ?
-    0 : rtems_rtl_obj_tramp_avail_space (obj) / obj->tramp_size;
+  return obj->tramp_base == NULL || obj->tramp_slots == 0 ?
+    0 : rtems_rtl_obj_tramp_avail_space (obj) / obj->tramp_slot_size;
 }
 
 /**
@@ -571,22 +582,6 @@ rtems_rtl_obj_sect* rtems_rtl_obj_find_section_by_mask (const rtems_rtl_obj* obj
                                                         int                  index,
                                                         uint32_t             mask);
 
-/**
- * Allocate a table for trampoline fixup calls.
- *
- * @param obj The object file's descriptor.
- * @retval true The table was allocated.
- * @retval false The alloction failed.
- */
-bool rtems_rtl_obj_alloc_trampoline (rtems_rtl_obj* obj);
-
-/**
- * Erase the object file descriptor's trampoline table..
- *
- * @param obj The object file's descriptor.
- */
-void rtems_rtl_obj_erase_trampoline (rtems_rtl_obj* obj);
-
 /**
  * Allocate a table for dependent objects.
  *
@@ -749,6 +744,24 @@ size_t rtems_rtl_obj_bss_size (const rtems_rtl_obj* obj);
  */
 uint32_t rtems_rtl_obj_bss_alignment (const rtems_rtl_obj* obj);
 
+/**
+ * The trampoline size.
+ *
+ * @param obj The object file's descriptor.
+ * @return size_t The size of the trampoline memory of the object file.
+ */
+size_t rtems_rtl_obj_tramp_size (const rtems_rtl_obj* obj);
+
+/**
+ * The trampolinme alignment for the architecture.
+ *
+ * This is implemented and set in the architecture backend.
+ *
+ * @param obj The object file's descriptor.
+ * @return uint32_t The alignment. Can be 0 or 1 for not aligned or the alignment.
+ */
+uint32_t rtems_rtl_obj_tramp_alignment (const rtems_rtl_obj* obj);
+
 /**
  * Relocate the object file. The object file's section are parsed for any
  * relocation type sections.
@@ -810,11 +823,19 @@ bool rtems_rtl_obj_load_symbols (rtems_rtl_obj*             obj,
  * @retval true The object has been sucessfully loaded.
  * @retval false The load failed. The RTL error has been set.
  */
-bool
-rtems_rtl_obj_alloc_sections (rtems_rtl_obj*             obj,
-                              int                        fd,
-                              rtems_rtl_obj_sect_handler handler,
-                              void*                      data);
+bool rtems_rtl_obj_alloc_sections (rtems_rtl_obj*             obj,
+                                   int                        fd,
+                                   rtems_rtl_obj_sect_handler handler,
+                                   void*                      data);
+
+/**
+ * Resize the sections.
+ *
+ * @param obj The object file's descriptor.
+ * @retval true The object has been sucessfully loaded.
+ * @retval false The load failed. The RTL error has been set.
+ */
+bool rtems_rtl_obj_resize_sections (rtems_rtl_obj* obj);
 
 /**
  * Load the sections that have been allocated memory in the target. The bss
diff --git a/cpukit/libdl/rtl-alloc-heap.c b/cpukit/libdl/rtl-alloc-heap.c
index 10150a0753..f90233874e 100644
--- a/cpukit/libdl/rtl-alloc-heap.c
+++ b/cpukit/libdl/rtl-alloc-heap.c
@@ -9,7 +9,7 @@
  */
 
 /*
- *  COPYRIGHT (c) 2012 Chris Johns <chrisj at rtems.org>
+ *  COPYRIGHT (c) 2012,2023 Chris Johns <chrisj at rtems.org>
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -54,6 +54,9 @@ rtems_rtl_alloc_heap (rtems_rtl_alloc_cmd cmd,
       free (*address);
       *address = NULL;
       break;
+    case RTEMS_RTL_ALLOC_RESIZE:
+      *address = realloc (*address, size);
+      break;
     case RTEMS_RTL_ALLOC_LOCK:
       _RTEMS_Lock_allocator();
       break;
diff --git a/cpukit/libdl/rtl-allocator.c b/cpukit/libdl/rtl-allocator.c
index f09690d71a..7503183367 100644
--- a/cpukit/libdl/rtl-allocator.c
+++ b/cpukit/libdl/rtl-allocator.c
@@ -9,7 +9,7 @@
  */
 
 /*
- *  COPYRIGHT (c) 2012, 2018 Chris Johns <chrisj at rtems.org>
+ *  COPYRIGHT (c) 2012, 2018, 2023 Chris Johns <chrisj at rtems.org>
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -110,6 +110,39 @@ rtems_rtl_alloc_del (rtems_rtl_alloc_tag tag, void* address)
   rtems_rtl_unlock ();
 }
 
+void* rtems_rtl_alloc_resize (rtems_rtl_alloc_tag tag,
+                              void*               address,
+                              size_t              size,
+                              bool                zero)
+{
+  rtems_rtl_data* rtl = rtems_rtl_lock ();
+  const void* prev_address = address;
+
+  /*
+   * Resize memory of an existing allocation. The address field is set
+   * by the allocator and may change.
+   */
+  if (rtl != NULL)
+    rtl->allocator.allocator (RTEMS_RTL_ALLOC_RESIZE, tag, &address, size);
+
+  rtems_rtl_unlock ();
+
+  if (rtems_rtl_trace (RTEMS_RTL_TRACE_ALLOCATOR))
+    printf ("rtl: alloc: resize: %s%s prev-addr=%p addr=%p size=%zu\n",
+            rtems_rtl_trace_tag_label (tag), prev_address == address ? "" : " MOVED",
+            prev_address, address, size);
+
+  /*
+   * Only zero the memory if asked to and the resize was successful. We
+   * cannot clear the resized area if bigger than the previouis allocation
+   * because we do not have the original size.
+   */
+  if (address != NULL && zero)
+    memset (address, 0, size);
+
+  return address;
+}
+
 void
 rtems_rtl_alloc_wr_enable (rtems_rtl_alloc_tag tag, void* address)
 {
@@ -277,21 +310,23 @@ rtems_rtl_alloc_module_new (void** text_base, size_t text_size,
 {
   *text_base = *const_base = *data_base = *bss_base = NULL;
 
-  if (text_size)
+  if (data_size != 0)
   {
-    *text_base = rtems_rtl_alloc_new (rtems_rtl_alloc_text_tag (),
-                                      text_size, false);
-    if (!*text_base)
+    *data_base = rtems_rtl_alloc_new (rtems_rtl_alloc_data_tag (),
+                                      data_size, false);
+    if (*data_base == NULL)
     {
+      rtems_rtl_alloc_module_del (text_base, const_base, eh_base,
+                                  data_base, bss_base);
       return false;
     }
   }
 
-  if (const_size)
+  if (bss_size != 0)
   {
-    *const_base = rtems_rtl_alloc_new (rtems_rtl_alloc_const_tag (),
-                                       const_size, false);
-    if (!*const_base)
+    *bss_base = rtems_rtl_alloc_new (rtems_rtl_alloc_bss_tag (),
+                                     bss_size, false);
+    if (*bss_base == NULL)
     {
       rtems_rtl_alloc_module_del (text_base, const_base, eh_base,
                                   data_base, bss_base);
@@ -299,11 +334,11 @@ rtems_rtl_alloc_module_new (void** text_base, size_t text_size,
     }
   }
 
-  if (eh_size)
+  if (eh_size != 0)
   {
     *eh_base = rtems_rtl_alloc_new (rtems_rtl_alloc_eh_tag (),
                                     eh_size, false);
-    if (!*eh_base)
+    if (*eh_base == NULL)
     {
       rtems_rtl_alloc_module_del (text_base, const_base, eh_base,
                                   data_base, bss_base);
@@ -311,11 +346,11 @@ rtems_rtl_alloc_module_new (void** text_base, size_t text_size,
     }
   }
 
-  if (data_size)
+  if (const_size != 0)
   {
-    *data_base = rtems_rtl_alloc_new (rtems_rtl_alloc_data_tag (),
-                                      data_size, false);
-    if (!*data_base)
+    *const_base = rtems_rtl_alloc_new (rtems_rtl_alloc_const_tag (),
+                                       const_size, false);
+    if (*const_base == NULL)
     {
       rtems_rtl_alloc_module_del (text_base, const_base, eh_base,
                                   data_base, bss_base);
@@ -323,14 +358,72 @@ rtems_rtl_alloc_module_new (void** text_base, size_t text_size,
     }
   }
 
-  if (bss_size)
+  if (text_size != 0)
   {
-    *bss_base = rtems_rtl_alloc_new (rtems_rtl_alloc_bss_tag (),
-                                     bss_size, false);
-    if (!*bss_base)
+    *text_base = rtems_rtl_alloc_new (rtems_rtl_alloc_text_tag (),
+                                      text_size, false);
+    if (*text_base == NULL)
+    {
+      return false;
+    }
+  }
+
+  return true;
+}
+
+bool
+rtems_rtl_alloc_module_resize (void** text_base, size_t text_size,
+                               void** const_base, size_t const_size,
+                               void** eh_base, size_t eh_size,
+                               void** data_base, size_t data_size,
+                               void** bss_base, size_t bss_size)
+{
+  if (data_size != 0)
+  {
+    *data_base = rtems_rtl_alloc_resize (rtems_rtl_alloc_data_tag (),
+                                         *data_base, data_size, false);
+    if (*data_base == NULL)
+    {
+      return false;
+    }
+  }
+
+  if (bss_size != 0)
+  {
+    *bss_base = rtems_rtl_alloc_resize (rtems_rtl_alloc_bss_tag (),
+                                        *bss_base, bss_size, false);
+    if (*bss_base == NULL)
+    {
+      return false;
+    }
+  }
+
+  if (eh_size != 0)
+  {
+    *eh_base = rtems_rtl_alloc_resize (rtems_rtl_alloc_eh_tag (),
+                                       *eh_base, eh_size, false);
+    if (*eh_base == NULL)
+    {
+      return false;
+    }
+  }
+
+  if (const_size != 0)
+  {
+    *const_base = rtems_rtl_alloc_resize (rtems_rtl_alloc_const_tag (),
+                                          *const_base, const_size, false);
+    if (*const_base == NULL)
+    {
+      return false;
+    }
+  }
+
+  if (text_size != 0)
+  {
+    *text_base = rtems_rtl_alloc_resize (rtems_rtl_alloc_text_tag (),
+                                         *text_base, text_size, false);
+    if (*text_base == NULL)
     {
-      rtems_rtl_alloc_module_del (text_base, const_base, eh_base,
-                                  data_base, bss_base);
       return false;
     }
   }
diff --git a/cpukit/libdl/rtl-elf.c b/cpukit/libdl/rtl-elf.c
index b46d2ac3a0..dd6d8617bb 100644
--- a/cpukit/libdl/rtl-elf.c
+++ b/cpukit/libdl/rtl-elf.c
@@ -805,7 +805,7 @@ rtems_rtl_elf_tramp_resolve_reloc (rtems_rtl_unresolv_rec* rec,
       }
 
       if (unresolved || rs == rtems_rtl_elf_rel_tramp_add)
-        tramp->obj->tramps_size += tramp->obj->tramp_size;
+        ++tramp->obj->tramp_slots;
       if (rs == rtems_rtl_elf_rel_failure)
       {
         *failure = true;
@@ -818,7 +818,7 @@ rtems_rtl_elf_tramp_resolve_reloc (rtems_rtl_unresolv_rec* rec,
 }
 
 static bool
-rtems_rtl_elf_alloc_trampoline (rtems_rtl_obj* obj, size_t unresolved)
+rtems_rtl_elf_find_trampolines (rtems_rtl_obj* obj, size_t unresolved)
 {
   rtems_rtl_tramp_data td =  { 0 };
   td.obj = obj;
@@ -829,21 +829,20 @@ rtems_rtl_elf_alloc_trampoline (rtems_rtl_obj* obj, size_t unresolved)
   if (td.failure)
     return false;
   rtems_rtl_trampoline_remove (obj);
-  obj->tramp_relocs = obj->tramp_size == 0 ? 0 : obj->tramps_size / obj->tramp_size;
+  obj->tramp_relocs = obj->tramp_slots;
   if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
-    printf ("rtl: tramp:elf: tramps: %zu count:%zu total:%zu\n",
+    printf ("rtl: tramp:elf: tramps: slots:%zu count:%zu total:%zu\n",
             obj->tramp_relocs, td.count, td.total);
   /*
    * Add on enough space to handle the unresolved externals that need to be
    * resolved at some point in time. They could all require fixups and
    * trampolines.
    */
-  obj->tramps_size += obj->tramp_size * unresolved;
+  obj->tramp_slots += unresolved;
   if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
-    printf ("rtl: tramp:elf: slots: %zu (%zu)\n",
-            obj->tramp_size == 0 ? 0 : obj->tramps_size / obj->tramp_size,
-            obj->tramps_size);
-  return rtems_rtl_obj_alloc_trampoline (obj);
+    printf ("rtl: tramp:elf: slots:%zu (%zu)\n",
+            obj->tramp_slots, obj->tramp_slots * obj->tramp_slot_size);
+  return true;
 }
 
 static bool
@@ -1730,7 +1729,7 @@ rtems_rtl_elf_file_load (rtems_rtl_obj* obj, int fd)
   /*
    * Set the format's architecture's maximum tramp size.
    */
-  obj->tramp_size = rtems_rtl_elf_relocate_tramp_max_size ();
+  obj->tramp_slot_size = rtems_rtl_elf_relocate_tramp_max_size ();
 
   /*
    * Parse the section information first so we have the memory map of the object
@@ -1779,13 +1778,23 @@ rtems_rtl_elf_file_load (rtems_rtl_obj* obj, int fd)
   if (!rtems_rtl_obj_alloc_sections (obj, fd, rtems_rtl_elf_arch_alloc, &ehdr))
     return false;
 
-  if (!rtems_rtl_obj_load_symbols (obj, fd, rtems_rtl_elf_symbols_locate, &ehdr))
+  if (!rtems_rtl_elf_dependents (obj, &relocs))
     return false;
 
-  if (!rtems_rtl_elf_dependents (obj, &relocs))
+  if (!rtems_rtl_elf_find_trampolines (obj, relocs.unresolved))
     return false;
 
-  if (!rtems_rtl_elf_alloc_trampoline (obj, relocs.unresolved))
+  /*
+   * Resize the sections to allocate the trampoline memory as part of
+   * the text section.
+   */
+  if (rtems_rtl_obj_has_trampolines (obj))
+  {
+    if (!rtems_rtl_obj_resize_sections (obj))
+      return false;
+  }
+
+  if (!rtems_rtl_obj_load_symbols (obj, fd, rtems_rtl_elf_symbols_locate, &ehdr))
     return false;
 
   /*
diff --git a/cpukit/libdl/rtl-mdreloc-aarch64.c b/cpukit/libdl/rtl-mdreloc-aarch64.c
index e6c6ba3627..792dc91b2e 100644
--- a/cpukit/libdl/rtl-mdreloc-aarch64.c
+++ b/cpukit/libdl/rtl-mdreloc-aarch64.c
@@ -163,6 +163,12 @@ get_veneer_size(int type)
   return 16;
 }
 
+uint32_t rtems_rtl_obj_tramp_alignment (const rtems_rtl_obj* obj)
+{
+  (void) obj;
+  return sizeof(uint64_t);
+}
+
 size_t
 rtems_rtl_elf_relocate_tramp_max_size (void)
 {
@@ -386,6 +392,7 @@ rtems_rtl_elf_reloc_rela (rtems_rtl_obj*            obj,
         target -= (uintptr_t)where >> 12;
 
         if (checkoverflow(target, 21, raddr, " x 4k", where, off)) {
+          printf("]] %d\n", __LINE__);
           return rtems_rtl_elf_rel_failure;
         }
 
@@ -416,6 +423,10 @@ rtems_rtl_elf_reloc_rela (rtems_rtl_obj*            obj,
         return rtems_rtl_elf_rel_failure;
       }
 
+      if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+        printf ("rtl: JUMP26/PC26/CALL: insn=%p where=%p target=%p raddr=%p parsing=%d\n",
+                insn, (void*) where, (void*) target, (void*) raddr, parsing);
+
       target = (intptr_t)target >> 2;
 
       if (((Elf_Sword)target > 0x1FFFFFF) || ((Elf_Sword)target < -0x2000000)) {
@@ -435,9 +446,8 @@ rtems_rtl_elf_reloc_rela (rtems_rtl_obj*            obj,
           return rtems_rtl_elf_rel_failure;
         }
 
-        tramp_addr = ((Elf_Addr)(uintptr_t)obj->tramp_brk) | (symvalue & 1);
+        tramp_addr = ((Elf_Addr)(uintptr_t) obj->tramp_brk) | (symvalue & 1);
         obj->tramp_brk = set_veneer(obj->tramp_brk, symvalue);
-
         target = tramp_addr + rela->r_addend - (uintptr_t)where;
         target = (uintptr_t)target >> 2;
       }
@@ -462,6 +472,7 @@ rtems_rtl_elf_reloc_rela (rtems_rtl_obj*            obj,
         raddr = (Elf_Addr)symvalue + rela->r_addend;
         target = raddr - (uintptr_t)where;
         if (checkoverflow(target, 32, raddr, "", where, off)) {
+          printf("]] %d\n", __LINE__);
           return rtems_rtl_elf_rel_failure;
         }
         *where32 = target;
diff --git a/cpukit/libdl/rtl-mdreloc-arm.c b/cpukit/libdl/rtl-mdreloc-arm.c
index b45708dd46..16efbe79da 100644
--- a/cpukit/libdl/rtl-mdreloc-arm.c
+++ b/cpukit/libdl/rtl-mdreloc-arm.c
@@ -108,6 +108,12 @@ get_veneer_size(int type)
   return 8;
 }
 
+uint32_t rtems_rtl_obj_tramp_alignment (const rtems_rtl_obj* obj)
+{
+  (void) obj;
+  return sizeof(uint32_t);
+}
+
 size_t
 rtems_rtl_elf_relocate_tramp_max_size (void)
 {
diff --git a/cpukit/libdl/rtl-mdreloc-bfin.c b/cpukit/libdl/rtl-mdreloc-bfin.c
index f46b86ce34..cf3f3f88c0 100644
--- a/cpukit/libdl/rtl-mdreloc-bfin.c
+++ b/cpukit/libdl/rtl-mdreloc-bfin.c
@@ -99,6 +99,12 @@ load_ptr(void *where)
 	return (res);
 }
 
+uint32_t rtems_rtl_obj_tramp_alignment (const rtems_rtl_obj* obj)
+{
+  (void) obj;
+  return sizeof(uint32_t);
+}
+
 size_t
 rtems_rtl_elf_relocate_tramp_max_size (void)
 {
diff --git a/cpukit/libdl/rtl-mdreloc-i386.c b/cpukit/libdl/rtl-mdreloc-i386.c
index 40b09d4be2..09cbe4f42f 100644
--- a/cpukit/libdl/rtl-mdreloc-i386.c
+++ b/cpukit/libdl/rtl-mdreloc-i386.c
@@ -64,6 +64,12 @@ rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
   return true;
 }
 
+uint32_t rtems_rtl_obj_tramp_alignment (const rtems_rtl_obj* obj)
+{
+  (void) obj;
+  return sizeof(uint32_t);
+}
+
 size_t
 rtems_rtl_elf_relocate_tramp_max_size (void)
 {
diff --git a/cpukit/libdl/rtl-mdreloc-lm32.c b/cpukit/libdl/rtl-mdreloc-lm32.c
index de0609345f..af904cd126 100644
--- a/cpukit/libdl/rtl-mdreloc-lm32.c
+++ b/cpukit/libdl/rtl-mdreloc-lm32.c
@@ -92,6 +92,12 @@ rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
   return true;
 }
 
+uint32_t rtems_rtl_obj_tramp_alignment (const rtems_rtl_obj* obj)
+{
+  (void) obj;
+  return sizeof(uint32_t);
+}
+
 size_t
 rtems_rtl_elf_relocate_tramp_max_size (void)
 {
diff --git a/cpukit/libdl/rtl-mdreloc-m68k.c b/cpukit/libdl/rtl-mdreloc-m68k.c
index 873574ef7c..a88d612c28 100644
--- a/cpukit/libdl/rtl-mdreloc-m68k.c
+++ b/cpukit/libdl/rtl-mdreloc-m68k.c
@@ -77,6 +77,12 @@ rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
   return true;
 }
 
+uint32_t rtems_rtl_obj_tramp_alignment (const rtems_rtl_obj* obj)
+{
+  (void) obj;
+  return sizeof(uint32_t);
+}
+
 size_t
 rtems_rtl_elf_relocate_tramp_max_size (void)
 {
diff --git a/cpukit/libdl/rtl-mdreloc-mips.c b/cpukit/libdl/rtl-mdreloc-mips.c
index d43b144895..91d88c9986 100644
--- a/cpukit/libdl/rtl-mdreloc-mips.c
+++ b/cpukit/libdl/rtl-mdreloc-mips.c
@@ -93,6 +93,12 @@ rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
   return true;
 }
 
+uint32_t rtems_rtl_obj_tramp_alignment (const rtems_rtl_obj* obj)
+{
+  (void) obj;
+  return sizeof(uint32_t);
+}
+
 size_t
 rtems_rtl_elf_relocate_tramp_max_size (void)
 {
diff --git a/cpukit/libdl/rtl-mdreloc-moxie.c b/cpukit/libdl/rtl-mdreloc-moxie.c
index 6238ac99d2..a3cfe63b6a 100644
--- a/cpukit/libdl/rtl-mdreloc-moxie.c
+++ b/cpukit/libdl/rtl-mdreloc-moxie.c
@@ -93,6 +93,12 @@ rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
   return true;
 }
 
+uint32_t rtems_rtl_obj_tramp_alignment (const rtems_rtl_obj* obj)
+{
+  (void) obj;
+  return sizeof(uint32_t);
+}
+
 size_t
 rtems_rtl_elf_relocate_tramp_max_size (void)
 {
diff --git a/cpukit/libdl/rtl-mdreloc-powerpc.c b/cpukit/libdl/rtl-mdreloc-powerpc.c
index 49ed9e848c..09c2ab1512 100644
--- a/cpukit/libdl/rtl-mdreloc-powerpc.c
+++ b/cpukit/libdl/rtl-mdreloc-powerpc.c
@@ -207,6 +207,12 @@ rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
   return true;
 }
 
+uint32_t rtems_rtl_obj_tramp_alignment (const rtems_rtl_obj* obj)
+{
+  (void) obj;
+  return sizeof(uint32_t);
+}
+
 size_t
 rtems_rtl_elf_relocate_tramp_max_size (void)
 {
diff --git a/cpukit/libdl/rtl-mdreloc-riscv.c b/cpukit/libdl/rtl-mdreloc-riscv.c
index e6778dcc90..c0b7556366 100644
--- a/cpukit/libdl/rtl-mdreloc-riscv.c
+++ b/cpukit/libdl/rtl-mdreloc-riscv.c
@@ -89,6 +89,12 @@ rtems_rtl_elf_rel_resolve_sym (Elf_Word type) {
   return true;
 }
 
+uint32_t rtems_rtl_obj_tramp_alignment (const rtems_rtl_obj* obj)
+{
+  (void) obj;
+  return sizeof(uint32_t);
+}
+
 size_t
 rtems_rtl_elf_relocate_tramp_max_size (void) {
   /*
diff --git a/cpukit/libdl/rtl-mdreloc-sparc.c b/cpukit/libdl/rtl-mdreloc-sparc.c
index 7dd8a2af2f..9810de988e 100644
--- a/cpukit/libdl/rtl-mdreloc-sparc.c
+++ b/cpukit/libdl/rtl-mdreloc-sparc.c
@@ -209,6 +209,12 @@ rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
   return r;
 }
 
+uint32_t rtems_rtl_obj_tramp_alignment (const rtems_rtl_obj* obj)
+{
+  (void) obj;
+  return sizeof(uint32_t);
+}
+
 size_t
 rtems_rtl_elf_relocate_tramp_max_size (void)
 {
diff --git a/cpukit/libdl/rtl-mdreloc-v850.c b/cpukit/libdl/rtl-mdreloc-v850.c
index 8d1f3c02a7..826763a2b5 100644
--- a/cpukit/libdl/rtl-mdreloc-v850.c
+++ b/cpukit/libdl/rtl-mdreloc-v850.c
@@ -93,6 +93,12 @@ rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
   return true;
 }
 
+uint32_t rtems_rtl_obj_tramp_alignment (const rtems_rtl_obj* obj)
+{
+  (void) obj;
+  return sizeof(uint32_t);
+}
+
 size_t
 rtems_rtl_elf_relocate_tramp_max_size (void)
 {
diff --git a/cpukit/libdl/rtl-obj.c b/cpukit/libdl/rtl-obj.c
index 24d1e09048..a35fbf9e8d 100644
--- a/cpukit/libdl/rtl-obj.c
+++ b/cpukit/libdl/rtl-obj.c
@@ -137,7 +137,6 @@ rtems_rtl_obj_free (rtems_rtl_obj* obj)
   rtems_rtl_obj_erase_sections (obj);
   rtems_rtl_obj_erase_dependents (obj);
   rtems_rtl_symbol_obj_erase (obj);
-  rtems_rtl_obj_erase_trampoline (obj);
   rtems_rtl_obj_free_names (obj);
   if (obj->sec_num != NULL)
     free (obj->sec_num);
@@ -599,26 +598,6 @@ rtems_rtl_obj_find_section_by_mask (const rtems_rtl_obj* obj,
   return match.sect;
 }
 
-bool
-rtems_rtl_obj_alloc_trampoline (rtems_rtl_obj* obj)
-{
-  if (obj->tramps_size == 0)
-    return true;
-  obj->trampoline = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_OBJECT,
-                                         obj->tramps_size,
-                                         true);
-  if (obj->trampoline == NULL)
-    rtems_rtl_set_error (ENOMEM, "no memory for the trampoline");
-  obj->tramp_brk = obj->trampoline;
-  return obj->trampoline != NULL;
-}
-
-void
-rtems_rtl_obj_erase_trampoline (rtems_rtl_obj* obj)
-{
-  rtems_rtl_alloc_del (RTEMS_RTL_ALLOC_OBJECT, obj->trampoline);
-}
-
 bool
 rtems_rtl_obj_alloc_dependents (rtems_rtl_obj* obj, size_t dependents)
 {
@@ -828,6 +807,12 @@ rtems_rtl_obj_bss_size (const rtems_rtl_obj* obj)
   return rtems_rtl_obj_section_size (obj, RTEMS_RTL_OBJ_SECT_BSS);
 }
 
+size_t
+rtems_rtl_obj_tramp_size (const rtems_rtl_obj* obj)
+{
+  return obj->tramp_slots * obj->tramp_slot_size;
+}
+
 uint32_t
 rtems_rtl_obj_bss_alignment (const rtems_rtl_obj* obj)
 {
@@ -919,10 +904,10 @@ rtems_rtl_obj_synchronize_cache (rtems_rtl_obj* obj)
                                                    size);
   }
 
-  if (obj->trampoline != NULL)
+  if (obj->tramp_base != NULL)
   {
-    rtems_cache_instruction_sync_after_code_change(obj->trampoline,
-                                                   obj->tramps_size);
+    rtems_cache_instruction_sync_after_code_change(obj->tramp_base,
+                                                   obj->tramp_size);
   }
 }
 
@@ -1069,19 +1054,29 @@ rtems_rtl_obj_sections_locate (uint32_t            mask,
   }
 }
 
-bool
-rtems_rtl_obj_alloc_sections (rtems_rtl_obj*             obj,
-                              int                        fd,
-                              rtems_rtl_obj_sect_handler handler,
-                              void*                      data)
+static void
+rtems_rtl_obj_set_sizes (rtems_rtl_obj* obj)
 {
   size_t text_size;
+  size_t tramp_size;
   size_t const_size;
   size_t eh_size;
   size_t data_size;
   size_t bss_size;
 
-  text_size  = rtems_rtl_obj_text_size (obj) + rtems_rtl_obj_const_alignment (obj);
+  text_size  = rtems_rtl_obj_text_size (obj);
+  tramp_size = rtems_rtl_obj_tramp_size (obj);
+
+  if (tramp_size != 0)
+  {
+    text_size += rtems_rtl_obj_tramp_alignment (obj);
+    tramp_size += rtems_rtl_obj_const_alignment (obj);
+  }
+  else
+  {
+    text_size += rtems_rtl_obj_const_alignment (obj);
+  }
+
   const_size = rtems_rtl_obj_const_size (obj) + rtems_rtl_obj_eh_alignment (obj);
   eh_size    = rtems_rtl_obj_eh_size (obj) + rtems_rtl_obj_data_alignment (obj);
   data_size  = rtems_rtl_obj_data_size (obj) + rtems_rtl_obj_bss_alignment (obj);
@@ -1090,13 +1085,69 @@ rtems_rtl_obj_alloc_sections (rtems_rtl_obj*             obj,
   /*
    * Set the sizes held in the object data. We need this for a fast reference.
    */
-  obj->text_size  = text_size;
+  obj->text_size  = text_size + tramp_size;
+  obj->tramp_size = tramp_size;
   obj->const_size = const_size;
   obj->data_size  = data_size;
   obj->eh_size    = eh_size;
   obj->bss_size   = bss_size;
 
+  obj->exec_size = text_size + const_size + eh_size + data_size + bss_size;
+}
+
+static void
+rtems_rtl_obj_print_sizes (rtems_rtl_obj* obj, const char* label)
+{
+if (rtems_rtl_trace (RTEMS_RTL_TRACE_LOAD_SECT))
+  {
+    printf ("rtl: %s sect: text  - b:%p s:%zi a:%" PRIu32 "\n",
+            label, obj->text_base, obj->text_size, rtems_rtl_obj_text_alignment (obj));
+    printf ("rtl: %s sect: tramp - b:%p s:%zi a:%" PRIu32 "\n",
+            label, obj->tramp_base, obj->tramp_size, rtems_rtl_obj_tramp_alignment (obj));
+    printf ("rtl: %s sect: const - b:%p s:%zi a:%" PRIu32 "\n",
+            label, obj->const_base, obj->const_size, rtems_rtl_obj_const_alignment (obj));
+    printf ("rtl: %s sect: eh    - b:%p s:%zi a:%" PRIu32 "\n",
+            label, obj->eh_base, obj->eh_size, rtems_rtl_obj_eh_alignment (obj));
+    printf ("rtl: %s sect: data  - b:%p s:%zi a:%" PRIu32 "\n",
+            label, obj->data_base, obj->data_size, rtems_rtl_obj_data_alignment (obj));
+    printf ("rtl: %s sect: bss   - b:%p s:%zi a:%" PRIu32 "\n",
+            label, obj->bss_base, obj->bss_size, rtems_rtl_obj_bss_alignment (obj));
+  }
+}
+
+static void
+rtems_rtl_obj_locate (rtems_rtl_obj* obj)
+{
   /*
+   * Locate all text, data and bss sections in seperate operations so each type of
+   * section is grouped together.
+   */
+  rtems_rtl_obj_sections_locate (RTEMS_RTL_OBJ_SECT_TEXT,
+                                 rtems_rtl_alloc_text_tag (),
+                                 obj, obj->text_base);
+  rtems_rtl_obj_sections_locate (RTEMS_RTL_OBJ_SECT_CONST,
+                                 rtems_rtl_alloc_const_tag (),
+                                 obj, obj->const_base);
+  rtems_rtl_obj_sections_locate (RTEMS_RTL_OBJ_SECT_EH,
+                                 rtems_rtl_alloc_eh_tag (),
+                                 obj, obj->eh_base);
+  rtems_rtl_obj_sections_locate (RTEMS_RTL_OBJ_SECT_DATA,
+                                 rtems_rtl_alloc_data_tag (),
+                                 obj, obj->data_base);
+  rtems_rtl_obj_sections_locate (RTEMS_RTL_OBJ_SECT_BSS,
+                                 rtems_rtl_alloc_bss_tag (),
+                                 obj, obj->bss_base);
+}
+
+bool
+rtems_rtl_obj_alloc_sections (rtems_rtl_obj*             obj,
+                              int                        fd,
+                              rtems_rtl_obj_sect_handler handler,
+                              void*                      data)
+{
+  rtems_rtl_obj_set_sizes (obj);
+
+    /*
    * Perform any specific allocations for sections.
    */
   if (handler != NULL)
@@ -1116,33 +1167,28 @@ rtems_rtl_obj_alloc_sections (rtems_rtl_obj*             obj,
    * Let the allocator manage the actual allocation. The user can use the
    * standard heap or provide a specific allocator with memory protection.
    */
-  if (!rtems_rtl_alloc_module_new (&obj->text_base, text_size,
-                                   &obj->const_base, const_size,
-                                   &obj->eh_base, eh_size,
-                                   &obj->data_base, data_size,
-                                   &obj->bss_base, bss_size))
+  if (!rtems_rtl_alloc_module_new (&obj->text_base, obj->text_size,
+                                   &obj->const_base, obj->const_size,
+                                   &obj->eh_base, obj->eh_size,
+                                   &obj->data_base, obj->data_size,
+                                   &obj->bss_base, obj->bss_size))
   {
     obj->exec_size = 0;
     rtems_rtl_set_error (ENOMEM, "no memory to load obj");
     return false;
   }
 
-  obj->exec_size = text_size + const_size + eh_size + data_size + bss_size;
-
-  if (rtems_rtl_trace (RTEMS_RTL_TRACE_LOAD_SECT))
+  /*
+   * Set the trampoline base if there are trampolines
+   */
+  if (obj->tramp_size != 0)
   {
-    printf ("rtl: load sect: text  - b:%p s:%zi a:%" PRIu32 "\n",
-            obj->text_base, text_size, rtems_rtl_obj_text_alignment (obj));
-    printf ("rtl: load sect: const - b:%p s:%zi a:%" PRIu32 "\n",
-            obj->const_base, const_size, rtems_rtl_obj_const_alignment (obj));
-    printf ("rtl: load sect: eh    - b:%p s:%zi a:%" PRIu32 "\n",
-            obj->eh_base, eh_size, rtems_rtl_obj_eh_alignment (obj));
-    printf ("rtl: load sect: data  - b:%p s:%zi a:%" PRIu32 "\n",
-            obj->data_base, data_size, rtems_rtl_obj_data_alignment (obj));
-    printf ("rtl: load sect: bss   - b:%p s:%zi a:%" PRIu32 "\n",
-            obj->bss_base, bss_size, rtems_rtl_obj_bss_alignment (obj));
+    obj->tramp_base = obj->tramp_brk =
+      obj->text_base + obj->text_size - obj->tramp_size;
   }
 
+  rtems_rtl_obj_print_sizes (obj, "alloc");
+
   /*
    * Determine the load order.
    */
@@ -1153,24 +1199,48 @@ rtems_rtl_obj_alloc_sections (rtems_rtl_obj*             obj,
   rtems_rtl_obj_sections_link_order (RTEMS_RTL_OBJ_SECT_BSS,   obj);
 
   /*
-   * Locate all text, data and bss sections in seperate operations so each type of
-   * section is grouped together.
+   * Locate the sections to the allocated section bases
    */
-  rtems_rtl_obj_sections_locate (RTEMS_RTL_OBJ_SECT_TEXT,
-                                 rtems_rtl_alloc_text_tag (),
-                                 obj, obj->text_base);
-  rtems_rtl_obj_sections_locate (RTEMS_RTL_OBJ_SECT_CONST,
-                                 rtems_rtl_alloc_const_tag (),
-                                 obj, obj->const_base);
-  rtems_rtl_obj_sections_locate (RTEMS_RTL_OBJ_SECT_EH,
-                                 rtems_rtl_alloc_eh_tag (),
-                                 obj, obj->eh_base);
-  rtems_rtl_obj_sections_locate (RTEMS_RTL_OBJ_SECT_DATA,
-                                 rtems_rtl_alloc_data_tag (),
-                                 obj, obj->data_base);
-  rtems_rtl_obj_sections_locate (RTEMS_RTL_OBJ_SECT_BSS,
-                                 rtems_rtl_alloc_bss_tag (),
-                                 obj, obj->bss_base);
+  rtems_rtl_obj_locate (obj);
+
+  return true;
+}
+
+bool
+rtems_rtl_obj_resize_sections (rtems_rtl_obj* obj)
+{
+  rtems_rtl_obj_set_sizes (obj);
+
+  /*
+   * Let the allocator manage the resizing.
+   */
+  if (!rtems_rtl_alloc_module_resize (&obj->text_base, obj->text_size,
+                                      &obj->const_base, obj->const_size,
+                                      &obj->eh_base, obj->eh_size,
+                                      &obj->data_base, obj->data_size,
+                                      &obj->bss_base, obj->bss_size))
+  {
+    rtems_rtl_obj_free (obj);
+    obj->exec_size = 0;
+    rtems_rtl_set_error (ENOMEM, "no memory resize obj");
+    return false;
+  }
+
+  /*
+   * Set the trampoline base if there are trampolines
+   */
+  if (obj->tramp_size != 0)
+  {
+    obj->tramp_base = obj->tramp_brk =
+      obj->text_base + obj->text_size - obj->tramp_size;
+  }
+
+  rtems_rtl_obj_print_sizes (obj, "resize");
+
+  /*
+   * Locate the sections to the allocated section bases
+   */
+  rtems_rtl_obj_locate (obj);
 
   return true;
 }
diff --git a/cpukit/libdl/rtl-shell.c b/cpukit/libdl/rtl-shell.c
index 69de6bad83..18f1e08901 100644
--- a/cpukit/libdl/rtl-shell.c
+++ b/cpukit/libdl/rtl-shell.c
@@ -572,7 +572,7 @@ rtems_rtl_obj_printer (rtems_rtl_obj_print* print, rtems_rtl_obj* obj)
       rtems_printf (print->printer, "%-*cslots     : %zu\n", indent + 4, ' ',
                     slots);
       rtems_printf (print->printer, "%-*csize      : %zu\n", indent + 4, ' ',
-                    obj->tramps_size);
+                    obj->tramp_size);
       rtems_printf (print->printer, "%-*cslot size : %zu\n", indent + 4, ' ',
                     obj->tramp_size);
       rtems_printf (print->printer, "%-*cused      : %zu\n", indent + 4, ' ',
diff --git a/testsuites/libtests/dl09/dl-load.c b/testsuites/libtests/dl09/dl-load.c
index ce9708c3a3..216fb5a201 100644
--- a/testsuites/libtests/dl09/dl-load.c
+++ b/testsuites/libtests/dl09/dl-load.c
@@ -116,8 +116,12 @@ static void dl_check_resolved(void* handle, bool has_unresolved)
       rtems_test_assert (unresolved == 0);
     }
   }
-  printf ("handel: %p: %sunresolved externals\n",
-          handle, unresolved != 0 ? "" : "no ");
+  if (handle == RTLD_SELF)
+    printf ("handle: RTL_SELF: %sunresolved externals\n",
+            unresolved != 0 ? "" : "no ");
+  else
+    printf ("handle: %p: %sunresolved externals\n",
+            handle, unresolved != 0 ? "" : "no ");
 }
 
 static void* dl_load_obj (const char* name, bool has_unresolved)
@@ -152,12 +156,20 @@ static void dl_close (void* handle)
 
 static int dl_call (void* handle, const char* func)
 {
+  static call_sig last_call;
   call_sig call = dlsym (handle, func);
   if (call == NULL)
   {
     printf("dlsym failed: symbol not found: %s\n", func);
     return 1;
   }
+  if (last_call != NULL && last_call != call)
+  {
+    printf("Call location different: moved by: %i (call:%p last:%p)\n",
+           (int) (call - last_call),
+           call, last_call);
+  }
+  last_call = call;
   call ();
   return 0;
 }
-- 
2.37.1



More information about the devel mailing list