gdb/ia64-tdep.c - gdb
Global variables defined
Data types defined
Functions defined
Macros defined
Source code
- #include "defs.h"
- #include "inferior.h"
- #include "gdbcore.h"
- #include "arch-utils.h"
- #include "floatformat.h"
- #include "gdbtypes.h"
- #include "regcache.h"
- #include "reggroups.h"
- #include "frame.h"
- #include "frame-base.h"
- #include "frame-unwind.h"
- #include "doublest.h"
- #include "value.h"
- #include "objfiles.h"
- #include "elf/common.h"
- #include "elf-bfd.h"
- #include "dis-asm.h"
- #include "infcall.h"
- #include "osabi.h"
- #include "ia64-tdep.h"
- #include "cp-abi.h"
- #ifdef HAVE_LIBUNWIND_IA64_H
- #include "elf/ia64.h"
- #include "ia64-libunwind-tdep.h"
- #define KERNEL_START 0xc000000000000000ULL
- static size_t ktab_size = 0;
- struct ia64_table_entry
- {
- uint64_t start_offset;
- uint64_t end_offset;
- uint64_t info_offset;
- };
- static struct ia64_table_entry *ktab = NULL;
- #endif
- typedef enum instruction_type
- {
- A,
- I,
- M,
- F,
- B,
- L,
- X,
- undefined
- } instruction_type;
- #define SLOT_MULTIPLIER 1
- #define BUNDLE_LEN 16
- #if BREAKPOINT_MAX < BUNDLE_LEN - 2
- # error "BREAKPOINT_MAX < BUNDLE_LEN - 2"
- #endif
- static gdbarch_init_ftype ia64_gdbarch_init;
- static gdbarch_register_name_ftype ia64_register_name;
- static gdbarch_register_type_ftype ia64_register_type;
- static gdbarch_breakpoint_from_pc_ftype ia64_breakpoint_from_pc;
- static gdbarch_skip_prologue_ftype ia64_skip_prologue;
- static struct type *is_float_or_hfa_type (struct type *t);
- static CORE_ADDR ia64_find_global_pointer (struct gdbarch *gdbarch,
- CORE_ADDR faddr);
- #define NUM_IA64_RAW_REGS 462
- static int sp_regnum = IA64_GR12_REGNUM;
- static int fp_regnum = IA64_VFP_REGNUM;
- static int lr_regnum = IA64_VRAP_REGNUM;
- enum pseudo_regs { FIRST_PSEUDO_REGNUM = NUM_IA64_RAW_REGS,
- VBOF_REGNUM = IA64_NAT127_REGNUM + 1, V32_REGNUM,
- V127_REGNUM = V32_REGNUM + 95,
- VP0_REGNUM, VP16_REGNUM = VP0_REGNUM + 16,
- VP63_REGNUM = VP0_REGNUM + 63, LAST_PSEUDO_REGNUM };
- static char *ia64_register_names[] =
- { "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",
- "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "",
- "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
- "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
- "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
- "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
- "f32", "f33", "f34", "f35", "f36", "f37", "f38", "f39",
- "f40", "f41", "f42", "f43", "f44", "f45", "f46", "f47",
- "f48", "f49", "f50", "f51", "f52", "f53", "f54", "f55",
- "f56", "f57", "f58", "f59", "f60", "f61", "f62", "f63",
- "f64", "f65", "f66", "f67", "f68", "f69", "f70", "f71",
- "f72", "f73", "f74", "f75", "f76", "f77", "f78", "f79",
- "f80", "f81", "f82", "f83", "f84", "f85", "f86", "f87",
- "f88", "f89", "f90", "f91", "f92", "f93", "f94", "f95",
- "f96", "f97", "f98", "f99", "f100", "f101", "f102", "f103",
- "f104", "f105", "f106", "f107", "f108", "f109", "f110", "f111",
- "f112", "f113", "f114", "f115", "f116", "f117", "f118", "f119",
- "f120", "f121", "f122", "f123", "f124", "f125", "f126", "f127",
- "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "",
- "b0", "b1", "b2", "b3", "b4", "b5", "b6", "b7",
- "vfp", "vrap",
- "pr", "ip", "psr", "cfm",
- "kr0", "kr1", "kr2", "kr3", "kr4", "kr5", "kr6", "kr7",
- "", "", "", "", "", "", "", "",
- "rsc", "bsp", "bspstore", "rnat",
- "", "fcr", "", "",
- "eflag", "csd", "ssd", "cflg", "fsr", "fir", "fdr", "",
- "ccv", "", "", "", "unat", "", "", "",
- "fpsr", "", "", "", "itc",
- "", "", "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "", "",
- "pfs", "lc", "ec",
- "", "", "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "", "", "",
- "",
- "nat0", "nat1", "nat2", "nat3", "nat4", "nat5", "nat6", "nat7",
- "nat8", "nat9", "nat10", "nat11", "nat12", "nat13", "nat14", "nat15",
- "nat16", "nat17", "nat18", "nat19", "nat20", "nat21", "nat22", "nat23",
- "nat24", "nat25", "nat26", "nat27", "nat28", "nat29", "nat30", "nat31",
- "nat32", "nat33", "nat34", "nat35", "nat36", "nat37", "nat38", "nat39",
- "nat40", "nat41", "nat42", "nat43", "nat44", "nat45", "nat46", "nat47",
- "nat48", "nat49", "nat50", "nat51", "nat52", "nat53", "nat54", "nat55",
- "nat56", "nat57", "nat58", "nat59", "nat60", "nat61", "nat62", "nat63",
- "nat64", "nat65", "nat66", "nat67", "nat68", "nat69", "nat70", "nat71",
- "nat72", "nat73", "nat74", "nat75", "nat76", "nat77", "nat78", "nat79",
- "nat80", "nat81", "nat82", "nat83", "nat84", "nat85", "nat86", "nat87",
- "nat88", "nat89", "nat90", "nat91", "nat92", "nat93", "nat94", "nat95",
- "nat96", "nat97", "nat98", "nat99", "nat100","nat101","nat102","nat103",
- "nat104","nat105","nat106","nat107","nat108","nat109","nat110","nat111",
- "nat112","nat113","nat114","nat115","nat116","nat117","nat118","nat119",
- "nat120","nat121","nat122","nat123","nat124","nat125","nat126","nat127",
- "bof",
- "r32", "r33", "r34", "r35", "r36", "r37", "r38", "r39",
- "r40", "r41", "r42", "r43", "r44", "r45", "r46", "r47",
- "r48", "r49", "r50", "r51", "r52", "r53", "r54", "r55",
- "r56", "r57", "r58", "r59", "r60", "r61", "r62", "r63",
- "r64", "r65", "r66", "r67", "r68", "r69", "r70", "r71",
- "r72", "r73", "r74", "r75", "r76", "r77", "r78", "r79",
- "r80", "r81", "r82", "r83", "r84", "r85", "r86", "r87",
- "r88", "r89", "r90", "r91", "r92", "r93", "r94", "r95",
- "r96", "r97", "r98", "r99", "r100", "r101", "r102", "r103",
- "r104", "r105", "r106", "r107", "r108", "r109", "r110", "r111",
- "r112", "r113", "r114", "r115", "r116", "r117", "r118", "r119",
- "r120", "r121", "r122", "r123", "r124", "r125", "r126", "r127",
- "p0", "p1", "p2", "p3", "p4", "p5", "p6", "p7",
- "p8", "p9", "p10", "p11", "p12", "p13", "p14", "p15",
- "p16", "p17", "p18", "p19", "p20", "p21", "p22", "p23",
- "p24", "p25", "p26", "p27", "p28", "p29", "p30", "p31",
- "p32", "p33", "p34", "p35", "p36", "p37", "p38", "p39",
- "p40", "p41", "p42", "p43", "p44", "p45", "p46", "p47",
- "p48", "p49", "p50", "p51", "p52", "p53", "p54", "p55",
- "p56", "p57", "p58", "p59", "p60", "p61", "p62", "p63",
- };
- struct ia64_frame_cache
- {
- CORE_ADDR base;
- CORE_ADDR pc;
- CORE_ADDR saved_sp;
- CORE_ADDR bsp;
- CORE_ADDR cfm;
- CORE_ADDR prev_cfm;
- int frameless;
- int sof;
- int sol;
- int sor;
- CORE_ADDR after_prologue;
-
- int mem_stack_frame_size;
-
- int fp_reg;
-
- CORE_ADDR saved_regs[NUM_IA64_RAW_REGS];
- };
- static int
- floatformat_valid (const struct floatformat *fmt, const void *from)
- {
- return 1;
- }
- static const struct floatformat floatformat_ia64_ext_little =
- {
- floatformat_little, 82, 0, 1, 17, 65535, 0x1ffff, 18, 64,
- floatformat_intbit_yes, "floatformat_ia64_ext_little", floatformat_valid, NULL
- };
- static const struct floatformat floatformat_ia64_ext_big =
- {
- floatformat_big, 82, 46, 47, 17, 65535, 0x1ffff, 64, 64,
- floatformat_intbit_yes, "floatformat_ia64_ext_big", floatformat_valid
- };
- static const struct floatformat *floatformats_ia64_ext[2] =
- {
- &floatformat_ia64_ext_big,
- &floatformat_ia64_ext_little
- };
- static struct type *
- ia64_ext_type (struct gdbarch *gdbarch)
- {
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- if (!tdep->ia64_ext_type)
- tdep->ia64_ext_type
- = arch_float_type (gdbarch, 128, "builtin_type_ia64_ext",
- floatformats_ia64_ext);
- return tdep->ia64_ext_type;
- }
- static int
- ia64_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
- struct reggroup *group)
- {
- int vector_p;
- int float_p;
- int raw_p;
- if (group == all_reggroup)
- return 1;
- vector_p = TYPE_VECTOR (register_type (gdbarch, regnum));
- float_p = TYPE_CODE (register_type (gdbarch, regnum)) == TYPE_CODE_FLT;
- raw_p = regnum < NUM_IA64_RAW_REGS;
- if (group == float_reggroup)
- return float_p;
- if (group == vector_reggroup)
- return vector_p;
- if (group == general_reggroup)
- return (!vector_p && !float_p);
- if (group == save_reggroup || group == restore_reggroup)
- return raw_p;
- return 0;
- }
- static const char *
- ia64_register_name (struct gdbarch *gdbarch, int reg)
- {
- return ia64_register_names[reg];
- }
- struct type *
- ia64_register_type (struct gdbarch *arch, int reg)
- {
- if (reg >= IA64_FR0_REGNUM && reg <= IA64_FR127_REGNUM)
- return ia64_ext_type (arch);
- else
- return builtin_type (arch)->builtin_long;
- }
- static int
- ia64_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg)
- {
- if (reg >= IA64_GR32_REGNUM && reg <= IA64_GR127_REGNUM)
- return V32_REGNUM + (reg - IA64_GR32_REGNUM);
- return reg;
- }
- static long long
- extract_bit_field (const gdb_byte *bundle, int from, int len)
- {
- long long result = 0LL;
- int to = from + len;
- int from_byte = from / 8;
- int to_byte = to / 8;
- unsigned char *b = (unsigned char *) bundle;
- unsigned char c;
- int lshift;
- int i;
- c = b[from_byte];
- if (from_byte == to_byte)
- c = ((unsigned char) (c << (8 - to % 8))) >> (8 - to % 8);
- result = c >> (from % 8);
- lshift = 8 - (from % 8);
- for (i = from_byte+1; i < to_byte; i++)
- {
- result |= ((long long) b[i]) << lshift;
- lshift += 8;
- }
- if (from_byte < to_byte && (to % 8 != 0))
- {
- c = b[to_byte];
- c = ((unsigned char) (c << (8 - to % 8))) >> (8 - to % 8);
- result |= ((long long) c) << lshift;
- }
- return result;
- }
- static void
- replace_bit_field (gdb_byte *bundle, long long val, int from, int len)
- {
- int to = from + len;
- int from_byte = from / 8;
- int to_byte = to / 8;
- unsigned char *b = (unsigned char *) bundle;
- unsigned char c;
- if (from_byte == to_byte)
- {
- unsigned char left, right;
- c = b[from_byte];
- left = (c >> (to % 8)) << (to % 8);
- right = ((unsigned char) (c << (8 - from % 8))) >> (8 - from % 8);
- c = (unsigned char) (val & 0xff);
- c = (unsigned char) (c << (from % 8 + 8 - to % 8)) >> (8 - to % 8);
- c |= right | left;
- b[from_byte] = c;
- }
- else
- {
- int i;
- c = b[from_byte];
- c = ((unsigned char) (c << (8 - from % 8))) >> (8 - from % 8);
- c = c | (val << (from % 8));
- b[from_byte] = c;
- val >>= 8 - from % 8;
- for (i = from_byte+1; i < to_byte; i++)
- {
- c = val & 0xff;
- val >>= 8;
- b[i] = c;
- }
- if (to % 8 != 0)
- {
- unsigned char cv = (unsigned char) val;
- c = b[to_byte];
- c = c >> (to % 8) << (to % 8);
- c |= ((unsigned char) (cv << (8 - to % 8))) >> (8 - to % 8);
- b[to_byte] = c;
- }
- }
- }
- static long long
- slotN_contents (gdb_byte *bundle, int slotnum)
- {
- return extract_bit_field (bundle, 5+41*slotnum, 41);
- }
- static void
- replace_slotN_contents (gdb_byte *bundle, long long instr, int slotnum)
- {
- replace_bit_field (bundle, instr, 5+41*slotnum, 41);
- }
- static const enum instruction_type template_encoding_table[32][3] =
- {
- { M, I, I },
- { M, I, I },
- { M, I, I },
- { M, I, I },
- { M, L, X },
- { M, L, X },
- { undefined, undefined, undefined },
- { undefined, undefined, undefined },
- { M, M, I },
- { M, M, I },
- { M, M, I },
- { M, M, I },
- { M, F, I },
- { M, F, I },
- { M, M, F },
- { M, M, F },
- { M, I, B },
- { M, I, B },
- { M, B, B },
- { M, B, B },
- { undefined, undefined, undefined },
- { undefined, undefined, undefined },
- { B, B, B },
- { B, B, B },
- { M, M, B },
- { M, M, B },
- { undefined, undefined, undefined },
- { undefined, undefined, undefined },
- { M, F, B },
- { M, F, B },
- { undefined, undefined, undefined },
- { undefined, undefined, undefined },
- };
- static CORE_ADDR
- fetch_instruction (CORE_ADDR addr, instruction_type *it, long long *instr)
- {
- gdb_byte bundle[BUNDLE_LEN];
- int slotnum = (int) (addr & 0x0f) / SLOT_MULTIPLIER;
- long long template;
- int val;
-
- if (slotnum > 2)
- {
- warning (_("Can't fetch instructions for slot numbers greater than 2.\n"
- "Using slot 0 instead"));
- slotnum = 0;
- }
- addr &= ~0x0f;
- val = target_read_memory (addr, bundle, BUNDLE_LEN);
- if (val != 0)
- return 0;
- *instr = slotN_contents (bundle, slotnum);
- template = extract_bit_field (bundle, 0, 5);
- *it = template_encoding_table[(int)template][slotnum];
- if (slotnum == 2 || (slotnum == 1 && *it == L))
- addr += 16;
- else
- addr += (slotnum + 1) * SLOT_MULTIPLIER;
- return addr;
- }
- #define IA64_BREAKPOINT 0x00003333300LL
- static int
- ia64_memory_insert_breakpoint (struct gdbarch *gdbarch,
- struct bp_target_info *bp_tgt)
- {
- CORE_ADDR addr = bp_tgt->placed_address = bp_tgt->reqstd_address;
- gdb_byte bundle[BUNDLE_LEN];
- int slotnum = (int) (addr & 0x0f) / SLOT_MULTIPLIER, shadow_slotnum;
- long long instr_breakpoint;
- int val;
- int template;
- struct cleanup *cleanup;
- if (slotnum > 2)
- error (_("Can't insert breakpoint for slot numbers greater than 2."));
- addr &= ~0x0f;
-
- cleanup = make_show_memory_breakpoints_cleanup (0);
- val = target_read_memory (addr, bundle, BUNDLE_LEN);
- if (val != 0)
- {
- do_cleanups (cleanup);
- return val;
- }
-
- shadow_slotnum = slotnum;
-
- bp_tgt->shadow_len = BUNDLE_LEN - shadow_slotnum;
- template = extract_bit_field (bundle, 0, 5);
- if (template_encoding_table[template][slotnum] == X)
- {
-
- gdb_assert (slotnum == 2);
- error (_("Can't insert breakpoint for non-existing slot X"));
- }
- if (template_encoding_table[template][slotnum] == L)
- {
-
- gdb_assert (slotnum == 1);
- slotnum = 2;
- }
-
- memcpy (bp_tgt->shadow_contents, bundle + shadow_slotnum,
- bp_tgt->shadow_len);
-
- make_show_memory_breakpoints_cleanup (1);
- val = target_read_memory (addr, bundle, BUNDLE_LEN);
- if (val != 0)
- {
- do_cleanups (cleanup);
- return val;
- }
-
- instr_breakpoint = slotN_contents (bundle, slotnum);
- if (instr_breakpoint == IA64_BREAKPOINT)
- internal_error (__FILE__, __LINE__,
- _("Address %s already contains a breakpoint."),
- paddress (gdbarch, bp_tgt->placed_address));
- replace_slotN_contents (bundle, IA64_BREAKPOINT, slotnum);
- bp_tgt->placed_size = bp_tgt->shadow_len;
- val = target_write_memory (addr + shadow_slotnum, bundle + shadow_slotnum,
- bp_tgt->shadow_len);
- do_cleanups (cleanup);
- return val;
- }
- static int
- ia64_memory_remove_breakpoint (struct gdbarch *gdbarch,
- struct bp_target_info *bp_tgt)
- {
- CORE_ADDR addr = bp_tgt->placed_address;
- gdb_byte bundle_mem[BUNDLE_LEN], bundle_saved[BUNDLE_LEN];
- int slotnum = (addr & 0x0f) / SLOT_MULTIPLIER, shadow_slotnum;
- long long instr_breakpoint, instr_saved;
- int val;
- int template;
- struct cleanup *cleanup;
- addr &= ~0x0f;
-
- cleanup = make_show_memory_breakpoints_cleanup (1);
- val = target_read_memory (addr, bundle_mem, BUNDLE_LEN);
- if (val != 0)
- {
- do_cleanups (cleanup);
- return val;
- }
-
- shadow_slotnum = slotnum;
- template = extract_bit_field (bundle_mem, 0, 5);
- if (template_encoding_table[template][slotnum] == X)
- {
-
- gdb_assert (slotnum == 2);
- warning (_("Cannot remove breakpoint at address %s from non-existing "
- "X-type slot, memory has changed underneath"),
- paddress (gdbarch, bp_tgt->placed_address));
- do_cleanups (cleanup);
- return -1;
- }
- if (template_encoding_table[template][slotnum] == L)
- {
-
- gdb_assert (slotnum == 1);
- slotnum = 2;
- }
- gdb_assert (bp_tgt->placed_size == BUNDLE_LEN - shadow_slotnum);
- gdb_assert (bp_tgt->placed_size == bp_tgt->shadow_len);
- instr_breakpoint = slotN_contents (bundle_mem, slotnum);
- if (instr_breakpoint != IA64_BREAKPOINT)
- {
- warning (_("Cannot remove breakpoint at address %s, "
- "no break instruction at such address."),
- paddress (gdbarch, bp_tgt->placed_address));
- do_cleanups (cleanup);
- return -1;
- }
-
- memcpy (bundle_saved, bundle_mem, BUNDLE_LEN);
- memcpy (bundle_saved + shadow_slotnum, bp_tgt->shadow_contents,
- bp_tgt->shadow_len);
- instr_saved = slotN_contents (bundle_saved, slotnum);
-
- replace_slotN_contents (bundle_mem, instr_saved, slotnum);
- val = target_write_raw_memory (addr, bundle_mem, BUNDLE_LEN);
- do_cleanups (cleanup);
- return val;
- }
- static const gdb_byte *
- ia64_breakpoint_from_pc (struct gdbarch *gdbarch,
- CORE_ADDR *pcptr, int *lenptr)
- {
- CORE_ADDR addr = *pcptr;
- static gdb_byte bundle[BUNDLE_LEN];
- int slotnum = (int) (*pcptr & 0x0f) / SLOT_MULTIPLIER, shadow_slotnum;
- long long instr_fetched;
- int val;
- int template;
- struct cleanup *cleanup;
- if (slotnum > 2)
- error (_("Can't insert breakpoint for slot numbers greater than 2."));
- addr &= ~0x0f;
-
- cleanup = make_show_memory_breakpoints_cleanup (0);
- val = target_read_memory (addr, bundle, BUNDLE_LEN);
- do_cleanups (cleanup);
-
- if (val != 0)
- return NULL;
-
- shadow_slotnum = slotnum;
-
- *lenptr = BUNDLE_LEN - shadow_slotnum;
-
- template = extract_bit_field (bundle, 0, 5);
- if (template_encoding_table[template][slotnum] == X)
- {
- gdb_assert (slotnum == 2);
- error (_("Can't insert breakpoint for non-existing slot X"));
- }
- if (template_encoding_table[template][slotnum] == L)
- {
- gdb_assert (slotnum == 1);
- slotnum = 2;
- }
-
- instr_fetched = slotN_contents (bundle, slotnum);
- instr_fetched &= 0x1003ffffc0LL;
- replace_slotN_contents (bundle, instr_fetched, slotnum);
- return bundle + shadow_slotnum;
- }
- static CORE_ADDR
- ia64_read_pc (struct regcache *regcache)
- {
- ULONGEST psr_value, pc_value;
- int slot_num;
- regcache_cooked_read_unsigned (regcache, IA64_PSR_REGNUM, &psr_value);
- regcache_cooked_read_unsigned (regcache, IA64_IP_REGNUM, &pc_value);
- slot_num = (psr_value >> 41) & 3;
- return pc_value | (slot_num * SLOT_MULTIPLIER);
- }
- void
- ia64_write_pc (struct regcache *regcache, CORE_ADDR new_pc)
- {
- int slot_num = (int) (new_pc & 0xf) / SLOT_MULTIPLIER;
- ULONGEST psr_value;
- regcache_cooked_read_unsigned (regcache, IA64_PSR_REGNUM, &psr_value);
- psr_value &= ~(3LL << 41);
- psr_value |= (ULONGEST)(slot_num & 0x3) << 41;
- new_pc &= ~0xfLL;
- regcache_cooked_write_unsigned (regcache, IA64_PSR_REGNUM, psr_value);
- regcache_cooked_write_unsigned (regcache, IA64_IP_REGNUM, new_pc);
- }
- #define IS_NaT_COLLECTION_ADDR(addr) ((((addr) >> 3) & 0x3f) == 0x3f)
- static CORE_ADDR
- rse_address_add(CORE_ADDR addr, int nslots)
- {
- CORE_ADDR new_addr;
- int mandatory_nat_slots = nslots / 63;
- int direction = nslots < 0 ? -1 : 1;
- new_addr = addr + 8 * (nslots + mandatory_nat_slots);
- if ((new_addr >> 9) != ((addr + 8 * 64 * mandatory_nat_slots) >> 9))
- new_addr += 8 * direction;
- if (IS_NaT_COLLECTION_ADDR(new_addr))
- new_addr += 8 * direction;
- return new_addr;
- }
- static enum register_status
- ia64_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
- int regnum, gdb_byte *buf)
- {
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- enum register_status status;
- if (regnum >= V32_REGNUM && regnum <= V127_REGNUM)
- {
- #ifdef HAVE_LIBUNWIND_IA64_H
-
- if (!libunwind_is_initialized ()
- || libunwind_get_reg_special (gdbarch, regcache, regnum, buf) != 0)
- #endif
- {
-
- enum register_status status;
- ULONGEST cfm;
- ULONGEST bsp;
- CORE_ADDR reg;
- status = regcache_cooked_read_unsigned (regcache,
- IA64_BSP_REGNUM, &bsp);
- if (status != REG_VALID)
- return status;
- status = regcache_cooked_read_unsigned (regcache,
- IA64_CFM_REGNUM, &cfm);
- if (status != REG_VALID)
- return status;
-
- bsp = rse_address_add (bsp, -(cfm & 0x7f));
- if ((cfm & 0x7f) > regnum - V32_REGNUM)
- {
- ULONGEST reg_addr = rse_address_add (bsp, (regnum - V32_REGNUM));
- reg = read_memory_integer ((CORE_ADDR)reg_addr, 8, byte_order);
- store_unsigned_integer (buf, register_size (gdbarch, regnum),
- byte_order, reg);
- }
- else
- store_unsigned_integer (buf, register_size (gdbarch, regnum),
- byte_order, 0);
- }
- }
- else if (IA64_NAT0_REGNUM <= regnum && regnum <= IA64_NAT31_REGNUM)
- {
- ULONGEST unatN_val;
- ULONGEST unat;
- status = regcache_cooked_read_unsigned (regcache, IA64_UNAT_REGNUM, &unat);
- if (status != REG_VALID)
- return status;
- unatN_val = (unat & (1LL << (regnum - IA64_NAT0_REGNUM))) != 0;
- store_unsigned_integer (buf, register_size (gdbarch, regnum),
- byte_order, unatN_val);
- }
- else if (IA64_NAT32_REGNUM <= regnum && regnum <= IA64_NAT127_REGNUM)
- {
- ULONGEST natN_val = 0;
- ULONGEST bsp;
- ULONGEST cfm;
- CORE_ADDR gr_addr = 0;
- status = regcache_cooked_read_unsigned (regcache, IA64_BSP_REGNUM, &bsp);
- if (status != REG_VALID)
- return status;
- status = regcache_cooked_read_unsigned (regcache, IA64_CFM_REGNUM, &cfm);
- if (status != REG_VALID)
- return status;
-
- bsp = rse_address_add (bsp, -(cfm & 0x7f));
- if ((cfm & 0x7f) > regnum - V32_REGNUM)
- gr_addr = rse_address_add (bsp, (regnum - V32_REGNUM));
- if (gr_addr != 0)
- {
-
- CORE_ADDR nat_addr = gr_addr | 0x1f8;
- CORE_ADDR nat_collection;
- int nat_bit;
-
- if (nat_addr >= bsp)
- regcache_cooked_read_unsigned (regcache, IA64_RNAT_REGNUM,
- &nat_collection);
- else
- nat_collection = read_memory_integer (nat_addr, 8, byte_order);
- nat_bit = (gr_addr >> 3) & 0x3f;
- natN_val = (nat_collection >> nat_bit) & 1;
- }
- store_unsigned_integer (buf, register_size (gdbarch, regnum),
- byte_order, natN_val);
- }
- else if (regnum == VBOF_REGNUM)
- {
-
- ULONGEST bsp, vbsp;
- ULONGEST cfm;
- status = regcache_cooked_read_unsigned (regcache, IA64_BSP_REGNUM, &bsp);
- if (status != REG_VALID)
- return status;
- status = regcache_cooked_read_unsigned (regcache, IA64_CFM_REGNUM, &cfm);
- if (status != REG_VALID)
- return status;
-
- vbsp = rse_address_add (bsp, -(cfm & 0x7f));
- store_unsigned_integer (buf, register_size (gdbarch, regnum),
- byte_order, vbsp);
- }
- else if (VP0_REGNUM <= regnum && regnum <= VP63_REGNUM)
- {
- ULONGEST pr;
- ULONGEST cfm;
- ULONGEST prN_val;
- status = regcache_cooked_read_unsigned (regcache, IA64_PR_REGNUM, &pr);
- if (status != REG_VALID)
- return status;
- status = regcache_cooked_read_unsigned (regcache, IA64_CFM_REGNUM, &cfm);
- if (status != REG_VALID)
- return status;
- if (VP16_REGNUM <= regnum && regnum <= VP63_REGNUM)
- {
-
- int rrb_pr = (cfm >> 32) & 0x3f;
-
- regnum = VP16_REGNUM
- + ((regnum - VP16_REGNUM) + rrb_pr) % 48;
- }
- prN_val = (pr & (1LL << (regnum - VP0_REGNUM))) != 0;
- store_unsigned_integer (buf, register_size (gdbarch, regnum),
- byte_order, prN_val);
- }
- else
- memset (buf, 0, register_size (gdbarch, regnum));
- return REG_VALID;
- }
- static void
- ia64_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
- int regnum, const gdb_byte *buf)
- {
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- if (regnum >= V32_REGNUM && regnum <= V127_REGNUM)
- {
- ULONGEST bsp;
- ULONGEST cfm;
- regcache_cooked_read_unsigned (regcache, IA64_BSP_REGNUM, &bsp);
- regcache_cooked_read_unsigned (regcache, IA64_CFM_REGNUM, &cfm);
- bsp = rse_address_add (bsp, -(cfm & 0x7f));
- if ((cfm & 0x7f) > regnum - V32_REGNUM)
- {
- ULONGEST reg_addr = rse_address_add (bsp, (regnum - V32_REGNUM));
- write_memory (reg_addr, (void *) buf, 8);
- }
- }
- else if (IA64_NAT0_REGNUM <= regnum && regnum <= IA64_NAT31_REGNUM)
- {
- ULONGEST unatN_val, unat, unatN_mask;
- regcache_cooked_read_unsigned (regcache, IA64_UNAT_REGNUM, &unat);
- unatN_val = extract_unsigned_integer (buf, register_size (gdbarch,
- regnum),
- byte_order);
- unatN_mask = (1LL << (regnum - IA64_NAT0_REGNUM));
- if (unatN_val == 0)
- unat &= ~unatN_mask;
- else if (unatN_val == 1)
- unat |= unatN_mask;
- regcache_cooked_write_unsigned (regcache, IA64_UNAT_REGNUM, unat);
- }
- else if (IA64_NAT32_REGNUM <= regnum && regnum <= IA64_NAT127_REGNUM)
- {
- ULONGEST natN_val;
- ULONGEST bsp;
- ULONGEST cfm;
- CORE_ADDR gr_addr = 0;
- regcache_cooked_read_unsigned (regcache, IA64_BSP_REGNUM, &bsp);
- regcache_cooked_read_unsigned (regcache, IA64_CFM_REGNUM, &cfm);
-
- bsp = rse_address_add (bsp, -(cfm & 0x7f));
- if ((cfm & 0x7f) > regnum - V32_REGNUM)
- gr_addr = rse_address_add (bsp, (regnum - V32_REGNUM));
- natN_val = extract_unsigned_integer (buf, register_size (gdbarch,
- regnum),
- byte_order);
- if (gr_addr != 0 && (natN_val == 0 || natN_val == 1))
- {
-
- CORE_ADDR nat_addr = gr_addr | 0x1f8;
- CORE_ADDR nat_collection;
- int natN_bit = (gr_addr >> 3) & 0x3f;
- ULONGEST natN_mask = (1LL << natN_bit);
-
- if (nat_addr >= bsp)
- {
- regcache_cooked_read_unsigned (regcache,
- IA64_RNAT_REGNUM,
- &nat_collection);
- if (natN_val)
- nat_collection |= natN_mask;
- else
- nat_collection &= ~natN_mask;
- regcache_cooked_write_unsigned (regcache, IA64_RNAT_REGNUM,
- nat_collection);
- }
- else
- {
- gdb_byte nat_buf[8];
- nat_collection = read_memory_integer (nat_addr, 8, byte_order);
- if (natN_val)
- nat_collection |= natN_mask;
- else
- nat_collection &= ~natN_mask;
- store_unsigned_integer (nat_buf, register_size (gdbarch, regnum),
- byte_order, nat_collection);
- write_memory (nat_addr, nat_buf, 8);
- }
- }
- }
- else if (VP0_REGNUM <= regnum && regnum <= VP63_REGNUM)
- {
- ULONGEST pr;
- ULONGEST cfm;
- ULONGEST prN_val;
- ULONGEST prN_mask;
- regcache_cooked_read_unsigned (regcache, IA64_PR_REGNUM, &pr);
- regcache_cooked_read_unsigned (regcache, IA64_CFM_REGNUM, &cfm);
- if (VP16_REGNUM <= regnum && regnum <= VP63_REGNUM)
- {
-
- int rrb_pr = (cfm >> 32) & 0x3f;
-
- regnum = VP16_REGNUM
- + ((regnum - VP16_REGNUM) + rrb_pr) % 48;
- }
- prN_val = extract_unsigned_integer (buf, register_size (gdbarch, regnum),
- byte_order);
- prN_mask = (1LL << (regnum - VP0_REGNUM));
- if (prN_val == 0)
- pr &= ~prN_mask;
- else if (prN_val == 1)
- pr |= prN_mask;
- regcache_cooked_write_unsigned (regcache, IA64_PR_REGNUM, pr);
- }
- }
- static int
- ia64_convert_register_p (struct gdbarch *gdbarch, int regno, struct type *type)
- {
- return (regno >= IA64_FR0_REGNUM && regno <= IA64_FR127_REGNUM
- && type != ia64_ext_type (gdbarch));
- }
- static int
- ia64_register_to_value (struct frame_info *frame, int regnum,
- struct type *valtype, gdb_byte *out,
- int *optimizedp, int *unavailablep)
- {
- struct gdbarch *gdbarch = get_frame_arch (frame);
- gdb_byte in[MAX_REGISTER_SIZE];
-
- if (!get_frame_register_bytes (frame, regnum, 0,
- register_size (gdbarch, regnum),
- in, optimizedp, unavailablep))
- return 0;
- convert_typed_floating (in, ia64_ext_type (gdbarch), out, valtype);
- *optimizedp = *unavailablep = 0;
- return 1;
- }
- static void
- ia64_value_to_register (struct frame_info *frame, int regnum,
- struct type *valtype, const gdb_byte *in)
- {
- struct gdbarch *gdbarch = get_frame_arch (frame);
- gdb_byte out[MAX_REGISTER_SIZE];
- convert_typed_floating (in, valtype, out, ia64_ext_type (gdbarch));
- put_frame_register (frame, regnum, out);
- }
- static int max_skip_non_prologue_insns = 40;
- FIXME
- static CORE_ADDR
- refine_prologue_limit (CORE_ADDR pc, CORE_ADDR lim_pc, int *trust_limit)
- {
- struct symtab_and_line prologue_sal;
- CORE_ADDR start_pc = pc;
- CORE_ADDR end_pc;
-
- if (find_pc_partial_function (pc, NULL, NULL, &end_pc) && end_pc < lim_pc)
- lim_pc = end_pc;
-
- *trust_limit = 0;
- prologue_sal = find_pc_line (pc, 0);
- if (prologue_sal.line != 0)
- {
- int i;
- CORE_ADDR addr = prologue_sal.end;
-
- for (i = 2 * max_skip_non_prologue_insns;
- i > 0 && (lim_pc == 0 || addr < lim_pc);
- i--)
- {
- struct symtab_and_line sal;
- sal = find_pc_line (addr, 0);
- if (sal.line == 0)
- break;
- if (sal.line <= prologue_sal.line
- && sal.symtab == prologue_sal.symtab)
- {
- prologue_sal = sal;
- }
- addr = sal.end;
- }
- if (lim_pc == 0 || prologue_sal.end < lim_pc)
- {
- lim_pc = prologue_sal.end;
- if (start_pc == get_pc_function_start (lim_pc))
- *trust_limit = 1;
- }
- }
- return lim_pc;
- }
- #define isScratch(_regnum_) ((_regnum_) == 2 || (_regnum_) == 3 \
- || (8 <= (_regnum_) && (_regnum_) <= 11) \
- || (14 <= (_regnum_) && (_regnum_) <= 31))
- #define imm9(_instr_) \
- ( ((((_instr_) & 0x01000000000LL) ? -1 : 0) << 8) \
- | (((_instr_) & 0x00008000000LL) >> 20) \
- | (((_instr_) & 0x00000001fc0LL) >> 6))
- static struct ia64_frame_cache *
- ia64_alloc_frame_cache (void)
- {
- struct ia64_frame_cache *cache;
- int i;
- cache = FRAME_OBSTACK_ZALLOC (struct ia64_frame_cache);
-
- cache->base = 0;
- cache->pc = 0;
- cache->cfm = 0;
- cache->prev_cfm = 0;
- cache->sof = 0;
- cache->sol = 0;
- cache->sor = 0;
- cache->bsp = 0;
- cache->fp_reg = 0;
- cache->frameless = 1;
- for (i = 0; i < NUM_IA64_RAW_REGS; i++)
- cache->saved_regs[i] = 0;
- return cache;
- }
- static CORE_ADDR
- examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc,
- struct frame_info *this_frame,
- struct ia64_frame_cache *cache)
- {
- CORE_ADDR next_pc;
- CORE_ADDR last_prologue_pc = pc;
- instruction_type it;
- long long instr;
- int cfm_reg = 0;
- int ret_reg = 0;
- int fp_reg = 0;
- int unat_save_reg = 0;
- int pr_save_reg = 0;
- int mem_stack_frame_size = 0;
- int spill_reg = 0;
- CORE_ADDR spill_addr = 0;
- char instores[8];
- char infpstores[8];
- char reg_contents[256];
- int trust_limit;
- int frameless = 1;
- int i;
- CORE_ADDR addr;
- gdb_byte buf[8];
- CORE_ADDR bof, sor, sol, sof, cfm, rrb_gr;
- memset (instores, 0, sizeof instores);
- memset (infpstores, 0, sizeof infpstores);
- memset (reg_contents, 0, sizeof reg_contents);
- if (cache->after_prologue != 0
- && cache->after_prologue <= lim_pc)
- return cache->after_prologue;
- lim_pc = refine_prologue_limit (pc, lim_pc, &trust_limit);
- next_pc = fetch_instruction (pc, &it, &instr);
-
- if (pc < lim_pc && next_pc
- && it == M && ((instr & 0x1ee0000003fLL) == 0x02c00000000LL))
- {
-
- int sor = (int) ((instr & 0x00078000000LL) >> 27);
- int sol = (int) ((instr & 0x00007f00000LL) >> 20);
- int sof = (int) ((instr & 0x000000fe000LL) >> 13);
- int rN = (int) ((instr & 0x00000001fc0LL) >> 6);
-
- if (!this_frame ||
- (sof == (cache->cfm & 0x7f) &&
- sol == ((cache->cfm >> 7) & 0x7f)))
- frameless = 0;
- cfm_reg = rN;
- last_prologue_pc = next_pc;
- pc = next_pc;
- }
- else
- {
-
- if (pc < lim_pc && next_pc
- && (it == I || it == M)
- && ((instr & 0x1ee00000000LL) == 0x10800000000LL))
- {
-
- int imm = (int) ((((instr & 0x01000000000LL) ? -1 : 0) << 13)
- | ((instr & 0x001f8000000LL) >> 20)
- | ((instr & 0x000000fe000LL) >> 13));
- int rM = (int) ((instr & 0x00007f00000LL) >> 20);
- int rN = (int) ((instr & 0x00000001fc0LL) >> 6);
- int qp = (int) (instr & 0x0000000003fLL);
- if (qp == 0 && rN == 2 && imm == 0 && rM == 12 && fp_reg == 0)
- {
-
- fp_reg = rN;
- last_prologue_pc = next_pc;
- }
- }
-
- if (!fp_reg)
- {
- pc = lim_pc;
- if (trust_limit)
- last_prologue_pc = lim_pc;
- }
- }
-
- while (pc < lim_pc)
- {
- next_pc = fetch_instruction (pc, &it, &instr);
- if (next_pc == 0)
- break;
- if (it == B && ((instr & 0x1e1f800003fLL) != 0x04000000000LL))
- {
-
- if (trust_limit)
- lim_pc = pc;
- break;
- }
- else if (((instr & 0x3fLL) != 0LL) &&
- (frameless || ret_reg != 0))
- {
-
- if (trust_limit)
- lim_pc = pc;
- break;
- }
- else if (it == I && ((instr & 0x1eff8000000LL) == 0x00188000000LL))
- {
-
- int b2 = (int) ((instr & 0x0000000e000LL) >> 13);
- int rN = (int) ((instr & 0x00000001fc0LL) >> 6);
- int qp = (int) (instr & 0x0000000003f);
- if (qp == 0 && b2 == 0 && rN >= 32 && ret_reg == 0)
- {
- ret_reg = rN;
- last_prologue_pc = next_pc;
- }
- }
- else if ((it == I || it == M)
- && ((instr & 0x1ee00000000LL) == 0x10800000000LL))
- {
-
- int imm = (int) ((((instr & 0x01000000000LL) ? -1 : 0) << 13)
- | ((instr & 0x001f8000000LL) >> 20)
- | ((instr & 0x000000fe000LL) >> 13));
- int rM = (int) ((instr & 0x00007f00000LL) >> 20);
- int rN = (int) ((instr & 0x00000001fc0LL) >> 6);
- int qp = (int) (instr & 0x0000000003fLL);
- if (qp == 0 && rN >= 32 && imm == 0 && rM == 12 && fp_reg == 0)
- {
-
- fp_reg = rN;
- last_prologue_pc = next_pc;
- }
- else if (qp == 0 && rN == 12 && rM == 12)
- {
-
- mem_stack_frame_size -= imm;
- last_prologue_pc = next_pc;
- }
- else if (qp == 0 && rN == 2
- && ((rM == fp_reg && fp_reg != 0) || rM == 12))
- {
- gdb_byte buf[MAX_REGISTER_SIZE];
- CORE_ADDR saved_sp = 0;
-
- FIXME
-
- FIXME
- if (this_frame)
- {
- struct gdbarch *gdbarch = get_frame_arch (this_frame);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- get_frame_register (this_frame, sp_regnum, buf);
- saved_sp = extract_unsigned_integer (buf, 8, byte_order);
- }
- spill_addr = saved_sp
- + (rM == 12 ? 0 : mem_stack_frame_size)
- + imm;
- spill_reg = rN;
- last_prologue_pc = next_pc;
- }
- else if (qp == 0 && rM >= 32 && rM < 40 && !instores[rM-32] &&
- rN < 256 && imm == 0)
- {
-
- reg_contents[rN] = rM;
- last_prologue_pc = next_pc;
- }
- else if (frameless && qp == 0 && rN == fp_reg && imm == 0 &&
- rM == 2)
- {
-
- last_prologue_pc = next_pc;
- break;
- }
- }
- else if (it == M
- && ( ((instr & 0x1efc0000000LL) == 0x0eec0000000LL)
- || ((instr & 0x1ffc8000000LL) == 0x0cec0000000LL) ))
- {
-
- int imm = imm9(instr);
- int rN = (int) ((instr & 0x00007f00000LL) >> 20);
- int fM = (int) ((instr & 0x000000fe000LL) >> 13);
- int qp = (int) (instr & 0x0000000003fLL);
- if (qp == 0 && rN == spill_reg && spill_addr != 0
- && ((2 <= fM && fM <= 5) || (16 <= fM && fM <= 31)))
- {
- cache->saved_regs[IA64_FR0_REGNUM + fM] = spill_addr;
- if ((instr & 0x1efc0000000LL) == 0x0eec0000000LL)
- spill_addr += imm;
- else
- spill_addr = 0;
- last_prologue_pc = next_pc;
- }
- }
- else if ((it == M && ((instr & 0x1eff8000000LL) == 0x02110000000LL))
- || (it == I && ((instr & 0x1eff8000000LL) == 0x00050000000LL)) )
- {
-
- int arM = (int) ((instr & 0x00007f00000LL) >> 20);
- int rN = (int) ((instr & 0x00000001fc0LL) >> 6);
- int qp = (int) (instr & 0x0000000003fLL);
- if (qp == 0 && isScratch (rN) && arM == 36 )
- {
-
- unat_save_reg = rN;
- last_prologue_pc = next_pc;
- }
- }
- else if (it == I && ((instr & 0x1eff8000000LL) == 0x00198000000LL))
- {
-
- int rN = (int) ((instr & 0x00000001fc0LL) >> 6);
- int qp = (int) (instr & 0x0000000003fLL);
- if (qp == 0 && isScratch (rN))
- {
- pr_save_reg = rN;
- last_prologue_pc = next_pc;
- }
- }
- else if (it == M
- && ( ((instr & 0x1ffc8000000LL) == 0x08cc0000000LL)
- || ((instr & 0x1efc0000000LL) == 0x0acc0000000LL)))
- {
-
- int rN = (int) ((instr & 0x00007f00000LL) >> 20);
- int rM = (int) ((instr & 0x000000fe000LL) >> 13);
- int qp = (int) (instr & 0x0000000003fLL);
- int indirect = rM < 256 ? reg_contents[rM] : 0;
- if (qp == 0 && rN == spill_reg && spill_addr != 0
- && (rM == unat_save_reg || rM == pr_save_reg))
- {
-
- if (rM == unat_save_reg)
- {
-
- cache->saved_regs[IA64_UNAT_REGNUM] = spill_addr;
- unat_save_reg = 0;
- }
- else
- {
-
- cache->saved_regs[IA64_PR_REGNUM] = spill_addr;
- pr_save_reg = 0;
- }
- if ((instr & 0x1efc0000000LL) == 0x0acc0000000LL)
-
- spill_addr += imm9(instr);
- else
- spill_addr = 0;
- last_prologue_pc = next_pc;
- }
- else if (qp == 0 && 32 <= rM && rM < 40 && !instores[rM-32])
- {
-
- instores[rM-32] = 1;
- last_prologue_pc = next_pc;
- }
- else if (qp == 0 && 32 <= indirect && indirect < 40 &&
- !instores[indirect-32])
- {
-
- instores[indirect-32] = 1;
- last_prologue_pc = next_pc;
- }
- }
- else if (it == M && ((instr & 0x1ff08000000LL) == 0x08c00000000LL))
- {
-
- int rM = (int) ((instr & 0x000000fe000LL) >> 13);
- int qp = (int) (instr & 0x0000000003fLL);
- int indirect = rM < 256 ? reg_contents[rM] : 0;
- if (qp == 0 && 32 <= rM && rM < 40 && !instores[rM-32])
- {
- instores[rM-32] = 1;
- last_prologue_pc = next_pc;
- }
- else if (qp == 0 && 32 <= indirect && indirect < 40 &&
- !instores[indirect-32])
- {
-
- instores[indirect-32] = 1;
- last_prologue_pc = next_pc;
- }
- }
- else if (it == M && ((instr & 0x1ff88000000LL) == 0x0cc80000000LL))
- {
-
- int fM = (int) ((instr & 0x000000fe000LL) >> 13);
- int qp = (int) (instr & 0x0000000003fLL);
- if (qp == 0 && 8 <= fM && fM < 16 && !infpstores[fM - 8])
- {
- infpstores[fM-8] = 1;
- last_prologue_pc = next_pc;
- }
- }
- else if (it == M
- && ( ((instr & 0x1ffc8000000LL) == 0x08ec0000000LL)
- || ((instr & 0x1efc0000000LL) == 0x0aec0000000LL)))
- {
-
- int rN = (int) ((instr & 0x00007f00000LL) >> 20);
- int rM = (int) ((instr & 0x000000fe000LL) >> 13);
- int qp = (int) (instr & 0x0000000003fLL);
- if (qp == 0 && rN == spill_reg && 4 <= rM && rM <= 7)
- {
-
- cache->saved_regs[IA64_GR0_REGNUM + rM] = spill_addr;
- if ((instr & 0x1efc0000000LL) == 0x0aec0000000LL)
-
- spill_addr += imm9(instr);
- else
- spill_addr = 0;
- last_prologue_pc = next_pc;
- }
- }
- pc = next_pc;
- }
-
- if (!frameless && this_frame)
- {
- struct gdbarch *gdbarch = get_frame_arch (this_frame);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
-
- cfm = cache->cfm;
- sor = cache->sor;
- sof = cache->sof;
- sol = cache->sol;
- rrb_gr = (cfm >> 18) & 0x7f;
-
- bof = rse_address_add (cache->bsp, -sof);
- for (i = 0, addr = bof;
- i < sof;
- i++, addr += 8)
- {
- if (IS_NaT_COLLECTION_ADDR (addr))
- {
- addr += 8;
- }
- if (i+32 == cfm_reg)
- cache->saved_regs[IA64_CFM_REGNUM] = addr;
- if (i+32 == ret_reg)
- cache->saved_regs[IA64_VRAP_REGNUM] = addr;
- if (i+32 == fp_reg)
- cache->saved_regs[IA64_VFP_REGNUM] = addr;
- }
-
- cfm = 0;
- if (cache->saved_regs[IA64_CFM_REGNUM] != 0)
- {
- cfm = read_memory_integer (cache->saved_regs[IA64_CFM_REGNUM],
- 8, byte_order);
- }
- else if (cfm_reg != 0)
- {
- get_frame_register (this_frame, cfm_reg, buf);
- cfm = extract_unsigned_integer (buf, 8, byte_order);
- }
- cache->prev_cfm = cfm;
- if (cfm != 0)
- {
- sor = ((cfm >> 14) & 0xf) * 8;
- sof = (cfm & 0x7f);
- sol = (cfm >> 7) & 0x7f;
- rrb_gr = (cfm >> 18) & 0x7f;
-
- bof = rse_address_add (bof, -sol);
- for (i = 0, addr = bof;
- i < sof;
- i++, addr += 8)
- {
- if (IS_NaT_COLLECTION_ADDR (addr))
- {
- addr += 8;
- }
- if (i < sor)
- cache->saved_regs[IA64_GR32_REGNUM
- + ((i + (sor - rrb_gr)) % sor)]
- = addr;
- else
- cache->saved_regs[IA64_GR32_REGNUM + i] = addr;
- }
- }
- }
-
- if (trust_limit && lim_pc >= last_prologue_pc)
- last_prologue_pc = lim_pc;
- cache->frameless = frameless;
- cache->after_prologue = last_prologue_pc;
- cache->mem_stack_frame_size = mem_stack_frame_size;
- cache->fp_reg = fp_reg;
- return last_prologue_pc;
- }
- CORE_ADDR
- ia64_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
- {
- struct ia64_frame_cache cache;
- cache.base = 0;
- cache.after_prologue = 0;
- cache.cfm = 0;
- cache.bsp = 0;
-
- return examine_prologue (pc, pc+1024, 0, &cache);
- }
- static struct ia64_frame_cache *
- ia64_frame_cache (struct frame_info *this_frame, void **this_cache)
- {
- struct gdbarch *gdbarch = get_frame_arch (this_frame);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- struct ia64_frame_cache *cache;
- gdb_byte buf[8];
- CORE_ADDR cfm, psr;
- if (*this_cache)
- return *this_cache;
- cache = ia64_alloc_frame_cache ();
- *this_cache = cache;
- get_frame_register (this_frame, sp_regnum, buf);
- cache->saved_sp = extract_unsigned_integer (buf, 8, byte_order);
-
- get_frame_register (this_frame, IA64_BSP_REGNUM, buf);
- cache->bsp = extract_unsigned_integer (buf, 8, byte_order);
- get_frame_register (this_frame, IA64_PSR_REGNUM, buf);
- psr = extract_unsigned_integer (buf, 8, byte_order);
- get_frame_register (this_frame, IA64_CFM_REGNUM, buf);
- cfm = extract_unsigned_integer (buf, 8, byte_order);
- cache->sof = (cfm & 0x7f);
- cache->sol = (cfm >> 7) & 0x7f;
- cache->sor = ((cfm >> 14) & 0xf) * 8;
- cache->cfm = cfm;
- cache->pc = get_frame_func (this_frame);
- if (cache->pc != 0)
- examine_prologue (cache->pc, get_frame_pc (this_frame), this_frame, cache);
- cache->base = cache->saved_sp + cache->mem_stack_frame_size;
- return cache;
- }
- static void
- ia64_frame_this_id (struct frame_info *this_frame, void **this_cache,
- struct frame_id *this_id)
- {
- struct gdbarch *gdbarch = get_frame_arch (this_frame);
- struct ia64_frame_cache *cache =
- ia64_frame_cache (this_frame, this_cache);
-
- if (cache->base != 0)
- (*this_id) = frame_id_build_special (cache->base, cache->pc, cache->bsp);
- if (gdbarch_debug >= 1)
- fprintf_unfiltered (gdb_stdlog,
- "regular frame id: code %s, stack %s, "
- "special %s, this_frame %s\n",
- paddress (gdbarch, this_id->code_addr),
- paddress (gdbarch, this_id->stack_addr),
- paddress (gdbarch, cache->bsp),
- host_address_to_string (this_frame));
- }
- static struct value *
- ia64_frame_prev_register (struct frame_info *this_frame, void **this_cache,
- int regnum)
- {
- struct gdbarch *gdbarch = get_frame_arch (this_frame);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- struct ia64_frame_cache *cache = ia64_frame_cache (this_frame, this_cache);
- gdb_byte buf[8];
- gdb_assert (regnum >= 0);
- if (!target_has_registers)
- error (_("No registers."));
- if (regnum == gdbarch_sp_regnum (gdbarch))
- return frame_unwind_got_constant (this_frame, regnum, cache->base);
- else if (regnum == IA64_BSP_REGNUM)
- {
- struct value *val;
- CORE_ADDR prev_cfm, bsp, prev_bsp;
-
- val = ia64_frame_prev_register (this_frame, this_cache, IA64_CFM_REGNUM);
- prev_cfm = extract_unsigned_integer (value_contents_all (val),
- 8, byte_order);
- bsp = rse_address_add (cache->bsp, -(cache->sof));
- prev_bsp =
- rse_address_add (bsp, (prev_cfm & 0x7f) - ((prev_cfm >> 7) & 0x7f));
- return frame_unwind_got_constant (this_frame, regnum, prev_bsp);
- }
- else if (regnum == IA64_CFM_REGNUM)
- {
- CORE_ADDR addr = cache->saved_regs[IA64_CFM_REGNUM];
- if (addr != 0)
- return frame_unwind_got_memory (this_frame, regnum, addr);
- if (cache->prev_cfm)
- return frame_unwind_got_constant (this_frame, regnum, cache->prev_cfm);
- if (cache->frameless)
- return frame_unwind_got_register (this_frame, IA64_PFS_REGNUM,
- IA64_PFS_REGNUM);
- return frame_unwind_got_register (this_frame, regnum, 0);
- }
- else if (regnum == IA64_VFP_REGNUM)
- {
-
- return frame_unwind_got_constant (this_frame, regnum, cache->base);
- }
- else if (VP0_REGNUM <= regnum && regnum <= VP63_REGNUM)
- {
- struct value *pr_val;
- ULONGEST prN;
- pr_val = ia64_frame_prev_register (this_frame, this_cache,
- IA64_PR_REGNUM);
- if (VP16_REGNUM <= regnum && regnum <= VP63_REGNUM)
- {
-
- int rrb_pr = (cache->cfm >> 32) & 0x3f;
-
- regnum = VP16_REGNUM + ((regnum - VP16_REGNUM) + rrb_pr) % 48;
- }
- prN = extract_bit_field (value_contents_all (pr_val),
- regnum - VP0_REGNUM, 1);
- return frame_unwind_got_constant (this_frame, regnum, prN);
- }
- else if (IA64_NAT0_REGNUM <= regnum && regnum <= IA64_NAT31_REGNUM)
- {
- struct value *unat_val;
- ULONGEST unatN;
- unat_val = ia64_frame_prev_register (this_frame, this_cache,
- IA64_UNAT_REGNUM);
- unatN = extract_bit_field (value_contents_all (unat_val),
- regnum - IA64_NAT0_REGNUM, 1);
- return frame_unwind_got_constant (this_frame, regnum, unatN);
- }
- else if (IA64_NAT32_REGNUM <= regnum && regnum <= IA64_NAT127_REGNUM)
- {
- int natval = 0;
-
- CORE_ADDR gr_addr;
- gr_addr = cache->saved_regs[regnum - IA64_NAT0_REGNUM + IA64_GR0_REGNUM];
- if (gr_addr != 0)
- {
-
- CORE_ADDR nat_addr = gr_addr | 0x1f8;
- CORE_ADDR bsp;
- CORE_ADDR nat_collection;
- int nat_bit;
-
- get_frame_register (this_frame, IA64_BSP_REGNUM, buf);
- bsp = extract_unsigned_integer (buf, 8, byte_order);
- if (nat_addr >= bsp)
- {
- get_frame_register (this_frame, IA64_RNAT_REGNUM, buf);
- nat_collection = extract_unsigned_integer (buf, 8, byte_order);
- }
- else
- nat_collection = read_memory_integer (nat_addr, 8, byte_order);
- nat_bit = (gr_addr >> 3) & 0x3f;
- natval = (nat_collection >> nat_bit) & 1;
- }
- return frame_unwind_got_constant (this_frame, regnum, natval);
- }
- else if (regnum == IA64_IP_REGNUM)
- {
- CORE_ADDR pc = 0;
- CORE_ADDR addr = cache->saved_regs[IA64_VRAP_REGNUM];
- if (addr != 0)
- {
- read_memory (addr, buf, register_size (gdbarch, IA64_IP_REGNUM));
- pc = extract_unsigned_integer (buf, 8, byte_order);
- }
- else if (cache->frameless)
- {
- get_frame_register (this_frame, IA64_BR0_REGNUM, buf);
- pc = extract_unsigned_integer (buf, 8, byte_order);
- }
- pc &= ~0xf;
- return frame_unwind_got_constant (this_frame, regnum, pc);
- }
- else if (regnum == IA64_PSR_REGNUM)
- {
-
- ULONGEST slot_num = 0;
- CORE_ADDR pc = 0;
- CORE_ADDR psr = 0;
- CORE_ADDR addr = cache->saved_regs[IA64_VRAP_REGNUM];
- get_frame_register (this_frame, IA64_PSR_REGNUM, buf);
- psr = extract_unsigned_integer (buf, 8, byte_order);
- if (addr != 0)
- {
- read_memory (addr, buf, register_size (gdbarch, IA64_IP_REGNUM));
- pc = extract_unsigned_integer (buf, 8, byte_order);
- }
- else if (cache->frameless)
- {
- get_frame_register (this_frame, IA64_BR0_REGNUM, buf);
- pc = extract_unsigned_integer (buf, 8, byte_order);
- }
- psr &= ~(3LL << 41);
- slot_num = pc & 0x3LL;
- psr |= (CORE_ADDR)slot_num << 41;
- return frame_unwind_got_constant (this_frame, regnum, psr);
- }
- else if (regnum == IA64_BR0_REGNUM)
- {
- CORE_ADDR addr = cache->saved_regs[IA64_BR0_REGNUM];
- if (addr != 0)
- return frame_unwind_got_memory (this_frame, regnum, addr);
- return frame_unwind_got_constant (this_frame, regnum, 0);
- }
- else if ((regnum >= IA64_GR32_REGNUM && regnum <= IA64_GR127_REGNUM)
- || (regnum >= V32_REGNUM && regnum <= V127_REGNUM))
- {
- CORE_ADDR addr = 0;
- if (regnum >= V32_REGNUM)
- regnum = IA64_GR32_REGNUM + (regnum - V32_REGNUM);
- addr = cache->saved_regs[regnum];
- if (addr != 0)
- return frame_unwind_got_memory (this_frame, regnum, addr);
- if (cache->frameless)
- {
- struct value *reg_val;
- CORE_ADDR prev_cfm, prev_bsp, prev_bof;
- FIXME
- if (regnum >= V32_REGNUM)
- regnum = IA64_GR32_REGNUM + (regnum - V32_REGNUM);
- reg_val = ia64_frame_prev_register (this_frame, this_cache,
- IA64_CFM_REGNUM);
- prev_cfm = extract_unsigned_integer (value_contents_all (reg_val),
- 8, byte_order);
- reg_val = ia64_frame_prev_register (this_frame, this_cache,
- IA64_BSP_REGNUM);
- prev_bsp = extract_unsigned_integer (value_contents_all (reg_val),
- 8, byte_order);
- prev_bof = rse_address_add (prev_bsp, -(prev_cfm & 0x7f));
- addr = rse_address_add (prev_bof, (regnum - IA64_GR32_REGNUM));
- return frame_unwind_got_memory (this_frame, regnum, addr);
- }
- return frame_unwind_got_constant (this_frame, regnum, 0);
- }
- else
- {
- CORE_ADDR addr = 0;
- if (IA64_FR32_REGNUM <= regnum && regnum <= IA64_FR127_REGNUM)
- {
-
- int rrb_fr = (cache->cfm >> 25) & 0x7f;
-
- regnum = IA64_FR32_REGNUM
- + ((regnum - IA64_FR32_REGNUM) + rrb_fr) % 96;
- }
-
- addr = cache->saved_regs[regnum];
- if (addr != 0)
- return frame_unwind_got_memory (this_frame, regnum, addr);
-
- else
- return frame_unwind_got_register (this_frame, regnum, regnum);
- }
- }
- static const struct frame_unwind ia64_frame_unwind =
- {
- NORMAL_FRAME,
- default_frame_unwind_stop_reason,
- &ia64_frame_this_id,
- &ia64_frame_prev_register,
- NULL,
- default_frame_sniffer
- };
- static void
- ia64_sigtramp_frame_init_saved_regs (struct frame_info *this_frame,
- struct ia64_frame_cache *cache)
- {
- struct gdbarch *gdbarch = get_frame_arch (this_frame);
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- if (tdep->sigcontext_register_address)
- {
- int regno;
- cache->saved_regs[IA64_VRAP_REGNUM]
- = tdep->sigcontext_register_address (gdbarch, cache->base,
- IA64_IP_REGNUM);
- cache->saved_regs[IA64_CFM_REGNUM]
- = tdep->sigcontext_register_address (gdbarch, cache->base,
- IA64_CFM_REGNUM);
- cache->saved_regs[IA64_PSR_REGNUM]
- = tdep->sigcontext_register_address (gdbarch, cache->base,
- IA64_PSR_REGNUM);
- cache->saved_regs[IA64_BSP_REGNUM]
- = tdep->sigcontext_register_address (gdbarch, cache->base,
- IA64_BSP_REGNUM);
- cache->saved_regs[IA64_RNAT_REGNUM]
- = tdep->sigcontext_register_address (gdbarch, cache->base,
- IA64_RNAT_REGNUM);
- cache->saved_regs[IA64_CCV_REGNUM]
- = tdep->sigcontext_register_address (gdbarch, cache->base,
- IA64_CCV_REGNUM);
- cache->saved_regs[IA64_UNAT_REGNUM]
- = tdep->sigcontext_register_address (gdbarch, cache->base,
- IA64_UNAT_REGNUM);
- cache->saved_regs[IA64_FPSR_REGNUM]
- = tdep->sigcontext_register_address (gdbarch, cache->base,
- IA64_FPSR_REGNUM);
- cache->saved_regs[IA64_PFS_REGNUM]
- = tdep->sigcontext_register_address (gdbarch, cache->base,
- IA64_PFS_REGNUM);
- cache->saved_regs[IA64_LC_REGNUM]
- = tdep->sigcontext_register_address (gdbarch, cache->base,
- IA64_LC_REGNUM);
- for (regno = IA64_GR1_REGNUM; regno <= IA64_GR31_REGNUM; regno++)
- cache->saved_regs[regno] =
- tdep->sigcontext_register_address (gdbarch, cache->base, regno);
- for (regno = IA64_BR0_REGNUM; regno <= IA64_BR7_REGNUM; regno++)
- cache->saved_regs[regno] =
- tdep->sigcontext_register_address (gdbarch, cache->base, regno);
- for (regno = IA64_FR2_REGNUM; regno <= IA64_FR31_REGNUM; regno++)
- cache->saved_regs[regno] =
- tdep->sigcontext_register_address (gdbarch, cache->base, regno);
- }
- }
- static struct ia64_frame_cache *
- ia64_sigtramp_frame_cache (struct frame_info *this_frame, void **this_cache)
- {
- struct gdbarch *gdbarch = get_frame_arch (this_frame);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- struct ia64_frame_cache *cache;
- gdb_byte buf[8];
- if (*this_cache)
- return *this_cache;
- cache = ia64_alloc_frame_cache ();
- get_frame_register (this_frame, sp_regnum, buf);
-
- cache->base = extract_unsigned_integer (buf, 8, byte_order) + 16;
- get_frame_register (this_frame, IA64_BSP_REGNUM, buf);
- cache->bsp = extract_unsigned_integer (buf, 8, byte_order);
- get_frame_register (this_frame, IA64_CFM_REGNUM, buf);
- cache->cfm = extract_unsigned_integer (buf, 8, byte_order);
- cache->sof = cache->cfm & 0x7f;
- ia64_sigtramp_frame_init_saved_regs (this_frame, cache);
- *this_cache = cache;
- return cache;
- }
- static void
- ia64_sigtramp_frame_this_id (struct frame_info *this_frame,
- void **this_cache, struct frame_id *this_id)
- {
- struct gdbarch *gdbarch = get_frame_arch (this_frame);
- struct ia64_frame_cache *cache =
- ia64_sigtramp_frame_cache (this_frame, this_cache);
- (*this_id) = frame_id_build_special (cache->base,
- get_frame_pc (this_frame),
- cache->bsp);
- if (gdbarch_debug >= 1)
- fprintf_unfiltered (gdb_stdlog,
- "sigtramp frame id: code %s, stack %s, "
- "special %s, this_frame %s\n",
- paddress (gdbarch, this_id->code_addr),
- paddress (gdbarch, this_id->stack_addr),
- paddress (gdbarch, cache->bsp),
- host_address_to_string (this_frame));
- }
- static struct value *
- ia64_sigtramp_frame_prev_register (struct frame_info *this_frame,
- void **this_cache, int regnum)
- {
- gdb_byte buf[MAX_REGISTER_SIZE];
- struct gdbarch *gdbarch = get_frame_arch (this_frame);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- struct ia64_frame_cache *cache =
- ia64_sigtramp_frame_cache (this_frame, this_cache);
- gdb_assert (regnum >= 0);
- if (!target_has_registers)
- error (_("No registers."));
- if (regnum == IA64_IP_REGNUM)
- {
- CORE_ADDR pc = 0;
- CORE_ADDR addr = cache->saved_regs[IA64_VRAP_REGNUM];
- if (addr != 0)
- {
- read_memory (addr, buf, register_size (gdbarch, IA64_IP_REGNUM));
- pc = extract_unsigned_integer (buf, 8, byte_order);
- }
- pc &= ~0xf;
- return frame_unwind_got_constant (this_frame, regnum, pc);
- }
- else if ((regnum >= IA64_GR32_REGNUM && regnum <= IA64_GR127_REGNUM)
- || (regnum >= V32_REGNUM && regnum <= V127_REGNUM))
- {
- CORE_ADDR addr = 0;
- if (regnum >= V32_REGNUM)
- regnum = IA64_GR32_REGNUM + (regnum - V32_REGNUM);
- addr = cache->saved_regs[regnum];
- if (addr != 0)
- return frame_unwind_got_memory (this_frame, regnum, addr);
- return frame_unwind_got_constant (this_frame, regnum, 0);
- }
- else
- {
- CORE_ADDR addr = cache->saved_regs[regnum];
- if (addr != 0)
- return frame_unwind_got_memory (this_frame, regnum, addr);
- return frame_unwind_got_constant (this_frame, regnum, 0);
- }
- }
- static int
- ia64_sigtramp_frame_sniffer (const struct frame_unwind *self,
- struct frame_info *this_frame,
- void **this_cache)
- {
- struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (this_frame));
- if (tdep->pc_in_sigtramp)
- {
- CORE_ADDR pc = get_frame_pc (this_frame);
- if (tdep->pc_in_sigtramp (pc))
- return 1;
- }
- return 0;
- }
- static const struct frame_unwind ia64_sigtramp_frame_unwind =
- {
- SIGTRAMP_FRAME,
- default_frame_unwind_stop_reason,
- ia64_sigtramp_frame_this_id,
- ia64_sigtramp_frame_prev_register,
- NULL,
- ia64_sigtramp_frame_sniffer
- };
- static CORE_ADDR
- ia64_frame_base_address (struct frame_info *this_frame, void **this_cache)
- {
- struct ia64_frame_cache *cache = ia64_frame_cache (this_frame, this_cache);
- return cache->base;
- }
- static const struct frame_base ia64_frame_base =
- {
- &ia64_frame_unwind,
- ia64_frame_base_address,
- ia64_frame_base_address,
- ia64_frame_base_address
- };
- #ifdef HAVE_LIBUNWIND_IA64_H
- struct ia64_unwind_table_entry
- {
- unw_word_t start_offset;
- unw_word_t end_offset;
- unw_word_t info_offset;
- };
- static __inline__ uint64_t
- ia64_rse_slot_num (uint64_t addr)
- {
- return (addr >> 3) & 0x3f;
- }
- static __inline__ uint64_t
- ia64_rse_skip_regs (uint64_t addr, long num_regs)
- {
- long delta = ia64_rse_slot_num(addr) + num_regs;
- if (num_regs < 0)
- delta -= 0x3e;
- return addr + ((num_regs + delta/0x3f) << 3);
- }
- static int
- ia64_gdb2uw_regnum (int regnum)
- {
- if (regnum == sp_regnum)
- return UNW_IA64_SP;
- else if (regnum == IA64_BSP_REGNUM)
- return UNW_IA64_BSP;
- else if ((unsigned) (regnum - IA64_GR0_REGNUM) < 128)
- return UNW_IA64_GR + (regnum - IA64_GR0_REGNUM);
- else if ((unsigned) (regnum - V32_REGNUM) < 95)
- return UNW_IA64_GR + 32 + (regnum - V32_REGNUM);
- else if ((unsigned) (regnum - IA64_FR0_REGNUM) < 128)
- return UNW_IA64_FR + (regnum - IA64_FR0_REGNUM);
- else if ((unsigned) (regnum - IA64_PR0_REGNUM) < 64)
- return -1;
- else if ((unsigned) (regnum - IA64_BR0_REGNUM) < 8)
- return UNW_IA64_BR + (regnum - IA64_BR0_REGNUM);
- else if (regnum == IA64_PR_REGNUM)
- return UNW_IA64_PR;
- else if (regnum == IA64_IP_REGNUM)
- return UNW_REG_IP;
- else if (regnum == IA64_CFM_REGNUM)
- return UNW_IA64_CFM;
- else if ((unsigned) (regnum - IA64_AR0_REGNUM) < 128)
- return UNW_IA64_AR + (regnum - IA64_AR0_REGNUM);
- else if ((unsigned) (regnum - IA64_NAT0_REGNUM) < 128)
- return UNW_IA64_NAT + (regnum - IA64_NAT0_REGNUM);
- else
- return -1;
- }
- static int
- ia64_uw2gdb_regnum (int uw_regnum)
- {
- if (uw_regnum == UNW_IA64_SP)
- return sp_regnum;
- else if (uw_regnum == UNW_IA64_BSP)
- return IA64_BSP_REGNUM;
- else if ((unsigned) (uw_regnum - UNW_IA64_GR) < 32)
- return IA64_GR0_REGNUM + (uw_regnum - UNW_IA64_GR);
- else if ((unsigned) (uw_regnum - UNW_IA64_GR) < 128)
- return V32_REGNUM + (uw_regnum - (IA64_GR0_REGNUM + 32));
- else if ((unsigned) (uw_regnum - UNW_IA64_FR) < 128)
- return IA64_FR0_REGNUM + (uw_regnum - UNW_IA64_FR);
- else if ((unsigned) (uw_regnum - UNW_IA64_BR) < 8)
- return IA64_BR0_REGNUM + (uw_regnum - UNW_IA64_BR);
- else if (uw_regnum == UNW_IA64_PR)
- return IA64_PR_REGNUM;
- else if (uw_regnum == UNW_REG_IP)
- return IA64_IP_REGNUM;
- else if (uw_regnum == UNW_IA64_CFM)
- return IA64_CFM_REGNUM;
- else if ((unsigned) (uw_regnum - UNW_IA64_AR) < 128)
- return IA64_AR0_REGNUM + (uw_regnum - UNW_IA64_AR);
- else if ((unsigned) (uw_regnum - UNW_IA64_NAT) < 128)
- return IA64_NAT0_REGNUM + (uw_regnum - UNW_IA64_NAT);
- else
- return -1;
- }
- static int
- ia64_is_fpreg (int uw_regnum)
- {
- return unw_is_fpreg (uw_regnum);
- }
- static int
- ia64_access_reg (unw_addr_space_t as, unw_regnum_t uw_regnum, unw_word_t *val,
- int write, void *arg)
- {
- int regnum = ia64_uw2gdb_regnum (uw_regnum);
- unw_word_t bsp, sof, sol, cfm, psr, ip;
- struct frame_info *this_frame = arg;
- struct gdbarch *gdbarch = get_frame_arch (this_frame);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- long new_sof, old_sof;
- gdb_byte buf[MAX_REGISTER_SIZE];
-
- gdb_assert (!write);
- switch (uw_regnum)
- {
- case UNW_REG_IP:
-
- get_frame_register (this_frame, IA64_IP_REGNUM, buf);
- ip = extract_unsigned_integer (buf, 8, byte_order);
- get_frame_register (this_frame, IA64_PSR_REGNUM, buf);
- psr = extract_unsigned_integer (buf, 8, byte_order);
- *val = ip | ((psr >> 41) & 0x3);
- break;
- case UNW_IA64_AR_BSP:
-
- get_frame_register (this_frame, IA64_BSP_REGNUM, buf);
- bsp = extract_unsigned_integer (buf, 8, byte_order);
- get_frame_register (this_frame, IA64_CFM_REGNUM, buf);
- cfm = extract_unsigned_integer (buf, 8, byte_order);
- sof = gdbarch_tdep (gdbarch)->size_of_register_frame (this_frame, cfm);
- *val = ia64_rse_skip_regs (bsp, -sof);
- break;
- case UNW_IA64_AR_BSPSTORE:
-
- get_frame_register (this_frame, IA64_BSP_REGNUM, buf);
- *val = extract_unsigned_integer (buf, 8, byte_order);
- break;
- default:
-
- get_frame_register (this_frame, regnum, buf);
- *val = extract_unsigned_integer (buf, 8, byte_order);
- break;
- }
- if (gdbarch_debug >= 1)
- fprintf_unfiltered (gdb_stdlog,
- " access_reg: from cache: %4s=%s\n",
- (((unsigned) regnum <= IA64_NAT127_REGNUM)
- ? ia64_register_names[regnum] : "r??"),
- paddress (gdbarch, *val));
- return 0;
- }
- static int
- ia64_access_fpreg (unw_addr_space_t as, unw_regnum_t uw_regnum,
- unw_fpreg_t *val, int write, void *arg)
- {
- int regnum = ia64_uw2gdb_regnum (uw_regnum);
- struct frame_info *this_frame = arg;
-
- gdb_assert (!write);
- get_frame_register (this_frame, regnum, (gdb_byte *) val);
- return 0;
- }
- static int
- ia64_access_rse_reg (unw_addr_space_t as, unw_regnum_t uw_regnum,
- unw_word_t *val, int write, void *arg)
- {
- int regnum = ia64_uw2gdb_regnum (uw_regnum);
- unw_word_t bsp, sof, sol, cfm, psr, ip;
- struct regcache *regcache = arg;
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- long new_sof, old_sof;
- gdb_byte buf[MAX_REGISTER_SIZE];
-
- gdb_assert (!write);
- switch (uw_regnum)
- {
- case UNW_REG_IP:
-
- regcache_cooked_read (regcache, IA64_IP_REGNUM, buf);
- ip = extract_unsigned_integer (buf, 8, byte_order);
- regcache_cooked_read (regcache, IA64_PSR_REGNUM, buf);
- psr = extract_unsigned_integer (buf, 8, byte_order);
- *val = ip | ((psr >> 41) & 0x3);
- break;
- case UNW_IA64_AR_BSP:
-
- regcache_cooked_read (regcache, IA64_BSP_REGNUM, buf);
- bsp = extract_unsigned_integer (buf, 8, byte_order);
- regcache_cooked_read (regcache, IA64_CFM_REGNUM, buf);
- cfm = extract_unsigned_integer (buf, 8, byte_order);
- sof = (cfm & 0x7f);
- *val = ia64_rse_skip_regs (bsp, -sof);
- break;
- case UNW_IA64_AR_BSPSTORE:
-
- regcache_cooked_read (regcache, IA64_BSP_REGNUM, buf);
- *val = extract_unsigned_integer (buf, 8, byte_order);
- break;
- default:
-
- regcache_cooked_read (regcache, regnum, buf);
- *val = extract_unsigned_integer (buf, 8, byte_order);
- break;
- }
- if (gdbarch_debug >= 1)
- fprintf_unfiltered (gdb_stdlog,
- " access_rse_reg: from cache: %4s=%s\n",
- (((unsigned) regnum <= IA64_NAT127_REGNUM)
- ? ia64_register_names[regnum] : "r??"),
- paddress (gdbarch, *val));
- return 0;
- }
- static int
- ia64_access_rse_fpreg (unw_addr_space_t as, unw_regnum_t uw_regnum,
- unw_fpreg_t *val, int write, void *arg)
- {
- int regnum = ia64_uw2gdb_regnum (uw_regnum);
- struct regcache *regcache = arg;
-
- gdb_assert (!write);
- regcache_cooked_read (regcache, regnum, (gdb_byte *) val);
- return 0;
- }
- static int
- ia64_access_mem (unw_addr_space_t as,
- unw_word_t addr, unw_word_t *val,
- int write, void *arg)
- {
- if (addr - KERNEL_START < ktab_size)
- {
- unw_word_t *laddr = (unw_word_t*) ((char *) ktab
- + (addr - KERNEL_START));
- if (write)
- *laddr = *val;
- else
- *val = *laddr;
- return 0;
- }
- XXX
- if (write)
- return target_write_memory (addr, (gdb_byte *) val, sizeof (unw_word_t));
- else
- return target_read_memory (addr, (gdb_byte *) val, sizeof (unw_word_t));
- }
- static LONGEST
- getunwind_table (gdb_byte **buf_p)
- {
- LONGEST x;
- FIXME
- x = target_read_alloc (¤t_target, TARGET_OBJECT_UNWIND_TABLE,
- NULL, buf_p);
- return x;
- }
- static int
- get_kernel_table (unw_word_t ip, unw_dyn_info_t *di)
- {
- static struct ia64_table_entry *etab;
- if (!ktab)
- {
- gdb_byte *ktab_buf;
- LONGEST size;
- size = getunwind_table (&ktab_buf);
- if (size <= 0)
- return -UNW_ENOINFO;
- ktab = (struct ia64_table_entry *) ktab_buf;
- ktab_size = size;
- for (etab = ktab; etab->start_offset; ++etab)
- etab->info_offset += KERNEL_START;
- }
- if (ip < ktab[0].start_offset || ip >= etab[-1].end_offset)
- return -UNW_ENOINFO;
- di->format = UNW_INFO_FORMAT_TABLE;
- di->gp = 0;
- di->start_ip = ktab[0].start_offset;
- di->end_ip = etab[-1].end_offset;
- di->u.ti.name_ptr = (unw_word_t) "<kernel>";
- di->u.ti.segbase = 0;
- di->u.ti.table_len = ((char *) etab - (char *) ktab) / sizeof (unw_word_t);
- di->u.ti.table_data = (unw_word_t *) ktab;
- if (gdbarch_debug >= 1)
- fprintf_unfiltered (gdb_stdlog, "get_kernel_table: found table `%s': "
- "segbase=%s, length=%s, gp=%s\n",
- (char *) di->u.ti.name_ptr,
- hex_string (di->u.ti.segbase),
- pulongest (di->u.ti.table_len),
- hex_string (di->gp));
- return 0;
- }
- static int
- ia64_find_unwind_table (struct objfile *objfile, unw_word_t ip,
- unw_dyn_info_t *dip, void **buf)
- {
- Elf_Internal_Phdr *phdr, *p_text = NULL, *p_unwind = NULL;
- Elf_Internal_Ehdr *ehdr;
- unw_word_t segbase = 0;
- CORE_ADDR load_base;
- bfd *bfd;
- int i;
- bfd = objfile->obfd;
- ehdr = elf_tdata (bfd)->elf_header;
- phdr = elf_tdata (bfd)->phdr;
- load_base = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
- for (i = 0; i < ehdr->e_phnum; ++i)
- {
- switch (phdr[i].p_type)
- {
- case PT_LOAD:
- if ((unw_word_t) (ip - load_base - phdr[i].p_vaddr)
- < phdr[i].p_memsz)
- p_text = phdr + i;
- break;
- case PT_IA_64_UNWIND:
- p_unwind = phdr + i;
- break;
- default:
- break;
- }
- }
- if (!p_text || !p_unwind)
- return -UNW_ENOINFO;
-
- segbase = p_text->p_vaddr + load_base;
- if ((p_unwind->p_vaddr - p_text->p_vaddr) >= p_text->p_memsz)
- {
- int ok = 0;
- for (i = 0; i < ehdr->e_phnum; ++i)
- {
- if (phdr[i].p_type == PT_LOAD
- && (p_unwind->p_vaddr - phdr[i].p_vaddr) < phdr[i].p_memsz)
- {
- ok = 1;
-
- segbase = phdr[i].p_vaddr + load_base;
- }
- }
- if (!ok)
- return -UNW_ENOINFO;
- }
- dip->start_ip = p_text->p_vaddr + load_base;
- dip->end_ip = dip->start_ip + p_text->p_memsz;
- dip->gp = ia64_find_global_pointer (get_objfile_arch (objfile), ip);
- dip->format = UNW_INFO_FORMAT_REMOTE_TABLE;
- dip->u.rti.name_ptr = (unw_word_t) bfd_get_filename (bfd);
- dip->u.rti.segbase = segbase;
- dip->u.rti.table_len = p_unwind->p_memsz / sizeof (unw_word_t);
- dip->u.rti.table_data = p_unwind->p_vaddr + load_base;
- return 0;
- }
- static int
- ia64_find_proc_info_x (unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi,
- int need_unwind_info, void *arg)
- {
- struct obj_section *sec = find_pc_section (ip);
- unw_dyn_info_t di;
- int ret;
- void *buf = NULL;
- if (!sec)
- {
- XXX
- if (get_kernel_table (ip, &di) < 0)
- return -UNW_ENOINFO;
- if (gdbarch_debug >= 1)
- fprintf_unfiltered (gdb_stdlog, "ia64_find_proc_info_x: %s -> "
- "(name=`%s',segbase=%s,start=%s,end=%s,gp=%s,"
- "length=%s,data=%s)\n",
- hex_string (ip), (char *)di.u.ti.name_ptr,
- hex_string (di.u.ti.segbase),
- hex_string (di.start_ip), hex_string (di.end_ip),
- hex_string (di.gp),
- pulongest (di.u.ti.table_len),
- hex_string ((CORE_ADDR)di.u.ti.table_data));
- }
- else
- {
- ret = ia64_find_unwind_table (sec->objfile, ip, &di, &buf);
- if (ret < 0)
- return ret;
- if (gdbarch_debug >= 1)
- fprintf_unfiltered (gdb_stdlog, "ia64_find_proc_info_x: %s -> "
- "(name=`%s',segbase=%s,start=%s,end=%s,gp=%s,"
- "length=%s,data=%s)\n",
- hex_string (ip), (char *)di.u.rti.name_ptr,
- hex_string (di.u.rti.segbase),
- hex_string (di.start_ip), hex_string (di.end_ip),
- hex_string (di.gp),
- pulongest (di.u.rti.table_len),
- hex_string (di.u.rti.table_data));
- }
- ret = libunwind_search_unwind_table (&as, ip, &di, pi, need_unwind_info,
- arg);
-
- xfree (buf);
- return ret;
- }
- static void
- ia64_put_unwind_info (unw_addr_space_t as,
- unw_proc_info_t *pip, void *arg)
- {
-
- }
- static int
- ia64_get_dyn_info_list (unw_addr_space_t as,
- unw_word_t *dilap, void *arg)
- {
- struct obj_section *text_sec;
- struct objfile *objfile;
- unw_word_t ip, addr;
- unw_dyn_info_t di;
- int ret;
- if (!libunwind_is_initialized ())
- return -UNW_ENOINFO;
- for (objfile = object_files; objfile; objfile = objfile->next)
- {
- void *buf = NULL;
- text_sec = objfile->sections + SECT_OFF_TEXT (objfile);
- ip = obj_section_addr (text_sec);
- ret = ia64_find_unwind_table (objfile, ip, &di, &buf);
- if (ret >= 0)
- {
- addr = libunwind_find_dyn_list (as, &di, arg);
-
- xfree (buf);
- if (addr)
- {
- if (gdbarch_debug >= 1)
- fprintf_unfiltered (gdb_stdlog,
- "dynamic unwind table in objfile %s "
- "at %s (gp=%s)\n",
- bfd_get_filename (objfile->obfd),
- hex_string (addr), hex_string (di.gp));
- *dilap = addr;
- return 0;
- }
- }
- }
- return -UNW_ENOINFO;
- }
- static void
- ia64_libunwind_frame_this_id (struct frame_info *this_frame, void **this_cache,
- struct frame_id *this_id)
- {
- struct gdbarch *gdbarch = get_frame_arch (this_frame);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- struct frame_id id = outer_frame_id;
- gdb_byte buf[8];
- CORE_ADDR bsp;
- libunwind_frame_this_id (this_frame, this_cache, &id);
- if (frame_id_eq (id, outer_frame_id))
- {
- (*this_id) = outer_frame_id;
- return;
- }
-
- get_frame_register (this_frame, IA64_BSP_REGNUM, buf);
- bsp = extract_unsigned_integer (buf, 8, byte_order);
- (*this_id) = frame_id_build_special (id.stack_addr, id.code_addr, bsp);
- if (gdbarch_debug >= 1)
- fprintf_unfiltered (gdb_stdlog,
- "libunwind frame id: code %s, stack %s, "
- "special %s, this_frame %s\n",
- paddress (gdbarch, id.code_addr),
- paddress (gdbarch, id.stack_addr),
- paddress (gdbarch, bsp),
- host_address_to_string (this_frame));
- }
- static struct value *
- ia64_libunwind_frame_prev_register (struct frame_info *this_frame,
- void **this_cache, int regnum)
- {
- int reg = regnum;
- struct gdbarch *gdbarch = get_frame_arch (this_frame);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- struct value *val;
- if (VP0_REGNUM <= regnum && regnum <= VP63_REGNUM)
- reg = IA64_PR_REGNUM;
- else if (IA64_NAT0_REGNUM <= regnum && regnum <= IA64_NAT127_REGNUM)
- reg = IA64_UNAT_REGNUM;
-
- val = libunwind_frame_prev_register (this_frame, this_cache, reg);
- if (VP0_REGNUM <= regnum && regnum <= VP63_REGNUM)
- {
- ULONGEST prN_val;
- if (VP16_REGNUM <= regnum && regnum <= VP63_REGNUM)
- {
- int rrb_pr = 0;
- ULONGEST cfm;
- gdb_byte buf[MAX_REGISTER_SIZE];
-
- get_frame_register (this_frame, IA64_CFM_REGNUM, buf);
- cfm = extract_unsigned_integer (buf, 8, byte_order);
- rrb_pr = (cfm >> 32) & 0x3f;
-
- regnum = VP16_REGNUM + ((regnum - VP16_REGNUM) + rrb_pr) % 48;
- }
- prN_val = extract_bit_field (value_contents_all (val),
- regnum - VP0_REGNUM, 1);
- return frame_unwind_got_constant (this_frame, regnum, prN_val);
- }
- else if (IA64_NAT0_REGNUM <= regnum && regnum <= IA64_NAT127_REGNUM)
- {
- ULONGEST unatN_val;
- unatN_val = extract_bit_field (value_contents_all (val),
- regnum - IA64_NAT0_REGNUM, 1);
- return frame_unwind_got_constant (this_frame, regnum, unatN_val);
- }
- else if (regnum == IA64_BSP_REGNUM)
- {
- struct value *cfm_val;
- CORE_ADDR prev_bsp, prev_cfm;
-
- prev_bsp = extract_unsigned_integer (value_contents_all (val),
- 8, byte_order);
- cfm_val = libunwind_frame_prev_register (this_frame, this_cache,
- IA64_CFM_REGNUM);
- prev_cfm = extract_unsigned_integer (value_contents_all (cfm_val),
- 8, byte_order);
- prev_bsp = rse_address_add (prev_bsp, (prev_cfm & 0x7f));
- return frame_unwind_got_constant (this_frame, regnum, prev_bsp);
- }
- else
- return val;
- }
- static int
- ia64_libunwind_frame_sniffer (const struct frame_unwind *self,
- struct frame_info *this_frame,
- void **this_cache)
- {
- if (libunwind_is_initialized ()
- && libunwind_frame_sniffer (self, this_frame, this_cache))
- return 1;
- return 0;
- }
- static const struct frame_unwind ia64_libunwind_frame_unwind =
- {
- NORMAL_FRAME,
- default_frame_unwind_stop_reason,
- ia64_libunwind_frame_this_id,
- ia64_libunwind_frame_prev_register,
- NULL,
- ia64_libunwind_frame_sniffer,
- libunwind_frame_dealloc_cache
- };
- static void
- ia64_libunwind_sigtramp_frame_this_id (struct frame_info *this_frame,
- void **this_cache,
- struct frame_id *this_id)
- {
- struct gdbarch *gdbarch = get_frame_arch (this_frame);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- gdb_byte buf[8];
- CORE_ADDR bsp;
- struct frame_id id = outer_frame_id;
- CORE_ADDR prev_ip;
- libunwind_frame_this_id (this_frame, this_cache, &id);
- if (frame_id_eq (id, outer_frame_id))
- {
- (*this_id) = outer_frame_id;
- return;
- }
-
- get_frame_register (this_frame, IA64_BSP_REGNUM, buf);
- bsp = extract_unsigned_integer (buf, 8, byte_order);
-
- (*this_id) = frame_id_build_special (id.stack_addr, id.code_addr, bsp);
- if (gdbarch_debug >= 1)
- fprintf_unfiltered (gdb_stdlog,
- "libunwind sigtramp frame id: code %s, "
- "stack %s, special %s, this_frame %s\n",
- paddress (gdbarch, id.code_addr),
- paddress (gdbarch, id.stack_addr),
- paddress (gdbarch, bsp),
- host_address_to_string (this_frame));
- }
- static struct value *
- ia64_libunwind_sigtramp_frame_prev_register (struct frame_info *this_frame,
- void **this_cache, int regnum)
- {
- struct gdbarch *gdbarch = get_frame_arch (this_frame);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- struct value *prev_ip_val;
- CORE_ADDR prev_ip;
-
- prev_ip_val = libunwind_frame_prev_register (this_frame, this_cache,
- IA64_IP_REGNUM);
- prev_ip = extract_unsigned_integer (value_contents_all (prev_ip_val),
- 8, byte_order);
- if (prev_ip == 0)
- {
- void *tmp_cache = NULL;
- return ia64_sigtramp_frame_prev_register (this_frame, &tmp_cache,
- regnum);
- }
- else
- return ia64_libunwind_frame_prev_register (this_frame, this_cache, regnum);
- }
- static int
- ia64_libunwind_sigtramp_frame_sniffer (const struct frame_unwind *self,
- struct frame_info *this_frame,
- void **this_cache)
- {
- if (libunwind_is_initialized ())
- {
- if (libunwind_sigtramp_frame_sniffer (self, this_frame, this_cache))
- return 1;
- return 0;
- }
- else
- return ia64_sigtramp_frame_sniffer (self, this_frame, this_cache);
- }
- static const struct frame_unwind ia64_libunwind_sigtramp_frame_unwind =
- {
- SIGTRAMP_FRAME,
- default_frame_unwind_stop_reason,
- ia64_libunwind_sigtramp_frame_this_id,
- ia64_libunwind_sigtramp_frame_prev_register,
- NULL,
- ia64_libunwind_sigtramp_frame_sniffer
- };
- unw_accessors_t ia64_unw_accessors =
- {
- ia64_find_proc_info_x,
- ia64_put_unwind_info,
- ia64_get_dyn_info_list,
- ia64_access_mem,
- ia64_access_reg,
- ia64_access_fpreg,
-
-
- };
- unw_accessors_t ia64_unw_rse_accessors =
- {
- ia64_find_proc_info_x,
- ia64_put_unwind_info,
- ia64_get_dyn_info_list,
- ia64_access_mem,
- ia64_access_rse_reg,
- ia64_access_rse_fpreg,
-
-
- };
- struct libunwind_descr ia64_libunwind_descr =
- {
- ia64_gdb2uw_regnum,
- ia64_uw2gdb_regnum,
- ia64_is_fpreg,
- &ia64_unw_accessors,
- &ia64_unw_rse_accessors,
- };
- #endif
- static int
- ia64_use_struct_convention (struct type *type)
- {
- struct type *float_elt_type;
-
- if (!(TYPE_CODE (type) == TYPE_CODE_STRUCT
- || TYPE_CODE (type) == TYPE_CODE_UNION
- || TYPE_CODE (type) == TYPE_CODE_ARRAY))
- return 0;
-
- float_elt_type = is_float_or_hfa_type (type);
- if (float_elt_type != NULL
- && TYPE_LENGTH (type) / TYPE_LENGTH (float_elt_type) <= 8)
- return 0;
-
- return TYPE_LENGTH (type) > 32;
- }
- static int
- ia64_struct_type_p (const struct type *type)
- {
- return (TYPE_CODE (type) == TYPE_CODE_STRUCT
- || TYPE_CODE (type) == TYPE_CODE_UNION);
- }
- static void
- ia64_extract_return_value (struct type *type, struct regcache *regcache,
- gdb_byte *valbuf)
- {
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
- struct type *float_elt_type;
- float_elt_type = is_float_or_hfa_type (type);
- if (float_elt_type != NULL)
- {
- gdb_byte from[MAX_REGISTER_SIZE];
- int offset = 0;
- int regnum = IA64_FR8_REGNUM;
- int n = TYPE_LENGTH (type) / TYPE_LENGTH (float_elt_type);
- while (n-- > 0)
- {
- regcache_cooked_read (regcache, regnum, from);
- convert_typed_floating (from, ia64_ext_type (gdbarch),
- (char *)valbuf + offset, float_elt_type);
- offset += TYPE_LENGTH (float_elt_type);
- regnum++;
- }
- }
- else if (!ia64_struct_type_p (type) && TYPE_LENGTH (type) < 8)
- {
-
-
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- ULONGEST val;
- regcache_cooked_read_unsigned (regcache, IA64_GR8_REGNUM, &val);
- store_unsigned_integer (valbuf, TYPE_LENGTH (type), byte_order, val);
- }
- else
- {
- ULONGEST val;
- int offset = 0;
- int regnum = IA64_GR8_REGNUM;
- int reglen = TYPE_LENGTH (register_type (gdbarch, IA64_GR8_REGNUM));
- int n = TYPE_LENGTH (type) / reglen;
- int m = TYPE_LENGTH (type) % reglen;
- while (n-- > 0)
- {
- ULONGEST val;
- regcache_cooked_read_unsigned (regcache, regnum, &val);
- memcpy ((char *)valbuf + offset, &val, reglen);
- offset += reglen;
- regnum++;
- }
- if (m)
- {
- regcache_cooked_read_unsigned (regcache, regnum, &val);
- memcpy ((char *)valbuf + offset, &val, m);
- }
- }
- }
- static void
- ia64_store_return_value (struct type *type, struct regcache *regcache,
- const gdb_byte *valbuf)
- {
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
- struct type *float_elt_type;
- float_elt_type = is_float_or_hfa_type (type);
- if (float_elt_type != NULL)
- {
- gdb_byte to[MAX_REGISTER_SIZE];
- int offset = 0;
- int regnum = IA64_FR8_REGNUM;
- int n = TYPE_LENGTH (type) / TYPE_LENGTH (float_elt_type);
- while (n-- > 0)
- {
- convert_typed_floating ((char *)valbuf + offset, float_elt_type,
- to, ia64_ext_type (gdbarch));
- regcache_cooked_write (regcache, regnum, to);
- offset += TYPE_LENGTH (float_elt_type);
- regnum++;
- }
- }
- else
- {
- ULONGEST val;
- int offset = 0;
- int regnum = IA64_GR8_REGNUM;
- int reglen = TYPE_LENGTH (register_type (gdbarch, IA64_GR8_REGNUM));
- int n = TYPE_LENGTH (type) / reglen;
- int m = TYPE_LENGTH (type) % reglen;
- while (n-- > 0)
- {
- ULONGEST val;
- memcpy (&val, (char *)valbuf + offset, reglen);
- regcache_cooked_write_unsigned (regcache, regnum, val);
- offset += reglen;
- regnum++;
- }
- if (m)
- {
- memcpy (&val, (char *)valbuf + offset, m);
- regcache_cooked_write_unsigned (regcache, regnum, val);
- }
- }
- }
- static enum return_value_convention
- ia64_return_value (struct gdbarch *gdbarch, struct value *function,
- struct type *valtype, struct regcache *regcache,
- gdb_byte *readbuf, const gdb_byte *writebuf)
- {
- int struct_return = ia64_use_struct_convention (valtype);
- if (writebuf != NULL)
- {
- gdb_assert (!struct_return);
- ia64_store_return_value (valtype, regcache, writebuf);
- }
- if (readbuf != NULL)
- {
- gdb_assert (!struct_return);
- ia64_extract_return_value (valtype, regcache, readbuf);
- }
- if (struct_return)
- return RETURN_VALUE_STRUCT_CONVENTION;
- else
- return RETURN_VALUE_REGISTER_CONVENTION;
- }
- static int
- is_float_or_hfa_type_recurse (struct type *t, struct type **etp)
- {
- switch (TYPE_CODE (t))
- {
- case TYPE_CODE_FLT:
- if (*etp)
- return TYPE_LENGTH (*etp) == TYPE_LENGTH (t);
- else
- {
- *etp = t;
- return 1;
- }
- break;
- case TYPE_CODE_ARRAY:
- return
- is_float_or_hfa_type_recurse (check_typedef (TYPE_TARGET_TYPE (t)),
- etp);
- break;
- case TYPE_CODE_STRUCT:
- {
- int i;
- for (i = 0; i < TYPE_NFIELDS (t); i++)
- if (!is_float_or_hfa_type_recurse
- (check_typedef (TYPE_FIELD_TYPE (t, i)), etp))
- return 0;
- return 1;
- }
- break;
- default:
- return 0;
- break;
- }
- }
- static struct type *
- is_float_or_hfa_type (struct type *t)
- {
- struct type *et = 0;
- return is_float_or_hfa_type_recurse (t, &et) ? et : 0;
- }
- static int
- slot_alignment_is_next_even (struct type *t)
- {
- switch (TYPE_CODE (t))
- {
- case TYPE_CODE_INT:
- case TYPE_CODE_FLT:
- if (TYPE_LENGTH (t) > 8)
- return 1;
- else
- return 0;
- case TYPE_CODE_ARRAY:
- return
- slot_alignment_is_next_even (check_typedef (TYPE_TARGET_TYPE (t)));
- case TYPE_CODE_STRUCT:
- {
- int i;
- for (i = 0; i < TYPE_NFIELDS (t); i++)
- if (slot_alignment_is_next_even
- (check_typedef (TYPE_FIELD_TYPE (t, i))))
- return 1;
- return 0;
- }
- default:
- return 0;
- }
- }
- static CORE_ADDR
- ia64_find_global_pointer_from_dynamic_section (struct gdbarch *gdbarch,
- CORE_ADDR faddr)
- {
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- struct obj_section *faddr_sect;
- faddr_sect = find_pc_section (faddr);
- if (faddr_sect != NULL)
- {
- struct obj_section *osect;
- ALL_OBJFILE_OSECTIONS (faddr_sect->objfile, osect)
- {
- if (strcmp (osect->the_bfd_section->name, ".dynamic") == 0)
- break;
- }
- if (osect < faddr_sect->objfile->sections_end)
- {
- CORE_ADDR addr, endaddr;
- addr = obj_section_addr (osect);
- endaddr = obj_section_endaddr (osect);
- while (addr < endaddr)
- {
- int status;
- LONGEST tag;
- gdb_byte buf[8];
- status = target_read_memory (addr, buf, sizeof (buf));
- if (status != 0)
- break;
- tag = extract_signed_integer (buf, sizeof (buf), byte_order);
- if (tag == DT_PLTGOT)
- {
- CORE_ADDR global_pointer;
- status = target_read_memory (addr + 8, buf, sizeof (buf));
- if (status != 0)
- break;
- global_pointer = extract_unsigned_integer (buf, sizeof (buf),
- byte_order);
-
- return global_pointer;
- }
- if (tag == DT_NULL)
- break;
- addr += 16;
- }
- }
- }
- return 0;
- }
- static CORE_ADDR
- ia64_find_global_pointer (struct gdbarch *gdbarch, CORE_ADDR faddr)
- {
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- CORE_ADDR addr = 0;
- if (tdep->find_global_pointer_from_solib)
- addr = tdep->find_global_pointer_from_solib (gdbarch, faddr);
- if (addr == 0)
- addr = ia64_find_global_pointer_from_dynamic_section (gdbarch, faddr);
- return addr;
- }
- static CORE_ADDR
- find_extant_func_descr (struct gdbarch *gdbarch, CORE_ADDR faddr)
- {
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- struct obj_section *faddr_sect;
-
- faddr_sect = find_pc_section (faddr);
- if (faddr_sect && strcmp (faddr_sect->the_bfd_section->name, ".opd") == 0)
- return faddr;
- if (faddr_sect != NULL)
- {
- struct obj_section *osect;
- ALL_OBJFILE_OSECTIONS (faddr_sect->objfile, osect)
- {
- if (strcmp (osect->the_bfd_section->name, ".opd") == 0)
- break;
- }
- if (osect < faddr_sect->objfile->sections_end)
- {
- CORE_ADDR addr, endaddr;
- addr = obj_section_addr (osect);
- endaddr = obj_section_endaddr (osect);
- while (addr < endaddr)
- {
- int status;
- LONGEST faddr2;
- gdb_byte buf[8];
- status = target_read_memory (addr, buf, sizeof (buf));
- if (status != 0)
- break;
- faddr2 = extract_signed_integer (buf, sizeof (buf), byte_order);
- if (faddr == faddr2)
- return addr;
- addr += 16;
- }
- }
- }
- return 0;
- }
- static CORE_ADDR
- find_func_descr (struct regcache *regcache, CORE_ADDR faddr, CORE_ADDR *fdaptr)
- {
- struct gdbarch *gdbarch = get_regcache_arch (regcache);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- CORE_ADDR fdesc;
- fdesc = find_extant_func_descr (gdbarch, faddr);
- if (fdesc == 0)
- {
- ULONGEST global_pointer;
- gdb_byte buf[16];
- fdesc = *fdaptr;
- *fdaptr += 16;
- global_pointer = ia64_find_global_pointer (gdbarch, faddr);
- if (global_pointer == 0)
- regcache_cooked_read_unsigned (regcache,
- IA64_GR1_REGNUM, &global_pointer);
- store_unsigned_integer (buf, 8, byte_order, faddr);
- store_unsigned_integer (buf + 8, 8, byte_order, global_pointer);
- write_memory (fdesc, buf, 16);
- }
- return fdesc;
- }
- static CORE_ADDR
- ia64_convert_from_func_ptr_addr (struct gdbarch *gdbarch, CORE_ADDR addr,
- struct target_ops *targ)
- {
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- struct obj_section *s;
- gdb_byte buf[8];
- s = find_pc_section (addr);
-
- if (s && strcmp (s->the_bfd_section->name, ".opd") == 0)
- return read_memory_unsigned_integer (addr, 8, byte_order);
-
- if (s && (s->the_bfd_section->flags & SEC_CODE) == 0
- && target_read_memory (addr, buf, 8) == 0)
- {
- CORE_ADDR pc = extract_unsigned_integer (buf, 8, byte_order);
- struct obj_section *pc_section = find_pc_section (pc);
- if (pc_section && (pc_section->the_bfd_section->flags & SEC_CODE))
- return pc;
- }
-
- if (s)
- {
- struct bound_minimal_symbol minsym;
- minsym = lookup_minimal_symbol_by_pc (addr);
- if (minsym.minsym
- && is_vtable_name (MSYMBOL_LINKAGE_NAME (minsym.minsym)))
- return read_memory_unsigned_integer (addr, 8, byte_order);
- }
- return addr;
- }
- static CORE_ADDR
- ia64_frame_align (struct gdbarch *gdbarch, CORE_ADDR sp)
- {
- return sp & ~0xfLL;
- }
- static void
- ia64_allocate_new_rse_frame (struct regcache *regcache, ULONGEST bsp, int sof)
- {
- ULONGEST cfm, pfs, new_bsp;
- regcache_cooked_read_unsigned (regcache, IA64_CFM_REGNUM, &cfm);
- new_bsp = rse_address_add (bsp, sof);
- regcache_cooked_write_unsigned (regcache, IA64_BSP_REGNUM, new_bsp);
- regcache_cooked_read_unsigned (regcache, IA64_PFS_REGNUM, &pfs);
- pfs &= 0xc000000000000000LL;
- pfs |= (cfm & 0xffffffffffffLL);
- regcache_cooked_write_unsigned (regcache, IA64_PFS_REGNUM, pfs);
- cfm &= 0xc000000000000000LL;
- cfm |= sof;
- regcache_cooked_write_unsigned (regcache, IA64_CFM_REGNUM, cfm);
- }
- static void
- ia64_store_argument_in_slot (struct regcache *regcache, CORE_ADDR bsp,
- int slotnum, gdb_byte *buf)
- {
- write_memory (rse_address_add (bsp, slotnum), buf, 8);
- }
- static void
- ia64_set_function_addr (struct regcache *regcache, CORE_ADDR func_addr)
- {
-
- }
- static CORE_ADDR
- ia64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
- struct regcache *regcache, CORE_ADDR bp_addr,
- int nargs, struct value **args, CORE_ADDR sp,
- int struct_return, CORE_ADDR struct_addr)
- {
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- int argno;
- struct value *arg;
- struct type *type;
- int len, argoffset;
- int nslots, rseslots, memslots, slotnum, nfuncargs;
- int floatreg;
- ULONGEST bsp;
- CORE_ADDR funcdescaddr, pc, global_pointer;
- CORE_ADDR func_addr = find_function_addr (function, NULL);
- nslots = 0;
- nfuncargs = 0;
-
- for (argno = 0; argno < nargs; argno++)
- {
- arg = args[argno];
- type = check_typedef (value_type (arg));
- len = TYPE_LENGTH (type);
- if ((nslots & 1) && slot_alignment_is_next_even (type))
- nslots++;
- if (TYPE_CODE (type) == TYPE_CODE_FUNC)
- nfuncargs++;
- nslots += (len + 7) / 8;
- }
-
- rseslots = (nslots > 8) ? 8 : nslots;
- memslots = nslots - rseslots;
-
- regcache_cooked_read_unsigned (regcache, IA64_BSP_REGNUM, &bsp);
- tdep->infcall_ops.allocate_new_rse_frame (regcache, bsp, rseslots);
-
- funcdescaddr = sp - nfuncargs * 16;
- funcdescaddr &= ~0xfLL;
-
- sp = sp - 16 - (memslots + nfuncargs) * 8;
- sp &= ~0xfLL;
-
- slotnum = 0;
- floatreg = IA64_FR8_REGNUM;
- for (argno = 0; argno < nargs; argno++)
- {
- struct type *float_elt_type;
- arg = args[argno];
- type = check_typedef (value_type (arg));
- len = TYPE_LENGTH (type);
-
- if (len == 8
- && TYPE_CODE (type) == TYPE_CODE_PTR
- && TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_FUNC)
- {
- gdb_byte val_buf[8];
- ULONGEST faddr = extract_unsigned_integer (value_contents (arg),
- 8, byte_order);
- store_unsigned_integer (val_buf, 8, byte_order,
- find_func_descr (regcache, faddr,
- &funcdescaddr));
- if (slotnum < rseslots)
- tdep->infcall_ops.store_argument_in_slot (regcache, bsp,
- slotnum, val_buf);
- else
- write_memory (sp + 16 + 8 * (slotnum - rseslots), val_buf, 8);
- slotnum++;
- continue;
- }
-
-
- if ((slotnum & 1) && slot_alignment_is_next_even (type))
- slotnum++;
- argoffset = 0;
- while (len > 0)
- {
- gdb_byte val_buf[8];
- memset (val_buf, 0, 8);
- if (!ia64_struct_type_p (type) && len < 8)
- {
-
- store_unsigned_integer
- (val_buf, 8, byte_order,
- extract_unsigned_integer (value_contents (arg), len,
- byte_order));
- }
- else
- {
-
- memcpy (val_buf, value_contents (arg) + argoffset,
- (len > 8) ? 8 : len);
- }
- if (slotnum < rseslots)
- tdep->infcall_ops.store_argument_in_slot (regcache, bsp,
- slotnum, val_buf);
- else
- write_memory (sp + 16 + 8 * (slotnum - rseslots), val_buf, 8);
- argoffset += 8;
- len -= 8;
- slotnum++;
- }
-
- float_elt_type = is_float_or_hfa_type (type);
- if (float_elt_type != NULL)
- {
- argoffset = 0;
- len = TYPE_LENGTH (type);
- while (len > 0 && floatreg < IA64_FR16_REGNUM)
- {
- char to[MAX_REGISTER_SIZE];
- convert_typed_floating (value_contents (arg) + argoffset,
- float_elt_type, to,
- ia64_ext_type (gdbarch));
- regcache_cooked_write (regcache, floatreg, (void *)to);
- floatreg++;
- argoffset += TYPE_LENGTH (float_elt_type);
- len -= TYPE_LENGTH (float_elt_type);
- }
- }
- }
-
- if (struct_return)
- {
- regcache_cooked_write_unsigned (regcache, IA64_GR8_REGNUM,
- (ULONGEST) struct_addr);
- }
- global_pointer = ia64_find_global_pointer (gdbarch, func_addr);
- if (global_pointer != 0)
- regcache_cooked_write_unsigned (regcache, IA64_GR1_REGNUM, global_pointer);
-
- regcache_cooked_write_unsigned (regcache, IA64_BR0_REGNUM, bp_addr);
- regcache_cooked_write_unsigned (regcache, sp_regnum, sp);
- tdep->infcall_ops.set_function_addr (regcache, func_addr);
- return sp;
- }
- static const struct ia64_infcall_ops ia64_infcall_ops =
- {
- ia64_allocate_new_rse_frame,
- ia64_store_argument_in_slot,
- ia64_set_function_addr
- };
- static struct frame_id
- ia64_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
- {
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- gdb_byte buf[8];
- CORE_ADDR sp, bsp;
- get_frame_register (this_frame, sp_regnum, buf);
- sp = extract_unsigned_integer (buf, 8, byte_order);
- get_frame_register (this_frame, IA64_BSP_REGNUM, buf);
- bsp = extract_unsigned_integer (buf, 8, byte_order);
- if (gdbarch_debug >= 1)
- fprintf_unfiltered (gdb_stdlog,
- "dummy frame id: code %s, stack %s, special %s\n",
- paddress (gdbarch, get_frame_pc (this_frame)),
- paddress (gdbarch, sp), paddress (gdbarch, bsp));
- return frame_id_build_special (sp, get_frame_pc (this_frame), bsp);
- }
- static CORE_ADDR
- ia64_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
- {
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- gdb_byte buf[8];
- CORE_ADDR ip, psr, pc;
- frame_unwind_register (next_frame, IA64_IP_REGNUM, buf);
- ip = extract_unsigned_integer (buf, 8, byte_order);
- frame_unwind_register (next_frame, IA64_PSR_REGNUM, buf);
- psr = extract_unsigned_integer (buf, 8, byte_order);
- pc = (ip & ~0xf) | ((psr >> 41) & 3);
- return pc;
- }
- static int
- ia64_print_insn (bfd_vma memaddr, struct disassemble_info *info)
- {
- info->bytes_per_line = SLOT_MULTIPLIER;
- return print_insn_ia64 (memaddr, info);
- }
- static int
- ia64_size_of_register_frame (struct frame_info *this_frame, ULONGEST cfm)
- {
- return (cfm & 0x7f);
- }
- static struct gdbarch *
- ia64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
- {
- struct gdbarch *gdbarch;
- struct gdbarch_tdep *tdep;
-
- arches = gdbarch_list_lookup_by_info (arches, &info);
- if (arches != NULL)
- return arches->gdbarch;
- tdep = xzalloc (sizeof (struct gdbarch_tdep));
- gdbarch = gdbarch_alloc (&info, tdep);
- tdep->size_of_register_frame = ia64_size_of_register_frame;
-
- set_gdbarch_long_double_format (gdbarch, floatformats_i387_ext);
- set_gdbarch_short_bit (gdbarch, 16);
- set_gdbarch_int_bit (gdbarch, 32);
- set_gdbarch_long_bit (gdbarch, 64);
- set_gdbarch_long_long_bit (gdbarch, 64);
- set_gdbarch_float_bit (gdbarch, 32);
- set_gdbarch_double_bit (gdbarch, 64);
- set_gdbarch_long_double_bit (gdbarch, 128);
- set_gdbarch_ptr_bit (gdbarch, 64);
- set_gdbarch_num_regs (gdbarch, NUM_IA64_RAW_REGS);
- set_gdbarch_num_pseudo_regs (gdbarch,
- LAST_PSEUDO_REGNUM - FIRST_PSEUDO_REGNUM);
- set_gdbarch_sp_regnum (gdbarch, sp_regnum);
- set_gdbarch_fp0_regnum (gdbarch, IA64_FR0_REGNUM);
- set_gdbarch_register_name (gdbarch, ia64_register_name);
- set_gdbarch_register_type (gdbarch, ia64_register_type);
- set_gdbarch_pseudo_register_read (gdbarch, ia64_pseudo_register_read);
- set_gdbarch_pseudo_register_write (gdbarch, ia64_pseudo_register_write);
- set_gdbarch_dwarf2_reg_to_regnum (gdbarch, ia64_dwarf_reg_to_regnum);
- set_gdbarch_register_reggroup_p (gdbarch, ia64_register_reggroup_p);
- set_gdbarch_convert_register_p (gdbarch, ia64_convert_register_p);
- set_gdbarch_register_to_value (gdbarch, ia64_register_to_value);
- set_gdbarch_value_to_register (gdbarch, ia64_value_to_register);
- set_gdbarch_skip_prologue (gdbarch, ia64_skip_prologue);
- set_gdbarch_return_value (gdbarch, ia64_return_value);
- set_gdbarch_memory_insert_breakpoint (gdbarch,
- ia64_memory_insert_breakpoint);
- set_gdbarch_memory_remove_breakpoint (gdbarch,
- ia64_memory_remove_breakpoint);
- set_gdbarch_breakpoint_from_pc (gdbarch, ia64_breakpoint_from_pc);
- set_gdbarch_read_pc (gdbarch, ia64_read_pc);
- set_gdbarch_write_pc (gdbarch, ia64_write_pc);
-
- set_gdbarch_push_dummy_call (gdbarch, ia64_push_dummy_call);
- tdep->infcall_ops = ia64_infcall_ops;
- set_gdbarch_frame_align (gdbarch, ia64_frame_align);
- set_gdbarch_dummy_id (gdbarch, ia64_dummy_id);
- set_gdbarch_unwind_pc (gdbarch, ia64_unwind_pc);
- #ifdef HAVE_LIBUNWIND_IA64_H
- frame_unwind_append_unwinder (gdbarch,
- &ia64_libunwind_sigtramp_frame_unwind);
- frame_unwind_append_unwinder (gdbarch, &ia64_libunwind_frame_unwind);
- frame_unwind_append_unwinder (gdbarch, &ia64_sigtramp_frame_unwind);
- libunwind_frame_set_descr (gdbarch, &ia64_libunwind_descr);
- #else
- frame_unwind_append_unwinder (gdbarch, &ia64_sigtramp_frame_unwind);
- #endif
- frame_unwind_append_unwinder (gdbarch, &ia64_frame_unwind);
- frame_base_set_default (gdbarch, &ia64_frame_base);
-
- set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
- set_gdbarch_print_insn (gdbarch, ia64_print_insn);
- set_gdbarch_convert_from_func_ptr_addr (gdbarch,
- ia64_convert_from_func_ptr_addr);
-
- set_gdbarch_vtable_function_descriptors (gdbarch, 1);
-
- gdbarch_init_osabi (info, gdbarch);
- return gdbarch;
- }
- extern initialize_file_ftype _initialize_ia64_tdep;
- void
- _initialize_ia64_tdep (void)
- {
- gdbarch_register (bfd_arch_ia64, ia64_gdbarch_init, NULL);
- }