public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Andrew Burgess <aburgess@redhat.com>
To: gdb-patches@sourceware.org
Cc: Andrew Burgess <aburgess@redhat.com>
Subject: [PATCHv2 3/6] gdb/arm: avoid undefined behaviour in arm_frame_is_thumb
Date: Fri, 10 Jun 2022 14:08:11 +0100	[thread overview]
Message-ID: <0d968da223ab233af5ce95520f5472a4d849d269.1654866187.git.aburgess@redhat.com> (raw)
In-Reply-To: <cover.1654866187.git.aburgess@redhat.com>

This commit fixes real undefined behaviour in GDB which I spotted when
working on a later patch in this series.  The later patch in this
series detects when the result of gdbarch_tdep() is cast to the wrong
type.

The issue is revealed by the gdb.multi/multi-arch.exp test.

In this test we setup two inferiors, an AArch64 process, and an ARM
process, then at one point we have inferior 1 selected (the AArch64
inferior), and we place a breakpoint on a symbol present in the other
inferior (the ARM inferior).

During the process of creating the breakpoint we call arm_pc_is_thumb,
the GDBARCH passed into this function is correct, that is, represents
the ARM process.

For whatever reason we are unable to figure out if the address in
question is thumb or not throughout most of arm_pc_is_thumb, and so we
get to this code at the end of the function:

  /* If we couldn't find any symbol, but we're talking to a running
     target, then trust the current value of $cpsr.  This lets
     "display/i $pc" always show the correct mode (though if there is
     a symbol table we will not reach here, so it still may not be
     displayed in the mode it will be executed).  */
  if (target_has_registers ())
    return arm_frame_is_thumb (get_current_frame ());

Which I guess is a last attempt to figure out the thumb status of an
address.  However, remember, we the AArch64 inferior is current at
this time, so the current frame is an AArch64 frame.

In arm_frame_is_thumb we call arm_psr_thumb_bit with the architecture
of the current frame (which will be an AArch64 architecture).

And in arm_psr_thumb_bit we do this:

  arm_gdbarch_tdep *tdep = (arm_gdbarch_tdep *) gdbarch_tdep (gdbarch);

which assumes that the current architecture is an ARM architecture.
In our case this is not true, its AArch64, and so we cast the tdep
object to arm_gdbarch_tdep when really it is of type
aarch64_gdbarch_tdep.

After this we access the fields of the tdep object, but this is
undefined behaviour.

To fix this I propose adding new code to arm_frame_is_thumb that
checks the bfd architecture of the current frame.  And frame that is
not bfd_arch_arm can't be a thumb frame.

I could add a gdb_assert to arm_psr_thumb_bit, however, I have not
done this.  A later commit in this series will add an assert to the
gdbarch_tdep() call to ensure that the cast is of the correct type.
This will make any assert (of bfd architecture) added to
arm_psr_thumb_bit redundant, so I've not added any such assert here.

With this commit in place the gdb.multi/multi-arch.exp test continues
to pass after I have applied the later patches that detect incorrect
casting of the gdbarch_tdep objects.
---
 gdb/arm-tdep.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index 7f27d4bd6e8..46027afade4 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -546,15 +546,19 @@ arm_is_thumb (struct regcache *regcache)
 int
 arm_frame_is_thumb (struct frame_info *frame)
 {
-  CORE_ADDR cpsr;
-  ULONGEST t_bit = arm_psr_thumb_bit (get_frame_arch (frame));
+  /* If the current frame is not ARM then it can't be thumb.  */
+  struct gdbarch *gdbarch = get_frame_arch (frame);
+  if (gdbarch_bfd_arch_info (target_gdbarch ())->arch != bfd_arch_arm)
+    return 0;
 
   /* Every ARM frame unwinder can unwind the T bit of the CPSR, either
      directly (from a signal frame or dummy frame) or by interpreting
      the saved LR (from a prologue or DWARF frame).  So consult it and
      trust the unwinders.  */
-  cpsr = get_frame_register_unsigned (frame, ARM_PS_REGNUM);
+  CORE_ADDR cpsr = get_frame_register_unsigned (frame, ARM_PS_REGNUM);
 
+  /* Find and extract the thumb bit.  */
+  ULONGEST t_bit = arm_psr_thumb_bit (gdbarch);
   return (cpsr & t_bit) != 0;
 }
 
