From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 15460 invoked by alias); 5 Jun 2012 12:58:39 -0000 Received: (qmail 15443 invoked by uid 22791); 5 Jun 2012 12:58:36 -0000 X-SWARE-Spam-Status: No, hits=-5.0 required=5.0 tests=AWL,BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,KHOP_RCVD_TRUST,KHOP_THREADED,RCVD_IN_DNSWL_LOW,RCVD_IN_HOSTKARMA_YE,TW_EG X-Spam-Check-By: sourceware.org Received: from mail-qc0-f169.google.com (HELO mail-qc0-f169.google.com) (209.85.216.169) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 05 Jun 2012 12:58:21 +0000 Received: by qcsd16 with SMTP id d16so3216503qcs.0 for ; Tue, 05 Jun 2012 05:58:19 -0700 (PDT) MIME-Version: 1.0 Received: by 10.229.135.78 with SMTP id m14mr5046804qct.129.1338901099210; Tue, 05 Jun 2012 05:58:19 -0700 (PDT) Received: by 10.229.192.129 with HTTP; Tue, 5 Jun 2012 05:58:18 -0700 (PDT) In-Reply-To: References: <20120511181737.GP29339@adacore.com> <201205202043.q4KKhRGw022215@glazunov.sibelius.xs4all.nl> <201205202138.q4KLcWBf011913@glazunov.sibelius.xs4all.nl> <201205282026.q4SKQ737007589@glazunov.sibelius.xs4all.nl> Date: Tue, 05 Jun 2012 12:58:00 -0000 Message-ID: Subject: Re: x32 ABI Support (was Re: Three weeks to branching (gdb 7.5 release)) From: "H.J. Lu" To: Mark Kettenis Cc: gdb-patches@sourceware.org Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2012-06/txt/msg00118.txt.bz2 On Thu, May 31, 2012 at 11:18 AM, H.J. Lu wrote: > On Mon, May 28, 2012 at 2:18 PM, H.J. Lu wrote: >> On Mon, May 28, 2012 at 1:26 PM, Mark Kettenis = wrote: >>>> Date: Sun, 20 May 2012 15:48:54 -0700 >>>> From: "H.J. Lu" >>>> >>>> Does this one look OK. =A0I extracted x32_init_abi from amd64_x32_init= _abi >>>> since amd64_x32_linux_init_abi can't call amd64_init_abi after >>>> calling amd64_linux_init_abi. >>> >>> I guess multiple-inheritance is a bad idea, even when implemented in C = ;) >>> >>> I really do think that amd64_x32_linux_init_abi() should call >>> amd64_x32_init_abi(). =A0That way it is immediately obvious that the OS= -specific ABI inherits everything from the generic ABI. >> >> X32 kernel interface are highly OS specific. =A0Different OSes can imple= ment >> very different kernel interfaces. =A0The only generic x32 bits are >> >> =A0struct gdbarch_tdep *tdep =3D gdbarch_tdep (gdbarch); >> >> =A0tdep->num_dword_regs =3D 17; >> >> =A0set_tdesc_pseudo_register_type (gdbarch, amd64_x32_pseudo_register_ty= pe); >> >> =A0set_gdbarch_long_bit (gdbarch, 32); >> =A0set_gdbarch_ptr_bit (gdbarch, 32); >> >> They are the same for all x32 OSes since they are determined by >> hardware, not OS. >> >>> In order too avoid too much code duplication, the common bits should >>> be split out from amd64_linux_init_abi() into a seperate function that >>> gets called from both amd64_linux_init_abi() and >>> amd64_x32_linux_init_abi(). =A0As I wrote earlier, it isn't entirely >>> obvious that everything in amd64_linix_init_abi() applies to the x32 >>> ABI. =A0So we should be conservative in moving stuff into the common >>> function. =A0In fact it might be a good idea to start out with something >>> like the attached diff, and gradually move things over. >> >> Linux x32 kernel interface shares > 90% of Linux amd64 kernel >> interface (309 system calls out of 337 are the same). =A0See >> 64-bit system call table in Linux kernel 3.4: >> >> http://git.kernel.org/?p=3Dlinux/kernel/git/stable/linux-stable.git;a=3D= blob;f=3Darch/x86/syscalls/syscall_64.tbl;h=3Ddd29a9ea27c560a9d2fcb6e1c2983= f8b8e9be407;hb=3DHEAD >> >> I believe we should start with sharing everything between Linux/x32 >> and Linux/amd64. =A0We can update x32 part as we go. >> > > > Here is the updated patch. =A0I added amd64_x32_init for generic x32 > setting. =A0It can be used by all x32 init_abi functions. =A0Since > tdep->tdesc can't be changed after being used, I renamed > amd64_init_abi/amd64_init_abi to amd64_init/amd64_linux_init > to take an =A0argument to set tdep->tdesc properly. =A0OK for trunk? > > Thanks. > Hi Mark, Do you have a chance to take a look at this? Thanks. H.J. > -- > H.J. > --- > 2012-05-31 =A0Mark Kettenis =A0 > =A0 =A0 =A0 =A0 =A0 =A0H.J. Lu =A0 > > =A0 =A0 =A0 =A0* amd64-linux-tdep.c (amd64_linux_init_abi): Renamed to ... > =A0 =A0 =A0 =A0(amd64_linux_init): This. =A0Add an argument, amd64_linux_= tdesc. > =A0 =A0 =A0 =A0(amd64_linux_init_abi): Call amd64_linux_init. > =A0 =A0 =A0 =A0(amd64_x32_linux_init_abi): New function. > =A0 =A0 =A0 =A0(_initialize_amd64_linux_tdep): Register bfd_mach_x64_32 w= ith > =A0 =A0 =A0 =A0amd64_x32_linux_init_abi. > > =A0 =A0 =A0 =A0* amd64-tdep.c (amd64_dword_names): Add "eip". > =A0 =A0 =A0 =A0(amd64_x32_pseudo_register_type): New function. > =A0 =A0 =A0 =A0(amd64_x32_init): Likewise. > =A0 =A0 =A0 =A0(amd64_x32_init_abi): Likewise. > =A0 =A0 =A0 =A0(amd64_init_abi): Renamed to ... > =A0 =A0 =A0 =A0(amd64_init): This. Add an argument, amd64_tdesc. > =A0 =A0 =A0 =A0(amd64_init_abi): Call amd64_init. > > =A0 =A0 =A0 =A0* amd64-tdep.h (amd64_x32_init_abi): New prototype. > =A0 =A0 =A0 =A0(amd64_x32_init): Likewise. > > =A0 =A0 =A0 =A0* i386-tdep.c (i386_pseudo_register_type): Make it global. > > =A0 =A0 =A0 =A0* i386-tdep.h (i386_pseudo_register_type): New prototype. > > diff --git a/gdb/amd64-linux-tdep.c b/gdb/amd64-linux-tdep.c > index 42dc89a..23bf318 100644 > --- a/gdb/amd64-linux-tdep.c > +++ b/gdb/amd64-linux-tdep.c > @@ -1288,7 +1288,8 @@ amd64_linux_core_read_description (struct > gdbarch *gdbarch, > =A0} > > =A0static void > -amd64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) > +amd64_linux_init (struct gdbarch_info info, struct gdbarch *gdbarch, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 const struct target_desc *amd64_linux_t= desc) > =A0{ > =A0 struct gdbarch_tdep *tdep =3D gdbarch_tdep (gdbarch); > =A0 const struct target_desc *tdesc =3D info.target_desc; > @@ -1310,9 +1311,10 @@ amd64_linux_init_abi (struct gdbarch_info info, > struct gdbarch *gdbarch) > =A0 set_gdbarch_num_regs (gdbarch, AMD64_LINUX_NUM_REGS); > > =A0 if (! tdesc_has_registers (tdesc)) > - =A0 =A0tdesc =3D tdesc_amd64_linux; > + =A0 =A0tdesc =3D amd64_linux_tdesc; > =A0 tdep->tdesc =3D tdesc; > > + =A0/* tdep->tdesc can't be changed after being used here. =A0*/ > =A0 feature =3D tdesc_find_feature (tdesc, "org.gnu.gdb.i386.linux"); > =A0 if (feature =3D=3D NULL) > =A0 =A0 return; > @@ -1543,6 +1545,24 @@ amd64_linux_init_abi (struct gdbarch_info info, > struct gdbarch *gdbarch) > > =A0 tdep->i386_syscall_record =3D amd64_linux_syscall_record; > =A0} > + > +static void > +amd64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) > +{ > + =A0amd64_linux_init (info, gdbarch, tdesc_amd64_linux); > +} > + > +static void > +amd64_x32_linux_init_abi (struct gdbarch_info info, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 struct gdbarch *gdbarch) > +{ > + =A0amd64_linux_init (info, gdbarch, tdesc_x32_linux); > + =A0amd64_x32_init (gdbarch); > + > + =A0 /* GNU/Linux uses SVR4-style shared libraries. =A0*/ > + =A0set_solib_svr4_fetch_link_map_offsets > + =A0 =A0(gdbarch, svr4_ilp32_fetch_link_map_offsets); > +} > > > > =A0/* Provide a prototype to silence -Wmissing-prototypes. =A0*/ > @@ -1553,6 +1573,8 @@ _initialize_amd64_linux_tdep (void) > =A0{ > =A0 gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64, > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0GDB_OSABI_LINUX, amd64= _linux_init_abi); > + =A0gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x64_32, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 GDB_OSABI_LINUX, amd64_= x32_linux_init_abi); > > =A0 /* Initialize the Linux target description. =A0*/ > =A0 initialize_tdesc_amd64_linux (); > diff --git a/gdb/amd64-tdep.c b/gdb/amd64-tdep.c > index df91a51..47f8019 100644 > --- a/gdb/amd64-tdep.c > +++ b/gdb/amd64-tdep.c > @@ -258,9 +258,32 @@ static const char *amd64_word_names[] =3D > =A0static const char *amd64_dword_names[] =3D > =A0{ > =A0 "eax", "ebx", "ecx", "edx", "esi", "edi", "ebp", "esp", > - =A0"r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d" > + =A0"r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d", > + =A0"eip" > =A0}; > > +/* Return the GDB type object for the "standard" data type of data in > + =A0 register REGNUM. =A0Only used for x32. =A0*/ > + > +static struct type * > +amd64_x32_pseudo_register_type (struct gdbarch *gdbarch, int regnum) > +{ > + =A0/* Use pointer types for ebp, esp and eip registers in x32. =A0*/ > + =A0struct gdbarch_tdep *tdep =3D gdbarch_tdep (gdbarch); > + =A0switch (regnum - tdep->eax_regnum) > + =A0 =A0{ > + =A0 =A0default: > + =A0 =A0 =A0break; > + =A0 =A0case AMD64_RBP_REGNUM: =A0 =A0 /* ebp =A0*/ > + =A0 =A0case AMD64_RSP_REGNUM: =A0 =A0 /* esp =A0*/ > + =A0 =A0 =A0return builtin_type (gdbarch)->builtin_data_ptr; > + =A0 =A0case AMD64_RIP_REGNUM: =A0 =A0 /* eip */ > + =A0 =A0 =A0return builtin_type (gdbarch)->builtin_func_ptr; > + =A0 =A0} > + > + =A0return i386_pseudo_register_type (gdbarch, regnum); > +} > + > =A0/* Return the name of register REGNUM. =A0*/ > > =A0static const char * > @@ -2606,8 +2629,9 @@ static const int amd64_record_regmap[] =3D > =A0 AMD64_DS_REGNUM, AMD64_ES_REGNUM, AMD64_FS_REGNUM, AMD64_GS_REGNUM > =A0}; > > -void > -amd64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) > +static void > +amd64_init (struct gdbarch_info info, struct gdbarch *gdbarch, > + =A0 =A0 =A0 =A0 =A0 const struct target_desc *amd64_tdesc) > =A0{ > =A0 struct gdbarch_tdep *tdep =3D gdbarch_tdep (gdbarch); > =A0 const struct target_desc *tdesc =3D info.target_desc; > @@ -2617,12 +2641,13 @@ amd64_init_abi (struct gdbarch_info info, > struct gdbarch *gdbarch) > =A0 tdep->sizeof_fpregset =3D I387_SIZEOF_FXSAVE; > > =A0 if (! tdesc_has_registers (tdesc)) > - =A0 =A0tdesc =3D tdesc_amd64; > + =A0 =A0tdesc =3D amd64_tdesc; > =A0 tdep->tdesc =3D tdesc; > > =A0 tdep->num_core_regs =3D AMD64_NUM_GREGS + I387_NUM_REGS; > =A0 tdep->register_names =3D amd64_register_names; > > + =A0/* tdep->tdesc can't be changed after being used here. =A0*/ > =A0 if (tdesc_find_feature (tdesc, "org.gnu.gdb.i386.avx") !=3D NULL) > =A0 =A0 { > =A0 =A0 =A0 tdep->ymmh_register_names =3D amd64_ymmh_names; > @@ -2730,6 +2755,32 @@ amd64_init_abi (struct gdbarch_info info, > struct gdbarch *gdbarch) > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0i386_stap_parse_special_token); > =A0} > > +void > +amd64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) > +{ > + =A0amd64_init (info, gdbarch, tdesc_amd64); > +} > + > +void > +amd64_x32_init (struct gdbarch *gdbarch) > +{ > + =A0struct gdbarch_tdep *tdep =3D gdbarch_tdep (gdbarch); > + > + =A0tdep->num_dword_regs =3D 17; > + > + =A0set_tdesc_pseudo_register_type (gdbarch, amd64_x32_pseudo_register_t= ype); > + > + =A0set_gdbarch_long_bit (gdbarch, 32); > + =A0set_gdbarch_ptr_bit (gdbarch, 32); > +} > + > +void > +amd64_x32_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) > +{ > + =A0amd64_init (info, gdbarch, tdesc_x32); > + =A0amd64_x32_init (gdbarch); > +} > + > =A0/* Provide a prototype to silence -Wmissing-prototypes. =A0*/ > =A0void _initialize_amd64_tdep (void); > > diff --git a/gdb/amd64-tdep.h b/gdb/amd64-tdep.h > index 1ed109c..ce47ae7 100644 > --- a/gdb/amd64-tdep.h > +++ b/gdb/amd64-tdep.h > @@ -80,6 +80,9 @@ extern void amd64_displaced_step_fixup (struct > gdbarch *gdbarch, > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0struct regcache *regs); > > =A0extern void amd64_init_abi (struct gdbarch_info info, struct gdbarch *= gdbarch); > +extern void amd64_x32_init_abi (struct gdbarch_info info, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 struct gdba= rch *gdbarch); > +extern void amd64_x32_init (struct gdbarch *gdbarch); > > =A0/* Fill register REGNUM in REGCACHE with the appropriate > =A0 =A0floating-point or SSE register value from *FXSAVE. =A0If REGNUM is > diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c > index 5b04505..6333556 100644 > --- a/gdb/i386-tdep.c > +++ b/gdb/i386-tdep.c > @@ -2780,7 +2780,7 @@ i386_mmx_type (struct gdbarch *gdbarch) > =A0/* Return the GDB type object for the "standard" data type of data in > =A0 =A0register REGNUM. =A0*/ > > -static struct type * > +struct type * > =A0i386_pseudo_register_type (struct gdbarch *gdbarch, int regnum) > =A0{ > =A0 if (i386_mmx_regnum_p (gdbarch, regnum)) > diff --git a/gdb/i386-tdep.h b/gdb/i386-tdep.h > index f297ae7..a12b1f5 100644 > --- a/gdb/i386-tdep.h > +++ b/gdb/i386-tdep.h > @@ -307,6 +307,7 @@ extern int i386_dword_regnum_p (struct gdbarch > *gdbarch, int regnum); > =A0extern int i386_xmm_regnum_p (struct gdbarch *gdbarch, int regnum); > =A0extern int i386_ymm_regnum_p (struct gdbarch *gdbarch, int regnum); > > +extern struct type *i386_pseudo_register_type (struct gdbarch *, int); > =A0extern const char *i386_pseudo_register_name (struct gdbarch *gdbarch, > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0 =A0 =A0 =A0int regnum);