* 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.
This commit is contained in:
Stu Grossman 1993-10-07 16:42:08 +00:00
parent 50a5403978
commit 981a330933
5 changed files with 126 additions and 41 deletions

View File

@ -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

View File

@ -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)

View File

@ -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;
}
}
}

View File

@ -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

View File

@ -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. */