* Re: [RFA]: Apropos patch
[not found] <Pine.LNX.4.10.10003231428540.30962-100000@propylaea.anduin.com>
@ 2000-03-23 14:54 ` Fernando Nasser
2000-04-01 0:00 ` Fernando Nasser
0 siblings, 1 reply; 3+ messages in thread
From: Fernando Nasser @ 2000-03-23 14:54 UTC (permalink / raw)
To: Daniel Berlin; +Cc: Stan Shebs, gdb-patches
Daniel Berlin wrote:
>
> > the help string should probably be rephrased a bit - use the
> > word "matching" at least, and ideally say "regular expression".
> > Do help rbreak for an example.
>
> howzabout "Search for all commands matching REGEXP"?
It sounds good to me.
--
Fernando Nasser
Red Hat - Toronto E-Mail: fnasser@cygnus.com
2323 Yonge Street, Suite #300 Tel: 416-482-2661 ext. 311
Toronto, Ontario M4P 2C9 Fax: 416-482-6299
From ac131313@cygnus.com Thu Mar 23 15:10:00 2000
From: Andrew Cagney <ac131313@cygnus.com>
To: Fernando Nasser <fnasser@cygnus.com>
Cc: David Whedon <davidw@gordian.com>, gdb-patches@sourceware.cygnus.com
Subject: Re: [REPOST #2] patch: command deprecator
Date: Thu, 23 Mar 2000 15:10:00 -0000
Message-id: <38DAA407.644AA5C1@cygnus.com>
References: <Pine.BSF.3.96.1000229114028.22997B-100000@ares.gordian.com> <38DA9AE8.64AF8635@cygnus.com>
X-SW-Source: 2000-03/msg00516.html
Content-length: 475
Fernando Nasser wrote:
>
> Andrew,
>
> I know that there are 3 new functions (and one test proc) in David's patch and it represents an added functionality, but
> the changes are not so big. Is there any chance that we could safely include those without his assignment?
None, sorry. This isn't a must have for GDB 5 so there isn't the
desperate rush.
If I lifted a page from the latest mills&boon and included in my own
book, would I be infringing on copyright?
Andrew
From dan@cgsoftware.com Thu Mar 23 15:16:00 2000
From: Daniel Berlin <dan@cgsoftware.com>
To: Andrew Cagney <ac131313@cygnus.com>
Cc: Fernando Nasser <fnasser@cygnus.com>, David Whedon <davidw@gordian.com>, gdb-patches@sourceware.cygnus.com
Subject: Re: [REPOST #2] patch: command deprecator
Date: Thu, 23 Mar 2000 15:16:00 -0000
Message-id: <Pine.LNX.4.10.10003231512300.30962-100000@propylaea.anduin.com>
References: <38DAA407.644AA5C1@cygnus.com>
X-SW-Source: 2000-03/msg00517.html
Content-length: 342
>
> None, sorry. This isn't a must have for GDB 5 so there isn't the
> desperate rush.
> If I lifted a page from the latest mills&boon and included in my own
> book, would I be infringing on copyright?
Depends on what your book is for.
(I asked a lawyer before i opened my mouth, to make sure i don't stick my
foot in it).
>
> Andrew
>
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [RFA]: Apropos patch
2000-03-23 14:54 ` [RFA]: Apropos patch Fernando Nasser
@ 2000-04-01 0:00 ` Fernando Nasser
0 siblings, 0 replies; 3+ messages in thread
From: Fernando Nasser @ 2000-04-01 0:00 UTC (permalink / raw)
To: Daniel Berlin; +Cc: Stan Shebs, gdb-patches
Daniel Berlin wrote:
>
> > the help string should probably be rephrased a bit - use the
> > word "matching" at least, and ideally say "regular expression".
> > Do help rbreak for an example.
>
> howzabout "Search for all commands matching REGEXP"?
It sounds good to me.
--
Fernando Nasser
Red Hat - Toronto E-Mail: fnasser@cygnus.com
2323 Yonge Street, Suite #300 Tel: 416-482-2661 ext. 311
Toronto, Ontario M4P 2C9 Fax: 416-482-6299
From msnyder@cygnus.com Sat Apr 01 00:00:00 2000
From: Michael Snyder <msnyder@cygnus.com>
To: gdb-patches@sourceware.cygnus.com
Subject: Re: [RFA] Demangled minsym hash table broken
Date: Sat, 01 Apr 2000 00:00:00 -0000
Message-id: <38E54791.26CF@cygnus.com>
References: <pusd46y7.fsf@dan.resnet.rochester.edu> <20000329195755.A4249@cygnus.com> <k8il44gk.fsf@dan.resnet.rochester.edu>
X-SW-Source: 2000-q1/msg01147.html
Content-length: 946
Daniel Berlin+list.gdb-patches wrote:
>
> Chris Faylor <cgf@cygnus.com> writes:
>
> >
> > Peter Schauer submitted a patch a while ago when he discovered this.
> >
> > It's here: http://sourceware.cygnus.com/ml/gdb-patches/2000-q1/msg00869.html
> >
> > I don't know if your patch is similar but we should probably go with the
> > simplest solution...
> >
>
> I'll work up some testcases and commit his patch, along with some more
> C++ support fixes i've been working on (Should help a lot with the
> people still using STABS).
Daniel, is this the result?
* minsyms.c (add_minsym_to_demangled_hash_table): New function.
(install_minimal_symbols): Fix demangled symbol problems caused
by
using add_minsym_to_hash_table for the demangled names, which is
Just a small nit: this is a static function in minsyms.c, yet
it's declared extern in symtab.h. Gives a new -Wall warning.
Michael
From kevinb@cygnus.com Sat Apr 01 00:00:00 2000
From: Kevin Buettner <kevinb@cygnus.com>
To: gdb-patches@sourceware.cygnus.com
Subject: [PATCH] gdb.base/pointers.c commit
Date: Sat, 01 Apr 2000 00:00:00 -0000
Message-id: <1000321230718.ZM26524@ocotillo.lan>
X-SW-Source: 2000-q1/msg00884.html
Content-length: 1828
I've just committed the change below. (This change was for AIX 4.3.)
* gdb.base/pointers.c (usevar): New function.
(main): Make sure that global variables v_int_pointer2, rptr,
and y are all referenced someplace in the program by calling
usevar() on them. [Some linkers delete symbols which are
never referenced. The space remains, but there's no way to
get a (symbolic) handle on the variable from the debugger.]
Index: gdb.base/pointers.c
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.base/pointers.c,v
retrieving revision 1.1.1.3
diff -u -p -r1.1.1.3 pointers.c
--- pointers.c 1999/08/02 23:46:51 1.1.1.3
+++ pointers.c 2000/03/21 22:59:17
@@ -71,35 +71,28 @@ float ** ptr_to_ptr_to_float;
int y;
+/* Do nothing function used for forcing some of the above variables to
+ be referenced by the program source. If the variables are not
+ referenced, some linkers will remove the symbol from the symbol
+ table making it impossible to refer to the variable in gdb. */
+void usevar (void *var) {}
+
int main ()
{
- void dummy();
- int more_code();
-
- /* Ensure that malloc is a pointer type; avoid use of "void" and any include files. */
- /* extern char *malloc();*/
-
- /* void *malloc(size_t);*/
-
-
-
+ void dummy();
+ int more_code();
+
#ifdef usestubs
set_debug_traps();
breakpoint();
#endif
dummy();
-/* v_int_pointer2 = &v_int_pointer;
- v_unsigned_int_pointer = &v_int;
-
- y = (v_unsigned_int_pointer == v_double_pointer);
-
- x = v_unsigned_int_pointer * v_double_pointer;
-
- v_unsigned_int_pointer = v_double_pointer;
-
- v_unsigned_int_pointer = v_unsigned_int;*/
more_code ();
+
+ usevar (&v_int_pointer2);
+ usevar (&rptr);
+ usevar (&y);
return 0;
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [RFA]: Apropos patch
[not found] <1z52tswd.fsf@dan.resnet.rochester.edu>
@ 2000-03-22 18:28 ` Stan Shebs
0 siblings, 0 replies; 3+ messages in thread
From: Stan Shebs @ 2000-03-22 18:28 UTC (permalink / raw)
To: dan; +Cc: gdb-patches, Fernando Nasser
"Daniel Berlin+list.gdb-patches" wrote:
>
> It includes documentation, a test case (which uses a slightly weird
> regexp so it only finds one thing, and we make sure it only found one
> thing), and all the apropriate changelog entries.
You're going to hate this, but now that I see the example in the manual,
I'm wondering why "prefix:" and "command:" are on separate lines?
Why not just imitate the syntax that comes out of the help command -
set symbol-reloading -- <help string>
show symbol-reloading -- <help string>
Another advantage is that users can then cut-n-paste from the apropos
output more easily.
> Let me know if i can check it in, i believe it needs approval from
> Stan Shebs, and Fernando Nasser.
Just needs approval from one of us, not both! I must confess to being
a bit mystified by the test though - why use "handle" as the match
string, and do I understand right, you're requiring that it be the
first output from apropos?
Stan
From dan@cgsoftware.com Wed Mar 22 19:25:00 2000
From: dan@cgsoftware.com (Daniel Berlin+list.gdb-patches)
To: shebs@apple.com
Cc: dan@cgsoftware.com, gdb-patches@sourceware.cygnus.com, Fernando Nasser <fnasser@cygnus.com>
Subject: Re: [RFA]: Apropos patch
Date: Wed, 22 Mar 2000 19:25:00 -0000
Message-id: <n1nqs6zl.fsf@dan.resnet.rochester.edu>
References: <1z52tswd.fsf@dan.resnet.rochester.edu> <38D9815A.FC4E178E@apple.com>
X-SW-Source: 2000-03/msg00493.html
Content-length: 1985
Stan Shebs <shebs@apple.com> writes:
> "Daniel Berlin+list.gdb-patches" wrote:
> >
> > It includes documentation, a test case (which uses a slightly weird
> > regexp so it only finds one thing, and we make sure it only found one
> > thing), and all the apropriate changelog entries.
>
> You're going to hate this, but now that I see the example in the manual,
> I'm wondering why "prefix:" and "command:" are on separate lines?
No particular reason, i can make it go away if you like, it's simple.
> Why not just imitate the syntax that comes out of the help command -
>
> set symbol-reloading -- <help string>
> show symbol-reloading -- <help string>
I thought of this, but the problem is that the help command only
displays the first line, and the match may not be there. If something
wanted to say, highlight the match, or something, it might not have
appeared in the first line, and thus, not in the output.
>
> Another advantage is that users can then cut-n-paste from the apropos
> output more easily.
>
> > Let me know if i can check it in, i believe it needs approval from
> > Stan Shebs, and Fernando Nasser.
>
> Just needs approval from one of us, not both! I must confess to being
> a bit mystified by the test though - why use "handle" as the match
> string, and do I understand right, you're requiring that it be the
> first output from apropos?
That regexp gets rid of every command with "print" in the name or doc
string, except one. Handle happened to be that one when i got done
removing commands by adding to the regexp, and i figured it should be
available on every single platform (even platforms where signals
basically were ignored when it came to gdb, like BeOS), so why not use
that?
If it come out to be some weird command, i would have changed the regex.
The [^:]+ just makes sure it doesn't catch another command.
It's kinda a crappy test, i'll revise it as soon as some consensus is
reached as to what the output should be like.
>
> Stan
From ezannoni@cygnus.com Wed Mar 22 19:52:00 2000
From: Elena Zannoni <ezannoni@cygnus.com>
To: Elena Zannoni <ezannoni@cygnus.com>
Cc: "Philippe De Muyter" <phdm@macqel.be>, ac131313@cygnus.com (Andrew Cagney), gdb-patches@sourceware.cygnus.com
Subject: Re: HAVE_POLL is not enough - RFA
Date: Wed, 22 Mar 2000 19:52:00 -0000
Message-id: <14553.37904.686232.810079@kwikemart.cygnus.com>
References: <38D5BE1D.7BB02C99@cygnus.com> <200003211559.QAA16996@mail.macqel.be> <14553.28151.426657.410579@kwikemart.cygnus.com>
X-SW-Source: 2000-03/msg00494.html
Content-length: 23076
I committed the following:
Same as original patch except for the USE_POLL thing, and I also added
a comment explaining the reason for the run time test for poll().
Elena
Index: event-loop.c
===================================================================
RCS file: /cvs/src/src/gdb/event-loop.c,v
retrieving revision 1.4
diff -c -r1.4 event-loop.c
*** event-loop.c 2000/03/20 19:59:38 1.4
--- event-loop.c 2000/03/23 03:42:24
***************
*** 25,34 ****
#include "event-top.h"
#ifdef HAVE_POLL
#include <poll.h>
! #else
#include <sys/types.h>
#include <string.h>
- #endif
#include <errno.h>
#include <setjmp.h>
#include <sys/time.h>
--- 25,33 ----
#include "event-top.h"
#ifdef HAVE_POLL
#include <poll.h>
! #endif
#include <sys/types.h>
#include <string.h>
#include <errno.h>
#include <setjmp.h>
#include <sys/time.h>
***************
*** 166,201 ****
/* As of 1999-04-30 only the input file descriptor is registered with the
event loop. */
#ifdef HAVE_POLL
! /* Poll based implementation of the notifier. */
static struct
{
/* Ptr to head of file handler list. */
file_handler *first_file_handler;
/* Ptr to array of pollfd structures. */
struct pollfd *poll_fds;
- /* Number of file descriptors to monitor. */
- int num_fds;
-
/* Timeout in milliseconds for calls to poll(). */
! int timeout;
!
! /* Flag to tell whether the timeout value shuld be used. */
! int timeout_valid;
! }
! gdb_notifier;
!
! #else /* ! HAVE_POLL */
!
! /* Select based implementation of the notifier. */
!
! static struct
! {
! /* Ptr to head of file handler list. */
! file_handler *first_file_handler;
/* Masks to be used in the next call to select.
Bits are set in response to calls to create_file_handler. */
--- 165,191 ----
/* As of 1999-04-30 only the input file descriptor is registered with the
event loop. */
+ /* Do we use poll or select ? */
#ifdef HAVE_POLL
! #define USE_POLL 1
! #else
! #define USE_POLL 0
! #endif /* HAVE_POLL */
+ static unsigned char use_poll = USE_POLL;
+
static struct
{
/* Ptr to head of file handler list. */
file_handler *first_file_handler;
+ #ifdef HAVE_POLL
/* Ptr to array of pollfd structures. */
struct pollfd *poll_fds;
/* Timeout in milliseconds for calls to poll(). */
! int poll_timeout;
! #endif
/* Masks to be used in the next call to select.
Bits are set in response to calls to create_file_handler. */
***************
*** 204,222 ****
/* What file descriptors were found ready by select. */
fd_set ready_masks[3];
! /* Number of valid bits (highest fd value + 1). */
int num_fds;
/* Time structure for calls to select(). */
! struct timeval timeout;
! /* Flag to tell whether the timeout struct should be used. */
int timeout_valid;
}
gdb_notifier;
- #endif /* HAVE_POLL */
-
/* Structure associated with a timer. PROC will be executed at the
first occasion after WHEN. */
struct gdb_timer
--- 194,211 ----
/* What file descriptors were found ready by select. */
fd_set ready_masks[3];
! /* Number of file descriptors to monitor. (for poll) */
! /* Number of valid bits (highest fd value + 1). (for select) */
int num_fds;
/* Time structure for calls to select(). */
! struct timeval select_timeout;
! /* Flag to tell whether the timeout should be used. */
int timeout_valid;
}
gdb_notifier;
/* Structure associated with a timer. PROC will be executed at the
first occasion after WHEN. */
struct gdb_timer
***************
*** 384,390 ****
}
free ((char *) event_ptr);
! /* Now call the procedure associted with the event. */
(*proc) (fd);
return 1;
}
--- 373,379 ----
}
free ((char *) event_ptr);
! /* Now call the procedure associated with the event. */
(*proc) (fd);
return 1;
}
***************
*** 473,482 ****
add_file_handler (int fd, handler_func * proc, gdb_client_data client_data)
{
#ifdef HAVE_POLL
! create_file_handler (fd, POLLIN, proc, client_data);
#else
! create_file_handler (fd, GDB_READABLE | GDB_EXCEPTION, proc, client_data);
#endif
}
/* Add a file handler/descriptor to the list of descriptors we are
--- 462,496 ----
add_file_handler (int fd, handler_func * proc, gdb_client_data client_data)
{
#ifdef HAVE_POLL
! struct pollfd fds;
! #endif
!
! if (use_poll)
! {
! #ifdef HAVE_POLL
! /* Check to see if poll () is usable. If not, we'll switch to
! use select. This can happen on systems like
! m68k-motorola-sys, `poll' cannot be used to wait for `stdin'.
! On m68k-motorola-sysv, tty's are not stream-based and not
! `poll'able.*/
! fds.fd = fd;
! fds.events = POLLIN;
! if (poll (&fds, 1, 0) == 1 && (fds.revents & POLLNVAL))
! use_poll = 0;
! #else
! internal_error ("event-loop.c : use_poll without HAVE_POLL");
! #endif /* HAVE_POLL */
! }
! if (use_poll)
! {
! #ifdef HAVE_POLL
! create_file_handler (fd, POLLIN, proc, client_data);
#else
! internal_error ("event-loop.c : use_poll without HAVE_POLL");
#endif
+ }
+ else
+ create_file_handler (fd, GDB_READABLE | GDB_EXCEPTION, proc, client_data);
}
/* Add a file handler/descriptor to the list of descriptors we are
***************
*** 512,559 ****
file_ptr->ready_mask = 0;
file_ptr->next_file = gdb_notifier.first_file_handler;
gdb_notifier.first_file_handler = file_ptr;
- #ifdef HAVE_POLL
- gdb_notifier.num_fds++;
- #endif
}
file_ptr->proc = proc;
file_ptr->client_data = client_data;
file_ptr->mask = mask;
#ifdef HAVE_POLL
!
! if (gdb_notifier.poll_fds)
! gdb_notifier.poll_fds =
! (struct pollfd *) realloc (gdb_notifier.poll_fds,
! (gdb_notifier.num_fds) * sizeof (struct pollfd));
! else
! gdb_notifier.poll_fds =
! (struct pollfd *) xmalloc (sizeof (struct pollfd));
! (gdb_notifier.poll_fds + gdb_notifier.num_fds - 1)->fd = fd;
! (gdb_notifier.poll_fds + gdb_notifier.num_fds - 1)->events = mask;
! (gdb_notifier.poll_fds + gdb_notifier.num_fds - 1)->revents = 0;
!
! #else /* ! HAVE_POLL */
!
! if (mask & GDB_READABLE)
! FD_SET (fd, &gdb_notifier.check_masks[0]);
! else
! FD_CLR (fd, &gdb_notifier.check_masks[0]);
!
! if (mask & GDB_WRITABLE)
! FD_SET (fd, &gdb_notifier.check_masks[1]);
else
! FD_CLR (fd, &gdb_notifier.check_masks[1]);
! if (mask & GDB_EXCEPTION)
! FD_SET (fd, &gdb_notifier.check_masks[2]);
! else
! FD_CLR (fd, &gdb_notifier.check_masks[2]);
! if (gdb_notifier.num_fds <= fd)
! gdb_notifier.num_fds = fd + 1;
! #endif /* HAVE_POLL */
}
/* Remove the file descriptor FD from the list of monitored fd's:
--- 526,574 ----
file_ptr->ready_mask = 0;
file_ptr->next_file = gdb_notifier.first_file_handler;
gdb_notifier.first_file_handler = file_ptr;
}
file_ptr->proc = proc;
file_ptr->client_data = client_data;
file_ptr->mask = mask;
+ if (use_poll)
+ {
#ifdef HAVE_POLL
! gdb_notifier.num_fds++;
! if (gdb_notifier.poll_fds)
! gdb_notifier.poll_fds =
! (struct pollfd *) realloc (gdb_notifier.poll_fds,
! (gdb_notifier.num_fds) * sizeof (struct pollfd));
! else
! gdb_notifier.poll_fds =
! (struct pollfd *) xmalloc (sizeof (struct pollfd));
! (gdb_notifier.poll_fds + gdb_notifier.num_fds - 1)->fd = fd;
! (gdb_notifier.poll_fds + gdb_notifier.num_fds - 1)->events = mask;
! (gdb_notifier.poll_fds + gdb_notifier.num_fds - 1)->revents = 0;
! #else
! internal_error ("event-loop.c : use_poll without HAVE_POLL");
! #endif /* HAVE_POLL */
! }
else
! {
! if (mask & GDB_READABLE)
! FD_SET (fd, &gdb_notifier.check_masks[0]);
! else
! FD_CLR (fd, &gdb_notifier.check_masks[0]);
! if (mask & GDB_WRITABLE)
! FD_SET (fd, &gdb_notifier.check_masks[1]);
! else
! FD_CLR (fd, &gdb_notifier.check_masks[1]);
! if (mask & GDB_EXCEPTION)
! FD_SET (fd, &gdb_notifier.check_masks[2]);
! else
! FD_CLR (fd, &gdb_notifier.check_masks[2]);
! if (gdb_notifier.num_fds <= fd)
! gdb_notifier.num_fds = fd + 1;
! }
}
/* Remove the file descriptor FD from the list of monitored fd's:
***************
*** 580,630 ****
if (file_ptr == NULL)
return;
#ifdef HAVE_POLL
! /* Create a new poll_fds array by copying every fd's information but the
! one we want to get rid of. */
! new_poll_fds =
! (struct pollfd *) xmalloc ((gdb_notifier.num_fds - 1) * sizeof (struct pollfd));
! for (i = 0, j = 0; i < gdb_notifier.num_fds; i++)
! {
! if ((gdb_notifier.poll_fds + i)->fd != fd)
{
! (new_poll_fds + j)->fd = (gdb_notifier.poll_fds + i)->fd;
! (new_poll_fds + j)->events = (gdb_notifier.poll_fds + i)->events;
! (new_poll_fds + j)->revents = (gdb_notifier.poll_fds + i)->revents;
! j++;
}
}
! free (gdb_notifier.poll_fds);
! gdb_notifier.poll_fds = new_poll_fds;
! gdb_notifier.num_fds--;
!
! #else /* ! HAVE_POLL */
!
! if (file_ptr->mask & GDB_READABLE)
! FD_CLR (fd, &gdb_notifier.check_masks[0]);
! if (file_ptr->mask & GDB_WRITABLE)
! FD_CLR (fd, &gdb_notifier.check_masks[1]);
! if (file_ptr->mask & GDB_EXCEPTION)
! FD_CLR (fd, &gdb_notifier.check_masks[2]);
! /* Find current max fd. */
! if ((fd + 1) == gdb_notifier.num_fds)
! {
! gdb_notifier.num_fds--;
! for (i = gdb_notifier.num_fds; i; i--)
{
! if (FD_ISSET (i - 1, &gdb_notifier.check_masks[0])
! || FD_ISSET (i - 1, &gdb_notifier.check_masks[1])
! || FD_ISSET (i - 1, &gdb_notifier.check_masks[2]))
! break;
}
- gdb_notifier.num_fds = i;
}
- #endif /* HAVE_POLL */
/* Deactivate the file descriptor, by clearing its mask,
so that it will not fire again. */
--- 595,650 ----
if (file_ptr == NULL)
return;
+ if (use_poll)
+ {
#ifdef HAVE_POLL
! /* Create a new poll_fds array by copying every fd's information but the
! one we want to get rid of. */
! new_poll_fds =
! (struct pollfd *) xmalloc ((gdb_notifier.num_fds - 1) * sizeof (struct pollfd));
! for (i = 0, j = 0; i < gdb_notifier.num_fds; i++)
{
! if ((gdb_notifier.poll_fds + i)->fd != fd)
! {
! (new_poll_fds + j)->fd = (gdb_notifier.poll_fds + i)->fd;
! (new_poll_fds + j)->events = (gdb_notifier.poll_fds + i)->events;
! (new_poll_fds + j)->revents = (gdb_notifier.poll_fds + i)->revents;
! j++;
! }
}
+ free (gdb_notifier.poll_fds);
+ gdb_notifier.poll_fds = new_poll_fds;
+ gdb_notifier.num_fds--;
+ #else
+ internal_error ("event-loop.c : use_poll without HAVE_POLL");
+ #endif /* HAVE_POLL */
}
! else
! {
! if (file_ptr->mask & GDB_READABLE)
! FD_CLR (fd, &gdb_notifier.check_masks[0]);
! if (file_ptr->mask & GDB_WRITABLE)
! FD_CLR (fd, &gdb_notifier.check_masks[1]);
! if (file_ptr->mask & GDB_EXCEPTION)
! FD_CLR (fd, &gdb_notifier.check_masks[2]);
! /* Find current max fd. */
! if ((fd + 1) == gdb_notifier.num_fds)
{
! gdb_notifier.num_fds--;
! for (i = gdb_notifier.num_fds; i; i--)
! {
! if (FD_ISSET (i - 1, &gdb_notifier.check_masks[0])
! || FD_ISSET (i - 1, &gdb_notifier.check_masks[1])
! || FD_ISSET (i - 1, &gdb_notifier.check_masks[2]))
! break;
! }
! gdb_notifier.num_fds = i;
}
}
/* Deactivate the file descriptor, by clearing its mask,
so that it will not fire again. */
***************
*** 675,711 ****
/* See if the desired events (mask) match the received
events (ready_mask). */
-
- #ifdef HAVE_POLL
- error_mask = POLLHUP | POLLERR | POLLNVAL;
- mask = (file_ptr->ready_mask & file_ptr->mask) |
- (file_ptr->ready_mask & error_mask);
- error_mask_returned = mask & error_mask;
! if (error_mask_returned != 0)
{
! /* Work in progress. We may need to tell somebody what
! kind of error we had. */
! if (error_mask_returned & POLLHUP)
! printf_unfiltered ("Hangup detected on fd %d\n", file_ptr->fd);
! if (error_mask_returned & POLLERR)
! printf_unfiltered ("Error detected on fd %d\n", file_ptr->fd);
! if (error_mask_returned & POLLNVAL)
! printf_unfiltered ("Invalid or non-`poll'able fd %d\n", file_ptr->fd);
! file_ptr->error = 1;
}
else
- file_ptr->error = 0;
- #else /* ! HAVE_POLL */
- if (file_ptr->ready_mask & GDB_EXCEPTION)
{
! printf_unfiltered ("Exception condition detected on fd %d\n", file_ptr->fd);
! file_ptr->error = 1;
}
- else
- file_ptr->error = 0;
- mask = file_ptr->ready_mask & file_ptr->mask;
- #endif /* HAVE_POLL */
/* Clear the received events for next time around. */
file_ptr->ready_mask = 0;
--- 695,738 ----
/* See if the desired events (mask) match the received
events (ready_mask). */
! if (use_poll)
{
! #ifdef HAVE_POLL
! error_mask = POLLHUP | POLLERR | POLLNVAL;
! mask = (file_ptr->ready_mask & file_ptr->mask) |
! (file_ptr->ready_mask & error_mask);
! error_mask_returned = mask & error_mask;
!
! if (error_mask_returned != 0)
! {
! /* Work in progress. We may need to tell somebody what
! kind of error we had. */
! if (error_mask_returned & POLLHUP)
! printf_unfiltered ("Hangup detected on fd %d\n", file_ptr->fd);
! if (error_mask_returned & POLLERR)
! printf_unfiltered ("Error detected on fd %d\n", file_ptr->fd);
! if (error_mask_returned & POLLNVAL)
! printf_unfiltered ("Invalid or non-`poll'able fd %d\n", file_ptr->fd);
! file_ptr->error = 1;
! }
! else
! file_ptr->error = 0;
! #else
! internal_error ("event-loop.c : use_poll without HAVE_POLL");
! #endif /* HAVE_POLL */
}
else
{
! if (file_ptr->ready_mask & GDB_EXCEPTION)
! {
! printf_unfiltered ("Exception condition detected on fd %d\n", file_ptr->fd);
! file_ptr->error = 1;
! }
! else
! file_ptr->error = 0;
! mask = file_ptr->ready_mask & file_ptr->mask;
}
/* Clear the received events for next time around. */
file_ptr->ready_mask = 0;
***************
*** 731,739 ****
file_handler *file_ptr;
gdb_event *file_event_ptr;
int num_found = 0;
- #ifdef HAVE_POLL
int i;
- #endif
/* Make sure all output is done before getting another event. */
gdb_flush (gdb_stdout);
--- 758,764 ----
***************
*** 742,849 ****
if (gdb_notifier.num_fds == 0)
return -1;
#ifdef HAVE_POLL
! num_found =
! poll (gdb_notifier.poll_fds,
! (unsigned long) gdb_notifier.num_fds,
! gdb_notifier.timeout_valid ? gdb_notifier.timeout : -1);
!
! /* Don't print anything if we get out of poll because of a
! signal. */
! if (num_found == -1 && errno != EINTR)
! perror_with_name ("Poll");
!
! #else /* ! HAVE_POLL */
!
! gdb_notifier.ready_masks[0] = gdb_notifier.check_masks[0];
! gdb_notifier.ready_masks[1] = gdb_notifier.check_masks[1];
! gdb_notifier.ready_masks[2] = gdb_notifier.check_masks[2];
!
! num_found = select (gdb_notifier.num_fds,
! & gdb_notifier.ready_masks[0],
! & gdb_notifier.ready_masks[1],
! & gdb_notifier.ready_masks[2],
! gdb_notifier.timeout_valid
! ? &gdb_notifier.timeout : NULL);
!
! /* Clear the masks after an error from select. */
! if (num_found == -1)
! {
! FD_ZERO (&gdb_notifier.ready_masks[0]);
! FD_ZERO (&gdb_notifier.ready_masks[1]);
! FD_ZERO (&gdb_notifier.ready_masks[2]);
! /* Dont print anything is we got a signal, let gdb handle it. */
! if (errno != EINTR)
! perror_with_name ("Select");
! }
#endif /* HAVE_POLL */
/* Enqueue all detected file events. */
#ifdef HAVE_POLL
! for (i = 0; (i < gdb_notifier.num_fds) && (num_found > 0); i++)
! {
! if ((gdb_notifier.poll_fds + i)->revents)
! num_found--;
! else
! continue;
for (file_ptr = gdb_notifier.first_file_handler;
! file_ptr != NULL;
file_ptr = file_ptr->next_file)
{
! if (file_ptr->fd == (gdb_notifier.poll_fds + i)->fd)
! break;
! }
! if (file_ptr)
! {
/* Enqueue an event only if this is still a new event for
this fd. */
if (file_ptr->ready_mask == 0)
{
file_event_ptr = create_file_event (file_ptr->fd);
async_queue_event (file_event_ptr, TAIL);
}
}
-
- file_ptr->ready_mask = (gdb_notifier.poll_fds + i)->revents;
- }
-
- #else /* ! HAVE_POLL */
-
- for (file_ptr = gdb_notifier.first_file_handler;
- (file_ptr != NULL) && (num_found > 0);
- file_ptr = file_ptr->next_file)
- {
- int mask = 0;
-
- if (FD_ISSET (file_ptr->fd, &gdb_notifier.ready_masks[0]))
- mask |= GDB_READABLE;
- if (FD_ISSET (file_ptr->fd, &gdb_notifier.ready_masks[1]))
- mask |= GDB_WRITABLE;
- if (FD_ISSET (file_ptr->fd, &gdb_notifier.ready_masks[2]))
- mask |= GDB_EXCEPTION;
-
- if (!mask)
- continue;
- else
- num_found--;
-
- /* Enqueue an event only if this is still a new event for
- this fd. */
-
- if (file_ptr->ready_mask == 0)
- {
- file_event_ptr = create_file_event (file_ptr->fd);
- async_queue_event (file_event_ptr, TAIL);
- }
- file_ptr->ready_mask = mask;
}
-
- #endif /* HAVE_POLL */
-
return 0;
}
\f
--- 767,880 ----
if (gdb_notifier.num_fds == 0)
return -1;
+ if (use_poll)
+ {
#ifdef HAVE_POLL
! num_found =
! poll (gdb_notifier.poll_fds,
! (unsigned long) gdb_notifier.num_fds,
! gdb_notifier.timeout_valid ? gdb_notifier.poll_timeout : -1);
!
! /* Don't print anything if we get out of poll because of a
! signal. */
! if (num_found == -1 && errno != EINTR)
! perror_with_name ("Poll");
! #else
! internal_error ("event-loop.c : use_poll without HAVE_POLL");
#endif /* HAVE_POLL */
+ }
+ else
+ {
+ gdb_notifier.ready_masks[0] = gdb_notifier.check_masks[0];
+ gdb_notifier.ready_masks[1] = gdb_notifier.check_masks[1];
+ gdb_notifier.ready_masks[2] = gdb_notifier.check_masks[2];
+ num_found = select (gdb_notifier.num_fds,
+ & gdb_notifier.ready_masks[0],
+ & gdb_notifier.ready_masks[1],
+ & gdb_notifier.ready_masks[2],
+ gdb_notifier.timeout_valid
+ ? &gdb_notifier.select_timeout : NULL);
+
+ /* Clear the masks after an error from select. */
+ if (num_found == -1)
+ {
+ FD_ZERO (&gdb_notifier.ready_masks[0]);
+ FD_ZERO (&gdb_notifier.ready_masks[1]);
+ FD_ZERO (&gdb_notifier.ready_masks[2]);
+ /* Dont print anything is we got a signal, let gdb handle it. */
+ if (errno != EINTR)
+ perror_with_name ("Select");
+ }
+ }
/* Enqueue all detected file events. */
+ if (use_poll)
+ {
#ifdef HAVE_POLL
+ for (i = 0; (i < gdb_notifier.num_fds) && (num_found > 0); i++)
+ {
+ if ((gdb_notifier.poll_fds + i)->revents)
+ num_found--;
+ else
+ continue;
! for (file_ptr = gdb_notifier.first_file_handler;
! file_ptr != NULL;
! file_ptr = file_ptr->next_file)
! {
! if (file_ptr->fd == (gdb_notifier.poll_fds + i)->fd)
! break;
! }
!
! if (file_ptr)
! {
! /* Enqueue an event only if this is still a new event for
! this fd. */
! if (file_ptr->ready_mask == 0)
! {
! file_event_ptr = create_file_event (file_ptr->fd);
! async_queue_event (file_event_ptr, TAIL);
! }
! }
+ file_ptr->ready_mask = (gdb_notifier.poll_fds + i)->revents;
+ }
+ #else
+ internal_error ("event-loop.c : use_poll without HAVE_POLL");
+ #endif /* HAVE_POLL */
+ }
+ else
+ {
for (file_ptr = gdb_notifier.first_file_handler;
! (file_ptr != NULL) && (num_found > 0);
file_ptr = file_ptr->next_file)
{
! int mask = 0;
! if (FD_ISSET (file_ptr->fd, &gdb_notifier.ready_masks[0]))
! mask |= GDB_READABLE;
! if (FD_ISSET (file_ptr->fd, &gdb_notifier.ready_masks[1]))
! mask |= GDB_WRITABLE;
! if (FD_ISSET (file_ptr->fd, &gdb_notifier.ready_masks[2]))
! mask |= GDB_EXCEPTION;
!
! if (!mask)
! continue;
! else
! num_found--;
!
/* Enqueue an event only if this is still a new event for
this fd. */
+
if (file_ptr->ready_mask == 0)
{
file_event_ptr = create_file_event (file_ptr->fd);
async_queue_event (file_event_ptr, TAIL);
}
+ file_ptr->ready_mask = mask;
}
}
return 0;
}
\f
***************
*** 1125,1136 ****
/* Now we need to update the timeout for select/ poll, because we
don't want to sit there while this timer is expiring. */
#ifdef HAVE_POLL
! gdb_notifier.timeout = delta.tv_sec * 1000;
#else
! gdb_notifier.timeout.tv_sec = delta.tv_sec;
! gdb_notifier.timeout.tv_usec = delta.tv_usec;
! #endif
gdb_notifier.timeout_valid = 1;
}
else
--- 1156,1174 ----
/* Now we need to update the timeout for select/ poll, because we
don't want to sit there while this timer is expiring. */
+ if (use_poll)
+ {
#ifdef HAVE_POLL
! gdb_notifier.poll_timeout = delta.tv_sec * 1000;
#else
! internal_error ("event-loop.c : use_poll without HAVE_POLL");
! #endif /* HAVE_POLL */
! }
! else
! {
! gdb_notifier.select_timeout.tv_sec = delta.tv_sec;
! gdb_notifier.select_timeout.tv_usec = delta.tv_usec;
! }
gdb_notifier.timeout_valid = 1;
}
else
Index: ChangeLog
===================================================================
RCS file: /cvs/src/src/gdb/ChangeLog,v
retrieving revision 1.164
diff -c -r1.164 ChangeLog
*** ChangeLog 2000/03/22 20:55:15 1.164
--- ChangeLog 2000/03/23 03:42:24
***************
*** 1,3 ****
--- 1,17 ----
+ 2000-03-22 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ From Philippe De Muyter <phdm@macqel.be>
+
+ * event-loop.c (sys/types.h): File now included unconditionally.
+ (use_poll): New variable..
+ (gdb_notifier): poll- and select-versions merged.
+ (add_file_handler): If HAVE_POLL, check whether poll is usable,
+ and reset `use_poll' if not.
+ (create_file_handler): Select poll- or select-version according to
+ `use_poll'.
+ (delete_file_handler, handle_file_event): Likewise.
+ (gdb_wait_for_event, poll_timers): Likewise.
+
2000-03-22 Peter Schauer <pes@regent.e-technik.tu-muenchen.de>
* printcmd.c (print_scalar_formatted): Truncate addresses to the
From kevinb@cygnus.com Wed Mar 22 20:40:00 2000
From: Kevin Buettner <kevinb@cygnus.com>
To: gdb-patches@sourceware.cygnus.com
Subject: [PATCH] HFA, function descriptor handling for IA-64
Date: Wed, 22 Mar 2000 20:40:00 -0000
Message-id: <1000323044022.ZM30003@ocotillo.lan>
X-SW-Source: 2000-03/msg00495.html
Content-length: 16374
I've just committed the patches below.
BTW, HFAs are Homogeneous Floating-point Aggregates which are merely
structs, or arrays, or arrays of structs, or structs of arrays, etc.
all of which contain the same type of float. The calling conventions
of the IA-64 architecture require that the floating point values
constituting an HFA be passed in floating point registers. Upon
return, HFAs of up to four elements are also returned in registers.
So, e.g, a complex type (which is simply a pair of floating point
values) is passed and returned very efficiently.
* ia64-linux-nat.c: Fix copyright.
(fill_gregset): Minor formatting fix.
* ia64-tdep.c (template_encoding_table, fetch_instruction,
examine_prologue): Clean up some compiler warnings.
(is_float_or_hfa_type_recurse, is_float_or_hfa_type, find_func_descr,
find_global_pointer, find_extant_func_descr): New functions.
(ia64_use_struct_convention, ia64_extract_return_value,
ia64_push_arguments): Handle HFAs.
(ia64_push_arguments): Find (or build) a function descriptor
when given a function address.
(ia64_push_return_address): Moved code for finding the
global pointer into its own function, find_global_pointer ().
Index: ia64-linux-nat.c
===================================================================
RCS file: /cvs/src/src/gdb/ia64-linux-nat.c,v
retrieving revision 1.1
diff -u -p -r1.1 ia64-linux-nat.c
--- ia64-linux-nat.c 2000/03/21 00:11:10 1.1
+++ ia64-linux-nat.c 2000/03/23 04:14:18
@@ -1,5 +1,5 @@
-/* Functions specific to running gdb native on IA64 running Linux.
- Copyright 1999 Free Software Foundation, Inc.
+/* Functions specific to running gdb native on IA-64 running Linux.
+ Copyright 1999, 2000 Free Software Foundation, Inc.
This file is part of GDB.
@@ -394,6 +394,6 @@ fill_gregset (gregsetp, regno)
gregset_t *gregsetp;
int regno;
{
- fprintf(stderr, "Warning: fill_gregset not implemented!\n");
+ fprintf (stderr, "Warning: fill_gregset not implemented!\n");
/* FIXME: Implement later */
}
Index: ia64-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/ia64-tdep.c,v
retrieving revision 1.1
diff -u -p -r1.1 ia64-tdep.c
--- ia64-tdep.c 2000/03/21 00:11:10 1.1
+++ ia64-tdep.c 2000/03/23 04:14:20
@@ -87,8 +87,8 @@ static gdbarch_push_arguments_ftype ia64
static gdbarch_push_return_address_ftype ia64_push_return_address;
static gdbarch_pop_frame_ftype ia64_pop_frame;
static gdbarch_saved_pc_after_call_ftype ia64_saved_pc_after_call;
-
static void ia64_pop_frame_regular (struct frame_info *frame);
+static struct type *is_float_or_hfa_type (struct type *t);
static int ia64_num_regs = 590;
@@ -384,7 +384,7 @@ replace_slotN_contents (unsigned char *b
replace_bit_field (bundle, instr, 5+41*slotnum, 41);
}
-static template_encoding_table[32][3] =
+static enum instruction_type template_encoding_table[32][3] =
{
{ M, I, I }, /* 00 */
{ M, I, I }, /* 01 */
@@ -445,7 +445,7 @@ fetch_instruction (CORE_ADDR addr, instr
template = extract_bit_field (bundle, 0, 5);
*it = template_encoding_table[(int)template][slotnum];
- if (slotnum == 2 || slotnum == 1 && *it == L)
+ if (slotnum == 2 || (slotnum == 1 && *it == L))
addr += 16;
else
addr += (slotnum + 1) * SLOT_MULTIPLIER;
@@ -639,7 +639,6 @@ examine_prologue (CORE_ADDR pc, CORE_ADD
{
CORE_ADDR next_pc;
CORE_ADDR last_prologue_pc = pc;
- int done = 0;
instruction_type it;
long long instr;
int do_fsr_stuff = 0;
@@ -1137,20 +1136,45 @@ ia64_get_saved_register (char *raw_buffe
int
ia64_use_struct_convention (int gcc_p, struct type *type)
{
- /* FIXME: Need to check for HFAs; structures containing (only) up to 8
- floating point values of the same size are returned in floating point
- registers. */
+ struct type *float_elt_type;
+
+ /* HFAs are structures (or arrays) consisting entirely of floating
+ point values of the same length. Up to 8 of these are returned
+ in registers. Don't use the struct convention when this is the
+ case. */
+ float_elt_type = is_float_or_hfa_type (type);
+ if (float_elt_type != NULL
+ && TYPE_LENGTH (type) / TYPE_LENGTH (float_elt_type) <= 8)
+ return 0;
+
+ /* Other structs of length 32 or less are returned in r8-r11.
+ Don't use the struct convention for those either. */
return TYPE_LENGTH (type) > 32;
}
void
ia64_extract_return_value (struct type *type, char *regbuf, char *valbuf)
{
- if (TYPE_CODE (type) == TYPE_CODE_FLT)
- ia64_register_convert_to_virtual (IA64_FR8_REGNUM, type,
- ®buf[REGISTER_BYTE (IA64_FR8_REGNUM)], valbuf);
+ struct type *float_elt_type;
+
+ float_elt_type = is_float_or_hfa_type (type);
+ if (float_elt_type != NULL)
+ {
+ int offset = 0;
+ int regnum = IA64_FR8_REGNUM;
+ int n = TYPE_LENGTH (type) / TYPE_LENGTH (float_elt_type);
+
+ while (n-- > 0)
+ {
+ ia64_register_convert_to_virtual (regnum, float_elt_type,
+ ®buf[REGISTER_BYTE (regnum)], valbuf + offset);
+ offset += TYPE_LENGTH (float_elt_type);
+ regnum++;
+ }
+ }
else
- memcpy (valbuf, ®buf[REGISTER_BYTE (IA64_GR8_REGNUM)], TYPE_LENGTH (type));
+ memcpy (valbuf, ®buf[REGISTER_BYTE (IA64_GR8_REGNUM)],
+ TYPE_LENGTH (type));
}
/* FIXME: Turn this into a stack of some sort. Unfortunately, something
@@ -1219,7 +1243,6 @@ ia64_init_extra_frame_info (int fromleaf
else
{
struct frame_info *frn = frame->next;
- CORE_ADDR cfm_addr;
FRAME_INIT_SAVED_REGS (frn);
@@ -1242,9 +1265,200 @@ ia64_init_extra_frame_info (int fromleaf
frame->extra_info->mem_stack_frame_size = -1; /* Not yet determined */
frame->extra_info->fp_reg = 0;
}
+
+static int
+is_float_or_hfa_type_recurse (struct type *t, struct type **etp)
+{
+ switch (TYPE_CODE (t))
+ {
+ case TYPE_CODE_FLT:
+ if (*etp)
+ return TYPE_LENGTH (*etp) == TYPE_LENGTH (t);
+ else
+ {
+ *etp = t;
+ return 1;
+ }
+ break;
+ case TYPE_CODE_ARRAY:
+ return is_float_or_hfa_type_recurse (TYPE_TARGET_TYPE (t), etp);
+ break;
+ case TYPE_CODE_STRUCT:
+ {
+ int i;
+
+ for (i = 0; i < TYPE_NFIELDS (t); i++)
+ if (!is_float_or_hfa_type_recurse (TYPE_FIELD_TYPE (t, i), etp))
+ return 0;
+ return 1;
+ }
+ break;
+ default:
+ return 0;
+ break;
+ }
+}
+
+/* Determine if the given type is one of the floating point types or
+ and HFA (which is a struct, array, or combination thereof whose
+ bottom-most elements are all of the same floating point type.) */
+
+static struct type *
+is_float_or_hfa_type (struct type *t)
+{
+ struct type *et = 0;
+
+ return is_float_or_hfa_type_recurse (t, &et) ? et : 0;
+}
+
+
+/* Attempt to find (and return) the global pointer for the given
+ function.
+
+ This is a rather nasty bit of code searchs for the .dynamic section
+ in the objfile corresponding to the pc of the function we're trying
+ to call. Once it finds the addresses at which the .dynamic section
+ lives in the child process, it scans the Elf64_Dyn entries for a
+ DT_PLTGOT tag. If it finds one of these, the corresponding
+ d_un.d_ptr value is the global pointer. */
+
+static CORE_ADDR
+find_global_pointer (CORE_ADDR faddr)
+{
+ struct partial_symtab *pst;
+
+ pst = find_pc_psymtab (faddr);
+ if (pst != NULL)
+ {
+ struct obj_section *osect;
+
+ ALL_OBJFILE_OSECTIONS (pst->objfile, osect)
+ {
+ if (strcmp (osect->the_bfd_section->name, ".dynamic") == 0)
+ break;
+ }
+
+ if (osect < pst->objfile->sections_end)
+ {
+ CORE_ADDR addr;
+
+ addr = osect->addr;
+ while (addr < osect->endaddr)
+ {
+ int status;
+ LONGEST tag;
+ char buf[8];
+
+ status = target_read_memory (addr, buf, sizeof (buf));
+ if (status != 0)
+ break;
+ tag = extract_signed_integer (buf, sizeof (buf));
+
+ if (tag == DT_PLTGOT)
+ {
+ CORE_ADDR global_pointer;
+
+ status = target_read_memory (addr + 8, buf, sizeof (buf));
+ if (status != 0)
+ break;
+ global_pointer = extract_address (buf, sizeof (buf));
+
+ /* The payoff... */
+ return global_pointer;
+ }
+
+ if (tag == DT_NULL)
+ break;
+
+ addr += 16;
+ }
+ }
+ }
+ return 0;
+}
+
+/* Given a function's address, attempt to find (and return) the
+ corresponding (canonical) function descriptor. Return 0 if
+ not found. */
+static CORE_ADDR
+find_extant_func_descr (CORE_ADDR faddr)
+{
+ struct partial_symtab *pst;
+ struct obj_section *osect;
+
+ /* Return early if faddr is already a function descriptor */
+ osect = find_pc_section (faddr);
+ if (osect && strcmp (osect->the_bfd_section->name, ".opd") == 0)
+ return faddr;
+
+ pst = find_pc_psymtab (faddr);
+ if (pst != NULL)
+ {
+ ALL_OBJFILE_OSECTIONS (pst->objfile, osect)
+ {
+ if (strcmp (osect->the_bfd_section->name, ".opd") == 0)
+ break;
+ }
+
+ if (osect < pst->objfile->sections_end)
+ {
+ CORE_ADDR addr;
+
+ addr = osect->addr;
+ while (addr < osect->endaddr)
+ {
+ int status;
+ LONGEST faddr2;
+ char buf[8];
+
+ status = target_read_memory (addr, buf, sizeof (buf));
+ if (status != 0)
+ break;
+ faddr2 = extract_signed_integer (buf, sizeof (buf));
+
+ if (faddr == faddr2)
+ return addr;
+
+ addr += 16;
+ }
+ }
+ }
+ return 0;
+}
+
+/* Attempt to find a function descriptor corresponding to the
+ given address. If none is found, construct one on the
+ stack using the address at fdaptr */
+
+static CORE_ADDR
+find_func_descr (CORE_ADDR faddr, CORE_ADDR *fdaptr)
+{
+ CORE_ADDR fdesc;
+
+ fdesc = find_extant_func_descr (faddr);
+
+ if (fdesc == 0)
+ {
+ CORE_ADDR global_pointer;
+ char buf[16];
+
+ fdesc = *fdaptr;
+ *fdaptr += 16;
-#define ROUND_UP(n,a) (((n)+(a)-1) & ~((a)-1))
+ global_pointer = find_global_pointer (faddr);
+ if (global_pointer == 0)
+ global_pointer = read_register (IA64_GR1_REGNUM);
+
+ store_address (buf, 8, faddr);
+ store_address (buf + 8, 8, global_pointer);
+
+ write_memory (fdesc, buf, 16);
+ }
+
+ return fdesc;
+}
+
CORE_ADDR
ia64_push_arguments (int nargs, value_ptr *args, CORE_ADDR sp,
int struct_return, CORE_ADDR struct_addr)
@@ -1253,11 +1467,12 @@ ia64_push_arguments (int nargs, value_pt
value_ptr arg;
struct type *type;
int len, argoffset;
- int nslots, rseslots, memslots, slotnum;
+ int nslots, rseslots, memslots, slotnum, nfuncargs;
int floatreg;
- CORE_ADDR bsp, cfm, pfs, new_bsp;
+ CORE_ADDR bsp, cfm, pfs, new_bsp, funcdescaddr;
nslots = 0;
+ nfuncargs = 0;
/* Count the number of slots needed for the arguments */
for (argno = 0; argno < nargs; argno++)
{
@@ -1270,12 +1485,17 @@ ia64_push_arguments (int nargs, value_pt
if (len > 8 && (nslots & 1))
nslots++;
+ if (TYPE_CODE (type) == TYPE_CODE_FUNC)
+ nfuncargs++;
+
nslots += (len + 7) / 8;
}
+ /* Divvy up the slots between the RSE and the memory stack */
rseslots = (nslots > 8) ? 8 : nslots;
memslots = nslots - rseslots;
+ /* Allocate a new RSE frame */
cfm = read_register (IA64_CFM_REGNUM);
bsp = read_register (IA64_BSP_REGNUM);
@@ -1292,18 +1512,51 @@ ia64_push_arguments (int nargs, value_pt
cfm |= rseslots;
write_register (IA64_CFM_REGNUM, cfm);
-
-
- sp = sp - 16 - memslots * 8;
+ /* We will attempt to find function descriptors in the .opd segment,
+ but if we can't we'll construct them ourselves. That being the
+ case, we'll need to reserve space on the stack for them. */
+ funcdescaddr = sp - nfuncargs * 16;
+ funcdescaddr &= ~0xfLL;
+
+ /* Adjust the stack pointer to it's new value. The calling conventions
+ require us to have 16 bytes of scratch, plus whatever space is
+ necessary for the memory slots and our function descriptors */
+ sp = sp - 16 - (memslots + nfuncargs) * 8;
sp &= ~0xfLL; /* Maintain 16 byte alignment */
+ /* Place the arguments where they belong. The arguments will be
+ either placed in the RSE backing store or on the memory stack.
+ In addition, floating point arguments or HFAs are placed in
+ floating point registers. */
slotnum = 0;
floatreg = IA64_FR8_REGNUM;
for (argno = 0; argno < nargs; argno++)
{
+ struct type *float_elt_type;
+
arg = args[argno];
type = check_typedef (VALUE_TYPE (arg));
len = TYPE_LENGTH (type);
+
+ /* Special handling for function parameters */
+ if (len == 8
+ && TYPE_CODE (type) == TYPE_CODE_PTR
+ && TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_FUNC)
+ {
+ char val_buf[8];
+
+ store_address (val_buf, 8,
+ find_func_descr (extract_address (VALUE_CONTENTS (arg), 8),
+ &funcdescaddr));
+ if (slotnum < rseslots)
+ write_memory (rse_address_add (bsp, slotnum), val_buf, 8);
+ else
+ write_memory (sp + 16 + 8 * (slotnum - rseslots), val_buf, 8);
+ slotnum++;
+ continue;
+ }
+
+ /* Normal slots */
if (len > 8 && (slotnum & 1))
slotnum++;
argoffset = 0;
@@ -1323,22 +1576,36 @@ ia64_push_arguments (int nargs, value_pt
len -= 8;
slotnum++;
}
- if (TYPE_CODE (type) == TYPE_CODE_FLT && floatreg < IA64_FR16_REGNUM)
- {
- ia64_register_convert_to_raw (type, floatreg, VALUE_CONTENTS (arg),
- ®isters[REGISTER_BYTE (floatreg)]);
- floatreg++;
+
+ /* Handle floating point types (including HFAs) */
+ float_elt_type = is_float_or_hfa_type (type);
+ if (float_elt_type != NULL)
+ {
+ argoffset = 0;
+ len = TYPE_LENGTH (type);
+ while (len > 0 && floatreg < IA64_FR16_REGNUM)
+ {
+ ia64_register_convert_to_raw (
+ float_elt_type,
+ floatreg,
+ VALUE_CONTENTS (arg) + argoffset,
+ ®isters[REGISTER_BYTE (floatreg)]);
+ floatreg++;
+ argoffset += TYPE_LENGTH (float_elt_type);
+ len -= TYPE_LENGTH (float_elt_type);
+ }
}
}
+ /* Store the struct return value in r8 if necessary. */
if (struct_return)
{
store_address (®isters[REGISTER_BYTE (IA64_GR8_REGNUM)],
REGISTER_RAW_SIZE (IA64_GR8_REGNUM),
struct_addr);
}
-
+ /* Sync gdb's idea of what the registers are with the target. */
target_store_registers (-1);
/* FIXME: This doesn't belong here! Instead, SAVE_DUMMY_FRAME_TOS needs
@@ -1359,64 +1626,10 @@ ia64_push_arguments (int nargs, value_pt
CORE_ADDR
ia64_push_return_address (CORE_ADDR pc, CORE_ADDR sp)
{
- struct partial_symtab *pst;
-
- /* Attempt to determine and set global pointer (r1) for this pc.
-
- This rather nasty bit of code searchs for the .dynamic section
- in the objfile corresponding to the pc of the function we're
- trying to call. Once it finds the addresses at which the .dynamic
- section lives in the child process, it scans the Elf64_Dyn entries
- for a DT_PLTGOT tag. If it finds one of these, the corresponding
- d_un.d_ptr value is the global pointer. */
- pst = find_pc_psymtab (pc);
- if (pst != NULL)
- {
- struct obj_section *osect;
-
- ALL_OBJFILE_OSECTIONS (pst->objfile, osect)
- {
- if (strcmp (osect->the_bfd_section->name, ".dynamic") == 0)
- break;
- }
-
- if (osect < pst->objfile->sections_end)
- {
- CORE_ADDR addr;
-
- addr = osect->addr;
- while (addr < osect->endaddr)
- {
- int status;
- LONGEST tag;
- char buf[8];
+ CORE_ADDR global_pointer = find_global_pointer (pc);
- status = target_read_memory (addr, buf, sizeof (buf));
- if (status != 0)
- break;
- tag = extract_signed_integer (buf, sizeof (buf));
-
- if (tag == DT_PLTGOT)
- {
- CORE_ADDR global_pointer;
-
- status = target_read_memory (addr + 8, buf, sizeof (buf));
- if (status != 0)
- break;
- global_pointer = extract_address (buf, sizeof (buf));
-
- /* The payoff... */
- write_register (IA64_GR1_REGNUM, global_pointer);
- break;
- }
-
- if (tag == DT_NULL)
- break;
-
- addr += 16;
- }
- }
- }
+ if (global_pointer != 0)
+ write_register (IA64_GR1_REGNUM, global_pointer);
write_register (IA64_BR0_REGNUM, CALL_DUMMY_ADDRESS ());
return sp;
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2000-04-01 0:00 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
[not found] <Pine.LNX.4.10.10003231428540.30962-100000@propylaea.anduin.com>
2000-03-23 14:54 ` [RFA]: Apropos patch Fernando Nasser
2000-04-01 0:00 ` Fernando Nasser
[not found] <1z52tswd.fsf@dan.resnet.rochester.edu>
2000-03-22 18:28 ` Stan Shebs
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox