aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog11
-rw-r--r--gdb/blockframe.c47
-rw-r--r--gdb/coff-solib.c13
-rw-r--r--gdb/infrun.c8
-rw-r--r--gdb/remote.c88
5 files changed, 126 insertions, 41 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 34a3593..b141b95 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,14 @@
+Thu Oct 7 09:22:04 1993 Stu Grossman (grossman at cygnus.com)
+
+ * blockframe.c (find_pc_partial_function): Fix handling for PCs
+ beyond the end of the last function in an objfile.
+ * coff-solib.c (coff_solib_add): Use BFD to get fields from .lib
+ section.
+ * infrun.c (wait_for_inferior): Modify test for subroutine entry
+ to include pc out of bounds of the previous function.
+ * remote.c (remote_wait): Use strtoul for parsing 'N' message.
+ Add code to relocate symfile_objfile->sections.
+
Thu Oct 7 06:22:43 1993 Jim Kingdon (kingdon@lioth.cygnus.com)
* config/sparc/sun4os4.mh: Add comment saying why we don't use
diff --git a/gdb/blockframe.c b/gdb/blockframe.c
index 7acbf6a..0d0e89a 100644
--- a/gdb/blockframe.c
+++ b/gdb/blockframe.c
@@ -624,6 +624,7 @@ find_pc_partial_function (pc, name, address, endaddr)
struct symbol *f;
struct minimal_symbol *msymbol;
struct partial_symbol *psb;
+ struct obj_section *sec;
if (pc >= cache_pc_function_low && pc < cache_pc_function_high)
goto return_cached_value;
@@ -688,6 +689,16 @@ find_pc_partial_function (pc, name, address, endaddr)
}
}
+ /* Not in the normal symbol tables, see if the pc is in a known section.
+ If it's not, then give up. This ensures that anything beyond the end
+ of the text seg doesn't appear to be part of the last function in the
+ text segment. */
+
+ sec = find_pc_section (pc);
+
+ if (!sec)
+ msymbol = NULL;
+
/* Must be in the minimal symbol table. */
if (msymbol == NULL)
{
@@ -701,40 +712,26 @@ find_pc_partial_function (pc, name, address, endaddr)
return 0;
}
- /* I believe the purpose of this check is to make sure that anything
- beyond the end of the text segment does not appear as part of the
- last function of the text segment. It assumes that there is something
- other than a mst_text symbol after the text segment. It is broken in
- various cases, so anything relying on this behavior (there might be
- some places) should be using find_pc_section or some such instead. */
+ /* See if we're in a transfer table for Sun shared libs. */
+
if (msymbol -> type == mst_text)
cache_pc_function_low = SYMBOL_VALUE_ADDRESS (msymbol);
else
/* It is a transfer table for Sun shared libraries. */
cache_pc_function_low = pc - FUNCTION_START_OFFSET;
+
cache_pc_function_name = SYMBOL_NAME (msymbol);
- if (SYMBOL_NAME (msymbol + 1) != NULL)
- /* This might be part of a different segment, which might be a bad
- idea. Perhaps we should be using the smaller of this address or the
- endaddr from find_pc_section. */
+ /* Use the lesser of the next minimal symbol, or the end of the section, as
+ the end of the function. */
+
+ if (SYMBOL_NAME (msymbol + 1) != NULL
+ && SYMBOL_VALUE_ADDRESS (msymbol + 1) < sec->endaddr)
cache_pc_function_high = SYMBOL_VALUE_ADDRESS (msymbol + 1);
else
- {
- /* We got the start address from the last msymbol in the objfile.
- So the end address is the end of the section. */
- struct obj_section *sec;
-
- sec = find_pc_section (pc);
- if (sec == NULL)
- {
- /* Don't know if this can happen but if it does, then just say
- that the function is 1 byte long. */
- cache_pc_function_high = cache_pc_function_low + 1;
- }
- else
- cache_pc_function_high = sec->endaddr;
- }
+ /* We got the start address from the last msymbol in the objfile.
+ So the end address is the end of the section. */
+ cache_pc_function_high = sec->endaddr;
return_cached_value:
if (address)
diff --git a/gdb/coff-solib.c b/gdb/coff-solib.c
index d6ea645..a4bf6c4 100644
--- a/gdb/coff-solib.c
+++ b/gdb/coff-solib.c
@@ -61,8 +61,8 @@ coff_solib_add (arg_string, from_tty, target)
unsigned char *lib;
struct libent
{
- long len;
- long unk;
+ bfd_byte len[4];
+ bfd_byte unk[4];
char filename[1];
};
@@ -76,10 +76,13 @@ coff_solib_add (arg_string, from_tty, target)
{
struct libent *ent;
struct objfile *objfile;
+ int len;
ent = (struct libent *)lib;
- if (ent->len <= 0)
+ len = bfd_get_32 (exec_bfd, ent->len);
+
+ if (len <= 0)
break;
objfile = symbol_file_add (ent->filename, from_tty,
@@ -87,8 +90,8 @@ coff_solib_add (arg_string, from_tty, target)
0, /* not mainline */
0, /* not mapped */
0); /* Not readnow */
- libsize -= ent->len * 4;
- lib += ent->len * 4;
+ libsize -= len * 4;
+ lib += len * 4;
}
}
}
diff --git a/gdb/infrun.c b/gdb/infrun.c
index 3744733..d539ddd 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -475,6 +475,7 @@ wait_for_inferior ()
int random_signal;
CORE_ADDR stop_sp = 0;
CORE_ADDR stop_func_start;
+ CORE_ADDR stop_func_end;
char *stop_func_name;
CORE_ADDR prologue_pc = 0, tmp;
struct symtab_and_line sal;
@@ -649,11 +650,12 @@ wait_for_inferior ()
stop_frame_address = FRAME_FP (get_current_frame ());
stop_sp = read_sp ();
stop_func_start = 0;
+ stop_func_end = 0;
stop_func_name = 0;
/* Don't care about return value; stop_func_start and stop_func_name
will both be 0 if it doesn't work. */
find_pc_partial_function (stop_pc, &stop_func_name, &stop_func_start,
- (CORE_ADDR *)NULL);
+ &stop_func_end);
stop_func_start += FUNCTION_START_OFFSET;
another_trap = 0;
bpstat_clear (&stop_bpstat);
@@ -1015,7 +1017,9 @@ wait_for_inferior ()
/* ==> See comments at top of file on this algorithm. <==*/
- if ((stop_pc == stop_func_start
+ if ((stop_pc < stop_func_start
+ || stop_pc >= stop_func_end
+ || stop_pc == stop_func_start
|| IN_SOLIB_TRAMPOLINE (stop_pc, stop_func_name))
&& (stop_func_start != prev_func_start
|| prologue_pc != stop_func_start
diff --git a/gdb/remote.c b/gdb/remote.c
index d3fef8b..9900b3b 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -209,6 +209,9 @@ remote_interrupt PARAMS ((int signo));
static void
remote_interrupt_twice PARAMS ((int signo));
+static void
+interrupt_query PARAMS ((void));
+
extern struct target_ops remote_ops; /* Forward decl */
/* This was 5 seconds, which is a long time to sit and wait.
@@ -424,18 +427,26 @@ remote_interrupt_twice (signo)
{
signal (signo, ofunc);
+ interrupt_query ();
+
+ signal (signo, remote_interrupt);
+}
+
+/* Ask the user what to do when an interrupt is received. */
+
+static void
+interrupt_query ()
+{
target_terminal_ours ();
+
if (query ("Interrupted while waiting for the program.\n\
Give up (and stop debugging it)? "))
{
target_mourn_inferior ();
return_to_top_level (RETURN_QUIT);
}
- else
- {
- signal (signo, remote_interrupt);
- target_terminal_inferior ();
- }
+
+ target_terminal_inferior ();
}
/* Wait until the remote machine stops, then return,
@@ -521,19 +532,25 @@ remote_wait (status)
new data address, and BB is the new bss address. This is
used by the NLM stub; gdb may see more sections. */
p = &buf[3];
- text_addr = strtol (p, &p1, 16);
+ text_addr = strtoul (p, &p1, 16);
if (p1 == p || *p1 != ';')
warning ("Malformed relocation packet: Packet '%s'", buf);
p = p1 + 1;
- data_addr = strtol (p, &p1, 16);
+ data_addr = strtoul (p, &p1, 16);
if (p1 == p || *p1 != ';')
warning ("Malformed relocation packet: Packet '%s'", buf);
p = p1 + 1;
- bss_addr = strtol (p, &p1, 16);
+ bss_addr = strtoul (p, &p1, 16);
if (p1 == p)
warning ("Malformed relocation packet: Packet '%s'", buf);
- if (symfile_objfile != NULL)
+ if (symfile_objfile != NULL
+ && (ANOFFSET (symfile_objfile->section_offsets,
+ SECT_OFF_TEXT) != text_addr
+ || ANOFFSET (symfile_objfile->section_offsets,
+ SECT_OFF_DATA) != data_addr
+ || ANOFFSET (symfile_objfile->section_offsets,
+ SECT_OFF_BSS) != bss_addr))
{
struct section_offsets *offs;
@@ -562,6 +579,36 @@ remote_wait (status)
ANOFFSET (offs, SECT_OFF_BSS) = bss_addr;
objfile_relocate (symfile_objfile, offs);
+ {
+ struct obj_section *s;
+ bfd *bfd;
+
+ bfd = symfile_objfile->obfd;
+
+ for (s = symfile_objfile->sections;
+ s < symfile_objfile->sections_end; ++s)
+ {
+ flagword flags;
+
+ flags = bfd_get_section_flags (bfd, s->sec_ptr);
+
+ if (flags & SEC_CODE)
+ {
+ s->addr += text_addr;
+ s->endaddr += text_addr;
+ }
+ else if (flags & (SEC_DATA | SEC_LOAD))
+ {
+ s->addr += data_addr;
+ s->endaddr += data_addr;
+ }
+ else if (flags & SEC_ALLOC)
+ {
+ s->addr += bss_addr;
+ s->endaddr += bss_addr;
+ }
+ }
+ }
}
break;
}
@@ -603,6 +650,17 @@ remote_fetch_registers (regno)
/* Unimplemented registers read as all bits zero. */
memset (regs, 0, REGISTER_BYTES);
+ /* We can get out of synch in various cases. If the first character
+ in the buffer is not a hex character, assume that has happened
+ and try to fetch another packet to read. */
+ while ((buf[0] < '0' || buf[0] > '9')
+ && (buf[0] < 'a' || buf[0] > 'f'))
+ {
+ if (sr_get_debug () > 0)
+ printf ("Bad register packet; fetching a new packet\n");
+ getpkt (buf, 0);
+ }
+
/* Reply describes registers byte by byte, each byte encoded as two
hex characters. Suck them all up, then supply them to the
register cacheing/storage mechanism. */
@@ -972,6 +1030,12 @@ putpkt (buf)
}
break; /* Here to retransmit */
}
+
+ if (quit_flag)
+ {
+ quit_flag = 0;
+ interrupt_query ();
+ }
}
}
@@ -994,6 +1058,12 @@ getpkt (buf, forever)
while (1)
{
+ if (quit_flag)
+ {
+ quit_flag = 0;
+ interrupt_query ();
+ }
+
/* This can loop forever if the remote side sends us characters
continuously, but if it pauses, we'll get a zero from readchar
because of timeout. Then we'll count that as a retry. */