From: "H.J. Lu" <hjl.tools@gmail.com>
To: Mark Kettenis <mark.kettenis@xs4all.nl>
Cc: gdb-patches@sourceware.org
Subject: Re: PATCH: Enable x86 XML target descriptions
Date: Mon, 22 Feb 2010 14:17:00 -0000 [thread overview]
Message-ID: <6dc9ffc81002220617o1d348e68hc918d434118cadcb@mail.gmail.com> (raw)
In-Reply-To: <201002221342.o1MDgSZA029705@glazunov.sibelius.xs4all.nl>
On Mon, Feb 22, 2010 at 5:42 AM, Mark Kettenis <mark.kettenis@xs4all.nl> wrote:
>> Date: Thu, 18 Feb 2010 15:01:35 -0800
>> From: "H.J. Lu" <hongjiu.lu@intel.com>
>>
>> On Thu, Feb 18, 2010 at 07:34:02AM -0800, H.J. Lu wrote:
>> > On Wed, Feb 17, 2010 at 09:43:12PM -0800, H.J. Lu wrote:
>> > > On Wed, Feb 10, 2010 at 12:03:03PM -0800, H.J. Lu wrote:
>> > > > Hi,
>> > > >
>> > > > This patch enables x86 XML target descriptions. I used
>> > > > i386_linux_init_orig_eax to support the old gdbserver which doesn't
>> > > > have XML target descriptions.
>> > > >
>> > > > The register description processing is handled in i386_gdbarch_init
>> > > > for 32bit/64bit as well as all ABIs to avoid code duplication and
>> > > > unnecessary complexity.
>> > > >
>> > > > OK to install?
>> > > >
>> > >
>> > > Here is the updated patch. I removed all BFD64 from i386 files. I
>> > > renamed I386_NUM_FREGS to I387_NUM_REGS and put it in i387-tdep.h.
>> > > I use it in amd64-tdep.c. I added a few fields to gdbarch_tdep so
>> > > that I can pass values from xxx_abit_init to i386_gdbarch_init. OK
>> > > to install?
>> > >
>> > > Thanks.
>> > >
>> > >
>> >
>> > A small update. I added I386_MXCSR_REGNUM so that "i387-tdep.h"
>> > isn't added for amd64-linux-nat.c, amd64-linux-tdep.c and
>> > i386-linux-tdep.c. OK to install?
>> >
>>
>> A small bug fix. amd64_linux_read_description should return
>> tdesc_i386_linux for 32bit.
>
> I tested a GDB with this diff on OpenBSD/i386 and only noticed one
> regression:
>
> Running ./gdb.xml/tdesc-regs.exp ...
> -PASS: gdb.xml/tdesc-regs.exp: set tdesc file single-reg.xml
> +FAIL: gdb.xml/tdesc-regs.exp: set tdesc file single-reg.xml
>
> To me it looks like this test needs to be adjusted now that the i386
> target has tdesc support.
I will do that.
> I still need a bit more time to review the diff. I'm sorry, but the
> tdesc stuff is something I'm simply not familiar with, so it takes
> some time to understand the implications of this diff. However, below
> are some questions/issues I ran into already.
>
>> diff --git a/gdb/amd64-linux-nat.c b/gdb/amd64-linux-nat.c
>> index 5c9e558..8038555 100644
>> --- a/gdb/amd64-linux-nat.c
>> +++ b/gdb/amd64-linux-nat.c
>> @@ -674,6 +674,17 @@ amd64_linux_siginfo_fixup (struct siginfo *native, gdb_byte *inf, int direction)
>> return 0;
>> }
>>
>> +/* Get Linux/x86 target description from running target. */
>> +
>> +static const struct target_desc *
>> +amd64_linux_read_description (struct target_ops *ops)
>> +{
>> + if (gdbarch_ptr_bit (target_gdbarch) == 64)
>> + return tdesc_amd64_linux;
>> + else
>> + return tdesc_i386_linux;
>> +}
>> +
>
> This made me wonder what happens if you attach to a process without
> loading an executable first. Currently this works, since GDB can
> figure out what executable belongs to the the process and load the
> executable automatically. But I fear a chicken & egg problem here:
> the gdbarch is derviced from the tdesc, but in order to determine the
> tdesc you need a gdbarch.
How do you attach to a process without loading an executable first?
Gdb has to load something to debug. Do you have a testcase? I will
fix it if it doesn't work already.
>> @@ -1260,10 +1242,38 @@ amd64_linux_record_signal (struct gdbarch *gdbarch,
>> return 0;
>> }
>>
>> +/* Get Linux/x86 target description from core dump. */
>> +
>> +static const struct target_desc *
>> +amd64_linux_core_read_description (struct gdbarch *gdbarch,
>> + struct target_ops *target,
>> + bfd *abfd)
>> +{
>> + asection *section = bfd_get_section_by_name (abfd, ".reg2");
>> +
>> + if (section == NULL)
>> + return NULL;
>> +
>> + switch (bfd_section_size (abfd, section))
>> + {
>> + case 0x200:
>> + /* Linux/x86-64. */
>> + return tdesc_amd64_linux;
>> + default:
>> + return NULL;
>> + }
>> +}
>
> This seems a bit odd to me. I'd expect this function to just return
> tdesc_amd64_linux unconditionally.
The folowup patch for AVX will change it to
xcr0 = i386_linux_core_read_xcr0 (gdbarch, target, abfd);
switch (bfd_section_size (abfd, section))
{
case 0x200:
/* Linux/x86-64. */
if ((xcr0 & XSTATE_AVX_MASK) == XSTATE_AVX_MASK)
return tdesc_amd64_avx_linux;
else
return tdesc_amd64_linux;
default:
return NULL;
}
Other OSes will need a similar change to support AVX.
>> @@ -1282,10 +1292,31 @@ amd64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
>>
>> /* Add the %orig_rax register used for syscall restarting. */
>> set_gdbarch_write_pc (gdbarch, amd64_linux_write_pc);
>> +
>> + /* Reserve a number for orig_rax. */
>> set_gdbarch_num_regs (gdbarch, AMD64_LINUX_NUM_REGS);
>> - set_gdbarch_register_name (gdbarch, amd64_linux_register_name);
>> - set_gdbarch_register_type (gdbarch, amd64_linux_register_type);
>> - set_gdbarch_register_reggroup_p (gdbarch, amd64_linux_register_reggroup_p);
>
> Why do you need to set num_regs here, but not the register_name,
> register_type and register_reggroup_p members? All four are set by
> tdesc_use_registers().
tdesc_use_registers is called after amd64_linux_init_abi. At this
point, num_regs is incorrect for Linux. We need to update it for
valid_p = tdesc_numbered_register (feature, tdesc_data,
AMD64_LINUX_ORIG_RAX_REGNUM,
"orig_rax");
>> +
>> + if (! tdesc_has_registers (tdesc))
>> + tdesc = tdesc_amd64_linux;
>> + tdep->tdesc = tdesc;
>> +
>> + feature = tdesc_find_feature (tdesc, "org.gnu.gdb.i386.linux");
>
> Shouldn't that be org.gnu.gdb.amd64.linux?
64bit-core.xml and 64bit-sse.xml have
<feature name="org.gnu.gdb.i386.core">
and
<feature name="org.gnu.gdb.i386.sse">
so that i386_gdbarch_init can have
/* Get core registers. */
feature_core = tdesc_find_feature (tdesc, "org.gnu.gdb.i386.core");
/* Get SSE registers. */
feature_vector = tdesc_find_feature (tdesc, "org.gnu.gdb.i386.sse");
after
/* Hook in ABI-specific overrides, if they have been registered. */
info.tdep_info = (void *) tdesc_data;
gdbarch_init_osabi (info, gdbarch);
It will be odd for 64bit-linux.xml to have
<feature name="org.gnu.gdb.i386.linux">
>> @@ -2112,87 +2107,22 @@ i386_return_value (struct gdbarch *gdbarch, struct type *func_type,
>> }
>>
>>
>> -/* Construct types for ISA-specific registers. */
>> -struct type *
>> -i386_eflags_type (struct gdbarch *gdbarch)
>> -{
>> - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
>> -
>> - if (!tdep->i386_eflags_type)
>> - {
>> - struct type *type;
>> -
>> - type = arch_flags_type (gdbarch, "builtin_type_i386_eflags", 4);
>> - append_flags_type_flag (type, 0, "CF");
>> - append_flags_type_flag (type, 1, NULL);
>> - append_flags_type_flag (type, 2, "PF");
>> - append_flags_type_flag (type, 4, "AF");
>> - append_flags_type_flag (type, 6, "ZF");
>> - append_flags_type_flag (type, 7, "SF");
>> - append_flags_type_flag (type, 8, "TF");
>> - append_flags_type_flag (type, 9, "IF");
>> - append_flags_type_flag (type, 10, "DF");
>> - append_flags_type_flag (type, 11, "OF");
>> - append_flags_type_flag (type, 14, "NT");
>> - append_flags_type_flag (type, 16, "RF");
>> - append_flags_type_flag (type, 17, "VM");
>> - append_flags_type_flag (type, 18, "AC");
>> - append_flags_type_flag (type, 19, "VIF");
>> - append_flags_type_flag (type, 20, "VIP");
>> - append_flags_type_flag (type, 21, "ID");
>> -
>> - tdep->i386_eflags_type = type;
>> - }
>> -
>> - return tdep->i386_eflags_type;
>> -}
>> -
>> -struct type *
>> -i386_mxcsr_type (struct gdbarch *gdbarch)
>> -{
>> - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
>> -
>> - if (!tdep->i386_mxcsr_type)
>> - {
>> - struct type *type;
>> -
>> - type = arch_flags_type (gdbarch, "builtin_type_i386_mxcsr", 4);
>> - append_flags_type_flag (type, 0, "IE");
>> - append_flags_type_flag (type, 1, "DE");
>> - append_flags_type_flag (type, 2, "ZE");
>> - append_flags_type_flag (type, 3, "OE");
>> - append_flags_type_flag (type, 4, "UE");
>> - append_flags_type_flag (type, 5, "PE");
>> - append_flags_type_flag (type, 6, "DAZ");
>> - append_flags_type_flag (type, 7, "IM");
>> - append_flags_type_flag (type, 8, "DM");
>> - append_flags_type_flag (type, 9, "ZM");
>> - append_flags_type_flag (type, 10, "OM");
>> - append_flags_type_flag (type, 11, "UM");
>> - append_flags_type_flag (type, 12, "PM");
>> - append_flags_type_flag (type, 15, "FZ");
>> -
>> - tdep->i386_mxcsr_type = type;
>> - }
>> -
>> - return tdep->i386_mxcsr_type;
>> -}
>> -
>> struct type *
>> i387_ext_type (struct gdbarch *gdbarch)
>> {
>> struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
>>
>> if (!tdep->i387_ext_type)
>> - tdep->i387_ext_type
>> - = arch_float_type (gdbarch, -1, "builtin_type_i387_ext",
>> - floatformats_i387_ext);
>> + {
>> + tdep->i387_ext_type = tdesc_find_type (gdbarch, "i387_ext");
>> + gdb_assert (tdep->i387_ext_type != NULL);
>> + }
>>
>> return tdep->i387_ext_type;
>> }
>>
>> /* Construct vector type for MMX registers. */
>> -struct type *
>> +static struct type *
>> i386_mmx_type (struct gdbarch *gdbarch)
>> {
>> struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
>> @@ -2233,84 +2163,14 @@ i386_mmx_type (struct gdbarch *gdbarch)
>> return tdep->i386_mmx_type;
>> }
>>
>> -struct type *
>> -i386_sse_type (struct gdbarch *gdbarch)
>> -{
>> - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
>> -
>> - if (!tdep->i386_sse_type)
>> - {
>> - const struct builtin_type *bt = builtin_type (gdbarch);
>> -
>> - /* The type we're building is this: */
>> -#if 0
>> - union __gdb_builtin_type_vec128i
>> - {
>> - int128_t uint128;
>> - int64_t v2_int64[2];
>> - int32_t v4_int32[4];
>> - int16_t v8_int16[8];
>> - int8_t v16_int8[16];
>> - double v2_double[2];
>> - float v4_float[4];
>> - };
>> -#endif
>> -
>> - struct type *t;
>> -
>> - t = arch_composite_type (gdbarch,
>> - "__gdb_builtin_type_vec128i", TYPE_CODE_UNION);
>> - append_composite_type_field (t, "v4_float",
>> - init_vector_type (bt->builtin_float, 4));
>> - append_composite_type_field (t, "v2_double",
>> - init_vector_type (bt->builtin_double, 2));
>> - append_composite_type_field (t, "v16_int8",
>> - init_vector_type (bt->builtin_int8, 16));
>> - append_composite_type_field (t, "v8_int16",
>> - init_vector_type (bt->builtin_int16, 8));
>> - append_composite_type_field (t, "v4_int32",
>> - init_vector_type (bt->builtin_int32, 4));
>> - append_composite_type_field (t, "v2_int64",
>> - init_vector_type (bt->builtin_int64, 2));
>> - append_composite_type_field (t, "uint128", bt->builtin_int128);
>> -
>> - TYPE_VECTOR (t) = 1;
>> - TYPE_NAME (t) = "builtin_type_vec128i";
>> - tdep->i386_sse_type = t;
>> - }
>> -
>> - return tdep->i386_sse_type;
>> -}
>
> I didn't realize these functions would effectively be moved into
> target-descriptions.c. That feels wrong.
That is how target description works. All types used in XML are
supported in target-descriptions.c.
>> + /* Target description may be changed. */
>> + tdesc = tdep->tdesc;
>> +
>> + if (! tdesc_has_registers (tdesc))
>> + {
>> + xfree (tdep);
>> + gdbarch_free (gdbarch);
>> + return NULL;
>> + }
>> +
>> + /* Get core registers. */
>> + feature_core = tdesc_find_feature (tdesc, "org.gnu.gdb.i386.core");
>> +
>> + /* Get SSE registers. */
>> + feature_vector = tdesc_find_feature (tdesc, "org.gnu.gdb.i386.sse");
>> +
>> + if (feature_core == NULL || feature_vector == NULL)
>> + {
>> + xfree (tdep);
>> + gdbarch_free (gdbarch);
>> + return NULL;
>> + }
>> +
>> + valid_p = 1;
>> +
>> + num_regs = tdep->num_core_regs;
>> + for (i = 0; i < num_regs; i++)
>> + valid_p &= tdesc_numbered_register (feature_core, tdesc_data, i,
>> + tdep->register_names[i]);
>> +
>> + /* Need to include %mxcsr, so add one. */
>> + num_regs += tdep->num_xmm_regs + 1;
>> + for (; i < num_regs; i++)
>> + valid_p &= tdesc_numbered_register (feature_vector, tdesc_data, i,
>> + tdep->register_names[i]);
>> +
>> + if (!valid_p)
>> + {
>> + tdesc_data_cleanup (tdesc_data);
>> + xfree (tdep);
>> + gdbarch_free (gdbarch);
>> + return NULL;
>> + }
>
> That's quite a bit of code to verify the sanity of the target description. I think that should go into a seperate function.
I will do that.
>> +
>> + tdesc_use_registers (gdbarch, tdesc, tdesc_data);
>> +
>> + /* Override gdbarch_register_reggroup_p set in tdesc_use_registers. */
>> + set_gdbarch_register_reggroup_p (gdbarch, tdep->register_reggroup_p);
>
> Why is it necessary to do this?
>
i386_gdbarch_init calls
1. gdbarch_init_osabi
2. tdesc_use_registers, which calls
set_gdbarch_register_reggroup_p (gdbarch, tdesc_register_reggroup_p);
If you want to change register_reggroup_p in gdbarch_init_osabi, you
have to store it in tdep and call set_gdbarch_register_reggroup_p after
tdesc_use_registers.
Thanks.
--
H.J.
next prev parent reply other threads:[~2010-02-22 14:17 UTC|newest]
Thread overview: 39+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-02-10 20:03 H.J. Lu
2010-02-17 14:59 ` H.J. Lu
2010-02-17 15:23 ` Mark Kettenis
2010-02-17 15:42 ` H.J. Lu
2010-02-17 15:46 ` Daniel Jacobowitz
2010-02-17 16:19 ` Mark Kettenis
2010-02-18 5:44 ` H.J. Lu
2010-02-18 15:37 ` H.J. Lu
2010-02-18 23:01 ` H.J. Lu
2010-02-22 13:42 ` Mark Kettenis
2010-02-22 14:17 ` H.J. Lu [this message]
2010-02-22 15:01 ` Mark Kettenis
2010-02-22 15:27 ` H.J. Lu
2010-02-22 15:30 ` Daniel Jacobowitz
2010-02-22 15:39 ` H.J. Lu
2010-02-28 20:30 ` Mark Kettenis
2010-02-28 20:58 ` H.J. Lu
2010-02-28 22:23 ` Daniel Jacobowitz
2010-02-22 14:41 ` Daniel Jacobowitz
2010-02-22 15:34 ` H.J. Lu
2010-02-22 15:52 ` Daniel Jacobowitz
2010-02-22 15:58 ` H.J. Lu
2010-02-22 16:10 ` Daniel Jacobowitz
2010-02-22 16:58 ` Mark Kettenis
2010-02-22 17:03 ` Daniel Jacobowitz
2010-02-22 19:52 ` Mark Kettenis
2010-02-22 21:06 ` H.J. Lu
2010-02-22 21:31 ` Mark Kettenis
2010-02-22 21:41 ` H.J. Lu
2010-02-22 22:05 ` H. Peter Anvin
2010-02-22 22:07 ` H.J. Lu
2010-02-22 22:15 ` H. Peter Anvin
2010-02-22 22:21 ` H.J. Lu
2010-02-28 20:12 ` Mark Kettenis
2010-02-22 21:04 ` H.J. Lu
2010-02-28 21:16 ` H.J. Lu
2010-03-01 14:49 ` Mark Kettenis
2010-03-01 17:07 ` Daniel Jacobowitz
2010-03-01 17:09 ` H.J. Lu
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=6dc9ffc81002220617o1d348e68hc918d434118cadcb@mail.gmail.com \
--to=hjl.tools@gmail.com \
--cc=gdb-patches@sourceware.org \
--cc=mark.kettenis@xs4all.nl \
/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