/* Target-dependent code for the ALPHA architecture, for GDB, the GNU Debugger.
- Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
+ Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
Free Software Foundation, Inc.
This file is part of GDB.
#include "regcache.h"
#include "doublest.h"
#include "arch-utils.h"
+#include "osabi.h"
+#include "block.h"
#include "elf-bfd.h"
static gdbarch_register_convert_to_virtual_ftype
alpha_register_convert_to_virtual;
static gdbarch_register_convert_to_raw_ftype alpha_register_convert_to_raw;
-static gdbarch_store_struct_return_ftype alpha_store_struct_return;
-static gdbarch_extract_return_value_ftype alpha_extract_return_value;
-static gdbarch_store_return_value_ftype alpha_store_return_value;
-static gdbarch_extract_struct_value_address_ftype
+static gdbarch_deprecated_extract_return_value_ftype alpha_extract_return_value;
+static gdbarch_deprecated_extract_struct_value_address_ftype
alpha_extract_struct_value_address;
static gdbarch_use_struct_convention_ftype alpha_use_struct_convention;
static gdbarch_frame_locals_address_ftype alpha_frame_locals_address;
static gdbarch_skip_prologue_ftype alpha_skip_prologue;
-static gdbarch_get_saved_register_ftype alpha_get_saved_register;
static gdbarch_saved_pc_after_call_ftype alpha_saved_pc_after_call;
-static gdbarch_frame_chain_ftype alpha_frame_chain;
-static gdbarch_frame_saved_pc_ftype alpha_frame_saved_pc;
-static gdbarch_frame_init_saved_regs_ftype alpha_frame_init_saved_regs;
-static gdbarch_push_arguments_ftype alpha_push_arguments;
-static gdbarch_push_dummy_frame_ftype alpha_push_dummy_frame;
-static gdbarch_pop_frame_ftype alpha_pop_frame;
static gdbarch_fix_call_dummy_ftype alpha_fix_call_dummy;
-static gdbarch_init_frame_pc_first_ftype alpha_init_frame_pc_first;
-static gdbarch_init_extra_frame_info_ftype alpha_init_extra_frame_info;
static gdbarch_get_longjmp_target_ftype alpha_get_longjmp_target;
}
\f
-static char *
+static const char *
alpha_register_name (int regno)
{
static char *register_names[] =
"f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
"f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
"f24", "f25", "f26", "f27", "f28", "f29", "f30", "fpcr",
- "pc", "vfp",
+ "pc", "vfp", "unique",
};
if (regno < 0)
#define SIGFRAME_REGSAVE_OFF (4 * 8)
#define SIGFRAME_FPREGSAVE_OFF (SIGFRAME_REGSAVE_OFF + 32 * 8 + 8)
#endif
- if (frame->signal_handler_caller)
+ if ((get_frame_type (frame) == SIGTRAMP_FRAME))
{
CORE_ADDR sigcontext_addr;
for (ireg = 0; ireg < 32; ireg++)
{
reg_position = sigcontext_addr + SIGFRAME_REGSAVE_OFF + ireg * 8;
- frame->saved_regs[ireg] = reg_position;
+ get_frame_saved_regs (frame)[ireg] = reg_position;
}
for (ireg = 0; ireg < 32; ireg++)
{
reg_position = sigcontext_addr + SIGFRAME_FPREGSAVE_OFF + ireg * 8;
- frame->saved_regs[FP0_REGNUM + ireg] = reg_position;
+ get_frame_saved_regs (frame)[FP0_REGNUM + ireg] = reg_position;
}
- frame->saved_regs[PC_REGNUM] = sigcontext_addr + SIGFRAME_PC_OFF;
+ get_frame_saved_regs (frame)[PC_REGNUM] = sigcontext_addr + SIGFRAME_PC_OFF;
return;
}
- proc_desc = frame->extra_info->proc_desc;
+ proc_desc = get_frame_extra_info (frame)->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
/* Fill in the offsets for the registers which gen_mask says
were saved. */
- reg_position = frame->frame + PROC_REG_OFFSET (proc_desc);
+ reg_position = get_frame_base (frame) + PROC_REG_OFFSET (proc_desc);
mask = PROC_REG_MASK (proc_desc);
returnreg = PROC_PC_REG (proc_desc);
register number. */
if (mask & (1 << returnreg))
{
- frame->saved_regs[returnreg] = reg_position;
+ get_frame_saved_regs (frame)[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))
{
- frame->saved_regs[ireg] = reg_position;
+ get_frame_saved_regs (frame)[ireg] = reg_position;
reg_position += 8;
}
/* Fill in the offsets for the registers which float_mask says
were saved. */
- reg_position = frame->frame + PROC_FREG_OFFSET (proc_desc);
+ reg_position = get_frame_base (frame) + PROC_FREG_OFFSET (proc_desc);
mask = PROC_FREG_MASK (proc_desc);
for (ireg = 0; ireg <= 31; ++ireg)
if (mask & (1 << ireg))
{
- frame->saved_regs[FP0_REGNUM + ireg] = reg_position;
+ get_frame_saved_regs (frame)[FP0_REGNUM + ireg] = reg_position;
reg_position += 8;
}
- frame->saved_regs[PC_REGNUM] = frame->saved_regs[returnreg];
+ get_frame_saved_regs (frame)[PC_REGNUM] = get_frame_saved_regs (frame)[returnreg];
}
static void
alpha_frame_init_saved_regs (struct frame_info *fi)
{
- if (fi->saved_regs == NULL)
+ if (get_frame_saved_regs (fi) == NULL)
alpha_find_saved_regs (fi);
- fi->saved_regs[SP_REGNUM] = fi->frame;
+ get_frame_saved_regs (fi)[SP_REGNUM] = get_frame_base (fi);
}
-static void
+static CORE_ADDR
alpha_init_frame_pc_first (int fromleaf, struct frame_info *prev)
{
- prev->pc = (fromleaf ? SAVED_PC_AFTER_CALL (prev->next) :
- prev->next ? FRAME_SAVED_PC (prev->next) : read_pc ());
+ return (fromleaf ? SAVED_PC_AFTER_CALL (get_next_frame (prev))
+ : get_next_frame (prev) ? DEPRECATED_FRAME_SAVED_PC (get_next_frame (prev))
+ : read_pc ());
}
static CORE_ADDR
read_next_frame_reg (struct frame_info *fi, int regno)
{
- for (; fi; fi = fi->next)
+ for (; fi; fi = get_next_frame (fi))
{
/* We have to get the saved sp from the sigcontext
if it is a signal handler frame. */
- if (regno == SP_REGNUM && !fi->signal_handler_caller)
- return fi->frame;
+ if (regno == SP_REGNUM && !(get_frame_type (fi) == SIGTRAMP_FRAME))
+ return get_frame_base (fi);
else
{
- if (fi->saved_regs == NULL)
+ if (get_frame_saved_regs (fi) == NULL)
alpha_find_saved_regs (fi);
- if (fi->saved_regs[regno])
- return read_memory_integer (fi->saved_regs[regno], 8);
+ if (get_frame_saved_regs (fi)[regno])
+ return read_memory_integer (get_frame_saved_regs (fi)[regno], 8);
}
}
return read_register (regno);
static CORE_ADDR
alpha_frame_saved_pc (struct frame_info *frame)
{
- alpha_extra_func_info_t proc_desc = frame->extra_info->proc_desc;
+ alpha_extra_func_info_t proc_desc = get_frame_extra_info (frame)->proc_desc;
/* We have to get the saved pc from the sigcontext
if it is a signal handler frame. */
- int pcreg = frame->signal_handler_caller ? PC_REGNUM
- : frame->extra_info->pc_reg;
+ int pcreg = ((get_frame_type (frame) == SIGTRAMP_FRAME)
+ ? PC_REGNUM
+ : get_frame_extra_info (frame)->pc_reg);
if (proc_desc && PROC_DESC_IS_DUMMY (proc_desc))
- return read_memory_integer (frame->frame - 8, 8);
+ return read_memory_integer (get_frame_base (frame) - 8, 8);
return read_next_frame_reg (frame, pcreg);
}
-static void
-alpha_get_saved_register (char *raw_buffer,
- int *optimized,
- CORE_ADDR *addrp,
- struct frame_info *frame,
- int regnum,
- enum lval_type *lval)
-{
- CORE_ADDR addr;
-
- if (!target_has_registers)
- error ("No registers.");
-
- /* Normal systems don't optimize out things with register numbers. */
- if (optimized != NULL)
- *optimized = 0;
- addr = find_saved_register (frame, regnum);
- if (addr != 0)
- {
- if (lval != NULL)
- *lval = lval_memory;
- if (regnum == SP_REGNUM)
- {
- if (raw_buffer != NULL)
- {
- /* Put it back in target format. */
- store_address (raw_buffer, REGISTER_RAW_SIZE (regnum),
- (LONGEST) addr);
- }
- if (addrp != NULL)
- *addrp = 0;
- return;
- }
- if (raw_buffer != NULL)
- target_read_memory (addr, raw_buffer, REGISTER_RAW_SIZE (regnum));
- }
- else
- {
- if (lval != NULL)
- *lval = lval_register;
- addr = REGISTER_BYTE (regnum);
- if (raw_buffer != NULL)
- read_register_gen (regnum, raw_buffer);
- }
- if (addrp != NULL)
- *addrp = addr;
-}
-
static CORE_ADDR
alpha_saved_pc_after_call (struct frame_info *frame)
{
- CORE_ADDR pc = frame->pc;
+ CORE_ADDR pc = get_frame_pc (frame);
CORE_ADDR tmp;
alpha_extra_func_info_t proc_desc;
int pcreg;
if (tmp != 0)
pc = tmp;
- proc_desc = find_proc_desc (pc, frame->next);
+ proc_desc = find_proc_desc (pc, get_next_frame (frame));
pcreg = proc_desc ? PROC_PC_REG (proc_desc) : ALPHA_RA_REGNUM;
- if (frame->signal_handler_caller)
+ if ((get_frame_type (frame) == SIGTRAMP_FRAME))
return alpha_frame_saved_pc (frame);
else
return read_register (pcreg);
if (start_pc < fence)
{
/* It's not clear to me why we reach this point when
- stop_soon_quietly, but with this test, at least we
+ stop_soon, but with this test, at least we
don't print out warnings for every child forked (eg, on
decstation). 22apr93 rich@cygnus.com. */
- if (!stop_soon_quietly)
+ if (stop_soon == NO_STOP_QUIETLY)
{
static int blurb_printed = 0;
struct frame_info *next_frame)
{
CORE_ADDR sp = read_next_frame_reg (next_frame, SP_REGNUM);
+ CORE_ADDR vfp = sp;
CORE_ADDR cur_pc;
int frame_size;
int has_frame_reg = 0;
unsigned long reg_mask = 0;
int pcreg = -1;
+ int regno;
if (start_pc == 0)
return NULL;
if ((word & 0xffff0000) == 0x23de0000) /* lda $sp,n($sp) */
{
if (word & 0x8000)
- frame_size += (-word) & 0xffff;
+ {
+ /* Consider only the first stack allocation instruction
+ to contain the static size of the frame. */
+ if (frame_size == 0)
+ frame_size += (-word) & 0xffff;
+ }
else
/* Exit loop if a positive stack adjustment is found, which
usually means that the stack cleanup code in the function
{
int reg = (word & 0x03e00000) >> 21;
reg_mask |= 1 << reg;
- temp_saved_regs[reg] = sp + (short) word;
+
+ /* Do not compute the address where the register was saved yet,
+ because we don't know yet if the offset will need to be
+ relative to $sp or $fp (we can not compute the address relative
+ to $sp if $sp is updated during the execution of the current
+ subroutine, for instance when doing some alloca). So just store
+ the offset for the moment, and compute the address later
+ when we know whether this frame has a frame pointer or not.
+ */
+ temp_saved_regs[reg] = (short) word;
/* Starting with OSF/1-3.2C, the system libraries are shipped
without local symbols, but they still contain procedure
}
else if ((word & 0xffe0ffff) == 0x6be08001) /* ret zero,reg,1 */
pcreg = (word >> 16) & 0x1f;
- else if (word == 0x47de040f) /* bis sp,sp fp */
- has_frame_reg = 1;
+ else if (word == 0x47de040f || word == 0x47fe040f) /* bis sp,sp fp */
+ {
+ /* ??? I am not sure what instruction is 0x47fe040f, and I
+ am suspecting that there was a typo and should have been
+ 0x47fe040f. I'm keeping it in the test above until further
+ investigation */
+ has_frame_reg = 1;
+ vfp = read_next_frame_reg (next_frame, ALPHA_GCC_FP_REGNUM);
+ }
}
if (pcreg == -1)
{
PROC_FRAME_REG (&temp_proc_desc) = ALPHA_GCC_FP_REGNUM;
else
PROC_FRAME_REG (&temp_proc_desc) = SP_REGNUM;
+
+ /* At this point, we know which of the Stack Pointer or the Frame Pointer
+ to use as the reference address to compute the saved registers address.
+ But in both cases, the processing above has set vfp to this reference
+ address, so just need to increment the offset of each saved register
+ by this address. */
+ for (regno = 0; regno < NUM_REGS; regno++)
+ {
+ if (reg_mask & 1 << regno)
+ temp_saved_regs[regno] += vfp;
+ }
+
PROC_FRAME_OFFSET (&temp_proc_desc) = frame_size;
PROC_REG_MASK (&temp_proc_desc) = reg_mask;
PROC_PC_REG (&temp_proc_desc) = (pcreg == -1) ? ALPHA_RA_REGNUM : pcreg;
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))
+ if (DEPRECATED_PC_IN_CALL_DUMMY (pc, 0, 0))
{
struct linked_proc_info *link;
CORE_ADDR sp = read_next_frame_reg (next_frame, SP_REGNUM);
alpha_frame_chain (struct frame_info *frame)
{
alpha_extra_func_info_t proc_desc;
- CORE_ADDR saved_pc = FRAME_SAVED_PC (frame);
+ CORE_ADDR saved_pc = DEPRECATED_FRAME_SAVED_PC (frame);
if (saved_pc == 0 || inside_entry_file (saved_pc))
return 0;
&& PROC_FRAME_OFFSET (proc_desc) == 0
/* The previous frame from a sigtramp frame might be frameless
and have frame size zero. */
- && !frame->signal_handler_caller)
+ && !(get_frame_type (frame) == SIGTRAMP_FRAME))
return alpha_frame_past_sigtramp_frame (frame, saved_pc);
else
return read_next_frame_reg (frame, PROC_FRAME_REG (proc_desc))
alpha_print_extra_frame_info (struct frame_info *fi)
{
if (fi
- && fi->extra_info
- && fi->extra_info->proc_desc
- && fi->extra_info->proc_desc->pdr.framereg < NUM_REGS)
+ && get_frame_extra_info (fi)
+ && get_frame_extra_info (fi)->proc_desc
+ && get_frame_extra_info (fi)->proc_desc->pdr.framereg < NUM_REGS)
printf_filtered (" frame pointer is at %s+%s\n",
- REGISTER_NAME (fi->extra_info->proc_desc->pdr.framereg),
- paddr_d (fi->extra_info->proc_desc->pdr.frameoffset));
+ REGISTER_NAME (get_frame_extra_info (fi)->proc_desc->pdr.framereg),
+ paddr_d (get_frame_extra_info (fi)->proc_desc->pdr.frameoffset));
}
static void
{
/* Use proc_desc calculated in frame_chain */
alpha_extra_func_info_t proc_desc =
- frame->next ? cached_proc_desc : find_proc_desc (frame->pc, frame->next);
-
- frame->extra_info = (struct frame_extra_info *)
- frame_obstack_alloc (sizeof (struct frame_extra_info));
-
- frame->saved_regs = NULL;
- frame->extra_info->localoff = 0;
- frame->extra_info->pc_reg = ALPHA_RA_REGNUM;
- frame->extra_info->proc_desc = proc_desc == &temp_proc_desc ? 0 : proc_desc;
+ get_next_frame (frame)
+ ? cached_proc_desc
+ : find_proc_desc (get_frame_pc (frame), get_next_frame (frame));
+
+ frame_extra_info_zalloc (frame, sizeof (struct frame_extra_info));
+
+ /* NOTE: cagney/2003-01-03: No need to set saved_regs to NULL,
+ always NULL by default. */
+ /* frame->saved_regs = NULL; */
+ get_frame_extra_info (frame)->localoff = 0;
+ get_frame_extra_info (frame)->pc_reg = ALPHA_RA_REGNUM;
+ get_frame_extra_info (frame)->proc_desc = proc_desc == &temp_proc_desc ? 0 : proc_desc;
if (proc_desc)
{
/* Get the locals offset and the saved pc register from the
procedure descriptor, they are valid even if we are in the
middle of the prologue. */
- frame->extra_info->localoff = PROC_LOCALOFF (proc_desc);
- frame->extra_info->pc_reg = PROC_PC_REG (proc_desc);
+ get_frame_extra_info (frame)->localoff = PROC_LOCALOFF (proc_desc);
+ get_frame_extra_info (frame)->pc_reg = PROC_PC_REG (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))
- frame->frame = (CORE_ADDR) PROC_DUMMY_FRAME (proc_desc);
+ deprecated_update_frame_base_hack (frame, (CORE_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 (frame->pc == PROC_LOW_ADDR (proc_desc)
+ else if (get_frame_pc (frame) == PROC_LOW_ADDR (proc_desc)
&& !alpha_proc_desc_is_dyn_sigtramp (proc_desc))
- frame->frame = read_next_frame_reg (frame->next, SP_REGNUM);
+ deprecated_update_frame_base_hack (frame, read_next_frame_reg (get_next_frame (frame), SP_REGNUM));
else
- frame->frame = read_next_frame_reg (frame->next, PROC_FRAME_REG (proc_desc))
- + PROC_FRAME_OFFSET (proc_desc);
+ deprecated_update_frame_base_hack (frame, read_next_frame_reg (get_next_frame (frame), PROC_FRAME_REG (proc_desc))
+ + PROC_FRAME_OFFSET (proc_desc));
if (proc_desc == &temp_proc_desc)
{
char *name;
/* Do not set the saved registers for a sigtramp frame,
- alpha_find_saved_registers will do that for us.
- We can't use frame->signal_handler_caller, it is not yet set. */
- find_pc_partial_function (frame->pc, &name,
+ alpha_find_saved_registers will do that for us. We can't
+ use (get_frame_type (frame) == SIGTRAMP_FRAME), it is not
+ yet set. */
+ /* FIXME: cagney/2002-11-18: This problem will go away once
+ frame.c:get_prev_frame() is modified to set the frame's
+ type before calling functions like this. */
+ find_pc_partial_function (get_frame_pc (frame), &name,
(CORE_ADDR *) NULL, (CORE_ADDR *) NULL);
- if (!PC_IN_SIGTRAMP (frame->pc, name))
+ if (!PC_IN_SIGTRAMP (get_frame_pc (frame), name))
{
- frame->saved_regs = (CORE_ADDR *)
- frame_obstack_alloc (SIZEOF_FRAME_SAVED_REGS);
- memcpy (frame->saved_regs, temp_saved_regs,
+ frame_saved_regs_zalloc (frame);
+ memcpy (get_frame_saved_regs (frame), temp_saved_regs,
SIZEOF_FRAME_SAVED_REGS);
- frame->saved_regs[PC_REGNUM]
- = frame->saved_regs[ALPHA_RA_REGNUM];
+ get_frame_saved_regs (frame)[PC_REGNUM]
+ = get_frame_saved_regs (frame)[ALPHA_RA_REGNUM];
}
}
}
static CORE_ADDR
alpha_frame_locals_address (struct frame_info *fi)
{
- return (fi->frame - fi->extra_info->localoff);
+ return (get_frame_base (fi) - get_frame_extra_info (fi)->localoff);
}
static CORE_ADDR
alpha_frame_args_address (struct frame_info *fi)
{
- return (fi->frame - (ALPHA_NUM_ARG_REGS * 8));
+ return (get_frame_base (fi) - (ALPHA_NUM_ARG_REGS * 8));
}
/* ALPHA stack frames are almost impenetrable. When execution stops,
{
register int regnum;
struct frame_info *frame = get_current_frame ();
- CORE_ADDR new_sp = frame->frame;
+ CORE_ADDR new_sp = get_frame_base (frame);
- alpha_extra_func_info_t proc_desc = frame->extra_info->proc_desc;
+ alpha_extra_func_info_t proc_desc = get_frame_extra_info (frame)->proc_desc;
/* we need proc_desc to know how to restore the registers;
if it is NULL, construct (a temporary) one */
if (proc_desc == NULL)
- proc_desc = find_proc_desc (frame->pc, frame->next);
+ proc_desc = find_proc_desc (get_frame_pc (frame), get_next_frame (frame));
/* Question: should we copy this proc_desc and save it in
frame->proc_desc? If we do, who will free it?
For now, we don't save a copy... */
- write_register (PC_REGNUM, FRAME_SAVED_PC (frame));
- if (frame->saved_regs == NULL)
+ write_register (PC_REGNUM, DEPRECATED_FRAME_SAVED_PC (frame));
+ if (get_frame_saved_regs (frame) == NULL)
alpha_find_saved_regs (frame);
if (proc_desc)
{
for (regnum = 32; --regnum >= 0;)
if (PROC_REG_MASK (proc_desc) & (1 << regnum))
write_register (regnum,
- read_memory_integer (frame->saved_regs[regnum],
+ read_memory_integer (get_frame_saved_regs (frame)[regnum],
8));
for (regnum = 32; --regnum >= 0;)
if (PROC_FREG_MASK (proc_desc) & (1 << regnum))
write_register (regnum + FP0_REGNUM,
- read_memory_integer (frame->saved_regs[regnum + FP0_REGNUM], 8));
+ read_memory_integer (get_frame_saved_regs (frame)[regnum + FP0_REGNUM], 8));
}
write_register (SP_REGNUM, new_sp);
flush_cached_frames ();
if (TYPE_CODE (valtype) == TYPE_CODE_FLT)
{
- double d = extract_floating (raw_buffer, REGISTER_RAW_SIZE (regnum));
- store_floating (virtual_buffer, TYPE_LENGTH (valtype), d);
+ double d = deprecated_extract_floating (raw_buffer, REGISTER_RAW_SIZE (regnum));
+ deprecated_store_floating (virtual_buffer, TYPE_LENGTH (valtype), d);
}
else if (TYPE_CODE (valtype) == TYPE_CODE_INT && TYPE_LENGTH (valtype) <= 4)
{
if (TYPE_CODE (valtype) == TYPE_CODE_FLT)
{
- double d = extract_floating (virtual_buffer, TYPE_LENGTH (valtype));
- store_floating (raw_buffer, REGISTER_RAW_SIZE (regnum), d);
+ double d = deprecated_extract_floating (virtual_buffer, TYPE_LENGTH (valtype));
+ deprecated_store_floating (raw_buffer, REGISTER_RAW_SIZE (regnum), d);
}
else if (TYPE_CODE (valtype) == TYPE_CODE_INT && TYPE_LENGTH (valtype) <= 4)
{
else
memcpy (raw_buffer, valbuf, length);
- write_register_bytes (REGISTER_BYTE (regnum), raw_buffer, length);
+ deprecated_write_register_bytes (REGISTER_BYTE (regnum), raw_buffer, length);
}
/* Just like reinit_frame_cache, but with the right arguments to be
}
\f
-/* This table matches the indices assigned to enum alpha_abi. Keep
- them in sync. */
-static const char * const alpha_abi_names[] =
-{
- "<unknown>",
- "OSF/1",
- "GNU/Linux",
- "FreeBSD",
- "NetBSD",
- NULL
-};
-
-static void
-process_note_abi_tag_sections (bfd *abfd, asection *sect, void *obj)
-{
- enum alpha_abi *os_ident_ptr = obj;
- const char *name;
- unsigned int sectsize;
-
- name = bfd_get_section_name (abfd, sect);
- sectsize = bfd_section_size (abfd, sect);
-
- if (strcmp (name, ".note.ABI-tag") == 0 && sectsize > 0)
- {
- unsigned int name_length, data_length, note_type;
- char *note;
-
- /* If the section is larger than this, it's probably not what we are
- looking for. */
- if (sectsize > 128)
- sectsize = 128;
-
- note = alloca (sectsize);
-
- bfd_get_section_contents (abfd, sect, note,
- (file_ptr) 0, (bfd_size_type) sectsize);
-
- name_length = bfd_h_get_32 (abfd, note);
- data_length = bfd_h_get_32 (abfd, note + 4);
- note_type = bfd_h_get_32 (abfd, note + 8);
-
- if (name_length == 4 && data_length == 16 && note_type == 1
- && strcmp (note + 12, "GNU") == 0)
- {
- int os_number = bfd_h_get_32 (abfd, note + 16);
-
- /* The case numbers are from abi-tags in glibc. */
- switch (os_number)
- {
- case 0 :
- *os_ident_ptr = ALPHA_ABI_LINUX;
- break;
-
- case 1 :
- internal_error
- (__FILE__, __LINE__,
- "process_note_abi_sections: Hurd objects not supported");
- break;
-
- case 2 :
- internal_error
- (__FILE__, __LINE__,
- "process_note_abi_sections: Solaris objects not supported");
- break;
-
- default :
- internal_error
- (__FILE__, __LINE__,
- "process_note_abi_sections: unknown OS number %d",
- os_number);
- break;
- }
- }
- }
- /* NetBSD uses a similar trick. */
- else if (strcmp (name, ".note.netbsd.ident") == 0 && sectsize > 0)
- {
- unsigned int name_length, desc_length, note_type;
- char *note;
-
- /* If the section is larger than this, it's probably not what we are
- looking for. */
- if (sectsize > 128)
- sectsize = 128;
-
- note = alloca (sectsize);
-
- bfd_get_section_contents (abfd, sect, note,
- (file_ptr) 0, (bfd_size_type) sectsize);
-
- name_length = bfd_h_get_32 (abfd, note);
- desc_length = bfd_h_get_32 (abfd, note + 4);
- note_type = bfd_h_get_32 (abfd, note + 8);
-
- if (name_length == 7 && desc_length == 4 && note_type == 1
- && strcmp (note + 12, "NetBSD") == 0)
- /* XXX Should we check the version here?
- Probably not necessary yet. */
- *os_ident_ptr = ALPHA_ABI_NETBSD;
- }
-}
-
-static int
-get_elfosabi (bfd *abfd)
-{
- int elfosabi;
- enum alpha_abi alpha_abi = ALPHA_ABI_UNKNOWN;
-
- elfosabi = elf_elfheader (abfd)->e_ident[EI_OSABI];
-
- /* When elfosabi is 0 (ELFOSABI_NONE), this is supposed to indicate
- what we're on a SYSV system. However, GNU/Linux uses a note section
- to record OS/ABI info, but leaves e_ident[EI_OSABI] zero. So we
- have to check the note sections too. */
- if (elfosabi == 0)
- {
- bfd_map_over_sections (abfd,
- process_note_abi_tag_sections,
- &alpha_abi);
- }
-
- if (alpha_abi != ALPHA_ABI_UNKNOWN)
- return alpha_abi;
-
- switch (elfosabi)
- {
- case ELFOSABI_NONE:
- /* Leave it as unknown. */
- break;
-
- case ELFOSABI_NETBSD:
- return ALPHA_ABI_NETBSD;
-
- case ELFOSABI_FREEBSD:
- return ALPHA_ABI_FREEBSD;
-
- case ELFOSABI_LINUX:
- return ALPHA_ABI_LINUX;
- }
-
- return ALPHA_ABI_UNKNOWN;
-}
-
-struct alpha_abi_handler
-{
- struct alpha_abi_handler *next;
- enum alpha_abi abi;
- void (*init_abi)(struct gdbarch_info, struct gdbarch *);
-};
-
-struct alpha_abi_handler *alpha_abi_handler_list = NULL;
-
-void
-alpha_gdbarch_register_os_abi (enum alpha_abi abi,
- void (*init_abi)(struct gdbarch_info,
- struct gdbarch *))
-{
- struct alpha_abi_handler **handler_p;
-
- for (handler_p = &alpha_abi_handler_list; *handler_p != NULL;
- handler_p = &(*handler_p)->next)
- {
- if ((*handler_p)->abi == abi)
- {
- internal_error
- (__FILE__, __LINE__,
- "alpha_gdbarch_register_os_abi: A handler for this ABI variant "
- "(%d) has already been registered", (int) abi);
- /* If user wants to continue, override previous definition. */
- (*handler_p)->init_abi = init_abi;
- return;
- }
- }
-
- (*handler_p)
- = (struct alpha_abi_handler *) xmalloc (sizeof (struct alpha_abi_handler));
- (*handler_p)->next = NULL;
- (*handler_p)->abi = abi;
- (*handler_p)->init_abi = init_abi;
-}
/* Initialize the current architecture based on INFO. If possible, re-use an
architecture from ARCHES, which is a list of architectures already created
{
struct gdbarch_tdep *tdep;
struct gdbarch *gdbarch;
- enum alpha_abi alpha_abi = ALPHA_ABI_UNKNOWN;
- struct alpha_abi_handler *abi_handler;
/* Try to determine the ABI of the object we are loading. */
-
- if (info.abfd != NULL)
+ if (info.abfd != NULL && info.osabi == GDB_OSABI_UNKNOWN)
{
- switch (bfd_get_flavour (info.abfd))
- {
- case bfd_target_elf_flavour:
- alpha_abi = get_elfosabi (info.abfd);
- break;
-
- case bfd_target_ecoff_flavour:
- /* Assume it's OSF/1. */
- alpha_abi = ALPHA_ABI_OSF1;
- break;
-
- default:
- /* Not sure what to do here, leave the ABI as unknown. */
- break;
- }
+ /* If it's an ECOFF file, assume it's OSF/1. */
+ if (bfd_get_flavour (info.abfd) == bfd_target_ecoff_flavour)
+ info.osabi = GDB_OSABI_OSF1;
}
/* Find a candidate among extant architectures. */
- for (arches = gdbarch_list_lookup_by_info (arches, &info);
- arches != NULL;
- arches = gdbarch_list_lookup_by_info (arches->next, &info))
- {
- /* Make sure the ABI selection matches. */
- tdep = gdbarch_tdep (arches->gdbarch);
- if (tdep && tdep->alpha_abi == alpha_abi)
- return arches->gdbarch;
- }
+ arches = gdbarch_list_lookup_by_info (arches, &info);
+ if (arches != NULL)
+ return arches->gdbarch;
tdep = xmalloc (sizeof (struct gdbarch_tdep));
gdbarch = gdbarch_alloc (&info, tdep);
- tdep->alpha_abi = alpha_abi;
- if (alpha_abi < ALPHA_ABI_INVALID)
- tdep->abi_name = alpha_abi_names[alpha_abi];
- else
- {
- internal_error (__FILE__, __LINE__, "Invalid setting of alpha_abi %d",
- (int) alpha_abi);
- tdep->abi_name = "<invalid>";
- }
-
/* Lowest text address. This is used by heuristic_proc_start() to
decide when to stop looking. */
tdep->vm_min_address = (CORE_ADDR) 0x120000000;
set_gdbarch_register_bytes (gdbarch, ALPHA_REGISTER_BYTES);
set_gdbarch_register_byte (gdbarch, alpha_register_byte);
set_gdbarch_register_raw_size (gdbarch, alpha_register_raw_size);
- set_gdbarch_max_register_raw_size (gdbarch, ALPHA_MAX_REGISTER_RAW_SIZE);
+ set_gdbarch_deprecated_max_register_raw_size (gdbarch, ALPHA_MAX_REGISTER_RAW_SIZE);
set_gdbarch_register_virtual_size (gdbarch, alpha_register_virtual_size);
- set_gdbarch_max_register_virtual_size (gdbarch,
+ set_gdbarch_deprecated_max_register_virtual_size (gdbarch,
ALPHA_MAX_REGISTER_VIRTUAL_SIZE);
set_gdbarch_register_virtual_type (gdbarch, alpha_register_virtual_type);
set_gdbarch_saved_pc_after_call (gdbarch, alpha_saved_pc_after_call);
- set_gdbarch_frame_chain (gdbarch, alpha_frame_chain);
- set_gdbarch_frame_chain_valid (gdbarch, func_frame_chain_valid);
- set_gdbarch_frame_saved_pc (gdbarch, alpha_frame_saved_pc);
+ set_gdbarch_deprecated_frame_chain (gdbarch, alpha_frame_chain);
+ set_gdbarch_deprecated_frame_saved_pc (gdbarch, alpha_frame_saved_pc);
- set_gdbarch_frame_init_saved_regs (gdbarch, alpha_frame_init_saved_regs);
- set_gdbarch_get_saved_register (gdbarch, alpha_get_saved_register);
+ set_gdbarch_deprecated_frame_init_saved_regs (gdbarch, alpha_frame_init_saved_regs);
set_gdbarch_use_struct_convention (gdbarch, alpha_use_struct_convention);
- set_gdbarch_extract_return_value (gdbarch, alpha_extract_return_value);
+ set_gdbarch_deprecated_extract_return_value (gdbarch, alpha_extract_return_value);
- set_gdbarch_store_struct_return (gdbarch, alpha_store_struct_return);
- set_gdbarch_store_return_value (gdbarch, alpha_store_return_value);
- set_gdbarch_extract_struct_value_address (gdbarch,
+ set_gdbarch_deprecated_store_struct_return (gdbarch, alpha_store_struct_return);
+ set_gdbarch_deprecated_store_return_value (gdbarch, alpha_store_return_value);
+ set_gdbarch_deprecated_extract_struct_value_address (gdbarch,
alpha_extract_struct_value_address);
/* Settings for calling functions in the inferior. */
- set_gdbarch_use_generic_dummy_frames (gdbarch, 0);
- set_gdbarch_call_dummy_length (gdbarch, 0);
- set_gdbarch_push_arguments (gdbarch, alpha_push_arguments);
- set_gdbarch_pop_frame (gdbarch, alpha_pop_frame);
+ set_gdbarch_deprecated_use_generic_dummy_frames (gdbarch, 0);
+ set_gdbarch_deprecated_push_arguments (gdbarch, alpha_push_arguments);
+ set_gdbarch_deprecated_pop_frame (gdbarch, alpha_pop_frame);
/* On the Alpha, the call dummy code is never copied to user space,
stopping the user call is achieved via a bp_call_dummy breakpoint.
But we need a fake CALL_DUMMY definition to enable the proper
call_function_by_hand and to avoid zero length array warnings. */
- set_gdbarch_call_dummy_p (gdbarch, 1);
set_gdbarch_call_dummy_words (gdbarch, alpha_call_dummy_words);
set_gdbarch_sizeof_call_dummy_words (gdbarch, 0);
set_gdbarch_frame_args_address (gdbarch, alpha_frame_args_address);
set_gdbarch_frame_locals_address (gdbarch, alpha_frame_locals_address);
- set_gdbarch_init_extra_frame_info (gdbarch, alpha_init_extra_frame_info);
+ set_gdbarch_deprecated_init_extra_frame_info (gdbarch, alpha_init_extra_frame_info);
/* Alpha OSF/1 inhibits execution of code on the stack. But there is
no need for a dummy on the Alpha. PUSH_ARGUMENTS takes care of all
argument handling and bp_call_dummy takes care of stopping the dummy. */
- set_gdbarch_call_dummy_location (gdbarch, AT_ENTRY_POINT);
set_gdbarch_call_dummy_address (gdbarch, alpha_call_dummy_address);
- set_gdbarch_call_dummy_breakpoint_offset_p (gdbarch, 1);
- set_gdbarch_call_dummy_breakpoint_offset (gdbarch, 0);
- set_gdbarch_call_dummy_start_offset (gdbarch, 0);
- set_gdbarch_pc_in_call_dummy (gdbarch, pc_in_call_dummy_at_entry_point);
- set_gdbarch_call_dummy_stack_adjust_p (gdbarch, 0);
- set_gdbarch_push_dummy_frame (gdbarch, alpha_push_dummy_frame);
+ set_gdbarch_deprecated_pc_in_call_dummy (gdbarch, deprecated_pc_in_call_dummy_at_entry_point);
+ set_gdbarch_deprecated_push_dummy_frame (gdbarch, alpha_push_dummy_frame);
+ /* Should be using push_dummy_call. */
+ set_gdbarch_deprecated_dummy_write_sp (gdbarch, generic_target_write_sp);
set_gdbarch_fix_call_dummy (gdbarch, alpha_fix_call_dummy);
- set_gdbarch_init_frame_pc (gdbarch, init_frame_pc_noop);
- set_gdbarch_init_frame_pc_first (gdbarch, alpha_init_frame_pc_first);
+ set_gdbarch_deprecated_init_frame_pc (gdbarch, init_frame_pc_noop);
+ set_gdbarch_deprecated_init_frame_pc_first (gdbarch, alpha_init_frame_pc_first);
set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
- /* Floats are always passed as doubles. */
- set_gdbarch_coerce_float_to_double (gdbarch,
- standard_coerce_float_to_double);
-
set_gdbarch_breakpoint_from_pc (gdbarch, alpha_breakpoint_from_pc);
set_gdbarch_decr_pc_after_break (gdbarch, 4);
set_gdbarch_frame_args_skip (gdbarch, 0);
/* Hook in ABI-specific overrides, if they have been registered. */
- if (alpha_abi == ALPHA_ABI_UNKNOWN)
- {
- /* Don't complain about not knowing the ABI variant if we don't
- have an inferior. */
- if (info.abfd)
- fprintf_filtered
- (gdb_stderr, "GDB doesn't recognize the ABI of the inferior. "
- "Attempting to continue with the default Alpha settings");
- }
- else
- {
- for (abi_handler = alpha_abi_handler_list; abi_handler != NULL;
- abi_handler = abi_handler->next)
- if (abi_handler->abi == alpha_abi)
- break;
-
- if (abi_handler)
- abi_handler->init_abi (info, gdbarch);
- else
- {
- /* We assume that if GDB_MULTI_ARCH is less than
- GDB_MULTI_ARCH_TM that an ABI variant can be supported by
- overriding definitions in this file. */
- if (GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL)
- fprintf_filtered
- (gdb_stderr,
- "A handler for the ABI variant \"%s\" is not built into this "
- "configuration of GDB. "
- "Attempting to continue with the default Alpha settings",
- alpha_abi_names[alpha_abi]);
- }
- }
+ gdbarch_init_osabi (info, gdbarch);
/* Now that we have tuned the configuration, set a few final things
based on what the OS ABI has told us. */
if (tdep == NULL)
return;
- if (tdep->abi_name != NULL)
- fprintf_unfiltered (file, "alpha_dump_tdep: ABI = %s\n", tdep->abi_name);
- else
- internal_error (__FILE__, __LINE__,
- "alpha_dump_tdep: illegal setting of tdep->alpha_abi (%d)",
- (int) tdep->alpha_abi);
-
fprintf_unfiltered (file,
"alpha_dump_tdep: vm_min_address = 0x%lx\n",
(long) tdep->vm_min_address);