This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: RFC: A change to the way we initialize new gdbarches
On Thu, Oct 05, 2006 at 10:06:09PM +0200, Mark Kettenis wrote:
> So what exactly should "set architecture auto" do?
>
> I think we should set the architecture to the architecture of the
> loaded file, or the default architecture if there is no loaded file.
I agree entirely; in fact, that's exactly the behavior I'm trying to
implement. The code never used to consult the default architecture
after GDB startup.
> Will there always be a meaningful default architecture? I think the
> answer is yes for all "hosted" targets. For example if I configure
> with --target==mips64-openbsd, the default endianness should be
> big-endian. But for embedded targets that's not always clear I think.
I think there's just as likely to be a valid default on embedded as
hosted targets. Of course, it's just a default - I don't think we need
to jump through hoops to make GDB do something sensible if your system
has a different default. Today, we pick up the default directly from
BFD; I think that's still sane.
> > This happens because we fill in the defaults for a new architecture from the
> > previously selected architecture. These are derived properties, based on
> > the user's settings (at the time), the selected file (at the time), and so
> > forth. This filling happens in two general places; in gdbarch_info_fill,
> > and in tdep files in the gdbarch_init method.
> >
> > Here's a proposed approach to change that. Note: it only compiles on i386
> > or x86-64. Changing the other architectures will not be hard, but it will
> > be somewhat time consuming, so I wanted to get feedback on what I've done
> > so far.
>
> Whatever we decide, I think it is necessary to have a thorough look at
> architectures that don't have a fixed endian-ness (like mips).
Definitely. In fact, I've gotten sidetracked onto x86-64 by Jan's
recent posting; I was originally working on this logic for MIPS and
that's the next architecture I'd be looking at.
> > Instead of inheriting derived properties (like "endianness") from the
> > previous architecture, only inherit primary properties (like "the endianness
> > of the user's file").
>
> I wonder whether inheriting anything from the previous architecture is
> a good idea at all.
In fact, there's an alternative. We could keep it separate. But I
suspect we still need to hold on to some global state; consider "set
endian" when there's a file loaded. We want to ignore any autodetected
endianness, but if the file indicates 64-bit MIPS rather than 32-bit
MIPS, we don't want to lose track of that information.
"Indicates ARM rather than MIPS" is a flashier example but requires a
GDB which supports both. Which we've been very close to for a while,
and I think I may make a final push to take us there soon. I'm going
to have to do lots of gdbarch cleanups now anyway :-)
I thought about breaking up the two bits of state, "current properties"
and "current gdbarch". But they're both troublesome for a hypothetical
future GDB which supports debugging more than one architecture at a
time, and the current properties bit would have the same problems as
the current gdbarch.
But thinking about it more today, maybe I got this backwards. We've
already got a global exec_bfd. We could check that every time we
updated the architecture. Instead of the current gdbarch_info_init and
gdbarch_info_fill, we'd have a single function which recomputed all the
interesting properties from all of the available sources, and call it
whenever one of them changed. That function would have to look at:
- The global override variables (set endian, set architecture, set
osabi).
- The current executable file.
- The current target, for target-fetched information.
What do you think?
> You're thinking about caching things to avoid refetching the info from
> the target isn't it? But we should invalidate that info when we
> disconnect from the target.
There's two cachings going on. One of them, the one I was talking
about here, is in today's GDB already: we try to reuse "struct gdbarch"
throughout a debugging session. So we don't want to have to create a
new one just because the user said "file".
The other, in our local GDB branch, is caching of data read from the
target. You're exactly right: we read it once, on connection, and make
sure not to read it again and to invalidate it when we disconnect.
It's a little more complicated: we sometimes refetch while remaining
connected. The "architecture" debugged by a stub can change when it
switches from one executable to another, for instance if one of them
uses a kernel FPU emulator and so appears to have floating point
registers, and the other is compiled for soft FP and thus doesn't have
meaningful FP registers. But that's just a detail.
> > What do you all think? Is this sensible, or am I moving in the wrong
> > direction?
>
> I find this particular bit of code very hard to understand, and I'm
> afraid I can't answer this question right now. Hopefully your answers
> to my questions will help me judging this better.
Thanks for looking at it! As you can tell from my floundering around
above, I find this stuff pretty confusing too; it takes twice as long
to grok as most bits of GDB. I hope these changes will make it a
little clearer.
--
Daniel Jacobowitz
CodeSourcery