-- 
2.25.4


  parent reply	other threads:[~2022-06-10 13:08 UTC|newest]

Thread overview: 83+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-05-31 14:30 [PATCH 0/5] Handle trying to use a native target with the wrong binary Andrew Burgess
2022-05-31 14:30 ` [PATCH 1/5] gdb/arm: move fetch of arm_gdbarch_tdep to a more inner scope Andrew Burgess
2022-06-01  7:58   ` Luis Machado
2022-05-31 14:30 ` [PATCH 2/5] gdb/mips: rewrite show_mask_address Andrew Burgess
2022-05-31 14:30 ` [PATCH 3/5] gdb: move the type cast into gdbarch_tdep Andrew Burgess
2022-06-01  8:01   ` Luis Machado
2022-05-31 14:30 ` [PATCH 4/5] gdb: ensure the cast in gdbarch_tdep is valid Andrew Burgess
2022-05-31 16:04   ` John Baldwin
2022-05-31 17:22     ` Andrew Burgess
2022-05-31 14:30 ` [PATCH 5/5] gdb: native target invalid architecture detection Andrew Burgess
2022-05-31 16:08   ` John Baldwin
2022-05-31 16:51     ` Andrew Burgess
2022-06-01  8:25       ` Luis Machado
2022-06-01 21:06         ` John Baldwin
2022-06-01 21:21           ` Christophe Lyon
2022-06-02 14:56             ` John Baldwin
2022-06-06 14:38         ` Andrew Burgess
2022-06-06 17:48           ` Andrew Burgess
2022-06-07 11:03             ` Luis Machado
2022-06-07 18:42               ` Pedro Alves
2022-06-07 20:15                 ` Pedro Alves
2022-06-08  8:18                   ` Luis Machado
2022-06-08 10:17                     ` Pedro Alves
2022-06-08  7:54                 ` Luis Machado
2022-06-08 10:12                   ` Pedro Alves
2022-06-08 11:20                     ` [PATCH v2] aarch64: Add fallback if ARM_CC_FOR_TARGET not set (was: Re: [PATCH 5/5] gdb: native target invalid architecture detection) Pedro Alves
2022-06-08 12:50                       ` Luis Machado
2022-06-08 13:23                         ` Pedro Alves
2022-06-08 13:38                       ` Andrew Burgess
2022-06-08 19:01                       ` John Baldwin
2022-06-08 21:48                         ` Pedro Alves
2022-06-09 16:31                           ` John Baldwin
2022-06-10 13:08 ` [PATCHv2 0/6] Handle trying to use a native target with the wrong binary Andrew Burgess
2022-06-10 13:08   ` [PATCHv2 1/6] gdb/arm: move fetch of arm_gdbarch_tdep to a more inner scope Andrew Burgess
2022-06-10 13:08   ` [PATCHv2 2/6] gdb/mips: rewrite show_mask_address Andrew Burgess
2022-06-10 13:08   ` Andrew Burgess [this message]
2022-06-10 15:21     ` [PATCHv2 3/6] gdb/arm: avoid undefined behaviour in arm_frame_is_thumb Luis Machado
2022-06-10 15:49       ` Andrew Burgess
2022-06-10 16:29         ` Luis Machado
2022-06-10 13:08   ` [PATCHv2 4/6] gdb: move the type cast into gdbarch_tdep Andrew Burgess
2022-06-10 16:35     ` Luis Machado
2022-06-10 13:08   ` [PATCHv2 5/6] gdb: ensure the cast in gdbarch_tdep is valid Andrew Burgess
2022-06-10 13:08   ` [PATCHv2 6/6] gdb: native target invalid architecture detection Andrew Burgess
2022-06-10 16:20     ` John Baldwin
2022-06-10 16:31     ` Luis Machado
2022-06-13 16:15   ` [PATCHv3 0/6] Handle trying to use a native target with the wrong binary Andrew Burgess
2022-06-13 16:15     ` [PATCHv3 1/6] gdb/arm: move fetch of arm_gdbarch_tdep to a more inner scope Andrew Burgess
2022-06-13 16:15     ` [PATCHv3 2/6] gdb/mips: rewrite show_mask_address Andrew Burgess
2022-06-13 16:15     ` [PATCHv3 3/6] gdb: select suitable thread for gdbarch_adjust_breakpoint_address Andrew Burgess
2022-06-14  9:45       ` Luis Machado
2022-06-14 14:05         ` Andrew Burgess
2022-06-24 16:58       ` Pedro Alves
2022-06-13 16:15     ` [PATCHv3 4/6] gdb: move the type cast into gdbarch_tdep Andrew Burgess
2022-06-13 16:15     ` [PATCHv3 5/6] gdb: ensure the cast in gdbarch_tdep is valid Andrew Burgess
2022-06-24 18:15       ` Pedro Alves
2022-06-13 16:15     ` [PATCHv3 6/6] gdb: native target invalid architecture detection Andrew Burgess
2022-06-24 19:23       ` Pedro Alves
2022-06-27 16:27         ` Andrew Burgess
2022-06-27 21:38           ` Pedro Alves
2022-06-28 10:37             ` Andrew Burgess
2022-06-28 12:42               ` [PATCH v2] gdb+gdbserver/Linux: avoid reading registers while going through shell (was: Re: [PATCHv3 6/6] gdb: native target invalid architecture detection) Pedro Alves
2022-06-28 14:21                 ` Andrew Burgess
2022-06-29 15:17                 ` Simon Marchi
2022-06-29 16:22                   ` [PATCH] Fix GDBserver regression due to change to avoid reading shell registers Pedro Alves
2022-06-29 16:38                     ` Simon Marchi
2022-06-30  9:33             ` [PATCHv3 6/6] gdb: native target invalid architecture detection Andrew Burgess
2022-06-30 11:44               ` Pedro Alves
2022-07-11 10:47                 ` Andrew Burgess
2022-06-24 10:15     ` [PATCHv3 0/6] Handle trying to use a native target with the wrong binary Andrew Burgess
2022-06-28 14:28     ` [PATCHv4 0/6] Detect invalid casts of gdbarch_tdep structures Andrew Burgess
2022-06-28 14:28       ` [PATCHv4 1/6] gdb/arm: move fetch of arm_gdbarch_tdep to a more inner scope Andrew Burgess
2022-06-28 14:28       ` [PATCHv4 2/6] gdb/mips: rewrite show_mask_address Andrew Burgess
2022-06-28 14:28       ` [PATCHv4 3/6] gdb: select suitable thread for gdbarch_adjust_breakpoint_address Andrew Burgess
2022-06-28 14:28       ` [PATCHv4 4/6] gdb: move the type cast into gdbarch_tdep Andrew Burgess
2022-06-28 14:28       ` [PATCHv4 5/6] gdbsupport: add checked_static_cast Andrew Burgess
2022-06-28 14:28       ` [PATCHv4 6/6] gdb: ensure the cast in gdbarch_tdep is valid Andrew Burgess
2022-07-11 10:46       ` [PATCHv4 0/6] Detect invalid casts of gdbarch_tdep structures Andrew Burgess
2022-07-21 18:21         ` Andrew Burgess
2022-07-22  0:50           ` Luis Machado
2022-07-23  0:02             ` [PATCH] Rename gdbarch_tdep template function to gdbarch_tdep_cast for g++ 4.8 Mark Wielaard
2022-07-25 11:19               ` Andrew Burgess
2022-07-25 11:27                 ` Mark Wielaard
2022-07-26 11:05                   ` Andrew Burgess

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=0d968da223ab233af5ce95520f5472a4d849d269.1654866187.git.aburgess@redhat.com \
    --to=aburgess@redhat.com \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).