From 72bba93b85e2e8c887df447c4237d0e7c21d07d8 Mon Sep 17 00:00:00 2001 From: Stu Grossman Date: Mon, 21 Mar 1994 19:57:38 +0000 Subject: [PATCH] Mon Mar 21 11:02:51 1994 Stu Grossman (grossman at cygnus.com) * alpha-tdep.c: Gobs of changes (many imported from mips-tdep) to improve remote debugging efficiency. Also fixed problems with doing function calls for programs with no entry points. * infcmd.c (run_stack_dummy): Use CALL_DUMMY_ADDRESS instead of entry_point_address. * inferior.h (PC_IN_CALL_DUMMY): ditto. * mdebugread.c (parse_symbol, parse_procedure, parse_external, parse_lines): Pass section_offsets info to these routines so that we can relocate symbol table entries upon readin. * (psymtab_to_symtab_1): Set symtab->primary to tell objfile_relocate to do relocations for our symbols. * (ecoff_relocate_efi): New routine to relocate adr field of PDRs (which hang off of the symbol table). * Use prim_record_minimal_symbols_and_info instead of prim_record_minimal_symbols to supply section info to make minimal symbol relocations work. * minsyms.c (prim_record_minimal_symbols_and_info): If section is -1, try to deduce it from ms_type. * objfiles.c (objfile_relocate): Use ALL_OBJFILE_SYMTABS where appropriate. Handle relocation of MIPS_EFI symbols special. Also, add code to relocate objfile->sections data structure. * remote.c (get_offsets): Use new protocol message to acquire section offsets from the target. * (remote_wait): Get rid of relocation stuff. That's all handled by objfile_relocate now. * config/alpha/alpha-nw.mt (TM_FILE): Use tm-alphanw.h. * config/alpha/tm-alpha.h: Define CALL_DUMMY_ADDRESS, and VM_MIN_ADDRESS. * config/alpha/tm-alphanw.h: DECR_PC_AFTER_BREAK=0, VM_MIN_ADDRESS=0. --- gdb/ChangeLog | 32 +++++ gdb/alpha-tdep.c | 331 +++++++++++++++++++++++++++++++---------------- gdb/mdebugread.c | 92 +++++++++---- gdb/minsyms.c | 23 +++- gdb/objfiles.c | 42 +++++- gdb/remote.c | 166 ++++++++++-------------- 6 files changed, 450 insertions(+), 236 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index b87030d157d..2e116cb0188 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -3,6 +3,38 @@ Mon Mar 21 11:50:28 1994 Jeffrey A. Law (law@snake.cs.utah.edu) * hppa-tdep.c (hppa_fix_call_dummy): Use value_ptr. (hppa_push_arguments): Likewise. +Mon Mar 21 11:02:51 1994 Stu Grossman (grossman at cygnus.com) + + * alpha-tdep.c: Gobs of changes (many imported from mips-tdep) to + improve remote debugging efficiency. Also fixed problems with + doing function calls for programs with no entry points. + * infcmd.c (run_stack_dummy): Use CALL_DUMMY_ADDRESS instead of + entry_point_address. + * inferior.h (PC_IN_CALL_DUMMY): ditto. + * mdebugread.c (parse_symbol, parse_procedure, parse_external, + parse_lines): Pass section_offsets info to these routines so that + we can relocate symbol table entries upon readin. + * (psymtab_to_symtab_1): Set symtab->primary to tell + objfile_relocate to do relocations for our symbols. + * (ecoff_relocate_efi): New routine to relocate adr field of PDRs + (which hang off of the symbol table). + * Use prim_record_minimal_symbols_and_info instead of + prim_record_minimal_symbols to supply section info to make minimal + symbol relocations work. + * minsyms.c (prim_record_minimal_symbols_and_info): If section is + -1, try to deduce it from ms_type. + * objfiles.c (objfile_relocate): Use ALL_OBJFILE_SYMTABS where + appropriate. Handle relocation of MIPS_EFI symbols special. Also, + add code to relocate objfile->sections data structure. + * remote.c (get_offsets): Use new protocol message to acquire + section offsets from the target. + * (remote_wait): Get rid of relocation stuff. That's all handled + by objfile_relocate now. + * config/alpha/alpha-nw.mt (TM_FILE): Use tm-alphanw.h. + * config/alpha/tm-alpha.h: Define CALL_DUMMY_ADDRESS, and + VM_MIN_ADDRESS. + * config/alpha/tm-alphanw.h: DECR_PC_AFTER_BREAK=0, VM_MIN_ADDRESS=0. + Sun Mar 20 15:21:57 1994 Doug Evans (dje@cygnus.com) * sparc-tdep.c (sparc_frame_find_save_regs): Use REGISTER_RAW_SIZE diff --git a/gdb/alpha-tdep.c b/gdb/alpha-tdep.c index 31c467be6e7..ce06b818311 100644 --- a/gdb/alpha-tdep.c +++ b/gdb/alpha-tdep.c @@ -25,10 +25,13 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "gdbcmd.h" #include "gdbcore.h" #include "dis-asm.h" +#include "symfile.h" +#include "objfiles.h" /* FIXME: Some of this code should perhaps be merged with mips-tdep.c. */ -#define VM_MIN_ADDRESS (CORE_ADDR)0x120000000 +/* FIXME: Put this declaration in frame.h. */ +extern struct obstack frame_cache_obstack; /* Forward declarations. */ @@ -51,6 +54,12 @@ alpha_in_lenient_prologue PARAMS ((CORE_ADDR, CORE_ADDR)); static void reinit_frame_cache_sfunc PARAMS ((char *, int, struct cmd_list_element *)); +static CORE_ADDR after_prologue PARAMS ((CORE_ADDR pc, + alpha_extra_func_info_t proc_desc)); + +static int in_prologue PARAMS ((CORE_ADDR pc, + alpha_extra_func_info_t proc_desc)); + /* Heuristic_proc_start may hunt through the text section for a long time across a 2400 baud serial line. Allows the user to limit this search. */ @@ -122,7 +131,70 @@ struct linked_proc_info } *linked_proc_desc_table = NULL; -#define READ_FRAME_REG(fi, regno) read_next_frame_reg((fi)->next, regno) +/* Guaranteed to set fci->saved_regs to some values (it never leaves it + NULL). */ + +void +alpha_find_saved_regs (fci) + FRAME fci; +{ + int ireg; + CORE_ADDR reg_position; + unsigned long mask; + alpha_extra_func_info_t proc_desc; + int returnreg; + + fci->saved_regs = (struct frame_saved_regs *) + obstack_alloc (&frame_cache_obstack, sizeof(struct frame_saved_regs)); + memset (fci->saved_regs, 0, sizeof (struct frame_saved_regs)); + + proc_desc = fci->proc_desc; + if (proc_desc == NULL) + /* I'm not sure how/whether this can happen. Normally when we can't + find a proc_desc, we "synthesize" one using heuristic_proc_desc + and set the saved_regs right away. */ + return; + + /* Fill in the offsets for the registers which gen_mask says + were saved. */ + + reg_position = fci->frame + PROC_REG_OFFSET (proc_desc); + mask = PROC_REG_MASK (proc_desc); + + returnreg = PROC_PC_REG (proc_desc); + + /* Note that RA is always saved first, regardless of it's actual + register number. */ + if (mask & (1 << returnreg)) + { + fci->saved_regs->regs[returnreg] = reg_position; + reg_position += 8; + mask &= ~(1 << returnreg); /* Clear bit for RA so we + don't save again later. */ + } + + for (ireg = 0; ireg <= 31 ; ++ireg) + if (mask & (1 << ireg)) + { + fci->saved_regs->regs[ireg] = reg_position; + reg_position += 8; + } + + /* Fill in the offsets for the registers which float_mask says + were saved. */ + + reg_position = fci->frame + PROC_FREG_OFFSET (proc_desc); + mask = PROC_FREG_MASK (proc_desc); + + for (ireg = 0; ireg <= 31 ; ++ireg) + if (mask & (1 << ireg)) + { + fci->saved_regs->regs[FP0_REGNUM+ireg] = reg_position; + reg_position += 8; + } + + fci->saved_regs->regs[PC_REGNUM] = fci->saved_regs->regs[returnreg]; +} static CORE_ADDR read_next_frame_reg(fi, regno) @@ -154,8 +226,13 @@ read_next_frame_reg(fi, regno) } else if (regno == SP_REGNUM) return fi->frame; - else if (fi->saved_regs->regs[regno]) - return read_memory_integer(fi->saved_regs->regs[regno], 8); + else + { + if (fi->saved_regs == NULL) + alpha_find_saved_regs (fi); + if (fi->saved_regs->regs[regno]) + return read_memory_integer(fi->saved_regs->regs[regno], 8); + } } return read_register(regno); } @@ -297,9 +374,67 @@ heuristic_proc_desc(start_pc, limit_pc, next_frame) PROC_FRAME_OFFSET(&temp_proc_desc) = frame_size; PROC_REG_MASK(&temp_proc_desc) = reg_mask; PROC_PC_REG(&temp_proc_desc) = RA_REGNUM; + PROC_LOCALOFF(&temp_proc_desc) = 0; /* XXX - bogus */ return &temp_proc_desc; } +/* This returns the PC of the first inst after the prologue. If we can't + find the prologue, then return 0. */ + +static CORE_ADDR +after_prologue (pc, proc_desc) + CORE_ADDR pc; + alpha_extra_func_info_t proc_desc; +{ + struct block *b; + struct symtab_and_line sal; + CORE_ADDR func_addr, func_end; + + if (!proc_desc) + proc_desc = find_proc_desc (pc, NULL); + + if (proc_desc) + { + /* If function is frameless, then we need to do it the hard way. I + strongly suspect that frameless always means prologueless... */ + if (PROC_FRAME_REG (proc_desc) == SP_REGNUM + && PROC_FRAME_OFFSET (proc_desc) == 0) + return 0; + } + + if (!find_pc_partial_function (pc, NULL, &func_addr, &func_end)) + return 0; /* Unknown */ + + sal = find_pc_line (func_addr, 0); + + if (sal.end < func_end) + return sal.end; + + /* The line after the prologue is after the end of the function. In this + case, tell the caller to find the prologue the hard way. */ + + return 0; +} + +/* Return non-zero if we *might* be in a function prologue. Return zero if we + are definatly *not* in a function prologue. */ + +static int +in_prologue (pc, proc_desc) + CORE_ADDR pc; + alpha_extra_func_info_t proc_desc; +{ + CORE_ADDR after_prologue_pc; + + after_prologue_pc = after_prologue (pc, proc_desc); + + if (after_prologue_pc == 0 + || pc < after_prologue_pc) + return 1; + else + return 0; +} + static alpha_extra_func_info_t find_proc_desc(pc, next_frame) CORE_ADDR pc; @@ -317,6 +452,7 @@ find_proc_desc(pc, next_frame) as it will be contained in the proc_desc we are searching for. So we have to find the proc_desc whose frame is closest to the current stack pointer. */ + if (PC_IN_CALL_DUMMY (pc, 0, 0)) { struct linked_proc_info *link; @@ -338,6 +474,7 @@ find_proc_desc(pc, next_frame) } b = block_for_pc(pc); + find_pc_partial_function (pc, NULL, &startaddr, NULL); if (b == NULL) sym = NULL; @@ -355,45 +492,39 @@ find_proc_desc(pc, next_frame) if (sym) { - /* IF (this is the topmost frame OR a frame interrupted by a signal) - * AND (this proc does not have debugging information OR + /* IF this is the topmost frame AND + * (this proc does not have debugging information OR * the PC is in the procedure prologue) * THEN create a "heuristic" proc_desc (by analyzing * the actual code) to replace the "official" proc_desc. */ proc_desc = (alpha_extra_func_info_t)SYMBOL_VALUE(sym); - if (next_frame == NULL || next_frame->signal_handler_caller) { - struct symtab_and_line val; - struct symbol *proc_symbol = - PROC_DESC_IS_DUMMY(proc_desc) ? 0 : PROC_SYMBOL(proc_desc); - - if (proc_symbol) { - val = find_pc_line (BLOCK_START - (SYMBOL_BLOCK_VALUE(proc_symbol)), - 0); - val.pc = val.end ? val.end : pc; - } - if (!proc_symbol || pc < val.pc) { + if (next_frame == NULL) + { + if (PROC_DESC_IS_DUMMY (proc_desc) || in_prologue (pc, proc_desc)) + { alpha_extra_func_info_t found_heuristic = - heuristic_proc_desc(PROC_LOW_ADDR(proc_desc), - pc, next_frame); + heuristic_proc_desc (PROC_LOW_ADDR (proc_desc), + pc, next_frame); + PROC_LOCALOFF (found_heuristic) = PROC_LOCALOFF (proc_desc); if (found_heuristic) - { - /* The call to heuristic_proc_desc determines - which registers have been saved so far and if the - frame is already set up. - The heuristic algorithm doesn't work well for other - information in the procedure descriptor, so copy - it from the found procedure descriptor. */ - PROC_LOCALOFF(found_heuristic) = PROC_LOCALOFF(proc_desc); - PROC_PC_REG(found_heuristic) = PROC_PC_REG(proc_desc); - proc_desc = found_heuristic; - } - } - } + proc_desc = found_heuristic; + } + } } else { + /* Is linked_proc_desc_table really necessary? It only seems to be used + by procedure call dummys. However, the procedures being called ought + to have their own proc_descs, and even if they don't, + heuristic_proc_desc knows how to create them! */ + + register struct linked_proc_info *link; + for (link = linked_proc_desc_table; link; link = link->next) + if (PROC_LOW_ADDR(&link->info) <= pc + && PROC_HIGH_ADDR(&link->info) > pc) + return &link->info; + if (startaddr == 0) startaddr = heuristic_proc_start (pc); @@ -454,104 +585,43 @@ void init_extra_frame_info(fci) struct frame_info *fci; { - extern struct obstack frame_cache_obstack; /* Use proc_desc calculated in frame_chain */ alpha_extra_func_info_t proc_desc = fci->next ? cached_proc_desc : find_proc_desc(fci->pc, fci->next); - fci->saved_regs = (struct frame_saved_regs*) - obstack_alloc (&frame_cache_obstack, sizeof(struct frame_saved_regs)); - memset (fci->saved_regs, 0, sizeof (struct frame_saved_regs)); + fci->saved_regs = NULL; fci->proc_desc = proc_desc == &temp_proc_desc ? 0 : proc_desc; if (proc_desc) { - int ireg; - CORE_ADDR reg_position; - unsigned long mask; - int returnreg; - /* Get the locals offset from the procedure descriptor, it is valid even if we are in the middle of the prologue. */ fci->localoff = PROC_LOCALOFF(proc_desc); /* Fixup frame-pointer - only needed for top frame */ + /* Fetch the frame pointer for a dummy frame from the procedure descriptor. */ if (PROC_DESC_IS_DUMMY(proc_desc)) fci->frame = (FRAME_ADDR) PROC_DUMMY_FRAME(proc_desc); + /* This may not be quite right, if proc has a real frame register. Get the value of the frame relative sp, procedure might have been interrupted by a signal at it's very start. */ - else if (fci->pc == PROC_LOW_ADDR(proc_desc)) - fci->frame = READ_FRAME_REG(fci, SP_REGNUM); + else if (fci->pc == PROC_LOW_ADDR (proc_desc) && !PROC_DESC_IS_DUMMY (proc_desc)) + fci->frame = read_next_frame_reg (fci->next, SP_REGNUM); else - fci->frame = READ_FRAME_REG(fci, PROC_FRAME_REG(proc_desc)) - + PROC_FRAME_OFFSET(proc_desc); - - /* If this is the innermost frame, and we are still in the - prologue (loosely defined), then the registers may not have - been saved yet. */ - if (fci->next == NULL - && !PROC_DESC_IS_DUMMY(proc_desc) - && alpha_in_lenient_prologue (PROC_LOW_ADDR (proc_desc), fci->pc)) - { - /* Can't just say that the registers are not saved, because they - might get clobbered halfway through the prologue. - heuristic_proc_desc already has the right code to figure out - exactly what has been saved, so use it. As far as I know we - could be doing this (as we do on the 68k, for example) - regardless of whether we are in the prologue; I'm leaving in - the check for being in the prologue only out of conservatism - (I'm not sure whether heuristic_proc_desc handles all cases, - for example). - - This stuff is ugly (and getting uglier by the minute). Probably - the best way to clean it up is to ignore the proc_desc's from - the symbols altogher, and get all the information we need by - examining the prologue (provided we can make the prologue - examining code good enough to get all the cases...). */ - proc_desc = - heuristic_proc_desc (PROC_LOW_ADDR (proc_desc), - fci->pc, - fci->next); - } + fci->frame = read_next_frame_reg (fci->next, PROC_FRAME_REG (proc_desc)) + + PROC_FRAME_OFFSET (proc_desc); if (proc_desc == &temp_proc_desc) - *fci->saved_regs = temp_saved_regs; - else { - /* Find which general-purpose registers were saved. - The return address register is the first saved register, - the other registers follow in ascending order. */ - reg_position = fci->frame + PROC_REG_OFFSET(proc_desc); - mask = PROC_REG_MASK(proc_desc) & 0xffffffffL; - returnreg = PROC_PC_REG(proc_desc); - if (mask & (1 << returnreg)) - { - fci->saved_regs->regs[returnreg] = reg_position; - reg_position += 8; - } - for (ireg = 0; mask; ireg++, mask >>= 1) - if (mask & 1) - { - if (ireg == returnreg) - continue; - fci->saved_regs->regs[ireg] = reg_position; - reg_position += 8; - } - /* find which floating-point registers were saved */ - reg_position = fci->frame + PROC_FREG_OFFSET(proc_desc); - mask = PROC_FREG_MASK(proc_desc) & 0xffffffffL; - for (ireg = 0; mask; ireg++, mask >>= 1) - if (mask & 1) - { - fci->saved_regs->regs[FP0_REGNUM+ireg] = reg_position; - reg_position += 8; - } + fci->saved_regs = (struct frame_saved_regs*) + obstack_alloc (&frame_cache_obstack, + sizeof (struct frame_saved_regs)); + *fci->saved_regs = temp_saved_regs; + fci->saved_regs->regs[PC_REGNUM] = fci->saved_regs->regs[RA_REGNUM]; } - - fci->saved_regs->regs[PC_REGNUM] = fci->saved_regs->regs[PROC_PC_REG(proc_desc)]; } } @@ -661,16 +731,18 @@ void alpha_push_dummy_frame() { int ireg; - struct linked_proc_info *link = (struct linked_proc_info*) - xmalloc(sizeof (struct linked_proc_info)); - alpha_extra_func_info_t proc_desc = &link->info; + struct linked_proc_info *link; + alpha_extra_func_info_t proc_desc; CORE_ADDR sp = read_register (SP_REGNUM); CORE_ADDR save_address; char raw_buffer[MAX_REGISTER_RAW_SIZE]; unsigned long mask; + link = (struct linked_proc_info *) xmalloc(sizeof (struct linked_proc_info)); link->next = linked_proc_desc_table; linked_proc_desc_table = link; + + proc_desc = &link->info; /* * The registers we must save are all those not preserved across @@ -764,7 +836,7 @@ alpha_push_dummy_frame() sp += PROC_REG_OFFSET(proc_desc); write_register (SP_REGNUM, sp); - PROC_LOW_ADDR(proc_desc) = entry_point_address (); + PROC_LOW_ADDR(proc_desc) = CALL_DUMMY_ADDRESS (); PROC_HIGH_ADDR(proc_desc) = PROC_LOW_ADDR(proc_desc) + 4; SET_PROC_DESC_IS_DUMMY(proc_desc); @@ -781,6 +853,8 @@ alpha_pop_frame() alpha_extra_func_info_t proc_desc = frame->proc_desc; write_register (PC_REGNUM, FRAME_SAVED_PC(frame)); + if (frame->saved_regs == NULL) + alpha_find_saved_regs (frame); if (proc_desc) { for (regnum = 32; --regnum >= 0; ) @@ -838,6 +912,19 @@ alpha_skip_prologue (pc, lenient) { unsigned long inst; int offset; + CORE_ADDR post_prologue_pc; + + /* See if we can determine the end of the prologue via the symbol table. + If so, then return either PC, or the PC after the prologue, whichever + is greater. */ + + post_prologue_pc = after_prologue (pc, NULL); + + if (post_prologue_pc != 0) + return max (pc, post_prologue_pc); + + /* Can't determine prologue from the symbol table, need to examine + instructions. */ /* Skip the typical prologue instructions. These are the stack adjustment instruction and the instructions that save registers on the stack @@ -1015,6 +1102,30 @@ reinit_frame_cache_sfunc (args, from_tty, c) reinit_frame_cache (); } +/* This is the definition of CALL_DUMMY_ADDRESS. It's a heuristic that is used + to find a convenient place in the text segment to stick a breakpoint to + detect the completion of a target function call (ala call_function_by_hand). + */ + +CORE_ADDR +alpha_call_dummy_address () +{ + CORE_ADDR entry; + struct minimal_symbol *sym; + + entry = entry_point_address (); + + if (entry != 0) + return entry; + + sym = lookup_minimal_symbol ("_Prelude", symfile_objfile); + + if (!sym || MSYMBOL_TYPE (sym) != mst_text) + return 0; + else + return SYMBOL_VALUE_ADDRESS (sym) + 4; +} + void _initialize_alpha_tdep () { diff --git a/gdb/mdebugread.c b/gdb/mdebugread.c index 4e713222bc5..7471f1e4729 100644 --- a/gdb/mdebugread.c +++ b/gdb/mdebugread.c @@ -315,7 +315,7 @@ static struct blockvector * new_bvect PARAMS ((int)); static int -parse_symbol PARAMS ((SYMR *, union aux_ext *, char *, int)); +parse_symbol PARAMS ((SYMR *, union aux_ext *, char *, int, struct section_offsets *)); static struct type * parse_type PARAMS ((int, union aux_ext *, unsigned int, int *, int, char *)); @@ -648,11 +648,12 @@ add_pending (fh, sh, t) SYMR's handled (normally one). */ static int -parse_symbol (sh, ax, ext_sh, bigend) +parse_symbol (sh, ax, ext_sh, bigend, section_offsets) SYMR *sh; union aux_ext *ax; char *ext_sh; int bigend; + struct section_offsets *section_offsets; { const bfd_size_type external_sym_size = debug_swap->external_sym_size; void (* const swap_sym_in) PARAMS ((bfd *, PTR, SYMR *)) = @@ -674,6 +675,19 @@ parse_symbol (sh, ax, ext_sh, bigend) else name = debug_info->ss + cur_fdr->issBase + sh->iss; + switch (sh->sc) + { + case scText: + sh->value += ANOFFSET (section_offsets, SECT_OFF_TEXT); + break; + case scData: + sh->value += ANOFFSET (section_offsets, SECT_OFF_DATA); + break; + case scBss: + sh->value += ANOFFSET (section_offsets, SECT_OFF_BSS); + break; + } + switch (sh->st) { case stNil: @@ -1699,13 +1713,15 @@ upgrade_type (fd, tpp, tq, ax, bigend, sym_name) to look for the function which contains the MIPS_EFI_SYMBOL_NAME symbol in question, or NULL to use top_stack->cur_block. */ -static void parse_procedure PARAMS ((PDR *, struct symtab *, unsigned long)); +static void parse_procedure PARAMS ((PDR *, struct symtab *, unsigned long, + struct section_offsets *)); static void -parse_procedure (pr, search_symtab, first_off) +parse_procedure (pr, search_symtab, first_off, section_offsets) PDR *pr; struct symtab *search_symtab; unsigned long first_off; + struct section_offsets *section_offsets; { struct symbol *s, *i; struct block *b; @@ -1810,7 +1826,8 @@ parse_procedure (pr, search_symtab, first_off) e = (struct mips_extra_func_info *) SYMBOL_VALUE (i); e->pdr = *pr; e->pdr.isym = (long) s; - e->pdr.adr += cur_fdr->adr - first_off; + e->pdr.adr += cur_fdr->adr - first_off + + ANOFFSET (section_offsets, SECT_OFF_TEXT); /* Correct incorrect setjmp procedure descriptor from the library to make backtrace through setjmp work. */ @@ -1824,6 +1841,20 @@ parse_procedure (pr, search_symtab, first_off) } } +/* Relocate the extra function info pointed to by the symbol table. */ + +void +ecoff_relocate_efi (sym, delta) + struct symbol *sym; + CORE_ADDR delta; +{ + struct mips_extra_func_info *e; + + e = (struct mips_extra_func_info *) SYMBOL_VALUE (sym); + + e->pdr.adr += delta; +} + /* Parse the external symbol ES. Just call parse_symbol() after making sure we know where the aux are for it. For procedures, parsing of the PDRs has already provided all the needed @@ -1834,10 +1865,11 @@ parse_procedure (pr, search_symtab, first_off) This routine clobbers top_stack->cur_block and ->cur_st. */ static void -parse_external (es, skip_procedures, bigend) +parse_external (es, skip_procedures, bigend, section_offsets) EXTR *es; int skip_procedures; int bigend; + struct section_offsets *section_offsets; { union aux_ext *ax; @@ -1904,7 +1936,7 @@ parse_external (es, skip_procedures, bigend) case stLabel: /* Note that the case of a symbol with indexNil must be handled anyways by parse_symbol(). */ - parse_symbol (&es->asym, ax, (char *) NULL, bigend); + parse_symbol (&es->asym, ax, (char *) NULL, bigend, section_offsets); break; default: break; @@ -1918,11 +1950,12 @@ parse_external (es, skip_procedures, bigend) with that and do not need to reorder our linetables */ static void -parse_lines (fh, pr, lt, maxlines) +parse_lines (fh, pr, lt, maxlines, section_offsets) FDR *fh; PDR *pr; struct linetable *lt; int maxlines; + struct section_offsets *section_offsets; { unsigned char *base; int j, k; @@ -1932,8 +1965,6 @@ parse_lines (fh, pr, lt, maxlines) if (fh->cbLine == 0) return; - base = debug_info->line + fh->cbLineOffset; - /* Scan by procedure descriptors */ k = 0; for (j = 0; j < fh->cpd; j++, pr++) @@ -1956,7 +1987,9 @@ parse_lines (fh, pr, lt, maxlines) halt = base + fh->cbLine; base += pr->cbLineOffset; - adr = fh->adr + pr->adr - first_off; + adr = fh->adr + pr->adr - first_off + + ANOFFSET (section_offsets, SECT_OFF_TEXT); + l = adr >> 2; /* in words */ for (lineno = pr->lnLow; base < halt; ) { @@ -2286,9 +2319,11 @@ parse_partial_symbols (objfile, section_offsets) { if (sh.st == stProc || sh.st == stStaticProc) { - long procaddr = sh.value; + long procaddr; long isym; - + + sh.value += ANOFFSET (section_offsets, SECT_OFF_TEXT); + procaddr = sh.value; isym = AUX_GET_ISYM (fh->fBigendian, (debug_info->external_aux @@ -2358,8 +2393,9 @@ parse_partial_symbols (objfile, section_offsets) int new_sdx; case stStaticProc: - prim_record_minimal_symbol (name, sh.value, mst_file_text, - objfile); + prim_record_minimal_symbol_and_info (name, sh.value, + mst_file_text, NULL, + SECT_OFF_TEXT, objfile); /* FALLTHROUGH */ @@ -2427,11 +2463,15 @@ parse_partial_symbols (objfile, section_offsets) || sh.sc == scRData || sh.sc == scPData || sh.sc == scXData) - prim_record_minimal_symbol (name, sh.value, mst_file_data, - objfile); + prim_record_minimal_symbol_and_info (name, sh.value, + mst_file_data, NULL, + SECT_OFF_DATA, + objfile); else - prim_record_minimal_symbol (name, sh.value, mst_file_bss, - objfile); + prim_record_minimal_symbol_and_info (name, sh.value, + mst_file_bss, NULL, + SECT_OFF_BSS, + objfile); class = LOC_STATIC; break; @@ -2899,7 +2939,7 @@ psymtab_to_symtab_1 (pst, filename) first_off = pr.adr; first_pdr = 0; } - parse_procedure (&pr, st, first_off); + parse_procedure (&pr, st, first_off, pst->section_offsets); } } else @@ -2966,7 +3006,7 @@ psymtab_to_symtab_1 (pst, filename) (*swap_sym_in) (cur_bfd, sym_ptr, &sh); c = parse_symbol (&sh, debug_info->external_aux + fh->iauxBase, - sym_ptr, fh->fBigendian); + sym_ptr, fh->fBigendian, pst->section_offsets); sym_ptr += c * external_sym_size; } @@ -2995,7 +3035,8 @@ psymtab_to_symtab_1 (pst, filename) pdr_ptr += external_pdr_size, pdr_in++) (*swap_pdr_in) (cur_bfd, pdr_ptr, pdr_in); - parse_lines (fh, pr_block, lines, maxlines); + parse_lines (fh, pr_block, lines, maxlines, + pst->section_offsets); if (lines->nitems < fh->cline) lines = shrink_linetable (lines); @@ -3003,7 +3044,8 @@ psymtab_to_symtab_1 (pst, filename) pdr_in = pr_block; pdr_in_end = pdr_in + fh->cpd; for (; pdr_in < pdr_in_end; pdr_in++) - parse_procedure (pdr_in, 0, pr_block->adr); + parse_procedure (pdr_in, 0, pr_block->adr, + pst->section_offsets); do_cleanups (old_chain); } @@ -3025,7 +3067,7 @@ psymtab_to_symtab_1 (pst, filename) ext_ptr = PST_PRIVATE (pst)->extern_tab; for (i = PST_PRIVATE (pst)->extern_count; --i >= 0; ext_ptr++) - parse_external (ext_ptr, 1, fh->fBigendian); + parse_external (ext_ptr, 1, fh->fBigendian, pst->section_offsets); /* If there are undefined symbols, tell the user. The alpha has an undefined symbol for every symbol that is @@ -3041,6 +3083,8 @@ psymtab_to_symtab_1 (pst, filename) } pop_parse_stack (); + st->primary = 1; + /* Sort the symbol table now, we are done adding symbols to it.*/ sort_symtab_syms (st); diff --git a/gdb/minsyms.c b/gdb/minsyms.c index ec724713f48..ff31f73a3b6 100644 --- a/gdb/minsyms.c +++ b/gdb/minsyms.c @@ -44,6 +44,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "symfile.h" #include "objfiles.h" #include "demangle.h" +#include "gdb-stabs.h" /* Accumulate the minimal symbols for each objfile in bunches of BUNCH_SIZE. At the end, copy them all into one newly allocated location on an objfile's @@ -327,7 +328,27 @@ prim_record_minimal_symbol_and_info (name, address, ms_type, info, section, SYMBOL_NAME (msymbol) = (char *) name; SYMBOL_INIT_LANGUAGE_SPECIFIC (msymbol, language_unknown); SYMBOL_VALUE_ADDRESS (msymbol) = address; - SYMBOL_SECTION (msymbol) = section; + if (section == -1) + switch (ms_type) + { + case mst_text: + case mst_file_text: + SYMBOL_SECTION (msymbol) = SECT_OFF_TEXT; + break; + case mst_data: + case mst_file_data: + SYMBOL_SECTION (msymbol) = SECT_OFF_DATA; + break; + case mst_bss: + case mst_file_bss: + SYMBOL_SECTION (msymbol) = SECT_OFF_BSS; + break; + default: + SYMBOL_SECTION (msymbol) = -1; + } + else + SYMBOL_SECTION (msymbol) = section; + MSYMBOL_TYPE (msymbol) = ms_type; /* FIXME: This info, if it remains, needs its own field. */ MSYMBOL_INFO (msymbol) = info; /* FIXME! */ diff --git a/gdb/objfiles.c b/gdb/objfiles.c index 6c6dfc20724..4f0dfd6d939 100644 --- a/gdb/objfiles.c +++ b/gdb/objfiles.c @@ -450,7 +450,7 @@ objfile_relocate (objfile, new_offsets) { struct symtab *s; - for (s = objfile->symtabs; s; s = s->next) + ALL_OBJFILE_SYMTABS (objfile, s) { struct linetable *l; struct blockvector *bv; @@ -492,6 +492,15 @@ objfile_relocate (objfile, new_offsets) SYMBOL_VALUE_ADDRESS (sym) += ANOFFSET (delta, SYMBOL_SECTION (sym)); } +#ifdef MIPS_EFI_SYMBOL_NAME + /* Relocate Extra Function Info for ecoff. */ + + else + if (SYMBOL_CLASS (sym) == LOC_CONST + && SYMBOL_NAMESPACE (sym) == LABEL_NAMESPACE + && STRCMP (SYMBOL_NAME (sym), MIPS_EFI_SYMBOL_NAME) == 0) + ecoff_relocate_efi (sym, ANOFFSET (delta, s->block_line_section)); +#endif } } } @@ -538,6 +547,37 @@ objfile_relocate (objfile, new_offsets) for (i = 0; i < objfile->num_sections; ++i) ANOFFSET (objfile->section_offsets, i) = ANOFFSET (new_offsets, i); } + + { + struct obj_section *s; + bfd *abfd; + + abfd = symfile_objfile->obfd; + + for (s = symfile_objfile->sections; + s < symfile_objfile->sections_end; ++s) + { + flagword flags; + + flags = bfd_get_section_flags (abfd, s->the_bfd_section); + + if (flags & SEC_CODE) + { + s->addr += ANOFFSET (delta, SECT_OFF_TEXT); + s->endaddr += ANOFFSET (delta, SECT_OFF_TEXT); + } + else if (flags & (SEC_DATA | SEC_LOAD)) + { + s->addr += ANOFFSET (delta, SECT_OFF_DATA); + s->endaddr += ANOFFSET (delta, SECT_OFF_DATA); + } + else if (flags & SEC_ALLOC) + { + s->addr += ANOFFSET (delta, SECT_OFF_BSS); + s->endaddr += ANOFFSET (delta, SECT_OFF_BSS); + } + } + } } /* Many places in gdb want to test just to see if we have any partial diff --git a/gdb/remote.c b/gdb/remote.c index 7240f0b5277..d969e11d8cf 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -90,22 +90,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ AA = signal number n... = register number r... = register contents - or... WAA The process extited, and AA is + or... WAA The process exited, and AA is the exit status. This is only applicable for certains sorts of targets. - or... NAATT;DD;BB Relocate the object file. - AA = signal number - TT = text address - DD = data address - BB = bss address - This is used by the NLM stub, - which is why it only has three - addresses rather than one per - section: the NLM stub always - sees only three sections, even - though gdb may see more. - kill request k toggle debug d toggle debug flag (see 386 & 68k stubs) @@ -116,17 +104,33 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ we can extend the protocol and GDB can tell whether the stub it is talking to uses the old or the new. +<<<<<<< remote.c + search tAA:PP,MM Search backwards starting at address +||||||| 1.81 + search tAA:PP,MM Search backword starting at address +======= search tAA:PP,MM Search backward starting at address +>>>>>>> 1.82 AA for a match with pattern PP and mask MM. PP and MM are 4 bytes. Not supported by all stubs. +<<<<<<< remote.c + general query qXXXX Request info about XXXX. + general set QXXXX=yyyy Set value of XXXX to yyyy. + query sect offs qOffsets Get section offsets. Reply is + Text=xxx;Data=yyy;Bss=zzz +*/ + +||||||| 1.81 +======= Responses can be run-length encoded to save space. A '*' means that the next two characters are hex digits giving a repeat count which stands for that many repititions of the character preceding the '*'. Note that this means that responses cannot contain '*'. Example: "0*03" means the same as "0000". */ +>>>>>>> 1.82 #include "defs.h" #include #include @@ -265,6 +269,49 @@ remote_close (quitting) remote_desc = NULL; } +/* Query the remote side for the text, data and bss offsets. */ + +static void +get_offsets () +{ + unsigned char buf [PBUFSIZ]; + int nvals; + CORE_ADDR text_addr, data_addr, bss_addr; + struct section_offsets *offs; + + putpkt ("qOffsets"); + + getpkt (buf, 1); + + if (buf[0] == 'E') + { + warning ("Remote failure reply: %s", buf); + return; + } + + nvals = sscanf (buf, "Text=%lx;Data=%lx;Bss=%lx", &text_addr, &data_addr, + &bss_addr); + if (nvals != 3) + error ("Malformed response to offset query, %s", buf); + + if (symfile_objfile == NULL) + return; + + offs = (struct section_offsets *) alloca (sizeof (struct section_offsets) + + symfile_objfile->num_sections + * sizeof (offs->offsets)); + memcpy (offs, symfile_objfile->section_offsets, + sizeof (struct section_offsets) + + symfile_objfile->num_sections + * sizeof (offs->offsets)); + + ANOFFSET (offs, SECT_OFF_TEXT) = text_addr; + ANOFFSET (offs, SECT_OFF_DATA) = data_addr; + ANOFFSET (offs, SECT_OFF_BSS) = bss_addr; + + objfile_relocate (symfile_objfile, offs); +} + /* Stub for catch_errors. */ static int @@ -274,13 +321,16 @@ remote_start_remote (dummy) immediate_quit = 1; /* Allow user to interrupt it */ /* Ack any packet which the remote side has already sent. */ - /* I'm not sure this \r is needed; we don't use it any other time we - send an ack. */ - SERIAL_WRITE (remote_desc, "+\r", 2); + + SERIAL_WRITE (remote_desc, "+", 1); + + get_offsets (); /* Get text, data & bss offsets */ + putpkt ("?"); /* initiate a query from remote machine */ immediate_quit = 0; start_remote (); /* Initialize gdb process mechanisms */ + return 1; } @@ -536,90 +586,6 @@ remote_wait (pid, status) } break; } - else if (buf[0] == 'N') - { - unsigned char *p1; - bfd_vma text_addr, data_addr, bss_addr; - - /* Relocate object file. Format is NAATT;DD;BB where AA is - the signal number, TT is the new text address, DD is the - 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 = strtoul (p, &p1, 16); - if (p1 == p || *p1 != ';') - warning ("Malformed relocation packet: Packet '%s'", buf); - p = p1 + 1; - data_addr = strtoul (p, &p1, 16); - if (p1 == p || *p1 != ';') - warning ("Malformed relocation packet: Packet '%s'", buf); - p = p1 + 1; - bss_addr = strtoul (p, &p1, 16); - if (p1 == p) - warning ("Malformed relocation packet: Packet '%s'", buf); - - 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; - - /* FIXME: This code assumes gdb-stabs.h is being used; - it's broken for xcoff, dwarf, sdb-coff, etc. But - there is no simple canonical representation for this - stuff. (Just what does "text" as seen by the stub - mean, anyway?). */ - - offs = ((struct section_offsets *) - alloca (sizeof (struct section_offsets) - + (symfile_objfile->num_sections - * sizeof (offs->offsets)))); - memcpy (offs, symfile_objfile->section_offsets, - (sizeof (struct section_offsets) - + (symfile_objfile->num_sections - * sizeof (offs->offsets)))); - ANOFFSET (offs, SECT_OFF_TEXT) = text_addr; - ANOFFSET (offs, SECT_OFF_DATA) = data_addr; - ANOFFSET (offs, SECT_OFF_BSS) = bss_addr; - - objfile_relocate (symfile_objfile, offs); - { - struct obj_section *s; - bfd *abfd; - - abfd = symfile_objfile->obfd; - - for (s = symfile_objfile->sections; - s < symfile_objfile->sections_end; ++s) - { - flagword flags; - - flags = bfd_get_section_flags (abfd, s->the_bfd_section); - - 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; - } else if (buf[0] == 'W') { /* The remote process exited. */ -- 2.30.2