Mostly rs6000 changes from IBM.

This commit is contained in:
Per Bothner 1992-02-29 06:03:43 +00:00
parent 8eb8b9aaa3
commit 818de002b6
12 changed files with 1223 additions and 407 deletions

View File

@ -1,3 +1,30 @@
Thu Feb 27 22:57:19 1992 Per Bothner (bothner@cygnus.com)
* rs6k-opcode.h, tm-rs6000.h, xm-rs6000.h, rs6000-tdep.c,
rs6000-xdep.c, xcoffexec.c, xcoffread.c:
Merge in changes (mostly from IBM) for RS6000.
* breakpoint.c, buildsym.c, infptrace.c, stack.c, symtab.c:
More changes from IBM for RS6000. These are in machine-
independent code, and probably could do with some cleaning
up. The most questionable of these are #ifdef IBM6000.
* infrun.c, sparc-tdep.c: Pass a parameter (signal number)
to single_step() (for consistency with rs6000 and i860).
* utils.c: Allow the 1st arg to xrealloc to be NULL
(in which case do malloc). This removes the need for
some tests in xcoff code (and perhaps other places?).
* coffread.c: Removed variables last_source_file,
type_vector, and type_vector_length as these are now
defined by buildsym.[ch].
* defs.h: Remove prototypes for malloc and realloc, since
these should only be used to implement xmalloc and xrealloc,
and they conflict with <stdlib.h> in AIX - where they
return void* even when __STDC__ isn't defined. Sigh.
* munch: Recognize *initialize* in data as well as text
(AIX uses data). Also, incorporate a patch from Garrett
Wollman <wollman@uvm-gen.uvm.edu> to make the sed script
much more sensible, by only trying to match the name of
the initialize_foo function, and not the junk before it.
Thu Feb 27 20:07:43 1992 Stu Grossman (grossman at cygnus.com)
* breakpoint.c (breakpoint_re_set_one): Don't reset breakpoint

View File

@ -842,6 +842,10 @@ end_symtab (end_addr, sort_pending, sort_linevec, objfile)
blockvector = make_blockvector (objfile);
}
#ifdef PROCESS_LINENUMBER_HOOK
PROCESS_LINENUMBER_HOOK (); /* Needed for aixcoff. */
#endif
/* Now create the symtab objects proper, one for each subfile. */
/* (The main file is the last one on the chain.) */

View File

@ -307,7 +307,7 @@ resume (step, sig)
#ifdef NO_SINGLE_STEP
if (step) {
single_step(); /* Do it the hard way, w/temp breakpoints */
single_step(sig); /* Do it the hard way, w/temp breakpoints */
step = 0; /* ...and don't ask hardware to do it. */
}
#endif
@ -555,7 +555,7 @@ child_create_inferior (exec_file, allargs, env)
#ifdef NEED_POSIX_SETPGID
debug_setpgrp = setpgid (0, 0);
#else
#ifdef USG
#if defined(USG) && !defined(SETPGRP_ARGS)
debug_setpgrp = setpgrp ();
#else
debug_setpgrp = setpgrp (getpid (), getpid ());
@ -916,7 +916,7 @@ wait_for_inferior ()
will be set and we should check whether we've hit the
step breakpoint. */
if (stop_signal == SIGTRAP && trap_expected
&& step_resume_break_address == NULL)
&& step_resume_break_address == 0)
bpstat_clear (&stop_bpstat);
else
{
@ -1046,7 +1046,7 @@ wait_for_inferior ()
/* Need to blow away step-resume breakpoint, as it
interferes with us */
remove_step_breakpoint ();
step_resume_break_address = NULL;
step_resume_break_address = 0;
stop_step_resume_break = 0;
#if 0 /* FIXME - Need to implement nested temporary breakpoints */
@ -1409,7 +1409,7 @@ wait_for_inferior ()
breakpoints_inserted = 0;
}
else if (!breakpoints_inserted &&
(step_resume_break_address != NULL || !another_trap))
(step_resume_break_address != 0 || !another_trap))
{
insert_step_breakpoint ();
breakpoints_failed = insert_breakpoints ();

View File

@ -20,7 +20,7 @@ if test "`$MUNCH_NM main.o | egrep main | egrep FUNC | egrep GLOB`" != "" ; then
# System V Release 4 style nm
$MUNCH_NM $* | egrep '|__?initialize_' | egrep FUNC | \
sed -e 's/^.*\(_initialize_[a-zA-Z0-9_]*\).*$/ {extern void \1 (); \1 ();}/'
elif test "`$MUNCH_NM main.o | egrep 'T _?main$'`" = "" ; then
elif test "`$MUNCH_NM main.o | egrep '[TD] _?main$'`" = "" ; then
# System V style nm
shift;
$MUNCH_NM $* | egrep '^(.*[^a-zA-Z_]_|_)_?initialize_.*\.text' | \
@ -28,8 +28,8 @@ elif test "`$MUNCH_NM main.o | egrep 'T _?main$'`" = "" ; then
else
# BSD style nm
# We now accept either text or data symbols, since the RT/PC uses data.
$MUNCH_NM -p $* | egrep '[TD] *_?_initialize_' | \
sed -e 's/^.*[TD] *_*\(.*\)/ {extern void _\1 (); _\1 ();}/'
$MUNCH_NM -p $* | egrep '[TD] *_?[_.]initialize_' | \
sed -e 's/^.*\(initialize_.*\)/ {extern void _\1 (); _\1 ();}/'
fi
echo '}'

View File

@ -46,190 +46,6 @@ extern int attach_flag;
/* Nonzero if we just simulated a single step break. */
int one_stepped;
#if 0
/* This is Damon's implementation of single step simulation. It suffers the
following program:
1 main () {
2 char buf[10];
3 puts ("test");
4 strcmp (buf, "test"); puts ("test");
5 exit (0);
6 }
You cannot `next' on line 4 in the above program. gdb puts a breakpoint
to the return address of `strcmp', and when execution arrives that point,
it is still in the line range and gdb attemps to resume it with single
steps. At that point the breakpoint at step_resume_break_address (return
address of strcmp) and single step's breakpoint mixes up and we end up
with a breakpoint which its shadow and itself are identical.
Fix that problem and use this version. FIXMEmgo.
*/
static struct sstep_breaks {
int address;
int data;
} tbreak[2];
/*
* branch_dest - calculate all places the current instruction may go
*/
static
branch_dest(tb)
register struct sstep_breaks *tb;
{
register ulong opcode, iar;
long instr;
int immediate, absolute;;
iar = read_pc(); /* current IAR */
target_read_memory(iar, &instr, sizeof (instr)); /* current inst */
opcode = instr >> 26;
absolute = instr & 2;
tb[1].address = -1;
switch (opcode) {
case 0x10: /* branch conditional */
immediate = ((instr & ~3) << 16) >> 16;
/*
* two possible locations for next instruction
*/
tb[0].address = iar + 4;
tb[1].address = immediate + (absolute ? 0 : iar);
break;
case 0x12: /* branch unconditional */
immediate = ((instr & ~3) << 6) >> 6;
/*
* only one possible location for next instr
*/
tb[0].address = immediate + (absolute ? 0 : iar);
break;
case 0x13: /* branch conditional register */
/*
* WE NEED TO CHECK THE CR HERE, TO SEE IF THIS IS
* REALLY UNCONDITIONAL.
*/
tb++->address = iar + 4;
switch ((instr >> 1) & 0x3ff) {
case 0x10: /* branch conditional register */
tb->address = read_register(LR_REGNUM) & ~3;
sigtramp_chk(tb); /* return from sig handler? */
break;
case 0x210: /* branch cond to CTR */
tb->address = read_register(CTR_REGNUM) & ~3;
sigtramp_chk(tb); /* return from sig handler? */
break;
default:
/*
* not a branch.
*/
tb->address = iar + 4;
break;
}
break;
default:
/*
* not a branch, flow proceeds normally
*/
tb->address = iar + 4;
break;
}
}
/*
* sigtramp_chk - heuristic check to see if we think we are returning
* from a signal handler.
*
* Input:
* tb - ^ to a single step branch location
*
* Note:
* When we are at the "br" instruction returning to a signal handler,
* we return in user mode to an address in the kernel. If the
* segment of the branch target is 0, we may very well be in a
* signal handler. From scrounging through this code, we note that
* register 29 has the signal context pointer, from which we can
* determine where we will end up next.
*/
sigtramp_chk(tb)
register struct sstep_breaks *tb; {
struct sigcontext sc;
if (tb->address & 0xf0000000)
return; /* can't have been sigtramp */
if (target_read_memory(read_register(GPR29), &sc, sizeof (sc)))
return; /* read fails, heuristic fails */
if ((sc.sc_jmpbuf.jmp_context.iar & 0xf0000000) == 0x10000000) {
/*
* looks like it might be ok.....
*/
tb->address = sc.sc_jmpbuf.jmp_context.iar;
}
}
/*
* single_step - no trace mode harware support, or software support.
* sigh.
*/
single_step(signal) {
register i;
if (!one_stepped) {
/*
* need to set breakpoints for single step.
* figure out all places the current instruction could go.
*/
branch_dest(&tbreak[0]);
/*
* always at least one place to go to
*/
target_insert_breakpoint(tbreak[0].address, &tbreak[0].data);
/*
* if there is another possible location, set a breakpoint there
* as well.
*/
if (tbreak[1].address != -1)
target_insert_breakpoint(tbreak[1].address, &tbreak[1].data);
one_stepped = 1;
ptrace(PT_CONTINUE, inferior_pid, 1, signal, 0);
} else {
/*
* need to clear the breakpoints.
*/
for (i = 0; i < 2; ++i)
if (tbreak[i].address != -1)
target_remove_breakpoint(tbreak[i].address, &tbreak[i].data);
one_stepped = 0;
}
return 1;
}
#else /* !DAMON'S VERSION */
/* Breakpoint shadows for the single step instructions will be kept here. */
static struct sstep_breaks {
@ -280,7 +96,7 @@ branch_dest (opcode, instr, pc, safety)
default: return -1;
}
return (dest < 0x10000000) ? safety : dest;
return (dest < TEXT_SEGMENT_BASE) ? safety : dest;
}
@ -309,6 +125,10 @@ int signal;
opcode = insn >> 26;
breaks[1] = branch_dest (opcode, insn, loc, breaks[0]);
/* Don't put two breakpoints on the same address. */
if (breaks[1] == breaks[0])
breaks[1] = -1;
stepBreaks[1].address = -1;
for (ii=0; ii < 2; ++ii) {
@ -324,7 +144,7 @@ int signal;
}
one_stepped = 1;
ptrace (PT_CONTINUE, inferior_pid, 1, signal);
ptrace (PT_CONTINUE, inferior_pid, 1, signal, 0);
}
else {
@ -336,10 +156,9 @@ int signal;
one_stepped = 0;
}
errno = 0;
return 1;
}
#endif /* !DAMON's version of single step. */
/* return pc value after skipping a function prologue. */
@ -360,8 +179,6 @@ int pc;
pc += 4;
op = read_memory_integer (pc, 4);
}
else /* else, this is a frameless invocation */
return pc;
if ((op & 0xfc00003e) == 0x7c000026) { /* mfcr Rx */
pc += 4;
@ -373,10 +190,12 @@ int pc;
op = read_memory_integer (pc, 4);
}
#if 0
if ((op & 0xfc1f0000) == 0xd8010000) { /* stfd Rx,NUM(r1) */
pc += 4; /* store floating register double */
op = read_memory_integer (pc, 4);
}
#endif
if ((op & 0xfc1f0000) == 0xbc010000) { /* stm Rx, NUM(r1) */
pc += 4;
@ -396,23 +215,32 @@ int pc;
op = read_memory_integer (pc, 4);
}
while ((op & 0xfc1f0000) == 0x90010000) { /* st r?, NUM(r1) */
pc += 4;
op = read_memory_integer (pc, 4);
}
/* store parameters into stack */
while(
(op & 0xfc1f0000) == 0xd8010000 || /* stfd Rx,NUM(r1) */
(op & 0xfc1f0000) == 0x90010000 || /* st r?, NUM(r1) */
(op & 0xfc000000) == 0xfc000000 || /* frsp, fp?, .. */
(op & 0xd0000000) == 0xd0000000) /* stfs, fp?, .. */
{
pc += 4; /* store fpr double */
op = read_memory_integer (pc, 4);
}
if (op == 0x603f0000) { /* oril r31, r1, 0x0 */
pc += 4; /* this happens if r31 is used as */
op = read_memory_integer (pc, 4); /* frame ptr. (gcc does that) */
if ((op >> 16) == 0x907f) { /* st r3, NUM(r31) */
pc += 4;
tmp = 0;
while ((op >> 16) == (0x907f + tmp)) { /* st r3, NUM(r31) */
pc += 4; /* st r4, NUM(r31), ... */
op = read_memory_integer (pc, 4);
tmp += 0x20;
}
}
return pc;
}
/* text start and end addresses in virtual memory. */
CORE_ADDR text_start;
@ -424,10 +252,21 @@ CORE_ADDR text_end;
frames, etc.
*************************************************************************/
/* The total size of dummy frame is 436, which is;
32 gpr's - 128 bytes
32 fpr's - 256 "
7 the rest - 28 "
and 24 extra bytes for the callee's link area. The last 24 bytes
for the link area might not be necessary, since it will be taken
care of by push_arguments(). */
#define DUMMY_FRAME_SIZE 436
#define DUMMY_FRAME_ADDR_SIZE 10
/* Make sure you initialize these in somewhere, in case gdb gives up what it
was debugging and starts debugging something else. FIXMEmgo */
was debugging and starts debugging something else. FIXMEibm */
static int dummy_frame_count = 0;
static int dummy_frame_size = 0;
@ -464,15 +303,13 @@ push_dummy_frame ()
before writing register values into the new frame, decrement and update
%sp first in order to secure your frame. */
write_register (SP_REGNUM, sp-408);
write_register (SP_REGNUM, sp-DUMMY_FRAME_SIZE);
#if 1
/* gdb relies on the state of current_frame. We'd better update it,
otherwise things like do_registers_info() wouldn't work properly! */
flush_cached_frames ();
set_current_frame (create_new_frame (sp-408, pc));
#endif /* 0 */
set_current_frame (create_new_frame (sp-DUMMY_FRAME_SIZE, pc));
/* save program counter in link register's space. */
write_memory (sp+8, &pc, 4);
@ -488,12 +325,17 @@ push_dummy_frame ()
for (ii=1; ii <=32; ++ii)
write_memory (sp-256-(ii*4), &registers[REGISTER_BYTE (32-ii)], 4);
/* so far, 32*2 + 32 words = 384 bytes have been written. We need 6 words
(24 bytes) for the rest of the registers. It brings the total to 408
bytes.
save sp or so call back chain right here. */
write_memory (sp-408, &sp, 4);
sp -= 408;
/* so far, 32*2 + 32 words = 384 bytes have been written.
7 extra registers in our register set: pc, ps, cnd, lr, cnt, xer, mq */
for (ii=1; ii <= (LAST_SP_REGNUM-FIRST_SP_REGNUM+1); ++ii) {
write_memory (sp-384-(ii*4),
&registers[REGISTER_BYTE (FPLAST_REGNUM + ii)], 4);
}
/* Save sp or so called back chain right here. */
write_memory (sp-DUMMY_FRAME_SIZE, &sp, 4);
sp -= DUMMY_FRAME_SIZE;
/* And finally, this is the back chain. */
write_memory (sp+8, &pc, 4);
@ -505,12 +347,13 @@ push_dummy_frame ()
In rs6000 when we push a dummy frame, we save all of the registers. This
is usually done before user calls a function explicitly.
After a dummy frame is pushed, some instructions are copied into stack, and
stack pointer is decremented even more. Since we don't have a frame pointer to
get back to the parent frame of the dummy, we start having trouble poping it.
Therefore, we keep a dummy frame stack, keeping addresses of dummy frames as
such. When poping happens and when we detect that was a dummy frame, we pop
it back to its parent by using dummy frame stack (`dummy_frame_addr' array).
After a dummy frame is pushed, some instructions are copied into stack,
and stack pointer is decremented even more. Since we don't have a frame
pointer to get back to the parent frame of the dummy, we start having
trouble poping it. Therefore, we keep a dummy frame stack, keeping
addresses of dummy frames as such. When poping happens and when we
detect that was a dummy frame, we pop it back to its parent by using
dummy frame stack (`dummy_frame_addr' array).
*/
pop_dummy_frame ()
@ -528,7 +371,13 @@ pop_dummy_frame ()
read_memory (sp-256-(ii*4), &registers[REGISTER_BYTE (32-ii)], 4);
}
read_memory (sp-400, &registers [REGISTER_BYTE(PC_REGNUM)], 4);
/* restore the rest of the registers. */
for (ii=1; ii <=(LAST_SP_REGNUM-FIRST_SP_REGNUM+1); ++ii)
read_memory (sp-384-(ii*4),
&registers[REGISTER_BYTE (FPLAST_REGNUM + ii)], 4);
read_memory (sp-(DUMMY_FRAME_SIZE-8),
&registers [REGISTER_BYTE(PC_REGNUM)], 4);
/* when a dummy frame was being pushed, we had to decrement %sp first, in
order to secure astack space. Thus, saved %sp (or %r1) value, is not the

View File

@ -39,6 +39,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <sys/stat.h>
#include <sys/core.h>
#include <sys/ldr.h>
#include <sys/utsname.h>
extern int errno;
extern int attach_flag;
@ -60,6 +61,7 @@ static int special_regs[] = {
extern int one_stepped;
void
fetch_inferior_registers (regno)
int regno;
{
@ -196,30 +198,19 @@ fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr)
frameless_function_invocation (fi)
struct frame_info *fi;
{
int ret;
CORE_ADDR func_start, after_prologue;
CORE_ADDR func_start;
int frameless, dummy;
#if 0
func_start = (LOAD_ADDR (get_pc_function_start (fi->pc)) +
FUNCTION_START_OFFSET);
#else
func_start = get_pc_function_start (fi->pc) + FUNCTION_START_OFFSET;
#endif
if (func_start)
{
after_prologue = func_start;
SKIP_PROLOGUE (after_prologue);
ret = (after_prologue == func_start);
}
else
/* If we can't find the start of the function, we don't really */
/* know whether the function is frameless, but we should be */
/* able to get a reasonable (i.e. best we can do under the */
/* circumstances) backtrace by saying that it isn't. */
ret = 0;
return ret;
/* If we failed to find the start of the function, it is a mistake
to inspect the instructions. */
if (!func_start)
return 0;
function_frame_info (func_start, &frameless, &dummy, &dummy, &dummy);
return frameless;
}
@ -245,8 +236,10 @@ unsigned int pid;
errno = 0;
ptrace(PT_LDINFO, pid, ldi, MAX_LOAD_SEGS * sizeof(*ldi), ldi);
if (errno)
if (errno) {
perror_with_name ("ptrace ldinfo");
return 0;
}
vmap_ldinfo(ldi);
@ -255,8 +248,10 @@ unsigned int pid;
} while (ldi->ldinfo_next
&& (ldi = (void *) (ldi->ldinfo_next + (char *) ldi)));
#if 0
/* Now that we've jumbled things around, re-sort them. */
sort_minimal_symbols ();
#endif
/* relocate the exec and core sections as well. */
vmap_exec ();
@ -275,13 +270,13 @@ typedef struct {
static LoadInfo *loadInfo = NULL;
static int loadInfoLen = 0;
static int loadInfoTocIndex = 0;
static int loadInfoTextIndex = 0;
int aix_loadInfoTextIndex = 0;
xcoff_init_loadinfo ()
{
loadInfoTocIndex = 0;
loadInfoTextIndex = 0;
aix_loadInfoTextIndex = 0;
if (loadInfoLen == 0) {
loadInfo = (void*) xmalloc (sizeof (LoadInfo) * LOADINFOLEN);
@ -297,7 +292,7 @@ free_loadinfo ()
loadInfo = NULL;
loadInfoLen = 0;
loadInfoTocIndex = 0;
loadInfoTextIndex = 0;
aix_loadInfoTextIndex = 0;
}
@ -313,24 +308,26 @@ xcoff_add_toc_to_loadinfo (unsigned long tocaddr)
add_text_to_loadinfo (unsigned long textaddr, unsigned long dataaddr)
{
while (loadInfoTextIndex >= loadInfoLen) {
while (aix_loadInfoTextIndex >= loadInfoLen) {
loadInfoLen += LOADINFOLEN;
loadInfo = (void*) xrealloc (loadInfo, sizeof(LoadInfo) * loadInfoLen);
}
loadInfo [loadInfoTextIndex].textorg = textaddr;
loadInfo [loadInfoTextIndex].dataorg = dataaddr;
++loadInfoTextIndex;
loadInfo [aix_loadInfoTextIndex].textorg = textaddr;
loadInfo [aix_loadInfoTextIndex].dataorg = dataaddr;
++aix_loadInfoTextIndex;
}
unsigned long
find_toc_address (unsigned long pc)
{
int ii, toc_entry;
int ii, toc_entry, tocbase = 0;
for (ii=0; ii < loadInfoTextIndex; ++ii)
if (pc > loadInfo [ii].textorg)
for (ii=0; ii < aix_loadInfoTextIndex; ++ii)
if (pc > loadInfo [ii].textorg && loadInfo [ii].textorg > tocbase) {
toc_entry = ii;
tocbase = loadInfo [ii].textorg;
}
return loadInfo [toc_entry].dataorg + loadInfo [toc_entry].toc_offset;
}
@ -342,11 +339,14 @@ find_toc_address (unsigned long pc)
exec_one_dummy_insn ()
{
#define DUMMY_INSN_ADDR 0x10000200
#define DUMMY_INSN_ADDR (TEXT_SEGMENT_BASE)+0x200
unsigned long shadow;
unsigned int status, pid;
/* We plant one dummy breakpoint into DUMMY_INSN_ADDR address. We assume that
this address will never be executed again by the real code. */
target_insert_breakpoint (DUMMY_INSN_ADDR, &shadow);
errno = 0;
@ -361,3 +361,24 @@ exec_one_dummy_insn ()
target_remove_breakpoint (DUMMY_INSN_ADDR, &shadow);
}
/* Return the number of initial trap signals we need to ignore once the inferior
process starts running. This will be `2' for aix-3.1, `3' for aix-3.2 */
int
aix_starting_inferior_traps ()
{
struct utsname unamebuf;
if (uname (&unamebuf) == -1)
fatal ("uname(3) failed.");
/* Assume the future versions will behave like 3.2 and return '3' for
anything other than 3.1x. The extra trap in 3.2 is the "trap after the
program is loaded" signal. */
if (unamebuf.version[0] == '3' && unamebuf.release[0] == '1')
return 2;
else
return 3;
}

View File

@ -1,13 +1,13 @@
/* IBM RS/6000 instruction set definitions, for GNU software. */
struct rs6000_insn {
typedef struct rs6000_insn {
char *operator; /* opcode name */
char *opr_ext; /* opcode name extension */
char *format; /* opcode format */
char p_opcode; /* primary opcode */
int e_opcode; /* extended opcode */
char oprnd_format[6]; /* operand format */
};
} OPCODE;
/* operand format specifiers */

View File

@ -517,6 +517,17 @@ lookup_symbol (name, block, namespace, is_a_field_of_this, symtab)
bv = BLOCKVECTOR (s);
block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
sym = lookup_block_symbol (block, msymbol -> name, namespace);
#if 0 /* defined(IBM6000) */
/* we kept static functions in misc_function_vector as well as
in static scope. We want to find them in the symbol table. */
if (!sym) {
block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
sym = lookup_block_symbol (block, misc_function_vector[ind].name,
namespace);
}
#endif
/* sym == 0 if symbol was found in the minimal symbol table
but not in the symtab.
Return 0 to use the msymbol definition of "foo_".

View File

@ -18,14 +18,32 @@ You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* A successful ptrace(continue) might return errno != 0 in this particular port
of rs6000. I am not sure why. We will use this kludge and ignore it until
we figure out the real problem. */
#define AIX_BUGGY_PTRACE_CONTINUE \
{ \
int ret = ptrace (PT_CONTINUE, inferior_pid, (int *)1, signal, 0); \
if (errno) { \
/* printf ("ret: %d, errno: %d, signal: %d\n", ret, errno, signal); */ \
errno = 0; } \
}
extern int symtab_relocated;
/* Minimum possible text address in AIX */
#define TEXT_SEGMENT_BASE 0x10000000
/* text addresses in a core file does not necessarily match to symbol table,
if symbol table relocation wasn't done yet. */
#define CORE_NEEDS_RELOCATION(PC) \
if (!symtab_relocated && !inferior_pid && (PC) > 0x10000000) \
(PC) -= (0x10000000 + text_adjustment (exec_bfd));
if (!symtab_relocated && !inferior_pid && (PC) > TEXT_SEGMENT_BASE) \
(PC) -= ( TEXT_SEGMENT_BASE + text_adjustment (exec_bfd));
/* Conversion between a register number in stab string to actual register num. */
@ -89,14 +107,40 @@ struct fp_status {
/* When a child process is just starting, we sneak in and relocate
the symbol table (and other stuff) after the dynamic linker has
figured out where they go. */
figured out where they go. But we want to do this relocation just
once. */
#define SOLIB_CREATE_INFERIOR_HOOK(PID) aixcoff_relocate_symtab (PID)
extern int aix_loadInfoTextIndex;
#define SOLIB_CREATE_INFERIOR_HOOK() \
do { \
if (aix_loadInfoTextIndex == 0) \
aixcoff_relocate_symtab (pid); \
} while (0)
/* In aix, number of the trap signals we need to skip over once the
inferior process starts running is different in version 3.1 and 3.2.
This will be 2 for version 3.1x, 3 for version 3.2x. */
#define START_INFERIOR_TRAPS_EXPECTED aix_starting_inferior_traps ()
/* In aixcoff, we cannot process line numbers when we see them. This is
mainly because we don't know the boundaries of the include files. So,
we postpone that, and then enter and sort(?) the whole line table at
once, when we are closing the current symbol table in end_symtab(). */
#define PROCESS_LINENUMBER_HOOK() aix_process_linenos ()
/* When a target process or core-file has been attached, we sneak in
and figure out where the shared libraries have got to. */
and figure out where the shared libraries have got to. In case there
is no inferior_process exists (e.g. bringing up a core file), we can't
attemtp to relocate symbol table, since we don't have information about
load segments. */
#define SOLIB_ADD(a, b, c) aixcoff_relocate_symtab (inferior_pid)
#define SOLIB_ADD(a, b, c) \
if (inferior_pid) aixcoff_relocate_symtab (inferior_pid)
/* Immediately after a function call, return the saved pc.
Can't go through the frames for this because on some machines
@ -173,7 +217,7 @@ extern char registers[];
There should be NUM_REGS strings in this initializer. */
#define REGISTER_NAMES \
{"r0", "sp", "toc", "r3", "r4", "r5", "r6", "r7", \
{"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \
"r8", "r9", "r10","r11","r12","r13","r14","r15", \
"r16","r17","r18","r19","r20","r21","r22","r23", \
"r24","r25","r26","r27","r28","r29","r30","r31", \
@ -194,6 +238,8 @@ extern char registers[];
#define SP_REGNUM 1 /* Contains address of top of stack */
#define TOC_REGNUM 2 /* TOC register */
#define FP0_REGNUM 32 /* Floating point register 0 */
#define GP0_REGNUM 0 /* GPR register 0 */
#define FP0_REGNUM 32 /* FPR (Floating point) register 0 */
#define FPLAST_REGNUM 63 /* Last floating point register */
/* Special purpose registers... */
@ -307,7 +353,21 @@ extern unsigned int rs6000_struct_return_address;
of type TYPE, given in virtual format. */
#define STORE_RETURN_VALUE(TYPE,VALBUF) \
printf ("FIXMEmgo! STORE_RETURN_VALUE not implemented yet!\n")
{ \
if (TYPE_CODE (TYPE) == TYPE_CODE_FLT) \
\
/* Floating point values are returned starting from FPR1 and up. \
Say a double_double_double type could be returned in \
FPR1/FPR2/FPR3 triple. */ \
\
write_register_bytes (REGISTER_BYTE (FP0_REGNUM+1), (VALBUF), \
TYPE_LENGTH (TYPE)); \
else \
/* Everything else is returned in GPR3 and up. */ \
write_register_bytes (REGISTER_BYTE (GP0_REGNUM+3), (VALBUF), \
TYPE_LENGTH (TYPE)); \
}
/* Extract from an array REGBUF containing the (raw) register state
the address in which a function should return its structure value,
@ -318,7 +378,12 @@ extern unsigned int rs6000_struct_return_address;
/* Do implement the attach and detach commands. */
#define ATTACH_DETACH /* FIXMEmgo! Not implemented yet! */
#define ATTACH_DETACH
/* infptrace.c requires those. */
#define PTRACE_ATTACH 30
#define PTRACE_DETACH 31
/* Describe the pointer in each stack frame to the previous stack frame
@ -453,3 +518,8 @@ extern unsigned int rs6000_struct_return_address;
#define FIX_CALL_DUMMY(dummyname, pc, fun, nargs, args, type, using_gcc) \
fix_call_dummy(dummyname, pc, fun, nargs, type)
/* Flag for machine-specific stuff in shared files. FIXME */
#ifndef IBM6000
#define IBM6000
#endif

View File

@ -42,9 +42,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Prototypes for local functions */
static void
add_to_section_table PARAMS ((bfd *, sec_ptr, PTR));
static void
file_command PARAMS ((char *, int));
@ -59,6 +56,8 @@ struct section_table *exec_sections, *exec_sections_end;
int write_files = 0;
extern int info_verbose;
bfd *exec_bfd; /* needed by core.c */
extern char *getenv();
@ -66,6 +65,7 @@ extern void child_create_inferior (), child_attach ();
extern void add_syms_addr_command ();
extern void symbol_file_command ();
static void exec_files_info();
extern struct objfile *lookup_objfile_bfd ();
/*
* the vmap struct is used to describe the virtual address space of
@ -102,18 +102,29 @@ extern struct target_ops exec_ops;
/* exec_close - done with exec file, clean up all resources. */
static void
exec_close(quitting) {
register struct vmap *vp, *nxt;
exec_close(quitting)
{
register struct vmap *vp, *nxt;
struct objfile *obj;
for (nxt = vmap; vp = nxt; )
{
nxt = vp->nxt;
for (nxt = vmap; vp = nxt; ) {
nxt = vp->nxt;
bfd_close(vp->bfd);
free_named_symtabs(vp->name, vp->member); /* XXX */
free(vp);
}
vmap = 0;
exec_bfd = 0;
/* if there is an objfile associated with this bfd,
free_objfile() will do proper cleanup of objfile *and* bfd. */
if (obj = lookup_objfile_bfd (vp->bfd))
free_objfile (obj);
else
bfd_close(vp->bfd);
free_named_symtabs(vp->name);
free(vp);
}
vmap = 0;
exec_bfd = 0;
}
/*
@ -327,7 +338,8 @@ relocate_minimal_symbol (objfile, msymbol, arg1, arg2, arg3)
PTR arg2;
PTR arg3;
{
msymbol -> address += (int) arg1;
if (msymbol->address < TEXT_SEGMENT_BASE)
msymbol -> address += (int) arg1;
}
/* true, if symbol table and minimal symbol table are relocated. */
@ -391,24 +403,18 @@ struct stat *vip;
vmap_symtab_1(s, vp, old_start);
}
}
if (vp->tstart != old_start)
if (vp->tstart != old_start) {
iterate_over_msymbols (relocate_minimal_symbol,
(PTR) (vp->tstart - old_start),
(PTR) NULL, (PTR) NULL);
/* breakpoints need to be relocated as well. */
fixup_breakpoints (0, TEXT_SEGMENT_BASE, vp->tstart - old_start);
}
symtab_relocated = 1;
}
fixup_misc_vector (int disp)
{
int ii;
for (ii=0; ii < misc_function_count; ++ii)
if (misc_function_vector[ii].address < 0x10000000)
misc_function_vector[ii].address += disp;
}
vmap_symtab_1(s, vp, old_start)
register struct symtab *s;
register struct vmap *vp;
@ -429,12 +435,14 @@ CORE_ADDR old_start;
/*
* The line table must be relocated. This is only present for
* b.text sections, so only vp->text type maps need be considered.
* .text sections, so only vp->text type maps need be considered.
*/
l = LINETABLE (s);
len = l->nitems;
for (i = 0; i < len; i++)
if (l) {
len = l->nitems;
for (i = 0; i < len; i++)
l->item[i].pc += reloc;
}
/* if this symbol table is not relocatable, only line table should
be relocated and the rest ignored. */
@ -693,7 +701,6 @@ retry:
} while (ldi->ldinfo_next
&& (ldi = (void *) (ldi->ldinfo_next + (char *) ldi)));
breakpoint_re_set();
}
/*
@ -728,18 +735,17 @@ vmap_inferior() {
we just tail-call it with more arguments to select between them. */
int
xfer_memory (memaddr, myaddr, len, write, abfd, sections, sections_end)
xfer_memory (memaddr, myaddr, len, write, target)
CORE_ADDR memaddr;
char *myaddr;
int len;
int write;
bfd *abfd;
struct section_table *sections, *sections_end;
struct target_ops *target;
{
boolean res;
struct section_table *p;
CORE_ADDR nextsectaddr, memend;
boolean (*xfer_fn) ();
boolean (*xfer_fn) PARAMS ((bfd *, sec_ptr, PTR, file_ptr, bfd_size_type));
if (len <= 0)
abort();
@ -748,13 +754,13 @@ xfer_memory (memaddr, myaddr, len, write, abfd, sections, sections_end)
xfer_fn = write? bfd_set_section_contents: bfd_get_section_contents;
nextsectaddr = memend;
for (p = sections; p < sections_end; p++)
for (p = target->to_sections; p < target->to_sections_end; p++)
{
if (p->addr <= memaddr)
if (p->endaddr >= memend)
{
/* Entire transfer is within this section. */
res = xfer_fn (abfd, p->sec_ptr, myaddr, memaddr - p->addr, len);
res = xfer_fn (p->bfd, p->sec_ptr, myaddr, memaddr - p->addr, len);
return (res != false)? len: 0;
}
else if (p->endaddr <= memaddr)
@ -766,7 +772,7 @@ xfer_memory (memaddr, myaddr, len, write, abfd, sections, sections_end)
{
/* This section overlaps the transfer. Just do half. */
len = p->endaddr - memaddr;
res = xfer_fn (abfd, p->sec_ptr, myaddr, memaddr - p->addr, len);
res = xfer_fn (p->bfd, p->sec_ptr, myaddr, memaddr - p->addr, len);
return (res != false)? len: 0;
}
else if (p->addr < nextsectaddr)
@ -779,24 +785,31 @@ xfer_memory (memaddr, myaddr, len, write, abfd, sections, sections_end)
return - (nextsectaddr - memaddr); /* Next boundary where we can help */
}
/* The function called by target_xfer_memory via our target_ops */
int
exec_xfer_memory (memaddr, myaddr, len, write)
CORE_ADDR memaddr;
char *myaddr;
int len;
int write;
void
print_section_info (t, abfd)
struct target_ops *t;
bfd *abfd;
{
return xfer_memory (memaddr, myaddr, len, write,
exec_bfd, exec_sections, exec_sections_end);
}
#if 1
struct section_table *p;
/*
* exec_files_info - "info files" command processor
*/
static void
exec_files_info() {
printf_filtered ("\t`%s', ", bfd_get_filename(abfd));
wrap_here (" ");
printf_filtered ("file type %s.\n", bfd_get_target(abfd));
for (p = t->to_sections; p < t->to_sections_end; p++) {
printf_filtered ("\t%s", local_hex_string_custom (p->addr, "08"));
printf_filtered (" - %s", local_hex_string_custom (p->endaddr, "08"));
if (info_verbose)
printf_filtered (" @ %s",
local_hex_string_custom (p->sec_ptr->filepos, "08"));
printf_filtered (" is %s", bfd_section_name (p->bfd, p->sec_ptr));
if (p->bfd != abfd) {
printf_filtered (" in %s", bfd_get_filename (p->bfd));
}
printf_filtered ("\n");
}
#else
register struct vmap *vp = vmap;
if (!vp)
@ -814,6 +827,14 @@ exec_files_info() {
, *vp->member ? "(" : ""
, vp->member
, *vp->member ? ")" : "");
#endif
}
static void
exec_files_info (t)
struct target_ops *t;
{
print_section_info (t, exec_bfd);
}
#ifdef DAMON
@ -914,7 +935,7 @@ Specify the filename of the executable file.",
child_attach, 0, 0, 0, /* attach, detach, resume, wait, */
0, 0, /* fetch_registers, store_registers, */
0, 0, 0, /* prepare_to_store, conv_to, conv_from, */
exec_xfer_memory, exec_files_info,
xfer_memory, exec_files_info,
0, 0, /* insert_breakpoint, remove_breakpoint, */
0, 0, 0, 0, 0, /* terminal stuff */
0, 0, /* kill, load */

File diff suppressed because it is too large Load Diff

View File

@ -54,7 +54,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Setpgrp() takes arguments, unlike ordinary Sys V's. */
#define SETPGRP_ARGS
#define SETPGRP_ARGS 1
/* RS6000/AIXCOFF does not support PT_STEP. Has to be simulated. */
@ -65,3 +65,13 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#define XCOFF_INIT_LOADINFO() xcoff_init_loadinfo()
#define XCOFF_ADD_TOC_TO_LOADINFO(x) xcoff_add_toc_to_loadinfo (x)
/* AIX's assembler doesn't grok dollar signs in identifiers.
So we use dots instead. This item must be coordinated with G++. */
#undef CPLUS_MARKER
#define CPLUS_MARKER '.'
/* Flag for machine-specific stuff in shared files. FIXME */
#ifndef IBM6000
#define IBM6000
#endif