2012-06-25 Gary Benson * elf/rtld.c: Include . (dl_main): Added static probes "rtld_init_start" and "rtld_init_complete". * elf/dl-load.c: Include . (lose): Take new parameter "nsid". Added static probe "rtld_map_complete". (_dl_map_object_from_fd): Pass namespace id to lose. Added static probe "rtld_map_start". (open_verify): Pass namespace id to lose. * elf/dl-open.c: Include . (dl_open_worker) Added static probes "rtld_map_complete", "rtld_reloc_start" and "rtld_reloc_complete". * elf/dl-close.c: Include . (_dl_close_worker): Added static probes "rtld_unmap_start" and "rtld_unmap_complete". diff --git a/elf/rtld.c b/elf/rtld.c index a5b0ab9..a99768f 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include @@ -1683,6 +1684,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 (); + LIBC_PROBE (rtld_init_start, 2, LM_ID_BASE, r); /* Auditing checkpoint: we are ready to signal that the initial map is being constructed. */ @@ -2400,6 +2402,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 (); + LIBC_PROBE (rtld_init_complete, 2, LM_ID_BASE, r); #ifndef MAP_COPY /* We must munmap() the cache file. */ diff --git a/elf/dl-load.c b/elf/dl-load.c index fe83f87..69ed3ea 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -35,6 +35,7 @@ #include #include #include +#include #include @@ -882,7 +883,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) @@ -896,6 +897,7 @@ lose (int code, int fd, const char *name, char *realname, struct link_map *l, { r->r_state = RT_CONSISTENT; _dl_debug_state (); + LIBC_PROBE (rtld_map_complete, 2, nsid, r); } _dl_signal_error (code, name, NULL, msg); @@ -934,7 +936,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. */ @@ -1041,6 +1043,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 (); + LIBC_PROBE (rtld_map_start, 2, nsid, r); make_consistent = true; } else @@ -1736,7 +1739,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. */ diff --git a/elf/dl-open.c b/elf/dl-open.c index 9fe0a7f..de73e26 100644 --- a/elf/dl-open.c +++ b/elf/dl-open.c @@ -32,6 +32,7 @@ #include #include #include +#include #include @@ -291,6 +292,7 @@ dl_open_worker (void *a) struct r_debug *r = _dl_debug_initialize (0, args->nsid); r->r_state = RT_CONSISTENT; _dl_debug_state (); + LIBC_PROBE (rtld_map_complete, 2, args->nsid, r); /* Print scope information. */ if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_SCOPES, 0)) @@ -376,10 +378,19 @@ dl_open_worker (void *a) } } + int relocation_in_progress = 0; + for (size_t i = nmaps; i-- > 0; ) { l = maps[i]; + if (! relocation_in_progress) + { + /* Notify the debugger that relocations are about to happen. */ + LIBC_PROBE (rtld_reloc_start, 2, args->nsid, r); + relocation_in_progress = 1; + } + #ifdef SHARED if (__builtin_expect (GLRO(dl_profile) != NULL, 0)) { @@ -544,6 +555,10 @@ cannot load any more object with static TLS")); } } + /* Notify the debugger all new objects have been relocated. */ + if (relocation_in_progress) + LIBC_PROBE (rtld_reloc_complete, 2, 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 d232294..1042905 100644 --- a/elf/dl-close.c +++ b/elf/dl-close.c @@ -31,6 +31,7 @@ #include #include #include +#include /* Type of the constructor functions. */ @@ -477,6 +478,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 (); + LIBC_PROBE (rtld_unmap_start, 2, nsid, r); if (unload_global) { @@ -746,6 +748,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 (); + LIBC_PROBE (rtld_unmap_complete, 2, nsid, r); /* Recheck if we need to retry, release the lock. */ out: