rtld: Add a postinit debugger hook
authorJohn Marino <draco@marino.st>
Sun, 30 Nov 2014 16:11:13 +0000 (17:11 +0100)
committerJohn Marino <draco@marino.st>
Sun, 30 Nov 2014 16:50:50 +0000 (17:50 +0100)
FreeBSD's dtrace(1) uses this hook to halt the "victim" process before its
entry point is called, at which point probes and DOF data are registered
with the kernel.  The r_debg_state hook cannot be used for this purpose,
as it is called before the program's init routines are invoked and in
particular before ODF is registered.  It may or may not be useful for
DragonFly by itself, but if dtrace every comes in, rtld will be ready.

Taken from: FreeBSD svn 265456 (6 May 2014)
FreeBSD svn 265578 (7 May 2014)

libexec/rtld-elf/Symbol.map
libexec/rtld-elf/rtld.c

index 7f4a67e..b2789d9 100644 (file)
@@ -14,6 +14,10 @@ DF306.0 {
     fdlopen;
 };
 
+DF402.0 {
+    r_debug_state;
+};
+
 DFprivate_1.0 {
     _rtld_allocate_tls;
     _rtld_free_tls;
@@ -21,4 +25,5 @@ DFprivate_1.0 {
     _rtld_thread_init;
     _rtld_addr_phdr;
     _rtld_get_stack_prot;
+    _r_debug_postinit;
 };
index e8e8f9d..4dc1486 100644 (file)
@@ -163,6 +163,7 @@ static bool matched_symbol(SymLook *, const Obj_Entry *, Sym_Match_Result *,
     const unsigned long);
 
 void r_debug_state(struct r_debug *, struct link_map *) __noinline;
+void _r_debug_postinit(struct link_map *) __noinline;
 
 /*
  * Data declarations.
@@ -725,6 +726,7 @@ _rtld_call_init(void)
        obj_main->init_array = obj_main->fini_array = (Elf_Addr)NULL;
     }
     objlist_call_init(&initlist, &lockstate);
+    _r_debug_postinit(&obj_main->linkmap);
     objlist_clear(&initlist);
     dbg("loading filtees");
     for (obj = obj_list->next; obj != NULL; obj = obj->next) {
@@ -3659,6 +3661,19 @@ r_debug_state(struct r_debug* rd, struct link_map *m)
     __asm __volatile("" : : : "memory");
 }
 
+/*
+ * A function called after init routines have completed. This can be used to
+ * break before a program's entry routine is called, and can be used when
+ * main is not available in the symbol table.
+ */
+void
+_r_debug_postinit(struct link_map *m)
+{
+
+       /* See r_debug_state(). */
+       __asm __volatile("" : : : "memory");
+}
+
 /*
  * Get address of the pointer variable in the main program.
  * Prefer non-weak symbol over the weak one.