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:
parent
4fd5eed484
commit
72bba93b85
|
@ -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
|
||||
|
|
331
gdb/alpha-tdep.c
331
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 ()
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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! */
|
||||
|
|
|
@ -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
|
||||
|
|
166
gdb/remote.c
166
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 <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. */
|
||||
|
|
Loading…
Reference in New Issue