You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
121 lines
3.8 KiB
121 lines
3.8 KiB
commit a74c2e1cbc8673dd7e97aae2f2705392e2ccc3f6 |
|
Author: Florian Weimer <fweimer@redhat.com> |
|
Date: Mon Nov 27 11:28:10 2023 +0100 |
|
|
|
elf: Introduce the _dl_open_relocate_one_object function |
|
|
|
It is extracted from dl_open_worker_begin. |
|
|
|
Reviewed-by: Carlos O'Donell <carlos@redhat.com> |
|
|
|
diff --git a/elf/dl-open.c b/elf/dl-open.c |
|
index c8a5d88161441031..cf3baccccb461878 100644 |
|
--- a/elf/dl-open.c |
|
+++ b/elf/dl-open.c |
|
@@ -467,6 +467,50 @@ activate_nodelete (struct link_map *new) |
|
} |
|
} |
|
|
|
+/* Relocate the object L. *RELOCATION_IN_PROGRESS controls whether |
|
+ the debugger is notified of the start of relocation processing. */ |
|
+static void |
|
+_dl_open_relocate_one_object (struct dl_open_args *args, struct r_debug *r, |
|
+ struct link_map *l, int reloc_mode, |
|
+ bool *relocation_in_progress) |
|
+{ |
|
+ if (l->l_real->l_relocated) |
|
+ return; |
|
+ |
|
+ if (!*relocation_in_progress) |
|
+ { |
|
+ /* Notify the debugger that relocations are about to happen. */ |
|
+ LIBC_PROBE (reloc_start, 2, args->nsid, r); |
|
+ *relocation_in_progress = true; |
|
+ } |
|
+ |
|
+#ifdef SHARED |
|
+ if (__glibc_unlikely (GLRO(dl_profile) != NULL)) |
|
+ { |
|
+ /* If this here is the shared object which we want to profile |
|
+ make sure the profile is started. We can find out whether |
|
+ this is necessary or not by observing the `_dl_profile_map' |
|
+ variable. If it was NULL but is not NULL afterwards we must |
|
+ start the profiling. */ |
|
+ struct link_map *old_profile_map = GL(dl_profile_map); |
|
+ |
|
+ _dl_relocate_object (l, l->l_scope, reloc_mode | RTLD_LAZY, 1); |
|
+ |
|
+ if (old_profile_map == NULL && GL(dl_profile_map) != NULL) |
|
+ { |
|
+ /* We must prepare the profiling. */ |
|
+ _dl_start_profile (); |
|
+ |
|
+ /* Prevent unloading the object. */ |
|
+ GL(dl_profile_map)->l_nodelete_active = true; |
|
+ } |
|
+ } |
|
+ else |
|
+#endif |
|
+ _dl_relocate_object (l, l->l_scope, reloc_mode, 0); |
|
+} |
|
+ |
|
+ |
|
/* struct dl_init_args and call_dl_init are used to call _dl_init with |
|
exception handling disabled. */ |
|
struct dl_init_args |
|
@@ -651,7 +695,7 @@ dl_open_worker_begin (void *a) |
|
} |
|
while (l != NULL); |
|
|
|
- int relocation_in_progress = 0; |
|
+ bool relocation_in_progress = false; |
|
|
|
/* Perform relocation. This can trigger lazy binding in IFUNC |
|
resolvers. For NODELETE mappings, these dependencies are not |
|
@@ -662,44 +706,8 @@ dl_open_worker_begin (void *a) |
|
are undefined anyway, so this is not a problem. */ |
|
|
|
for (unsigned int i = last; i-- > first; ) |
|
- { |
|
- l = new->l_initfini[i]; |
|
- |
|
- if (l->l_real->l_relocated) |
|
- continue; |
|
- |
|
- if (! relocation_in_progress) |
|
- { |
|
- /* Notify the debugger that relocations are about to happen. */ |
|
- LIBC_PROBE (reloc_start, 2, args->nsid, r); |
|
- relocation_in_progress = 1; |
|
- } |
|
- |
|
-#ifdef SHARED |
|
- if (__glibc_unlikely (GLRO(dl_profile) != NULL)) |
|
- { |
|
- /* If this here is the shared object which we want to profile |
|
- make sure the profile is started. We can find out whether |
|
- this is necessary or not by observing the `_dl_profile_map' |
|
- variable. If it was NULL but is not NULL afterwards we must |
|
- start the profiling. */ |
|
- struct link_map *old_profile_map = GL(dl_profile_map); |
|
- |
|
- _dl_relocate_object (l, l->l_scope, reloc_mode | RTLD_LAZY, 1); |
|
- |
|
- if (old_profile_map == NULL && GL(dl_profile_map) != NULL) |
|
- { |
|
- /* We must prepare the profiling. */ |
|
- _dl_start_profile (); |
|
- |
|
- /* Prevent unloading the object. */ |
|
- GL(dl_profile_map)->l_nodelete_active = true; |
|
- } |
|
- } |
|
- else |
|
-#endif |
|
- _dl_relocate_object (l, l->l_scope, reloc_mode, 0); |
|
- } |
|
+ _dl_open_relocate_one_object (args, r, new->l_initfini[i], reloc_mode, |
|
+ &relocation_in_progress); |
|
|
|
/* This only performs the memory allocations. The actual update of |
|
the scopes happens below, after failure is impossible. */
|
|
|