Support fine-grained control over Target Features
daniel5151 opened this issue · 3 comments
Aside from specifying the core architecture of the target, the Target Description XML is also used to specify various features of the architecture. As the docs say: "Features are currently used to describe available CPU registers and the types of their contents"
e.g: for x86, the core registers are defined under the org.gnu.gdb.i386.core
feature, while the optional SSE registers are defined under the org.gnu.gdb.i386.sse
feature.
Currently, the Arch
trait isn't very well suited to describing features, requiring a separate implementation for each set of features. i.e: if an architecture has 3 different features, A, B, and C, each with their own registers, there would have to be 3! (i.e: 6) different register structs to describe each set of features!
I'd like to preserve the current "described at compile time" approach to the Arch
trait, and I think with a little bit of experimentation, it shouldn't be too hard to find some sort of ergonomic trait-based solution to the problem.
Some general ideas:
- It might make sense to have the
target_features_xml
method accept aFnMut(&'static str)
callback (instead of returningOption<'static str>
, as that would allow building up an XML file in "chunks" based on which features are available.
Hmm, I wonder if a quick-and-dirty solution might be to create some sort of "arch builder" macro?
Instead of exposing types that implement Arch
directly, each arch exposes a bunch of different "feature" structures, which encode a feature's associated registers + xml string. Consumers of the crate will then invoke the arch builder macro with the set of features they're interested in, creating a brand-new Arch
impl suited specifically for their project.
A rough sketch of what the end-user API might look like:
arch_builder! {
name: CustomX86,
arch: x86_64,
features: [
core, sse, segments, avx
]
}
Not sure what the implementation might look like, but this would fix the immediate problem of how to easily compose different Arch traits.
Of course, this approach isn't that great, since macro-based codegen is kinda hacky in my book. That said, I wanted to write this idea down before I forgot it, since it might be a good jumping off point in the future.
So here's something interesting: https://sourceware.org/gdb/onlinedocs/gdb/Target-Description-Format.html#Inclusion
Turns out target description XMLs support using <xi:include href="foo.xml"/>
to split the description into multiple files...
For example:
target.xml
<?xml version="1.0"?>
<!DOCTYPE target SYSTEM "gdb-target.dtd">
<target version="1.0">
<architecture>i386:x86-64</architecture>
<xi:include href="core64-regs.xml"/>
</target>
core64-regs.xml
<?xml version="1.0"?>
<!DOCTYPE target SYSTEM "gdb-target.dtd">
<feature name="org.gnu.gdb.i386.core">
...
</feature>
I'm definitely going to update the TargetDescriptionXmlOverride
extension to support custom annexes, but I think it might be very useful to somehow leverage this functionality to support fine grained target features...
I plan on working on this by implementing #109 (comment) i.e. making the Arch
provide a standard XML <xi:include>
-ing all its (Arch
-defined + GDB-standard) features and make the gdbstub
backend forward <xi:include>
callbacks from the GDB client to the Target
, giving it the opportunity, for each feature, to return the associated Arch
-defined XML, its own (don't really have a use-case for this... yet?), or None
.
This will help with unifying the MIPS architecture and trimming the ridiculously large list of AArch64 system registers that's reported to the GDB client (e.g. because the HW doesn't support an optional feature or because the GDB server can assume that the code won't ever run at certain ELs).