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.
This commit is contained in:
Stu Grossman 1994-03-21 19:57:38 +00:00
parent 4fd5eed484
commit 72bba93b85
6 changed files with 450 additions and 236 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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 <string.h>
#include <fcntl.h>
@ -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. */