List Info

Thread: GDB solib interface




GDB solib interface
user name
2006-12-04 22:12:27
I'm sorry - way back when Kevin asked that I investigate
this.  So now I
am.  

Anyway - Pretend that my "custom" GDB remote.c has
been told that a
library has been loaded - what would I need to write to use
the solib
interface?   Another way of asking the question would be, 
what would I
need to add to my remote interface file (remote.c) to have
it load the
symbols.

I am not looking for a command, per se,  just trying to
figure out what
functions/structures etc I need to write to have my
"custom" GDB load
the libraries symbols.

-----Original Message-----
From: Daniel Jacobowitz [mailto:drowfalse.org] 
Sent: Monday, December 04, 2006 2:58 PM
To: Smith, Stephen (SWCOE)
Cc: General GDB Mailing List
Subject: Re: GDB solib interface

On Mon, Dec 04, 2006 at 02:55:28PM -0700, Smith, Stephen
(SWCOE) wrote:
> I am running GDB to debug a remote application.  If I
find that a
shared
> library has been loaded, I would like to use the solib
interface to
load
> the appropriate shared library symbols.  
> 
> So lets assume that I have the file name of the shared
library, that
was
> just loaded, how do I inform the solib subsystem that
to load the
> symbols.

There's no command for this.  The solib system is designed
for targets
where the target can report that the library was loaded, or
where GDB
can otherwise detect it.  If you're willing to have a custom
GDB for
your platform, you might be able to make it examine the
shared library
table in your target, assuming there is one.

-- 
Daniel Jacobowitz
CodeSourcery
GDB solib interface
user name
2006-12-04 22:25:02
On Mon, 2006-12-04 at 15:12 -0700, Smith, Stephen (SWCOE)
wrote:
> I'm sorry - way back when Kevin asked that I
investigate this.  So now I
> am.  
> 
> Anyway - Pretend that my "custom" GDB
remote.c has been told that a
> library has been loaded - what would I need to write to
use the solib
> interface?   Another way of asking the question would
be,  what would I
> need to add to my remote interface file (remote.c) to
have it load the
> symbols.

Presumably something like solib_add() or add_symbol_file().

Your back-end (eg. remote target) should give you the name
of a shared library (with or without path), and then gdb 
has built-in schemes for finding it.

If your target libraries are different from your host
libraries
(which they usually are), you will need to tell GDB where to

find them (on the host file system), using the commands
    set solib-search-path 
and
    set solib-absolute-prefix

Daniel, I would have assumed that this stuff was 
working with linux-x-linux and gdbserver?


> 
> I am not looking for a command, per se,  just trying to
figure out what
> functions/structures etc I need to write to have my
"custom" GDB load
> the libraries symbols.
> 
> -----Original Message-----
> From: Daniel Jacobowitz [mailto:drowfalse.org] 
> Sent: Monday, December 04, 2006 2:58 PM
> To: Smith, Stephen (SWCOE)
> Cc: General GDB Mailing List
> Subject: Re: GDB solib interface
> 
> On Mon, Dec 04, 2006 at 02:55:28PM -0700, Smith,
Stephen (SWCOE) wrote:
> > I am running GDB to debug a remote application. 
If I find that a
> shared
> > library has been loaded, I would like to use the
solib interface to
> load
> > the appropriate shared library symbols.  
> > 
> > So lets assume that I have the file name of the
shared library, that
> was
> > just loaded, how do I inform the solib subsystem
that to load the
> > symbols.
> 
> There's no command for this.  The solib system is
designed for targets
> where the target can report that the library was
loaded, or where GDB
> can otherwise detect it.  If you're willing to have a
custom GDB for
> your platform, you might be able to make it examine the
shared library
> table in your target, assuming there is one.
> 
GDB solib interface
user name
2006-12-04 22:28:47
On Mon, Dec 04, 2006 at 03:12:27PM -0700, Smith, Stephen
(SWCOE) wrote:
> 
> I'm sorry - way back when Kevin asked that I
investigate this.  So now I
> am.  
> 
> Anyway - Pretend that my "custom" GDB
remote.c has been told that a
> library has been loaded - what would I need to write to
use the solib
> interface?   Another way of asking the question would
be,  what would I
> need to add to my remote interface file (remote.c) to
have it load the
> symbols.
> 
> I am not looking for a command, per se,  just trying to
figure out what
> functions/structures etc I need to write to have my
"custom" GDB load
> the libraries symbols.

Aha.  OK, that's different.

