2008-04-23 Maxim Grigoriev <maxim2405@gmail.com>

* Makefile.in (xtensa-tdep.o): Update dependencies.
	* configure.tgt (xtensa*): Update dependencies.
	* xtensa-tdep.c (arreg_number): Renamed from areg_number.
	Local variable areg renamed to arreg.
	(areg_number): New function.
	(xtensa_pseudo_register_read, xtensa_pseudo_register_write)
	(xtensa_extract_return_value, xtensa_store_return_value): areg_number
	replaced by arreg_number.
	(xtensa_windowed_frame_cache, struct xtensa_frame_cache): New comments.
	(xtensa_alloc_frame_cache): Initialize cache->wd.ws.
	(xtensa_scan_prologue): New function.
	(xtensa_frame_cache): New local fp_regnum. Handle separately the case,
	when ENTRY instraction hasn't been executed yet. Get the frame pointer
	value based on prologue analysis. Fix the bugs preventing WS and
	AR4-AR7/A11 registers from getting right values for intermediate frames,
	whose registers have been already spilled.
	(xtensa_frame_prev_register): Fix WS register value. Use are_number
	and arreg_number appropriately.
	(xtensa_gdbarch_init): Set solib_svr4_fetch_link_map_offsets to
	svr4_ilp32_fetch_link_map_offsets.
This commit is contained in:
Maxim Grigoriev 2008-04-23 21:17:05 +00:00
parent fe4fa32c96
commit ee967b5f61
4 changed files with 226 additions and 48 deletions

View file

@ -1,3 +1,26 @@
2008-04-23 Maxim Grigoriev <maxim2405@gmail.com>
* Makefile.in (xtensa-tdep.o): Update dependencies.
* configure.tgt (xtensa*): Update dependencies.
* xtensa-tdep.c (arreg_number): Renamed from areg_number.
Local variable areg renamed to arreg.
(areg_number): New function.
(xtensa_pseudo_register_read, xtensa_pseudo_register_write)
(xtensa_extract_return_value, xtensa_store_return_value): areg_number
replaced by arreg_number.
(xtensa_windowed_frame_cache, struct xtensa_frame_cache): New comments.
(xtensa_alloc_frame_cache): Initialize cache->wd.ws.
(xtensa_scan_prologue): New function.
(xtensa_frame_cache): New local fp_regnum. Handle separately the case,
when ENTRY instraction hasn't been executed yet. Get the frame pointer
value based on prologue analysis. Fix the bugs preventing WS and
AR4-AR7/A11 registers from getting right values for intermediate frames,
whose registers have been already spilled.
(xtensa_frame_prev_register): Fix WS register value. Use are_number
and arreg_number appropriately.
(xtensa_gdbarch_init): Set solib_svr4_fetch_link_map_offsets to
svr4_ilp32_fetch_link_map_offsets.
2008-04-23 Andrew Stubbs <andrew.stubbs@st.com> 2008-04-23 Andrew Stubbs <andrew.stubbs@st.com>
* printcmd.c: Define USE_PRINTF_I64 and PRINTF_HAS_LONG_LONG on MinGW. * printcmd.c: Define USE_PRINTF_I64 and PRINTF_HAS_LONG_LONG on MinGW.

View file

@ -3016,7 +3016,7 @@ xtensa-tdep.o: xtensa-tdep.c $(defs_h) $(doublest_h) $(frame_h) \
$(value_h) $(gdbcmd_h) $(gdbcore_h) $(dis_asm_h) $(symfile_h) \ $(value_h) $(gdbcmd_h) $(gdbcore_h) $(dis_asm_h) $(symfile_h) \
$(objfiles_h) $(gdb_string_h) $(linespec_h) $(regcache_h) \ $(objfiles_h) $(gdb_string_h) $(linespec_h) $(regcache_h) \
$(reggroups_h) $(arch_utils_h) $(osabi_h) $(block_h) $(gdb_assert_h) \ $(reggroups_h) $(arch_utils_h) $(osabi_h) $(block_h) $(gdb_assert_h) \
$(elf_bfd_h) $(xtensa_tdep_h) $(dwarf2_frame_h) $(elf_bfd_h) $(xtensa_tdep_h) $(dwarf2_frame_h) $(solib_svr4_h)
xtensa-config.o: $(defs_h) $(xtensa_tdep_h) xtensa-config.o: $(defs_h) $(xtensa_tdep_h)
# #

