forked from Imagelibrary/binutils-gdb
Compare commits
254 Commits
azanella/p
...
gdb-15-bra
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
123beb129e | ||
|
|
475f2cbbbd | ||
|
|
1fb59405aa | ||
|
|
3a20929e71 | ||
|
|
0c5e1b96e6 | ||
|
|
dd5eb961c9 | ||
|
|
ea2db342a9 | ||
|
|
bfc7a30a7d | ||
|
|
0f8e4e7f5f | ||
|
|
15e2e49ed0 | ||
|
|
9b90800559 | ||
|
|
80966f0224 | ||
|
|
30e1c7c3b9 | ||
|
|
b474a1c652 | ||
|
|
3e280897de | ||
|
|
cfe4f165c6 | ||
|
|
7eefed90bf | ||
|
|
b243eaa001 | ||
|
|
308e46ba8f | ||
|
|
728a97eb92 | ||
|
|
b91f11ef64 | ||
|
|
d939da6c03 | ||
|
|
b80e240e95 | ||
|
|
1d8a8bd951 | ||
|
|
ed543a1ad8 | ||
|
|
eaa8ce62a8 | ||
|
|
9cc8124148 | ||
|
|
aae4f96d04 | ||
|
|
aa8cd56a24 | ||
|
|
b7918205e0 | ||
|
|
752fd3dee2 | ||
|
|
6c15056535 | ||
|
|
74665e9c83 | ||
|
|
8105349d0c | ||
|
|
e812d600ca | ||
|
|
d1e92a4e5d | ||
|
|
4938c2a14d | ||
|
|
293608c633 | ||
|
|
72cae7e307 | ||
|
|
d60e081397 | ||
|
|
a4e9a4a258 | ||
|
|
a7e8c33b49 | ||
|
|
7f55224bf9 | ||
|
|
1c2a6995af | ||
|
|
1845efd7ef | ||
|
|
884ceb0648 | ||
|
|
36b9e9cda4 | ||
|
|
a82c5b2b0d | ||
|
|
853b50ce68 | ||
|
|
b0722a909e | ||
|
|
8ec3ace7e9 | ||
|
|
6fbec02804 | ||
|
|
7775dfb416 | ||
|
|
e07b759696 | ||
|
|
19a3119365 | ||
|
|
614cee8bd3 | ||
|
|
b21808d156 | ||
|
|
c7eb8137bd | ||
|
|
2a7d2f7b17 | ||
|
|
06a25c25ee | ||
|
|
5918e612c5 | ||
|
|
d3ddd57c5c | ||
|
|
06afc6e611 | ||
|
|
14a86c2024 | ||
|
|
6a4f7b4344 | ||
|
|
c331a477e1 | ||
|
|
b04e41f000 | ||
|
|
4141e65c9e | ||
|
|
e27deb60b1 | ||
|
|
aea7c65622 | ||
|
|
96caeefbf2 | ||
|
|
cee605dec1 | ||
|
|
58b9983b03 | ||
|
|
665ee950cb | ||
|
|
782bbd70ea | ||
|
|
ab78989a68 | ||
|
|
e076e02ac7 | ||
|
|
afc31609dd | ||
|
|
ac3fac59de | ||
|
|
174b564643 | ||
|
|
1ea44b4dda | ||
|
|
1f92e8f540 | ||
|
|
6c2f118aec | ||
|
|
896464c092 | ||
|
|
7ad81401be | ||
|
|
3c8349d9c5 | ||
|
|
6ee5218bb3 | ||
|
|
87fd313a63 | ||
|
|
721c6d6a56 | ||
|
|
7e95080f06 | ||
|
|
d6e12e6521 | ||
|
|
f1ca7a8663 | ||
|
|
23c84db5b3 | ||
|
|
0252f80e2d | ||
|
|
5d9b7e7274 | ||
|
|
5fc6163431 | ||
|
|
c9013a8511 | ||
|
|
4ff12ed8a6 | ||
|
|
37cba8b06c | ||
|
|
f4887f348a | ||
|
|
6869c5ee9e | ||
|
|
0f40ae10c7 | ||
|
|
7898a62f32 | ||
|
|
ba51e24c34 | ||
|
|
62eb742c4f | ||
|
|
ff6e00ab63 | ||
|
|
8aecb61b34 | ||
|
|
eb95d7939d | ||
|
|
21528df40e | ||
|
|
9ca807bc5f | ||
|
|
cac6b1f3b0 | ||
|
|
b99d8c2e96 | ||
|
|
838176b1d7 | ||
|
|
2b19251be8 | ||
|
|
f86feb2a7f | ||
|
|
fa08fd1d77 | ||
|
|
9ade3065a1 | ||
|
|
846d33f338 | ||
|
|
68163a5c4f | ||
|
|
897204a988 | ||
|
|
c331455027 | ||
|
|
fdcd19f594 | ||
|
|
1f7b8cce76 | ||
|
|
9542d1b3a0 | ||
|
|
4210743723 | ||
|
|
2daf900f61 | ||
|
|
f74feca10c | ||
|
|
9c8ee57a0f | ||
|
|
865b7d5d83 | ||
|
|
3831f9d6f1 | ||
|
|
5b1b2884ce | ||
|
|
1210b9b0ed | ||
|
|
05d5112c10 | ||
|
|
f086ab70d5 | ||
|
|
524b5ad7db | ||
|
|
5a8e6d7e78 | ||
|
|
867d8e09d7 | ||
|
|
de553d417e | ||
|
|
731a801b1e | ||
|
|
2c9e05f3a6 | ||
|
|
fa0424d0e3 | ||
|
|
67196cabf5 | ||
|
|
98032324bc | ||
|
|
3aa3fd0c2e | ||
|
|
771c98e80e | ||
|
|
f171f7e8df | ||
|
|
2ed13e3b58 | ||
|
|
9e58138c75 | ||
|
|
7b14ea4637 | ||
|
|
a0ac39eba6 | ||
|
|
056d54b711 | ||
|
|
7aa46e36e1 | ||
|
|
07f7e1c042 | ||
|
|
b822630603 | ||
|
|
f3fed29a2c | ||
|
|
74b18e3538 | ||
|
|
7ae383fd7a | ||
|
|
a443ee2422 | ||
|
|
1260e51a7f | ||
|
|
87984f7698 | ||
|
|
23b8eaaff0 | ||
|
|
416907555e | ||
|
|
a363b89f09 | ||
|
|
0770a377d1 | ||
|
|
afc5aff69f | ||
|
|
dc36238f1d | ||
|
|
79cc1a2d92 | ||
|
|
278329cf8f | ||
|
|
46042a600e | ||
|
|
760242224f | ||
|
|
ef812cfbf2 | ||
|
|
42fcd11a89 | ||
|
|
bb49d104a5 | ||
|
|
7ff33e182c | ||
|
|
2d25abcf7d | ||
|
|
ef1b80e913 | ||
|
|
e9d2651cb2 | ||
|
|
de136936c7 | ||
|
|
e7c91a1ff9 | ||
|
|
4a8ff36655 | ||
|
|
b178b3d8d0 | ||
|
|
ea91792f47 | ||
|
|
76604451b4 | ||
|
|
8d3ad0528d | ||
|
|
2b04f85455 | ||
|
|
60c75436e4 | ||
|
|
e885320150 | ||
|
|
f6535ad6bf | ||
|
|
7b20890ad6 | ||
|
|
35ad5708a7 | ||
|
|
ef5930bd0f | ||
|
|
f7e429d581 | ||
|
|
2de28d2f45 | ||
|
|
cec2e207d0 | ||
|
|
edd3f7be25 | ||
|
|
041fb9da7d | ||
|
|
b1f7227b7e | ||
|
|
0c7862ac50 | ||
|
|
f6c0e1bad2 | ||
|
|
d36933683a | ||
|
|
d417a64fc2 | ||
|
|
8d134aa67f | ||
|
|
d432cd83c0 | ||
|
|
476ed517b2 | ||
|
|
3eb137638e | ||
|
|
a21a737e01 | ||
|
|
1396b91045 | ||
|
|
390359aea1 | ||
|
|
72429c2a17 | ||
|
|
dd6d09fd2b | ||
|
|
ccda71a89a | ||
|
|
e7b3fd348f | ||
|
|
f33b87956f | ||
|
|
7d3de2ad64 | ||
|
|
1aa3b72f07 | ||
|
|
9c6d76c0d7 | ||
|
|
bdda01fd9b | ||
|
|
db432c3d50 | ||
|
|
af91ec845e | ||
|
|
7738a8af9d | ||
|
|
44709ad8f5 | ||
|
|
d1f2ec5e93 | ||
|
|
a49df3daea | ||
|
|
4239c6015a | ||
|
|
f41400ee71 | ||
|
|
0c7da7665f | ||
|
|
2681e24698 | ||
|
|
02be73cce7 | ||
|
|
05187655ae | ||
|
|
48db4a8344 | ||
|
|
2feb7c1810 | ||
|
|
3504ea2946 | ||
|
|
8fb41483be | ||
|
|
8215789c47 | ||
|
|
3e61e9a527 | ||
|
|
9b1ed1f3b5 | ||
|
|
a89164f88c | ||
|
|
116e8a3821 | ||
|
|
3ad94add7f | ||
|
|
8af148e476 | ||
|
|
1e1cc01596 | ||
|
|
ec7683e3d7 | ||
|
|
80fba8a24f | ||
|
|
5fcf2ea766 | ||
|
|
909e567305 | ||
|
|
8b69689d8b | ||
|
|
9c2db7a3c7 | ||
|
|
97b31937d6 | ||
|
|
d5185bee0b | ||
|
|
6aabfa4522 | ||
|
|
5194ca4da1 | ||
|
|
d2c4f42000 | ||
|
|
85f8f79ea8 | ||
|
|
38e47144a5 |
@@ -16,7 +16,7 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
# Controls whether to enable development-mode features by default.
|
# Controls whether to enable development-mode features by default.
|
||||||
development=true
|
development=false
|
||||||
|
|
||||||
# Indicate whether this is a release branch.
|
# Indicate whether this is a release branch.
|
||||||
experimental=true
|
experimental=true
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
In releases, the date is not included in either version strings or
|
In releases, the date is not included in either version strings or
|
||||||
sonames. */
|
sonames. */
|
||||||
#define BFD_VERSION_DATE 20240526
|
#define BFD_VERSION_DATE 20241229
|
||||||
#define BFD_VERSION @bfd_version@
|
#define BFD_VERSION @bfd_version@
|
||||||
#define BFD_VERSION_STRING @bfd_version_package@ @bfd_version_string@
|
#define BFD_VERSION_STRING @bfd_version_package@ @bfd_version_string@
|
||||||
#define REPORT_BUGS_TO @report_bugs_to@
|
#define REPORT_BUGS_TO @report_bugs_to@
|
||||||
|
|||||||
2
gdb/NEWS
2
gdb/NEWS
@@ -1,7 +1,7 @@
|
|||||||
What has changed in GDB?
|
What has changed in GDB?
|
||||||
(Organized release by release)
|
(Organized release by release)
|
||||||
|
|
||||||
*** Changes since GDB 14
|
*** Changes in GDB 15
|
||||||
|
|
||||||
* The MPX commands "show/set mpx bound" have been deprecated, as Intel
|
* The MPX commands "show/set mpx bound" have been deprecated, as Intel
|
||||||
listed MPX as removed in 2019.
|
listed MPX as removed in 2019.
|
||||||
|
|||||||
@@ -78,12 +78,6 @@ public:
|
|||||||
|
|
||||||
int can_do_single_step () override;
|
int can_do_single_step () override;
|
||||||
|
|
||||||
/* Override the GNU/Linux inferior startup hook. */
|
|
||||||
void post_startup_inferior (ptid_t) override;
|
|
||||||
|
|
||||||
/* Override the GNU/Linux post attach hook. */
|
|
||||||
void post_attach (int pid) override;
|
|
||||||
|
|
||||||
/* These three defer to common nat/ code. */
|
/* These three defer to common nat/ code. */
|
||||||
void low_new_thread (struct lwp_info *lp) override
|
void low_new_thread (struct lwp_info *lp) override
|
||||||
{ aarch64_linux_new_thread (lp); }
|
{ aarch64_linux_new_thread (lp); }
|
||||||
@@ -93,6 +87,7 @@ public:
|
|||||||
{ aarch64_linux_prepare_to_resume (lp); }
|
{ aarch64_linux_prepare_to_resume (lp); }
|
||||||
|
|
||||||
void low_new_fork (struct lwp_info *parent, pid_t child_pid) override;
|
void low_new_fork (struct lwp_info *parent, pid_t child_pid) override;
|
||||||
|
void low_init_process (pid_t pid) override;
|
||||||
void low_forget_process (pid_t pid) override;
|
void low_forget_process (pid_t pid) override;
|
||||||
|
|
||||||
/* Add our siginfo layout converter. */
|
/* Add our siginfo layout converter. */
|
||||||
@@ -844,29 +839,18 @@ ps_get_thread_area (struct ps_prochandle *ph,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Implement the virtual inf_ptrace_target::post_startup_inferior method. */
|
/* Implement the "low_init_process" target_ops method. */
|
||||||
|
|
||||||
void
|
void
|
||||||
aarch64_linux_nat_target::post_startup_inferior (ptid_t ptid)
|
aarch64_linux_nat_target::low_init_process (pid_t pid)
|
||||||
{
|
|
||||||
low_forget_process (ptid.pid ());
|
|
||||||
aarch64_linux_get_debug_reg_capacity (ptid.pid ());
|
|
||||||
linux_nat_target::post_startup_inferior (ptid);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Implement the "post_attach" target_ops method. */
|
|
||||||
|
|
||||||
void
|
|
||||||
aarch64_linux_nat_target::post_attach (int pid)
|
|
||||||
{
|
{
|
||||||
low_forget_process (pid);
|
low_forget_process (pid);
|
||||||
/* Set the hardware debug register capacity. If
|
/* Set the hardware debug register capacity. This requires the process to be
|
||||||
aarch64_linux_get_debug_reg_capacity is not called
|
ptrace-stopped, otherwise detection will fail and software watchpoints will
|
||||||
(as it is in aarch64_linux_child_post_startup_inferior) then
|
be used instead of hardware. If we allow this to be done lazily, we
|
||||||
software watchpoints will be used instead of hardware
|
cannot guarantee that it's called when the process is ptrace-stopped, so
|
||||||
watchpoints when attaching to a target. */
|
do it now. */
|
||||||
aarch64_linux_get_debug_reg_capacity (pid);
|
aarch64_linux_get_debug_reg_capacity (pid);
|
||||||
linux_nat_target::post_attach (pid);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Implement the "read_description" target_ops method. */
|
/* Implement the "read_description" target_ops method. */
|
||||||
|
|||||||
@@ -3808,10 +3808,12 @@ aarch64_displaced_step_copy_insn (struct gdbarch *gdbarch,
|
|||||||
if (aarch64_decode_insn (insn, &inst, 1, NULL) != 0)
|
if (aarch64_decode_insn (insn, &inst, 1, NULL) != 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* Look for a Load Exclusive instruction which begins the sequence. */
|
/* Look for a Load Exclusive instruction which begins the sequence,
|
||||||
if (inst.opcode->iclass == ldstexcl && bit (insn, 22))
|
or for a MOPS instruction. */
|
||||||
|
if ((inst.opcode->iclass == ldstexcl && bit (insn, 22))
|
||||||
|
|| AARCH64_CPU_HAS_FEATURE (*inst.opcode->avariant, MOPS))
|
||||||
{
|
{
|
||||||
/* We can't displaced step atomic sequences. */
|
/* We can't displaced step atomic sequences nor MOPS instructions. */
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5186,6 +5188,71 @@ aarch64_record_asimd_load_store (aarch64_insn_decode_record *aarch64_insn_r)
|
|||||||
return AARCH64_RECORD_SUCCESS;
|
return AARCH64_RECORD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Record handler for Memory Copy and Memory Set instructions. */
|
||||||
|
|
||||||
|
static unsigned int
|
||||||
|
aarch64_record_memcopy_memset (aarch64_insn_decode_record *aarch64_insn_r)
|
||||||
|
{
|
||||||
|
if (record_debug)
|
||||||
|
debug_printf ("Process record: memory copy and memory set\n");
|
||||||
|
|
||||||
|
uint8_t op1 = bits (aarch64_insn_r->aarch64_insn, 22, 23);
|
||||||
|
uint8_t op2 = bits (aarch64_insn_r->aarch64_insn, 12, 15);
|
||||||
|
uint32_t reg_rd = bits (aarch64_insn_r->aarch64_insn, 0, 4);
|
||||||
|
uint32_t reg_rn = bits (aarch64_insn_r->aarch64_insn, 5, 9);
|
||||||
|
uint32_t record_buf[3];
|
||||||
|
uint64_t record_buf_mem[4];
|
||||||
|
|
||||||
|
if (op1 == 3 && op2 > 11)
|
||||||
|
/* Unallocated instructions. */
|
||||||
|
return AARCH64_RECORD_UNKNOWN;
|
||||||
|
|
||||||
|
/* Set instructions have two registers and one memory region to be
|
||||||
|
recorded. */
|
||||||
|
record_buf[0] = reg_rd;
|
||||||
|
record_buf[1] = reg_rn;
|
||||||
|
aarch64_insn_r->reg_rec_count = 2;
|
||||||
|
|
||||||
|
ULONGEST dest_addr;
|
||||||
|
regcache_raw_read_unsigned (aarch64_insn_r->regcache, reg_rd, &dest_addr);
|
||||||
|
|
||||||
|
LONGEST length;
|
||||||
|
regcache_raw_read_signed (aarch64_insn_r->regcache, reg_rn, &length);
|
||||||
|
|
||||||
|
/* In one of the algorithm options a processor can implement, the length
|
||||||
|
in Rn has an inverted sign. */
|
||||||
|
if (length < 0)
|
||||||
|
length *= -1;
|
||||||
|
|
||||||
|
record_buf_mem[0] = length;
|
||||||
|
record_buf_mem[1] = dest_addr;
|
||||||
|
aarch64_insn_r->mem_rec_count = 1;
|
||||||
|
|
||||||
|
if (op1 != 3)
|
||||||
|
{
|
||||||
|
/* Copy instructions have an additional register and an additional
|
||||||
|
memory region to be recorded. */
|
||||||
|
uint32_t reg_rs = bits (aarch64_insn_r->aarch64_insn, 16, 20);
|
||||||
|
|
||||||
|
record_buf[2] = reg_rs;
|
||||||
|
aarch64_insn_r->reg_rec_count++;
|
||||||
|
|
||||||
|
ULONGEST source_addr;
|
||||||
|
regcache_raw_read_unsigned (aarch64_insn_r->regcache, reg_rs,
|
||||||
|
&source_addr);
|
||||||
|
|
||||||
|
record_buf_mem[2] = length;
|
||||||
|
record_buf_mem[3] = source_addr;
|
||||||
|
aarch64_insn_r->mem_rec_count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
MEM_ALLOC (aarch64_insn_r->aarch64_mems, aarch64_insn_r->mem_rec_count,
|
||||||
|
record_buf_mem);
|
||||||
|
REG_ALLOC (aarch64_insn_r->aarch64_regs, aarch64_insn_r->reg_rec_count,
|
||||||
|
record_buf);
|
||||||
|
return AARCH64_RECORD_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
/* Record handler for load and store instructions. */
|
/* Record handler for load and store instructions. */
|
||||||
|
|
||||||
static unsigned int
|
static unsigned int
|
||||||
@@ -5463,6 +5530,10 @@ aarch64_record_load_store (aarch64_insn_decode_record *aarch64_insn_r)
|
|||||||
if (insn_bits10_11 == 0x01 || insn_bits10_11 == 0x03)
|
if (insn_bits10_11 == 0x01 || insn_bits10_11 == 0x03)
|
||||||
record_buf[aarch64_insn_r->reg_rec_count++] = reg_rn;
|
record_buf[aarch64_insn_r->reg_rec_count++] = reg_rn;
|
||||||
}
|
}
|
||||||
|
/* Memory Copy and Memory Set instructions. */
|
||||||
|
else if ((insn_bits24_27 & 1) == 1 && insn_bits28_29 == 1
|
||||||
|
&& insn_bits10_11 == 1 && !insn_bit21)
|
||||||
|
return aarch64_record_memcopy_memset (aarch64_insn_r);
|
||||||
/* Advanced SIMD load/store instructions. */
|
/* Advanced SIMD load/store instructions. */
|
||||||
else
|
else
|
||||||
return aarch64_record_asimd_load_store (aarch64_insn_r);
|
return aarch64_record_asimd_load_store (aarch64_insn_r);
|
||||||
|
|||||||
@@ -36,6 +36,7 @@
|
|||||||
%{
|
%{
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <unordered_map>
|
||||||
#include "expression.h"
|
#include "expression.h"
|
||||||
#include "value.h"
|
#include "value.h"
|
||||||
#include "parser-defs.h"
|
#include "parser-defs.h"
|
||||||
|
|||||||
@@ -37,6 +37,7 @@
|
|||||||
#include "auxv.h"
|
#include "auxv.h"
|
||||||
#include "observable.h"
|
#include "observable.h"
|
||||||
#include "solib-target.h"
|
#include "solib-target.h"
|
||||||
|
#include "event-top.h"
|
||||||
|
|
||||||
#include "gdbsupport/version.h"
|
#include "gdbsupport/version.h"
|
||||||
|
|
||||||
@@ -1040,7 +1041,11 @@ default_print_insn (bfd_vma memaddr, disassemble_info *info)
|
|||||||
info->mach, current_program_space->exec_bfd ());
|
info->mach, current_program_space->exec_bfd ());
|
||||||
|
|
||||||
gdb_assert (disassemble_fn != NULL);
|
gdb_assert (disassemble_fn != NULL);
|
||||||
return (*disassemble_fn) (memaddr, info);
|
int res = (*disassemble_fn) (memaddr, info);
|
||||||
|
|
||||||
|
QUIT;
|
||||||
|
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* See arch-utils.h. */
|
/* See arch-utils.h. */
|
||||||
|
|||||||
@@ -103,6 +103,7 @@ public:
|
|||||||
|
|
||||||
/* Handle process creation and exit. */
|
/* Handle process creation and exit. */
|
||||||
void low_new_fork (struct lwp_info *parent, pid_t child_pid) override;
|
void low_new_fork (struct lwp_info *parent, pid_t child_pid) override;
|
||||||
|
void low_init_process (pid_t pid) override;
|
||||||
void low_forget_process (pid_t pid) override;
|
void low_forget_process (pid_t pid) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -805,6 +806,19 @@ arm_linux_process_info_get (pid_t pid)
|
|||||||
return proc;
|
return proc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Implement the "low_init_process" target_ops method. */
|
||||||
|
|
||||||
|
void
|
||||||
|
arm_linux_nat_target::low_init_process (pid_t pid)
|
||||||
|
{
|
||||||
|
/* Set the hardware debug register capacity. This requires the process to be
|
||||||
|
ptrace-stopped, otherwise detection will fail and software watchpoints will
|
||||||
|
be used instead of hardware. If we allow this to be done lazily, we
|
||||||
|
cannot guarantee that it's called when the process is ptrace-stopped, so
|
||||||
|
do it now. */
|
||||||
|
arm_linux_get_hwbp_cap ();
|
||||||
|
}
|
||||||
|
|
||||||
/* Called whenever GDB is no longer debugging process PID. It deletes
|
/* Called whenever GDB is no longer debugging process PID. It deletes
|
||||||
data structures that keep track of debug register state. */
|
data structures that keep track of debug register state. */
|
||||||
|
|
||||||
|
|||||||
@@ -287,10 +287,10 @@ cp_search_static_and_baseclasses (const char *name,
|
|||||||
struct type *scope_type = scope_sym.symbol->type ();
|
struct type *scope_type = scope_sym.symbol->type ();
|
||||||
|
|
||||||
/* If the scope is a function/method, then look up NESTED as a local
|
/* If the scope is a function/method, then look up NESTED as a local
|
||||||
static variable. E.g., "print 'function()::static_var'". */
|
static variable or type. E.g., "print 'function()::static_var'". */
|
||||||
if ((scope_type->code () == TYPE_CODE_FUNC
|
if ((scope_type->code () == TYPE_CODE_FUNC
|
||||||
|| scope_type->code () == TYPE_CODE_METHOD)
|
|| scope_type->code () == TYPE_CODE_METHOD)
|
||||||
&& (domain & SEARCH_VAR_DOMAIN) != 0)
|
&& (domain & (SEARCH_VAR_DOMAIN | SEARCH_TYPE_DOMAIN)) != 0)
|
||||||
return lookup_symbol (nested, scope_sym.symbol->value_block (),
|
return lookup_symbol (nested, scope_sym.symbol->value_block (),
|
||||||
domain, NULL);
|
domain, NULL);
|
||||||
|
|
||||||
|
|||||||
@@ -197,7 +197,12 @@ gdb_disassembler_memory_reader::dis_asm_read_memory
|
|||||||
(bfd_vma memaddr, gdb_byte *myaddr, unsigned int len,
|
(bfd_vma memaddr, gdb_byte *myaddr, unsigned int len,
|
||||||
struct disassemble_info *info) noexcept
|
struct disassemble_info *info) noexcept
|
||||||
{
|
{
|
||||||
return target_read_code (memaddr, myaddr, len);
|
auto res = catch_exceptions<int, -1> ([&]
|
||||||
|
{
|
||||||
|
return target_read_code (memaddr, myaddr, len);
|
||||||
|
});
|
||||||
|
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Wrapper of memory_error. */
|
/* Wrapper of memory_error. */
|
||||||
|
|||||||
@@ -658,17 +658,30 @@ annotate/index.html: $(ANNOTATE_DOC_FILES)
|
|||||||
-I $(srcdir) \
|
-I $(srcdir) \
|
||||||
$(srcdir)/annotate.texinfo
|
$(srcdir)/annotate.texinfo
|
||||||
|
|
||||||
# Man pages
|
# Man pages. The TEXI2POD and TEXI2MAN steps are performed within a
|
||||||
%.pod : gdb.texinfo $(GDB_DOC_FILES)
|
# single recipe to support how we distribute GDB releases. A release
|
||||||
$(ECHO_TEXI2POD) $(TEXI2POD) $(MANCONF) -D$* < $(srcdir)/gdb.texinfo > $@
|
# includes the .1 and .5 man pages in the source tree, but not the
|
||||||
|
# .pod files.
|
||||||
$(MAN1S) : %.1 : %.pod $(GDB_DOC_FILES)
|
#
|
||||||
|
# When building and installing a release of GDB it should not be
|
||||||
|
# necessary to rebuild the .1 or .5 man page files, nor should it be
|
||||||
|
# necessary to rebuild the .pod files.
|
||||||
|
#
|
||||||
|
# If we split the .pod creation from the creation of the .1 and .5
|
||||||
|
# pages, then the .pod files must become a dependency, this will
|
||||||
|
# trigger an attempt to rebuild these files while building and
|
||||||
|
# installing a release of GDB, which is something we don't want.
|
||||||
|
$(MAN1S) : %.1 : $(GDB_DOC_FILES)
|
||||||
|
$(ECHO_TEXI2POD) $(TEXI2POD) $(MANCONF) -D$* < $(srcdir)/gdb.texinfo > $*.pod
|
||||||
$(ECHO_TEXI2MAN) ($(POD2MAN1) $*.pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \
|
$(ECHO_TEXI2MAN) ($(POD2MAN1) $*.pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \
|
||||||
mv -f $@.T$$$$ $@) || (rm -f $@.T$$$$ && exit 1)
|
mv -f $@.T$$$$ $@) || (rm -f $@.T$$$$ && exit 1)
|
||||||
|
$(SILENCE) rm -f $*.pod
|
||||||
|
|
||||||
$(MAN5S) : %.5 : %.pod $(GDB_DOC_FILES)
|
$(MAN5S) : %.5 : $(GDB_DOC_FILES)
|
||||||
$(ECHO_TEXI2MAN) ($(POD2MAN1) $*.pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \
|
$(ECHO_TEXI2POD) $(TEXI2POD) $(MANCONF) -D$* < $(srcdir)/gdb.texinfo > $*.pod
|
||||||
|
$(ECHO_TEXI2MAN) ($(POD2MAN5) $*.pod | sed -e '/^.if n .na/d' > $@.T$$$$ && \
|
||||||
mv -f $@.T$$$$ $@) || (rm -f $@.T$$$$ && exit 1)
|
mv -f $@.T$$$$ $@) || (rm -f $@.T$$$$ && exit 1)
|
||||||
|
$(SILENCE) rm -f $*.pod
|
||||||
|
|
||||||
force:
|
force:
|
||||||
|
|
||||||
|
|||||||
@@ -16440,12 +16440,6 @@ cooked_indexer::index_dies (cutu_reader *reader,
|
|||||||
flags &= ~IS_STATIC;
|
flags &= ~IS_STATIC;
|
||||||
flags |= parent_entry->flags & IS_STATIC;
|
flags |= parent_entry->flags & IS_STATIC;
|
||||||
}
|
}
|
||||||
/* If the parent is an enum, but not an enum class, then use the
|
|
||||||
grandparent instead. */
|
|
||||||
if (this_parent_entry != nullptr
|
|
||||||
&& this_parent_entry->tag == DW_TAG_enumeration_type
|
|
||||||
&& !is_enum_class)
|
|
||||||
this_parent_entry = this_parent_entry->get_parent ();
|
|
||||||
|
|
||||||
if (abbrev->tag == DW_TAG_namespace
|
if (abbrev->tag == DW_TAG_namespace
|
||||||
&& m_language == language_cplus
|
&& m_language == language_cplus
|
||||||
@@ -16505,7 +16499,15 @@ cooked_indexer::index_dies (cutu_reader *reader,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_TAG_enumeration_type:
|
case DW_TAG_enumeration_type:
|
||||||
info_ptr = recurse (reader, info_ptr, this_entry, fully);
|
/* We need to recurse even for an anonymous enumeration.
|
||||||
|
Which scope we record as the parent scope depends on
|
||||||
|
whether we're reading an "enum class". If so, we use
|
||||||
|
the enum itself as the parent, yielding names like
|
||||||
|
"enum_class::enumerator"; otherwise we inject the
|
||||||
|
names into our own parent scope. */
|
||||||
|
info_ptr = recurse (reader, info_ptr,
|
||||||
|
is_enum_class ? this_entry : parent_entry,
|
||||||
|
fully);
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case DW_TAG_module:
|
case DW_TAG_module:
|
||||||
@@ -17914,8 +17916,8 @@ public:
|
|||||||
we're processing the end of a sequence. */
|
we're processing the end of a sequence. */
|
||||||
void record_line (bool end_sequence);
|
void record_line (bool end_sequence);
|
||||||
|
|
||||||
/* Check ADDRESS is -1, or zero and less than UNRELOCATED_LOWPC, and if true
|
/* Check ADDRESS is -1, -2, or zero and less than UNRELOCATED_LOWPC, and if
|
||||||
nop-out rest of the lines in this sequence. */
|
true nop-out rest of the lines in this sequence. */
|
||||||
void check_line_address (struct dwarf2_cu *cu,
|
void check_line_address (struct dwarf2_cu *cu,
|
||||||
const gdb_byte *line_ptr,
|
const gdb_byte *line_ptr,
|
||||||
unrelocated_addr unrelocated_lowpc,
|
unrelocated_addr unrelocated_lowpc,
|
||||||
@@ -18325,13 +18327,16 @@ lnp_state_machine::check_line_address (struct dwarf2_cu *cu,
|
|||||||
unrelocated_addr unrelocated_lowpc,
|
unrelocated_addr unrelocated_lowpc,
|
||||||
unrelocated_addr address)
|
unrelocated_addr address)
|
||||||
{
|
{
|
||||||
/* Linkers resolve a symbolic relocation referencing a GC'd function to 0 or
|
/* Linkers resolve a symbolic relocation referencing a GC'd function to 0,
|
||||||
-1. If ADDRESS is 0, ignoring the opcode will err if the text section is
|
-1 or -2 (-2 is used by certain lld versions, see
|
||||||
|
https://github.com/llvm/llvm-project/commit/e618ccbf431f6730edb6d1467a127c3a52fd57f7).
|
||||||
|
If ADDRESS is 0, ignoring the opcode will err if the text section is
|
||||||
located at 0x0. In this case, additionally check that if
|
located at 0x0. In this case, additionally check that if
|
||||||
ADDRESS < UNRELOCATED_LOWPC. */
|
ADDRESS < UNRELOCATED_LOWPC. */
|
||||||
|
|
||||||
if ((address == (unrelocated_addr) 0 && address < unrelocated_lowpc)
|
if ((address == (unrelocated_addr) 0 && address < unrelocated_lowpc)
|
||||||
|| address == (unrelocated_addr) -1)
|
|| address == (unrelocated_addr) -1
|
||||||
|
|| address == (unrelocated_addr) -2)
|
||||||
{
|
{
|
||||||
/* This line table is for a function which has been
|
/* This line table is for a function which has been
|
||||||
GCd by the linker. Ignore it. PR gdb/12528 */
|
GCd by the linker. Ignore it. PR gdb/12528 */
|
||||||
|
|||||||
@@ -24,6 +24,8 @@
|
|||||||
|
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
||||||
|
#include "extension.h"
|
||||||
|
|
||||||
struct cmd_list_element;
|
struct cmd_list_element;
|
||||||
|
|
||||||
/* The current quit handler (and its type). This is called from the
|
/* The current quit handler (and its type). This is called from the
|
||||||
@@ -81,6 +83,29 @@ extern void quit_serial_event_set ();
|
|||||||
|
|
||||||
extern void quit_serial_event_clear ();
|
extern void quit_serial_event_clear ();
|
||||||
|
|
||||||
|
/* Wrap f (args) and handle exceptions by:
|
||||||
|
- returning val, and
|
||||||
|
- calling set_quit_flag or set_force_quit_flag, if needed. */
|
||||||
|
|
||||||
|
template <typename R, R val, typename F, typename... Args>
|
||||||
|
static R
|
||||||
|
catch_exceptions (F &&f, Args&&... args)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return f (std::forward<Args> (args)...);
|
||||||
|
}
|
||||||
|
catch (const gdb_exception &ex)
|
||||||
|
{
|
||||||
|
if (ex.reason == RETURN_QUIT)
|
||||||
|
set_quit_flag ();
|
||||||
|
else if (ex.reason == RETURN_FORCED_QUIT)
|
||||||
|
set_force_quit_flag ();
|
||||||
|
}
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
extern void display_gdb_prompt (const char *new_prompt);
|
extern void display_gdb_prompt (const char *new_prompt);
|
||||||
extern void gdb_setup_readline (int);
|
extern void gdb_setup_readline (int);
|
||||||
extern void gdb_disable_readline (void);
|
extern void gdb_disable_readline (void);
|
||||||
|
|||||||
@@ -528,7 +528,7 @@ objfile_find_memory_regions (struct target_ops *self,
|
|||||||
find_memory_region_ftype func, void *obfd)
|
find_memory_region_ftype func, void *obfd)
|
||||||
{
|
{
|
||||||
/* Use objfile data to create memory sections. */
|
/* Use objfile data to create memory sections. */
|
||||||
bfd_vma temp_bottom, temp_top;
|
bfd_vma temp_bottom = 0, temp_top = 0;
|
||||||
|
|
||||||
/* Call callback function for each objfile section. */
|
/* Call callback function for each objfile section. */
|
||||||
for (objfile *objfile : current_program_space->objfiles ())
|
for (objfile *objfile : current_program_space->objfiles ())
|
||||||
|
|||||||
@@ -930,29 +930,6 @@ gdb_bfd_openw (const char *filename, const char *target)
|
|||||||
return gdb_bfd_ref_ptr::new_reference (result);
|
return gdb_bfd_ref_ptr::new_reference (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Wrap f (args) and handle exceptions by:
|
|
||||||
- returning val, and
|
|
||||||
- calling set_quit_flag or set_force_quit_flag, if needed. */
|
|
||||||
|
|
||||||
template <typename R, R val, typename F, typename... Args>
|
|
||||||
static R
|
|
||||||
catch_exceptions (F &&f, Args&&... args)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return f (std::forward<Args> (args)...);
|
|
||||||
}
|
|
||||||
catch (const gdb_exception &ex)
|
|
||||||
{
|
|
||||||
if (ex.reason == RETURN_QUIT)
|
|
||||||
set_quit_flag ();
|
|
||||||
else if (ex.reason == RETURN_FORCED_QUIT)
|
|
||||||
set_force_quit_flag ();
|
|
||||||
}
|
|
||||||
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* See gdb_bfd.h. */
|
/* See gdb_bfd.h. */
|
||||||
|
|
||||||
gdb_bfd_ref_ptr
|
gdb_bfd_ref_ptr
|
||||||
|
|||||||
@@ -76,8 +76,19 @@ typedef wint_t gdb_wint_t;
|
|||||||
We exploit this fact in the hope that there are hosts that define
|
We exploit this fact in the hope that there are hosts that define
|
||||||
this but which do not support "wchar_t" as an encoding argument to
|
this but which do not support "wchar_t" as an encoding argument to
|
||||||
iconv_open. We put the endianness into the encoding name to avoid
|
iconv_open. We put the endianness into the encoding name to avoid
|
||||||
hosts that emit a BOM when the unadorned name is used. */
|
hosts that emit a BOM when the unadorned name is used.
|
||||||
#if defined (__STDC_ISO_10646__)
|
|
||||||
|
Also, on version 14 macOS 'Sonoma', the implementation of iconv was
|
||||||
|
changed in such a way that breaks the way that gdb was using it.
|
||||||
|
Specifically, using wchar_t as an intermediate encoding silently
|
||||||
|
breaks when attempting to do character-by-character encoding.
|
||||||
|
By using the intermediate_encoding function to choose a suitable
|
||||||
|
encoding to put in the wchar_t, the iconv implementation behaves as
|
||||||
|
we expect it to. Strictly speaking, this seems to be a bug in
|
||||||
|
Sonoma specifically, but it is desirable for binaries built for
|
||||||
|
older versions of macOS to still work on newer ones such as Sonoma,
|
||||||
|
so there is no version check here for this workaround. */
|
||||||
|
#if defined (__STDC_ISO_10646__) || defined (__APPLE__)
|
||||||
#define USE_INTERMEDIATE_ENCODING_FUNCTION
|
#define USE_INTERMEDIATE_ENCODING_FUNCTION
|
||||||
#define INTERMEDIATE_ENCODING intermediate_encoding ()
|
#define INTERMEDIATE_ENCODING intermediate_encoding ()
|
||||||
const char *intermediate_encoding (void);
|
const char *intermediate_encoding (void);
|
||||||
|
|||||||
@@ -280,13 +280,13 @@ struct gdb_mpz
|
|||||||
gdb_mpz operator>> (unsigned long nbits) const
|
gdb_mpz operator>> (unsigned long nbits) const
|
||||||
{
|
{
|
||||||
gdb_mpz result;
|
gdb_mpz result;
|
||||||
mpz_tdiv_q_2exp (result.m_val, m_val, nbits);
|
mpz_fdiv_q_2exp (result.m_val, m_val, nbits);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
gdb_mpz &operator>>= (unsigned long nbits)
|
gdb_mpz &operator>>= (unsigned long nbits)
|
||||||
{
|
{
|
||||||
mpz_tdiv_q_2exp (m_val, m_val, nbits);
|
mpz_fdiv_q_2exp (m_val, m_val, nbits);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -454,6 +454,12 @@ linux_init_ptrace_procfs (pid_t pid, int attached)
|
|||||||
linux_ptrace_init_warnings ();
|
linux_ptrace_init_warnings ();
|
||||||
linux_proc_init_warnings ();
|
linux_proc_init_warnings ();
|
||||||
proc_mem_file_is_writable ();
|
proc_mem_file_is_writable ();
|
||||||
|
|
||||||
|
/* Let the arch-specific native code do any needed initialization.
|
||||||
|
Some architectures need to call ptrace to check for hardware
|
||||||
|
watchpoints support, etc. Call it now, when we know the tracee
|
||||||
|
is ptrace-stopped. */
|
||||||
|
linux_target->low_init_process (pid);
|
||||||
}
|
}
|
||||||
|
|
||||||
linux_nat_target::~linux_nat_target ()
|
linux_nat_target::~linux_nat_target ()
|
||||||
|
|||||||
@@ -164,6 +164,12 @@ public:
|
|||||||
virtual void low_new_clone (struct lwp_info *parent, pid_t child_lwp)
|
virtual void low_new_clone (struct lwp_info *parent, pid_t child_lwp)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
/* The method to call, if any, when we have a new (from run/attach,
|
||||||
|
not fork) process to debug. The process is ptrace-stopped when
|
||||||
|
this is called. */
|
||||||
|
virtual void low_init_process (pid_t pid)
|
||||||
|
{}
|
||||||
|
|
||||||
/* The method to call, if any, when a process is no longer
|
/* The method to call, if any, when a process is no longer
|
||||||
attached. */
|
attached. */
|
||||||
virtual void low_forget_process (pid_t pid)
|
virtual void low_forget_process (pid_t pid)
|
||||||
|
|||||||
@@ -545,6 +545,8 @@ struct ppc_linux_nat_target final : public linux_nat_target
|
|||||||
|
|
||||||
void low_new_clone (struct lwp_info *, pid_t) override;
|
void low_new_clone (struct lwp_info *, pid_t) override;
|
||||||
|
|
||||||
|
void low_init_process (pid_t pid) override;
|
||||||
|
|
||||||
void low_forget_process (pid_t pid) override;
|
void low_forget_process (pid_t pid) override;
|
||||||
|
|
||||||
void low_prepare_to_resume (struct lwp_info *) override;
|
void low_prepare_to_resume (struct lwp_info *) override;
|
||||||
@@ -2705,6 +2707,19 @@ ppc_linux_nat_target::remove_watchpoint (CORE_ADDR addr, int len,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Implement the "low_init_process" target_ops method. */
|
||||||
|
|
||||||
|
void
|
||||||
|
ppc_linux_nat_target::low_init_process (pid_t pid)
|
||||||
|
{
|
||||||
|
/* Set the hardware debug register capacity. This requires the process to be
|
||||||
|
ptrace-stopped, otherwise detection will fail and software watchpoints will
|
||||||
|
be used instead of hardware. If we allow this to be done lazily, we
|
||||||
|
cannot guarantee that it's called when the process is ptrace-stopped, so
|
||||||
|
do it now. */
|
||||||
|
m_dreg_interface.detect (ptid_t (pid, pid));
|
||||||
|
}
|
||||||
|
|
||||||
/* Clean up the per-process info associated with PID. When using the
|
/* Clean up the per-process info associated with PID. When using the
|
||||||
HWDEBUG interface, we also erase the per-thread state of installed
|
HWDEBUG interface, we also erase the per-thread state of installed
|
||||||
debug registers for all the threads that belong to the group of PID.
|
debug registers for all the threads that belong to the group of PID.
|
||||||
|
|||||||
@@ -667,12 +667,13 @@ disasmpy_info_read_memory (PyObject *self, PyObject *args, PyObject *kw)
|
|||||||
disasm_info_object *obj = (disasm_info_object *) self;
|
disasm_info_object *obj = (disasm_info_object *) self;
|
||||||
DISASMPY_DISASM_INFO_REQUIRE_VALID (obj);
|
DISASMPY_DISASM_INFO_REQUIRE_VALID (obj);
|
||||||
|
|
||||||
LONGEST length, offset = 0;
|
gdb_py_longest length, offset = 0;
|
||||||
gdb::unique_xmalloc_ptr<gdb_byte> buffer;
|
gdb::unique_xmalloc_ptr<gdb_byte> buffer;
|
||||||
static const char *keywords[] = { "length", "offset", nullptr };
|
static const char *keywords[] = { "length", "offset", nullptr };
|
||||||
|
|
||||||
if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "L|L", keywords,
|
if (!gdb_PyArg_ParseTupleAndKeywords (args, kw,
|
||||||
&length, &offset))
|
GDB_PY_LL_ARG "|" GDB_PY_LL_ARG,
|
||||||
|
keywords, &length, &offset))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
/* The apparent address from which we are reading memory. Note that in
|
/* The apparent address from which we are reading memory. Note that in
|
||||||
@@ -849,13 +850,14 @@ gdbpy_disassembler::read_memory_func (bfd_vma memaddr, gdb_byte *buff,
|
|||||||
/* The DisassembleInfo.read_memory method expects an offset from the
|
/* The DisassembleInfo.read_memory method expects an offset from the
|
||||||
address stored within the DisassembleInfo object; calculate that
|
address stored within the DisassembleInfo object; calculate that
|
||||||
offset here. */
|
offset here. */
|
||||||
LONGEST offset = (LONGEST) memaddr - (LONGEST) obj->address;
|
gdb_py_longest offset
|
||||||
|
= (gdb_py_longest) memaddr - (gdb_py_longest) obj->address;
|
||||||
|
|
||||||
/* Now call the DisassembleInfo.read_memory method. This might have been
|
/* Now call the DisassembleInfo.read_memory method. This might have been
|
||||||
overridden by the user. */
|
overridden by the user. */
|
||||||
gdbpy_ref<> result_obj (PyObject_CallMethod ((PyObject *) obj,
|
gdbpy_ref<> result_obj (PyObject_CallMethod ((PyObject *) obj,
|
||||||
"read_memory",
|
"read_memory",
|
||||||
"KL", len, offset));
|
"I" GDB_PY_LL_ARG, len, offset));
|
||||||
|
|
||||||
/* Handle any exceptions. */
|
/* Handle any exceptions. */
|
||||||
if (result_obj == nullptr)
|
if (result_obj == nullptr)
|
||||||
|
|||||||
@@ -266,7 +266,7 @@ stpy_lazy_string_elt_type (lazy_string_object *lazy)
|
|||||||
{
|
{
|
||||||
case TYPE_CODE_PTR:
|
case TYPE_CODE_PTR:
|
||||||
case TYPE_CODE_ARRAY:
|
case TYPE_CODE_ARRAY:
|
||||||
return realtype->target_type ();
|
return check_typedef (realtype->target_type ());
|
||||||
default:
|
default:
|
||||||
/* This is done to preserve existing behaviour. PR 20769.
|
/* This is done to preserve existing behaviour. PR 20769.
|
||||||
E.g., gdb.parse_and_eval("my_int_variable").lazy_string().type. */
|
E.g., gdb.parse_and_eval("my_int_variable").lazy_string().type. */
|
||||||
|
|||||||
@@ -390,6 +390,35 @@ gdbpy_handle_exception ()
|
|||||||
|
|
||||||
if (fetched_error.type_matches (PyExc_KeyboardInterrupt))
|
if (fetched_error.type_matches (PyExc_KeyboardInterrupt))
|
||||||
throw_quit ("Quit");
|
throw_quit ("Quit");
|
||||||
|
else if (fetched_error.type_matches (PyExc_SystemExit))
|
||||||
|
{
|
||||||
|
gdbpy_ref<> value = fetched_error.value ();
|
||||||
|
gdbpy_ref<> code (PyObject_GetAttrString (value.get (), "code"));
|
||||||
|
int exit_arg;
|
||||||
|
|
||||||
|
if (code.get () == Py_None)
|
||||||
|
{
|
||||||
|
/* CODE == None: exit status is 0. */
|
||||||
|
exit_arg = 0;
|
||||||
|
}
|
||||||
|
else if (code.get () != nullptr && PyLong_Check (code.get ()))
|
||||||
|
{
|
||||||
|
/* CODE == integer: exit status is aforementioned integer. */
|
||||||
|
exit_arg = PyLong_AsLong (code.get ());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (code.get () == nullptr)
|
||||||
|
gdbpy_print_stack ();
|
||||||
|
|
||||||
|
/* Otherwise: exit status is 1, print code to stderr. */
|
||||||
|
if (msg != nullptr)
|
||||||
|
gdb_printf (gdb_stderr, "%s\n", msg.get ());
|
||||||
|
exit_arg = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
quit_force (&exit_arg, 0);
|
||||||
|
}
|
||||||
else if (! fetched_error.type_matches (gdbpy_gdberror_exc)
|
else if (! fetched_error.type_matches (gdbpy_gdberror_exc)
|
||||||
|| msg == NULL || *msg == '\0')
|
|| msg == NULL || *msg == '\0')
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2072,6 +2072,7 @@ record_full_core_target::resume (ptid_t ptid, int step,
|
|||||||
enum gdb_signal signal)
|
enum gdb_signal signal)
|
||||||
{
|
{
|
||||||
record_full_resume_step = step;
|
record_full_resume_step = step;
|
||||||
|
record_full_resume_ptid = ptid;
|
||||||
record_full_resumed = 1;
|
record_full_resumed = 1;
|
||||||
record_full_execution_dir = ::execution_direction;
|
record_full_execution_dir = ::execution_direction;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -382,6 +382,8 @@ frv_current_sos ()
|
|||||||
li->map = loadmap;
|
li->map = loadmap;
|
||||||
li->got_value = got_addr;
|
li->got_value = got_addr;
|
||||||
li->lm_addr = lm_addr;
|
li->lm_addr = lm_addr;
|
||||||
|
sop->lm_info = std::move (li);
|
||||||
|
|
||||||
/* Fetch the name. */
|
/* Fetch the name. */
|
||||||
addr = extract_unsigned_integer (lm_buf.l_name,
|
addr = extract_unsigned_integer (lm_buf.l_name,
|
||||||
sizeof (lm_buf.l_name),
|
sizeof (lm_buf.l_name),
|
||||||
|
|||||||
73
gdb/testsuite/gdb.arch/aarch64-mops-single-step.c
Normal file
73
gdb/testsuite/gdb.arch/aarch64-mops-single-step.c
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
/* This file is part of GDB, the GNU debugger.
|
||||||
|
|
||||||
|
Copyright 2024 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#define TEST_STRING "Just a test string."
|
||||||
|
#define BUF_SIZE sizeof(TEST_STRING)
|
||||||
|
|
||||||
|
int
|
||||||
|
main (void)
|
||||||
|
{
|
||||||
|
char source[BUF_SIZE] = TEST_STRING;
|
||||||
|
char dest[BUF_SIZE];
|
||||||
|
char *p, *q;
|
||||||
|
long size, zero;
|
||||||
|
|
||||||
|
/* Note: The prfm instruction in the asm statements below is there just
|
||||||
|
to allow the testcase to recognize when the PC is at the instruction
|
||||||
|
right after the MOPS sequence. */
|
||||||
|
|
||||||
|
p = dest;
|
||||||
|
size = sizeof (dest);
|
||||||
|
zero = 0;
|
||||||
|
/* Break memset. */
|
||||||
|
/* memset implemented in MOPS instructions. */
|
||||||
|
__asm__ volatile ("setp [%0]!, %1!, %2\n\t"
|
||||||
|
"setm [%0]!, %1!, %2\n\t"
|
||||||
|
"sete [%0]!, %1!, %2\n\t"
|
||||||
|
"prfm pldl3keep, [%0, #0]\n\t"
|
||||||
|
: "+&r"(p), "+&r"(size)
|
||||||
|
: "r"(zero)
|
||||||
|
: "memory");
|
||||||
|
|
||||||
|
p = dest;
|
||||||
|
q = source;
|
||||||
|
size = sizeof (dest);
|
||||||
|
/* Break memcpy. */
|
||||||
|
/* memcpy implemented in MOPS instructions. */
|
||||||
|
__asm__ volatile ("cpyfp [%0]!, [%1]!, %2!\n\t"
|
||||||
|
"cpyfm [%0]!, [%1]!, %2!\n\t"
|
||||||
|
"cpyfe [%0]!, [%1]!, %2!\n\t"
|
||||||
|
"prfm pldl3keep, [%0, #0]\n\t"
|
||||||
|
: "+&r" (p), "+&r" (q), "+&r" (size)
|
||||||
|
:
|
||||||
|
: "memory");
|
||||||
|
|
||||||
|
p = dest;
|
||||||
|
q = source;
|
||||||
|
size = sizeof (dest);
|
||||||
|
/* Break memmove. */
|
||||||
|
/* memmove implemented in MOPS instructions. */
|
||||||
|
__asm__ volatile ("cpyp [%0]!, [%1]!, %2!\n\t"
|
||||||
|
"cpym [%0]!, [%1]!, %2!\n\t"
|
||||||
|
"cpye [%0]!, [%1]!, %2!\n\t"
|
||||||
|
"prfm pldl3keep, [%0, #0]\n\t"
|
||||||
|
: "+&r" (p), "+&r" (q), "+&r" (size)
|
||||||
|
:
|
||||||
|
: "memory");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
98
gdb/testsuite/gdb.arch/aarch64-mops-single-step.exp
Normal file
98
gdb/testsuite/gdb.arch/aarch64-mops-single-step.exp
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
# Copyright 2024 Free Software Foundation, Inc.
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
# This file is part of the GDB testsuite.
|
||||||
|
|
||||||
|
# Test single stepping through MOPS (memory operations) instruction sequences.
|
||||||
|
|
||||||
|
require allow_aarch64_mops_tests
|
||||||
|
|
||||||
|
standard_testfile
|
||||||
|
if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile} \
|
||||||
|
[list debug additional_flags=-march=armv9.3-a]] } {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
# If the inferior is rescheduled to another CPU while a main or epilogue
|
||||||
|
# instruction is executed, the OS resets the inferior back to the prologue
|
||||||
|
# instruction, so we need to allow for that possibility.
|
||||||
|
proc step_through_sequence { prefix } {
|
||||||
|
set count 0
|
||||||
|
|
||||||
|
while { [is_at_instruction ${prefix}p] == 1 && $count < 50 } {
|
||||||
|
incr count
|
||||||
|
|
||||||
|
# The stepi output isn't useful to detect whether we stepped over
|
||||||
|
# the instruction.
|
||||||
|
gdb_test "stepi" "\[^\r\n\]+" "step over ${prefix}p"
|
||||||
|
if { [is_at_instruction ${prefix}m] == 1 } {
|
||||||
|
pass "stepped over ${prefix}p"
|
||||||
|
} else {
|
||||||
|
fail "stepped over ${prefix}e"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
gdb_test "stepi" "\[^\r\n\]+" "step over ${prefix}m"
|
||||||
|
if { [is_at_instruction ${prefix}e] == 1 } {
|
||||||
|
pass "stepped over ${prefix}m"
|
||||||
|
} elseif { [is_at_instruction ${prefix}p] == 1 } {
|
||||||
|
# The inferior was rescheduled to another CPU.
|
||||||
|
pass "${prefix}m: reset back to prologue"
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
fail "stepped over ${prefix}m"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
gdb_test "stepi" "\[^\r\n\]+" "step over ${prefix}e"
|
||||||
|
if { [is_at_instruction prfm] == 1 } {
|
||||||
|
pass "stepped over ${prefix}e"
|
||||||
|
return 1
|
||||||
|
} elseif { [is_at_instruction ${prefix}p] == 1 } {
|
||||||
|
# The inferior was rescheduled to another CPU.
|
||||||
|
pass "${prefix}e: reset back to prologue"
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fail "step through $prefix sequence"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if ![runto_main] {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
gdb_breakpoint ${srcfile}:[gdb_get_line_number "Break memset"]
|
||||||
|
gdb_breakpoint ${srcfile}:[gdb_get_line_number "Break memcpy"]
|
||||||
|
gdb_breakpoint ${srcfile}:[gdb_get_line_number "Break memmove"]
|
||||||
|
|
||||||
|
gdb_continue_to_breakpoint "memset breakpoint"
|
||||||
|
|
||||||
|
if { [arrive_at_instruction setp] } {
|
||||||
|
step_through_sequence set
|
||||||
|
}
|
||||||
|
|
||||||
|
gdb_continue_to_breakpoint "memcpy breakpoint"
|
||||||
|
|
||||||
|
if { [arrive_at_instruction cpyfp] } {
|
||||||
|
step_through_sequence cpyf
|
||||||
|
}
|
||||||
|
|
||||||
|
gdb_continue_to_breakpoint "memmove breakpoint"
|
||||||
|
|
||||||
|
if { [arrive_at_instruction cpyp] } {
|
||||||
|
step_through_sequence cpy
|
||||||
|
}
|
||||||
66
gdb/testsuite/gdb.arch/aarch64-mops-watchpoint.c
Normal file
66
gdb/testsuite/gdb.arch/aarch64-mops-watchpoint.c
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
/* This test program is part of GDB, the GNU debugger.
|
||||||
|
|
||||||
|
Copyright 2024 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
int
|
||||||
|
main (void)
|
||||||
|
{
|
||||||
|
char source[40] __attribute__ ((aligned (8)))
|
||||||
|
= "This is a relatively long string...";
|
||||||
|
char a[40] __attribute__ ((aligned (8)))
|
||||||
|
= "String to be overwritten with zeroes";
|
||||||
|
char b[40] __attribute__ ((aligned (8)))
|
||||||
|
= "Another string to be memcopied...";
|
||||||
|
char c[40] __attribute__ ((aligned (8)))
|
||||||
|
= "Another string to be memmoved...";
|
||||||
|
char *p, *q;
|
||||||
|
long size, zero;
|
||||||
|
|
||||||
|
/* Break here. */
|
||||||
|
p = a;
|
||||||
|
size = sizeof (a);
|
||||||
|
zero = 0;
|
||||||
|
/* memset implemented in MOPS instructions. */
|
||||||
|
__asm__ volatile ("setp [%0]!, %1!, %2\n\t"
|
||||||
|
"setm [%0]!, %1!, %2\n\t"
|
||||||
|
"sete [%0]!, %1!, %2\n\t"
|
||||||
|
: "+&r"(p), "+&r"(size)
|
||||||
|
: "r"(zero)
|
||||||
|
: "memory");
|
||||||
|
|
||||||
|
p = b;
|
||||||
|
q = source;
|
||||||
|
size = sizeof (b);
|
||||||
|
/* memmove implemented in MOPS instructions. */
|
||||||
|
__asm__ volatile ("cpyp [%0]!, [%1]!, %2!\n\t"
|
||||||
|
"cpym [%0]!, [%1]!, %2!\n\t"
|
||||||
|
"cpye [%0]!, [%1]!, %2!\n\t"
|
||||||
|
: "+&r" (p), "+&r" (q), "+&r" (size)
|
||||||
|
:
|
||||||
|
: "memory");
|
||||||
|
p = c;
|
||||||
|
q = source;
|
||||||
|
size = sizeof (c);
|
||||||
|
/* memcpy implemented in MOPS instructions. */
|
||||||
|
__asm__ volatile ("cpyfp [%0]!, [%1]!, %2!\n\t"
|
||||||
|
"cpyfm [%0]!, [%1]!, %2!\n\t"
|
||||||
|
"cpyfe [%0]!, [%1]!, %2!\n\t"
|
||||||
|
: "+&r" (p), "+&r" (q), "+&r" (size)
|
||||||
|
:
|
||||||
|
: "memory");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
79
gdb/testsuite/gdb.arch/aarch64-mops-watchpoint.exp
Normal file
79
gdb/testsuite/gdb.arch/aarch64-mops-watchpoint.exp
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
# Copyright 2024 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# Test a binary that uses MOPS (Memory Operations) instructions.
|
||||||
|
# This test is similar to gdb.base/memops-watchpoint.exp, but specifically
|
||||||
|
# tests MOPS instructions rather than whatever instructions are used in the
|
||||||
|
# system libc's implementation of memset/memcpy/memmove.
|
||||||
|
|
||||||
|
require allow_hw_watchpoint_tests allow_aarch64_mops_tests
|
||||||
|
|
||||||
|
standard_testfile
|
||||||
|
|
||||||
|
if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile} \
|
||||||
|
[list debug additional_flags=-march=armv9.3-a]] } {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
set linespec ${srcfile}:[gdb_get_line_number "Break here"]
|
||||||
|
if ![runto ${linespec}] {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
gdb_test "watch -location a\[28\]" \
|
||||||
|
"(Hardware w|W)atchpoint ${decimal}: -location a\\\[28\\\]" \
|
||||||
|
"set watch on a"
|
||||||
|
gdb_test "watch -location b\[28\]" \
|
||||||
|
"(Hardware w|W)atchpoint ${decimal}: -location b\\\[28\\\]" \
|
||||||
|
"set watchpoint on b"
|
||||||
|
gdb_test "watch -location c\[28\]" \
|
||||||
|
"(Hardware w|W)atchpoint ${decimal}: -location c\\\[28\\\]" \
|
||||||
|
"set watchpoint on c"
|
||||||
|
|
||||||
|
gdb_test "continue" \
|
||||||
|
[multi_line \
|
||||||
|
"Continuing\\." \
|
||||||
|
"" \
|
||||||
|
"Hardware watchpoint ${decimal}: -location a\\\[28\\\]" \
|
||||||
|
"" \
|
||||||
|
"Old value = 104 'h'" \
|
||||||
|
"New value = 0 '\\\\000'" \
|
||||||
|
"$hex in main \\(\\) at .*aarch64-mops-watchpoint.c:$decimal" \
|
||||||
|
"${decimal}\\s+__asm__ volatile \\(\"setp.*\\\\n\\\\t\""] \
|
||||||
|
"continue until set watchpoint hits"
|
||||||
|
|
||||||
|
gdb_test "continue" \
|
||||||
|
[multi_line \
|
||||||
|
"Continuing\\." \
|
||||||
|
"" \
|
||||||
|
"Hardware watchpoint ${decimal}: -location b\\\[28\\\]" \
|
||||||
|
"" \
|
||||||
|
"Old value = 101 'e'" \
|
||||||
|
"New value = 114 'r'" \
|
||||||
|
"$hex in main \\(\\) at .*aarch64-mops-watchpoint.c:$decimal" \
|
||||||
|
"${decimal}\\s+__asm__ volatile \\(\"cpyp.*\\\\n\\\\t\""] \
|
||||||
|
"continue until cpy watchpoint hits"
|
||||||
|
|
||||||
|
gdb_test "continue" \
|
||||||
|
[multi_line \
|
||||||
|
"Continuing\\." \
|
||||||
|
"" \
|
||||||
|
"Hardware watchpoint ${decimal}: -location c\\\[28\\\]" \
|
||||||
|
"" \
|
||||||
|
"Old value = 100 'd'" \
|
||||||
|
"New value = 114 'r'" \
|
||||||
|
"$hex in main \\(\\) at .*aarch64-mops-watchpoint.c:$decimal" \
|
||||||
|
"${decimal}\\s+__asm__ volatile \\(\"cpyfp.*\\\\n\\\\t\""] \
|
||||||
|
"continue until cpyf watchpoint hits"
|
||||||
@@ -123,10 +123,12 @@ proc make_val_cast {lang signed bits val} {
|
|||||||
return "$val as ${sign_prefix}$bits"
|
return "$val as ${sign_prefix}$bits"
|
||||||
} else {
|
} else {
|
||||||
# C-like cast.
|
# C-like cast.
|
||||||
if {$signed} {
|
if {!$signed} {
|
||||||
|
set sign_prefix "unsigned "
|
||||||
|
} elseif {$lang == "opencl"} {
|
||||||
set sign_prefix ""
|
set sign_prefix ""
|
||||||
} else {
|
} else {
|
||||||
set sign_prefix "un"
|
set sign_prefix "signed "
|
||||||
}
|
}
|
||||||
if {$bits == 8} {
|
if {$bits == 8} {
|
||||||
set type "char"
|
set type "char"
|
||||||
@@ -143,7 +145,7 @@ proc make_val_cast {lang signed bits val} {
|
|||||||
} else {
|
} else {
|
||||||
error "$lang: unsupported bits"
|
error "$lang: unsupported bits"
|
||||||
}
|
}
|
||||||
return "(${sign_prefix}signed $type) $val"
|
return "(${sign_prefix}$type) $val"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -178,7 +180,7 @@ proc test_shifts {} {
|
|||||||
"unknown" "ada" "modula-2" "pascal" "fortran"
|
"unknown" "ada" "modula-2" "pascal" "fortran"
|
||||||
}
|
}
|
||||||
if {[lsearch -exact $skip_langs $lang] >= 0} {
|
if {[lsearch -exact $skip_langs $lang] >= 0} {
|
||||||
return
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
gdb_test_no_output "set language $lang"
|
gdb_test_no_output "set language $lang"
|
||||||
@@ -344,8 +346,11 @@ proc test_shifts {} {
|
|||||||
with_test_prefix "rsh neg lhs" {
|
with_test_prefix "rsh neg lhs" {
|
||||||
test_shift $lang "print -1 >> 0" " = -1"
|
test_shift $lang "print -1 >> 0" " = -1"
|
||||||
test_shift $lang "print -1 >> 1" " = -1"
|
test_shift $lang "print -1 >> 1" " = -1"
|
||||||
|
test_shift $lang "print -2 >> 1" " = -1"
|
||||||
|
test_shift $lang "print -3 >> 1" " = -2"
|
||||||
test_shift $lang "print -8 >> 1" " = -4"
|
test_shift $lang "print -8 >> 1" " = -4"
|
||||||
test_shift $lang "print [make_int64 $lang -8] >> 1" " = -4"
|
test_shift $lang "print [make_int64 $lang -8] >> 1" " = -4"
|
||||||
|
test_rshift_tl $lang "print -8 >> 100" " = -1"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Make sure an unsigned 64-bit value with high bit set isn't
|
# Make sure an unsigned 64-bit value with high bit set isn't
|
||||||
@@ -360,6 +365,18 @@ proc test_shifts {} {
|
|||||||
test_rshift_tl $lang \
|
test_rshift_tl $lang \
|
||||||
"print -1 >> [make_uint64 $lang 0xffffffffffffffff]" " = -1"
|
"print -1 >> [make_uint64 $lang 0xffffffffffffffff]" " = -1"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Check if shift value isn't silently truncated to 32bit.
|
||||||
|
with_test_prefix "lower-32bit-zero" {
|
||||||
|
test_lshift_tl $lang \
|
||||||
|
"print 1 << [make_uint64 $lang 0x100000000]" " = 0"
|
||||||
|
test_rshift_tl $lang \
|
||||||
|
"print 1 >> [make_uint64 $lang 0x100000000]" " = 0"
|
||||||
|
test_lshift_tl $lang \
|
||||||
|
"print -1 << [make_uint64 $lang 0x100000000]" " = 0"
|
||||||
|
test_rshift_tl $lang \
|
||||||
|
"print -1 >> [make_uint64 $lang 0x100000000]" " = -1"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -692,7 +692,7 @@ set show_conv_list \
|
|||||||
{$_gdb_setting_str = <internal function _gdb_setting_str>} \
|
{$_gdb_setting_str = <internal function _gdb_setting_str>} \
|
||||||
{$_gdb_setting = <internal function _gdb_setting>} \
|
{$_gdb_setting = <internal function _gdb_setting>} \
|
||||||
{$_gdb_major = 15} \
|
{$_gdb_major = 15} \
|
||||||
{$_gdb_minor = 1} \
|
{$_gdb_minor = 3} \
|
||||||
{$_shell_exitsignal = void} \
|
{$_shell_exitsignal = void} \
|
||||||
{$_shell_exitcode = 0} \
|
{$_shell_exitcode = 0} \
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,6 +41,8 @@ int large_2d_array[][10] = {
|
|||||||
{90, 91, 92, 93, 94, 95, 96, 97, 98, 99}
|
{90, 91, 92, 93, 94, 95, 96, 97, 98, 99}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
char large_empty_string[100000] = "";
|
||||||
|
|
||||||
int
|
int
|
||||||
main ()
|
main ()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -240,3 +240,13 @@ with_test_prefix "with unlimited print elements" {
|
|||||||
"value is not available" \
|
"value is not available" \
|
||||||
"output expression referring unavailable element from history"
|
"output expression referring unavailable element from history"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gdb_test_no_output "set max-value-size 10000"
|
||||||
|
gdb_test_no_output "set print elements 200"
|
||||||
|
|
||||||
|
gdb_test "print large_empty_string" \
|
||||||
|
" = \\\{0 '\\\\000' <repeats 10000 times>, <unavailable> <repeats 90000 times>\\\}" \
|
||||||
|
"print large empty string which is not fully available"
|
||||||
|
gdb_test -nonl "output large_empty_string" \
|
||||||
|
"\\\{0 '\\\\000' <repeats 10000 times>, <unavailable> <repeats 90000 times>\\\}" \
|
||||||
|
"output large empty string which is not fully available"
|
||||||
|
|||||||
35
gdb/testsuite/gdb.dwarf2/enum-type-c++.cc
Normal file
35
gdb/testsuite/gdb.dwarf2/enum-type-c++.cc
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
/* This testcase is part of GDB, the GNU debugger.
|
||||||
|
|
||||||
|
Copyright 2024 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
namespace ns {
|
||||||
|
|
||||||
|
class A {
|
||||||
|
public:
|
||||||
|
enum {
|
||||||
|
val1 = 1
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class ec
|
||||||
|
{
|
||||||
|
val2 = 2,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
int u1 = ns::A::val1;
|
||||||
|
|
||||||
|
int u2 = (int)ns::ec::val2;
|
||||||
54
gdb/testsuite/gdb.dwarf2/enum-type-c++.exp
Normal file
54
gdb/testsuite/gdb.dwarf2/enum-type-c++.exp
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
# Copyright 2024 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
require !readnow
|
||||||
|
|
||||||
|
load_lib dwarf.exp
|
||||||
|
|
||||||
|
# This test can only be run on targets which support DWARF-2 and use gas.
|
||||||
|
require dwarf2_support
|
||||||
|
|
||||||
|
standard_testfile main.c .cc
|
||||||
|
|
||||||
|
if { [prepare_for_testing "failed to prepare" $testfile \
|
||||||
|
[list $srcfile $srcfile2] {debug c++}] } {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
require {string equal [have_index $binfile] ""}
|
||||||
|
|
||||||
|
set re_ws "\[ \t\]"
|
||||||
|
|
||||||
|
# Regression test for PR31900.
|
||||||
|
set val1 ns::A::val1
|
||||||
|
gdb_test_lines "maint print objfiles" \
|
||||||
|
"val1 has a parent" \
|
||||||
|
[multi_line \
|
||||||
|
"" \
|
||||||
|
"$re_ws+qualified:$re_ws+$val1" \
|
||||||
|
".*"]
|
||||||
|
|
||||||
|
gdb_test "print $val1" " = $val1"
|
||||||
|
|
||||||
|
# Regression test for PR32158.
|
||||||
|
set val2 ns::ec::val2
|
||||||
|
gdb_test_lines "maint print objfiles" \
|
||||||
|
"val2 has correct parent" \
|
||||||
|
[multi_line \
|
||||||
|
"" \
|
||||||
|
"$re_ws+qualified:$re_ws+$val2" \
|
||||||
|
".*"]
|
||||||
|
|
||||||
|
gdb_test "print $val2" " = $val2"
|
||||||
@@ -65,6 +65,41 @@ Dwarf::assemble $asm_file {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cu {} {
|
||||||
|
DW_TAG_compile_unit {
|
||||||
|
{DW_AT_language @DW_LANG_C_plus_plus}
|
||||||
|
{DW_AT_name tmp.c}
|
||||||
|
{DW_AT_comp_dir /tmp}
|
||||||
|
} {
|
||||||
|
declare_labels integer_label forward
|
||||||
|
|
||||||
|
integer_label: DW_TAG_base_type {
|
||||||
|
{DW_AT_byte_size 4 DW_FORM_sdata}
|
||||||
|
{DW_AT_encoding @DW_ATE_signed}
|
||||||
|
{DW_AT_name int}
|
||||||
|
}
|
||||||
|
|
||||||
|
DW_TAG_enumeration_type {
|
||||||
|
{DW_AT_specification :$forward}
|
||||||
|
} {
|
||||||
|
DW_TAG_enumerator {
|
||||||
|
{DW_AT_name val1}
|
||||||
|
{DW_AT_const_value 1 DW_FORM_sdata}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DW_TAG_namespace {
|
||||||
|
{DW_AT_name ns}
|
||||||
|
} {
|
||||||
|
forward: DW_TAG_enumeration_type {
|
||||||
|
{DW_AT_name e}
|
||||||
|
{DW_AT_type :$integer_label}
|
||||||
|
{DW_AT_declaration 1 flag}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if { [prepare_for_testing "failed to prepare" ${testfile} \
|
if { [prepare_for_testing "failed to prepare" ${testfile} \
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ proc py_remove_all_disassemblers {} {
|
|||||||
#
|
#
|
||||||
# Each different disassembler tests some different feature of the
|
# Each different disassembler tests some different feature of the
|
||||||
# Python disassembler API.
|
# Python disassembler API.
|
||||||
set nop "(nop|nop\t0)"
|
set nop "(nop|nop\t0|[string_to_regexp nop\t{0}])"
|
||||||
set unknown_error_pattern "unknown disassembler error \\(error = -1\\)"
|
set unknown_error_pattern "unknown disassembler error \\(error = -1\\)"
|
||||||
set addr_pattern "\r\n=> ${curr_pc_pattern} <\[^>\]+>:\\s+"
|
set addr_pattern "\r\n=> ${curr_pc_pattern} <\[^>\]+>:\\s+"
|
||||||
set base_pattern "${addr_pattern}${nop}"
|
set base_pattern "${addr_pattern}${nop}"
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ def check_building_disassemble_result():
|
|||||||
|
|
||||||
|
|
||||||
def is_nop(s):
|
def is_nop(s):
|
||||||
return s == "nop" or s == "nop\t0"
|
return s == "nop" or s == "nop\t0" or s == "nop\t{0}"
|
||||||
|
|
||||||
|
|
||||||
# Remove all currently registered disassemblers.
|
# Remove all currently registered disassemblers.
|
||||||
|
|||||||
@@ -118,6 +118,11 @@ main ()
|
|||||||
c.a_method (0, 1);
|
c.a_method (0, 1);
|
||||||
c.a_const_method (0, 1);
|
c.a_const_method (0, 1);
|
||||||
C::a_static_method (0, 1);
|
C::a_static_method (0, 1);
|
||||||
|
|
||||||
|
struct Local { int g; } l;
|
||||||
|
l.g = 5;
|
||||||
|
typedef int IntType;
|
||||||
|
IntType it = 6;
|
||||||
#endif
|
#endif
|
||||||
enum E e;
|
enum E e;
|
||||||
|
|
||||||
|
|||||||
@@ -85,6 +85,12 @@ proc test_fields {lang} {
|
|||||||
gdb_test "python print (gdb.parse_and_eval ('C::a_static_method').type.fields ()\[0\].type)" "int"
|
gdb_test "python print (gdb.parse_and_eval ('C::a_static_method').type.fields ()\[0\].type)" "int"
|
||||||
gdb_test "python print (gdb.parse_and_eval ('C::a_static_method').type.fields ()\[1\].type)" "char"
|
gdb_test "python print (gdb.parse_and_eval ('C::a_static_method').type.fields ()\[1\].type)" "char"
|
||||||
gdb_test "python print (gdb.parse_and_eval ('c')\['a_static_method'\].type.fields ()\[0\].type)" "int"
|
gdb_test "python print (gdb.parse_and_eval ('c')\['a_static_method'\].type.fields ()\[0\].type)" "int"
|
||||||
|
|
||||||
|
# Test function-local types.
|
||||||
|
gdb_test "python print (gdb.lookup_type ('main()::Local'))" "Local"
|
||||||
|
gdb_test "python print (gdb.lookup_type ('main()::Local').fields ()\[0\].type)" "int"
|
||||||
|
gdb_test "python print (gdb.lookup_type ('main()::IntType'))" "IntType"
|
||||||
|
gdb_test "python print (gdb.lookup_type ('main()::IntType').target ())" "int"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Test normal fields usage in structs.
|
# Test normal fields usage in structs.
|
||||||
|
|||||||
69
gdb/testsuite/gdb.python/sys-exit.exp
Normal file
69
gdb/testsuite/gdb.python/sys-exit.exp
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
# Copyright 2024 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# Check that python sys.exit makes gdb exit, with the correct exit status.
|
||||||
|
|
||||||
|
require allow_python_tests
|
||||||
|
|
||||||
|
# Have this code in a proc avoids clashing with runtest variable exit_status.
|
||||||
|
|
||||||
|
proc do_test { n {expected_exit_status ""} {msg ""}} {
|
||||||
|
if { $expected_exit_status == "" } {
|
||||||
|
set expected_exit_status $n
|
||||||
|
}
|
||||||
|
|
||||||
|
with_test_prefix $n {
|
||||||
|
clean_restart
|
||||||
|
|
||||||
|
# Regression test for PR python/31946.
|
||||||
|
set seen_message 0
|
||||||
|
gdb_test_multiple "python sys.exit ($n)" "python sys.exit" {
|
||||||
|
-re "\r\n$msg\r\n" {
|
||||||
|
set seen_message 1
|
||||||
|
exp_continue
|
||||||
|
}
|
||||||
|
eof {
|
||||||
|
set wait_status [wait -i $::gdb_spawn_id]
|
||||||
|
clear_gdb_spawn_id
|
||||||
|
|
||||||
|
verbose -log "GDB process exited with wait status $wait_status"
|
||||||
|
|
||||||
|
set os_error [lindex $wait_status 2]
|
||||||
|
set exit_status [lindex $wait_status 3]
|
||||||
|
|
||||||
|
gdb_assert \
|
||||||
|
{ $os_error == 0 \
|
||||||
|
&& $exit_status == $expected_exit_status } \
|
||||||
|
$gdb_test_name
|
||||||
|
|
||||||
|
if { $msg != "" } {
|
||||||
|
gdb_assert { $seen_message }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Test sys.exit (<int>).
|
||||||
|
do_test 0
|
||||||
|
do_test 1
|
||||||
|
do_test 2
|
||||||
|
|
||||||
|
# Test sys.exit (None).
|
||||||
|
do_test None 0
|
||||||
|
|
||||||
|
# Test sys.exit (<string>).
|
||||||
|
do_test {"Error Message"} 1 "Error Message"
|
||||||
|
do_test {""} 1
|
||||||
78
gdb/testsuite/gdb.reverse/aarch64-mops.c
Normal file
78
gdb/testsuite/gdb.reverse/aarch64-mops.c
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
/* This test program is part of GDB, the GNU debugger.
|
||||||
|
|
||||||
|
Copyright 2024 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define INITIAL_STRING "Initial fill value."
|
||||||
|
#define NEW_STRING "Just a test string."
|
||||||
|
#define BUF_SIZE sizeof(NEW_STRING)
|
||||||
|
|
||||||
|
int
|
||||||
|
main (void)
|
||||||
|
{
|
||||||
|
char dest[BUF_SIZE] = INITIAL_STRING;
|
||||||
|
char source[BUF_SIZE] = NEW_STRING;
|
||||||
|
register char *p asm ("x19");
|
||||||
|
register char *q asm ("x20");
|
||||||
|
register long size asm ("x21");
|
||||||
|
register long zero asm ("x22");
|
||||||
|
|
||||||
|
p = dest;
|
||||||
|
size = BUF_SIZE;
|
||||||
|
zero = 0;
|
||||||
|
/* Before setp. */
|
||||||
|
/* memset implemented in MOPS instructions. */
|
||||||
|
__asm__ volatile ("setp [%0]!, %1!, %2\n\t"
|
||||||
|
"setm [%0]!, %1!, %2\n\t"
|
||||||
|
"sete [%0]!, %1!, %2\n\t"
|
||||||
|
: "+&r"(p), "+&r"(size)
|
||||||
|
: "r"(zero)
|
||||||
|
: "memory");
|
||||||
|
|
||||||
|
/* After sete. */
|
||||||
|
p = dest;
|
||||||
|
q = source;
|
||||||
|
size = BUF_SIZE;
|
||||||
|
memcpy (dest, INITIAL_STRING, sizeof (dest));
|
||||||
|
/* Before cpyp. */
|
||||||
|
/* memmove implemented in MOPS instructions. */
|
||||||
|
__asm__ volatile ("cpyp [%0]!, [%1]!, %2!\n\t"
|
||||||
|
"cpym [%0]!, [%1]!, %2!\n\t"
|
||||||
|
"cpye [%0]!, [%1]!, %2!\n\t"
|
||||||
|
: "+&r" (p), "+&r" (q), "+&r" (size)
|
||||||
|
:
|
||||||
|
: "memory");
|
||||||
|
|
||||||
|
/* After cpye. */
|
||||||
|
p = dest;
|
||||||
|
q = source;
|
||||||
|
size = BUF_SIZE;
|
||||||
|
memcpy (dest, INITIAL_STRING, sizeof (dest));
|
||||||
|
/* Before cpyfp. */
|
||||||
|
/* memcpy implemented in MOPS instructions. */
|
||||||
|
__asm__ volatile ("cpyfp [%0]!, [%1]!, %2!\n\t"
|
||||||
|
"cpyfm [%0]!, [%1]!, %2!\n\t"
|
||||||
|
"cpyfe [%0]!, [%1]!, %2!\n\t"
|
||||||
|
: "+&r" (p), "+&r" (q), "+&r" (size)
|
||||||
|
:
|
||||||
|
: "memory");
|
||||||
|
|
||||||
|
/* After cpyfe. */
|
||||||
|
p = dest;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
186
gdb/testsuite/gdb.reverse/aarch64-mops.exp
Normal file
186
gdb/testsuite/gdb.reverse/aarch64-mops.exp
Normal file
@@ -0,0 +1,186 @@
|
|||||||
|
# Copyright 2024 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# Test instruction record for AArch64 FEAT_MOPS instructions.
|
||||||
|
# Based on gdb.reverse/ppc_record_test_isa_3_1.exp
|
||||||
|
#
|
||||||
|
# The basic flow of the record tests are:
|
||||||
|
# 1) Stop before executing the instructions of interest. Record
|
||||||
|
# the initial value of the registers that the instruction will
|
||||||
|
# change, i.e. the destination register.
|
||||||
|
# 2) Execute the instructions. Record the new value of the
|
||||||
|
# registers that changed.
|
||||||
|
# 3) Reverse the direction of the execution and execute back to
|
||||||
|
# just before the instructions of interest. Record the final
|
||||||
|
# value of the registers of interest.
|
||||||
|
# 4) Check that the initial and new values of the registers are
|
||||||
|
# different, i.e. the instruction changed the registers as expected.
|
||||||
|
# 5) Check that the initial and final values of the registers are
|
||||||
|
# the same, i.e. GDB record restored the registers to their
|
||||||
|
# original values.
|
||||||
|
|
||||||
|
require allow_aarch64_mops_tests
|
||||||
|
|
||||||
|
standard_testfile
|
||||||
|
|
||||||
|
if { [prepare_for_testing "failed to prepare" ${testfile} ${srcfile} \
|
||||||
|
[list debug additional_flags=-march=armv9.3-a]] } {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
if ![runto_main] {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
gdb_test_no_output "record full"
|
||||||
|
|
||||||
|
foreach_with_prefix insn_prefix {"set" "cpy" "cpyf"} {
|
||||||
|
global decimal hex
|
||||||
|
|
||||||
|
set before_seq [gdb_get_line_number "Before ${insn_prefix}p"]
|
||||||
|
set after_seq [gdb_get_line_number "After ${insn_prefix}e"]
|
||||||
|
|
||||||
|
gdb_test "break $before_seq" \
|
||||||
|
"Breakpoint $decimal at $hex: file .*/aarch64-mops.c, line $decimal\\." \
|
||||||
|
"break before instruction sequence"
|
||||||
|
gdb_continue_to_breakpoint "about to execute instruction sequence" \
|
||||||
|
[multi_line ".*/aarch64-mops.c:$decimal" \
|
||||||
|
"$decimal\[ \t\]+__asm__ volatile \\(\"${insn_prefix}p \[^\r\n\]+\""]
|
||||||
|
|
||||||
|
# Depending on the compiler, the line number information may put GDB a few
|
||||||
|
# instructions before the beginning of the asm statement.
|
||||||
|
arrive_at_instruction "${insn_prefix}p"
|
||||||
|
# Add a breakpoint that we're sure is at the prologue instruction.
|
||||||
|
gdb_test "break *\$pc" \
|
||||||
|
"Breakpoint $decimal at $hex: file .*/aarch64-mops.c, line $decimal\\." \
|
||||||
|
"break at prologue instruction"
|
||||||
|
|
||||||
|
# Record the initial memory and register values.
|
||||||
|
set dest_initial [get_valueof "/x" "dest" "unable to read initial" \
|
||||||
|
"get dest initial value"]
|
||||||
|
set x19_initial [capture_command_output "info register x19" ""]
|
||||||
|
set x21_initial [capture_command_output "info register x21" ""]
|
||||||
|
|
||||||
|
# The set instructions use the ZERO variable, but not Q nor SOURCE,
|
||||||
|
# and the other instructions are the opposite.
|
||||||
|
if {[string compare $insn_prefix "set"] == 0} {
|
||||||
|
set x22_initial [capture_command_output "info register x22" ""]
|
||||||
|
} else {
|
||||||
|
set x20_initial [capture_command_output "info register x20" ""]
|
||||||
|
set source_initial [get_valueof "/x" "source" "unable to read initial" \
|
||||||
|
"get source initial value"]
|
||||||
|
}
|
||||||
|
|
||||||
|
gdb_test "break $after_seq" \
|
||||||
|
"Breakpoint $decimal at $hex: file .*/aarch64-mops.c, line $decimal\\." \
|
||||||
|
"break after instruction sequence"
|
||||||
|
gdb_continue_to_breakpoint "executed instruction sequence" \
|
||||||
|
[multi_line ".*/aarch64-mops.c:$decimal" "$decimal\[ \t\]+p = dest;"]
|
||||||
|
|
||||||
|
# Record the new memory and register values.
|
||||||
|
set dest_new [get_valueof "/x" "dest" "unable to read new" \
|
||||||
|
"get dest new value"]
|
||||||
|
set x19_new [capture_command_output "info register x19" ""]
|
||||||
|
set x21_new [capture_command_output "info register x21" ""]
|
||||||
|
|
||||||
|
if {[string compare $insn_prefix "set"] == 0} {
|
||||||
|
set x22_new [capture_command_output "info register x22" ""]
|
||||||
|
} else {
|
||||||
|
set x20_new [capture_command_output "info register x20" ""]
|
||||||
|
set source_new [get_valueof "/x" "source" "unable to read new" \
|
||||||
|
"get source new value"]
|
||||||
|
}
|
||||||
|
|
||||||
|
# Execute in reverse to before the instruction sequence.
|
||||||
|
gdb_test_no_output "set exec-direction reverse"
|
||||||
|
|
||||||
|
gdb_continue_to_breakpoint "reversed execution of instruction sequence" \
|
||||||
|
[multi_line ".*/aarch64-mops.c:$decimal" \
|
||||||
|
"$decimal\[ \t\]+__asm__ volatile \\(\"${insn_prefix}p \[^\r\n\]+\""]
|
||||||
|
|
||||||
|
# Record the final memory and register values.
|
||||||
|
set dest_final [get_valueof "/x" "dest" "unable to read final" \
|
||||||
|
"get dest final value"]
|
||||||
|
set x19_final [capture_command_output "info register x19" ""]
|
||||||
|
set x21_final [capture_command_output "info register x21" ""]
|
||||||
|
|
||||||
|
if {[string compare $insn_prefix "set"] == 0} {
|
||||||
|
set x22_final [capture_command_output "info register x22" ""]
|
||||||
|
} else {
|
||||||
|
set x20_final [capture_command_output "info register x20" ""]
|
||||||
|
set source_final [get_valueof "/x" "source" "unable to read final" \
|
||||||
|
"get source final value"]
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check initial and new values of dest are different.
|
||||||
|
gdb_assert [string compare $dest_initial $dest_new] \
|
||||||
|
"check dest initial value versus dest new value"
|
||||||
|
|
||||||
|
# Check initial and new values of x19 are different.
|
||||||
|
gdb_assert [string compare $x19_initial $x19_new] \
|
||||||
|
"check x19 initial value versus x19 new value"
|
||||||
|
|
||||||
|
# Check initial and new values of x21 are different.
|
||||||
|
gdb_assert [string compare $x21_initial $x21_new] \
|
||||||
|
"check x21 initial value versus x21 new value"
|
||||||
|
|
||||||
|
if {[string compare $insn_prefix "set"] == 0} {
|
||||||
|
# Check initial and new values of x22 are the same.
|
||||||
|
# The register with the value to set shouldn't change.
|
||||||
|
gdb_assert ![string compare $x22_initial $x22_new] \
|
||||||
|
"check x22 initial value versus x22 new value"
|
||||||
|
} else {
|
||||||
|
# Check initial and new values of x20 are different.
|
||||||
|
gdb_assert [string compare $x20_initial $x20_new] \
|
||||||
|
"check x20 initial value versus x20 new value"
|
||||||
|
# Check initial and new values of source are the same.
|
||||||
|
gdb_assert ![string compare $source_initial $source_new] \
|
||||||
|
"check source initial value versus source new value"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check initial and final values of dest are the same.
|
||||||
|
gdb_assert ![string compare $dest_initial $dest_final] \
|
||||||
|
"check dest initial value versus dest final value"
|
||||||
|
|
||||||
|
# Check initial and final values of x19 are the same.
|
||||||
|
gdb_assert ![string compare $x19_initial $x19_final] \
|
||||||
|
"check x19 initial value versus x19 final value"
|
||||||
|
|
||||||
|
# Check initial and final values of x21 are the same.
|
||||||
|
gdb_assert ![string compare $x21_initial $x21_final] \
|
||||||
|
"check x21 initial value versus x21 final value"
|
||||||
|
|
||||||
|
if {[string compare $insn_prefix "set"] == 0} {
|
||||||
|
# Check initial and final values of x22 are the same.
|
||||||
|
gdb_assert ![string compare $x22_initial $x22_final] \
|
||||||
|
"check x22 initial value versus x22 final value"
|
||||||
|
} else {
|
||||||
|
# Check initial and final values of x20 are the same.
|
||||||
|
gdb_assert ![string compare $x20_initial $x20_final] \
|
||||||
|
"check x20 initial value versus x20 final value"
|
||||||
|
|
||||||
|
# Check initial and final values of source are the same.
|
||||||
|
gdb_assert ![string compare $source_initial $source_final] \
|
||||||
|
"check source initial value versus source final value"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Restore forward execution and go to end of recording.
|
||||||
|
gdb_test_no_output "set exec-direction forward"
|
||||||
|
gdb_test "record goto end" \
|
||||||
|
[multi_line \
|
||||||
|
"Go forward to insn number $decimal" \
|
||||||
|
"#0 main \\(\\) at .*/aarch64-mops.c:$decimal" \
|
||||||
|
"$decimal\[ \t\]+p = dest;"]
|
||||||
|
}
|
||||||
@@ -69,6 +69,8 @@ with_timeout_factor 10 {
|
|||||||
gdb_test "kill" "" "kill process, prepare to debug log file" \
|
gdb_test "kill" "" "kill process, prepare to debug log file" \
|
||||||
"Kill the program being debugged\\? \\(y or n\\) " "y"
|
"Kill the program being debugged\\? \\(y or n\\) " "y"
|
||||||
|
|
||||||
|
clean_restart ${binfile}
|
||||||
|
|
||||||
gdb_test "record restore $precsave" \
|
gdb_test "record restore $precsave" \
|
||||||
"Restored records from core file .*" \
|
"Restored records from core file .*" \
|
||||||
"reload core file"
|
"reload core file"
|
||||||
|
|||||||
@@ -848,6 +848,44 @@ proc gdb_continue_to_breakpoint {name {location_pattern .*}} {
|
|||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Check whether GDB is stopped at the given instruction.
|
||||||
|
# INSTRUCTION should be just its mnemonic, without any arguments.
|
||||||
|
|
||||||
|
proc is_at_instruction { instruction } {
|
||||||
|
global gdb_prompt hex
|
||||||
|
|
||||||
|
set test "pc points to $instruction"
|
||||||
|
gdb_test_multiple {x/i $pc} $test {
|
||||||
|
-re -wrap "=> $hex \[^\r\n\]+:\t$instruction\t\[^\r\n\]+" {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
-re "\r\n$gdb_prompt $" {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# Single-steps GDB until it arrives at the given instruction.
|
||||||
|
# INSTRUCTION should be just its mnemonic, without any arguments.
|
||||||
|
|
||||||
|
proc arrive_at_instruction { instruction } {
|
||||||
|
set count 0
|
||||||
|
|
||||||
|
while { [is_at_instruction $instruction] != 1 } {
|
||||||
|
gdb_test -nopass "stepi" "\[^\r\n\]+" \
|
||||||
|
"stepi #$count to reach $instruction"
|
||||||
|
incr count
|
||||||
|
|
||||||
|
if { $count > 50 } {
|
||||||
|
fail "didn't reach $instruction"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
# gdb_internal_error_resync:
|
# gdb_internal_error_resync:
|
||||||
#
|
#
|
||||||
@@ -4496,6 +4534,67 @@ proc aarch64_supports_sme_svl { length } {
|
|||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Run a test on the target to see if it supports AArch64 MOPS (Memory
|
||||||
|
# Operations) extensions. Return 1 if so, 0 if it does not. Note this
|
||||||
|
# causes a restart of GDB.
|
||||||
|
|
||||||
|
gdb_caching_proc allow_aarch64_mops_tests {} {
|
||||||
|
global srcdir subdir gdb_prompt inferior_exited_re
|
||||||
|
|
||||||
|
set me "allow_aarch64_mops_tests"
|
||||||
|
|
||||||
|
if { ![is_aarch64_target]} {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# ARMv9.3-A contains the MOPS extension. The test program doesn't use it,
|
||||||
|
# but take the opportunity to check whether the toolchain knows about MOPS.
|
||||||
|
set compile_flags "{additional_flags=-march=armv9.3-a}"
|
||||||
|
|
||||||
|
# Compile a program that tests the MOPS feature.
|
||||||
|
set src {
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <sys/auxv.h>
|
||||||
|
|
||||||
|
#ifndef HWCAP2_MOPS
|
||||||
|
#define HWCAP2_MOPS (1UL << 43)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
bool mops_supported = getauxval (AT_HWCAP2) & HWCAP2_MOPS;
|
||||||
|
|
||||||
|
return !mops_supported;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if {![gdb_simple_compile $me $src executable $compile_flags]} {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# Compilation succeeded so now run it via gdb.
|
||||||
|
clean_restart $obj
|
||||||
|
gdb_run_cmd
|
||||||
|
gdb_expect {
|
||||||
|
-re ".*$inferior_exited_re with code 01.*${gdb_prompt} $" {
|
||||||
|
verbose -log "\n$me mops support not detected"
|
||||||
|
set allow_mops_tests 0
|
||||||
|
}
|
||||||
|
-re ".*$inferior_exited_re normally.*${gdb_prompt} $" {
|
||||||
|
verbose -log "\n$me: mops support detected"
|
||||||
|
set allow_mops_tests 1
|
||||||
|
}
|
||||||
|
default {
|
||||||
|
warning "\n$me: default case taken"
|
||||||
|
set allow_mops_tests 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gdb_exit
|
||||||
|
remote_file build delete $obj
|
||||||
|
|
||||||
|
verbose "$me: returning $allow_mops_tests" 2
|
||||||
|
return $allow_mops_tests
|
||||||
|
}
|
||||||
|
|
||||||
# A helper that compiles a test case to see if __int128 is supported.
|
# A helper that compiles a test case to see if __int128 is supported.
|
||||||
proc gdb_int128_helper {lang} {
|
proc gdb_int128_helper {lang} {
|
||||||
return [gdb_can_simple_compile "i128-for-$lang" {
|
return [gdb_can_simple_compile "i128-for-$lang" {
|
||||||
|
|||||||
@@ -1086,7 +1086,7 @@ type_length_bits (type *type)
|
|||||||
static bool
|
static bool
|
||||||
check_valid_shift_count (enum exp_opcode op, type *result_type,
|
check_valid_shift_count (enum exp_opcode op, type *result_type,
|
||||||
type *shift_count_type, const gdb_mpz &shift_count,
|
type *shift_count_type, const gdb_mpz &shift_count,
|
||||||
unsigned long &nbits)
|
ULONGEST &nbits)
|
||||||
{
|
{
|
||||||
if (!shift_count_type->is_unsigned ())
|
if (!shift_count_type->is_unsigned ())
|
||||||
{
|
{
|
||||||
@@ -1112,7 +1112,7 @@ check_valid_shift_count (enum exp_opcode op, type *result_type,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nbits = shift_count.as_integer<unsigned long> ();
|
nbits = shift_count.as_integer<ULONGEST> ();
|
||||||
if (nbits >= type_length_bits (result_type))
|
if (nbits >= type_length_bits (result_type))
|
||||||
{
|
{
|
||||||
/* In Go, shifting by large amounts is defined. Be silent and
|
/* In Go, shifting by large amounts is defined. Be silent and
|
||||||
@@ -1291,7 +1291,7 @@ scalar_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
|
|||||||
|
|
||||||
case BINOP_LSH:
|
case BINOP_LSH:
|
||||||
{
|
{
|
||||||
unsigned long nbits;
|
ULONGEST nbits;
|
||||||
if (!check_valid_shift_count (op, result_type, type2, v2, nbits))
|
if (!check_valid_shift_count (op, result_type, type2, v2, nbits))
|
||||||
v = 0;
|
v = 0;
|
||||||
else
|
else
|
||||||
@@ -1301,9 +1301,23 @@ scalar_binop (struct value *arg1, struct value *arg2, enum exp_opcode op)
|
|||||||
|
|
||||||
case BINOP_RSH:
|
case BINOP_RSH:
|
||||||
{
|
{
|
||||||
unsigned long nbits;
|
ULONGEST nbits;
|
||||||
if (!check_valid_shift_count (op, result_type, type2, v2, nbits))
|
if (!check_valid_shift_count (op, result_type, type2, v2, nbits))
|
||||||
v = 0;
|
{
|
||||||
|
/* Pretend the too-large shift was decomposed in a
|
||||||
|
number of smaller shifts. An arithmetic signed
|
||||||
|
right shift of a negative number always yields -1
|
||||||
|
with such semantics. This is the right thing to
|
||||||
|
do for Go, and we might as well do it for
|
||||||
|
languages where it is undefined. Also, pretend a
|
||||||
|
shift by a negative number was a shift by the
|
||||||
|
negative number cast to unsigned, which is the
|
||||||
|
same as shifting by a too-large number. */
|
||||||
|
if (v1 < 0 && !result_type->is_unsigned ())
|
||||||
|
v = -1;
|
||||||
|
else
|
||||||
|
v = 0;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
v = v1 >> nbits;
|
v = v1 >> nbits;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1716,10 +1716,6 @@ value::record_latest ()
|
|||||||
fetch_lazy ();
|
fetch_lazy ();
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONGEST limit = m_limited_length;
|
|
||||||
if (limit != 0)
|
|
||||||
mark_bytes_unavailable (limit, m_enclosing_type->length () - limit);
|
|
||||||
|
|
||||||
/* Mark the value as recorded in the history for the availability check. */
|
/* Mark the value as recorded in the history for the availability check. */
|
||||||
m_in_history = true;
|
m_in_history = true;
|
||||||
|
|
||||||
@@ -3931,6 +3927,11 @@ value::fetch_lazy_memory ()
|
|||||||
if (len > 0)
|
if (len > 0)
|
||||||
read_value_memory (this, 0, stack (), addr,
|
read_value_memory (this, 0, stack (), addr,
|
||||||
contents_all_raw ().data (), len);
|
contents_all_raw ().data (), len);
|
||||||
|
|
||||||
|
/* If only part of an array was loaded, mark the rest as unavailable. */
|
||||||
|
if (m_limited_length > 0)
|
||||||
|
mark_bytes_unavailable (m_limited_length,
|
||||||
|
m_enclosing_type->length () - m_limited_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* See value.h. */
|
/* See value.h. */
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
15.0.50.DATE-git
|
15.2.90.DATE-git
|
||||||
|
|||||||
@@ -180,6 +180,12 @@ x86_linux_nat_target::read_description ()
|
|||||||
xcr0 = xstateregs[(I386_LINUX_XSAVE_XCR0_OFFSET
|
xcr0 = xstateregs[(I386_LINUX_XSAVE_XCR0_OFFSET
|
||||||
/ sizeof (uint64_t))];
|
/ sizeof (uint64_t))];
|
||||||
|
|
||||||
|
#ifdef __x86_64__
|
||||||
|
/* No MPX on x32. */
|
||||||
|
if (is_x32)
|
||||||
|
xcr0 &= ~X86_XSTATE_MPX;
|
||||||
|
#endif
|
||||||
|
|
||||||
m_xsave_layout = x86_fetch_xsave_layout (xcr0, x86_xsave_length ());
|
m_xsave_layout = x86_fetch_xsave_layout (xcr0, x86_xsave_length ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user