I wrote some code for this purpose, a few months ago, which
I meant to
submit.  That was for DLL targets.  I haven't had time yet. 
I'm afraid
it's not real easy to untangle from the rest of that project
now :-(
If that's what you need, I can try to do it tomorrow.

-- 
Daniel Jacobowitz
CodeSourcery
GDB solib interface
user name
2006-12-04 22:29:22
On Mon, Dec 04, 2006 at 02:25:02PM -0800, Michael Snyder
wrote:
> Daniel, I would have assumed that this stuff was 
> working with linux-x-linux and gdbserver?

No, solib-svr4 doesn't need any of this because it's just
grubbing
around in target memory.

-- 
Daniel Jacobowitz
CodeSourcery
GDB solib interface
user name
2006-12-04 22:48:32
Well in my case the target is elf not pe.  But otherwise it
should be
similar.  


-----Original Message-----
From: Daniel Jacobowitz [mailto:drowfalse.org] 
Sent: Monday, December 04, 2006 3:29 PM
To: Smith, Stephen (SWCOE)
Cc: General GDB Mailing List
Subject: Re: GDB solib interface

On Mon, Dec 04, 2006 Daniel Jacobowitz wrote:

Aha.  OK, that's different.

I wrote some code for this purpose, a few months ago, which
I meant to
submit.  That was for DLL targets.  I haven't had time yet. 
I'm afraid
it's not real easy to untangle from the rest of that project
now :-(
If that's what you need, I can try to do it tomorrow.

-- 
Daniel Jacobowitz
CodeSourcery
GDB solib interface
user name
2006-12-04 23:47:58
On Mon, 2006-12-04 at 15:48 -0700, Smith, Stephen (SWCOE)
wrote:
> Well in my case the target is elf not pe.  But
otherwise it should be
> similar.  

Is your target by any chance svr4 compatible?


GDB solib interface
user name
2006-12-05 02:09:45
No, the OS is not SVR4 compatible.

sps

-----Original Message-----
From: Michael Snyder [mailto:Michael.Snyderpalmsource.com] 
Sent: Monday, December 04, 2006 4:48 PM
To: Smith, Stephen (SWCOE)
Cc: Daniel Jacobowitz; General GDB Mailing List
Subject: RE: GDB solib interface

On Mon, 2006-12-04 at 15:48 -0700, Smith, Stephen (SWCOE)
wrote:
> Well in my case the target is elf not pe.  But
otherwise it should be
> similar.  

Is your target by any chance svr4 compatible?

GDB solib interface
user name
2006-12-05 23:03:17
Could you try and get it.  I would like to see how to do it.

On Mon, Dec 04, 2006 Daniel Jacobowitz wrote

I wrote some code for this purpose, a few months ago, which
I meant to
submit.  That was for DLL targets.  I haven't had time yet. 
I'm afraid
it's not real easy to untangle from the rest of that project
now :-(
If that's what you need, I can try to do it tomorrow.

GDB solib interface
user name
2006-12-08 21:19:22
On Mon, Dec 04, 2006 at 05:28:47PM -0500, Daniel Jacobowitz
wrote:
> On Mon, Dec 04, 2006 at 03:12:27PM -0700, Smith,
Stephen (SWCOE) wrote:
> > 
> > I'm sorry - way back when Kevin asked that I
investigate this.  So now I
> > am.  
> > 
> > Anyway - Pretend that my "custom" GDB
remote.c has been told that a
> > library has been loaded - what would I need to
write to use the solib
> > interface?   Another way of asking the question
would be,  what would I
> > need to add to my remote interface file (remote.c)
to have it load the
> > symbols.
> > 
> > I am not looking for a command, per se,  just
trying to figure out what
> > functions/structures etc I need to write to have
my "custom" GDB load
> > the libraries symbols.
> 
> Aha.  OK, that's different.
> 
> I wrote some code for this purpose, a few months ago,
which I meant to
> submit.  That was for DLL targets.  I haven't had time
yet.  I'm afraid
> it's not real easy to untangle from the rest of that
project now :-(

Here you go.  I haven't tested this patch on its own at all,
so if it
breaks, you get to keep both pieces.  Add solib-target.o to
TDEPFILES
for your target to enable it.

It works by two mechanisms.  You can send
"qfDllInfo" to get the entire
list from a remote target, and the remote target can report
load /
unload events as special 'T' stop packets.  It should be
fairly
apparent from the code.

Some draft docs I wrote at the time:

`qfDllInfo'
`qsDllInfo'

  Obtain a list of currently loaded DLLs from the target. 
Like
  `qfThreadInfo', this request works iteratively.  The
`qfDllInfo'
  packet is issued first to start at the beginning of the
DLL list,
  and the `qsDllInfo' packet is used to fetch additional
entries.

  Reply:
  `m' Name=HEXSTR,TextSeg=ADDR,DataSeg=ADDR

    Returns the name (as a hexadecimal-encoded sequence of
ASCII
    characters), text load address, and data load address
for this DLL.
    Other Name=Value pairs may be added in the future for
particular
    targets.

  `m'
Name=HEXSTR,TextSeg=ADDR,DataSeg=ADDR;Name=HEXSTR,TextSeg=AD
DR,DataSeg=ADDR...

    Multiple DLL entries may be included in the same packet;
a semicolon
    marks the start of a new DLL description.  A single DLL
    will never be split across multiple packets.

  `l'

    Marks the end of a list of DLLs.

[Editorial note: maybe use `ml' instead?  Then we can use
`mName=FOO,TextSeg=ADDR,DataSeg=ADDR;l' and save a round
trip.  This is not quite
parallel to qfThreadInfo but that should be ok.]

[Editorial note: No support is provided for DLLs with
extremely long names
that do not fit in a packet.  A solution for this can be
added at a later
date if necessary.]

If any stopped threads had DLL events not yet reported to
GDB, either the
effects of those events should not be included in the result
of the query,
or the queued DLL events should be discarded before they are
reported to
GDB.

[Editorial note: You wrote that every dlopen triggers an
event even if the
DLL was already loaded.  Should the stub drop the event in
that case?
Should it report it anyway and have duplicates handled on
the GDB side?
That would let the long-lost "catch load
<libname>" command work again.
If so, then the above paragraph must be deleted and some
words about how
GDB should ignore apparent duplicates added.]

Reporting DLL events
--------------------

The `T' stop packet response is extended to take three
additional
N:R pairs.  When any of these are encountered, the stopped
thread
is assumed to be at a DLL event.  The signal should be
SIGTRAP.
There may be multiple load and unload events in the stop
packet.

  `load:Name=HEXSTR,TextSeg=ADDR,DataSeg=ADDR[,nop]'

    A new DLL has been loaded; it is described in the stop
packet.

    If "nop" is specified, this DLL was already
loaded, e.g. by
    an earlier call to dlopen.

  `unload:IDENTIFIER=VALUE[,nop]'

    A DLL has been unloaded.  A single identifier is
provided to
    uniquely identify which DLL has been unloaded. 
Depending
    on the target, this may be the text or data address; the
name
    can be used, but may not be unambiguous.

    If "nop" is specified, this DLL was not
unloaded, e.g. because
    another thread still had a handle to it.

  `dll:dll'

    Multiple DLL events have occured.  GDB should query the
target for the
    current state of DLLs.

-- 
Daniel Jacobowitz
CodeSourcery

Index: Makefile.in
============================================================
=======
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.856
diff -u -p -r1.856 Makefile.in
--- Makefile.in	28 Nov 2006 22:14:31 -0000	1.856
+++ Makefile.in	8 Dec 2006 21:09:03 -0000
 -2516,7
+2516,8  remote.o: remote.c $(defs_h) $(gdb_strin
 	$(gdb_stabs_h) $(gdbthread_h) $(remote_h) $(regcache_h)
$(value_h) 
 	$(gdb_assert_h) $(event_loop_h) $(event_top_h)
$(inf_loop_h) 
 	$(serial_h) $(gdbcore_h) $(remote_fileio_h) $(solib_h)
$(observer_h) 
-	$(cli_decode_h) $(cli_setshow_h) $(memory_map_h)
$(target_descriptions_h)
+	$(cli_decode_h) $(cli_setshow_h) $(memory_map_h)
$(target_descriptions_h) 
+	$(solist_h)
 remote-e7000.o: remote-e7000.c $(defs_h) $(gdbcore_h)
$(gdbarch_h) 
 	$(inferior_h) $(target_h) $(value_h) $(command_h)
$(gdb_string_h) 
 	$(exceptions_h) $(gdbcmd_h) $(serial_h) $(remote_utils_h)

 -2650,6
+2651,8  solib-svr4.o: solib-svr4.c $(defs_h) $(e
 	$(gdbcore_h) $(target_h) $(inferior_h) $(gdb_assert_h) 
 	$(solist_h) $(solib_h) $(solib_svr4_h) $(bfd_target_h)
$(elf_bfd_h) 
 	$(exec_h)
+solib-target.o: solib-target.c $(defs_h) $(solist_h)
$(symtab_h) $(symfile_h) 
+	$(target_h) $(gdb_string_h)
 sol-thread.o: sol-thread.c $(defs_h) $(gdbthread_h)
$(target_h) 
 	$(inferior_h) $(gdb_stat_h) $(gdbcmd_h) $(gdbcore_h)
$(regcache_h) 
 	$(solib_h) $(symfile_h) $(gdb_string_h) $(gregset_h)
Index: infrun.c
============================================================
=======
RCS file: /cvs/src/src/gdb/infrun.c,v
retrieving revision 1.216
diff -u -p -r1.216 infrun.c
--- infrun.c	18 Oct 2006 16:56:13 -0000	1.216
+++ infrun.c	8 Dec 2006 21:09:04 -0000
 -884,6
+884,8  init_wait_for_inferior (void)
   clear_proceed_status ();
 
   stepping_past_singlestep_breakpoint = 0;
+
+  target_last_wait_ptid = minus_one_ptid;
 }
 
 /* This enum encodes possible reasons for doing a
target_wait, so that
 -1262,6
+1264,9  handle_inferior_event (struct execution_
   target_last_wait_ptid = ecs->ptid;
   target_last_waitstatus = *ecs->wp;
 
+  /* Always clear state belonging to the previous time we
stopped.  */
+  stop_stack_dummy = 0;
+
   adjust_pc_after_break (ecs);
 
   switch (ecs->infwait_state)
 -1322,13
+1327,16  handle_inferior_event (struct execution_
       /* Ignore gracefully during startup of the inferior,
as it
          might be the shell which has just loaded some
objects,
          otherwise add the symbols for the newly loaded
objects.  */
-#ifdef SOLIB_ADD
       if (stop_soon == NO_STOP_QUIETLY)
 	{
+	  int breakpoints_were_inserted;
+
 	  /* Remove breakpoints, SOLIB_ADD might adjust
 	     breakpoint addresses via breakpoint_re_set.  */
+	  breakpoints_were_inserted = breakpoints_inserted;
 	  if (breakpoints_inserted)
 	    remove_breakpoints ();
+	  breakpoints_inserted = 0;
 
 	  /* Check for any newly added shared libraries if we're
 	     supposed to be adding them automatically.  Switch
 -1350,17
+1358,52  handle_inferior_event (struct execution_
 	     exec/process stratum, instead relying on the target
stack
 	     to propagate relevant changes (stop, section table
 	     changed, ...) up to other layers.  */
+#ifdef SOLIB_ADD
 	  SOLIB_ADD (NULL, 0, &current_target,
auto_solib_add);
+#else
+	  solib_add (NULL, 0, &current_target,
auto_solib_add);
+#endif
 	  target_terminal_inferior ();
 
+	  /* Try to reenable shared library breakpoints,
additional
+	     code segments in shared libraries might be mapped in
now. */
+	  re_enable_breakpoints_in_shlibs ();
+
+	  /* If requested, stop when the dynamic linker notifies
+	     gdb of events.  This allows the user to get control
+	     and place breakpoints in initializer routines for
+	     dynamically loaded objects (among other things).  */
+	  if (stop_on_solib_events)
+	    {
+	      stop_stepping (ecs);
+	      return;
+	    }
+
+	  /* NOTE drow/2006-03-14: This might be a good place to
check
+	     for "catch load".  */
+
 	  /* Reinsert breakpoints and continue.  */
-	  if (breakpoints_inserted)
-	    insert_breakpoints ();
+	  if (breakpoints_were_inserted)
+	    {
+	      insert_breakpoints ();
+	      breakpoints_inserted = 1;
+	    }
 	}
-#endif
-      resume (0, TARGET_SIGNAL_0);
-      prepare_to_wait (ecs);
-      return;
+
+      /* NOTE drow/2006-03-28: For the reason described
before the
+	 previous if statement, GDB used to automatically resume
+	 here.  But that's only true if a shell is running; if
+	 we've just attached to a process, then that's a whole
+	 different case - it might have been stopped at a load
+	 event.  */
+      if (inferior_ignoring_startup_exec_events ||
stop_soon == NO_STOP_QUIETLY)
+	{
+	  resume (0, TARGET_SIGNAL_0);
+	  prepare_to_wait (ecs);
+	  return;
+	}
+      else
+	break;
 
     case TARGET_WAITKIND_SPURIOUS:
       if (debug_infrun)
 -1779,7
+1822,6  handle_inferior_event (struct execution_
   ecs->another_trap = 0;
   bpstat_clear (&stop_bpstat);
   stop_step = 0;
-  stop_stack_dummy = 0;
   stop_print_frame = 1;
   ecs->random_signal = 0;
   stopped_by_random_signal = 0;
Index: remote.c
============================================================
=======
RCS file: /cvs/src/src/gdb/remote.c,v
retrieving revision 1.241
diff -u -p -r1.241 remote.c
--- remote.c	28 Nov 2006 22:14:31 -0000	1.241
+++ remote.c	8 Dec 2006 21:09:04 -0000
 -43,6
+43,7 
 #include "gdb_assert.h"
 #include "observer.h"
 #include "solib.h"
+#include "solist.h"
 #include "cli/cli-decode.h"
 #include "cli/cli-setshow.h"
 #include "target-descriptions.h"
 -897,6
+898,7  enum {
   PACKET_qGetTLSAddr,
   PACKET_qSupported,
   PACKET_QPassSignals,
+  PACKET_qfDllInfo,
   PACKET_MAX
 };
 
 -2076,6
+2078,152  get_offsets (void)
   objfile_relocate (symfile_objfile, offs);
 }
 
+/* Parse a load or unload message for a DLL.  Loads are
required to
+   have all fields, unloads must have at least one.  P is
not
+   necessarily NUL terminated, but it is always either NUL
or semicolon
+   terminated (i.e. *P_END is either NUL or a semicolon)
and the containing
+   string is NUL terminated.  */
+
+int
+parse_load_response (const char *p, const char *p_end, int
is_load)
+{
+  const char *name_start;
+  char *name;
+  CORE_ADDR text_addr, data_addr;
+  int i;
+
+  name = NULL;
+  text_addr = ~(CORE_ADDR) 0;
+  data_addr = ~(CORE_ADDR) 0;
+
+  if (p < p_end && strncmp (p,
"Name=", 5) == 0)
+    {
+      p += 5;
+
+      name_start = p;
+      while (p < p_end && *p != ',')
+	p++;
+
+      if ((p - name_start) % 2 != 0)
+	return -1;
+
+      name = alloca ((p - name_start) / 2 + 1);
+      i = hex2bin (name_start, name, (p - name_start) / 2);
+      name[i] = '';
+
+      if (p < p_end)
+	p++;
+    }
+  else if (is_load)
+    return -1;
+
+  if (p < p_end && strncmp (p,
"TextSeg=", 8) == 0)
+    {
+      p += 8;
+
+      text_addr = 0;
+      while (p < p_end && *p != ',')
+	text_addr = (text_addr << 4) + fromhex (*p++);
+
+      if (p < p_end)
+	p++;
+    }
+  else if (is_load)
+    return -1;
+
+  if (p < p_end && strncmp (p,
"DataSeg=", 8) == 0)
+    {
+      p += 8;
+
+      data_addr = 0;
+      while (p < p_end && *p != ',')
+	data_addr = (data_addr << 4) + fromhex (*p++);
+
+      if (p < p_end)
+	p++;
+    }
+  else if (is_load)
+    return -1;
+
+  if (is_load)
+    current_target_so_ops->add_one_solib (name,
text_addr, data_addr);
+  else
+    {
+      if (text_addr == ~(CORE_ADDR) 0
+	  && data_addr == ~(CORE_ADDR) 0
+	  && name == NULL)
+	return -1;
+
+      current_target_so_ops->remove_one_solib (name,
text_addr, data_addr);
+    }
+
+  return 0;
+}
+
+/* Query the remote side for loaded solibs.  */
+
+static void
+remote_get_shared_libraries (struct target_ops *ops)
+{
+  struct remote_state *rs = get_remote_state ();
+
+  /* If this target doesn't support remote DLLs, nothing to
do.  */
+  if (current_target_so_ops->add_one_solib == NULL)
+    return;
+
+  /* If qfDllInfo is not available, nothing to do.  */
+  if (remote_protocol_packets[PACKET_qfDllInfo].support ==
PACKET_DISABLE)
+    return;
+
+  putpkt ("qfDllInfo");
+  getpkt (&rs->buf, &rs->buf_size, 0);
+
+  if (packet_ok (rs->buf,
&remote_protocol_packets[PACKET_qfDllInfo]) ==
PACKET_ERROR)
+    {
+      warning (_("Remote failure reply: %s"),
rs->buf);
+      return;
+    }
+  else if
(remote_protocol_packets[PACKET_qfDllInfo].support ==
PACKET_DISABLE)
+    /* It wasn't disabled before, but it is now.  */
+    return;
+
+  while (rs->buf[0] == 'm')
+    {
+      char *p = rs->buf + 1;
+
+      while (1)
+	{
+	  char *p_end = p;
+
+	  while (*p_end && *p_end != ';')
+	    p_end++;
+
+	  if (parse_load_response (p, p_end, 1) != 0)
+	    {
+	      warning (_("Malformed response to DLL query,
%s"), rs->buf);
+	      return;
+	    }
+
+	  if (*p_end == ';')
+	    p = p_end + 1;
+	  else
+	    break;
+	}
+
+      putpkt ("qsDllInfo");
+      getpkt (&rs->buf, &rs->buf_size, 0);
+    }
+
+  if (strcmp (rs->buf, "l") != 0)
+    {
+      warning (_("Malformed response to DLL query,
%s"), rs->buf);
+      return;
+    }
+
+  /* We don't need to call solib_add here, because we're
being called from
+     ->current_sos ().  */
+}
+
 /* Stub for catch_exception.  */
 
 static void
 -3093,6
+3241,7  remote_wait (ptid_t ptid, struct target_
   struct remote_arch_state *rsa = get_remote_arch_state ();
   ULONGEST thread_num = -1;
   ULONGEST addr;
+  int solibs_changed = 0;
 
   status->kind = TARGET_WAITKIND_EXITED;
   status->value.integer = 0;
 -3178,6
+3327,60  Packet: '%s'n"),
 			p = unpack_varlen_hex (++p1, &addr);
 			remote_watch_data_address = (CORE_ADDR)addr;
 		      }
+		    else if (strncmp (p, "load", p1 - p) == 0)
+		      {
+			p1++;
+			p_temp = p1;
+			while (*p_temp && *p_temp != ';')
+			  p_temp++;
+
+			if (p_temp - p1 > 4
+			    && strncmp (p_temp - 4, ",nop", 4)
== 0)
+			  {
+			    /* For now, ignore no-op unload events.  Later,
+			       maybe report them?  */
+			  }
+			else
+			  {
+			    parse_load_response (p1, p_temp, 1);
+
+			    solibs_changed = 1;
+			  }
+
+			p = p_temp;
+		      }
+		    else if (strncmp (p, "unload", p1 - p) ==
0)
+		      {
+			p1++;
+			p_temp = p1;
+			while (*p_temp && *p_temp != ';')
+			  p_temp++;
+
+			if (p_temp - p1 > 4
+			    && strncmp (p_temp - 4, ",nop", 4)
== 0)
+			  {
+			    /* For now, ignore no-op unload events.  Later,
+			       maybe report them?  */
+			  }
+			else
+			  {
+			    parse_load_response (p1, p_temp, 0);
+
+			    solibs_changed = 1;
+			  }
+
+			p = p_temp;
+		      }
+		    else if (strncmp (p, "dll", p1 - p) == 0)
+		      {
+			p1++;
+			p_temp = p1;
+			while (*p_temp && *p_temp != ';')
+			  p_temp++;
+
+			solibs_changed = -1;
+			p = p_temp;
+		      }
 		    else
  		      {
  			/* Silently skip unknown optional info.  */
 -3269,6
+3472,12  Packet: '%s'n"),
 	}
     }
 got_status:
+  if (solibs_changed == -1)
+    remote_get_shared_libraries (NULL);
+  
+  if (solibs_changed != 0)
+    status->kind = TARGET_WAITKIND_LOADED;
+
   if (thread_num != -1)
     {
       return pid_to_ptid (thread_num);
 -6203,6
+6412,7  Specify the serial device it is connecte
   remote_ops.to_flash_erase = remote_flash_erase;
   remote_ops.to_flash_done = remote_flash_done;
   remote_ops.to_read_description = remote_read_description;
+  remote_ops.to_get_shared_libraries =
remote_get_shared_libraries;
 }
 
 /* Set up the extended remote vector by making a copy of
the standard
 -6335,7
+6545,8  Specify the serial device it is connecte
   remote_async_ops.to_memory_map = remote_memory_map;
   remote_async_ops.to_flash_erase = remote_flash_erase;
   remote_async_ops.to_flash_done = remote_flash_done;
-  remote_ops.to_read_description = remote_read_description;
+  remote_async_ops.to_read_description =
remote_read_description;
+  remote_async_ops.to_get_shared_libraries =
remote_get_shared_libraries;
 }
 
 /* Set up the async extended remote vector by making a copy
of the standard
 -6601,6
+6812,9  Show the maximum size of the address (in
   add_packet_config_cmd
(&remote_protocol_packets[PACKET_qSupported],
 			 "qSupported", "supported-packets",
0);
 
+  add_packet_config_cmd
(&remote_protocol_packets[PACKET_qfDllInfo],
+			 "qfDllInfo", "dll-info", 0);
+
   /* Keep the old ``set remote Z-packet ...'' working. 
Each individual
      Z sub-packet has its own set and show commands, but
users may
      have sets to this variable in their .gdbinit files (or
in their
Index: solib-target.c
============================================================
=======
RCS file: solib-target.c
diff -N solib-target.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ solib-target.c	8 Dec 2006 21:09:04 -0000
 -0,0
+1,269 
+/* Definitions for targets which report shared library
events.
+
+   Copyright (C) 2006
+   Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it
and/or modify
+   it under the terms of the GNU General Public License as
published by
+   the Free Software Foundation; either version 2 of the
License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be
useful,
+   but WITHOUT ANY WARRANTY; without even the implied
warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General
Public License
+   along with this program; if not, write to the Free
Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
+
+#include "defs.h"
+#include "solist.h"
+#include "symtab.h"
+#include "symfile.h"
+#include "target.h"
+
+#include "gdb_string.h"
+
+struct lm_info
+{
+  CORE_ADDR textSeg, dataSeg;
+};
+
+static struct so_list *solib_start;
+static int solibs_fetched;
+
+static struct so_list *
+solib_target_current_sos (void)
+{
+  struct so_list *sop;
+  struct so_list *start = NULL;
+  struct so_list *last = NULL;
+
+  /* If we have not asked the target for the list of shared
libraries
+     yet, do it now.  */
+  if (!solibs_fetched)
+    {
+      solibs_fetched = 1;
+      target_get_shared_libraries ();
+    }
+
+  for (sop = solib_start; sop; sop = sop->next)
+    {
+      struct so_list *new;
+
+      /* Duplicate the recorded solib.  */
+      new = XZALLOC (struct so_list);
+      strcpy (new->so_name, sop->so_name);
+      strcpy (new->so_original_name,
sop->so_original_name);
+      new->lm_info = XMALLOC (struct lm_info);
+      *new->lm_info = *sop->lm_info;
+
+      /* Add it to the list.  */
+      if (!start)
+	last = start = new;
+      else
+	{
+	  last->next = new;
+	  last = new;
+	}
+    }
+
+  return start;
+}
+
+static void
+solib_target_special_symbol_handling (void)
+{
+  /* Nothing needed.  */
+}
+
+static void
+solib_target_solib_create_inferior_hook (void)
+{
+  /* Nothing needed.  */
+}
+
+static void
+solib_target_clear_solib (void)
+{
+  struct so_list *sop, *next;
+
+  for (sop = solib_start; sop; sop = next)
+    {
+      next = sop->next;
+
+      free_so (sop);
+    }
+
+  solib_start = NULL;
+  solibs_fetched = 0;
+}
+
+static void
+solib_target_free_so (struct so_list *so)
+{
+  xfree (so->lm_info);
+}
+
+static void
+solib_target_relocate_section_addresses (struct so_list
*so,
+					 struct section_table *sec)
+{
+  int flags = bfd_get_section_flags (sec->bfd,
sec->the_bfd_section);
+  CORE_ADDR offset;
+
+  offset = symfile_section_offset_from_segment
(sec->bfd, sec->the_bfd_section,
+						so->lm_info->textSeg,
+						so->lm_info->dataSeg);
+
+  sec->addr += offset;
+  sec->endaddr += offset;
+
+  /* If we haven't set these yet, do so now.  If this
fails, we may waste some
+     cycles uselessly retrying it, but that is rare and
harmless.  */
+  if (so->addr_low == 0 && so->addr_high ==
0)
+    {
+      CORE_ADDR text_len, data_len;
+
+      symfile_find_segment_lengths (sec->bfd,
&text_len, &data_len);
+
+      if (text_len)
+	{
+	  so->addr_low = so->lm_info->textSeg;
+	  so->addr_high = so->addr_low + text_len;
+	}
+      else if (data_len)
+	{
+	  so->addr_low = so->lm_info->dataSeg;
+	  so->addr_high = so->addr_low + data_len;
+	}
+    }
+}
+
+static int
+solib_target_open_symbol_file_object (void *from_ttyp)
+{
+  /* We can't locate the main symbol file based on the
target's
+     knowledge; the user has to specify it.  */
+  return 0;
+}
+
+static int
+solib_target_in_dynsym_resolve_code (CORE_ADDR pc)
+{
+  /* Assume there isn't target dynsym resolution code.  DLL
targets
+     generally have only import stubs (which GDB treats as
"PLT entries"),
+     and no runtime binding code.  */
+  return 0;
+}
+
+static void
+solib_target_add_one_solib (char *soname, CORE_ADDR
textSeg,
+			    CORE_ADDR dataSeg)
+{
+  struct so_list *new_solib, *so;
+
+  /* We should already have queried the target for shared
libraries
+     before this point.  If we haven't, we may have just
connected;
+     we'll be querying shortly.  */
+  if (!solibs_fetched)
+    return;
+
+  /* Check for duplicates already on the list.  This can
happen, for
+     instance, if we are stopped at a DLL load event when
we first
+     connect to a remote target: the DLL will already be in
the
+     queried list, but also be reported by the initial
wait.  */
+  for (so = solib_start; so; so = so->next)
+    if (strcmp (so->so_name, soname) == 0
+	&& so->lm_info->textSeg == textSeg
+	&& so->lm_info->dataSeg == dataSeg)
+      return;
+
+  new_solib = XZALLOC (struct so_list);
+  strncpy (new_solib->so_name, soname,
SO_NAME_MAX_PATH_SIZE - 1);
+  new_solib->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '';
+  strncpy (new_solib->so_original_name, soname,
SO_NAME_MAX_PATH_SIZE - 1);
+  new_solib->so_original_name[SO_NAME_MAX_PATH_SIZE - 1]
= '';
+
+  new_solib->lm_info = XZALLOC (struct lm_info);
+  new_solib->lm_info->textSeg = textSeg;
+  new_solib->lm_info->dataSeg = dataSeg;
+
+  if (solib_start == NULL)
+    solib_start = new_solib;
+  else
+    {
+      so = solib_start;
+      while (so->next)
+	so = so->next;
+      so->next = new_solib;
+    }
+
+  /* We do not trigger symbol reading here; the target will
do it,
+     after all load events have been processed.  */
+}
+
+static void
+solib_target_remove_one_solib (char *soname, CORE_ADDR
textSeg,
+			       CORE_ADDR dataSeg)
+{
+  struct so_list **slot, *removed;
+
+  /* We should already have queried the target for shared
libraries
+     before this point.  If we haven't, we may have just
connected;
+     we'll be querying shortly.  */
+  if (!solibs_fetched)
+    return;
+
+  for (slot = &solib_start; *slot != NULL; slot =
&(*slot)->next)
+    {
+      if (textSeg != ~(CORE_ADDR) 0 && textSeg !=
(*slot)->lm_info->textSeg)
+	continue;
+      if (dataSeg != ~(CORE_ADDR) 0 && dataSeg !=
(*slot)->lm_info->dataSeg)
+	continue;
+      if (soname != NULL && strcmp (soname,
(*slot)->so_name) != 0)
+	continue;
+      break;
+    }
+
+  if (*slot == NULL)
+    return;
+
+  removed = *slot;
+  *slot = removed->next;
+
+  free_so (removed);
+
+  /* We do not trigger symbol unloading here; the target
will do it,
+     after all unload events have been processed.  */
+}
+
+static struct target_so_ops solib_target_so_ops;
+
+extern initialize_file_ftype _initialize_solib_target; /*
-Wmissing-prototypes */
+
+void
+_initialize_solib_target (void)
+{
+  solib_target_so_ops.relocate_section_addresses
+    = solib_target_relocate_section_addresses;
+  solib_target_so_ops.free_so = solib_target_free_so;
+  solib_target_so_ops.clear_solib =
solib_target_clear_solib;
+  solib_target_so_ops.solib_create_inferior_hook
+    = solib_target_solib_create_inferior_hook;
+  solib_target_so_ops.special_symbol_handling
+    = solib_target_special_symbol_handling;
+  solib_target_so_ops.current_sos =
solib_target_current_sos;
+  solib_target_so_ops.open_symbol_file_object
+    = solib_target_open_symbol_file_object;
+  solib_target_so_ops.in_dynsym_resolve_code
+    = solib_target_in_dynsym_resolve_code;
+  solib_target_so_ops.add_one_solib =
solib_target_add_one_solib;
+  solib_target_so_ops.remove_one_solib =
solib_target_remove_one_solib;
+
+  current_target_so_ops = &solib_target_so_ops;
+}
Index: solist.h
============================================================
=======
RCS file: /cvs/src/src/gdb/solist.h,v
retrieving revision 1.12
diff -u -p -r1.12 solist.h
--- solist.h	17 Dec 2005 22:34:02 -0000	1.12
+++ solist.h	8 Dec 2006 21:09:04 -0000
 -104,7
+104,11  struct target_so_ops
        Convenience function for remote debuggers finding
host libs.  */
     int (*find_and_open_solib) (char *soname,
         unsigned o_flags, char **temp_pathname);
-    
+
+    void (*add_one_solib) (char *soname, CORE_ADDR textSeg,
+			   CORE_ADDR dataSeg);
+    void (*remove_one_solib) (char *soname, CORE_ADDR
textSeg,
+			      CORE_ADDR dataSeg);
   };
 
 /* Free the memory associated with a (so_list *).  */
Index: target.c
============================================================
=======
RCS file: /cvs/src/src/gdb/target.c,v
retrieving revision 1.131
diff -u -p -r1.131 target.c
--- target.c	5 Dec 2006 20:38:13 -0000	1.131
+++ target.c	8 Dec 2006 21:09:05 -0000
 -470,6
+470,7  update_current_target (void)
       /* Do not inherit to_memory_map.  */
       /* Do not inherit to_flash_erase.  */
       /* Do not inherit to_flash_done.  */
+      /* Do not inherit to_get_shared_libraries.  */
     }
 #undef INHERIT
 
 -1716,6
+1717,27  target_read_description (struct target_o
 }
 
 /* Look through the list of possible targets for a target
that can
+   fetch shared libraries.  */
+
+void
+target_get_shared_libraries (void)
+{
+  struct target_ops *t;
+
+  for (t = current_target.beneath; t != NULL; t =
t->beneath)
+    {
+      if (t->to_get_shared_libraries != NULL)
+	{
+	  t->to_get_shared_libraries (t);
+	  break;
+	}
+    }
+
+  if (targetdebug)
+    fprintf_unfiltered (gdb_stdlog,
"target_get_shared_libraries ()n");
+}
+
+/* Look through the list of possible targets for a target
that can
    execute a run or attach command without any other data. 
This is
    used to locate the default process stratum.
 
Index: target.h
============================================================
=======
RCS file: /cvs/src/src/gdb/target.h,v
retrieving revision 1.92
diff -u -p -r1.92 target.h
--- target.h	28 Nov 2006 22:10:26 -0000	1.92
+++ target.h	8 Dec 2006 21:09:05 -0000
 -497,6
+497,9  struct target_ops
        was available.  */
     const struct target_desc *(*to_read_description)
(struct target_ops *ops);
 
+    /* Refresh the list of shared libraries.  */
+    void (*to_get_shared_libraries) (struct target_ops
*ops);
+
     int to_magic;
     /* Need sub-structure for target machine related rather
than comm related?
      */
 -1208,6
+1211,10  extern const struct target_desc *target_
 #define RESUME_EXECD_VFORKING_CHILD_TO_GET_PARENT_VFORK()
(0)
 #endif
 
+/* Refresh the list of shared libraries from the target. 
*/
+
+extern void target_get_shared_libraries (void);
+
 /* Routines for maintenance of the target structures...
 
    add_target:   Add a target to the list of all possible
targets.
GDB solib interface
user name
2006-12-08 22:23:01
Thanks,  

Now I have a couple of questions.

1)  I take it that there isn't anything special here with
regard to DLL
(PE binary files) vs. SO (ELF binraries)

2)  You have HEXSTR in a couple places, since I am not
familiar with
this representation, how would foo.dll be coded in HEXSTR
format.

I think that the rest is self explanatory.


-----Original Message-----
From: Daniel Jacobowitz [mailto:drowfalse.org] 
Sent: Friday, December 08, 2006 2:19 PM
To: Smith, Stephen (SWCOE); General GDB Mailing List
Subject: Re: GDB solib interface
GDB solib interface
user name
2006-12-08 23:21:27
On Fri, Dec 08, 2006 at 03:23:01PM -0700, Smith, Stephen
(SWCOE) wrote:
> Thanks,  
> 
> Now I have a couple of questions.
> 
> 1)  I take it that there isn't anything special here
with regard to DLL
> (PE binary files) vs. SO (ELF binraries)

I've only used it with ELF, despite the DLL naming.

> 2)  You have HEXSTR in a couple places, since I am not
familiar with
> this representation, how would foo.dll be coded in
HEXSTR format.

Just convert the ascii to base 16, two digits per letter.

-- 
Daniel Jacobowitz
CodeSourcery
GDB solib interface
user name
2006-12-15 21:12:17
Ok,  I build gdb for to different targets,  i686-pc-elf and 
powerpc-motorola-elf.  My host is i686-pc-cygwin.

So the question becomes how do I decide which file to modify
for the
TDEPFILES line?

-----Original Message-----
From: Daniel Jacobowitz [mailto:drowfalse.org] 
Sent: Friday, December 08, 2006 2:19 PM
To: Smith, Stephen (SWCOE); General GDB Mailing List
Subject: Re: GDB solib interface

Here you go.  I haven't tested this patch on its own at all,
so if it
breaks, you get to keep both pieces.  Add solib-target.o to
TDEPFILES
for your target to enable it.
GDB solib interface
user name
2006-12-15 22:39:17
On Fri, Dec 15, 2006 at 02:12:17PM -0700, Smith, Stephen
(SWCOE) wrote:
> Ok,  I build gdb for to different targets,  i686-pc-elf
and 
> powerpc-motorola-elf.  My host is i686-pc-cygwin.
> 
> So the question becomes how do I decide which file to
modify for the
> TDEPFILES line?

See which one the build is using by checking
gdb/configure.tgt.

-- 
Daniel Jacobowitz
CodeSourcery
GDB solib interface
user name
2006-12-17 00:42:39
The function solib_target_relocate_section_addresses()
refers to
functions and datamembers that no longer exist.  I believe
that
borrowing code from the svr4 code is the correct thing to
do.

Can anyone confirm that that is the right thing?


-----Original Message-----
From: Daniel Jacobowitz [mailto:drowfalse.org] 
Sent: Friday, December 08, 2006 2:19 PM
To: Smith, Stephen (SWCOE); General GDB Mailing List
Subject: Re: GDB solib interface

+static void
+solib_target_free_so (struct so_list *so)
+{
+  xfree (so->lm_info);
+}
+
+static void
+solib_target_relocate_section_addresses (struct so_list
*so,
+					 struct section_table *sec)
+{
+  int flags = bfd_get_section_flags (sec->bfd,
sec->the_bfd_section);
+  CORE_ADDR offset;
+
+  offset = symfile_section_offset_from_segment
(sec->bfd,
sec->the_bfd_section,
+						so->lm_info->textSeg,
+						so->lm_info->dataSeg);
+
GDB solib interface
user name
2006-12-17 02:16:52
On Sat, Dec 16, 2006 at 05:42:39PM -0700, Smith, Stephen
(SWCOE) wrote:
> The function solib_target_relocate_section_addresses()
refers to
> functions and datamembers that no longer exist.  I
believe that
> borrowing code from the svr4 code is the correct thing
to do.
> 
> Can anyone confirm that that is the right thing?

Sorry, it's actually the other way round.  It's not that the
things it
refers to no longer exist - they've never existed in the FSF
source,
they were part of another patch from the tree I took this
from.

I think the equivalent would be initializing
so->textsection.

-- 
Daniel Jacobowitz
CodeSourcery
GDB solib interface
user name
2006-12-17 06:41:16
Maybe I got my answer, but I'm not sure.  Should I lift the
code from 
the solib-svr4.c file? 

Daniel Jacobowitz wrote:
> I think the equivalent would be initializing
so->textsection.
>
>   

GDB solib interface
user name
2006-12-17 15:24:15
On Sat, Dec 16, 2006 at 11:41:16PM -0700, Stephen &
Linda Smith wrote:
> Maybe I got my answer, but I'm not sure.  Should I lift
the code from 
> the solib-svr4.c file? 

I don't know.

-- 
Daniel Jacobowitz
CodeSourcery
GDB solib interface
user name
2006-12-29 22:13:43
Array
GDB solib interface
user name
2006-12-29 22:59:56
Array
GDB solib interface
user name
2006-12-29 22:59:56
Array
[1-20] [21]

about | contact  Other archives ( Real Estate discussion Medical topics )