View file

@ -523,7 +523,7 @@ xtensa*-*-linux*) gdb_target=linux
;; ;;
xtensa*) xtensa*)
# Target: Tensilica Xtensa processors # Target: Tensilica Xtensa processors
gdb_target_obs="xtensa-tdep.o xtensa-config.o" gdb_target_obs="xtensa-tdep.o xtensa-config.o solib.o solib-svr4.o"
;; ;;
esac esac

View file

@ -19,6 +19,7 @@
#include "defs.h" #include "defs.h"
#include "frame.h" #include "frame.h"
#include "solib-svr4.h"
#include "symtab.h" #include "symtab.h"
#include "symfile.h" #include "symfile.h"
#include "objfiles.h" #include "objfiles.h"
@ -114,18 +115,33 @@ static int xtensa_debug_level = 0;
#define PS_WOE (1<<18) #define PS_WOE (1<<18)
#define PS_EXC (1<<4) #define PS_EXC (1<<4)
/* Convert a live Ax register number to the corresponding Areg number. */ /* Convert a live A-register number to the corresponding AR-register number. */
static int static int
areg_number (struct gdbarch *gdbarch, int regnum, ULONGEST wb) arreg_number (struct gdbarch *gdbarch, int a_regnum, ULONGEST wb)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
int arreg;
arreg = a_regnum - tdep->a0_base;
arreg += (wb & ((tdep->num_aregs - 1) >> 2)) << WB_SHIFT;
arreg &= tdep->num_aregs - 1;
return arreg + tdep->ar_base;
}
/* Convert a live AR-register number to the corresponding A-register order
number in a range [0..15]. Return -1, if AR_REGNUM is out of WB window. */
static int
areg_number (struct gdbarch *gdbarch, int ar_regnum, unsigned int wb)
{ {
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
int areg; int areg;
areg = regnum - tdep->a0_base; areg = ar_regnum - tdep->ar_base;
areg += (wb & ((tdep->num_aregs - 1) >> 2)) << WB_SHIFT; if (areg < 0 || areg >= tdep->num_aregs)
areg &= tdep->num_aregs - 1; return -1;
areg = (areg - wb * 4) & (tdep->num_aregs - 1);
return areg + tdep->ar_base; return (areg > 15) ? -1 : areg;
} }
static inline int static inline int
@ -516,7 +532,8 @@ xtensa_pseudo_register_read (struct gdbarch *gdbarch,
gdb_byte *buf = (gdb_byte *) alloca (MAX_REGISTER_SIZE); gdb_byte *buf = (gdb_byte *) alloca (MAX_REGISTER_SIZE);
regcache_raw_read (regcache, gdbarch_tdep (gdbarch)->wb_regnum, buf); regcache_raw_read (regcache, gdbarch_tdep (gdbarch)->wb_regnum, buf);
regnum = areg_number (gdbarch, regnum, extract_unsigned_integer (buf, 4)); regnum = arreg_number (gdbarch, regnum,
extract_unsigned_integer (buf, 4));
} }
/* We can always read non-pseudo registers. */ /* We can always read non-pseudo registers. */
@ -613,7 +630,8 @@ xtensa_pseudo_register_write (struct gdbarch *gdbarch,
regcache_raw_read (regcache, regcache_raw_read (regcache,
gdbarch_tdep (gdbarch)->wb_regnum, buf); gdbarch_tdep (gdbarch)->wb_regnum, buf);
regnum = areg_number (gdbarch, regnum, extract_unsigned_integer (buf, 4)); regnum = arreg_number (gdbarch, regnum,
extract_unsigned_integer (buf, 4));
} }
/* We can always write 'core' registers. /* We can always write 'core' registers.
@ -880,9 +898,15 @@ xtensa_regset_from_core_section (struct gdbarch *core_arch,
/* Frame cache part for Windowed ABI. */ /* Frame cache part for Windowed ABI. */
typedef struct xtensa_windowed_frame_cache typedef struct xtensa_windowed_frame_cache
{ {
int wb; /* Base for this frame; -1 if not in regfile. */ int wb; /* WINDOWBASE of the previous frame. */
int callsize; /* Call size to next frame. */ int callsize; /* Call size of this frame. */
int ws; int ws; /* WINDOWSTART of the previous frame. It keeps track of
life windows only. If there is no bit set for the
window, that means it had been already spilled
because of window overflow. */
/* Spilled A-registers from the previous frame.
AREGS[i] == -1, if corresponding AR is alive. */
CORE_ADDR aregs[XTENSA_NUM_SAVED_AREGS]; CORE_ADDR aregs[XTENSA_NUM_SAVED_AREGS];
} xtensa_windowed_frame_cache_t; } xtensa_windowed_frame_cache_t;
@ -932,11 +956,11 @@ typedef struct xtensa_call0_frame_cache
typedef struct xtensa_frame_cache typedef struct xtensa_frame_cache
{ {
CORE_ADDR base; /* Stack pointer of the next frame. */ CORE_ADDR base; /* Stack pointer of this frame. */
CORE_ADDR pc; /* PC at the entry point to the function. */ CORE_ADDR pc; /* PC at the entry point to the function. */
CORE_ADDR ra; /* The raw return address. */ CORE_ADDR ra; /* The raw return address (without CALLINC). */
CORE_ADDR ps; /* The PS register of the frame. */ CORE_ADDR ps; /* The PS register of the previous frame. */
CORE_ADDR prev_sp; /* Stack Pointer of the frame. */ CORE_ADDR prev_sp; /* Stack Pointer of the previous frame. */
int call0; /* It's a call0 framework (else windowed). */ int call0; /* It's a call0 framework (else windowed). */
union union
{ {
@ -979,6 +1003,7 @@ xtensa_alloc_frame_cache (int windowed)
else else
{ {
cache->wd.wb = 0; cache->wd.wb = 0;
cache->wd.ws = 0;
cache->wd.callsize = -1; cache->wd.callsize = -1;
for (i = 0; i < XTENSA_NUM_SAVED_AREGS; i++) for (i = 0; i < XTENSA_NUM_SAVED_AREGS; i++)
@ -1028,9 +1053,126 @@ xtensa_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame)
return frame_id_build (fp + SP_ALIGNMENT, pc); return frame_id_build (fp + SP_ALIGNMENT, pc);
} }
/* Returns the best guess about which register is a frame pointer
for the function containing CURRENT_PC. */
#define XTENSA_ISA_BSZ 32 /* Instruction buffer size. */
static unsigned int
xtensa_scan_prologue (struct gdbarch *gdbarch, CORE_ADDR current_pc)
{
#define RETURN_FP goto done
unsigned int fp_regnum = gdbarch_tdep (gdbarch)->a0_base + 1;
CORE_ADDR start_addr;
xtensa_isa isa;
xtensa_insnbuf ins, slot;
char ibuf[XTENSA_ISA_BSZ];
CORE_ADDR ia, bt, ba;
xtensa_format ifmt;
int ilen, islots, is;
xtensa_opcode opc;
const char *opcname;
find_pc_partial_function (current_pc, NULL, &start_addr, NULL);
if (start_addr == 0)
return fp_regnum;
if (!xtensa_default_isa)
xtensa_default_isa = xtensa_isa_init (0, 0);
isa = xtensa_default_isa;
gdb_assert (XTENSA_ISA_BSZ >= xtensa_isa_maxlength (isa));
ins = xtensa_insnbuf_alloc (isa);
slot = xtensa_insnbuf_alloc (isa);
ba = 0;
for (ia = start_addr, bt = ia; ia < current_pc ; ia += ilen)
{
if (ia + xtensa_isa_maxlength (isa) > bt)
{
ba = ia;
bt = (ba + XTENSA_ISA_BSZ) < current_pc
? ba + XTENSA_ISA_BSZ : current_pc;
read_memory (ba, ibuf, bt - ba);
}
xtensa_insnbuf_from_chars (isa, ins, &ibuf[ia-ba], 0);
ifmt = xtensa_format_decode (isa, ins);
if (ifmt == XTENSA_UNDEFINED)
RETURN_FP;
ilen = xtensa_format_length (isa, ifmt);
if (ilen == XTENSA_UNDEFINED)
RETURN_FP;
islots = xtensa_format_num_slots (isa, ifmt);
if (islots == XTENSA_UNDEFINED)
RETURN_FP;
for (is = 0; is < islots; ++is)
{
if (xtensa_format_get_slot (isa, ifmt, is, ins, slot))
RETURN_FP;
opc = xtensa_opcode_decode (isa, ifmt, is, slot);
if (opc == XTENSA_UNDEFINED)
RETURN_FP;
opcname = xtensa_opcode_name (isa, opc);
if (strcasecmp (opcname, "mov.n") == 0
|| strcasecmp (opcname, "or") == 0)
{
unsigned int register_operand;
/* Possible candidate for setting frame pointer
from A1. This is what we are looking for. */
if (xtensa_operand_get_field (isa, opc, 1, ifmt,
is, slot, &register_operand) != 0)
RETURN_FP;
if (xtensa_operand_decode (isa, opc, 1, &register_operand) != 0)
RETURN_FP;
if (register_operand == 1) /* Mov{.n} FP A1. */
{
if (xtensa_operand_get_field (isa, opc, 0, ifmt, is, slot,
&register_operand) != 0)
RETURN_FP;
if (xtensa_operand_decode (isa, opc, 0,
&register_operand) != 0)
RETURN_FP;
fp_regnum = gdbarch_tdep (gdbarch)->a0_base + register_operand;
RETURN_FP;
}
}
if (
/* We have problems decoding the memory. */
opcname == NULL
|| strcasecmp (opcname, "ill") == 0
|| strcasecmp (opcname, "ill.n") == 0
/* Hit planted breakpoint. */
|| strcasecmp (opcname, "break") == 0
|| strcasecmp (opcname, "break.n") == 0
/* Flow control instructions finish prologue. */
|| xtensa_opcode_is_branch (isa, opc) > 0
|| xtensa_opcode_is_jump (isa, opc) > 0
|| xtensa_opcode_is_loop (isa, opc) > 0
|| xtensa_opcode_is_call (isa, opc) > 0
|| strcasecmp (opcname, "simcall") == 0
|| strcasecmp (opcname, "syscall") == 0)
/* Can not continue analysis. */
RETURN_FP;
}
}
done:
xtensa_insnbuf_free(isa, slot);
xtensa_insnbuf_free(isa, ins);
return fp_regnum;
}
/* The key values to identify the frame using "cache" are /* The key values to identify the frame using "cache" are
cache->base = SP of this frame; cache->base = SP (or best guess about FP) of this frame;
cache->pc = entry-PC (entry point of the frame function); cache->pc = entry-PC (entry point of the frame function);
cache->prev_sp = SP of the previous frame. cache->prev_sp = SP of the previous frame.
*/ */
@ -1047,6 +1189,7 @@ xtensa_frame_cache (struct frame_info *next_frame, void **this_cache)
CORE_ADDR ra, wb, ws, pc, sp, ps; CORE_ADDR ra, wb, ws, pc, sp, ps;
struct gdbarch *gdbarch = get_frame_arch (next_frame); struct gdbarch *gdbarch = get_frame_arch (next_frame);
unsigned int ps_regnum = gdbarch_ps_regnum (gdbarch); unsigned int ps_regnum = gdbarch_ps_regnum (gdbarch);
unsigned int fp_regnum;
char op1; char op1;
int windowed; int windowed;
@ -1090,21 +1233,35 @@ xtensa_frame_cache (struct frame_info *next_frame, void **this_cache)
cache->wd.ws = ws; cache->wd.ws = ws;
cache->prev_sp = frame_unwind_register_unsigned cache->prev_sp = frame_unwind_register_unsigned
(next_frame, gdbarch_tdep (gdbarch)->a0_base + 1); (next_frame, gdbarch_tdep (gdbarch)->a0_base + 1);
/* This only can be the outermost frame since we are
just about to execute ENTRY. SP hasn't been set yet.
We can assume any frame size, because it does not
matter, and, let's fake frame base in cache. */
cache->base = cache->prev_sp + 16;
cache->pc = pc;
cache->ra = (cache->pc & 0xc0000000) | (ra & 0x3fffffff);
cache->ps = (ps & ~PS_CALLINC_MASK)
| ((WINSIZE(ra)/4) << PS_CALLINC_SHIFT);
return cache;
} }
else else
{ {
fp_regnum = xtensa_scan_prologue (gdbarch, pc);
ra = frame_unwind_register_unsigned ra = frame_unwind_register_unsigned
(next_frame, gdbarch_tdep (gdbarch)->a0_base); (next_frame, gdbarch_tdep (gdbarch)->a0_base);
cache->wd.callsize = WINSIZE (ra); cache->wd.callsize = WINSIZE (ra);
cache->wd.wb = (wb - cache->wd.callsize / 4) cache->wd.wb = (wb - cache->wd.callsize / 4)
& (gdbarch_tdep (gdbarch)->num_aregs / 4 - 1); & (gdbarch_tdep (gdbarch)->num_aregs / 4 - 1);
cache->wd.ws = ws & ~(1 << wb); cache->wd.ws = ws & ~(1 << wb);
}
cache->pc = frame_func_unwind (next_frame, NORMAL_FRAME); cache->pc = frame_func_unwind (next_frame, NORMAL_FRAME);
cache->ra = (cache->pc & 0xc0000000) | (ra & 0x3fffffff); cache->ra = (cache->pc & 0xc0000000) | (ra & 0x3fffffff);
cache->ps = (ps & ~PS_CALLINC_MASK) cache->ps = (ps & ~PS_CALLINC_MASK)
| ((WINSIZE(ra)/4) << PS_CALLINC_SHIFT); | ((WINSIZE(ra)/4) << PS_CALLINC_SHIFT);
}
if (cache->wd.ws == 0) if (cache->wd.ws == 0)
{ {
@ -1122,12 +1279,13 @@ xtensa_frame_cache (struct frame_info *next_frame, void **this_cache)
if (cache->wd.callsize > 4) if (cache->wd.callsize > 4)
{ {
/* Set A4...A7/A11. */ /* Set A4...A7/A11. */
/* Read an SP of the previous frame. */ /* Get the SP of the frame previous to the previous one.
To achieve this, we have to dereference SP twice. */
sp = (CORE_ADDR) read_memory_integer (sp - 12, 4); sp = (CORE_ADDR) read_memory_integer (sp - 12, 4);
sp = (CORE_ADDR) read_memory_integer (sp - 12, 4); sp = (CORE_ADDR) read_memory_integer (sp - 12, 4);
sp -= cache->wd.callsize * 4; sp -= cache->wd.callsize * 4;
for ( /* i=4 */ ; i < cache->wd.callsize; i++, sp += 4) for ( i = 4; i < cache->wd.callsize; i++, sp += 4)
{ {
cache->wd.aregs[i] = sp; cache->wd.aregs[i] = sp;
} }
@ -1138,19 +1296,18 @@ xtensa_frame_cache (struct frame_info *next_frame, void **this_cache)
/* If RA is equal to 0 this frame is an outermost frame. Leave /* If RA is equal to 0 this frame is an outermost frame. Leave
cache->prev_sp unchanged marking the boundary of the frame stack. */ cache->prev_sp unchanged marking the boundary of the frame stack. */
{ {
if (cache->wd.ws == 0) if ((cache->wd.ws & (1 << cache->wd.wb)) == 0)
{ {
/* Register window overflow already happened. /* Register window overflow already happened.
We can read caller's SP from the proper spill loction. */ We can read caller's SP from the proper spill loction. */
cache->prev_sp = sp = frame_unwind_register_unsigned (next_frame,
read_memory_integer (cache->wd.aregs[1], gdbarch_tdep (gdbarch)->a0_base + 1);
register_size (gdbarch, cache->prev_sp = read_memory_integer (sp - 12, 4);
gdbarch_tdep (gdbarch)->a0_base + 1));
} }
else else
{ {
/* Read caller's frame SP directly from the previous window. */ /* Read caller's frame SP directly from the previous window. */
int regnum = areg_number int regnum = arreg_number
(gdbarch, gdbarch_tdep (gdbarch)->a0_base + 1, (gdbarch, gdbarch_tdep (gdbarch)->a0_base + 1,
cache->wd.wb); cache->wd.wb);
@ -1161,10 +1318,10 @@ xtensa_frame_cache (struct frame_info *next_frame, void **this_cache)
else /* Call0 framework. */ else /* Call0 framework. */
{ {
call0_frame_cache (next_frame, cache, pc); call0_frame_cache (next_frame, cache, pc);
fp_regnum = cache->c0.fp_regnum;
} }
cache->base = frame_unwind_register_unsigned cache->base = frame_unwind_register_unsigned (next_frame, fp_regnum);
(next_frame, gdbarch_tdep (gdbarch)->a0_base + 1);
return cache; return cache;
} }
@ -1272,12 +1429,7 @@ xtensa_frame_prev_register (struct frame_info *next_frame,
else if (!cache->call0) else if (!cache->call0)
{ {
if (regnum == gdbarch_tdep (gdbarch)->ws_regnum) if (regnum == gdbarch_tdep (gdbarch)->ws_regnum)
{ saved_reg = cache->wd.ws;
if (cache->wd.ws != 0)
saved_reg = cache->wd.ws;
else
saved_reg = 1 << cache->wd.wb;
}
else if (regnum == gdbarch_tdep (gdbarch)->wb_regnum) else if (regnum == gdbarch_tdep (gdbarch)->wb_regnum)
saved_reg = cache->wd.wb; saved_reg = cache->wd.wb;
else if (regnum == gdbarch_ps_regnum (gdbarch)) else if (regnum == gdbarch_ps_regnum (gdbarch))
@ -1302,18 +1454,18 @@ xtensa_frame_prev_register (struct frame_info *next_frame,
if (!cache->call0) /* Windowed ABI. */ if (!cache->call0) /* Windowed ABI. */
{ {
/* Convert A-register numbers to AR-register numbers. */ /* Convert A-register numbers to AR-register numbers,
if we deal with A-register. */
if (regnum >= gdbarch_tdep (gdbarch)->a0_base if (regnum >= gdbarch_tdep (gdbarch)->a0_base
&& regnum <= gdbarch_tdep (gdbarch)->a0_base + 15) && regnum <= gdbarch_tdep (gdbarch)->a0_base + 15)
regnum = areg_number (gdbarch, regnum, cache->wd.wb); regnum = arreg_number (gdbarch, regnum, cache->wd.wb);
/* Check if AR-register has been saved to stack. */ /* Check, if we deal with AR-register saved on stack. */
if (regnum >= gdbarch_tdep (gdbarch)->ar_base if (regnum >= gdbarch_tdep (gdbarch)->ar_base
&& regnum <= (gdbarch_tdep (gdbarch)->ar_base && regnum <= (gdbarch_tdep (gdbarch)->ar_base
+ gdbarch_tdep (gdbarch)->num_aregs)) + gdbarch_tdep (gdbarch)->num_aregs))
{ {
int areg = regnum - gdbarch_tdep (gdbarch)->ar_base int areg = areg_number (gdbarch, regnum, cache->wd.wb);
- (cache->wd.wb * 4);
if (areg >= 0 if (areg >= 0
&& areg < XTENSA_NUM_SAVED_AREGS && areg < XTENSA_NUM_SAVED_AREGS
@ -1443,7 +1595,7 @@ xtensa_extract_return_value (struct type *type,
register (A2) in the caller window. */ register (A2) in the caller window. */
regcache_raw_read_unsigned regcache_raw_read_unsigned
(regcache, gdbarch_tdep (gdbarch)->wb_regnum, &wb); (regcache, gdbarch_tdep (gdbarch)->wb_regnum, &wb);
areg = areg_number (gdbarch, areg = arreg_number (gdbarch,
gdbarch_tdep (gdbarch)->a0_base + 2 + callsize, wb); gdbarch_tdep (gdbarch)->a0_base + 2 + callsize, wb);
} }
else else
@ -1493,8 +1645,8 @@ xtensa_store_return_value (struct type *type,
internal_error (__FILE__, __LINE__, internal_error (__FILE__, __LINE__,
_("unimplemented for this length: %d"), _("unimplemented for this length: %d"),
TYPE_LENGTH (type)); TYPE_LENGTH (type));
areg = areg_number (gdbarch, areg = arreg_number (gdbarch,
gdbarch_tdep (gdbarch)->a0_base + 2 + callsize, wb); gdbarch_tdep (gdbarch)->a0_base + 2 + callsize, wb);
DEBUGTRACE ("[xtensa_store_return_value] callsize %d wb %d\n", DEBUGTRACE ("[xtensa_store_return_value] callsize %d wb %d\n",
callsize, (int) wb); callsize, (int) wb);
@ -2666,6 +2818,9 @@ xtensa_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
set_gdbarch_regset_from_core_section (gdbarch, set_gdbarch_regset_from_core_section (gdbarch,
xtensa_regset_from_core_section); xtensa_regset_from_core_section);
set_solib_svr4_fetch_link_map_offsets
(gdbarch, svr4_ilp32_fetch_link_map_offsets);
return gdbarch; return gdbarch;
} }