summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Johns <chrisj@rtems.org>2019-01-15 17:47:41 +1100
committerChris Johns <chrisj@rtems.org>2019-02-09 10:06:34 +1100
commitd8c70ba65b13cd023b50b8aed5d91e455017cdd5 (patch)
treef78c3441ef74a7315ef4f7850bd27631bf0d2502
parentlibdl: Fix the support for constructors and desctructors. (diff)
downloadrtems-d8c70ba65b13cd023b50b8aed5d91e455017cdd5.tar.bz2
libdl: Add support for trampolines
- Trampolines or fixups for veneers provide long jump support for instruciton sets that implement short relative address branches. The linker provides trampolines when creating a static image. This patch adds trampoline support to libdl and the ARM architecture. - The dl09 test requires enough memory so modules are outside the relative branch instruction ranges for the architecture. Updates #3685
-rw-r--r--cpukit/include/rtems/rtl/rtl-obj.h38
-rw-r--r--cpukit/libdl/rtl-elf.c57
-rw-r--r--cpukit/libdl/rtl-elf.h64
-rw-r--r--cpukit/libdl/rtl-mdreloc-arm.c301
-rw-r--r--cpukit/libdl/rtl-mdreloc-bfin.c54
-rw-r--r--cpukit/libdl/rtl-mdreloc-h8300.c54
-rw-r--r--cpukit/libdl/rtl-mdreloc-i386.c54
-rw-r--r--cpukit/libdl/rtl-mdreloc-lm32.c54
-rw-r--r--cpukit/libdl/rtl-mdreloc-m68k.c54
-rw-r--r--cpukit/libdl/rtl-mdreloc-mips.c70
-rw-r--r--cpukit/libdl/rtl-mdreloc-moxie.c54
-rw-r--r--cpukit/libdl/rtl-mdreloc-powerpc.c56
-rw-r--r--cpukit/libdl/rtl-mdreloc-sparc.c54
-rw-r--r--cpukit/libdl/rtl-mdreloc-v850.c54
-rw-r--r--cpukit/libdl/rtl-obj.c33
-rw-r--r--testsuites/libtests/Makefile.am48
-rw-r--r--testsuites/libtests/configure.ac1
-rw-r--r--testsuites/libtests/dl01/dl-load.c41
-rw-r--r--testsuites/libtests/dl08/dl-load.c36
-rw-r--r--testsuites/libtests/dl09/dl-load.c195
-rw-r--r--testsuites/libtests/dl09/dl-load.h21
-rw-r--r--testsuites/libtests/dl09/dl-o1.c61
-rw-r--r--testsuites/libtests/dl09/dl-o1.h23
-rw-r--r--testsuites/libtests/dl09/dl-o2.c39
-rw-r--r--testsuites/libtests/dl09/dl-o2.h25
-rw-r--r--testsuites/libtests/dl09/dl-o3.c40
-rw-r--r--testsuites/libtests/dl09/dl-o3.h15
-rw-r--r--testsuites/libtests/dl09/dl-o4.c40
-rw-r--r--testsuites/libtests/dl09/dl-o4.h29
-rw-r--r--testsuites/libtests/dl09/dl-o5.c36
-rw-r--r--testsuites/libtests/dl09/dl-o5.h30
-rw-r--r--testsuites/libtests/dl09/dl09.doc23
-rw-r--r--testsuites/libtests/dl09/dl09.scn390
-rw-r--r--testsuites/libtests/dl09/init.c90
34 files changed, 2088 insertions, 146 deletions
diff --git a/cpukit/include/rtems/rtl/rtl-obj.h b/cpukit/include/rtems/rtl/rtl-obj.h
index b7522a7d39..4ce356015c 100644
--- a/cpukit/include/rtems/rtl/rtl-obj.h
+++ b/cpukit/include/rtems/rtl/rtl-obj.h
@@ -1,5 +1,5 @@
/*
- * COPYRIGHT (c) 2012 Chris Johns <chrisj@rtems.org>
+ * COPYRIGHT (c) 2012,2019 Chris Johns <chrisj@rtems.org>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
@@ -220,6 +220,12 @@ struct rtems_rtl_obj
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 the tramopline memory. */
+ void* tramp_brk; /**< Trampoline memory allocator. MD
+ * relocators can take memory from the
+ * break upto the size. */
struct link_map* linkmap; /**< For GDB. */
void* loader; /**< The file details specific to a
* loader. */
@@ -353,6 +359,20 @@ static inline bool rtems_rtl_obj_has_symbol (const rtems_rtl_obj* obj,
}
/**
+ * Is there space in the trampoline memory for a trapoline.
+ *
+ * @param obj The object file's descriptor to check for available space.
+ * @param size The size to be allocated.
+ * @retval bool Returns @true if the space is available.
+ */
+static inline bool rtems_rtl_obj_has_ramp_space (const rtems_rtl_obj* obj,
+ const size_t size)
+{
+ return (obj->trampoline != NULL &&
+ ((obj->tramp_brk - obj->trampoline) + size) <= obj->tramp_size);
+}
+
+/**
* Allocate an object structure on the heap.
*
* @retval NULL No memory for the object.
@@ -477,6 +497,22 @@ rtems_rtl_obj_sect* rtems_rtl_obj_find_section_by_mask (const rtems_rtl_obj* obj
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.
*
* @param obj The object file's descriptor.
diff --git a/cpukit/libdl/rtl-elf.c b/cpukit/libdl/rtl-elf.c
index 63242acaae..96af16cb52 100644
--- a/cpukit/libdl/rtl-elf.c
+++ b/cpukit/libdl/rtl-elf.c
@@ -87,10 +87,7 @@ rtems_rtl_elf_find_symbol (rtems_rtl_obj* obj,
*/
*symbol = rtems_rtl_symbol_obj_find (obj, symname);
if (!*symbol)
- {
- rtems_rtl_set_error (EINVAL, "global symbol not found: %s", symname);
return false;
- }
*value = (Elf_Addr) (*symbol)->value;
return true;
@@ -100,10 +97,7 @@ rtems_rtl_elf_find_symbol (rtems_rtl_obj* obj,
sect = rtems_rtl_obj_find_section_by_index (obj, sym->st_shndx);
if (!sect)
- {
- rtems_rtl_set_error (EINVAL, "reloc symbol's section not found");
return false;
- }
*value = sym->st_value + (Elf_Addr) sect->base;
return true;
@@ -145,6 +139,35 @@ rtems_rtl_elf_reloc_parser (rtems_rtl_obj* obj,
void* data)
{
rtems_rtl_elf_reloc_data* rd = (rtems_rtl_elf_reloc_data*) data;
+
+ /*
+ * Check the reloc record to see if a trampoline is needed.
+ */
+ if (is_rela)
+ {
+ const Elf_Rela* rela = (const Elf_Rela*) relbuf;
+ if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+ printf ("rtl: rela tramp: sym:%s(%d)=%08jx type:%d off:%08jx addend:%d\n",
+ symname, (int) ELF_R_SYM (rela->r_info),
+ (uintmax_t) symvalue, (int) ELF_R_TYPE (rela->r_info),
+ (uintmax_t) rela->r_offset, (int) rela->r_addend);
+ if (!rtems_rtl_elf_relocate_rela_tramp (obj, rela, targetsect,
+ symname, sym->st_info, symvalue))
+ return false;
+ }
+ else
+ {
+ const Elf_Rel* rel = (const Elf_Rel*) relbuf;
+ if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+ printf ("rtl: rel tramp: sym:%s(%d)=%08jx type:%d off:%08jx\n",
+ symname, (int) ELF_R_SYM (rel->r_info),
+ (uintmax_t) symvalue, (int) ELF_R_TYPE (rel->r_info),
+ (uintmax_t) rel->r_offset);
+ if (!rtems_rtl_elf_relocate_rel_tramp (obj, rel, targetsect,
+ symname, sym->st_info, symvalue))
+ return false;
+ }
+
/*
* If the symbol has been resolved and there is a symbol name it is a global
* symbol and from another object file so add it as a dependency.
@@ -153,7 +176,7 @@ rtems_rtl_elf_reloc_parser (rtems_rtl_obj* obj,
{
++rd->unresolved;
}
- else if (resolved && symname != NULL)
+ else if (symname != NULL)
{
/*
* Find the symbol's object file. It cannot be NULL so ignore that result
@@ -557,6 +580,19 @@ rtems_rtl_elf_common (rtems_rtl_obj* obj,
}
static bool
+rtems_rtl_elf_alloc_trampoline (rtems_rtl_obj* obj, size_t unresolved)
+{
+ /*
+ * 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->tramp_size +=
+ rtems_rtl_elf_relocate_tramp_max_size () * unresolved;
+ return rtems_rtl_obj_alloc_trampoline (obj);
+}
+
+static bool
rtems_rtl_elf_dependents (rtems_rtl_obj* obj, rtems_rtl_elf_reloc_data* reloc)
{
/*
@@ -1297,12 +1333,19 @@ rtems_rtl_elf_file_load (rtems_rtl_obj* obj, int fd)
if (!rtems_rtl_obj_load_sections (obj, fd, rtems_rtl_elf_loader, &ehdr))
return false;
+ /*
+ * Parse the relocation records. It lets us know how many dependents
+ * and fixup trampolines there are.
+ */
if (!rtems_rtl_obj_relocate (obj, fd, rtems_rtl_elf_relocs_parser, &relocs))
return false;
if (!rtems_rtl_elf_dependents (obj, &relocs))
return false;
+ if (!rtems_rtl_elf_alloc_trampoline (obj, relocs.unresolved))
+ return false;
+
if (!rtems_rtl_obj_load_symbols (obj, fd, rtems_rtl_elf_symbols, &ehdr))
return false;
diff --git a/cpukit/libdl/rtl-elf.h b/cpukit/libdl/rtl-elf.h
index 1f5f82eb89..d781bfb3a4 100644
--- a/cpukit/libdl/rtl-elf.h
+++ b/cpukit/libdl/rtl-elf.h
@@ -52,6 +52,16 @@ extern "C" {
**/
/**
+ * Relocation trampoline relocation data.
+ */
+typedef struct rtems_rtl_mdreloc_trmap
+{
+ bool parsing; /**< The reloc records are being parsed. */
+ void* tampolines; /**< The trampoline memory. */
+ size_t size; /**< The trampoline size. */
+} rtems_rtl_mdreloc_tramp;
+
+/**
* Maximum string length. This a read buffering limit rather than a
* specific ELF length. I hope this is ok as I am concerned about
* some C++ symbol lengths.
@@ -81,6 +91,56 @@ uint32_t rtems_rtl_elf_section_flags (const rtems_rtl_obj* obj,
bool rtems_rtl_elf_rel_resolve_sym (Elf_Word type);
/**
+ * Architecture specific relocation maximum trampoline size. A trampoline entry
+ * of this size is allocated for each unresolved external.
+ *
+ * @return size_t The maximum size of a trampoline for this architecture.
+ */
+size_t rtems_rtl_elf_relocate_tramp_max_size (void);
+
+/**
+ * Architecture specific relocation trampoline handler compiled in for a
+ * specific architecture by the build system. The handler determines if the
+ * relocation record requires a trampoline.
+ *
+ * @param obj The object file being relocated.
+ * @param rel The ELF relocation record.
+ * @param sect The section of the object file the relocation is for.
+ * @param symname The symbol's name.
+ * @param syminfo The ELF symbol info field.
+ * @param symvalue If a symbol is referenced, this is the symbols value.
+ * @retval bool The relocation is valid.
+ * @retval bool The relocation is not valid.
+ */
+bool rtems_rtl_elf_relocate_rel_tramp (rtems_rtl_obj* obj,
+ const Elf_Rel* rel,
+ const rtems_rtl_obj_sect* sect,
+ const char* symname,
+ const Elf_Byte syminfo,
+ const Elf_Word symvalue);
+
+/**
+ * Architecture specific relocation handler compiled in for a specific
+ * architecture by the build system. The handler applies the relocation
+ * to the target.
+ *
+ * @param obj The object file being relocated.
+ * @param rela The ELF addend relocation record.
+ * @param sect The section of the object file the relocation is for.
+ * @param symname The symbol's name.
+ * @param syminfo The ELF symbol info field.
+ * @param symvalue If a symbol is referenced, this is the symbols value.
+ * @retval bool The relocation is valid.
+ * @retval bool The relocation is not valid.
+ */
+bool rtems_rtl_elf_relocate_rela_tramp (rtems_rtl_obj* obj,
+ const Elf_Rela* rela,
+ const rtems_rtl_obj_sect* sect,
+ const char* symname,
+ const Elf_Byte syminfo,
+ const Elf_Word symvalue);
+
+/**
* Architecture specific relocation handler compiled in for a specific
* architecture by the build system. The handler applies the relocation
* to the target.
@@ -94,7 +154,7 @@ bool rtems_rtl_elf_rel_resolve_sym (Elf_Word type);
* @retval bool The relocation has been applied.
* @retval bool The relocation could not be applied.
*/
-bool rtems_rtl_elf_relocate_rel (const rtems_rtl_obj* obj,
+bool rtems_rtl_elf_relocate_rel (rtems_rtl_obj* obj,
const Elf_Rel* rel,
const rtems_rtl_obj_sect* sect,
const char* symname,
@@ -115,7 +175,7 @@ bool rtems_rtl_elf_relocate_rel (const rtems_rtl_obj* obj,
* @retval bool The relocation has been applied.
* @retval bool The relocation could not be applied.
*/
-bool rtems_rtl_elf_relocate_rela (const rtems_rtl_obj* obj,
+bool rtems_rtl_elf_relocate_rela (rtems_rtl_obj* obj,
const Elf_Rela* rela,
const rtems_rtl_obj_sect* sect,
const char* symname,
diff --git a/cpukit/libdl/rtl-mdreloc-arm.c b/cpukit/libdl/rtl-mdreloc-arm.c
index ef00701d32..a00f0f8825 100644
--- a/cpukit/libdl/rtl-mdreloc-arm.c
+++ b/cpukit/libdl/rtl-mdreloc-arm.c
@@ -33,18 +33,17 @@
static inline Elf_Addr
load_ptr(void *where)
{
- Elf_Addr res;
+ Elf_Addr res;
- memcpy(&res, where, sizeof(res));
+ memcpy(&res, where, sizeof(res));
- return (res);
+ return (res);
}
static inline void
store_ptr(void *where, Elf_Addr val)
{
-
- memcpy(where, &val, sizeof(val));
+ memcpy(where, &val, sizeof(val));
}
/*
@@ -67,6 +66,33 @@ sign_extend31(Elf_Addr val)
return 0x7fffffff & val;
}
+static void*
+set_veneer(void* tramopline, Elf_Addr target)
+{
+ /*
+ * http://shell-storm.org/online/Online-Assembler-and-Disassembler/
+ *
+ * ldr.w pc, [pc]
+ */
+ uint32_t* tramp = (uint32_t*) tramopline;
+ *tramp++ = 0xf000f8df;
+ *tramp++ = (uint32_t) target;
+ return tramp;
+}
+
+static size_t
+get_veneer_size(int type)
+{
+ (void) type;
+ return 8;
+}
+
+size_t
+rtems_rtl_elf_relocate_tramp_max_size (void)
+{
+ return 8;
+}
+
uint32_t
rtems_rtl_elf_section_flags (const rtems_rtl_obj* obj,
const Elf_Shdr* shdr)
@@ -84,24 +110,49 @@ rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
}
bool
-rtems_rtl_elf_relocate_rela (const rtems_rtl_obj* obj,
+rtems_rtl_elf_relocate_rela_tramp (rtems_rtl_obj* obj,
+ const Elf_Rela* rela,
+ const rtems_rtl_obj_sect* sect,
+ const char* symname,
+ const Elf_Byte syminfo,
+ const Elf_Word symvalue)
+{
+ (void) obj;
+ (void) rela;
+ (void) sect;
+ (void) symname;
+ (void) syminfo;
+ (void) symvalue;
+ rtems_rtl_set_error (EINVAL, "rela type record not supported");
+ return false;
+}
+
+bool
+rtems_rtl_elf_relocate_rela (rtems_rtl_obj* obj,
const Elf_Rela* rela,
const rtems_rtl_obj_sect* sect,
const char* symname,
const Elf_Byte syminfo,
const Elf_Word symvalue)
{
+ (void) obj;
+ (void) rela;
+ (void) sect;
+ (void) symname;
+ (void) syminfo;
+ (void) symvalue;
rtems_rtl_set_error (EINVAL, "rela type record not supported");
return false;
}
-bool
-rtems_rtl_elf_relocate_rel (const rtems_rtl_obj* obj,
- const Elf_Rel* rel,
- const rtems_rtl_obj_sect* sect,
- const char* symname,
- const Elf_Byte syminfo,
- const Elf_Word symvalue)
+static bool
+rtems_rtl_elf_relor_rel (rtems_rtl_obj* obj,
+ const Elf_Rel* rel,
+ const rtems_rtl_obj_sect* sect,
+ const char* symname,
+ const Elf_Byte syminfo,
+ const Elf_Word symvalue,
+ const bool parsing)
{
Elf_Addr *where;
Elf_Addr tmp;
@@ -142,21 +193,40 @@ rtems_rtl_elf_relocate_rel (const rtems_rtl_obj* obj,
tmp = (Elf_Sword)tmp >> 2;
if (((Elf_Sword)tmp > 0x7fffff) || ((Elf_Sword)tmp < -0x800000)) {
- printf("CALL/JUMP24 Overflow\n");
- return false;
- }
+ Elf_Word tramp_addr;
+ size_t tramp_size = get_veneer_size(ELF_R_TYPE(rel->r_info));
- *where = (*where & 0xff000000) | (tmp & 0xffffff);
+ if (parsing) {
+ obj->tramp_size += tramp_size;
+ return true;
+ }
- if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
- printf ("rtl: JUMP24/PC24/CALL %p @ %p in %s\n",
- (void *)*where, where, rtems_rtl_obj_oname (obj));
+ if (!rtems_rtl_obj_has_ramp_space (obj, tramp_size)) {
+ rtems_rtl_set_error (EINVAL,
+ "%s: CALL/JUMP24: overflow: no tramp memory",
+ sect->name);
+ return false;
+ }
+ tramp_addr = ((Elf_Addr) obj->tramp_brk) | (symvalue & 1);
+ obj->tramp_brk = set_veneer(obj->tramp_brk, symvalue);
+
+ tmp = tramp_addr + (addend << 2) - (Elf_Addr)where;
+ tmp = (Elf_Sword)tmp >> 2;
+ }
+
+ if (!parsing) {
+ *where = (*where & 0xff000000) | (tmp & 0xffffff);
+
+ if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+ printf ("rtl: JUMP24/PC24/CALL %p @ %p in %s\n",
+ (void *)*where, where, rtems_rtl_obj_oname (obj));
+ }
break;
case R_TYPE(V4BX):
/* Miscellaneous, ignore */
- if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) {
+ if (!parsing && rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) {
printf ("rtl: V4BX %p @ %p in %s\n",
(void *)*where, where, rtems_rtl_obj_oname (obj));
}
@@ -182,72 +252,78 @@ rtems_rtl_elf_relocate_rel (const rtems_rtl_obj* obj,
}
}
- *where = (insn & 0xfff0f000) | ((tmp & 0xf000) << 4) | (tmp & 0xfff);
+ if (!parsing) {
+ *where = (insn & 0xfff0f000) | ((tmp & 0xf000) << 4) | (tmp & 0xfff);
- if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
- printf ("rtl: MOVT_ABS/MOVW_ABS_NC %p @ %p in %s\n",
- (void *)*where, where, rtems_rtl_obj_oname (obj));
+ if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+ printf ("rtl: MOVT_ABS/MOVW_ABS_NC %p @ %p in %s\n",
+ (void *)*where, where, rtems_rtl_obj_oname (obj));
+ }
break;
-
case R_TYPE(REL32): /* word32 (S + A) | T - P */
case R_TYPE(ABS32): /* word32 (S + A) | T */
case R_TYPE(GLOB_DAT): /* word32 (S + A) | T */
case R_TYPE(PREL31): /* word32 (S + A) | T - P */
case R_TYPE(TARGET1): /* Equivalent to ABS32 */
case R_TYPE(TARGET2): /* Equivalent to REL32 */
- if (__predict_true(RELOC_ALIGNED_P(where))) {
- tmp = *where + symvalue;
- if (isThumb(symvalue))
- tmp |= 1;
- if (ELF_R_TYPE(rel->r_info) == R_TYPE(REL32) ||
- ELF_R_TYPE(rel->r_info) == R_TYPE(TARGET2))
- tmp -= (Elf_Addr)where;
- else if (ELF_R_TYPE(rel->r_info) == R_TYPE(PREL31))
- tmp = sign_extend31(tmp - (Elf_Addr)where);
- *where = tmp;
- } else {
- tmp = load_ptr(where) + symvalue;
- if (isThumb(symvalue))
- tmp |= 1;
- if (ELF_R_TYPE(rel->r_info) == R_TYPE(REL32) ||
- ELF_R_TYPE(rel->r_info) == R_TYPE(TARGET2))
- tmp -= (Elf_Addr)where;
- else if (ELF_R_TYPE(rel->r_info) == R_TYPE(PREL31))
- tmp = sign_extend31(tmp - (Elf_Addr)where);
- store_ptr(where, tmp);
- }
+ if (!parsing) {
+ if (__predict_true(RELOC_ALIGNED_P(where))) {
+ tmp = *where + symvalue;
+ if (isThumb(symvalue))
+ tmp |= 1;
+ if (ELF_R_TYPE(rel->r_info) == R_TYPE(REL32) ||
+ ELF_R_TYPE(rel->r_info) == R_TYPE(TARGET2))
+ tmp -= (Elf_Addr)where;
+ else if (ELF_R_TYPE(rel->r_info) == R_TYPE(PREL31))
+ tmp = sign_extend31(tmp - (Elf_Addr)where);
+ if (!parsing) {
+ *where = tmp;
+ }
+ } else {
+ tmp = load_ptr(where) + symvalue;
+ if (isThumb(symvalue))
+ tmp |= 1;
+ if (ELF_R_TYPE(rel->r_info) == R_TYPE(REL32) ||
+ ELF_R_TYPE(rel->r_info) == R_TYPE(TARGET2))
+ tmp -= (Elf_Addr)where;
+ else if (ELF_R_TYPE(rel->r_info) == R_TYPE(PREL31))
+ tmp = sign_extend31(tmp - (Elf_Addr)where);
+ store_ptr(where, tmp);
+ }
- if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
- printf ("rtl: REL32/ABS32/GLOB_DAT/PREL31/TARGET2 %p @ %p in %s\n",
- (void *)tmp, where, rtems_rtl_obj_oname (obj));
+ if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC))
+ printf ("rtl: REL32/ABS32/GLOB_DAT/PREL31/TARGET2 %p @ %p in %s\n",
+ (void *)tmp, where, rtems_rtl_obj_oname (obj));
+ }
break;
case R_TYPE(THM_MOVT_ABS):
case R_TYPE(THM_MOVW_ABS_NC):
- upper_insn = *(uint16_t *)where;
- lower_insn = *((uint16_t *)where + 1);
-
- addend = ((upper_insn & 0x000f) << 12) | ((upper_insn & 0x0400) << 1) |
- ((lower_insn & 0x7000) >> 4) | (lower_insn & 0x00ff);
- addend = (addend ^ 0x8000) - 0x8000;
-
- tmp = addend + symvalue;
- if (ELF32_R_TYPE(rel->r_info) == R_ARM_THM_MOVT_ABS)
- tmp >>= 16;
-
- *(uint16_t *)where = (uint16_t)((upper_insn & 0xfbf0) |
- ((tmp & 0xf000) >> 12) |
- ((tmp & 0x0800) >> 1));
- *((uint16_t *)where + 1) = (uint16_t)((lower_insn & 0x8f00) |
- ((tmp & 0x0700) << 4) |
- (tmp & 0x00ff));
-
- if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) {
- printf ("rtl: THM_MOVT_ABS/THM_MOVW_ABS_NC %p @ %p in %s\n",
- (void *)*where, where, rtems_rtl_obj_oname (obj));
+ if (!parsing) {
+ upper_insn = *(uint16_t *)where;
+ lower_insn = *((uint16_t *)where + 1);
+
+ addend = ((upper_insn & 0x000f) << 12) | ((upper_insn & 0x0400) << 1) |
+ ((lower_insn & 0x7000) >> 4) | (lower_insn & 0x00ff);
+ addend = (addend ^ 0x8000) - 0x8000;
+
+ tmp = addend + symvalue;
+ if (ELF32_R_TYPE(rel->r_info) == R_ARM_THM_MOVT_ABS)
+ tmp >>= 16;
+
+ *(uint16_t *)where = (uint16_t)((upper_insn & 0xfbf0) |
+ ((tmp & 0xf000) >> 12) |
+ ((tmp & 0x0800) >> 1));
+ *((uint16_t *)where + 1) = (uint16_t)((lower_insn & 0x8f00) |
+ ((tmp & 0x0700) << 4) |
+ (tmp & 0x00ff));
+
+ if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) {
+ printf ("rtl: THM_MOVT_ABS/THM_MOVW_ABS_NC %p @ %p in %s\n",
+ (void *)*where, where, rtems_rtl_obj_oname (obj));
+ }
}
-
break;
case R_TYPE(THM_JUMP24):
@@ -278,24 +354,44 @@ rtems_rtl_elf_relocate_rel (const rtems_rtl_obj* obj,
tmp = tmp - (Elf_Addr)where;
if (((Elf_Sword)tmp > 0x7fffff) || ((Elf_Sword)tmp < -0x800000)) {
- printf("THM_CALL/JUMP24 overflow\n");
- return false;
- }
+ Elf_Word tramp_addr;
+ size_t tramp_size = get_veneer_size(ELF_R_TYPE(rel->r_info));
+
+ if (parsing) {
+ obj->tramp_size += tramp_size;
+ return true;
+ }
+
+ if (!rtems_rtl_obj_has_ramp_space (obj, tramp_size)) {
+ rtems_rtl_set_error (EINVAL,
+ "%s: THM_CALL/JUMP24: overflow: no tramp memory",
+ sect->name);
+ return false;
+ }
- sign = (tmp >> 24) & 1;
- *(uint16_t *)where = (uint16_t)((upper_insn & 0xf800) | (sign << 10) |
- ((tmp >> 12) & 0x3ff));
+ tramp_addr = ((Elf_Addr) obj->tramp_brk) | (symvalue & 1);
+ obj->tramp_brk = set_veneer(obj->tramp_brk, symvalue);
- *((uint16_t *)where + 1) = (uint16_t)((lower_insn & 0xd000)|
- ((sign ^ (~(tmp >> 23) & 1)) << 13) |
- ((sign ^ (~(tmp >> 22) & 1)) << 11) |
- ((tmp >> 1) & 0x7ff));
- if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)){
- printf ("rtl: THM_CALL/JUMP24 %p @ %p in %s\n",
- (void *)*where, where, rtems_rtl_obj_oname (obj));
+ tmp = tramp_addr + addend;
+ tmp = tmp - (Elf_Addr)where;
}
+ if (!parsing) {
+ sign = (tmp >> 24) & 1;
+ *(uint16_t *)where = (uint16_t)((upper_insn & 0xf800) | (sign << 10) |
+ ((tmp >> 12) & 0x3ff));
+
+ *((uint16_t *)where + 1) = (uint16_t)((lower_insn & 0xd000)|
+ ((sign ^ (~(tmp >> 23) & 1)) << 13) |
+ ((sign ^ (~(tmp >> 22) & 1)) << 11) |
+ ((tmp >> 1) & 0x7ff));
+
+ if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)){
+ printf ("rtl: THM_CALL/JUMP24 %p @ %p in %s\n",
+ (void *)*where, where, rtems_rtl_obj_oname (obj));
+ }
+ }
break;
case R_TYPE(THM_JUMP19):
@@ -327,6 +423,7 @@ rtems_rtl_elf_relocate_rel (const rtems_rtl_obj* obj,
rtems_rtl_set_error (EINVAL, "%s: Overflow %" PRIu32 " "
"THM_JUMP19 relocations",
sect->name, (uint32_t) ELF_R_TYPE(rel->r_info));
+ return true;
return false;
}
@@ -359,6 +456,40 @@ rtems_rtl_elf_relocate_rel (const rtems_rtl_obj* obj,
}
bool
+rtems_rtl_elf_relocate_rel_tramp (rtems_rtl_obj* obj,
+ const Elf_Rel* rel,
+ const rtems_rtl_obj_sect* sect,
+ const char* symname,
+ const Elf_Byte syminfo,
+ const Elf_Word symvalue)
+{
+ return rtems_rtl_elf_relor_rel (obj,
+ rel,
+ sect,
+ symname,
+ syminfo,
+ symvalue,
+ true);
+}
+
+bool
+rtems_rtl_elf_relocate_rel (rtems_rtl_obj* obj,
+ const Elf_Rel* rel,
+ const rtems_rtl_obj_sect* sect,
+ const char* symname,
+ const Elf_Byte syminfo,
+ const Elf_Word symvalue)
+{
+ return rtems_rtl_elf_relor_rel (obj,
+ rel,
+ sect,
+ symname,
+ syminfo,
+ symvalue,
+ false);
+}
+
+bool
rtems_rtl_elf_unwind_parse (const rtems_rtl_obj* obj,
const char* name,
uint32_t flags)
diff --git a/cpukit/libdl/rtl-mdreloc-bfin.c b/cpukit/libdl/rtl-mdreloc-bfin.c
index e1190046a3..b4c20fac24 100644
--- a/cpukit/libdl/rtl-mdreloc-bfin.c
+++ b/cpukit/libdl/rtl-mdreloc-bfin.c
@@ -32,8 +32,34 @@ load_ptr(void *where)
return (res);
}
+size_t
+rtems_rtl_elf_relocate_tramp_max_size (void)
+{
+ /*
+ * Disable by returning 0.
+ */
+ return 0;
+}
+
bool
-rtems_rtl_elf_relocate_rela (const rtems_rtl_obj* obj,
+rtems_rtl_elf_relocate_rela_tramp (rtems_rtl_obj* obj,
+ const Elf_Rela* rela,
+ const rtems_rtl_obj_sect* sect,
+ const char* symname,
+ const Elf_Byte syminfo,
+ const Elf_Word symvalue)
+{
+ (void) obj;
+ (void) rela;
+ (void) sect;
+ (void) symname;
+ (void) syminfo;
+ (void) symvalue;
+ return true;
+}
+
+bool
+rtems_rtl_elf_relocate_rela (rtems_rtl_obj* obj,
const Elf_Rela* rela,
const rtems_rtl_obj_sect* sect,
const char* symname,
@@ -112,13 +138,37 @@ rtems_rtl_elf_relocate_rela (const rtems_rtl_obj* obj,
}
bool
-rtems_rtl_elf_relocate_rel (const rtems_rtl_obj* obj,
+rtems_rtl_elf_relocate_rel_tramp (rtems_rtl_obj* obj,
+ const Elf_Rel* rel,
+ const rtems_rtl_obj_sect* sect,
+ const char* symname,
+ const Elf_Byte syminfo,
+ const Elf_Word symvalue)
+{
+ (void) obj;
+ (void) rel;
+ (void) sect;
+ (void) symname;
+ (void) syminfo;
+ (void) symvalue;
+ rtems_rtl_set_error (EINVAL, "rel type record not supported");
+ return false;
+}
+
+bool
+rtems_rtl_elf_relocate_rel (rtems_rtl_obj* obj,
const Elf_Rel* rel,
const rtems_rtl_obj_sect* sect,
const char* symname,
const Elf_Byte syminfo,
const Elf_Word symvalue)
{
+ (void) obj;
+ (void) rel;
+ (void) sect;
+ (void) symname;
+ (void) syminfo;
+ (void) symvalue;
rtems_rtl_set_error (EINVAL, "rel type record not supported");
return false;
}
diff --git a/cpukit/libdl/rtl-mdreloc-h8300.c b/cpukit/libdl/rtl-mdreloc-h8300.c
index 54af83973f..e0cb826dc8 100644
--- a/cpukit/libdl/rtl-mdreloc-h8300.c
+++ b/cpukit/libdl/rtl-mdreloc-h8300.c
@@ -25,8 +25,34 @@ rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
return true;
}
+size_t
+rtems_rtl_elf_relocate_tramp_max_size (void)
+{
+ /*
+ * Disable by returning 0.
+ */
+ return 0;
+}
+
bool
-rtems_rtl_elf_relocate_rela (const rtems_rtl_obj* obj,
+rtems_rtl_elf_relocate_rela_tramp (rtems_rtl_obj* obj,
+ const Elf_Rela* rela,
+ const rtems_rtl_obj_sect* sect,
+ const char* symname,
+ const Elf_Byte syminfo,
+ const Elf_Word symvalue)
+{
+ (void) obj;
+ (void) rela;
+ (void) sect;
+ (void) symname;
+ (void) syminfo;
+ (void) symvalue;
+ return true;
+}
+
+bool
+rtems_rtl_elf_relocate_rela (rtems_rtl_obj* obj,
const Elf_Rela* rela,
const rtems_rtl_obj_sect* sect,
const char* symname,
@@ -98,13 +124,37 @@ rtems_rtl_elf_relocate_rela (const rtems_rtl_obj* obj,
}
bool
-rtems_rtl_elf_relocate_rel (const rtems_rtl_obj* obj,
+rtems_rtl_elf_relocate_rel_tramp (rtems_rtl_obj* obj,
+ const Elf_Rel* rel,
+ const rtems_rtl_obj_sect* sect,
+ const char* symname,
+ const Elf_Byte syminfo,
+ const Elf_Word symvalue)
+{
+ (void) obj;
+ (void) rel;
+ (void) sect;
+ (void) symname;
+ (void) syminfo;
+ (void) symvalue;
+ rtems_rtl_set_error (EINVAL, "rel type record not supported");
+ return false;
+}
+
+bool
+rtems_rtl_elf_relocate_rel (rtems_rtl_obj* obj,
const Elf_Rel* rel,
const rtems_rtl_obj_sect* sect,
const char* symname,
const Elf_Byte syminfo,
const Elf_Word symvalue)
{
+ (void) obj;
+ (void) rel;
+ (void) sect;
+ (void) symname;
+ (void) syminfo;
+ (void) symvalue;
rtems_rtl_set_error (EINVAL, "rel type record not supported");
return false;
}
diff --git a/cpukit/libdl/rtl-mdreloc-i386.c b/cpukit/libdl/rtl-mdreloc-i386.c
index f0aa61b8ee..773ef8e916 100644
--- a/cpukit/libdl/rtl-mdreloc-i386.c
+++ b/cpukit/libdl/rtl-mdreloc-i386.c
@@ -31,20 +31,70 @@ rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
return true;
}
+size_t
+rtems_rtl_elf_relocate_tramp_max_size (void)
+{
+ /*
+ * Disable by returning 0.
+ */
+ return 0;
+}
+
bool
-rtems_rtl_elf_relocate_rela (const rtems_rtl_obj* obj,
+rtems_rtl_elf_relocate_rela_tramp (rtems_rtl_obj* obj,
+ const Elf_Rela* rela,
+ const rtems_rtl_obj_sect* sect,
+ const char* symname,
+ const Elf_Byte syminfo,
+ const Elf_Word symvalue)
+{
+ (void) obj;
+ (void) rela;
+ (void) sect;
+ (void) symname;
+ (void) syminfo;
+ (void) symvalue;
+ rtems_rtl_set_error (EINVAL, "rela type record not supported");
+ return false;
+}
+
+bool
+rtems_rtl_elf_relocate_rela (rtems_rtl_obj* obj,
const Elf_Rela* rel,
const rtems_rtl_obj_sect* sect,
const char* symname,
const Elf_Byte syminfo,
const Elf_Word symvalue)
{
+ (void) obj;
+ (void) rela;
+ (void) sect;
+ (void) symname;
+ (void) syminfo;
+ (void) symvalue;
rtems_rtl_set_error (EINVAL, "rela type record not supported");
return false;
}
bool
-rtems_rtl_elf_relocate_rel (const rtems_rtl_obj* obj,
+rtems_rtl_elf_relocate_rel_tramp (rtems_rtl_obj* obj,
+ const Elf_Rel* rel,
+ const rtems_rtl_obj_sect* sect,
+ const char* symname,
+ const Elf_Byte syminfo,
+ const Elf_Word symvalue)
+{
+ (void) obj;
+ (void) rel;
+ (void) sect;
+ (void) symname;
+ (void) syminfo;
+ (void) symvalue;
+ return true;
+}
+
+bool
+rtems_rtl_elf_relocate_rel (rtems_rtl_obj* obj,
const Elf_Rel* rel,
const rtems_rtl_obj_sect* sect,
const char* symname,
diff --git a/cpukit/libdl/rtl-mdreloc-lm32.c b/cpukit/libdl/rtl-mdreloc-lm32.c
index ad59ec2e09..cf64ea8fb3 100644
--- a/cpukit/libdl/rtl-mdreloc-lm32.c
+++ b/cpukit/libdl/rtl-mdreloc-lm32.c
@@ -25,8 +25,34 @@ rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
return true;
}
+size_t
+rtems_rtl_elf_relocate_tramp_max_size (void)
+{
+ /*
+ * Disable by returning 0.
+ */
+ return 0;
+}
+
+bool
+rtems_rtl_elf_relocate_rela_tramp (rtems_rtl_obj* obj,
+ const Elf_Rela* rela,
+ const rtems_rtl_obj_sect* sect,
+ const char* symname,
+ const Elf_Byte syminfo,
+ const Elf_Word symvalue)
+{
+ (void) obj;
+ (void) rela;
+ (void) sect;
+ (void) symname;
+ (void) syminfo;
+ (void) symvalue;
+ return true;
+}
+
bool
-rtems_rtl_elf_relocate_rela (const rtems_rtl_obj* obj,
+rtems_rtl_elf_relocate_rela (rtems_rtl_obj* obj,
const Elf_Rela* rela,
const rtems_rtl_obj_sect* sect,
const char* symname,
@@ -117,13 +143,37 @@ rtems_rtl_elf_relocate_rela (const rtems_rtl_obj* obj,
}
bool
-rtems_rtl_elf_relocate_rel (const rtems_rtl_obj* obj,
+rtems_rtl_elf_relocate_rel_tramp (rtems_rtl_obj* obj,
+ const Elf_Rel* rel,
+ const rtems_rtl_obj_sect* sect,
+ const char* symname,
+ const Elf_Byte syminfo,
+ const Elf_Word symvalue)
+{
+ (void) obj;
+ (void) rela;
+ (void) sect;
+ (void) symname;
+ (void) syminfo;
+ (void) symvalue;
+ rtems_rtl_set_error (EINVAL, "rel type record not supported");
+ return false;
+}
+
+bool
+rtems_rtl_elf_relocate_rel (rtems_rtl_obj* obj,
const Elf_Rel* rel,
const rtems_rtl_obj_sect* sect,
const char* symname,
const Elf_Byte syminfo,
const Elf_Word symvalue)
{
+ (void) obj;
+ (void) rela;
+ (void) sect;
+ (void) symname;
+ (void) syminfo;
+ (void) symvalue;
rtems_rtl_set_error (EINVAL, "rela type record not supported");
return false;
}
diff --git a/cpukit/libdl/rtl-mdreloc-m68k.c b/cpukit/libdl/rtl-mdreloc-m68k.c
index f42899b118..1981e93d56 100644
--- a/cpukit/libdl/rtl-mdreloc-m68k.c
+++ b/cpukit/libdl/rtl-mdreloc-m68k.c
@@ -45,8 +45,34 @@ rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
return true;
}
+size_t
+rtems_rtl_elf_relocate_tramp_max_size (void)
+{
+ /*
+ * Disable by returning 0.
+ */
+ return 0;
+}
+
bool
-rtems_rtl_elf_relocate_rela (const rtems_rtl_obj* obj,
+rtems_rtl_elf_relocate_rela_tramp (rtems_rtl_obj* obj,
+ const Elf_Rela* rela,
+ const rtems_rtl_obj_sect* sect,
+ const char* symname,
+ const Elf_Byte syminfo,
+ const Elf_Word symvalue)
+{
+ (void) obj;
+ (void) rela;
+ (void) sect;
+ (void) symname;
+ (void) syminfo;
+ (void) symvalue;
+ return true;
+}
+
+bool
+rtems_rtl_elf_relocate_rela (rtems_rtl_obj* obj,
const Elf_Rela* rela,
const rtems_rtl_obj_sect* sect,
const char* symnane,
@@ -145,13 +171,37 @@ rtems_rtl_elf_relocate_rela (const rtems_rtl_obj* obj,
}
bool
-rtems_rtl_elf_relocate_rel (const rtems_rtl_obj* obj,
+rtems_rtl_elf_relocate_rel_tramp (rtems_rtl_obj* obj,
+ const Elf_Rel* rel,
+ const rtems_rtl_obj_sect* sect,
+ const char* symname,
+ const Elf_Byte syminfo,
+ const Elf_Word symvalue)
+{
+ (void) obj;
+ (void) rel;
+ (void) sect;
+ (void) symname;
+ (void) syminfo;
+ (void) symvalue;
+ rtems_rtl_set_error (EINVAL, "rel type record not supported");
+ return false;
+}
+
+bool
+rtems_rtl_elf_relocate_rel (rtems_rtl_obj* obj,
const Elf_Rel* rel,
const rtems_rtl_obj_sect* sect,
const char* symname,
const Elf_Byte syminfo,
const Elf_Word symvalue)
{
+ (void) obj;
+ (void) rel;
+ (void) sect;
+ (void) symname;
+ (void) syminfo;
+ (void) symvalue;
rtems_rtl_set_error (EINVAL, "rel type record not supported");
return false;
}
diff --git a/cpukit/libdl/rtl-mdreloc-mips.c b/cpukit/libdl/rtl-mdreloc-mips.c
index 7ad18b382f..4860fdfe72 100644
--- a/cpukit/libdl/rtl-mdreloc-mips.c
+++ b/cpukit/libdl/rtl-mdreloc-mips.c
@@ -25,18 +25,68 @@ rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
return true;
}
+size_t
+rtems_rtl_elf_relocate_tramp_max_size (void)
+{
+ /*
+ * Disable by returning 0.
+ */
+ return 0;
+}
+
bool
-rtems_rtl_elf_relocate_rela (const rtems_rtl_obj* obj,
+rtems_rtl_elf_relocate_rela_tramp (rtems_rtl_obj* obj,
+ const Elf_Rela* rela,
+ const rtems_rtl_obj_sect* sect,
+ const char* symname,
+ const Elf_Byte syminfo,
+ const Elf_Word symvalue)
+{
+ (void) obj;
+ (void) rela;
+ (void) sect;
+ (void) symname;
+ (void) syminfo;
+ (void) symvalue;
+ rtems_rtl_set_error (EINVAL, "rela type record not supported");
+ return false;
+}
+
+bool
+rtems_rtl_elf_relocate_rela (rtems_rtl_obj* obj,
const Elf_Rela* rela,
const rtems_rtl_obj_sect* sect,
const char* symname,
const Elf_Byte syminfo,
const Elf_Word symvalue)
{
+ (void) obj;
+ (void) rela;
+ (void) sect;
+ (void) symname;
+ (void) syminfo;
+ (void) symvalue;
rtems_rtl_set_error (EINVAL, "rela type record not supported");
return false;
}
+bool
+rtems_rtl_elf_relocate_rel_tramp (rtems_rtl_obj* obj,
+ const Elf_Rel* rel,
+ const rtems_rtl_obj_sect* sect,
+ const char* symname,
+ const Elf_Byte syminfo,
+ const Elf_Word symvalue)
+{
+ (void) obj;
+ (void) rel;
+ (void) sect;
+ (void) symname;
+ (void) syminfo;
+ (void) symvalue;
+ return true;
+}
+
/*
* 1. _gp_disp symbol are not considered in this file.
* 2. There is a local/external column;
@@ -46,7 +96,7 @@ rtems_rtl_elf_relocate_rela (const rtems_rtl_obj* obj,
* just consider symtype here.
*/
bool
-rtems_rtl_elf_relocate_rel (const rtems_rtl_obj* obj,
+rtems_rtl_elf_relocate_rel (rtems_rtl_obj* obj,
const Elf_Rel* rel,
const rtems_rtl_obj_sect* sect,
const char* symname,
@@ -183,16 +233,16 @@ rtems_rtl_elf_relocate_rel (const rtems_rtl_obj* obj,
break;
- default:
- printf ("rtl: reloc unknown: sym = %lu, type = %lu, offset = %p, "
- "contents = %p\n",
+ default:
+ printf ("rtl: reloc unknown: sym = %lu, type = %lu, offset = %p, "
+ "contents = %p\n",
ELF_R_SYM(rel->r_info), (uint32_t) ELF_R_TYPE(rel->r_info),
(void *)rel->r_offset, (void *)*where);
- rtems_rtl_set_error (EINVAL,
- "%s: Unsupported relocation type %ld "
- "in non-PLT relocations",
- sect->name, (uint32_t) ELF_R_TYPE(rel->r_info));
- return false;
+ rtems_rtl_set_error (EINVAL,
+ "%s: Unsupported relocation type %ld "
+ "in non-PLT relocations",
+ sect->name, (uint32_t) ELF_R_TYPE(rel->r_info));
+ return false;
}
return true;
diff --git a/cpukit/libdl/rtl-mdreloc-moxie.c b/cpukit/libdl/rtl-mdreloc-moxie.c
index 68cbeeceb2..cc0558eaa5 100644
--- a/cpukit/libdl/rtl-mdreloc-moxie.c
+++ b/cpukit/libdl/rtl-mdreloc-moxie.c
@@ -26,8 +26,34 @@ rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
return true;
}
+size_t
+rtems_rtl_elf_relocate_tramp_max_size (void)
+{
+ /*
+ * Disable by returning 0.
+ */
+ return 0;
+}
+
bool
-rtems_rtl_elf_relocate_rela (const rtems_rtl_obj* obj,
+rtems_rtl_elf_relocate_rela_tramp (rtems_rtl_obj* obj,
+ const Elf_Rela* rela,
+ const rtems_rtl_obj_sect* sect,
+ const char* symname,
+ const Elf_Byte syminfo,
+ const Elf_Word symvalue)
+{
+ (void) obj;
+ (void) rela;
+ (void) sect;
+ (void) symname;
+ (void) syminfo;
+ (void) symvalue;
+ return true;
+}
+
+bool
+rtems_rtl_elf_relocate_rela (rtems_rtl_obj* obj,
const Elf_Rela* rela,
const rtems_rtl_obj_sect* sect,
const char* symname,
@@ -85,13 +111,37 @@ rtems_rtl_elf_relocate_rela (const rtems_rtl_obj* obj,
}
bool
-rtems_rtl_elf_relocate_rel (const rtems_rtl_obj* obj,
+rtems_rtl_elf_relocate_rel_tramp (rtems_rtl_obj* obj,
+ const Elf_Rel* rel,
+ const rtems_rtl_obj_sect* sect,
+ const char* symname,
+ const Elf_Byte syminfo,
+ const Elf_Word symvalue)
+{
+ (void) obj;
+ (void) rel;
+ (void) sect;
+ (void) symname;
+ (void) syminfo;
+ (void) symvalue;
+ rtems_rtl_set_error (EINVAL, "rel type record not supported");
+ return false;
+}
+
+bool
+rtems_rtl_elf_relocate_rel (rtems_rtl_obj* obj,
const Elf_Rel* rel,
const rtems_rtl_obj_sect* sect,
const char* symname,
const Elf_Byte syminfo,
const Elf_Word symvalue)
{
+ (void) obj;
+ (void) rel;
+ (void) sect;
+ (void) symname;
+ (void) syminfo;
+ (void) symvalue;
rtems_rtl_set_error (EINVAL, "rel type record not supported");
return false;
}
diff --git a/cpukit/libdl/rtl-mdreloc-powerpc.c b/cpukit/libdl/rtl-mdreloc-powerpc.c
index e59c415828..b205ed5215 100644
--- a/cpukit/libdl/rtl-mdreloc-powerpc.c
+++ b/cpukit/libdl/rtl-mdreloc-powerpc.c
@@ -36,8 +36,34 @@ rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
return true;
}
+size_t
+rtems_rtl_elf_relocate_tramp_max_size (void)
+{
+ /*
+ * Disable by returning 0.
+ */
+ return 0;
+}
+
+bool
+rtems_rtl_elf_relocate_rela_tramp (rtems_rtl_obj* obj,
+ const Elf_Rela* rela,
+ const rtems_rtl_obj_sect* sect,
+ const char* symname,
+ const Elf_Byte syminfo,
+ const Elf_Word symvalue)
+{
+ (void) obj;
+ (void) rela;
+ (void) sect;
+ (void) symname;
+ (void) syminfo;
+ (void) symvalue;
+ return true;
+}
+
bool
-rtems_rtl_elf_relocate_rela (const rtems_rtl_obj* obj,
+rtems_rtl_elf_relocate_rela (rtems_rtl_obj* obj,
const Elf_Rela* rela,
const rtems_rtl_obj_sect* sect,
const char* symname,
@@ -198,14 +224,38 @@ rtems_rtl_elf_relocate_rela (const rtems_rtl_obj* obj,
}
bool
-rtems_rtl_elf_relocate_rel (const rtems_rtl_obj* obj,
+rtems_rtl_elf_relocate_rel_tramp (rtems_rtl_obj* obj,
+ const Elf_Rel* rel,
+ const rtems_rtl_obj_sect* sect,
+ const char* symname,
+ const Elf_Byte syminfo,
+ const Elf_Word symvalue)
+{
+ (void) obj;
+ (void) rel;
+ (void) sect;
+ (void) symname;
+ (void) syminfo;
+ (void) symvalue;
+ rtems_rtl_set_error (EINVAL, "rel type record not supported");
+ return false;
+}
+
+bool
+rtems_rtl_elf_relocate_rel (rtems_rtl_obj* obj,
const Elf_Rel* rel,
const rtems_rtl_obj_sect* sect,
const char* symname,
const Elf_Byte syminfo,
const Elf_Word symvalue)
{
- printf ("rtl: rel type record not supported; please report\n");
+ (void) obj;
+ (void) rel;
+ (void) sect;
+ (void) symname;
+ (void) syminfo;
+ (void) symvalue;
+ rtems_rtl_set_error (EINVAL, "rel type record not supported");
return false;
}
diff --git a/cpukit/libdl/rtl-mdreloc-sparc.c b/cpukit/libdl/rtl-mdreloc-sparc.c
index c0860a3d3f..bc05392659 100644
--- a/cpukit/libdl/rtl-mdreloc-sparc.c
+++ b/cpukit/libdl/rtl-mdreloc-sparc.c
@@ -144,8 +144,34 @@ rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
return RELOC_RESOLVE_SYMBOL (type) ? true : false;
}
+size_t
+rtems_rtl_elf_relocate_tramp_max_size (void)
+{
+ /*
+ * Disable by returning 0.
+ */
+ return 0;
+}
+
+bool
+rtems_rtl_elf_relocate_rela_tramp (rtems_rtl_obj* obj,
+ const Elf_Rela* rela,
+ const rtems_rtl_obj_sect* sect,
+ const char* symname,
+ const Elf_Byte syminfo,
+ const Elf_Word symvalue)
+{
+ (void) obj;
+ (void) rela;
+ (void) sect;
+ (void) symname;
+ (void) syminfo;
+ (void) symvalue;
+ return true;
+}
+
bool
-rtems_rtl_elf_relocate_rela (const rtems_rtl_obj* obj,
+rtems_rtl_elf_relocate_rela (rtems_rtl_obj* obj,
const Elf_Rela* rela,
const rtems_rtl_obj_sect* sect,
const char* symname,
@@ -261,13 +287,37 @@ rtems_rtl_elf_relocate_rela (const rtems_rtl_obj* obj,
}
bool
-rtems_rtl_elf_relocate_rel (const rtems_rtl_obj* obj,
+rtems_rtl_elf_relocate_rel_tramp (rtems_rtl_obj* obj,
+ const Elf_Rel* rel,
+ const rtems_rtl_obj_sect* sect,
+ const char* symname,
+ const Elf_Byte syminfo,
+ const Elf_Word symvalue)
+{
+ (void) obj;
+ (void) rel;
+ (void) sect;
+ (void) symname;
+ (void) syminfo;
+ (void) symvalue;
+ rtems_rtl_set_error (EINVAL, "rel type record not supported");
+ return false;
+}
+
+bool
+rtems_rtl_elf_relocate_rel (rtems_rtl_obj* obj,
const Elf_Rel* rel,
const rtems_rtl_obj_sect* sect,
const char* symname,
const Elf_Byte syminfo,
const Elf_Word symvalue)
{
+ (void) obj;
+ (void) rel;
+ (void) sect;
+ (void) symname;
+ (void) syminfo;
+ (void) symvalue;
printf ("rtl: rel type record not supported; please report\n");
return false;
}
diff --git a/cpukit/libdl/rtl-mdreloc-v850.c b/cpukit/libdl/rtl-mdreloc-v850.c
index cc2a1fa10e..2aca5e0270 100644
--- a/cpukit/libdl/rtl-mdreloc-v850.c
+++ b/cpukit/libdl/rtl-mdreloc-v850.c
@@ -26,8 +26,34 @@ rtems_rtl_elf_rel_resolve_sym (Elf_Word type)
return true;
}
+size_t
+rtems_rtl_elf_relocate_tramp_max_size (void)
+{
+ /*
+ * Disable by returning 0.
+ */
+ return 0;
+}
+
bool
-rtems_rtl_elf_relocate_rela (const rtems_rtl_obj* obj,
+rtems_rtl_elf_relocate_rela_tramp (rtems_rtl_obj* obj,
+ const Elf_Rela* rela,
+ const rtems_rtl_obj_sect* sect,
+ const char* symname,
+ const Elf_Byte syminfo,
+ const Elf_Word symvalue)
+{
+ (void) obj;
+ (void) rela;
+ (void) sect;
+ (void) symname;
+ (void) syminfo;
+ (void) symvalue;
+ return true;
+}
+
+bool
+rtems_rtl_elf_relocate_rela (rtems_rtl_obj* obj,
const Elf_Rela* rela,
const rtems_rtl_obj_sect* sect,
const char* symname,
@@ -94,13 +120,37 @@ rtems_rtl_elf_relocate_rela (const rtems_rtl_obj* obj,
}
bool
-rtems_rtl_elf_relocate_rel (const rtems_rtl_obj* obj,
+rtems_rtl_elf_relocate_rel_tramp (rtems_rtl_obj* obj,
+ const Elf_Rel* rel,
+ const rtems_rtl_obj_sect* sect,
+ const char* symname,
+ const Elf_Byte syminfo,
+ const Elf_Word symvalue)
+{
+ (void) obj;
+ (void) rel;
+ (void) sect;
+ (void) symname;
+ (void) syminfo;
+ (void) symvalue;
+ rtems_rtl_set_error (EINVAL, "rel type record not supported");
+ return false;
+}
+
+bool
+rtems_rtl_elf_relocate_rel (rtems_rtl_obj* obj,
const Elf_Rel* rel,
const rtems_rtl_obj_sect* sect,
const char* symname,
const Elf_Byte syminfo,
const Elf_Word symvalue)
{
+ (void) obj;
+ (void) rel;
+ (void) sect;
+ (void) symname;
+ (void) syminfo;
+ (void) symvalue;
rtems_rtl_set_error (EINVAL, "rel type record not supported");
return false;
}
diff --git a/cpukit/libdl/rtl-obj.c b/cpukit/libdl/rtl-obj.c
index 858713dee1..6f1f2e4916 100644
--- a/cpukit/libdl/rtl-obj.c
+++ b/cpukit/libdl/rtl-obj.c
@@ -118,6 +118,7 @@ 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);
@@ -557,6 +558,26 @@ rtems_rtl_obj_find_section_by_mask (const rtems_rtl_obj* obj,
}
bool
+rtems_rtl_obj_alloc_trampoline (rtems_rtl_obj* obj)
+{
+ if (obj->tramp_size == 0)
+ return true;
+ obj->trampoline = rtems_rtl_alloc_new (RTEMS_RTL_ALLOC_OBJECT,
+ obj->tramp_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)
{
rtems_rtl_obj_depends* depends;
@@ -837,9 +858,17 @@ rtems_rtl_obj_synchronize_cache (rtems_rtl_obj* obj)
rtems_rtl_obj_sect_sync_handler,
&sync_ctx);
- if (sync_ctx.end_va != sync_ctx.start_va) {
+ if (sync_ctx.end_va != sync_ctx.start_va)
+ {
+ size_t size = sync_ctx.end_va - sync_ctx.start_va;
rtems_cache_instruction_sync_after_code_change(sync_ctx.start_va,
- sync_ctx.end_va - sync_ctx.start_va);
+ size);
+ }
+
+ if (obj->trampoline != NULL)
+ {
+ rtems_cache_instruction_sync_after_code_change(obj->trampoline,
+ obj->tramp_size);
}
}
diff --git a/testsuites/libtests/Makefile.am b/testsuites/libtests/Makefile.am
index a5801d3cb3..22cf613dd3 100644
--- a/testsuites/libtests/Makefile.am
+++ b/testsuites/libtests/Makefile.am
@@ -440,7 +440,7 @@ dl05_SOURCES = dl05/init.c dl05/dl-load.c dl05/dl-cpp.cpp dl05-tar.c \
dl05_CPPFLAGS = $(AM_CPPFLAGS) $(TEST_FLAGS_dl05) $(support_includes)
dl05/init.c: dl05-tar.o
dl05.pre: $(dl05_OBJECTS) $(dl05_DEPENDENCIES)
- @rm -f dl05.pre
+ @rm -f dl05.pre dl05-sym.o
$(AM_V_CXXLD)$(LINK.cc) $(CPU_CFLAGS) $(AM_CFLAGS) $(AM_LDFLAGS) -o $@ $+
dl05-o5.o: dl05/dl-o5.cpp
$(AM_V_CXX)$(CXXCOMPILE) -c -o $@ $<
@@ -484,7 +484,7 @@ dl06-pre-init.o: dl06-pre-tar.o
$(AM_V_CC)$(COMPILE) $(dl06_CPPFLAGS) $(CPU_CFLAGS) $(AM_CFLAGS) \
-DDL06_PRE -c -o $@ $(srcdir)/dl06/init.c
dl06.pre: dl06-pre-init.o dl06/dl06-dl-load.o dl06-pre-tar.o
- @rm -f $@
+ @rm -f $@ dl06-sym.o
$(AM_V_CCLD)$(LINK.c) $(CPU_CFLAGS) $(AM_CFLAGS) $(AM_LDFLAGS) -o $@ $+ $(LDADD)
dl06-o1.o: dl06/dl06-o1.c Makefile
$(AM_V_CC)$(COMPILE) -c -o $@ $<
@@ -522,7 +522,7 @@ dl07_SOURCES = dl07/init.c dl07/dl-load.c dl07-tar.c dl07-tar.h
dl07_CPPFLAGS = $(AM_CPPFLAGS) $(TEST_FLAGS_dl07) $(support_includes)
dl07/init.c: dl07-tar.o
dl07.pre: $(dl07_OBJECTS) $(dl07_DEPENDENCIES)
- @rm -f dl07.pre
+ @rm -f dl07.pre dl07-sym.o
$(AM_V_CCLD)$(LINK.c) $(CPU_CFLAGS) $(AM_CFLAGS) $(AM_LDFLAGS) -o $@ $+
dl07-o1.o: dl07/dl-o1.c Makefile
$(AM_V_CC)$(COMPILE) -c -o $@ $<
@@ -562,7 +562,7 @@ dl08_SOURCES = dl08/init.c dl08/dl-load.c dl08-tar.c dl08-tar.h
dl08_CPPFLAGS = $(AM_CPPFLAGS) $(TEST_FLAGS_dl08) $(support_includes)
dl08/init.c: dl08-tar.o
dl08.pre: $(dl08_OBJECTS) $(dl08_DEPENDENCIES)
- @rm -f dl08.pre
+ @rm -f dl08.pre dl08-syms.o
$(AM_V_CCLD)$(LINK.c) $(CPU_CFLAGS) $(AM_CFLAGS) $(AM_LDFLAGS) -o $@ $+
dl08-o1.o: dl08/dl-o1.c Makefile
$(AM_V_CC)$(COMPILE) -c -o $@ $<
@@ -605,6 +605,46 @@ CLEANFILES += dl08.pre dl08-sym.o libdl08_1.a libdl08_2.a dl08-o1.o dl08-o2.o \
endif
endif
+if DLTESTS
+if TEST_dl09
+lib_tests += dl09
+lib_screens += dl09/dl09.scn
+lib_docs += dl09/dl09.doc
+dl09_SOURCES = dl09/init.c dl09/dl-load.c dl09-tar.c dl09-tar.h
+dl09_CPPFLAGS = $(AM_CPPFLAGS) $(TEST_FLAGS_dl09) $(support_includes)
+dl09/init.c: dl09-tar.o
+dl09.pre: $(dl09_OBJECTS) $(dl09_DEPENDENCIES)
+ @rm -f dl09.pre dl09-syms.o
+ $(AM_V_CCLD)$(LINK.c) $(CPU_CFLAGS) $(AM_CFLAGS) $(AM_LDFLAGS) -o $@ $+
+dl09-o1.o: dl09/dl-o1.c Makefile
+ $(AM_V_CC)$(COMPILE) -c -o $@ $<
+dl09-o2.o: dl09/dl-o2.c Makefile
+ $(AM_V_CC)$(COMPILE) -c -o $@ $<
+dl09-o3.o: dl09/dl-o3.c Makefile
+ $(AM_V_CC)$(COMPILE) -c -o $@ $<
+dl09-o4.o: dl09/dl-o4.c Makefile
+ $(AM_V_CC)$(COMPILE) -c -o $@ $<
+dl09-o5.o: dl09/dl-o5.c Makefile
+ $(AM_V_CC)$(COMPILE) -c -o $@ $<
+dl09.tar: dl09-o1.o dl09-o2.o dl09-o3.o dl09-o4.o dl09-o5.o
+ @rm -f $@
+ $(AM_V_GEN)$(PAX) -w -f $@ $+
+dl09-tar.c: dl09.tar
+ $(AM_V_GEN)$(BIN2C) -C $< $@
+dl09-tar.h: dl09.tar
+ $(AM_V_GEN)$(BIN2C) -H $< $@
+dl09-tar.o: dl09-tar.c dl09-tar.h
+ $(AM_V_CC)$(COMPILE) -c -o $@ $<
+dl09-sym.o: dl09.pre
+ $(AM_V_GEN)rtems-syms -e -C $(CC) -c "$(CFLAGS)" -o $@ $<
+dl09$(EXEEXT): $(dl09_OBJECTS) $(dl09_DEPENDENCIES) dl09-sym.o
+ @rm -f $@
+ $(AM_V_CCLD)$(LINK.c) $(CPU_CFLAGS) $(AM_CFLAGS) $(AM_LDFLAGS) -o $@ $+
+CLEANFILES += dl09.pre dl09-sym.o dl09-o1.o dl09-o2.o dl09-o3.o dl09-o4.o \
+ dl09-o5.o dl09.tar dl09-tar.h
+endif
+endif
+
if TEST_dumpbuf01
lib_tests += dumpbuf01
lib_screens += dumpbuf01/dumpbuf01.scn
diff --git a/testsuites/libtests/configure.ac b/testsuites/libtests/configure.ac
index b32d06eb22..3bcc0ec5c4 100644
--- a/testsuites/libtests/configure.ac
+++ b/testsuites/libtests/configure.ac
@@ -133,6 +133,7 @@ RTEMS_TEST_CHECK([dl05])
RTEMS_TEST_CHECK([dl06])
RTEMS_TEST_CHECK([dl07])
RTEMS_TEST_CHECK([dl08])
+RTEMS_TEST_CHECK([dl09])
RTEMS_TEST_CHECK([dumpbuf01])
RTEMS_TEST_CHECK([dup2])
RTEMS_TEST_CHECK([exit01])
diff --git a/testsuites/libtests/dl01/dl-load.c b/testsuites/libtests/dl01/dl-load.c
index 5438196e67..d93550d15b 100644
--- a/testsuites/libtests/dl01/dl-load.c
+++ b/testsuites/libtests/dl01/dl-load.c
@@ -12,8 +12,41 @@
#include "dl-load.h"
-typedef int (*call_t)(int argc, const char* argv[]);
+#include <rtems/rtl/rtl-shell.h>
+#include <rtems/rtl/rtl-trace.h>
+
+#define TEST_TRACE 0
+#if TEST_TRACE
+ #define DEBUG_TRACE (RTEMS_RTL_TRACE_DETAIL | \
+ RTEMS_RTL_TRACE_WARNING | \
+ RTEMS_RTL_TRACE_LOAD | \
+ RTEMS_RTL_TRACE_UNLOAD | \
+ RTEMS_RTL_TRACE_SYMBOL | \
+ RTEMS_RTL_TRACE_RELOC | \
+ RTEMS_RTL_TRACE_ALLOCATOR | \
+ RTEMS_RTL_TRACE_UNRESOLVED | \
+ RTEMS_RTL_TRACE_ARCHIVES | \
+ RTEMS_RTL_TRACE_DEPENDENCY)
+ #define DL_DEBUG_TRACE DEBUG_TRACE /* RTEMS_RTL_TRACE_ALL */
+ #define DL_RTL_CMDS 1
+#else
+ #define DL_DEBUG_TRACE 0
+ #define DL_RTL_CMDS 0
+#endif
+
+static void dl_load_dump (void)
+{
+#if DL_RTL_CMDS
+ char* list[] = { "rtl", "list", NULL };
+ char* sym[] = { "rtl", "sym", NULL };
+ printf ("RTL List:\n");
+ rtems_rtl_shell_command (2, list);
+ printf ("RTL Sym:\n");
+ rtems_rtl_shell_command (2, sym);
+#endif
+}
+typedef int (*call_t)(int argc, const char* argv[]);
static const char* call_1[] = { "Line 1", "Line 2" };
static const char* call_2[] = { "Call 2, line 1",
@@ -28,6 +61,10 @@ int dl_load_test(void)
int unresolved;
char* message = "loaded";
+#if DL_DEBUG_TRACE
+ rtems_rtl_trace_set_mask (DL_DEBUG_TRACE);
+#endif
+
printf("load: /dl01-o1.o\n");
handle = dlopen ("/dl01-o1.o", RTLD_NOW | RTLD_GLOBAL);
@@ -44,6 +81,8 @@ int dl_load_test(void)
printf ("handle: %p %s\n", handle, message);
+ dl_load_dump ();
+
call = dlsym (handle, "rtems_main");
if (call == NULL)
{
diff --git a/testsuites/libtests/dl08/dl-load.c b/testsuites/libtests/dl08/dl-load.c
index 615a837b39..6f4c6f3fa4 100644
--- a/testsuites/libtests/dl08/dl-load.c
+++ b/testsuites/libtests/dl08/dl-load.c
@@ -7,18 +7,24 @@
* http://www.rtems.org/license/LICENSE.
*/
-#define ARCHIVE_TRACE (RTEMS_RTL_TRACE_DETAIL | \
- RTEMS_RTL_TRACE_WARNING | \
- RTEMS_RTL_TRACE_LOAD | \
- RTEMS_RTL_TRACE_UNLOAD | \
- RTEMS_RTL_TRACE_SYMBOL | \
- RTEMS_RTL_TRACE_RELOC | \
- RTEMS_RTL_TRACE_ALLOCATOR | \
- RTEMS_RTL_TRACE_UNRESOLVED | \
- RTEMS_RTL_TRACE_ARCHIVES | \
- RTEMS_RTL_TRACE_DEPENDENCY)
-#define DL08_DEBUG_TRACE 0 /* RTEMS_RTL_TRACE_ALL */
-#define DL08_RTL_CMDS 0
+#define TEST_TRACE 0
+#if TEST_TRACE
+ #define DEBUG_TRACE (RTEMS_RTL_TRACE_DETAIL | \
+ RTEMS_RTL_TRACE_WARNING | \
+ RTEMS_RTL_TRACE_LOAD | \
+ RTEMS_RTL_TRACE_UNLOAD | \
+ RTEMS_RTL_TRACE_SYMBOL | \
+ RTEMS_RTL_TRACE_RELOC | \
+ RTEMS_RTL_TRACE_ALLOCATOR | \
+ RTEMS_RTL_TRACE_UNRESOLVED | \
+ RTEMS_RTL_TRACE_ARCHIVES | \
+ RTEMS_RTL_TRACE_DEPENDENCY)
+ #define DL_DEBUG_TRACE DEBUG_TRACE /* RTEMS_RTL_TRACE_ALL */
+ #define DL_RTL_CMDS 1
+#else
+ #define DL_DEBUG_TRACE 0
+ #define DL_RTL_CMDS 0
+#endif
#include <dlfcn.h>
@@ -33,7 +39,7 @@ typedef int (*call_sig)(void);
static void dl_load_dump (void)
{
-#if DL08_RTL_CMDS
+#if DL_RTL_CMDS
char* list[] = { "rtl", "list", NULL };
char* sym[] = { "rtl", "sym", NULL };
printf ("RTL List:\n");
@@ -114,8 +120,8 @@ int dl_load_test(void)
printf ("Test source (link in strstr): %s\n", dl_localise_file (__FILE__));
-#if DL08_DEBUG_TRACE
- rtems_rtl_trace_set_mask (DL08_DEBUG_TRACE);
+#if DL_DEBUG_TRACE
+ rtems_rtl_trace_set_mask (DL_DEBUG_TRACE);
#endif
o1 = dl_load_obj("/dl08-o1.o", false);
diff --git a/testsuites/libtests/dl09/dl-load.c b/testsuites/libtests/dl09/dl-load.c
new file mode 100644
index 0000000000..ee0ef0a335
--- /dev/null
+++ b/testsuites/libtests/dl09/dl-load.c
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2019 Chris Johns <chrisj@rtems.org>.
+ * All rights reserved.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#define TEST_TRACE 0
+#if TEST_TRACE
+ #define DEBUG_TRACE (RTEMS_RTL_TRACE_DETAIL | \
+ RTEMS_RTL_TRACE_WARNING | \
+ RTEMS_RTL_TRACE_LOAD | \
+ RTEMS_RTL_TRACE_UNLOAD | \
+ RTEMS_RTL_TRACE_SYMBOL | \
+ RTEMS_RTL_TRACE_RELOC | \
+ RTEMS_RTL_TRACE_ALLOCATOR | \
+ RTEMS_RTL_TRACE_UNRESOLVED | \
+ RTEMS_RTL_TRACE_ARCHIVES | \
+ RTEMS_RTL_TRACE_DEPENDENCY)
+ #define DL09_DEBUG_TRACE DEBUG_TRACE /* RTEMS_RTL_TRACE_ALL */
+ #define DL09_RTL_CMDS 1
+#else
+ #define DL09_DEBUG_TRACE 0
+ #define DL09_RTL_CMDS 0
+#endif
+
+#include <dlfcn.h>
+
+#include "dl-load.h"
+
+#include <tmacros.h>
+
+#include <rtems/malloc.h>
+#include <rtems/rtl/rtl-shell.h>
+#include <rtems/rtl/rtl-trace.h>
+
+extern void rtems_shell_print_heap_info(
+ const char *c,
+ const Heap_Information *h
+);
+
+typedef struct
+{
+ void* handle;
+ void* space;
+} objects;
+
+typedef struct
+{
+ const char* name;
+ bool has_unresolved;
+ size_t space;
+} object_def;
+
+#define MBYTES(_m) ((_m) * 1024UL * 1024UL)
+#define NUMOF(_a) (sizeof(_a) / sizeof(_a[0]))
+
+typedef int (*call_sig)(void);
+
+static void dl_load_dump (void)
+{
+#if DL09_RTL_CMDS
+ char* list[] = { "rtl", "list", NULL };
+ char* sym[] = { "rtl", "sym", NULL };
+ Heap_Information_block info;
+ malloc_info( &info );
+ printf ("RTL List:\n");
+ rtems_rtl_shell_command (2, list);
+ printf ("RTL Sym:\n");
+ rtems_rtl_shell_command (2, sym);
+ printf ("Malloc:\n");
+ rtems_shell_print_heap_info("free", &info.Free);
+#endif
+}
+
+static void dl_check_resolved(void* handle, bool has_unresolved)
+{
+ int unresolved = 0;
+ rtems_test_assert (dlinfo (handle, RTLD_DI_UNRESOLVED, &unresolved) == 0);
+ if (has_unresolved)
+ {
+ if (unresolved == 0)
+ {
+ dl_load_dump();
+ rtems_test_assert (unresolved != 0);
+ }
+ }
+ else
+ {
+ if (unresolved != 0)
+ {
+ dl_load_dump();
+ rtems_test_assert (unresolved == 0);
+ }
+ }
+ printf ("handel: %p: %sunresolved externals\n",
+ handle, unresolved != 0 ? "" : "no ");
+}
+
+static void* dl_load_obj(const char* name, bool has_unresolved)
+{
+ void* handle;
+
+ printf("load: %s\n", name);
+
+ handle = dlopen (name, RTLD_NOW | RTLD_GLOBAL);
+ if (!handle)
+ {
+ printf("dlopen failed: %s\n", dlerror());
+ return NULL;
+ }
+
+ dl_check_resolved (handle, has_unresolved);
+
+ printf ("handle: %p loaded\n", handle);
+
+ return handle;
+}
+
+static void dl_close (void* handle)
+{
+ int r;
+ printf ("handle: %p closing\n", handle);
+ r = dlclose (handle);
+ if (r != 0)
+ printf("dlclose failed: %s\n", dlerror());
+ rtems_test_assert (r == 0);
+}
+
+static int dl_call (void* handle, const char* func)
+{
+ call_sig call = dlsym (handle, func);
+ if (call == NULL)
+ {
+ printf("dlsym failed: symbol not found: %s\n", func);
+ return 1;
+ }
+ call ();
+ return 0;
+}
+
+static void dl_object_open (object_def* od, objects* o)
+{
+ o->handle = dl_load_obj(od->name, od->has_unresolved);
+ rtems_test_assert (o->handle != NULL);
+ if (!od->has_unresolved)
+ dl_check_resolved (o->handle, false);
+ if (od->space != 0)
+ {
+ o->space = malloc (od->space);
+ printf("space alloc: %s: %d: %p\n", od->name, od->space, o->space);
+ rtems_test_assert (o->space != NULL);
+ }
+ dl_load_dump ();
+}
+
+static void dl_object_close (objects* o)
+{
+ dl_close (o->handle);
+ printf("space dealloc: %p\n", o->space);
+ free (o->space);
+}
+
+int dl_load_test(void)
+{
+ object_def od[5] = { { "/dl09-o1.o", true, MBYTES(32) },
+ { "/dl09-o2.o", true, MBYTES(32) },
+ { "/dl09-o3.o", true, MBYTES(32) },
+ { "/dl09-o4.o", true, MBYTES(32) },
+ { "/dl09-o5.o", false, 0 } };
+ objects o[5] = { 0 };
+ size_t i;
+
+ printf ("Test source (link in strstr): %s\n", dl_localise_file (__FILE__));
+
+#if DL09_DEBUG_TRACE
+ rtems_rtl_trace_set_mask (DL09_DEBUG_TRACE);
+#endif
+
+ for (i = 0; i < NUMOF(od); ++i)
+ dl_object_open (&od[i], &o[i]);
+
+ dl_load_dump ();
+
+ printf ("Running rtems_main_o1:\n");
+ if (dl_call (o[0].handle, "rtems_main_o1"))
+ return 1;
+
+ for (i = 0; i < NUMOF(od); ++i)
+ dl_object_close (&o[i]);
+
+ return 0;
+}
diff --git a/testsuites/libtests/dl09/dl-load.h b/testsuites/libtests/dl09/dl-load.h
new file mode 100644
index 0000000000..72872917aa
--- /dev/null
+++ b/testsuites/libtests/dl09/dl-load.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2014, 2018 Chris Johns <chrisj@rtems.org>. All rights reserved.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <string.h>
+
+#if !defined(_DL_LOAD_H_)
+#define _DL_LOAD_H_
+
+static inline const char* dl_localise_file (const char* file)
+{
+ return (const char*) strstr (file, "testsuites");
+}
+
+int dl_load_test(void);
+
+#endif
diff --git a/testsuites/libtests/dl09/dl-o1.c b/testsuites/libtests/dl09/dl-o1.c
new file mode 100644
index 0000000000..22b839a438
--- /dev/null
+++ b/testsuites/libtests/dl09/dl-o1.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2018 Chris Johns <chrisj@rtems.org>.
+ * All rights reserved.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include "dl-o1.h"
+
+#include <rtems/test.h>
+#include "dl-load.h"
+#include "dl-o1.h"
+#include "dl-o2.h"
+
+#define printf(...) rtems_printf(&rtems_test_printer, __VA_ARGS__);
+
+/*
+ * Create some symbols. The uninitialised will be in the common section with
+ * separated text and data and this means there is no actual section in the ELF
+ * file, the details for this are in the symbols.
+ */
+int dl01_bss1; /* unitialised, .bss */
+float dl01_bss2[30]; /* unitialised, .bss */
+char dl01_bss3[10]; /* unitialised, .bss */
+int dl01_data1 = 1; /* initialised, .data */
+float dl01_data2 = 0.3333; /* initialised, .data */
+const int dl01_const1 = 3; /* read-only, .const */
+const float dl01_const2 = 0.666; /* read-only, .const */
+int dl01_func1(void) /* code, .text */
+{
+ return 4;
+}
+
+/*
+ * Yes a decl in the source. This is a modules main and I could not find which
+ * header main is defined in.
+ */
+int rtems_main_o1 (void);
+
+#define DL_NAME "dlo1"
+#define PAINT_VAR(_v) sizeof(_v), &_v, _v
+
+int rtems_main_o1 (void)
+{
+ printf (DL_NAME ": module: %s\n", dl_localise_file (__FILE__));
+ printf (DL_NAME ": dl01_bss1: %4u: %p: %d\n", PAINT_VAR (dl01_bss1));
+ printf (DL_NAME ": dl01_bss2: %4u: %p: %f\n", PAINT_VAR (dl01_bss2[0]));
+ printf (DL_NAME ": dl01_bss3: %4u: %p: %02x\n", PAINT_VAR (dl01_bss3[0]));
+ printf (DL_NAME ": dl01_data1: %4u: %p: %d\n", PAINT_VAR (dl01_data1));
+ /* no %f in the rtems test printer */
+ printf (DL_NAME ": dl01_data2: %4u: %p: %f\n", PAINT_VAR (dl01_data2));
+ printf (DL_NAME ": dl01_const1: %4u: %p: %d\n", PAINT_VAR (dl01_const1));
+ printf (DL_NAME ": dl01_const2: %4u: %p: %f\n", PAINT_VAR (dl01_const2));
+ printf (DL_NAME ": dl01_func1: %4u: %p\n", sizeof(dl01_func1), &dl01_func1);
+
+ rtems_main_o2 ();
+
+ return 0;
+}
diff --git a/testsuites/libtests/dl09/dl-o1.h b/testsuites/libtests/dl09/dl-o1.h
new file mode 100644
index 0000000000..f6a10f1481
--- /dev/null
+++ b/testsuites/libtests/dl09/dl-o1.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2018 Chris Johns <chrisj@rtems.org>.
+ * All rights reserved.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#if !defined(DL01_H)
+#define DL01_H
+
+extern int dl01_bss1;
+extern float dl01_bss2[30];
+extern char dl01_bss3[10];
+extern int dl01_data1;
+extern float dl01_data2;
+extern const int dl01_const1;
+extern const float dl01_const2;
+
+int dl01_func1(void);
+
+#endif
diff --git a/testsuites/libtests/dl09/dl-o2.c b/testsuites/libtests/dl09/dl-o2.c
new file mode 100644
index 0000000000..907fe9a268
--- /dev/null
+++ b/testsuites/libtests/dl09/dl-o2.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2014 Chris Johns <chrisj@rtems.org>. All rights reserved.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include "dl-load.h"
+#include "dl-o2.h"
+#include "dl-o3.h"
+
+#include <rtems/test.h>
+
+#define printf(...) rtems_printf(&rtems_test_printer, __VA_ARGS__);
+
+int dl02_bss1;
+float dl02_bss2[7];
+char dl02_bss3[21];
+int dl02_data1;
+float dl02_data2;
+
+#define DL_NAME "dlo2"
+#define PAINT_VAR(_v) sizeof(_v), &_v, _v
+
+int rtems_main_o2 (void)
+{
+ printf (DL_NAME ": module: %s\n", dl_localise_file (__FILE__));
+ printf (DL_NAME ": dl02_bss1: %4u: %p: %d\n", PAINT_VAR (dl02_bss1));
+ printf (DL_NAME ": dl02_bss2: %4u: %p: %f\n", PAINT_VAR (dl02_bss2[0]));
+ printf (DL_NAME ": dl02_bss3: %4u: %p: %02x\n", PAINT_VAR (dl02_bss3[0]));
+ printf (DL_NAME ": dl02_data1: %4u: %p: %d\n", PAINT_VAR (dl02_data1));
+ /* no %f in the rtems test printer */
+ printf (DL_NAME ": dl02_data2: %4u: %p: %f\n", PAINT_VAR (dl02_data2));
+
+ rtems_main_o3 ();
+
+ return 0;
+}
diff --git a/testsuites/libtests/dl09/dl-o2.h b/testsuites/libtests/dl09/dl-o2.h
new file mode 100644
index 0000000000..d6c1820f46
--- /dev/null
+++ b/testsuites/libtests/dl09/dl-o2.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2018 Chris Johns <chrisj@rtems.org>.
+ * All rights reserved.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#if !defined(DL02_H)
+#define DL02_H
+
+/*
+ * A set of variables in dl-o2 reference by dl-03.
+ */
+
+extern int dl02_bss1;
+extern float dl02_bss2[7];
+extern char dl02_bss3[21];
+extern int dl02_data1;
+extern float dl02_data2;
+
+int rtems_main_o2 (void);
+
+#endif
diff --git a/testsuites/libtests/dl09/dl-o3.c b/testsuites/libtests/dl09/dl-o3.c
new file mode 100644
index 0000000000..4333f34057
--- /dev/null
+++ b/testsuites/libtests/dl09/dl-o3.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2014 Chris Johns <chrisj@rtems.org>. All rights reserved.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include "dl-load.h"
+#include "dl-o3.h"
+#include "dl-o4.h"
+#include "dl-o5.h"
+
+#include <inttypes.h>
+#include <rtems/test.h>
+
+#define printf(...) rtems_printf(&rtems_test_printer, __VA_ARGS__);
+
+#define DL_NAME "dlo3"
+#define PAINT_VAR(_v) sizeof(_v), &_v, _v
+
+int rtems_main_o3 ()
+{
+ printf (DL_NAME ": module: %s\n", dl_localise_file (__FILE__));
+ printf (DL_NAME ": dl04_unresolv_1: %4u: %p: %d\n", PAINT_VAR (dl04_unresolv_1));
+ printf (DL_NAME ": dl04_unresolv_2: %4u: %p: %f\n", PAINT_VAR (dl04_unresolv_2));
+ printf (DL_NAME ": dl04_unresolv_3: %4u: %p: %02x\n", PAINT_VAR (dl04_unresolv_3));
+ printf (DL_NAME ": dl04_unresolv_4: %4u: %p: %p\n", PAINT_VAR (dl04_unresolv_4));
+ printf (DL_NAME ": dl04_unresolv_5: %4u: %p: %d\n", PAINT_VAR (dl04_unresolv_5));
+ printf (DL_NAME ": dl04_unresolv_6: %4u: %p: %s\n", PAINT_VAR (dl04_unresolv_6));
+ printf (DL_NAME ": dl05_unresolv_1: %4u: %p: %" PRIu64 "\n", PAINT_VAR (dl05_unresolv_1));
+ printf (DL_NAME ": dl05_unresolv_2: %4u: %p: %" PRIu16 "\n", PAINT_VAR (dl05_unresolv_2));
+ printf (DL_NAME ": dl05_unresolv_3: %4u: %p: %" PRIu32 "\n", PAINT_VAR (dl05_unresolv_3));
+ printf (DL_NAME ": dl05_unresolv_4: %4u: %p: %" PRIu8 "\n", PAINT_VAR (dl05_unresolv_4));
+ printf (DL_NAME ": dl05_unresolv_5: %4u: %p: %" PRIi64 "\n", PAINT_VAR (dl05_unresolv_5));
+
+ rtems_main_o4 ();
+
+ return 0;
+}
diff --git a/testsuites/libtests/dl09/dl-o3.h b/testsuites/libtests/dl09/dl-o3.h
new file mode 100644
index 0000000000..8c5d18dfb1
--- /dev/null
+++ b/testsuites/libtests/dl09/dl-o3.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2018 Chris Johns <chrisj@rtems.org>.
+ * All rights reserved.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#if !defined(DL03_H)
+#define DL03_H
+
+int rtems_main_o3 (void);
+
+#endif
diff --git a/testsuites/libtests/dl09/dl-o4.c b/testsuites/libtests/dl09/dl-o4.c
new file mode 100644
index 0000000000..60ada7ac68
--- /dev/null
+++ b/testsuites/libtests/dl09/dl-o4.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2014 Chris Johns <chrisj@rtems.org>. All rights reserved.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include "dl-load.h"
+#include "dl-o4.h"
+#include "dl-o5.h"
+
+#include <rtems/test.h>
+
+#define printf(...) rtems_printf(&rtems_test_printer, __VA_ARGS__);
+
+int dl04_unresolv_1;
+float dl04_unresolv_2;
+char dl04_unresolv_3;
+char* dl04_unresolv_4;
+const int dl04_unresolv_5 = 4;
+const char* dl04_unresolv_6 = "dl-O4";
+
+#define DL_NAME "dlo4"
+#define PAINT_VAR(_v) sizeof(_v), &_v, _v
+
+int rtems_main_o4 (void)
+{
+ printf (DL_NAME ": module: %s\n", dl_localise_file (__FILE__));
+ printf (DL_NAME ": dl04_unresolv_1: %4u: %p: %d\n", PAINT_VAR (dl04_unresolv_1));
+ printf (DL_NAME ": dl04_unresolv_2: %4u: %p: %f\n", PAINT_VAR (dl04_unresolv_2));
+ printf (DL_NAME ": dl04_unresolv_3: %4u: %p: %02x\n", PAINT_VAR (dl04_unresolv_3));
+ printf (DL_NAME ": dl04_unresolv_4: %4u: %p: %p\n", PAINT_VAR (dl04_unresolv_4));
+ printf (DL_NAME ": dl04_unresolv_5: %4u: %p: %d\n", PAINT_VAR (dl04_unresolv_5));
+ printf (DL_NAME ": dl04_unresolv_6: %4u: %p: %s\n", PAINT_VAR (dl04_unresolv_6));
+
+ rtems_main_o5 ();
+
+ return 0;
+}
diff --git a/testsuites/libtests/dl09/dl-o4.h b/testsuites/libtests/dl09/dl-o4.h
new file mode 100644
index 0000000000..bab9fc1ae4
--- /dev/null
+++ b/testsuites/libtests/dl09/dl-o4.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2018 Chris Johns <chrisj@rtems.org>.
+ * All rights reserved.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#if !defined(DL04_H)
+#define DL04_H
+
+/*
+ * A set of variables in dl-o4 referenced by dl-03 and unresolved when dl-o3 is
+ * loaded. They are all uninitialised variables with various sizes in a mixed
+ * order to get various alignments. These and dl-o5 variables are designed to
+ * force the dependent tables to grow.
+ */
+
+extern int dl04_unresolv_1;
+extern float dl04_unresolv_2;
+extern char dl04_unresolv_3;
+extern char* dl04_unresolv_4;
+extern const int dl04_unresolv_5;
+extern const char* dl04_unresolv_6;
+
+int rtems_main_o4 (void);
+
+#endif
diff --git a/testsuites/libtests/dl09/dl-o5.c b/testsuites/libtests/dl09/dl-o5.c
new file mode 100644
index 0000000000..84e8c84173
--- /dev/null
+++ b/testsuites/libtests/dl09/dl-o5.c
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2019 Chris Johns <chrisj@rtems.org>. All rights reserved.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include "dl-load.h"
+#include "dl-o5.h"
+
+#include <inttypes.h>
+#include <rtems/test.h>
+
+#define printf(...) rtems_printf(&rtems_test_printer, __VA_ARGS__);
+
+uint64_t dl05_unresolv_1;
+uint16_t dl05_unresolv_2;
+uint32_t dl05_unresolv_3;
+uint8_t dl05_unresolv_4;
+int64_t dl05_unresolv_5;
+
+#define DL_NAME "dlo5"
+#define PAINT_VAR(_v) sizeof(_v), &_v, _v
+
+int rtems_main_o5 (void)
+{
+ printf (DL_NAME ": module: %s\n", dl_localise_file (__FILE__));
+ printf (DL_NAME ": dl05_unresolv_1: %4u: %p: %" PRIu64 "\n", PAINT_VAR (dl05_unresolv_1));
+ printf (DL_NAME ": dl05_unresolv_2: %4u: %p: %" PRIu16 "\n", PAINT_VAR (dl05_unresolv_2));
+ printf (DL_NAME ": dl05_unresolv_3: %4u: %p: %" PRIu32 "\n", PAINT_VAR (dl05_unresolv_3));
+ printf (DL_NAME ": dl05_unresolv_4: %4u: %p: %" PRIu8 "\n", PAINT_VAR (dl05_unresolv_4));
+ printf (DL_NAME ": dl05_unresolv_5: %4u: %p: %" PRIi64 "\n", PAINT_VAR (dl05_unresolv_5));
+
+ return 0;
+}
diff --git a/testsuites/libtests/dl09/dl-o5.h b/testsuites/libtests/dl09/dl-o5.h
new file mode 100644
index 0000000000..bb4ce468a2
--- /dev/null
+++ b/testsuites/libtests/dl09/dl-o5.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2018 Chris Johns <chrisj@rtems.org>.
+ * All rights reserved.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#include <stdint.h>
+
+#if !defined(DL05_H)
+#define DL05_H
+
+/*
+ * A set of variables in dl-o5 referenced by dl-03 and unresolved when dl-o3 is
+ * loaded. They are all uninitialised variables with various sizes in a mixed
+ * order to get various alignments. These and dl-o4 variables are designed to
+ * force the dependent tables to grow.
+ */
+
+extern uint64_t dl05_unresolv_1;
+extern uint16_t dl05_unresolv_2;
+extern uint32_t dl05_unresolv_3;
+extern uint8_t dl05_unresolv_4;
+extern int64_t dl05_unresolv_5;
+
+int rtems_main_o5 (void);
+
+#endif
diff --git a/testsuites/libtests/dl09/dl09.doc b/testsuites/libtests/dl09/dl09.doc
new file mode 100644
index 0000000000..4c5d97ef2a
--- /dev/null
+++ b/testsuites/libtests/dl09/dl09.doc
@@ -0,0 +1,23 @@
+# Copyright (c) 2019 Chris Johns <chrisj@rtems.org>
+#
+# The license and distribution terms for this file may be
+# found in the file LICENSE in this distribution or at
+# http://www.rtems.org/license/LICENSE.
+#
+
+This file describes the directives and concepts tested by this test set.
+
+test set name: dl09
+
+directives:
+
+ dlopen
+ dlinfo
+ dlsym
+ dlclose
+
+concepts:
+
++ Load modules with a space between then so short address range relative
+ instructions require trampolines.
++ Repeat 100 times.
diff --git a/testsuites/libtests/dl09/dl09.scn b/testsuites/libtests/dl09/dl09.scn
new file mode 100644
index 0000000000..f4b258f25b
--- /dev/null
+++ b/testsuites/libtests/dl09/dl09.scn
@@ -0,0 +1,390 @@
+*** BEGIN OF TEST libdl (RTL) 9 ***
+*** TEST VERSION: 5.0.0.ab08681fe52cad071f3a8d554af28c8bfc53b28f-modified
+*** TEST STATE: EXPECTED-PASS
+*** TEST BUILD: RTEMS_POSIX_API
+*** TEST TOOLS: 7.4.0 20181206 (RTEMS 5, RSB 257c9267cfce362138a265764c6a799c12c6b181, Newlib dc6e94551f09d3a983afd571478d63a09d6f66fa)
+--------------------------------------------------
+ Run: 0
+Test source (link in strstr): testsuites/libtests/dl09/dl-load.c
+load: /dl09-o1.o
+handel: 0x123510: unresolved externals
+handle: 0x123510 loaded
+space alloc: /dl09-o1.o: 33554432: 0x124d10
+load: /dl09-o2.o
+handel: 0x124390: unresolved externals
+handle: 0x124390 loaded
+space alloc: /dl09-o2.o: 33554432: 0x2125978
+load: /dl09-o3.o
+handel: 0x4125980: unresolved externals
+handle: 0x4125980 loaded
+space alloc: /dl09-o3.o: 33554432: 0x41267f0
+load: /dl09-o4.o
+handel: 0x41266b0: unresolved externals
+handle: 0x41266b0 loaded
+space alloc: /dl09-o4.o: 33554432: 0x6127528
+load: /dl09-o5.o
+handel: 0x8127530: no unresolved externals
+handle: 0x8127530 loaded
+handel: 0x8127530: no unresolved externals
+Running rtems_main_o1:
+dlo1: module: testsuites/libtests/dl09/dl-o1.c
+dlo1: dl01_bss1: 4: 0x124088: 0
+dlo1: dl01_bss2: 4: 0x12408c: %f
+dlo1: dl01_bss3: 1: 0x124104: 00
+dlo1: dl01_data1: 4: 0x124070: 1
+dlo1: dl01_data2: 4: 0x124074: %f
+dlo1: dl01_const1: 4: 0x124050: 3
+dlo1: dl01_const2: 4: 0x124054: %f
+dlo1: dl01_func1: 1: 0x123cf9
+dlo2: module: testsuites/libtests/dl09/dl-o2.c
+dlo2: dl02_bss1: 4: 0x2125468: 0
+dlo2: dl02_bss2: 4: 0x212546c: %f
+dlo2: dl02_bss3: 1: 0x2125488: 00
+dlo2: dl02_data1: 4: 0x21254a0: 0
+dlo2: dl02_data2: 4: 0x21254a4: %f
+dlo3: module: testsuites/libtests/dl09/dl-o3.c
+dlo3: dl04_unresolv_1: 4: 0x61270e8: 0
+dlo3: dl04_unresolv_2: 4: 0x61270ec: %f
+dlo3: dl04_unresolv_3: 1: 0x61270f0: 00
+dlo3: dl04_unresolv_4: 4: 0x61270f4: 0
+dlo3: dl04_unresolv_5: 4: 0x61270bc: 4
+dlo3: dl04_unresolv_6: 4: 0x61270d8: dl-O4
+dlo3: dl05_unresolv_1: 8: 0x8127d20: 0
+dlo3: dl05_unresolv_2: 2: 0x8127d28: 0
+dlo3: dl05_unresolv_3: 4: 0x8127d2c: 0
+dlo3: dl05_unresolv_4: 1: 0x8127d30: 0
+dlo3: dl05_unresolv_5: 8: 0x8127d38: 0
+dlo4: module: testsuites/libtests/dl09/dl-o4.c
+dlo4: dl04_unresolv_1: 4: 0x61270e8: 0
+dlo4: dl04_unresolv_2: 4: 0x61270ec: %f
+dlo4: dl04_unresolv_3: 1: 0x61270f0: 00
+dlo4: dl04_unresolv_4: 4: 0x61270f4: 0
+dlo4: dl04_unresolv_5: 4: 0x61270bc: 4
+dlo4: dl04_unresolv_6: 4: 0x61270d8: dl-O4
+dlo5: module: testsuites/libtests/dl09/dl-o5.c
+dlo5: dl05_unresolv_1: 8: 0x8127d20: 0
+dlo5: dl05_unresolv_2: 2: 0x8127d28: 0
+dlo5: dl05_unresolv_3: 4: 0x8127d2c: 0
+dlo5: dl05_unresolv_4: 1: 0x8127d30: 0
+dlo5: dl05_unresolv_5: 8: 0x8127d38: 0
+handle: 0x123510 closing
+space dealloc: 0x124d10
+handle: 0x124390 closing
+space dealloc: 0x2125978
+handle: 0x4125980 closing
+space dealloc: 0x41267f0
+handle: 0x41266b0 closing
+space dealloc: 0x6127528
+handle: 0x8127530 closing
+space dealloc: 0
+--------------------------------------------------
+ Run: 1
+Test source (link in strstr): testsuites/libtests/dl09/dl-load.c
+load: /dl09-o1.o
+handel: 0x123510: unresolved externals
+handle: 0x123510 loaded
+space alloc: /dl09-o1.o: 33554432: 0x124d10
+load: /dl09-o2.o
+handel: 0x124390: unresolved externals
+handle: 0x124390 loaded
+space alloc: /dl09-o2.o: 33554432: 0x2125978
+load: /dl09-o3.o
+handel: 0x4125980: unresolved externals
+handle: 0x4125980 loaded
+space alloc: /dl09-o3.o: 33554432: 0x41267f0
+load: /dl09-o4.o
+handel: 0x41266b0: unresolved externals
+handle: 0x41266b0 loaded
+space alloc: /dl09-o4.o: 33554432: 0x6127528
+load: /dl09-o5.o
+handel: 0x8127530: no unresolved externals
+handle: 0x8127530 loaded
+handel: 0x8127530: no unresolved externals
+Running rtems_main_o1:
+dlo1: module: testsuites/libtests/dl09/dl-o1.c
+dlo1: dl01_bss1: 4: 0x124088: 0
+dlo1: dl01_bss2: 4: 0x12408c: %f
+dlo1: dl01_bss3: 1: 0x124104: 00
+dlo1: dl01_data1: 4: 0x124070: 1
+dlo1: dl01_data2: 4: 0x124074: %f
+dlo1: dl01_const1: 4: 0x124050: 3
+dlo1: dl01_const2: 4: 0x124054: %f
+dlo1: dl01_func1: 1: 0x123cf9
+dlo2: module: testsuites/libtests/dl09/dl-o2.c
+dlo2: dl02_bss1: 4: 0x2125468: 0
+dlo2: dl02_bss2: 4: 0x212546c: %f
+dlo2: dl02_bss3: 1: 0x2125488: 00
+dlo2: dl02_data1: 4: 0x21254a0: 0
+dlo2: dl02_data2: 4: 0x21254a4: %f
+dlo3: module: testsuites/libtests/dl09/dl-o3.c
+dlo3: dl04_unresolv_1: 4: 0x61270e8: 0
+dlo3: dl04_unresolv_2: 4: 0x61270ec: %f
+dlo3: dl04_unresolv_3: 1: 0x61270f0: 00
+dlo3: dl04_unresolv_4: 4: 0x61270f4: 0
+dlo3: dl04_unresolv_5: 4: 0x61270bc: 4
+dlo3: dl04_unresolv_6: 4: 0x61270d8: dl-O4
+dlo3: dl05_unresolv_1: 8: 0x8127d20: 0
+dlo3: dl05_unresolv_2: 2: 0x8127d28: 0
+dlo3: dl05_unresolv_3: 4: 0x8127d2c: 0
+dlo3: dl05_unresolv_4: 1: 0x8127d30: 0
+dlo3: dl05_unresolv_5: 8: 0x8127d38: 0
+dlo4: module: testsuites/libtests/dl09/dl-o4.c
+dlo4: dl04_unresolv_1: 4: 0x61270e8: 0
+dlo4: dl04_unresolv_2: 4: 0x61270ec: %f
+dlo4: dl04_unresolv_3: 1: 0x61270f0: 00
+dlo4: dl04_unresolv_4: 4: 0x61270f4: 0
+dlo4: dl04_unresolv_5: 4: 0x61270bc: 4
+dlo4: dl04_unresolv_6: 4: 0x61270d8: dl-O4
+dlo5: module: testsuites/libtests/dl09/dl-o5.c
+dlo5: dl05_unresolv_1: 8: 0x8127d20: 0
+dlo5: dl05_unresolv_2: 2: 0x8127d28: 0
+dlo5: dl05_unresolv_3: 4: 0x8127d2c: 0
+dlo5: dl05_unresolv_4: 1: 0x8127d30: 0
+dlo5: dl05_unresolv_5: 8: 0x8127d38: 0
+handle: 0x123510 closing
+space dealloc: 0x124d10
+handle: 0x124390 closing
+space dealloc: 0x2125978
+handle: 0x4125980 closing
+space dealloc: 0x41267f0
+handle: 0x41266b0 closing
+space dealloc: 0x6127528
+handle: 0x8127530 closing
+space dealloc: 0
+--------------------------------------------------
+ Run: 2
+Test source (link in strstr): testsuites/libtests/dl09/dl-load.c
+load: /dl09-o1.o
+handel: 0x123510: unresolved externals
+handle: 0x123510 loaded
+space alloc: /dl09-o1.o: 33554432: 0x124d10
+load: /dl09-o2.o
+handel: 0x124390: unresolved externals
+handle: 0x124390 loaded
+space alloc: /dl09-o2.o: 33554432: 0x2125978
+load: /dl09-o3.o
+handel: 0x4125980: unresolved externals
+handle: 0x4125980 loaded
+space alloc: /dl09-o3.o: 33554432: 0x41267f0
+load: /dl09-o4.o
+handel: 0x41266b0: unresolved externals
+handle: 0x41266b0 loaded
+space alloc: /dl09-o4.o: 33554432: 0x6127528
+load: /dl09-o5.o
+handel: 0x8127530: no unresolved externals
+handle: 0x8127530 loaded
+handel: 0x8127530: no unresolved externals
+Running rtems_main_o1:
+dlo1: module: testsuites/libtests/dl09/dl-o1.c
+dlo1: dl01_bss1: 4: 0x124088: 0
+dlo1: dl01_bss2: 4: 0x12408c: %f
+dlo1: dl01_bss3: 1: 0x124104: 00
+dlo1: dl01_data1: 4: 0x124070: 1
+dlo1: dl01_data2: 4: 0x124074: %f
+dlo1: dl01_const1: 4: 0x124050: 3
+dlo1: dl01_const2: 4: 0x124054: %f
+dlo1: dl01_func1: 1: 0x123cf9
+dlo2: module: testsuites/libtests/dl09/dl-o2.c
+dlo2: dl02_bss1: 4: 0x2125468: 0
+dlo2: dl02_bss2: 4: 0x212546c: %f
+dlo2: dl02_bss3: 1: 0x2125488: 00
+dlo2: dl02_data1: 4: 0x21254a0: 0
+dlo2: dl02_data2: 4: 0x21254a4: %f
+dlo3: module: testsuites/libtests/dl09/dl-o3.c
+dlo3: dl04_unresolv_1: 4: 0x61270e8: 0
+dlo3: dl04_unresolv_2: 4: 0x61270ec: %f
+dlo3: dl04_unresolv_3: 1: 0x61270f0: 00
+dlo3: dl04_unresolv_4: 4: 0x61270f4: 0
+dlo3: dl04_unresolv_5: 4: 0x61270bc: 4
+dlo3: dl04_unresolv_6: 4: 0x61270d8: dl-O4
+dlo3: dl05_unresolv_1: 8: 0x8127d20: 0
+dlo3: dl05_unresolv_2: 2: 0x8127d28: 0
+dlo3: dl05_unresolv_3: 4: 0x8127d2c: 0
+dlo3: dl05_unresolv_4: 1: 0x8127d30: 0
+dlo3: dl05_unresolv_5: 8: 0x8127d38: 0
+dlo4: module: testsuites/libtests/dl09/dl-o4.c
+dlo4: dl04_unresolv_1: 4: 0x61270e8: 0
+dlo4: dl04_unresolv_2: 4: 0x61270ec: %f
+dlo4: dl04_unresolv_3: 1: 0x61270f0: 00
+dlo4: dl04_unresolv_4: 4: 0x61270f4: 0
+dlo4: dl04_unresolv_5: 4: 0x61270bc: 4
+dlo4: dl04_unresolv_6: 4: 0x61270d8: dl-O4
+dlo5: module: testsuites/libtests/dl09/dl-o5.c
+dlo5: dl05_unresolv_1: 8: 0x8127d20: 0
+dlo5: dl05_unresolv_2: 2: 0x8127d28: 0
+dlo5: dl05_unresolv_3: 4: 0x8127d2c: 0
+dlo5: dl05_unresolv_4: 1: 0x8127d30: 0
+dlo5: dl05_unresolv_5: 8: 0x8127d38: 0
+handle: 0x123510 closing
+space dealloc: 0x124d10
+handle: 0x124390 closing
+space dealloc: 0x2125978
+handle: 0x4125980 closing
+space dealloc: 0x41267f0
+handle: 0x41266b0 closing
+space dealloc: 0x6127528
+handle: 0x8127530 closing
+space dealloc: 0
+--------------------------------------------------
+ Run: 3
+Test source (link in strstr): testsuites/libtests/dl09/dl-load.c
+load: /dl09-o1.o
+handel: 0x123510: unresolved externals
+handle: 0x123510 loaded
+space alloc: /dl09-o1.o: 33554432: 0x124d10
+load: /dl09-o2.o
+handel: 0x124390: unresolved externals
+handle: 0x124390 loaded
+space alloc: /dl09-o2.o: 33554432: 0x2125978
+load: /dl09-o3.o
+handel: 0x4125980: unresolved externals
+handle: 0x4125980 loaded
+space alloc: /dl09-o3.o: 33554432: 0x41267f0
+load: /dl09-o4.o
+handel: 0x41266b0: unresolved externals
+handle: 0x41266b0 loaded
+space alloc: /dl09-o4.o: 33554432: 0x6127528
+load: /dl09-o5.o
+handel: 0x8127530: no unresolved externals
+handle: 0x8127530 loaded
+handel: 0x8127530: no unresolved externals
+Running rtems_main_o1:
+dlo1: module: testsuites/libtests/dl09/dl-o1.c
+dlo1: dl01_bss1: 4: 0x124088: 0
+dlo1: dl01_bss2: 4: 0x12408c: %f
+dlo1: dl01_bss3: 1: 0x124104: 00
+dlo1: dl01_data1: 4: 0x124070: 1
+dlo1: dl01_data2: 4: 0x124074: %f
+dlo1: dl01_const1: 4: 0x124050: 3
+dlo1: dl01_const2: 4: 0x124054: %f
+dlo1: dl01_func1: 1: 0x123cf9
+dlo2: module: testsuites/libtests/dl09/dl-o2.c
+dlo2: dl02_bss1: 4: 0x2125468: 0
+dlo2: dl02_bss2: 4: 0x212546c: %f
+dlo2: dl02_bss3: 1: 0x2125488: 00
+dlo2: dl02_data1: 4: 0x21254a0: 0
+dlo2: dl02_data2: 4: 0x21254a4: %f
+dlo3: module: testsuites/libtests/dl09/dl-o3.c
+dlo3: dl04_unresolv_1: 4: 0x61270e8: 0
+dlo3: dl04_unresolv_2: 4: 0x61270ec: %f
+dlo3: dl04_unresolv_3: 1: 0x61270f0: 00
+dlo3: dl04_unresolv_4: 4: 0x61270f4: 0
+dlo3: dl04_unresolv_5: 4: 0x61270bc: 4
+dlo3: dl04_unresolv_6: 4: 0x61270d8: dl-O4
+dlo3: dl05_unresolv_1: 8: 0x8127d20: 0
+dlo3: dl05_unresolv_2: 2: 0x8127d28: 0
+dlo3: dl05_unresolv_3: 4: 0x8127d2c: 0
+dlo3: dl05_unresolv_4: 1: 0x8127d30: 0
+dlo3: dl05_unresolv_5: 8: 0x8127d38: 0
+dlo4: module: testsuites/libtests/dl09/dl-o4.c
+dlo4: dl04_unresolv_1: 4: 0x61270e8: 0
+dlo4: dl04_unresolv_2: 4: 0x61270ec: %f
+dlo4: dl04_unresolv_3: 1: 0x61270f0: 00
+dlo4: dl04_unresolv_4: 4: 0x61270f4: 0
+dlo4: dl04_unresolv_5: 4: 0x61270bc: 4
+dlo4: dl04_unresolv_6: 4: 0x61270d8: dl-O4
+dlo5: module: testsuites/libtests/dl09/dl-o5.c
+dlo5: dl05_unresolv_1: 8: 0x8127d20: 0
+dlo5: dl05_unresolv_2: 2: 0x8127d28: 0
+dlo5: dl05_unresolv_3: 4: 0x8127d2c: 0
+dlo5: dl05_unresolv_4: 1: 0x8127d30: 0
+dlo5: dl05_unresolv_5: 8: 0x8127d38: 0
+handle: 0x123510 closing
+space dealloc: 0x124d10
+handle: 0x124390 closing
+space dealloc: 0x2125978
+handle: 0x4125980 closing
+space dealloc: 0x41267f0
+handle: 0x41266b0 closing
+space dealloc: 0x6127528
+handle: 0x8127530 closing
+space dealloc: 0
+--------------------------------------------------
+
+ REPEAT 100 TIMES
+
+--------------------------------------------------
+ Run: 99
+Test source (link in strstr): testsuites/libtests/dl09/dl-load.c
+load: /dl09-o1.o
+handel: 0x123510: unresolved externals
+handle: 0x123510 loaded
+space alloc: /dl09-o1.o: 33554432: 0x124d10
+load: /dl09-o2.o
+handel: 0x124390: unresolved externals
+handle: 0x124390 loaded
+space alloc: /dl09-o2.o: 33554432: 0x2125978
+load: /dl09-o3.o
+handel: 0x4125980: unresolved externals
+handle: 0x4125980 loaded
+space alloc: /dl09-o3.o: 33554432: 0x41267f0
+load: /dl09-o4.o
+handel: 0x41266b0: unresolved externals
+handle: 0x41266b0 loaded
+space alloc: /dl09-o4.o: 33554432: 0x6127528
+load: /dl09-o5.o
+handel: 0x8127530: no unresolved externals
+handle: 0x8127530 loaded
+handel: 0x8127530: no unresolved externals
+Running rtems_main_o1:
+dlo1: module: testsuites/libtests/dl09/dl-o1.c
+dlo1: dl01_bss1: 4: 0x124088: 0
+dlo1: dl01_bss2: 4: 0x12408c: %f
+dlo1: dl01_bss3: 1: 0x124104: 00
+dlo1: dl01_data1: 4: 0x124070: 1
+dlo1: dl01_data2: 4: 0x124074: %f
+dlo1: dl01_const1: 4: 0x124050: 3
+dlo1: dl01_const2: 4: 0x124054: %f
+dlo1: dl01_func1: 1: 0x123cf9
+dlo2: module: testsuites/libtests/dl09/dl-o2.c
+dlo2: dl02_bss1: 4: 0x2125468: 0
+dlo2: dl02_bss2: 4: 0x212546c: %f
+dlo2: dl02_bss3: 1: 0x2125488: 00
+dlo2: dl02_data1: 4: 0x21254a0: 0
+dlo2: dl02_data2: 4: 0x21254a4: %f
+dlo3: module: testsuites/libtests/dl09/dl-o3.c
+dlo3: dl04_unresolv_1: 4: 0x61270e8: 0
+dlo3: dl04_unresolv_2: 4: 0x61270ec: %f
+dlo3: dl04_unresolv_3: 1: 0x61270f0: 00
+dlo3: dl04_unresolv_4: 4: 0x61270f4: 0
+dlo3: dl04_unresolv_5: 4: 0x61270bc: 4
+dlo3: dl04_unresolv_6: 4: 0x61270d8: dl-O4
+dlo3: dl05_unresolv_1: 8: 0x8127d20: 0
+dlo3: dl05_unresolv_2: 2: 0x8127d28: 0
+dlo3: dl05_unresolv_3: 4: 0x8127d2c: 0
+dlo3: dl05_unresolv_4: 1: 0x8127d30: 0
+dlo3: dl05_unresolv_5: 8: 0x8127d38: 0
+dlo4: module: testsuites/libtests/dl09/dl-o4.c
+dlo4: dl04_unresolv_1: 4: 0x61270e8: 0
+dlo4: dl04_unresolv_2: 4: 0x61270ec: %f
+dlo4: dl04_unresolv_3: 1: 0x61270f0: 00
+dlo4: dl04_unresolv_4: 4: 0x61270f4: 0
+dlo4: dl04_unresolv_5: 4: 0x61270bc: 4
+dlo4: dl04_unresolv_6: 4: 0x61270d8: dl-O4
+dlo5: module: testsuites/libtests/dl09/dl-o5.c
+dlo5: dl05_unresolv_1: 8: 0x8127d20: 0
+dlo5: dl05_unresolv_2: 2: 0x8127d28: 0
+dlo5: dl05_unresolv_3: 4: 0x8127d2c: 0
+dlo5: dl05_unresolv_4: 1: 0x8127d30: 0
+dlo5: dl05_unresolv_5: 8: 0x8127d38: 0
+handle: 0x123510 closing
+space dealloc: 0x124d10
+handle: 0x124390 closing
+space dealloc: 0x2125978
+handle: 0x4125980 closing
+space dealloc: 0x41267f0
+handle: 0x41266b0 closing
+space dealloc: 0x6127528
+handle: 0x8127530 closing
+space dealloc: 0
+
+*** END OF TEST libdl (RTL) 9 ***
+
+
+*** FATAL ***
+fatal source: 5 (RTEMS_FATAL_SOURCE_EXIT)
+fatal code: 0 (0x00000000)
+RTEMS version: 5.0.0.ab08681fe52cad071f3a8d554af28c8bfc53b28f-modified
+RTEMS tools: 7.4.0 20181206 (RTEMS 5, RSB 257c9267cfce362138a265764c6a799c12c6b181, Newlib dc6e94551f09d3a983afd571478d63a09d6f66fa)
+executing thread ID: 0x08a010001
+executing thread name: UI1
diff --git a/testsuites/libtests/dl09/init.c b/testsuites/libtests/dl09/init.c
new file mode 100644
index 0000000000..dbcc7ba84c
--- /dev/null
+++ b/testsuites/libtests/dl09/init.c
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2018 Chris Johns <chrisj@rtems.org>. All rights reserved.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#ifdef HAVE_CONFIG_H
+ #include "config.h"
+#endif
+
+#include "tmacros.h"
+
+#include <errno.h>
+#include <string.h>
+#include <stdint.h>
+#include <unistd.h>
+
+#include <rtems/rtl/rtl.h>
+#include <rtems/untar.h>
+
+#include "dl-load.h"
+
+const char rtems_test_name[] = "libdl (RTL) 9";
+
+/* forward declarations to avoid warnings */
+static rtems_task Init(rtems_task_argument argument);
+
+#include "dl09-tar.h"
+
+#define TARFILE_START dl09_tar
+#define TARFILE_SIZE dl09_tar_size
+
+static int test(void)
+{
+ int ret;
+ ret = dl_load_test();
+ if (ret)
+ rtems_test_exit(ret);
+ return 0;
+}
+
+static void Init(rtems_task_argument arg)
+{
+ int te;
+ int i;
+
+ TEST_BEGIN();
+
+ te = Untar_FromMemory((void *)TARFILE_START, (size_t)TARFILE_SIZE);
+ if (te != 0)
+ {
+ printf("untar failed: %d\n", te);
+ rtems_test_exit(1);
+ exit (1);
+ }
+
+ for (i = 0; i < 100; ++i)
+ {
+ printf ("--------------------------------------------------\n");
+ printf (" Run: %d\n", i);
+ test();
+ }
+
+ TEST_END();
+
+ rtems_test_exit(0);
+}
+
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+#define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
+
+#define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 4
+
+#define CONFIGURE_MAXIMUM_TASKS 1
+
+#define CONFIGURE_MAXIMUM_SEMAPHORES 1
+
+#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_INIT_TASK_STACK_SIZE (8U * 1024U)
+
+#define CONFIGURE_INIT_TASK_ATTRIBUTES (RTEMS_DEFAULT_ATTRIBUTES | RTEMS_FLOATING_POINT)
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>