* How to implement gcore on pa-hpux ?
@ 2006-01-04 17:40 Joel Brobecker
2006-01-04 18:40 ` Daniel Jacobowitz
0 siblings, 1 reply; 11+ messages in thread
From: Joel Brobecker @ 2006-01-04 17:40 UTC (permalink / raw)
To: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 1583 bytes --]
Hello,
I have implemented the gcore command on pa-hpux for one of our customers.
I would like to contribute this work, but I know that for sure the
approach is took is not acceptable.
The work is based on using the TT_PROC_CORE ttrace command:
TT_PROC_CORE This request causes the traced process to generate a
core file in the target process's current working
directory. The core file is named core.pid where pid is
the process ID of the target process. The process's
state is left unchanged. The lwpid, addr, data and
addr2 arguments must be zero.
So I created a new function in infttrace.c. In order to avoid re-writing
the part of gcore.c that add the command, and handles the arguments of this
command, I simply hooked the new infttrace directly into the gcore code.
A bit crude, but it works and it's pretty localized.
For the FSF tree, I'd like to implement this a little better, and it
seems to me that the core part of this command, the part that actually
creates the core file, should be a method of some vector. But which
vector?
The way the gcore command is currently written, it seems that it would
make sense for it to be part of the target vector. No?
However, in the case of HP/UX, there is a slight complication, because
the method is only good in the native case...
Any suggestion?
Attached is the infttrace function that creates the core dump. It is
largely inspired from the HP WDB debugger sources (contributed recently).
Thanks,
--
Joel
[-- Attachment #2: dcf.c --]
[-- Type: text/plain, Size: 1156 bytes --]
void
dump_core_file (int pid, const char *filename)
{
int tt_status;
char buf[64];
tt_status = call_ttrace (TT_PROC_CORE, pid, (TTRACE_ARG_TYPE) filename, 0, 0);
if (tt_status == -1)
{
/* With some versions of HP/UX, specifying the name of the core file
is not supported, so this may have been the cause for this failure.
Try again without the file name. */
tt_status = call_ttrace (TT_PROC_CORE, pid, 0, 0, 0);
if (tt_status != -1)
{
/* Success, so indeed the filename was the source of the problem.
Inform the user that the core file was named differently
(if indeed the filename is different from the default core
file name!) */
sprintf (buf, "core.%d", pid);
if (strcmp (filename, buf) != 0)
{
warning ("The Operating System does not allow the dump in %s",
filename);
filename = buf;
}
}
}
if (tt_status == -1)
perror_with_name ("ttrace:");
else
fprintf_filtered (gdb_stdout, "Saved corefile %s\n", filename);
}
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: How to implement gcore on pa-hpux ?
2006-01-04 17:40 How to implement gcore on pa-hpux ? Joel Brobecker
@ 2006-01-04 18:40 ` Daniel Jacobowitz
2006-01-04 19:12 ` Michael Snyder
2006-01-05 4:03 ` Joel Brobecker
0 siblings, 2 replies; 11+ messages in thread
From: Daniel Jacobowitz @ 2006-01-04 18:40 UTC (permalink / raw)
To: Joel Brobecker; +Cc: gdb-patches
On Wed, Jan 04, 2006 at 09:40:09PM +0400, Joel Brobecker wrote:
>
> So I created a new function in infttrace.c. In order to avoid re-writing
> the part of gcore.c that add the command, and handles the arguments of this
> command, I simply hooked the new infttrace directly into the gcore code.
> A bit crude, but it works and it's pretty localized.
>
> For the FSF tree, I'd like to implement this a little better, and it
> seems to me that the core part of this command, the part that actually
> creates the core file, should be a method of some vector. But which
> vector?
>
> The way the gcore command is currently written, it seems that it would
> make sense for it to be part of the target vector. No?
>
> However, in the case of HP/UX, there is a slight complication, because
> the method is only good in the native case...
If you really mean target vector, then this isn't a complication at
all. The native case should have its own target vector already, in
inf-ttrace.c (note the dash in modern sources). Ideally remote targets
could gcore; but there's been no interest in implementing that so far,
so it's not worth concerning ourselves with until someone wants to work
on it.
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: How to implement gcore on pa-hpux ?
2006-01-04 18:40 ` Daniel Jacobowitz
@ 2006-01-04 19:12 ` Michael Snyder
2006-01-05 3:24 ` Joel Brobecker
2006-01-05 4:03 ` Joel Brobecker
1 sibling, 1 reply; 11+ messages in thread
From: Michael Snyder @ 2006-01-04 19:12 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: Joel Brobecker, gdb-patches
Daniel Jacobowitz wrote:
> On Wed, Jan 04, 2006 at 09:40:09PM +0400, Joel Brobecker wrote:
>
>>So I created a new function in infttrace.c. In order to avoid re-writing
>>the part of gcore.c that add the command, and handles the arguments of this
>>command, I simply hooked the new infttrace directly into the gcore code.
>>A bit crude, but it works and it's pretty localized.
>>
>>For the FSF tree, I'd like to implement this a little better, and it
>>seems to me that the core part of this command, the part that actually
>>creates the core file, should be a method of some vector. But which
>>vector?
>>
>>The way the gcore command is currently written, it seems that it would
>>make sense for it to be part of the target vector. No?
>>
>>However, in the case of HP/UX, there is a slight complication, because
>>the method is only good in the native case...
>
>
> If you really mean target vector, then this isn't a complication at
> all. The native case should have its own target vector already, in
> inf-ttrace.c (note the dash in modern sources). Ideally remote targets
> could gcore; but there's been no interest in implementing that so far,
> so it's not worth concerning ourselves with until someone wants to work
> on it.
Alternatively...
The "gcore" command is actually defined in gcore.c. If someone
(hpux) wanted to define it differently, it should be as simple as
linking in your own (eg.) hpux-gcore.c module, *instead of* the
generic gcore.c module.
Current targets that implement gcore in the generic way
do so by adding gcore.o to the NATDEPFILES.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: How to implement gcore on pa-hpux ?
2006-01-04 19:12 ` Michael Snyder
@ 2006-01-05 3:24 ` Joel Brobecker
2006-01-06 4:40 ` Michael Snyder
0 siblings, 1 reply; 11+ messages in thread
From: Joel Brobecker @ 2006-01-05 3:24 UTC (permalink / raw)
To: Michael Snyder; +Cc: Daniel Jacobowitz, gdb-patches
> The "gcore" command is actually defined in gcore.c. If someone
> (hpux) wanted to define it differently, it should be as simple as
> linking in your own (eg.) hpux-gcore.c module, *instead of* the
> generic gcore.c module.
>
> Current targets that implement gcore in the generic way
> do so by adding gcore.o to the NATDEPFILES.
That's almost the approach I took. The problem with the above
is that you end up rewriting a bunch of code that could have
been reused (namely the code that adds the "gcore" command,
and the part of gcore_command that deals with arguments).
If you really want to know, I did
gcore_command (...)
{
[part that deals with arguments]
#ifdef HAVE_TTRACE
dump_core_file (...);
return;
#endif
[rest of the regular gcore_command]
}
This is why I'm suggesting that the part that writes the core file
become a method. That way, we can have several types of gcore
implementations.
One variation of your proposal is maybe to extract out the part
that writes the core file from gcore.c, move it to gcore-elf.c
(is this elf only????), and then have a gcore-hpux.c. I'm not too
fond of this approach, though, because eventually we want to be
able to have support for multiple targets in the same debugger.
Say we have a HP/UX native debugger that also supports a target
that the current gcore module supports. We'd have to choose one
or the other, but we couldn't have both.
--
Joel
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: How to implement gcore on pa-hpux ?
2006-01-04 18:40 ` Daniel Jacobowitz
2006-01-04 19:12 ` Michael Snyder
@ 2006-01-05 4:03 ` Joel Brobecker
2006-01-05 5:02 ` Daniel Jacobowitz
1 sibling, 1 reply; 11+ messages in thread
From: Joel Brobecker @ 2006-01-05 4:03 UTC (permalink / raw)
To: gdb-patches
> If you really mean target vector, then this isn't a complication at
> all. The native case should have its own target vector already, in
> inf-ttrace.c (note the dash in modern sources). Ideally remote targets
> could gcore; but there's been no interest in implementing that so far,
> so it's not worth concerning ourselves with until someone wants to work
> on it.
I proposed the target vector indeed because I thought that we might want
to let remote targets also do a core dump, eventually. Thinking about it
more, maybe this wasn't the best approach after all.
using the target vector, the native HP/UX case seems to be a no-brainer,
which is always nice. Suppose I add a new method to that vector that
does core file dumping, however. The problem is: How do we set that
method of all the cases where we already support gcore? For instance,
i386-linux.
Seems to me that this should be done during the tdep initialization
phase, where we know what type of architecture we're dealing with.
But then, can we lightly manipulate target vectors like this, and
has the target vector been set at this point? This is a bit of a gray
area for me, at the moment, but I have concerns.
On the other hand, setting the method during the tdep initialization
phase does suggest that maybe a gdbarch method might be better suited.
The current gcore implementation doesn't seem to be depending on
anything native, so the gdbarch method seems well suited for it.
There is the issue of HP/UX however, because in our case, it's
native-only. Setting the new gdbarch method using ttrace code would
break the tdep/nat separation.
So it leads me to propose the following approach: How about I add
two new methods:
- 1 new gdbarch method: This would be the prefered method to call
when trying to dump a core file. This method would be set to
the current implementation in all the configurations where this
feature is already supported.
- 1 new target method: This would be the fallback method when the
gdbarch method is not implemented. Set to null by default, it
would be set to ttrace.c:dump_core_file in inf_ttrace_target().
- In all other cases, we tell the user that this function is not
implemented on this target.
The rationale would be:
- If we have a target-dependent implementation, great! Use it.
- Otherwise, do we have a native-only implementation (in the
target vector)? If yes, then better than nothing, use it.
- Otherwise, this feature in unimplemented.
Seems plausible?
--
Joel
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: How to implement gcore on pa-hpux ?
2006-01-05 4:03 ` Joel Brobecker
@ 2006-01-05 5:02 ` Daniel Jacobowitz
0 siblings, 0 replies; 11+ messages in thread
From: Daniel Jacobowitz @ 2006-01-05 5:02 UTC (permalink / raw)
To: Joel Brobecker; +Cc: gdb-patches
On Thu, Jan 05, 2006 at 07:53:11AM +0400, Joel Brobecker wrote:
> using the target vector, the native HP/UX case seems to be a no-brainer,
> which is always nice. Suppose I add a new method to that vector that
> does core file dumping, however. The problem is: How do we set that
> method of all the cases where we already support gcore? For instance,
> i386-linux.
We set it in linux-nat.c:linux_target () and inherit it into all
GNU/Linux targets.
The current Linux mechanism is not target-independent; it's
native-only, because it grubs around in /proc.
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: How to implement gcore on pa-hpux ?
2006-01-05 3:24 ` Joel Brobecker
@ 2006-01-06 4:40 ` Michael Snyder
2006-01-06 10:28 ` Joel Brobecker
0 siblings, 1 reply; 11+ messages in thread
From: Michael Snyder @ 2006-01-06 4:40 UTC (permalink / raw)
To: Joel Brobecker; +Cc: Daniel Jacobowitz, gdb-patches
Joel Brobecker wrote:
>>The "gcore" command is actually defined in gcore.c. If someone
>>(hpux) wanted to define it differently, it should be as simple as
>>linking in your own (eg.) hpux-gcore.c module, *instead of* the
>>generic gcore.c module.
>>
>>Current targets that implement gcore in the generic way
>>do so by adding gcore.o to the NATDEPFILES.
>
>
> That's almost the approach I took. The problem with the above
> is that you end up rewriting a bunch of code that could have
> been reused (namely the code that adds the "gcore" command,
> and the part of gcore_command that deals with arguments).
>
> If you really want to know, I did
>
> gcore_command (...)
> {
> [part that deals with arguments]
>
> #ifdef HAVE_TTRACE
> dump_core_file (...);
> return;
> #endif
>
> [rest of the regular gcore_command]
> }
OK, well, without looking at your code I don't know if this is
applicable, but I did write the gcore code so as to use callbacks.
It was intended to be extendable, so that whatever needed to be
done per-section(segment) could be done by the callbacks, which
you could supply.
The callbacks supplied are for elf, for instance, which
is the only object format that I directly addressed, but
I would hope that callbacks for other formats could be
made to fit. I was intending, for instance, to implement
a callback for remote targets that would simply read the
memory from the remote-writeable sections and copy it into
a file.
Can this not be made to work for you?
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: How to implement gcore on pa-hpux ?
2006-01-06 4:40 ` Michael Snyder
@ 2006-01-06 10:28 ` Joel Brobecker
2006-01-06 13:43 ` Daniel Jacobowitz
0 siblings, 1 reply; 11+ messages in thread
From: Joel Brobecker @ 2006-01-06 10:28 UTC (permalink / raw)
To: Michael Snyder; +Cc: Daniel Jacobowitz, gdb-patches
> OK, well, without looking at your code I don't know if this is
> applicable, but I did write the gcore code so as to use callbacks.
> It was intended to be extendable, so that whatever needed to be
> done per-section(segment) could be done by the callbacks, which
> you could supply.
>
> The callbacks supplied are for elf, for instance, which
> is the only object format that I directly addressed, but
> I would hope that callbacks for other formats could be
> made to fit. I was intending, for instance, to implement
> a callback for remote targets that would simply read the
> memory from the remote-writeable sections and copy it into
> a file.
>
> Can this not be made to work for you?
I think I see what you mean, and I now understand the reason for
the callbacks. I suppose I could do the same for HP/UX, but it would
be more work than just relying on ttrace.
The discussion started because I thought it would be a shame to
duplicate a few lines of code. But perhaps there is another way
of dealing with this.
1. Create a new file gcore-elf.c
Move the elf section there.
2. Create a new file gcore-hpux.c
Put the hpux code there
3. Have gcore call a predefined routine, or maybe a hook
specified by the gcore-* module.
It's not as elegant as having a gdbarch or target method, but it's
probably easier to implement. We defer a bit the work that makes this
a method of some vector, but it's not necessary right now. Perhaps
the pragmatic thing to do would be to wait until we need it before
we start worrying about it. Even then, the work is slightly prepared
because we already have the genericity based on the hook.
What do you guys think?
--
Joel
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: How to implement gcore on pa-hpux ?
2006-01-06 10:28 ` Joel Brobecker
@ 2006-01-06 13:43 ` Daniel Jacobowitz
2006-01-09 5:59 ` Joel Brobecker
0 siblings, 1 reply; 11+ messages in thread
From: Daniel Jacobowitz @ 2006-01-06 13:43 UTC (permalink / raw)
To: Joel Brobecker; +Cc: Michael Snyder, gdb-patches
On Fri, Jan 06, 2006 at 02:28:24PM +0400, Joel Brobecker wrote:
> It's not as elegant as having a gdbarch or target method, but it's
> probably easier to implement. We defer a bit the work that makes this
> a method of some vector, but it's not necessary right now. Perhaps
> the pragmatic thing to do would be to wait until we need it before
> we start worrying about it. Even then, the work is slightly prepared
> because we already have the genericity based on the hook.
>
> What do you guys think?
I think that if you need to add new files and rely on magic function
names, then you're already past the time when you needed to add things
to a vector.
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: How to implement gcore on pa-hpux ?
2006-01-06 13:43 ` Daniel Jacobowitz
@ 2006-01-09 5:59 ` Joel Brobecker
2006-01-22 20:43 ` Daniel Jacobowitz
0 siblings, 1 reply; 11+ messages in thread
From: Joel Brobecker @ 2006-01-09 5:59 UTC (permalink / raw)
To: Michael Snyder, gdb-patches
[-- Attachment #1: Type: text/plain, Size: 3189 bytes --]
> On Fri, Jan 06, 2006 at 02:28:24PM +0400, Joel Brobecker wrote:
> > It's not as elegant as having a gdbarch or target method, but it's
> > probably easier to implement. We defer a bit the work that makes this
> > a method of some vector, but it's not necessary right now. Perhaps
> > the pragmatic thing to do would be to wait until we need it before
> > we start worrying about it. Even then, the work is slightly prepared
> > because we already have the genericity based on the hook.
> >
> > What do you guys think?
>
> I think that if you need to add new files and rely on magic function
> names, then you're already past the time when you needed to add things
> to a vector.
Magic function name? Ouch, my heart ;-).
OK, will try to play with the target vector. For the record, here is
what I had in mind. I implemented it because it's not that far off the
road to using the target vector. In this case, it's the gcore module
itself that holds the method pointer rather than the target vector.
It's not as powerful, because it is not dynamic the way target vectors
are, but it's not worse than before.
2006-01-09 Joel Brobecker <brobecker@adacore.com>
* gcore.c: Extract all the code writing the core file and move
it to a new file gcore-elf.c. Update list of #include's.
(write_core_p): New static variable.
(gcore_command): Call write_core_p to write the core file.
(gcore_set_write_core): New function.
* defs.h (write_core_ftype): New typdef.
(gcore_set_write_core): Add declaration.
* Makefile.in (COMMON_OBS): Add gcore.o
(gcore.o): Update dependencies.
(gcore-elf.o): Add rule.
* config/alpha/alpha-linux.mh (NATDEPFILES): Replace gcore.o by
gcore-elf.o.
* config/alpha/fbsd.mh (NATDEPFILES): Likewise.
* config/arm/linux.mh (NATDEPFILES): Likewise.
* config/i386/fbsd.mh (NATDEPFILES): Likewise.
* config/i386/fbsd64.mh (NATDEPFILES): Likewise.
* config/i386/i386sol2.mh (NATDEPFILES): Likewise.
* config/i386/i386v42mp.mh (NATDEPFILES): Likewise.
* config/i386/linux.mh (NATDEPFILES): Likewise.
* config/i386/linux64.mh (NATDEPFILES): Likewise.
* config/i386/sol2-64.mh (NATDEPFILES): Likewise.
* config/ia64/linux.mh (NATDEPFILES): Likewise.
* config/m32r/linux.mh (NATDEPFILES): Likewise.
* config/m68k/linux.mh (NATDEPFILES): Likewise.
* config/mips/linux.mh (NATDEPFILES): Likewise.
* config/pa/linux.mh (NATDEPFILES): Likewise.
* config/powerpc/linux.mh (NATDEPFILES): Likewise.
* config/powerpc/ppc64-linux.mh (NATDEPFILES): Likewise.
* config/s390/s390.mh (NATDEPFILES): Likewise.
* config/sparc/fbsd.mh (NATDEPFILES): Likewise.
* config/sparc/linux.mh (NATDEPFILES): Likewise.
* config/sparc/linux64.mh (NATDEPFILES): Likewise.
* config/sparc/sol2.mh (NATDEPFILES): Likewise.
* inf-ttrace.c (inf_ttrace_write_core): New function.
(_initialize_inf_ttrace): Set gcore write_core method
to inf_ttrace_write_core.
Tested on x86-linux and pa32-hpux, no regression.
--
Joel
[-- Attachment #2: gcore-hpux.diff --]
[-- Type: text/plain, Size: 31336 bytes --]
Index: gcore.c
===================================================================
RCS file: /cvs/src/src/gdb/gcore.c,v
retrieving revision 1.18
diff -u -p -r1.18 gcore.c
--- gcore.c 17 Dec 2005 22:33:59 -0000 1.18
+++ gcore.c 9 Jan 2006 05:39:53 -0000
@@ -20,33 +20,21 @@
Boston, MA 02110-1301, USA. */
#include "defs.h"
-#include "elf-bfd.h"
-#include "infcall.h"
#include "inferior.h"
-#include "gdbcore.h"
-#include "objfiles.h"
-#include "symfile.h"
+#include "target.h"
+#include "command.h"
-#include "cli/cli-decode.h"
-
-#include "gdb_assert.h"
-
-static char *default_gcore_target (void);
-static enum bfd_architecture default_gcore_arch (void);
-static unsigned long default_gcore_mach (void);
-static int gcore_memory_sections (bfd *);
+static write_core_ftype *write_core_p = NULL;
/* Generate a core file from the inferior process. */
static void
gcore_command (char *args, int from_tty)
{
- struct cleanup *old_chain;
char *corefilename, corefilename_buffer[40];
- asection *note_sec = NULL;
- bfd *obfd;
- void *note_data = NULL;
- int note_size = 0;
+
+ if (write_core_p == NULL)
+ error ("Command not supported on this platform");
/* No use generating a corefile without a target process. */
if (!target_has_execution)
@@ -61,431 +49,13 @@ gcore_command (char *args, int from_tty)
corefilename = corefilename_buffer;
}
- if (info_verbose)
- fprintf_filtered (gdb_stdout,
- "Opening corefile '%s' for output.\n", corefilename);
-
- /* Open the output file. */
- obfd = bfd_openw (corefilename, default_gcore_target ());
- if (!obfd)
- error (_("Failed to open '%s' for output."), corefilename);
-
- /* Need a cleanup that will close the file (FIXME: delete it?). */
- old_chain = make_cleanup_bfd_close (obfd);
-
- bfd_set_format (obfd, bfd_core);
- bfd_set_arch_mach (obfd, default_gcore_arch (), default_gcore_mach ());
-
- /* An external target method must build the notes section. */
- note_data = target_make_corefile_notes (obfd, ¬e_size);
-
- /* Create the note section. */
- if (note_data != NULL && note_size != 0)
- {
- note_sec = bfd_make_section_anyway (obfd, "note0");
- if (note_sec == NULL)
- error (_("Failed to create 'note' section for corefile: %s"),
- bfd_errmsg (bfd_get_error ()));
-
- bfd_set_section_vma (obfd, note_sec, 0);
- bfd_set_section_flags (obfd, note_sec,
- SEC_HAS_CONTENTS | SEC_READONLY | SEC_ALLOC);
- bfd_set_section_alignment (obfd, note_sec, 0);
- bfd_set_section_size (obfd, note_sec, note_size);
- }
-
- /* Now create the memory/load sections. */
- if (gcore_memory_sections (obfd) == 0)
- error (_("gcore: failed to get corefile memory sections from target."));
-
- /* Write out the contents of the note section. */
- if (note_data != NULL && note_size != 0)
- {
- if (!bfd_set_section_contents (obfd, note_sec, note_data, 0, note_size))
- warning (_("writing note section (%s)"), bfd_errmsg (bfd_get_error ()));
- }
-
- /* Succeeded. */
- fprintf_filtered (gdb_stdout, "Saved corefile %s\n", corefilename);
-
- /* Clean-ups will close the output file and free malloc memory. */
- do_cleanups (old_chain);
- return;
-}
-
-static unsigned long
-default_gcore_mach (void)
-{
-#if 1 /* See if this even matters... */
- return 0;
-#else
-#ifdef TARGET_ARCHITECTURE
- const struct bfd_arch_info *bfdarch = TARGET_ARCHITECTURE;
-
- if (bfdarch != NULL)
- return bfdarch->mach;
-#endif /* TARGET_ARCHITECTURE */
- if (exec_bfd == NULL)
- error (_("Can't find default bfd machine type (need execfile)."));
-
- return bfd_get_mach (exec_bfd);
-#endif /* 1 */
-}
-
-static enum bfd_architecture
-default_gcore_arch (void)
-{
-#ifdef TARGET_ARCHITECTURE
- const struct bfd_arch_info * bfdarch = TARGET_ARCHITECTURE;
-
- if (bfdarch != NULL)
- return bfdarch->arch;
-#endif
- if (exec_bfd == NULL)
- error (_("Can't find bfd architecture for corefile (need execfile)."));
-
- return bfd_get_arch (exec_bfd);
-}
-
-static char *
-default_gcore_target (void)
-{
- /* FIXME: This may only work for ELF targets. */
- if (exec_bfd == NULL)
- return NULL;
- else
- return bfd_get_target (exec_bfd);
-}
-
-/* Derive a reasonable stack segment by unwinding the target stack,
- and store its limits in *BOTTOM and *TOP. Return non-zero if
- successful. */
-
-static int
-derive_stack_segment (bfd_vma *bottom, bfd_vma *top)
-{
- struct frame_info *fi, *tmp_fi;
-
- gdb_assert (bottom);
- gdb_assert (top);
-
- /* Can't succeed without stack and registers. */
- if (!target_has_stack || !target_has_registers)
- return 0;
-
- /* Can't succeed without current frame. */
- fi = get_current_frame ();
- if (fi == NULL)
- return 0;
-
- /* Save frame pointer of TOS frame. */
- *top = get_frame_base (fi);
- /* If current stack pointer is more "inner", use that instead. */
- if (INNER_THAN (read_sp (), *top))
- *top = read_sp ();
-
- /* Find prev-most frame. */
- while ((tmp_fi = get_prev_frame (fi)) != NULL)
- fi = tmp_fi;
-
- /* Save frame pointer of prev-most frame. */
- *bottom = get_frame_base (fi);
-
- /* Now canonicalize their order, so that BOTTOM is a lower address
- (as opposed to a lower stack frame). */
- if (*bottom > *top)
- {
- bfd_vma tmp_vma;
-
- tmp_vma = *top;
- *top = *bottom;
- *bottom = tmp_vma;
- }
-
- return 1;
+ write_core_p (ptid_get_pid (inferior_ptid), corefilename);
}
-/* Derive a reasonable heap segment for ABFD by looking at sbrk and
- the static data sections. Store its limits in *BOTTOM and *TOP.
- Return non-zero if successful. */
-
-static int
-derive_heap_segment (bfd *abfd, bfd_vma *bottom, bfd_vma *top)
-{
- bfd_vma top_of_data_memory = 0;
- bfd_vma top_of_heap = 0;
- bfd_size_type sec_size;
- struct value *zero, *sbrk;
- bfd_vma sec_vaddr;
- asection *sec;
-
- gdb_assert (bottom);
- gdb_assert (top);
-
- /* This function depends on being able to call a function in the
- inferior. */
- if (!target_has_execution)
- return 0;
-
- /* The following code assumes that the link map is arranged as
- follows (low to high addresses):
-
- ---------------------------------
- | text sections |
- ---------------------------------
- | data sections (including bss) |
- ---------------------------------
- | heap |
- --------------------------------- */
-
- for (sec = abfd->sections; sec; sec = sec->next)
- {
- if (bfd_get_section_flags (abfd, sec) & SEC_DATA
- || strcmp (".bss", bfd_section_name (abfd, sec)) == 0)
- {
- sec_vaddr = bfd_get_section_vma (abfd, sec);
- sec_size = bfd_get_section_size (sec);
- if (sec_vaddr + sec_size > top_of_data_memory)
- top_of_data_memory = sec_vaddr + sec_size;
- }
- }
-
- /* Now get the top-of-heap by calling sbrk in the inferior. */
- if (lookup_minimal_symbol ("sbrk", NULL, NULL) != NULL)
- {
- sbrk = find_function_in_inferior ("sbrk");
- if (sbrk == NULL)
- return 0;
- }
- else if (lookup_minimal_symbol ("_sbrk", NULL, NULL) != NULL)
- {
- sbrk = find_function_in_inferior ("_sbrk");
- if (sbrk == NULL)
- return 0;
- }
- else
- return 0;
-
- zero = value_from_longest (builtin_type_int, 0);
- gdb_assert (zero);
- sbrk = call_function_by_hand (sbrk, 1, &zero);
- if (sbrk == NULL)
- return 0;
- top_of_heap = value_as_long (sbrk);
-
- /* Return results. */
- if (top_of_heap > top_of_data_memory)
- {
- *bottom = top_of_data_memory;
- *top = top_of_heap;
- return 1;
- }
-
- /* No additional heap space needs to be saved. */
- return 0;
-}
-
-static void
-make_output_phdrs (bfd *obfd, asection *osec, void *ignored)
-{
- int p_flags = 0;
- int p_type;
-
- /* FIXME: these constants may only be applicable for ELF. */
- if (strncmp (bfd_section_name (obfd, osec), "load", 4) == 0)
- p_type = PT_LOAD;
- else
- p_type = PT_NOTE;
-
- p_flags |= PF_R; /* Segment is readable. */
- if (!(bfd_get_section_flags (obfd, osec) & SEC_READONLY))
- p_flags |= PF_W; /* Segment is writable. */
- if (bfd_get_section_flags (obfd, osec) & SEC_CODE)
- p_flags |= PF_X; /* Segment is executable. */
-
- bfd_record_phdr (obfd, p_type, 1, p_flags, 0, 0, 0, 0, 1, &osec);
-}
-
-static int
-gcore_create_callback (CORE_ADDR vaddr, unsigned long size,
- int read, int write, int exec, void *data)
-{
- bfd *obfd = data;
- asection *osec;
- flagword flags = SEC_ALLOC | SEC_HAS_CONTENTS | SEC_LOAD;
-
- /* If the memory segment has no permissions set, ignore it, otherwise
- when we later try to access it for read/write, we'll get an error
- or jam the kernel. */
- if (read == 0 && write == 0 && exec == 0)
- {
- if (info_verbose)
- {
- fprintf_filtered (gdb_stdout, "Ignore segment, %s bytes at 0x%s\n",
- paddr_d (size), paddr_nz (vaddr));
- }
-
- return 0;
- }
-
- if (write == 0)
- {
- /* See if this region of memory lies inside a known file on disk.
- If so, we can avoid copying its contents by clearing SEC_LOAD. */
- struct objfile *objfile;
- struct obj_section *objsec;
-
- ALL_OBJSECTIONS (objfile, objsec)
- {
- bfd *abfd = objfile->obfd;
- asection *asec = objsec->the_bfd_section;
- bfd_vma align = (bfd_vma) 1 << bfd_get_section_alignment (abfd,
- asec);
- bfd_vma start = objsec->addr & -align;
- bfd_vma end = (objsec->endaddr + align - 1) & -align;
- /* Match if either the entire memory region lies inside the
- section (i.e. a mapping covering some pages of a large
- segment) or the entire section lies inside the memory region
- (i.e. a mapping covering multiple small sections).
-
- This BFD was synthesized from reading target memory,
- we don't want to omit that. */
- if (((vaddr >= start && vaddr + size <= end)
- || (start >= vaddr && end <= vaddr + size))
- && !(bfd_get_file_flags (abfd) & BFD_IN_MEMORY))
- {
- flags &= ~SEC_LOAD;
- goto keep; /* break out of two nested for loops */
- }
- }
-
- keep:
- flags |= SEC_READONLY;
- }
-
- if (exec)
- flags |= SEC_CODE;
- else
- flags |= SEC_DATA;
-
- osec = bfd_make_section_anyway (obfd, "load");
- if (osec == NULL)
- {
- warning (_("Couldn't make gcore segment: %s"),
- bfd_errmsg (bfd_get_error ()));
- return 1;
- }
-
- if (info_verbose)
- {
- fprintf_filtered (gdb_stdout, "Save segment, %s bytes at 0x%s\n",
- paddr_d (size), paddr_nz (vaddr));
- }
-
- bfd_set_section_size (obfd, osec, size);
- bfd_set_section_vma (obfd, osec, vaddr);
- bfd_section_lma (obfd, osec) = 0; /* ??? bfd_set_section_lma? */
- bfd_set_section_flags (obfd, osec, flags);
- return 0;
-}
-
-static int
-objfile_find_memory_regions (int (*func) (CORE_ADDR, unsigned long,
- int, int, int, void *),
- void *obfd)
-{
- /* Use objfile data to create memory sections. */
- struct objfile *objfile;
- struct obj_section *objsec;
- bfd_vma temp_bottom, temp_top;
-
- /* Call callback function for each objfile section. */
- ALL_OBJSECTIONS (objfile, objsec)
- {
- bfd *ibfd = objfile->obfd;
- asection *isec = objsec->the_bfd_section;
- flagword flags = bfd_get_section_flags (ibfd, isec);
- int ret;
-
- if ((flags & SEC_ALLOC) || (flags & SEC_LOAD))
- {
- int size = bfd_section_size (ibfd, isec);
- int ret;
-
- ret = (*func) (objsec->addr, bfd_section_size (ibfd, isec),
- 1, /* All sections will be readable. */
- (flags & SEC_READONLY) == 0, /* Writable. */
- (flags & SEC_CODE) != 0, /* Executable. */
- obfd);
- if (ret != 0)
- return ret;
- }
- }
-
- /* Make a stack segment. */
- if (derive_stack_segment (&temp_bottom, &temp_top))
- (*func) (temp_bottom, temp_top - temp_bottom,
- 1, /* Stack section will be readable. */
- 1, /* Stack section will be writable. */
- 0, /* Stack section will not be executable. */
- obfd);
-
- /* Make a heap segment. */
- if (derive_heap_segment (exec_bfd, &temp_bottom, &temp_top))
- (*func) (temp_bottom, temp_top - temp_bottom,
- 1, /* Heap section will be readable. */
- 1, /* Heap section will be writable. */
- 0, /* Heap section will not be executable. */
- obfd);
-
- return 0;
-}
-
-static void
-gcore_copy_callback (bfd *obfd, asection *osec, void *ignored)
-{
- bfd_size_type size = bfd_section_size (obfd, osec);
- struct cleanup *old_chain = NULL;
- void *memhunk;
-
- /* Read-only sections are marked; we don't have to copy their contents. */
- if ((bfd_get_section_flags (obfd, osec) & SEC_LOAD) == 0)
- return;
-
- /* Only interested in "load" sections. */
- if (strncmp ("load", bfd_section_name (obfd, osec), 4) != 0)
- return;
-
- memhunk = xmalloc (size);
- /* ??? This is crap since xmalloc should never return NULL. */
- if (memhunk == NULL)
- error (_("Not enough memory to create corefile."));
- old_chain = make_cleanup (xfree, memhunk);
-
- if (target_read_memory (bfd_section_vma (obfd, osec),
- memhunk, size) != 0)
- warning (_("Memory read failed for corefile section, %s bytes at 0x%s."),
- paddr_d (size), paddr (bfd_section_vma (obfd, osec)));
- if (!bfd_set_section_contents (obfd, osec, memhunk, 0, size))
- warning (_("Failed to write corefile contents (%s)."),
- bfd_errmsg (bfd_get_error ()));
-
- do_cleanups (old_chain); /* Frees MEMHUNK. */
-}
-
-static int
-gcore_memory_sections (bfd *obfd)
+void
+gcore_set_write_core (write_core_ftype *write_core)
{
- if (target_find_memory_regions (gcore_create_callback, obfd) != 0)
- return 0; /* FIXME: error return/msg? */
-
- /* Record phdrs for section-to-segment mapping. */
- bfd_map_over_sections (obfd, make_output_phdrs, NULL);
-
- /* Copy memory region contents. */
- bfd_map_over_sections (obfd, gcore_copy_callback, NULL);
-
- return 1;
+ write_core_p = write_core;
}
void
@@ -496,5 +66,4 @@ Save a core file with the current state
Argument is optional filename. Default filename is 'core.<process_id>'."));
add_com_alias ("gcore", "generate-core-file", class_files, 1);
- exec_set_find_memory_regions (objfile_find_memory_regions);
}
Index: defs.h
===================================================================
RCS file: /cvs/src/src/gdb/defs.h,v
retrieving revision 1.190
diff -u -p -r1.190 defs.h
--- defs.h 17 Dec 2005 22:33:59 -0000 1.190
+++ defs.h 9 Jan 2006 05:39:42 -0000
@@ -1217,4 +1217,9 @@ extern int use_windows;
extern ULONGEST align_up (ULONGEST v, int n);
extern ULONGEST align_down (ULONGEST v, int n);
+/* Core file generation. */
+
+typedef void (write_core_ftype) (int pid, const char *filename);
+void gcore_set_write_core (write_core_ftype *write_core);
+
#endif /* #ifndef DEFS_H */
Index: Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.772
diff -u -p -r1.772 Makefile.in
--- Makefile.in 4 Jan 2006 19:34:58 -0000 1.772
+++ Makefile.in 9 Jan 2006 05:39:10 -0000
@@ -940,7 +940,7 @@ COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $
reggroups.o regset.o \
trad-frame.o \
tramp-frame.o \
- solib.o solib-null.o
+ solib.o solib-null.o gcore.o
TSOBS = inflow.o
@@ -1971,9 +1971,9 @@ f-typeprint.o: f-typeprint.c $(defs_h) $
f-valprint.o: f-valprint.c $(defs_h) $(gdb_string_h) $(symtab_h) \
$(gdbtypes_h) $(expression_h) $(value_h) $(valprint_h) $(language_h) \
$(f_lang_h) $(frame_h) $(gdbcore_h) $(command_h) $(block_h)
-gcore.o: gcore.c $(defs_h) $(elf_bfd_h) $(infcall_h) $(inferior_h) \
- $(gdbcore_h) $(objfiles_h) $(symfile_h) $(cli_decode_h) \
- $(gdb_assert_h)
+gcore.o: gcore.c $(defs_h) $(inferior_h) $(target_h) $(command_h)
+gcore-elf.o: gcore-elf.c $(defs_h) $(elf_bfd_h) $(infcall_h) \
+ $(inferior_h) $(gdbcore_h) $(gdb_assert_h)
gdbarch.o: gdbarch.c $(defs_h) $(arch_utils_h) $(gdbcmd_h) $(inferior_h) \
$(symcat_h) $(floatformat_h) $(gdb_assert_h) $(gdb_string_h) \
$(gdb_events_h) $(reggroups_h) $(osabi_h) $(gdb_obstack_h)
Index: config/alpha/alpha-linux.mh
===================================================================
RCS file: /cvs/src/src/gdb/config/alpha/alpha-linux.mh,v
retrieving revision 1.19
diff -u -p -r1.19 alpha-linux.mh
--- config/alpha/alpha-linux.mh 4 Jan 2006 19:33:09 -0000 1.19
+++ config/alpha/alpha-linux.mh 9 Jan 2006 05:41:08 -0000
@@ -1,7 +1,7 @@
# Host: Little-endian Alpha running Linux
NAT_FILE= nm-linux.h
NATDEPFILES= inf-ptrace.o corelow.o alpha-nat.o alpha-linux-nat.o \
- fork-child.o proc-service.o linux-thread-db.o gcore.o \
+ fork-child.o proc-service.o linux-thread-db.o gcore-elf.o \
linux-nat.o linux-fork.o
# The dynamically loaded libthread_db needs access to symbols in the
Index: config/alpha/fbsd.mh
===================================================================
RCS file: /cvs/src/src/gdb/config/alpha/fbsd.mh,v
retrieving revision 1.7
diff -u -p -r1.7 fbsd.mh
--- config/alpha/fbsd.mh 5 Mar 2005 14:36:10 -0000 1.7
+++ config/alpha/fbsd.mh 9 Jan 2006 05:41:08 -0000
@@ -1,6 +1,6 @@
# Host: FreeBSD/alpha
NATDEPFILES= fork-child.o inf-ptrace.o \
fbsd-nat.o alphabsd-nat.o \
- gcore.o solib.o solib-svr4.o solib-legacy.o \
+ gcore-elf.o solib.o solib-svr4.o solib-legacy.o \
corelow.o core-regset.o
NAT_FILE= nm-fbsd.h
Index: config/arm/linux.mh
===================================================================
RCS file: /cvs/src/src/gdb/config/arm/linux.mh,v
retrieving revision 1.17
diff -u -p -r1.17 linux.mh
--- config/arm/linux.mh 4 Jan 2006 19:33:09 -0000 1.17
+++ config/arm/linux.mh 9 Jan 2006 05:41:08 -0000
@@ -2,7 +2,7 @@
NAT_FILE= nm-linux.h
NATDEPFILES= inf-ptrace.o fork-child.o corelow.o \
- core-regset.o arm-linux-nat.o gcore.o \
+ core-regset.o arm-linux-nat.o gcore-elf.o \
proc-service.o linux-thread-db.o linux-nat.o linux-fork.o
LOADLIBES= -ldl -rdynamic
Index: config/i386/fbsd.mh
===================================================================
RCS file: /cvs/src/src/gdb/config/i386/fbsd.mh,v
retrieving revision 1.19
diff -u -p -r1.19 fbsd.mh
--- config/i386/fbsd.mh 1 Oct 2004 17:26:12 -0000 1.19
+++ config/i386/fbsd.mh 9 Jan 2006 05:41:09 -0000
@@ -1,7 +1,7 @@
# Host: FreeBSD/i386
NATDEPFILES= fork-child.o inf-ptrace.o \
fbsd-nat.o i386-nat.o i386bsd-nat.o i386fbsd-nat.o \
- gcore.o bsd-kvm.o
+ gcore-elf.o bsd-kvm.o
NAT_FILE= nm-fbsd.h
LOADLIBES= -lkvm
Index: config/i386/fbsd64.mh
===================================================================
RCS file: /cvs/src/src/gdb/config/i386/fbsd64.mh,v
retrieving revision 1.11
diff -u -p -r1.11 fbsd64.mh
--- config/i386/fbsd64.mh 1 Oct 2004 17:26:13 -0000 1.11
+++ config/i386/fbsd64.mh 9 Jan 2006 05:41:09 -0000
@@ -1,6 +1,6 @@
# Host: FreeBSD/amd64
NATDEPFILES= fork-child.o inf-ptrace.o \
fbsd-nat.o amd64-nat.o amd64bsd-nat.o amd64fbsd-nat.o \
- gcore.o bsd-kvm.o
+ gcore-elf.o bsd-kvm.o
LOADLIBES= -lkvm
Index: config/i386/i386sol2.mh
===================================================================
RCS file: /cvs/src/src/gdb/config/i386/i386sol2.mh,v
retrieving revision 1.11
diff -u -p -r1.11 i386sol2.mh
--- config/i386/i386sol2.mh 31 Oct 2004 15:35:08 -0000 1.11
+++ config/i386/i386sol2.mh 9 Jan 2006 05:41:09 -0000
@@ -1,4 +1,4 @@
# Host: Solaris x86
NATDEPFILES= fork-child.o i386v4-nat.o i386-sol2-nat.o \
- procfs.o proc-api.o proc-events.o proc-flags.o proc-why.o gcore.o
+ procfs.o proc-api.o proc-events.o proc-flags.o proc-why.o gcore-elf.o
NAT_FILE= nm-i386sol2.h
Index: config/i386/i386v42mp.mh
===================================================================
RCS file: /cvs/src/src/gdb/config/i386/i386v42mp.mh,v
retrieving revision 1.9
diff -u -p -r1.9 i386v42mp.mh
--- config/i386/i386v42mp.mh 5 Aug 2004 15:23:53 -0000 1.9
+++ config/i386/i386v42mp.mh 9 Jan 2006 05:41:09 -0000
@@ -11,6 +11,6 @@ NAT_FILE= nm-i386v42mp.h
# consequence, make considers subsequent tab-indented lines to be
# some sort of error.
NATDEPFILES= corelow.o core-regset.o fork-child.o i386v4-nat.o \
- gcore.o solib.o solib-svr4.o solib-legacy.o procfs.o proc-api.o \
+ gcore-elf.o solib.o solib-svr4.o solib-legacy.o procfs.o proc-api.o \
proc-events.o proc-flags.o proc-why.o uw-thread.o
Index: config/i386/linux.mh
===================================================================
RCS file: /cvs/src/src/gdb/config/i386/linux.mh,v
retrieving revision 1.19
diff -u -p -r1.19 linux.mh
--- config/i386/linux.mh 4 Jan 2006 19:33:11 -0000 1.19
+++ config/i386/linux.mh 9 Jan 2006 05:41:09 -0000
@@ -3,7 +3,7 @@
NAT_FILE= nm-linux.h
NATDEPFILES= inf-ptrace.o fork-child.o corelow.o \
core-aout.o i386-nat.o i386-linux-nat.o \
- proc-service.o linux-thread-db.o gcore.o \
+ proc-service.o linux-thread-db.o gcore-elf.o \
linux-nat.o linux-fork.o
# The dynamically loaded libthread_db needs access to symbols in the
Index: config/i386/linux64.mh
===================================================================
RCS file: /cvs/src/src/gdb/config/i386/linux64.mh,v
retrieving revision 1.7
diff -u -p -r1.7 linux64.mh
--- config/i386/linux64.mh 4 Jan 2006 19:33:11 -0000 1.7
+++ config/i386/linux64.mh 9 Jan 2006 05:41:09 -0000
@@ -1,7 +1,7 @@
# Host: GNU/Linux x86-64
NATDEPFILES= inf-ptrace.o fork-child.o \
i386-nat.o amd64-nat.o amd64-linux-nat.o linux-nat.o \
- proc-service.o linux-thread-db.o gcore.o linux-fork.o
+ proc-service.o linux-thread-db.o gcore-elf.o linux-fork.o
NAT_FILE= nm-linux64.h
# The dynamically loaded libthread_db needs access to symbols in the
Index: config/i386/sol2-64.mh
===================================================================
RCS file: /cvs/src/src/gdb/config/i386/sol2-64.mh,v
retrieving revision 1.1
diff -u -p -r1.1 sol2-64.mh
--- config/i386/sol2-64.mh 1 Nov 2004 21:05:56 -0000 1.1
+++ config/i386/sol2-64.mh 9 Jan 2006 05:41:10 -0000
@@ -1,4 +1,4 @@
# Host: Solaris x86_64
NATDEPFILES= fork-child.o amd64-nat.o i386v4-nat.o i386-sol2-nat.o \
- procfs.o proc-api.o proc-events.o proc-flags.o proc-why.o gcore.o
+ procfs.o proc-api.o proc-events.o proc-flags.o proc-why.o gcore-elf.o
NAT_FILE= nm-i386sol2.h
Index: config/ia64/linux.mh
===================================================================
RCS file: /cvs/src/src/gdb/config/ia64/linux.mh,v
retrieving revision 1.20
diff -u -p -r1.20 linux.mh
--- config/ia64/linux.mh 4 Jan 2006 19:33:11 -0000 1.20
+++ config/ia64/linux.mh 9 Jan 2006 05:41:10 -0000
@@ -1,7 +1,7 @@
# Host: Intel IA-64 running GNU/Linux
NAT_FILE= nm-linux.h
-NATDEPFILES= inf-ptrace.o fork-child.o corelow.o gcore.o \
+NATDEPFILES= inf-ptrace.o fork-child.o corelow.o gcore-elf.o \
core-aout.o core-regset.o ia64-linux-nat.o \
proc-service.o linux-thread-db.o linux-nat.o linux-fork.o
Index: config/m32r/linux.mh
===================================================================
RCS file: /cvs/src/src/gdb/config/m32r/linux.mh,v
retrieving revision 1.4
diff -u -p -r1.4 linux.mh
--- config/m32r/linux.mh 4 Jan 2006 19:33:11 -0000 1.4
+++ config/m32r/linux.mh 9 Jan 2006 05:41:10 -0000
@@ -2,7 +2,7 @@
NAT_FILE= nm-linux.h
NATDEPFILES= inf-ptrace.o fork-child.o corelow.o \
- m32r-linux-nat.o gcore.o proc-service.o linux-thread-db.o \
+ m32r-linux-nat.o gcore-elf.o proc-service.o linux-thread-db.o \
linux-nat.o linux-fork.o
LOADLIBES= -ldl -rdynamic
Index: config/m68k/linux.mh
===================================================================
RCS file: /cvs/src/src/gdb/config/m68k/linux.mh,v
retrieving revision 1.18
diff -u -p -r1.18 linux.mh
--- config/m68k/linux.mh 4 Jan 2006 19:33:11 -0000 1.18
+++ config/m68k/linux.mh 9 Jan 2006 05:41:10 -0000
@@ -2,7 +2,7 @@
NAT_FILE= nm-linux.h
NATDEPFILES= inf-ptrace.o fork-child.o \
- corelow.o core-aout.o m68klinux-nat.o gcore.o \
+ corelow.o core-aout.o m68klinux-nat.o gcore-elf.o \
proc-service.o linux-thread-db.o linux-nat.o linux-fork.o
# The dynamically loaded libthread_db needs access to symbols in the
Index: config/mips/linux.mh
===================================================================
RCS file: /cvs/src/src/gdb/config/mips/linux.mh,v
retrieving revision 1.11
diff -u -p -r1.11 linux.mh
--- config/mips/linux.mh 4 Jan 2006 19:33:12 -0000 1.11
+++ config/mips/linux.mh 9 Jan 2006 05:41:10 -0000
@@ -1,7 +1,7 @@
# Host: Linux/MIPS
NAT_FILE= nm-linux.h
NATDEPFILES= inf-ptrace.o fork-child.o mips-linux-nat.o \
- linux-thread-db.o proc-service.o gcore.o \
+ linux-thread-db.o proc-service.o gcore-elf.o \
linux-nat.o linux-fork.o
LOADLIBES = -ldl -rdynamic
Index: config/pa/linux.mh
===================================================================
RCS file: /cvs/src/src/gdb/config/pa/linux.mh,v
retrieving revision 1.7
diff -u -p -r1.7 linux.mh
--- config/pa/linux.mh 4 Jan 2006 19:33:12 -0000 1.7
+++ config/pa/linux.mh 9 Jan 2006 05:41:10 -0000
@@ -1,7 +1,7 @@
# Host: Hewlett-Packard PA-RISC machine, running Linux
XDEPFILES=
NAT_FILE= nm-linux.h
-NATDEPFILES= inf-ptrace.o fork-child.o corelow.o gcore.o \
+NATDEPFILES= inf-ptrace.o fork-child.o corelow.o gcore-elf.o \
core-regset.o hppa-linux-nat.o \
proc-service.o linux-thread-db.o linux-nat.o linux-fork.o
Index: config/powerpc/linux.mh
===================================================================
RCS file: /cvs/src/src/gdb/config/powerpc/linux.mh,v
retrieving revision 1.20
diff -u -p -r1.20 linux.mh
--- config/powerpc/linux.mh 4 Jan 2006 19:33:12 -0000 1.20
+++ config/powerpc/linux.mh 9 Jan 2006 05:41:10 -0000
@@ -5,6 +5,6 @@ XM_CLIBS=
NAT_FILE= nm-linux.h
NATDEPFILES= inf-ptrace.o fork-child.o \
ppc-linux-nat.o proc-service.o linux-thread-db.o \
- gcore.o linux-nat.o linux-fork.o
+ gcore-elf.o linux-nat.o linux-fork.o
LOADLIBES = -ldl -rdynamic
Index: config/powerpc/ppc64-linux.mh
===================================================================
RCS file: /cvs/src/src/gdb/config/powerpc/ppc64-linux.mh,v
retrieving revision 1.9
diff -u -p -r1.9 ppc64-linux.mh
--- config/powerpc/ppc64-linux.mh 4 Jan 2006 19:33:12 -0000 1.9
+++ config/powerpc/ppc64-linux.mh 9 Jan 2006 05:41:11 -0000
@@ -5,7 +5,7 @@ XM_CLIBS=
NAT_FILE= nm-ppc64-linux.h
NATDEPFILES= inf-ptrace.o fork-child.o \
ppc-linux-nat.o proc-service.o linux-thread-db.o \
- gcore.o linux-nat.o linux-fork.o
+ gcore-elf.o linux-nat.o linux-fork.o
# The PowerPC has severe limitations on TOC size, and uses them even
# for non-PIC code. GDB overflows those tables when compiling with
Index: config/s390/s390.mh
===================================================================
RCS file: /cvs/src/src/gdb/config/s390/s390.mh,v
retrieving revision 1.13
diff -u -p -r1.13 s390.mh
--- config/s390/s390.mh 10 Sep 2005 18:11:13 -0000 1.13
+++ config/s390/s390.mh 9 Jan 2006 05:41:11 -0000
@@ -1,5 +1,5 @@
# Host: S390, running Linux
NAT_FILE= nm-linux.h
NATDEPFILES= inf-ptrace.o fork-child.o corelow.o s390-nat.o \
- gcore.o linux-thread-db.o proc-service.o linux-nat.o
+ gcore-elf.o linux-thread-db.o proc-service.o linux-nat.o
LOADLIBES = -ldl -rdynamic
Index: config/sparc/fbsd.mh
===================================================================
RCS file: /cvs/src/src/gdb/config/sparc/fbsd.mh,v
retrieving revision 1.9
diff -u -p -r1.9 fbsd.mh
--- config/sparc/fbsd.mh 15 Jul 2005 20:10:19 -0000 1.9
+++ config/sparc/fbsd.mh 9 Jan 2006 05:41:11 -0000
@@ -1,6 +1,6 @@
# Host: FreeBSD/sparc64
NATDEPFILES= fork-child.o inf-ptrace.o \
fbsd-nat.o sparc-nat.o sparc64-nat.o sparc64fbsd-nat.o \
- gcore.o bsd-kvm.o
+ gcore-elf.o bsd-kvm.o
LOADLIBES= -lkvm
Index: config/sparc/linux.mh
===================================================================
RCS file: /cvs/src/src/gdb/config/sparc/linux.mh,v
retrieving revision 1.17
diff -u -p -r1.17 linux.mh
--- config/sparc/linux.mh 4 Jan 2006 19:33:12 -0000 1.17
+++ config/sparc/linux.mh 9 Jan 2006 05:41:11 -0000
@@ -3,7 +3,7 @@ NAT_FILE= nm-linux.h
NATDEPFILES= sparc-nat.o sparc-sol2-nat.o sparc-linux-nat.o \
corelow.o core-regset.o fork-child.o inf-ptrace.o \
proc-service.o linux-thread-db.o \
- gcore.o linux-nat.o linux-fork.o
+ gcore-elf.o linux-nat.o linux-fork.o
# The dynamically loaded libthread_db needs access to symbols in the
# gdb executable.
Index: config/sparc/linux64.mh
===================================================================
RCS file: /cvs/src/src/gdb/config/sparc/linux64.mh,v
retrieving revision 1.8
diff -u -p -r1.8 linux64.mh
--- config/sparc/linux64.mh 4 Jan 2006 19:33:13 -0000 1.8
+++ config/sparc/linux64.mh 9 Jan 2006 05:41:11 -0000
@@ -4,7 +4,7 @@ NATDEPFILES= sparc-nat.o sparc64-nat.o s
corelow.o core-regset.o \
fork-child.o inf-ptrace.o \
proc-service.o linux-thread-db.o \
- gcore.o linux-nat.o linux-fork.o
+ gcore-elf.o linux-nat.o linux-fork.o
# The dynamically loaded libthread_db needs access to symbols in the
# gdb executable.
Index: config/sparc/sol2.mh
===================================================================
RCS file: /cvs/src/src/gdb/config/sparc/sol2.mh,v
retrieving revision 1.3
diff -u -p -r1.3 sol2.mh
--- config/sparc/sol2.mh 7 Apr 2004 00:15:12 -0000 1.3
+++ config/sparc/sol2.mh 9 Jan 2006 05:41:11 -0000
@@ -1,5 +1,5 @@
# Host: Solaris SPARC & UltraSPARC
NAT_FILE= nm-sol2.h
NATDEPFILES= sparc-sol2-nat.o \
- corelow.o core-regset.o fork-child.o gcore.o \
+ corelow.o core-regset.o fork-child.o gcore-elf.o \
procfs.o proc-api.o proc-events.o proc-flags.o proc-why.o
Index: inf-ttrace.c
===================================================================
RCS file: /cvs/src/src/gdb/inf-ttrace.c,v
retrieving revision 1.18
diff -u -p -r1.18 inf-ttrace.c
--- inf-ttrace.c 23 Dec 2005 20:51:35 -0000 1.18
+++ inf-ttrace.c 9 Jan 2006 05:40:07 -0000
@@ -1116,6 +1116,45 @@ inf_ttrace_pid_to_str (ptid_t ptid)
return normal_pid_to_str (ptid);
}
+
+void
+inf_ttrace_write_core (int pid, const char *filename)
+{
+ int tt_status;
+ char buf[64];
+
+ tt_status = ttrace (TT_PROC_CORE, pid, 0, (uintptr_t) filename, 0, 0);
+
+ if (tt_status == -1)
+ {
+ /* With some versions of HP/UX, specifying the name of the core file
+ is not supported, so this may have been the cause for this failure.
+ Try again without the file name. */
+ tt_status = ttrace (TT_PROC_CORE, pid, 0, 0, 0, 0);
+
+ if (tt_status != -1)
+ {
+ /* Success, so indeed the filename was the source of the problem.
+ Inform the user that the core file was named differently
+ (if indeed the filename is different from the default core
+ file name!) */
+ sprintf (buf, "core.%d", pid);
+ if (strcmp (filename, buf) != 0)
+ {
+ warning ("The Operating System does not allow the dump in %s",
+ filename);
+ filename = buf;
+ }
+ }
+ }
+
+ if (tt_status == -1)
+ perror_with_name ("ttrace:");
+ else
+ fprintf_filtered (gdb_stdout, "Saved corefile %s\n", filename);
+
+}
+
\f
struct target_ops *
@@ -1156,5 +1195,6 @@ _initialize_inf_ttrace (void)
{
#ifdef HAVE_TTRACE
inf_ttrace_page_dict.pagesize = getpagesize();
+ gcore_set_write_core (inf_ttrace_write_core);
#endif
}
[-- Attachment #3: gcore-elf.c --]
[-- Type: text/plain, Size: 13827 bytes --]
/* Generate a core file for the inferior process.
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 "elf-bfd.h"
#include "infcall.h"
#include "inferior.h"
#include "gdbcore.h"
#include "objfiles.h"
#include "gdb_assert.h"
static char *default_gcore_target (void);
static enum bfd_architecture default_gcore_arch (void);
static unsigned long default_gcore_mach (void);
static int gcore_memory_sections (bfd *);
static void gcore_elf_write_core (int pid, const char *corefilename);
/* Generate a core file from the inferior process. */
static void
gcore_elf_write_core (int pid, const char *corefilename)
{
struct cleanup *old_chain;
asection *note_sec = NULL;
bfd *obfd;
void *note_data = NULL;
int note_size = 0;
if (info_verbose)
fprintf_filtered (gdb_stdout,
"Opening corefile '%s' for output.\n", corefilename);
/* Open the output file. */
obfd = bfd_openw (corefilename, default_gcore_target ());
if (!obfd)
error (_("Failed to open '%s' for output."), corefilename);
/* Need a cleanup that will close the file (FIXME: delete it?). */
old_chain = make_cleanup_bfd_close (obfd);
bfd_set_format (obfd, bfd_core);
bfd_set_arch_mach (obfd, default_gcore_arch (), default_gcore_mach ());
/* An external target method must build the notes section. */
note_data = target_make_corefile_notes (obfd, ¬e_size);
/* Create the note section. */
if (note_data != NULL && note_size != 0)
{
note_sec = bfd_make_section_anyway (obfd, "note0");
if (note_sec == NULL)
error (_("Failed to create 'note' section for corefile: %s"),
bfd_errmsg (bfd_get_error ()));
bfd_set_section_vma (obfd, note_sec, 0);
bfd_set_section_flags (obfd, note_sec,
SEC_HAS_CONTENTS | SEC_READONLY | SEC_ALLOC);
bfd_set_section_alignment (obfd, note_sec, 0);
bfd_set_section_size (obfd, note_sec, note_size);
}
/* Now create the memory/load sections. */
if (gcore_memory_sections (obfd) == 0)
error (_("gcore: failed to get corefile memory sections from target."));
/* Write out the contents of the note section. */
if (note_data != NULL && note_size != 0)
{
if (!bfd_set_section_contents (obfd, note_sec, note_data, 0, note_size))
warning (_("writing note section (%s)"), bfd_errmsg (bfd_get_error ()));
}
/* Succeeded. */
fprintf_filtered (gdb_stdout, "Saved corefile %s\n", corefilename);
/* Clean-ups will close the output file and free malloc memory. */
do_cleanups (old_chain);
return;
}
static unsigned long
default_gcore_mach (void)
{
#if 1 /* See if this even matters... */
return 0;
#else
#ifdef TARGET_ARCHITECTURE
const struct bfd_arch_info *bfdarch = TARGET_ARCHITECTURE;
if (bfdarch != NULL)
return bfdarch->mach;
#endif /* TARGET_ARCHITECTURE */
if (exec_bfd == NULL)
error (_("Can't find default bfd machine type (need execfile)."));
return bfd_get_mach (exec_bfd);
#endif /* 1 */
}
static enum bfd_architecture
default_gcore_arch (void)
{
#ifdef TARGET_ARCHITECTURE
const struct bfd_arch_info * bfdarch = TARGET_ARCHITECTURE;
if (bfdarch != NULL)
return bfdarch->arch;
#endif
if (exec_bfd == NULL)
error (_("Can't find bfd architecture for corefile (need execfile)."));
return bfd_get_arch (exec_bfd);
}
static char *
default_gcore_target (void)
{
/* FIXME: This may only work for ELF targets. */
if (exec_bfd == NULL)
return NULL;
else
return bfd_get_target (exec_bfd);
}
/* Derive a reasonable stack segment by unwinding the target stack,
and store its limits in *BOTTOM and *TOP. Return non-zero if
successful. */
static int
derive_stack_segment (bfd_vma *bottom, bfd_vma *top)
{
struct frame_info *fi, *tmp_fi;
gdb_assert (bottom);
gdb_assert (top);
/* Can't succeed without stack and registers. */
if (!target_has_stack || !target_has_registers)
return 0;
/* Can't succeed without current frame. */
fi = get_current_frame ();
if (fi == NULL)
return 0;
/* Save frame pointer of TOS frame. */
*top = get_frame_base (fi);
/* If current stack pointer is more "inner", use that instead. */
if (INNER_THAN (read_sp (), *top))
*top = read_sp ();
/* Find prev-most frame. */
while ((tmp_fi = get_prev_frame (fi)) != NULL)
fi = tmp_fi;
/* Save frame pointer of prev-most frame. */
*bottom = get_frame_base (fi);
/* Now canonicalize their order, so that BOTTOM is a lower address
(as opposed to a lower stack frame). */
if (*bottom > *top)
{
bfd_vma tmp_vma;
tmp_vma = *top;
*top = *bottom;
*bottom = tmp_vma;
}
return 1;
}
/* Derive a reasonable heap segment for ABFD by looking at sbrk and
the static data sections. Store its limits in *BOTTOM and *TOP.
Return non-zero if successful. */
static int
derive_heap_segment (bfd *abfd, bfd_vma *bottom, bfd_vma *top)
{
bfd_vma top_of_data_memory = 0;
bfd_vma top_of_heap = 0;
bfd_size_type sec_size;
struct value *zero, *sbrk;
bfd_vma sec_vaddr;
asection *sec;
gdb_assert (bottom);
gdb_assert (top);
/* This function depends on being able to call a function in the
inferior. */
if (!target_has_execution)
return 0;
/* The following code assumes that the link map is arranged as
follows (low to high addresses):
---------------------------------
| text sections |
---------------------------------
| data sections (including bss) |
---------------------------------
| heap |
--------------------------------- */
for (sec = abfd->sections; sec; sec = sec->next)
{
if (bfd_get_section_flags (abfd, sec) & SEC_DATA
|| strcmp (".bss", bfd_section_name (abfd, sec)) == 0)
{
sec_vaddr = bfd_get_section_vma (abfd, sec);
sec_size = bfd_get_section_size (sec);
if (sec_vaddr + sec_size > top_of_data_memory)
top_of_data_memory = sec_vaddr + sec_size;
}
}
/* Now get the top-of-heap by calling sbrk in the inferior. */
if (lookup_minimal_symbol ("sbrk", NULL, NULL) != NULL)
{
sbrk = find_function_in_inferior ("sbrk");
if (sbrk == NULL)
return 0;
}
else if (lookup_minimal_symbol ("_sbrk", NULL, NULL) != NULL)
{
sbrk = find_function_in_inferior ("_sbrk");
if (sbrk == NULL)
return 0;
}
else
return 0;
zero = value_from_longest (builtin_type_int, 0);
gdb_assert (zero);
sbrk = call_function_by_hand (sbrk, 1, &zero);
if (sbrk == NULL)
return 0;
top_of_heap = value_as_long (sbrk);
/* Return results. */
if (top_of_heap > top_of_data_memory)
{
*bottom = top_of_data_memory;
*top = top_of_heap;
return 1;
}
/* No additional heap space needs to be saved. */
return 0;
}
static void
make_output_phdrs (bfd *obfd, asection *osec, void *ignored)
{
int p_flags = 0;
int p_type;
/* FIXME: these constants may only be applicable for ELF. */
if (strncmp (bfd_section_name (obfd, osec), "load", 4) == 0)
p_type = PT_LOAD;
else
p_type = PT_NOTE;
p_flags |= PF_R; /* Segment is readable. */
if (!(bfd_get_section_flags (obfd, osec) & SEC_READONLY))
p_flags |= PF_W; /* Segment is writable. */
if (bfd_get_section_flags (obfd, osec) & SEC_CODE)
p_flags |= PF_X; /* Segment is executable. */
bfd_record_phdr (obfd, p_type, 1, p_flags, 0, 0, 0, 0, 1, &osec);
}
static int
gcore_create_callback (CORE_ADDR vaddr, unsigned long size,
int read, int write, int exec, void *data)
{
bfd *obfd = data;
asection *osec;
flagword flags = SEC_ALLOC | SEC_HAS_CONTENTS | SEC_LOAD;
/* If the memory segment has no permissions set, ignore it, otherwise
when we later try to access it for read/write, we'll get an error
or jam the kernel. */
if (read == 0 && write == 0 && exec == 0)
{
if (info_verbose)
{
fprintf_filtered (gdb_stdout, "Ignore segment, %s bytes at 0x%s\n",
paddr_d (size), paddr_nz (vaddr));
}
return 0;
}
if (write == 0)
{
/* See if this region of memory lies inside a known file on disk.
If so, we can avoid copying its contents by clearing SEC_LOAD. */
struct objfile *objfile;
struct obj_section *objsec;
ALL_OBJSECTIONS (objfile, objsec)
{
bfd *abfd = objfile->obfd;
asection *asec = objsec->the_bfd_section;
bfd_vma align = (bfd_vma) 1 << bfd_get_section_alignment (abfd,
asec);
bfd_vma start = objsec->addr & -align;
bfd_vma end = (objsec->endaddr + align - 1) & -align;
/* Match if either the entire memory region lies inside the
section (i.e. a mapping covering some pages of a large
segment) or the entire section lies inside the memory region
(i.e. a mapping covering multiple small sections).
This BFD was synthesized from reading target memory,
we don't want to omit that. */
if (((vaddr >= start && vaddr + size <= end)
|| (start >= vaddr && end <= vaddr + size))
&& !(bfd_get_file_flags (abfd) & BFD_IN_MEMORY))
{
flags &= ~SEC_LOAD;
goto keep; /* break out of two nested for loops */
}
}
keep:
flags |= SEC_READONLY;
}
if (exec)
flags |= SEC_CODE;
else
flags |= SEC_DATA;
osec = bfd_make_section_anyway (obfd, "load");
if (osec == NULL)
{
warning (_("Couldn't make gcore segment: %s"),
bfd_errmsg (bfd_get_error ()));
return 1;
}
if (info_verbose)
{
fprintf_filtered (gdb_stdout, "Save segment, %s bytes at 0x%s\n",
paddr_d (size), paddr_nz (vaddr));
}
bfd_set_section_size (obfd, osec, size);
bfd_set_section_vma (obfd, osec, vaddr);
bfd_section_lma (obfd, osec) = 0; /* ??? bfd_set_section_lma? */
bfd_set_section_flags (obfd, osec, flags);
return 0;
}
static int
objfile_find_memory_regions (int (*func) (CORE_ADDR, unsigned long,
int, int, int, void *),
void *obfd)
{
/* Use objfile data to create memory sections. */
struct objfile *objfile;
struct obj_section *objsec;
bfd_vma temp_bottom, temp_top;
/* Call callback function for each objfile section. */
ALL_OBJSECTIONS (objfile, objsec)
{
bfd *ibfd = objfile->obfd;
asection *isec = objsec->the_bfd_section;
flagword flags = bfd_get_section_flags (ibfd, isec);
int ret;
if ((flags & SEC_ALLOC) || (flags & SEC_LOAD))
{
int size = bfd_section_size (ibfd, isec);
int ret;
ret = (*func) (objsec->addr, bfd_section_size (ibfd, isec),
1, /* All sections will be readable. */
(flags & SEC_READONLY) == 0, /* Writable. */
(flags & SEC_CODE) != 0, /* Executable. */
obfd);
if (ret != 0)
return ret;
}
}
/* Make a stack segment. */
if (derive_stack_segment (&temp_bottom, &temp_top))
(*func) (temp_bottom, temp_top - temp_bottom,
1, /* Stack section will be readable. */
1, /* Stack section will be writable. */
0, /* Stack section will not be executable. */
obfd);
/* Make a heap segment. */
if (derive_heap_segment (exec_bfd, &temp_bottom, &temp_top))
(*func) (temp_bottom, temp_top - temp_bottom,
1, /* Heap section will be readable. */
1, /* Heap section will be writable. */
0, /* Heap section will not be executable. */
obfd);
return 0;
}
static void
gcore_copy_callback (bfd *obfd, asection *osec, void *ignored)
{
bfd_size_type size = bfd_section_size (obfd, osec);
struct cleanup *old_chain = NULL;
void *memhunk;
/* Read-only sections are marked; we don't have to copy their contents. */
if ((bfd_get_section_flags (obfd, osec) & SEC_LOAD) == 0)
return;
/* Only interested in "load" sections. */
if (strncmp ("load", bfd_section_name (obfd, osec), 4) != 0)
return;
memhunk = xmalloc (size);
/* ??? This is crap since xmalloc should never return NULL. */
if (memhunk == NULL)
error (_("Not enough memory to create corefile."));
old_chain = make_cleanup (xfree, memhunk);
if (target_read_memory (bfd_section_vma (obfd, osec),
memhunk, size) != 0)
warning (_("Memory read failed for corefile section, %s bytes at 0x%s."),
paddr_d (size), paddr (bfd_section_vma (obfd, osec)));
if (!bfd_set_section_contents (obfd, osec, memhunk, 0, size))
warning (_("Failed to write corefile contents (%s)."),
bfd_errmsg (bfd_get_error ()));
do_cleanups (old_chain); /* Frees MEMHUNK. */
}
static int
gcore_memory_sections (bfd *obfd)
{
if (target_find_memory_regions (gcore_create_callback, obfd) != 0)
return 0; /* FIXME: error return/msg? */
/* Record phdrs for section-to-segment mapping. */
bfd_map_over_sections (obfd, make_output_phdrs, NULL);
/* Copy memory region contents. */
bfd_map_over_sections (obfd, gcore_copy_callback, NULL);
return 1;
}
void
_initialize_gcore_elf (void)
{
gcore_set_write_core (gcore_elf_write_core);
exec_set_find_memory_regions (objfile_find_memory_regions);
}
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: How to implement gcore on pa-hpux ?
2006-01-09 5:59 ` Joel Brobecker
@ 2006-01-22 20:43 ` Daniel Jacobowitz
0 siblings, 0 replies; 11+ messages in thread
From: Daniel Jacobowitz @ 2006-01-22 20:43 UTC (permalink / raw)
To: gdb-patches
On Mon, Jan 09, 2006 at 09:58:48AM +0400, Joel Brobecker wrote:
> > On Fri, Jan 06, 2006 at 02:28:24PM +0400, Joel Brobecker wrote:
> > > It's not as elegant as having a gdbarch or target method, but it's
> > > probably easier to implement. We defer a bit the work that makes this
> > > a method of some vector, but it's not necessary right now. Perhaps
> > > the pragmatic thing to do would be to wait until we need it before
> > > we start worrying about it. Even then, the work is slightly prepared
> > > because we already have the genericity based on the hook.
> > >
> > > What do you guys think?
> >
> > I think that if you need to add new files and rely on magic function
> > names, then you're already past the time when you needed to add things
> > to a vector.
>
> Magic function name? Ouch, my heart ;-).
>
> OK, will try to play with the target vector. For the record, here is
> what I had in mind. I implemented it because it's not that far off the
> road to using the target vector. In this case, it's the gcore module
> itself that holds the method pointer rather than the target vector.
> It's not as powerful, because it is not dynamic the way target vectors
> are, but it's not worse than before.
Thanks. FYI, this patch is a perfect example of why I want you to use
the target vector instead:
> @@ -1156,5 +1195,6 @@ _initialize_inf_ttrace (void)
> {
> #ifdef HAVE_TTRACE
> inf_ttrace_page_dict.pagesize = getpagesize();
> + gcore_set_write_core (inf_ttrace_write_core);
> #endif
> }
inf_ttrace_write_core is only going to work when debugging using
ttrace. Just because it's an HP/UX system doesn't mean we aren't
connected to some non-native target.
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2006-01-22 20:43 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-01-04 17:40 How to implement gcore on pa-hpux ? Joel Brobecker
2006-01-04 18:40 ` Daniel Jacobowitz
2006-01-04 19:12 ` Michael Snyder
2006-01-05 3:24 ` Joel Brobecker
2006-01-06 4:40 ` Michael Snyder
2006-01-06 10:28 ` Joel Brobecker
2006-01-06 13:43 ` Daniel Jacobowitz
2006-01-09 5:59 ` Joel Brobecker
2006-01-22 20:43 ` Daniel Jacobowitz
2006-01-05 4:03 ` Joel Brobecker
2006-01-05 5:02 ` Daniel Jacobowitz
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox