From d8c70ba65b13cd023b50b8aed5d91e455017cdd5 Mon Sep 17 00:00:00 2001 From: Chris Johns Date: Tue, 15 Jan 2019 17:47:41 +1100 Subject: 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 --- cpukit/include/rtems/rtl/rtl-obj.h | 38 +++- cpukit/libdl/rtl-elf.c | 57 +++++- cpukit/libdl/rtl-elf.h | 64 +++++- cpukit/libdl/rtl-mdreloc-arm.c | 301 ++++++++++++++++++++-------- cpukit/libdl/rtl-mdreloc-bfin.c | 54 ++++- cpukit/libdl/rtl-mdreloc-h8300.c | 54 ++++- cpukit/libdl/rtl-mdreloc-i386.c | 54 ++++- cpukit/libdl/rtl-mdreloc-lm32.c | 54 ++++- cpukit/libdl/rtl-mdreloc-m68k.c | 54 ++++- cpukit/libdl/rtl-mdreloc-mips.c | 70 ++++++- cpukit/libdl/rtl-mdreloc-moxie.c | 54 ++++- cpukit/libdl/rtl-mdreloc-powerpc.c | 56 +++++- cpukit/libdl/rtl-mdreloc-sparc.c | 54 ++++- cpukit/libdl/rtl-mdreloc-v850.c | 54 ++++- cpukit/libdl/rtl-obj.c | 33 +++- testsuites/libtests/Makefile.am | 48 ++++- testsuites/libtests/configure.ac | 1 + testsuites/libtests/dl01/dl-load.c | 41 +++- testsuites/libtests/dl08/dl-load.c | 36 ++-- testsuites/libtests/dl09/dl-load.c | 195 +++++++++++++++++++ testsuites/libtests/dl09/dl-load.h | 21 ++ testsuites/libtests/dl09/dl-o1.c | 61 ++++++ testsuites/libtests/dl09/dl-o1.h | 23 +++ testsuites/libtests/dl09/dl-o2.c | 39 ++++ testsuites/libtests/dl09/dl-o2.h | 25 +++ testsuites/libtests/dl09/dl-o3.c | 40 ++++ testsuites/libtests/dl09/dl-o3.h | 15 ++ testsuites/libtests/dl09/dl-o4.c | 40 ++++ testsuites/libtests/dl09/dl-o4.h | 29 +++ testsuites/libtests/dl09/dl-o5.c | 36 ++++ testsuites/libtests/dl09/dl-o5.h | 30 +++ testsuites/libtests/dl09/dl09.doc | 23 +++ testsuites/libtests/dl09/dl09.scn | 390 +++++++++++++++++++++++++++++++++++++ testsuites/libtests/dl09/init.c | 90 +++++++++ 34 files changed, 2088 insertions(+), 146 deletions(-) create mode 100644 testsuites/libtests/dl09/dl-load.c create mode 100644 testsuites/libtests/dl09/dl-load.h create mode 100644 testsuites/libtests/dl09/dl-o1.c create mode 100644 testsuites/libtests/dl09/dl-o1.h create mode 100644 testsuites/libtests/dl09/dl-o2.c create mode 100644 testsuites/libtests/dl09/dl-o2.h create mode 100644 testsuites/libtests/dl09/dl-o3.c create mode 100644 testsuites/libtests/dl09/dl-o3.h create mode 100644 testsuites/libtests/dl09/dl-o4.c create mode 100644 testsuites/libtests/dl09/dl-o4.h create mode 100644 testsuites/libtests/dl09/dl-o5.c create mode 100644 testsuites/libtests/dl09/dl-o5.h create mode 100644 testsuites/libtests/dl09/dl09.doc create mode 100644 testsuites/libtests/dl09/dl09.scn create mode 100644 testsuites/libtests/dl09/init.c 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 + * COPYRIGHT (c) 2012,2019 Chris Johns * * 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. */ @@ -352,6 +358,20 @@ static inline bool rtems_rtl_obj_has_symbol (const rtems_rtl_obj* obj, sym < (obj->global_table + obj->global_syms)); } +/** + * 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. * @@ -476,6 +496,22 @@ 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. * 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 @@ -556,6 +579,19 @@ rtems_rtl_elf_common (rtems_rtl_obj* obj, return true; } +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 @@ -51,6 +51,16 @@ extern "C" { ** Imported NetBSD ELF Specifics End. **/ +/** + * 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 @@ -80,6 +90,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 @@ -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; } @@ -358,6 +455,40 @@ rtems_rtl_elf_relocate_rel (const rtems_rtl_obj* obj, return true; } +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, 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); @@ -556,6 +557,26 @@ 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->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) { @@ -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 +#include + +#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 @@ -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 . + * 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 + +#include "dl-load.h" + +#include + +#include +#include +#include + +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 . 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 + +#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 . + * 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 +#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 . + * 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 . 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 + +#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 . + * 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 . 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 +#include + +#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 . + * 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 . 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 + +#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 . + * 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 . 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 +#include + +#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 . + * 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 + +#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 +# +# 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 . 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 +#include +#include +#include + +#include +#include + +#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 -- cgit v1.2.3