• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

GNU Binutils with patches for OS216


Commit MetaInfo

Revisionfb20ccaae3ab3e6964b95e8e077d11b31c8f8d8c (tree)
Time2006-04-02 11:35:32
AuthorDaniel Jacobowitz <drow@fals...>
CommiterDaniel Jacobowitz

Log Message

Add support for VFP DWARF information and VFP single-precision
pseudo-registers.

Change Summary

Incremental Difference

--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -1806,7 +1806,7 @@ arm-tdep.o: arm-tdep.c $(defs_h) $(frame_h) $(inferior_h) $(gdbcmd_h) \
18061806 $(frame_unwind_h) $(frame_base_h) $(trad_frame_h) $(arm_tdep_h) \
18071807 $(gdb_sim_arm_h) $(elf_bfd_h) $(coff_internal_h) $(elf_arm_h) \
18081808 $(gdb_assert_h) $(bfd_in2_h) $(libcoff_h) $(objfiles_h) \
1809- $(dwarf2_frame_h) $(available_h)
1809+ $(dwarf2_frame_h) $(available_h) $(user_regs_h)
18101810 auxv.o: auxv.c $(defs_h) $(target_h) $(gdbtypes_h) $(command_h) \
18111811 $(inferior_h) $(valprint_h) $(gdb_assert_h) $(auxv_h) \
18121812 $(elf_common_h)
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -41,6 +41,7 @@
4141 #include "objfiles.h"
4242 #include "dwarf2-frame.h"
4343 #include "available.h"
44+#include "user-regs.h"
4445
4546 #include "arm-tdep.h"
4647 #include "gdb/sim-arm.h"
@@ -1352,6 +1353,10 @@ arm_register_type (struct gdbarch *gdbarch, int regnum)
13521353 if (avail_type)
13531354 return avail_type;
13541355
1356+ if (gdbarch_tdep (current_gdbarch)->have_vfp_pseudos
1357+ && regnum >= NUM_REGS && regnum < NUM_REGS + 32)
1358+ return builtin_type_float;
1359+
13551360 if (regnum >= ARM_F0_REGNUM && regnum < ARM_F0_REGNUM + NUM_FREGS)
13561361 {
13571362 if (!gdbarch_tdep (gdbarch)->have_fpa_registers)
@@ -1366,6 +1371,56 @@ arm_register_type (struct gdbarch *gdbarch, int regnum)
13661371 return builtin_type_int32;
13671372 }
13681373
1374+/* Map DWARF register numbers onto internal GDB register numbers. */
1375+static int
1376+arm_dwarf_reg_to_regnum (int reg)
1377+{
1378+ /* Core integer regs. */
1379+ if (reg >= 0 && reg <= 15)
1380+ return reg;
1381+
1382+ /* Legacy FPA encoding. These were once used in a way which
1383+ overlapped with VFP register numbering, so their use is
1384+ discouraged, but GDB doesn't support the ARM toolchain
1385+ which did that. */
1386+ if (reg >= 16 && reg <= 23)
1387+ return ARM_F0_REGNUM + reg - 16;
1388+
1389+ /* New assignments for the FPA registers. */
1390+ if (reg >= 96 && reg <= 103)
1391+ return ARM_F0_REGNUM + reg - 96;
1392+
1393+ /* VFP v2 registers. A double precision value is actually
1394+ in d1 rather than s2, but the ABI only defines numbering
1395+ for the single precision registers. This will "just work"
1396+ in GDB for little endian targets (we'll read eight bytes,
1397+ starting in s0 and then progressing to s1), but will be
1398+ reversed on big endian targets with VFP. This won't
1399+ be a problem for the new Neon quad registers; you're supposed
1400+ to use DW_OP_piece for those. */
1401+ if (reg >= 64 && reg <= 95)
1402+ {
1403+ char name_buf[4];
1404+
1405+ sprintf (name_buf, "s%d", reg - 64);
1406+ return user_reg_map_name_to_regnum (current_gdbarch, name_buf,
1407+ strlen (name_buf));
1408+ }
1409+
1410+ /* VFP v3 / Neon registers. This range is also used for VFP v2
1411+ registers, except that it now describes d0 instead of s0. */
1412+ if (reg >= 256 && reg <= 287)
1413+ {
1414+ char name_buf[4];
1415+
1416+ sprintf (name_buf, "d%d", reg - 256);
1417+ return user_reg_map_name_to_regnum (current_gdbarch, name_buf,
1418+ strlen (name_buf));
1419+ }
1420+
1421+ return -1;
1422+}
1423+
13691424 /* Map GDB internal REGNUM onto the Arm simulator register numbers. */
13701425 static int
13711426 arm_register_sim_regno (int regnum)
@@ -2475,6 +2530,19 @@ arm_register_name (int i)
24752530 return "";
24762531 }
24772532
2533+ if (gdbarch_tdep (current_gdbarch)->have_vfp_pseudos
2534+ && i >= NUM_REGS && i < NUM_REGS + 32)
2535+ {
2536+ static const char *const vfp_pseudo_names[] = {
2537+ "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
2538+ "s8", "s9", "s10", "s11", "s12", "s13", "s14", "s15",
2539+ "s16", "s17", "s18", "s19", "s20", "s21", "s22", "s23",
2540+ "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
2541+ };
2542+
2543+ return vfp_pseudo_names[i - NUM_REGS];
2544+ }
2545+
24782546 /* Check for target-supplied register numbers. */
24792547 return available_register_name (current_gdbarch, i);
24802548 }
@@ -2565,6 +2633,57 @@ arm_write_pc (CORE_ADDR pc, ptid_t ptid)
25652633 write_register_pid (ARM_PS_REGNUM, val & ~(CORE_ADDR) 0x20, ptid);
25662634 }
25672635 }
2636+
2637+static void
2638+arm_pseudo_vfp_read (struct gdbarch *gdbarch, struct regcache *regcache,
2639+ int regnum, gdb_byte *buf)
2640+{
2641+ char name_buf[4];
2642+ gdb_byte reg_buf[8];
2643+ int offset, double_regnum;
2644+
2645+ gdb_assert (regnum >= NUM_REGS && regnum <= NUM_REGS + 32);
2646+ regnum -= NUM_REGS;
2647+
2648+ /* s0 is always the least significant half of d0. */
2649+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
2650+ offset = (regnum & 1) ? 0 : 4;
2651+ else
2652+ offset = (regnum & 1) ? 4 : 0;
2653+
2654+ sprintf (name_buf, "d%d", regnum >> 1);
2655+ double_regnum = user_reg_map_name_to_regnum (gdbarch, name_buf,
2656+ strlen (name_buf));
2657+
2658+ regcache_raw_read (regcache, double_regnum, reg_buf);
2659+ memcpy (buf, reg_buf + offset, 4);
2660+}
2661+
2662+static void
2663+arm_pseudo_vfp_write (struct gdbarch *gdbarch, struct regcache *regcache,
2664+ int regnum, const gdb_byte *buf)
2665+{
2666+ char name_buf[4];
2667+ gdb_byte reg_buf[8];
2668+ int offset, double_regnum;
2669+
2670+ gdb_assert (regnum >= NUM_REGS && regnum <= NUM_REGS + 32);
2671+ regnum -= NUM_REGS;
2672+
2673+ /* s0 is always the least significant half of d0. */
2674+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
2675+ offset = (regnum & 1) ? 0 : 4;
2676+ else
2677+ offset = (regnum & 1) ? 4 : 0;
2678+
2679+ sprintf (name_buf, "d%d", regnum >> 1);
2680+ double_regnum = user_reg_map_name_to_regnum (gdbarch, name_buf,
2681+ strlen (name_buf));
2682+
2683+ regcache_raw_read (regcache, double_regnum, reg_buf);
2684+ memcpy (reg_buf + offset, buf, 4);
2685+ regcache_raw_write (regcache, double_regnum, reg_buf);
2686+}
25682687
25692688 static enum gdb_osabi
25702689 arm_elf_osabi_sniffer (bfd *abfd)
@@ -2628,6 +2747,27 @@ arm_check_feature_set (struct gdbarch *gdbarch,
26282747 }
26292748 else
26302749 gdbarch_tdep (gdbarch)->have_fpa_registers = 0;
2750+
2751+ /* If we have a VFP unit, check whether the single precision registers
2752+ are present. If not, then we will synthesize them as pseudo
2753+ registers. */
2754+
2755+ if (available_find_named_feature (feature_set, "org.gnu.gdb.arm.vfp"))
2756+ {
2757+ if (available_find_named_register (feature_set, "d0", -1)
2758+ && !available_find_named_register (feature_set, "s0", -1))
2759+ {
2760+ /* NOTE: This is the only set of pseudo registers used by
2761+ the ARM target at the moment. If more are added, a
2762+ little more care in numbering will be needed. */
2763+
2764+ set_gdbarch_num_pseudo_regs (gdbarch, 32);
2765+ set_gdbarch_pseudo_register_read (gdbarch, arm_pseudo_vfp_read);
2766+ set_gdbarch_pseudo_register_write (gdbarch, arm_pseudo_vfp_write);
2767+ gdbarch_tdep (gdbarch)->have_vfp_pseudos = 1;
2768+ }
2769+ gdbarch_tdep (gdbarch)->have_vfp_registers = 1;
2770+ }
26312771 }
26322772
26332773
@@ -2843,6 +2983,8 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
28432983 set_gdbarch_print_float_info (gdbarch, arm_print_float_info);
28442984
28452985 /* Internal <-> external register number maps. */
2986+ set_gdbarch_dwarf_reg_to_regnum (gdbarch, arm_dwarf_reg_to_regnum);
2987+ set_gdbarch_dwarf2_reg_to_regnum (gdbarch, arm_dwarf_reg_to_regnum);
28462988 set_gdbarch_register_sim_regno (gdbarch, arm_register_sim_regno);
28472989
28482990 /* Integer registers are 4 bytes. */
--- a/gdb/arm-tdep.h
+++ b/gdb/arm-tdep.h
@@ -132,6 +132,9 @@ struct gdbarch_tdep
132132 enum arm_float_model fp_model; /* Floating point calling conventions. */
133133
134134 int have_fpa_registers; /* Does the target report the FPA registers? */
135+ int have_vfp_registers; /* Does the target report the VFP registers? */
136+ int have_vfp_pseudos; /* Are we synthesizing the single precision
137+ VFP registers? */
135138
136139 CORE_ADDR lowest_pc; /* Lowest address at which instructions
137140 will appear. */
--- a/gdb/available.c
+++ b/gdb/available.c
@@ -546,9 +546,10 @@ find_register (const struct gdb_feature_set *features, int regnum)
546546 return NULL;
547547 }
548548
549-/* Search FEATURES for a register with target-specified name NAME,
550- and set its GDB register number to REGNUM. Return 1 if the
551- register was found, and 0 if it was not. This function should
549+/* Search FEATURES for a register with target-specified name NAME, and
550+ set its GDB register number to REGNUM. Pass REGNUM == -1 if you do
551+ not need to fix a register number for this register. Return 1 if
552+ the register was found, and 0 if it was not. This function should
552553 only be used while initializing a gdbarch. */
553554
554555 int
--- a/gdb/available.h
+++ b/gdb/available.h
@@ -145,8 +145,8 @@ int features_same_p (const struct gdb_feature_set *,
145145 void record_available_features (struct gdbarch *,
146146 struct gdb_feature_set *);
147147
148-/* Find a register with the given name, and set its internal register
149- number. */
148+/* Find a register with the given name, and optionally set its
149+ internal register number. */
150150
151151 int available_find_named_register (struct gdb_feature_set *,
152152 const char *, int);
--- a/gdb/frame.c
+++ b/gdb/frame.c
@@ -395,16 +395,26 @@ frame_find_by_id (struct frame_id id)
395395 {
396396 struct frame_info *frame;
397397
398+#if 0
398399 /* ZERO denotes the null frame, let the caller decide what to do
399400 about it. Should it instead return get_current_frame()? */
400401 if (!frame_id_p (id))
401402 return NULL;
403+#endif
402404
403405 for (frame = get_current_frame ();
404406 frame != NULL;
405407 frame = get_prev_frame (frame))
406408 {
407409 struct frame_id this = get_frame_id (frame);
410+#if 1
411+ /* We use an invalid frame id to mean "could not unwind from
412+ here"! This hack fixes the "value being assigned to is
413+ no longer active" problem. This strongly suggests that
414+ we need to change the representation. */
415+ if (!frame_id_p (id) && !frame_id_p (this))
416+ return frame;
417+#endif
408418 if (frame_id_eq (id, this))
409419 /* An exact match. */
410420 return frame;