From: Chris Johns <chr...@rtems.org>

- Fix the handling of pending objects.
- Add a constructor flags in objects to track then being called.

Closes #2921
---
 cpukit/include/rtems/rtl/rtl-obj.h            |  1 +
 cpukit/libdl/rtl-elf.c                        | 21 +++++
 cpukit/libdl/rtl-mdreloc-arm.c                | 12 ++-
 cpukit/libdl/rtl-unresolved.c                 |  4 +-
 cpukit/libdl/rtl.c                            | 93 ++++++++++++-------
 .../cpu/arm/include/machine/elf_machdep.h     | 72 ++++++++++----
 testsuites/libtests/dl08/dl-load.c            |  2 +-
 7 files changed, 145 insertions(+), 60 deletions(-)

diff --git a/cpukit/include/rtems/rtl/rtl-obj.h 
b/cpukit/include/rtems/rtl/rtl-obj.h
index bc503887e2..b7522a7d39 100644
--- a/cpukit/include/rtems/rtl/rtl-obj.h
+++ b/cpukit/include/rtems/rtl/rtl-obj.h
@@ -168,6 +168,7 @@ typedef bool (*rtems_rtl_obj_depends_iterator) 
(rtems_rtl_obj* obj,
 #define RTEMS_RTL_OBJ_RELOC_TAG    (1 << 3) /**< Tag the object as visited 
when reloc
                                              *   parsing. */
 #define RTEMS_RTL_OBJ_DEP_VISITED  (1 << 4) /**< Dependency loop detection. */
+#define RTEMS_RTL_OBJ_CTOR_RUN     (1 << 5) /**< Constructors have been 
called. */
 
 /**
  * RTL Object. There is one for each object module loaded plus one for the base
diff --git a/cpukit/libdl/rtl-elf.c b/cpukit/libdl/rtl-elf.c
index caa37e6bab..63242acaae 100644
--- a/cpukit/libdl/rtl-elf.c
+++ b/cpukit/libdl/rtl-elf.c
@@ -993,6 +993,24 @@ rtems_rtl_elf_parse_sections (rtems_rtl_obj* obj, int fd, 
Elf_Ehdr* ehdr)
         flags = RTEMS_RTL_OBJ_SECT_STR;
         break;
 
+      case SHT_INIT_ARRAY:
+        /*
+         * Constructors are text and need to be loaded.
+         */
+        flags = (RTEMS_RTL_OBJ_SECT_CTOR |
+                 RTEMS_RTL_OBJ_SECT_TEXT |
+                 RTEMS_RTL_OBJ_SECT_LOAD);
+        break;
+
+      case SHT_FINI_ARRAY:
+        /*
+         * Destructors are text and need to be loaded.
+         */
+        flags = (RTEMS_RTL_OBJ_SECT_DTOR |
+                 RTEMS_RTL_OBJ_SECT_TEXT |
+                 RTEMS_RTL_OBJ_SECT_LOAD);
+        break;
+
       default:
         /*
          * See if there are architecture specific flags?
@@ -1019,6 +1037,9 @@ rtems_rtl_elf_parse_sections (rtems_rtl_obj* obj, int fd, 
Elf_Ehdr* ehdr)
       if ((shdr.sh_flags & SHF_LINK_ORDER) != 0)
         flags |= RTEMS_RTL_OBJ_SECT_LINK;
 
+      /*
+       * Some architexctures support a named PROGBIT section for INIT/FINI.
+       */
       len = RTEMS_RTL_ELF_STRING_MAX;
       if (!rtems_rtl_obj_cache_read (strings, fd,
                                      sectstroff + shdr.sh_name,
diff --git a/cpukit/libdl/rtl-mdreloc-arm.c b/cpukit/libdl/rtl-mdreloc-arm.c
index 96e14fc676..ef00701d32 100644
--- a/cpukit/libdl/rtl-mdreloc-arm.c
+++ b/cpukit/libdl/rtl-mdreloc-arm.c
@@ -7,6 +7,7 @@
 #include <sys/cdefs.h>
 
 #include <errno.h>
+#include <inttypes.h>
 #include <stdio.h>
 #include <string.h>
 #include <sys/types.h>
@@ -193,6 +194,7 @@ rtems_rtl_elf_relocate_rel (const rtems_rtl_obj*      obj,
     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;
@@ -249,8 +251,8 @@ rtems_rtl_elf_relocate_rel (const rtems_rtl_obj*      obj,
       break;
 
     case R_TYPE(THM_JUMP24):
-      /* same to THM_CALL; insn b.w */
-    case R_TYPE(THM_CALL):
+      /* same as THM_PC22; insn b.w */
+    case R_TYPE(THM_PC22):
       upper_insn = *(uint16_t *)where;
       lower_insn = *((uint16_t *)where + 1);
       sign = (upper_insn & (1 << 10)) >> 10;
@@ -322,7 +324,7 @@ rtems_rtl_elf_relocate_rel (const rtems_rtl_obj*      obj,
       tmp = tmp - (Elf_Addr)where;
 
       if (((Elf_Sword)tmp > 0x7ffffe) || ((Elf_Sword)tmp < -0x800000)) {
-        rtems_rtl_set_error (EINVAL, "%s: Overflow %ld "
+        rtems_rtl_set_error (EINVAL, "%s: Overflow %" PRIu32 " "
                              "THM_JUMP19 relocations",
                              sect->name, (uint32_t) ELF_R_TYPE(rel->r_info));
         return false;
@@ -342,12 +344,12 @@ rtems_rtl_elf_relocate_rel (const rtems_rtl_obj*      obj,
       break;
 
     default:
-      printf ("rtl: reloc unknown: sym = %lu, type = %lu, offset = %p, "
+      printf ("rtl: reloc unknown: sym = %" PRIu32 ", type = %" PRIu32 ", 
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 "
+                           "%s: Unsupported relocation type %" PRIu32 " "
                            "in non-PLT relocations",
                            sect->name, (uint32_t) ELF_R_TYPE(rel->r_info));
       return false;
diff --git a/cpukit/libdl/rtl-unresolved.c b/cpukit/libdl/rtl-unresolved.c
index 4e81c3c64e..7e2d920594 100644
--- a/cpukit/libdl/rtl-unresolved.c
+++ b/cpukit/libdl/rtl-unresolved.c
@@ -181,7 +181,8 @@ rtems_rtl_unresolved_resolve_reloc (rtems_rtl_unresolv_rec* 
rec,
     if (rec->rec.reloc.name == rd->name && rec->rec.reloc.obj != NULL)
     {
       if (rtems_rtl_trace (RTEMS_RTL_TRACE_UNRESOLVED))
-        printf ("rtl: unresolv: resolve reloc: %s\n", 
rd->name_rec->rec.name.name);
+        printf ("rtl: unresolv: resolve reloc: %s\n",
+                rd->name_rec->rec.name.name);
 
       rtems_rtl_obj_relocate_unresolved (&rec->rec.reloc, rd->sym);
 
@@ -193,6 +194,7 @@ rtems_rtl_unresolved_resolve_reloc (rtems_rtl_unresolv_rec* 
rec,
       if (rec->rec.reloc.obj->unresolved == 0)
       {
         pending = rtems_rtl_pending_unprotected ();
+        rtems_chain_extract (&rec->rec.reloc.obj->link);
         rtems_chain_append (pending, &rec->rec.reloc.obj->link);
       }
 
diff --git a/cpukit/libdl/rtl.c b/cpukit/libdl/rtl.c
index f331cbbf02..a3664c7e34 100644
--- a/cpukit/libdl/rtl.c
+++ b/cpukit/libdl/rtl.c
@@ -512,6 +512,8 @@ rtems_rtl_load_object (const char* name, int mode)
       return NULL;
     }
 
+    rtems_chain_append (&rtl->pending, &obj->link);
+
     /*
      * Find the file in the file system using the search path. The fname field
      * will point to a valid file name if found.
@@ -523,8 +525,6 @@ rtems_rtl_load_object (const char* name, int mode)
       return NULL;
     }
 
-    rtems_chain_append (&rtl->pending, &obj->link);
-
     if (!rtems_rtl_obj_load (obj))
     {
       rtems_chain_extract (&obj->link);
@@ -533,6 +533,16 @@ rtems_rtl_load_object (const char* name, int mode)
       return NULL;
     }
 
+    /*
+     * If there are unresolved externals remove from the pending queue and 
place
+     * on the objects list until the symbols are resolved.
+     */
+    if (obj->unresolved != 0)
+    {
+      rtems_chain_extract (&obj->link);
+      rtems_chain_append (&rtl->objects, &obj->link);
+    }
+
     rtems_rtl_obj_caches_flush ();
   }
 
@@ -572,34 +582,34 @@ rtems_rtl_load (const char* name, int mode)
     node = rtems_chain_first (&rtl->pending);
     while (!rtems_chain_is_tail (&rtl->pending, node))
     {
-      rtems_rtl_obj* obj = (rtems_rtl_obj*) node;
+      rtems_rtl_obj* pobj = (rtems_rtl_obj*) node;
 
       /*
        * Move to the next pending object file and place this object file on the
        * RTL's objects list.
        */
-      node = rtems_chain_next (&obj->link);
-      rtems_chain_extract (&obj->link);
-      rtems_chain_append (&rtl->objects, &obj->link);
+      node = rtems_chain_next (&pobj->link);
+      rtems_chain_extract (&pobj->link);
+      rtems_chain_append (&rtl->objects, &pobj->link);
 
       /*
        * Make sure the object file and cache is synchronized.
        */
-      rtems_rtl_obj_synchronize_cache (obj);
+      rtems_rtl_obj_synchronize_cache (pobj);
 
       /*
-       * Run any local constructors if this is the first user because the
-       * object file will have just been loaded. Unlock the linker to avoid any
-       * dead locks if the object file needs to load files or update the symbol
-       * table. We also do not want a constructor to unload this object file.
+       * Run any local constructors if they have not been run. Unlock the 
linker
+       * to avoid any dead locks if the object file needs to load files or
+       * update the symbol table. We also do not want a constructor to unload
+       * this object file.
        */
-      if (obj->users == 1)
+      if ((pobj->flags & RTEMS_RTL_OBJ_CTOR_RUN) == 0)
       {
-        obj->flags |= RTEMS_RTL_OBJ_LOCKED;
+        pobj->flags |= RTEMS_RTL_OBJ_LOCKED | RTEMS_RTL_OBJ_CTOR_RUN;
         rtems_rtl_unlock ();
-        rtems_rtl_obj_run_ctors (obj);
+        rtems_rtl_obj_run_ctors (pobj);
         rtems_rtl_lock ();
-        obj->flags &= ~RTEMS_RTL_OBJ_LOCKED;
+        pobj->flags &= ~RTEMS_RTL_OBJ_LOCKED;
       }
     }
   }
@@ -623,7 +633,7 @@ rtems_rtl_unload_object (rtems_rtl_obj* obj)
   }
 
   /*
-   * Move the object file from the objects list to the pending list if 
unloaded.
+   * The object file cannot be unloaded if it is referenced.
    */
   if (rtems_rtl_obj_get_reference (obj) > 0)
   {
@@ -649,30 +659,43 @@ rtems_rtl_unload (rtems_rtl_obj* obj)
   {
     rtems_chain_control unloading;
     rtems_chain_node*   node;
+    bool                orphaned_found = true;
+    int                 loop = 0;
 
     /*
-     * Remove the orphaned object files from the objects list. This makes the
-     * list private and any changes in any desctructors will effect the run.
+     * Remove the orphaned object files from the objects list. The unloading is
+     * private so any changes in any desctructors will not effect the list as 
it
+     * is being iterated over.
+     *
+     * To avoid maintaining a complex tree loop while oprhans are still be 
found.
      */
+
     rtems_chain_initialize_empty (&unloading);
 
-    node = rtems_chain_first (&rtl->objects);
-    while (!rtems_chain_is_tail (&rtl->objects, node))
+    while (orphaned_found)
     {
-      rtems_chain_node* next_node = rtems_chain_next (node);
-      rtems_rtl_obj* uobj = (rtems_rtl_obj*) node;
-      if (rtems_rtl_trace (RTEMS_RTL_TRACE_UNLOAD))
-        printf ("rtl: unload object: %s: %s\n",
-                rtems_rtl_obj_oname (obj),
-                rtems_rtl_obj_orphaned (uobj) ? "orphaned" : "inuse");
-      if (rtems_rtl_obj_orphaned (uobj))
+      orphaned_found = false;
+      ++loop;
+      node = rtems_chain_first (&rtl->objects);
+      while (!rtems_chain_is_tail (&rtl->objects, node))
       {
-        rtems_rtl_obj_remove_dependencies (uobj);
-        rtems_chain_extract (&uobj->link);
-        rtems_chain_append (&unloading, &uobj->link);
-        uobj->flags |= RTEMS_RTL_OBJ_LOCKED;
+        rtems_chain_node* next_node = rtems_chain_next (node);
+        rtems_rtl_obj* uobj = (rtems_rtl_obj*) node;
+        if (rtems_rtl_trace (RTEMS_RTL_TRACE_UNLOAD))
+          printf ("rtl: unload object: %3i: %9s: %s\n",
+                  loop,
+                  rtems_rtl_obj_orphaned (uobj) ? "orphaned" : "inuse",
+                  rtems_rtl_obj_oname (uobj));
+        if (rtems_rtl_obj_orphaned (uobj))
+        {
+          orphaned_found = true;
+          rtems_rtl_obj_remove_dependencies (uobj);
+          rtems_chain_extract (&uobj->link);
+          rtems_chain_append (&unloading, &uobj->link);
+          uobj->flags |= RTEMS_RTL_OBJ_LOCKED;
+        }
+        node = next_node;
       }
-      node = next_node;
     }
 
     /*
@@ -684,7 +707,11 @@ rtems_rtl_unload (rtems_rtl_obj* obj)
     while (!rtems_chain_is_tail (&unloading, node))
     {
       rtems_rtl_obj* uobj = (rtems_rtl_obj*) node;
-      rtems_rtl_obj_run_dtors (uobj);
+      if ((uobj->flags & RTEMS_RTL_OBJ_CTOR_RUN) != 0)
+      {
+        rtems_rtl_obj_run_dtors (uobj);
+        uobj->flags &= ~RTEMS_RTL_OBJ_CTOR_RUN;
+      }
       node = rtems_chain_next (node);
     }
 
diff --git a/cpukit/score/cpu/arm/include/machine/elf_machdep.h 
b/cpukit/score/cpu/arm/include/machine/elf_machdep.h
index 8f01d05212..6196879481 100644
--- a/cpukit/score/cpu/arm/include/machine/elf_machdep.h
+++ b/cpukit/score/cpu/arm/include/machine/elf_machdep.h
@@ -1,4 +1,7 @@
-/*     $NetBSD: elf_machdep.h,v 1.8 2009/05/30 05:56:52 skrll Exp $    */
+/*     $NetBSD: elf_machdep.h,v 1.19 2017/11/06 03:47:45 christos Exp $        
*/
+
+#ifndef _ARM_ELF_MACHDEP_H_
+#define _ARM_ELF_MACHDEP_H_
 
 #if defined(__ARMEB__)
 #define ELF32_MACHDEP_ENDIANNESS       ELFDATA2MSB
@@ -24,7 +27,13 @@
 #define EF_ARM_NEW_ABI         0x00000080
 #define EF_ARM_OLD_ABI         0x00000100
 #define EF_ARM_SOFT_FLOAT      0x00000200
+#define EF_ARM_BE8             0x00800000
 #define EF_ARM_EABIMASK                0xff000000
+#define        EF_ARM_EABI_VER1        0x01000000
+#define        EF_ARM_EABI_VER2        0x02000000
+#define        EF_ARM_EABI_VER3        0x03000000
+#define        EF_ARM_EABI_VER4        0x04000000
+#define        EF_ARM_EABI_VER5        0x05000000
 
 #define        ELF32_MACHDEP_ID_CASES                                          
\
                case EM_ARM:                                            \
@@ -32,6 +41,7 @@
 
 #define        ELF32_MACHDEP_ID        EM_ARM
 
+#define        KERN_ELFSIZE            32
 #define ARCH_ELFSIZE           32      /* MD native binary size */
 
 /* Processor specific relocation types */
@@ -46,7 +56,7 @@
 #define R_ARM_THM_ABS5         7
 #define R_ARM_ABS8             8
 #define R_ARM_SBREL32          9
-#define R_ARM_THM_CALL  10
+#define R_ARM_THM_PC22         10
 #define R_ARM_THM_PC8          11
 #define R_ARM_AMP_VCALL9       12
 #define R_ARM_SWI24            13
@@ -68,34 +78,36 @@
 #define R_ARM_GOTPC            25
 #define R_ARM_GOT32            26
 #define R_ARM_PLT32            27
-#define R_ARM_CALL        28
-#define R_ARM_JUMP24      29
+#define R_ARM_CALL             28
+#define R_ARM_JUMP24           29
 #define R_ARM_THM_JUMP24       30
-#define R_ARM_BASE_ABS         31
-
+#define R_ARM_BASE_ABS         31
 #define R_ARM_ALU_PCREL_7_0    32
 #define R_ARM_ALU_PCREL_15_8   33
 #define R_ARM_ALU_PCREL_23_15  34
 #define R_ARM_ALU_SBREL_11_0   35
 #define R_ARM_ALU_SBREL_19_12  36
-#define R_ARM_ALU_SBREL_27_20  37
-#define R_ARM_V4BX        40
-#define R_ARM_TARGET2     41
-#define R_ARM_PREL31      42
-
-#define R_ARM_MOVW_ABS_NC     43
-#define R_ARM_MOVT_ABS        44
-
-#define R_ARM_THM_MOVW_ABS_NC 47
-#define R_ARM_THM_MOVT_ABS    48
-
-#define R_ARM_THM_JUMP19      51
+#define R_ARM_ALU_SBREL_27_20  37      // depcreated
+#define R_ARM_TARGET1          38
+#define R_ARM_SBREL31          39      // deprecated
+#define R_ARM_V4BX             40
+#define R_ARM_TARGET2          41
+#define R_ARM_PREL31           42
+#define R_ARM_MOVW_ABS_NC      43
+#define R_ARM_MOVT_ABS         44
+#define R_ARM_MOVW_PREL_NC     45
+#define R_ARM_MOVT_PREL                46
+#define R_ARM_THM_MOVW_ABS_NC  47
+#define R_ARM_THM_MOVT_ABS     48
+#define R_ARM_THM_MOVW_PREL_NC 49
+#define R_ARM_THM_MOVT_PREL    50
+#define R_ARM_THM_JUMP19       51
 
 /* 96-111 are reserved to G++. */
 #define R_ARM_GNU_VTENTRY      100
 #define R_ARM_GNU_VTINHERIT    101
-#define R_ARM_THM_JUMP11               102
-#define R_ARM_THM_JUMP8                103
+#define R_ARM_THM_PC11         102
+#define R_ARM_THM_PC9          103
 
 /* More TLS relocations */
 #define R_ARM_TLS_GD32         104     /* PC-rel 32 bit for global dynamic */
@@ -109,6 +121,8 @@
 
 /* 112-127 are reserved for private experiments. */
 
+#define R_ARM_IRELATIVE                160
+
 #define R_ARM_RXPC25           249
 #define R_ARM_RSBREL32         250
 #define R_ARM_THM_RPC22                251
@@ -124,9 +138,27 @@
 #define PF_ARM_PI              0x20000000
 #define PF_ARM_ENTRY           0x80000000
 
+/* Processor specific program header types */
+#define PT_ARM_EXIDX           (PT_LOPROC + 1)
+
 /* Processor specific section header flags */
 #define SHF_ENTRYSECT          0x10000000
 #define SHF_COMDEF             0x80000000
 
 /* Processor specific symbol types */
 #define STT_ARM_TFUNC          STT_LOPROC
+
+#ifdef _KERNEL
+#ifdef ELFSIZE
+#define        ELF_MD_PROBE_FUNC       ELFNAME2(arm_netbsd,probe)
+#define        ELF_MD_COREDUMP_SETUP   ELFNAME2(arm_netbsd,coredump_setup)
+#endif
+
+struct exec_package;
+
+int arm_netbsd_elf32_probe(struct lwp *, struct exec_package *, void *, char *,
+       vaddr_t *);
+void arm_netbsd_elf32_coredump_setup(struct lwp *, void *);
+#endif
+
+#endif /* _ARM_ELF_MACHDEP_H_ */
diff --git a/testsuites/libtests/dl08/dl-load.c 
b/testsuites/libtests/dl08/dl-load.c
index 3fd3597b78..615a837b39 100644
--- a/testsuites/libtests/dl08/dl-load.c
+++ b/testsuites/libtests/dl08/dl-load.c
@@ -126,7 +126,7 @@ int dl_load_test(void)
 
   dl_load_dump ();
 
-  printf ("\n\n\nRunning rtems_main_o1:\n\n");
+  printf ("Running rtems_main_o1:\n");
   if (dl_call (o1, "rtems_main_o1"))
     return 1;
 
-- 
2.19.1

_______________________________________________
devel mailing list
devel@rtems.org
http://lists.rtems.org/mailman/listinfo/devel

Reply via email to