RE: Why enforcing sw_breakpoint_from_kind() implementation in GDBserver targets

Aktemur, Tankut Baris
2020-06-16T13:15:32Z

Hi Shahab,

On Monday, June 15, 2020 12:39 PM, Shahab Vahedi wrote:
> Tankut,
>
> Thank you for your clear response. I have only one remark:
>
> On Fri, Jun 12, 2020 at 11:04:08AM +0000, Aktemur, Tankut Baris wrote:
> > So, the base linux target delegates the op to the low target and enforces
> > an implementation.
>
> What about scenarios that "sw_breakpoint_from_kind" for the linux is
> defined by the target? There would be no execution of base-linux-target
> flavour of "sw_breakpoint_from_kind". Hence, not a mandatory dependency
> to the low target's "sw_breakpoint_from_kind".

I'm not sure I understand this statement fully. Let me clarify these cases:

1. In GDB 9 (i.e. before C++'ification of gdbserver's target definition),
the base linux target implemented the "sw_breakpoint_from_kind" target op
to directly delegate to "sw_breakpoint_from_kind" of the linux low target.
It asserted that the low target's "sw_breakpoint_from_kind" function pointer
is non-null.

2. In the current GDB master (i.e. after the C++'ification refactoring), the
"sw_breakpoint_from_kind" is a pure virtual function in target.h. The base linux
target, linux_process_target, does not implement this method; it leaves it as a
pure virtual method to be implemented by the linux low target.

So, neither in case #1 nor in #2 there exists a concrete base linux target
implementation. If in case #1 the "sw_breakpoint_from_kind" target op was
invoked but the low linux target did not provide an implementation, we would
get a runtime assert.

>
> This scenario is actally not far fetched. That's what's happening in ARC
> port.
>
> Shahab

As far as I understand, there is a certain control flow and a combination
of (un)supported features in the ARC port with which the "sw_breakpoint_from_kind"
target op is not invoked. I'm not sure what this flow or feature combination is.

There might be two alternative approaches with the current code base:

1. The new linux low target (in this case, ARC) implements the "sw_breakpoint_from_kind"
target op with a "gdb_assert_not_reached".

2. The base linux target, linux_process_target, overrides the "sw_breakpoint_from_kind"
with a "gdb_assert_not_reached" so that new linux low targets can omit overriding
the method if they choose to do so.

IMHO #1 is the better approach, but I'm not a maintainer. The ia64 target is the
only linux low target that did not implement the "sw_breakpoint_from_kind" linux low
target op before C++'ification. It currently contains a gdb_assert_not_reached
to mimic this behavior.

Just out of curiosity, is there a specific reason why you want to avoid implementing
the "sw_breakpoint_from_kind" target op? If there is a breakpoint instruction defined
for ARC, it would be as simple as filling in the 'size' parameter with the length
of the instruction and returning a pointer to the instruction contents. For many
targets, there is only one breakpoint kind and those targets simply ignore the 'kind'
argument.

-Baris

Intel Deutschland GmbH
Registered Address: Am Campeon 10-12, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de
Managing Directors: Christin Eisenschmid, Gary Kershaw
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928