2024-02-20 13:43:54 +00:00
|
|
|
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
|
2024-05-22 13:49:58 +00:00
|
|
|
index 7dfb6b680c108c0b..160451790bb88447 100644
|
2024-02-20 13:43:54 +00:00
|
|
|
--- a/elf/dl-open.c
|
|
|
|
+++ b/elf/dl-open.c
|
|
|
|
@@ -466,6 +466,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
|
|
|
|
@@ -638,7 +682,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
|
|
|
|
@@ -649,44 +693,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. */
|