[haiku-commits] haiku: hrev50589 - src/system/runtime_loader headers/private/runtime_loader

  • From: jerome.duval@xxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Tue, 11 Oct 2016 22:29:37 +0200 (CEST)

hrev50589 adds 1 changeset to branch 'master'
old head: 1df36f2ceee7b41a50386a9106a3614f3f075d34
new head: e340f717a422917491cebe4b693c6d30416ea0f0
overview: 
http://cgit.haiku-os.org/haiku/log/?qt=range&q=e340f717a422+%5E1df36f2ceee7

----------------------------------------------------------------------------

e340f717a422: runtime_loader: add support for ELF init/term routine arrays.
  
  * binutils 2.27 defaults to DT_INIT_ARRAY instead of DT_INIT.

                                   [ Jérôme Duval <jerome.duval@xxxxxxxxx> ]

----------------------------------------------------------------------------

Revision:    hrev50589
Commit:      e340f717a422917491cebe4b693c6d30416ea0f0
URL:         http://cgit.haiku-os.org/haiku/commit/?id=e340f717a422
Author:      Jérôme Duval <jerome.duval@xxxxxxxxx>
Date:        Tue Oct 11 20:26:06 2016 UTC

----------------------------------------------------------------------------

3 files changed, 57 insertions(+), 3 deletions(-)
headers/private/runtime_loader/runtime_loader.h |  6 +++++
src/system/runtime_loader/elf.cpp               | 24 +++++++++++++++++
src/system/runtime_loader/elf_load_image.cpp    | 30 ++++++++++++++++++---

----------------------------------------------------------------------------

diff --git a/headers/private/runtime_loader/runtime_loader.h 
b/headers/private/runtime_loader/runtime_loader.h
index 6a754f2..d93f676 100644
--- a/headers/private/runtime_loader/runtime_loader.h
+++ b/headers/private/runtime_loader/runtime_loader.h
@@ -115,6 +115,12 @@ typedef struct image_t {
        int                                     rela_len;
        elf_rel                         *pltrel;
        int                                     pltrel_len;
+       addr_t                          *init_array;
+       int                                     init_array_len;
+       addr_t                          *preinit_array;
+       int                                     preinit_array_len;
+       addr_t                          *term_array;
+       int                                     term_array_len;
 
        unsigned                        dso_tls_id;
 
diff --git a/src/system/runtime_loader/elf.cpp 
b/src/system/runtime_loader/elf.cpp
index 6d30bbb..03b8bd1 100644
--- a/src/system/runtime_loader/elf.cpp
+++ b/src/system/runtime_loader/elf.cpp
@@ -257,9 +257,21 @@ init_dependencies(image_t *image, bool initHead)
 
                TRACE(("%ld:  init: %s\n", find_thread(NULL), image->name));
 
+               if (image->preinit_array) {
+                       uint count_preinit = image->preinit_array_len / 
sizeof(addr_t);
+                       for (uint j = 0; j < count_preinit; j++)
+                               
((init_term_function)image->preinit_array[j])(image->id);
+               }
+
                if (image->init_routine != 0)
                        ((init_term_function)image->init_routine)(image->id);
 
+               if (image->init_array) {
+                       uint count_init = image->init_array_len / 
sizeof(addr_t);
+                       for (uint j = 0; j < count_init; j++)
+                               
((init_term_function)image->init_array[j])(image->id);
+               }
+
                image_event(image, IMAGE_EVENT_INITIALIZED);
        }
        TRACE(("%ld:  init done.\n", find_thread(NULL)));
@@ -633,6 +645,12 @@ unload_library(void* handle, image_id imageID, bool addOn)
 
                        image_event(image, IMAGE_EVENT_UNINITIALIZING);
 
+                       if (image->term_array) {
+                               uint count_term = image->term_array_len / 
sizeof(addr_t);
+                               for (uint i = count_term; i-- > 0;)
+                                       
((init_term_function)image->term_array[i])(image->id);
+                       }
+
                        if (image->term_routine)
                                
((init_term_function)image->term_routine)(image->id);
 
@@ -1017,6 +1035,12 @@ terminate_program(void)
 
                image_event(image, IMAGE_EVENT_UNINITIALIZING);
 
+               if (image->term_array) {
+                       uint count_term = image->term_array_len / 
sizeof(addr_t);
+                       for (uint j = count_term; j-- > 0;)
+                               
((init_term_function)image->term_array[j])(image->id);
+               }
+
                if (image->term_routine)
                        ((init_term_function)image->term_routine)(image->id);
 
diff --git a/src/system/runtime_loader/elf_load_image.cpp 
b/src/system/runtime_loader/elf_load_image.cpp
index 73ffad1..7181562 100644
--- a/src/system/runtime_loader/elf_load_image.cpp
+++ b/src/system/runtime_loader/elf_load_image.cpp
@@ -339,6 +339,33 @@ parse_dynamic_segment(image_t* image)
                                }
                                break;
                        }
+                       case DT_INIT_ARRAY:
+                               // array of pointers to initialization functions
+                               image->init_array = (addr_t*)
+                                       (d[i].d_un.d_ptr + 
image->regions[0].delta);
+                               break;
+                       case DT_INIT_ARRAYSZ:
+                               // size in bytes of the array of initialization 
functions
+                               image->init_array_len = d[i].d_un.d_val;
+                               break;
+                       case DT_PREINIT_ARRAY:
+                               // array of pointers to pre-initialization 
functions
+                               image->preinit_array = (addr_t*)
+                                       (d[i].d_un.d_ptr + 
image->regions[0].delta);
+                               break;
+                       case DT_PREINIT_ARRAYSZ:
+                               // size in bytes of the array of 
pre-initialization functions
+                               image->preinit_array_len = d[i].d_un.d_val;
+                               break;
+                       case DT_FINI_ARRAY:
+                               // array of pointers to termination functions
+                               image->term_array = (addr_t*)
+                                       (d[i].d_un.d_ptr + 
image->regions[0].delta);
+                               break;
+                       case DT_FINI_ARRAYSZ:
+                               // size in bytes of the array of termination 
functions
+                               image->term_array_len = d[i].d_un.d_val;
+                               break;
                        default:
                                continue;
 
@@ -348,9 +375,6 @@ parse_dynamic_segment(image_t* image)
                        // DT_SYMENT: The size of a symbol table entry.
                        // DT_PLTREL: The type of the PLT relocation entries 
(DT_JMPREL).
                        // DT_BIND_NOW/DF_BIND_NOW: No lazy binding allowed.
-                       // DT_INIT_ARRAY[SZ], DT_FINI_ARRAY[SZ]: 
Initialization/termination
-                       //              function arrays.
-                       // DT_PREINIT_ARRAY[SZ]: Preinitialization function 
array.
                        // DT_RUNPATH: Library search path (supersedes 
DT_RPATH).
                        // DT_TEXTREL/DF_TEXTREL: Indicates whether text 
relocations are
                        //              required (for optimization purposes 
only).


Other related posts:

  • » [haiku-commits] haiku: hrev50589 - src/system/runtime_loader headers/private/runtime_loader - jerome . duval