GNU Binutils with patches for OS216
Revision | 215c69dc9a7d8f868198b5523abcf41458fb6e4a (tree) |
---|---|
Time | 2018-02-21 20:20:03 |
Author | Yao Qi <yao.qi@lina...> |
Commiter | Yao Qi |
No longer create readonly regcache
Nowadays, we create a readonly regcache in get_return_value, and pass it
to gdbarch_return_value to get the return value. In theory, we can pass a
readable_regcache instance and get the return value, because we don't need
to modify the regcache. Unfortunately, gdbarch_return_value is designed
to multiplex regcache, according to READBUF and WRITEBUF.
In fact, gdbarch_return_value should be split to three functions, 1) only
return return_value_convention, 2) pass regcache_readonly and readbuf, 3)
pass regcache and writebuf. These changes are out of the scope of this
patch series, so I pass regcache to gdbarch_return_value even for read,
and trust each gdbarch backend doesn't modify regcache.
gdb:
2018-02-21 Yao Qi <yao.qi@linaro.org>
* infcmd.c (get_return_value): Let stop_regs point to
get_current_regcache.
* regcache.c (regcache::regcache): Remove.
(register_dump_reg_buffer): New class.
(regcache_print): Adjust.
* regcache.h (regcache): Remove constructors.
@@ -1,5 +1,14 @@ | ||
1 | 1 | 2018-02-21 Yao Qi <yao.qi@linaro.org> |
2 | 2 | |
3 | + * infcmd.c (get_return_value): Let stop_regs point to | |
4 | + get_current_regcache. | |
5 | + * regcache.c (regcache::regcache): Remove. | |
6 | + (register_dump_reg_buffer): New class. | |
7 | + (regcache_print): Adjust. | |
8 | + * regcache.h (regcache): Remove constructors. | |
9 | + | |
10 | +2018-02-21 Yao Qi <yao.qi@linaro.org> | |
11 | + | |
3 | 12 | * regcache.c (class register_dump): New class. |
4 | 13 | (register_dump_regcache, register_dump_none): New class. |
5 | 14 | (register_dump_remote, register_dump_groups): New class. |
@@ -1625,8 +1625,8 @@ advance_command (const char *arg, int from_tty) | ||
1625 | 1625 | struct value * |
1626 | 1626 | get_return_value (struct value *function, struct type *value_type) |
1627 | 1627 | { |
1628 | - regcache stop_regs (regcache::readonly, *get_current_regcache ()); | |
1629 | - struct gdbarch *gdbarch = stop_regs.arch (); | |
1628 | + regcache *stop_regs = get_current_regcache (); | |
1629 | + struct gdbarch *gdbarch = stop_regs->arch (); | |
1630 | 1630 | struct value *value; |
1631 | 1631 | |
1632 | 1632 | value_type = check_typedef (value_type); |
@@ -1646,7 +1646,7 @@ get_return_value (struct value *function, struct type *value_type) | ||
1646 | 1646 | case RETURN_VALUE_ABI_RETURNS_ADDRESS: |
1647 | 1647 | case RETURN_VALUE_ABI_PRESERVES_ADDRESS: |
1648 | 1648 | value = allocate_value (value_type); |
1649 | - gdbarch_return_value (gdbarch, function, value_type, &stop_regs, | |
1649 | + gdbarch_return_value (gdbarch, function, value_type, stop_regs, | |
1650 | 1650 | value_contents_raw (value), NULL); |
1651 | 1651 | break; |
1652 | 1652 | case RETURN_VALUE_STRUCT_CONVENTION: |
@@ -219,13 +219,6 @@ do_cooked_read (void *src, int regnum, gdb_byte *buf) | ||
219 | 219 | return regcache_cooked_read (regcache, regnum, buf); |
220 | 220 | } |
221 | 221 | |
222 | -regcache::regcache (readonly_t, const regcache &src) | |
223 | - : regcache (src.arch (), nullptr, true) | |
224 | -{ | |
225 | - gdb_assert (!src.m_readonly_p); | |
226 | - save (do_cooked_read, (void *) &src); | |
227 | -} | |
228 | - | |
229 | 222 | readonly_detached_regcache::readonly_detached_regcache (const regcache &src) |
230 | 223 | : readonly_detached_regcache (src.arch (), do_cooked_read, (void *) &src) |
231 | 224 | { |
@@ -1512,6 +1505,55 @@ private: | ||
1512 | 1505 | const bool m_dump_pseudo; |
1513 | 1506 | }; |
1514 | 1507 | |
1508 | +/* Dump from reg_buffer, used when there is no thread or | |
1509 | + registers. */ | |
1510 | + | |
1511 | +class register_dump_reg_buffer : public register_dump, reg_buffer | |
1512 | +{ | |
1513 | +public: | |
1514 | + register_dump_reg_buffer (gdbarch *gdbarch, bool dump_pseudo) | |
1515 | + : register_dump (gdbarch), reg_buffer (gdbarch, dump_pseudo) | |
1516 | + { | |
1517 | + } | |
1518 | + | |
1519 | +protected: | |
1520 | + void dump_reg (ui_file *file, int regnum) override | |
1521 | + { | |
1522 | + if (regnum < 0) | |
1523 | + { | |
1524 | + if (m_has_pseudo) | |
1525 | + fprintf_unfiltered (file, "Cooked value"); | |
1526 | + else | |
1527 | + fprintf_unfiltered (file, "Raw value"); | |
1528 | + } | |
1529 | + else | |
1530 | + { | |
1531 | + if (regnum < gdbarch_num_regs (m_gdbarch) || m_has_pseudo) | |
1532 | + { | |
1533 | + auto size = register_size (m_gdbarch, regnum); | |
1534 | + | |
1535 | + if (size == 0) | |
1536 | + return; | |
1537 | + | |
1538 | + auto status = get_register_status (regnum); | |
1539 | + | |
1540 | + gdb_assert (status != REG_VALID); | |
1541 | + | |
1542 | + if (status == REG_UNKNOWN) | |
1543 | + fprintf_unfiltered (file, "<invalid>"); | |
1544 | + else | |
1545 | + fprintf_unfiltered (file, "<unavailable>"); | |
1546 | + } | |
1547 | + else | |
1548 | + { | |
1549 | + /* Just print "<cooked>" for pseudo register when | |
1550 | + regcache_dump_raw. */ | |
1551 | + fprintf_unfiltered (file, "<cooked>"); | |
1552 | + } | |
1553 | + } | |
1554 | + } | |
1555 | +}; | |
1556 | + | |
1515 | 1557 | /* For "maint print registers". */ |
1516 | 1558 | |
1517 | 1559 | class register_dump_none : public register_dump |
@@ -1633,22 +1675,19 @@ regcache_print (const char *args, enum regcache_dump_what what_to_dump) | ||
1633 | 1675 | case regcache_dump_raw: |
1634 | 1676 | case regcache_dump_cooked: |
1635 | 1677 | { |
1636 | - regcache *reg; | |
1678 | + auto dump_pseudo = (what_to_dump == regcache_dump_cooked); | |
1637 | 1679 | |
1638 | 1680 | if (target_has_registers) |
1639 | - reg = get_current_regcache (); | |
1681 | + dump.reset (new register_dump_regcache (get_current_regcache (), | |
1682 | + dump_pseudo)); | |
1640 | 1683 | else |
1641 | 1684 | { |
1642 | 1685 | /* For the benefit of "maint print registers" & co when |
1643 | 1686 | debugging an executable, allow dumping a regcache even when |
1644 | 1687 | there is no thread selected / no registers. */ |
1645 | - reg = new regcache (target_gdbarch ()); | |
1646 | - regs.reset (reg); | |
1688 | + dump.reset (new register_dump_reg_buffer (target_gdbarch (), | |
1689 | + dump_pseudo)); | |
1647 | 1690 | } |
1648 | - | |
1649 | - auto dump_pseudo = (what_to_dump == regcache_dump_cooked); | |
1650 | - | |
1651 | - dump.reset (new register_dump_regcache (reg, dump_pseudo)); | |
1652 | 1691 | } |
1653 | 1692 | break; |
1654 | 1693 | } |
@@ -1937,7 +1976,7 @@ cooked_read_test (struct gdbarch *gdbarch) | ||
1937 | 1976 | mock_target.reset (); |
1938 | 1977 | } |
1939 | 1978 | |
1940 | - regcache readonly (regcache::readonly, readwrite); | |
1979 | + readonly_detached_regcache readonly (readwrite); | |
1941 | 1980 | |
1942 | 1981 | /* GDB may go to target layer to fetch all registers and memory for |
1943 | 1982 | readonly regcache. */ |
@@ -307,16 +307,6 @@ class readonly_detached_regcache; | ||
307 | 307 | class regcache : public detached_regcache |
308 | 308 | { |
309 | 309 | public: |
310 | - regcache (gdbarch *gdbarch) | |
311 | - : regcache (gdbarch, nullptr, true) | |
312 | - {} | |
313 | - | |
314 | - struct readonly_t {}; | |
315 | - static constexpr readonly_t readonly {}; | |
316 | - | |
317 | - /* Create a readonly regcache from a non-readonly regcache. */ | |
318 | - regcache (readonly_t, const regcache &src); | |
319 | - | |
320 | 310 | DISABLE_COPY_AND_ASSIGN (regcache); |
321 | 311 | |
322 | 312 | /* Return REGCACHE's address space. */ |