diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h index d040590..226904e 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -958,6 +958,11 @@ extern void _dl_sort_fini (struct link_map *l, struct link_map **maps, extern void _dl_debug_state (void); rtld_hidden_proto (_dl_debug_state) +/* The dynamic linker calls this function after having changed any + shared object mappings. */ +extern void _dl_debug_state_extended (Lmid_t ns, struct r_debug *r) + internal_function; + /* Initialize `struct r_debug' if it has not already been done. The argument is the run-time load address of the dynamic linker, to be put in the `r_ldbase' member. Returns the address of the structure. */ diff --git a/elf/dl-debug.c b/elf/dl-debug.c index 2538364..84cc163 100644 --- a/elf/dl-debug.c +++ b/elf/dl-debug.c @@ -76,3 +76,19 @@ _dl_debug_state (void) { } rtld_hidden_def (_dl_debug_state) + + +/* This function exists solely to contain SystemTap probes which the + debugger can set breakpoints on. */ +void +_dl_debug_state_extended (Lmid_t ns, struct r_debug *r) +{ + if (r->r_state == RT_CONSISTENT) + { + LIBC_PROBE (r_debug_mod_complete, 2, ns, r); + } + else + { + LIBC_PROBE (r_debug_mod_starting, 2, ns, r); + } +} diff --git a/elf/rtld.c b/elf/rtld.c index 174954b..004060b 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -1658,6 +1658,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n", /* We start adding objects. */ r->r_state = RT_ADD; _dl_debug_state (); + _dl_debug_state_extended (LM_ID_BASE, r); /* Auditing checkpoint: we are ready to signal that the initial map is being constructed. */ @@ -2361,6 +2362,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n", r = _dl_debug_initialize (0, LM_ID_BASE); r->r_state = RT_CONSISTENT; _dl_debug_state (); + _dl_debug_state_extended (LM_ID_BASE, r); #ifndef MAP_COPY /* We must munmap() the cache file. */ diff --git a/elf/dl-open.c b/elf/dl-open.c index cf8e8cc..b487203 100644 --- a/elf/dl-open.c +++ b/elf/dl-open.c @@ -293,7 +293,9 @@ dl_open_worker (void *a) } #endif - /* Notify the debugger all new objects are now ready to go. */ + /* Notify the debugger all new objects are now ready to go. + Note that the corresponding _dl_debug_state_extended call + to this happens further on, after relocation is complete. */ struct r_debug *r = _dl_debug_initialize (0, args->nsid); r->r_state = RT_CONSISTENT; _dl_debug_state (); @@ -460,6 +462,9 @@ cannot load any more object with static TLS")); _dl_fatal_printf (N_("\ TLS generation counter wrapped! Please report this.")); + /* Notify the debugger all new objects have been relocated. */ + _dl_debug_state_extended (args->nsid, r); + /* Run the initializer functions of new objects. */ _dl_init (new, args->argc, args->argv, args->env); diff --git a/elf/dl-close.c b/elf/dl-close.c index efb2b58..49a3d07 100644 --- a/elf/dl-close.c +++ b/elf/dl-close.c @@ -471,6 +471,7 @@ _dl_close_worker (struct link_map *map) struct r_debug *r = _dl_debug_initialize (0, nsid); r->r_state = RT_DELETE; _dl_debug_state (); + _dl_debug_state_extended (nsid, r); if (unload_global) { @@ -724,6 +725,7 @@ _dl_close_worker (struct link_map *map) /* Notify the debugger those objects are finalized and gone. */ r->r_state = RT_CONSISTENT; _dl_debug_state (); + _dl_debug_state_extended (nsid, r); /* Recheck if we need to retry, release the lock. */ out: diff --git a/elf/dl-load.c b/elf/dl-load.c index f866066..7588ddf 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -793,7 +793,7 @@ _dl_init_paths (const char *llp) static void __attribute__ ((noreturn, noinline)) lose (int code, int fd, const char *name, char *realname, struct link_map *l, - const char *msg, struct r_debug *r) + const char *msg, struct r_debug *r, Lmid_t nsid) { /* The file might already be closed. */ if (fd != -1) @@ -805,6 +805,7 @@ lose (int code, int fd, const char *name, char *realname, struct link_map *l, { r->r_state = RT_CONSISTENT; _dl_debug_state (); + _dl_debug_state_extended (nsid, r); } _dl_signal_error (code, name, NULL, msg); @@ -843,7 +844,7 @@ _dl_map_object_from_fd (const char *name, int fd, struct filebuf *fbp, errval = errno; call_lose: lose (errval, fd, name, realname, l, errstring, - make_consistent ? r : NULL); + make_consistent ? r : NULL, nsid); } /* Look again to see if the real name matched another already loaded. */ @@ -950,6 +951,7 @@ _dl_map_object_from_fd (const char *name, int fd, struct filebuf *fbp, linking has not been used before. */ r->r_state = RT_ADD; _dl_debug_state (); + _dl_debug_state_extended (nsid, r); make_consistent = true; } else @@ -1645,7 +1647,7 @@ open_verify (const char *name, struct filebuf *fbp, struct link_map *loader, name = strdupa (realname); free (realname); } - lose (errval, fd, name, NULL, NULL, errstring, NULL); + lose (errval, fd, name, NULL, NULL, errstring, NULL, 0); } /* See whether the ELF header is what we expect. */