aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom de Vries <tdevries@suse.de>2025-03-07 09:25:33 +0100
committerTom de Vries <tdevries@suse.de>2025-03-07 09:25:33 +0100
commit5a98b457ade0f8fb9f13ac50c999ebf5a1ac1d2f (patch)
tree884c18d20cd0cf4b3ed5e9725706642ad0c52ec7
parenta7769415cb4a3207de4c18baf46794344ab220d1 (diff)
downloadbinutils-5a98b457ade0f8fb9f13ac50c999ebf5a1ac1d2f.zip
binutils-5a98b457ade0f8fb9f13ac50c999ebf5a1ac1d2f.tar.gz
binutils-5a98b457ade0f8fb9f13ac50c999ebf5a1ac1d2f.tar.bz2
[gdb/tdep] Fix rip-relative insn handling in amd64_get_used_input_int_reg
I wanted to add a unit test for an an rip-relative amd64 insn, so I did: ... $ gcc -fPIE hello.c ... and used an rip-relative insn from main: ... 4005db: 48 8d 3d 1e 00 00 00 lea 0x1e(%rip),%rdi ... While writing the unit test, I found that amd64_get_used_input_int_reg returns rbp as input register. Fix this by using rip_relative_p in amd64_get_used_input_int_reg to handle this case. Tested on x86_64-linux.
-rw-r--r--gdb/amd64-tdep.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/gdb/amd64-tdep.c b/gdb/amd64-tdep.c
index a2da139..09f41e5 100644
--- a/gdb/amd64-tdep.c
+++ b/gdb/amd64-tdep.c
@@ -1264,7 +1264,7 @@ amd64_get_used_input_int_regs (const struct amd64_insn *details,
used_regs_mask |= 1 << base;
used_regs_mask |= 1 << idx;
}
- else
+ else if (!rip_relative_p (modrm))
{
used_regs_mask |= 1 << rm;
}
@@ -3447,6 +3447,17 @@ test_amd64_get_insn_details (void)
SELF_CHECK (amd64_get_used_input_int_regs (&details, false)
== ((1 << EAX_REG_NUM)));
SELF_CHECK (rip_relative_offset (&details) == 0);
+
+ /* INSN: lea 0x1e(%rip),%rdi, rex prefix. */
+ insn = { 0x48, 0x8d, 0x3d, 0x1e, 0x00, 0x00, 0x00 };
+ amd64_get_insn_details (insn.data (), &details);
+ SELF_CHECK (details.opcode_len == 1);
+ SELF_CHECK (details.enc_prefix_offset == 0);
+ SELF_CHECK (details.opcode_offset == 1);
+ SELF_CHECK (details.modrm_offset == 2);
+ SELF_CHECK (amd64_get_used_input_int_regs (&details, false)
+ == (1 << EDI_REG_NUM));
+ SELF_CHECK (rip_relative_offset (&details) == 3);
}
static void