From 981a33093328ee54fb095007f733bea3a1dbe5bf Mon Sep 17 00:00:00 2001 From: Stu Grossman Date: Thu, 7 Oct 1993 16:42:08 +0000 Subject: [PATCH] * 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. --- gdb/ChangeLog | 11 ++++++ gdb/blockframe.c | 47 ++++++++++++-------------- gdb/coff-solib.c | 13 ++++--- gdb/infrun.c | 8 +++-- gdb/remote.c | 88 +++++++++++++++++++++++++++++++++++++++++++----- 5 files changed, 126 insertions(+), 41 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 34a359395b8..b141b9568e1 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 7acbf6a41f2..0d0e89a8d5f 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 d6ea6455ac4..a4bf6c4ebf7 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 37447334eb0..d539ddd5750 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 d3fef8ba12b..9900b3b1ad7 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. */ -- 2.30.2