From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 17518 invoked by alias); 18 Dec 2012 04:56:32 -0000 Received: (qmail 17507 invoked by uid 22791); 18 Dec 2012 04:56:28 -0000 X-SWARE-Spam-Status: No, hits=-4.4 required=5.0 tests=AWL,BAYES_00,KHOP_RCVD_UNTRUST,KHOP_THREADED,RCVD_IN_HOSTKARMA_W,RCVD_IN_HOSTKARMA_WL,TW_CP,TW_EG,TW_FN X-Spam-Check-By: sourceware.org Received: from relay1.mentorg.com (HELO relay1.mentorg.com) (192.94.38.131) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 18 Dec 2012 04:56:20 +0000 Received: from svr-orw-fem-01.mgc.mentorg.com ([147.34.98.93]) by relay1.mentorg.com with esmtp id 1TkpE2-0003d5-JI from Yao_Qi@mentor.com ; Mon, 17 Dec 2012 20:56:18 -0800 Received: from SVR-ORW-FEM-05.mgc.mentorg.com ([147.34.97.43]) by svr-orw-fem-01.mgc.mentorg.com over TLS secured channel with Microsoft SMTPSVC(6.0.3790.4675); Mon, 17 Dec 2012 20:56:18 -0800 Received: from qiyao.dyndns.org (147.34.91.1) by svr-orw-fem-05.mgc.mentorg.com (147.34.97.43) with Microsoft SMTP Server id 14.1.289.1; Mon, 17 Dec 2012 20:56:16 -0800 Message-ID: <50CFF750.2090905@codesourcery.com> Date: Tue, 18 Dec 2012 04:56:00 -0000 From: Yao Qi User-Agent: Mozilla/5.0 (X11; Linux i686; rv:15.0) Gecko/20120911 Thunderbird/15.0.1 MIME-Version: 1.0 To: Joel Brobecker CC: Subject: Re: [RFA/commit] Port GDB to powerpc-lynx178. References: <1355764695-5013-1-git-send-email-brobecker@adacore.com> In-Reply-To: <1355764695-5013-1-git-send-email-brobecker@adacore.com> Content-Type: text/plain; charset="UTF-8"; format=flowed Content-Transfer-Encoding: 8bit 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-12/txt/msg00607.txt.bz2 On 12/18/2012 01:18 AM, Joel Brobecker wrote: > diff --git a/gdb/rs6000-lynx178-tdep.c b/gdb/rs6000-lynx178-tdep.c > new file mode 100644 > index 0000000..21d6d84 > --- /dev/null > +++ b/gdb/rs6000-lynx178-tdep.c > @@ -0,0 +1,420 @@ > +/* Copyright (C) 2006-2012 Free Software Foundation, Inc. > + > + This file is part of GDB. > + > + This program is free software; you can redistribute it and/or modify > + it under the terms of the GNU General Public License as published by > + the Free Software Foundation; either version 3 of the License, or > + (at your option) any later version. > + > + This program is distributed in the hope that it will be useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + GNU General Public License for more details. > + > + You should have received a copy of the GNU General Public License > + along with this program. If not, see. */ > + > +#include "defs.h" > +#include "osabi.h" > +#include "regcache.h" > +#include "gdbcore.h" > +#include "gdbtypes.h" > +#include "infcall.h" > +#include "ppc-tdep.h" > +#include "value.h" > +#include "xcoffread.h" > + > +/* Implement the "push_dummy_call" gdbarch method. */ > + > +static CORE_ADDR > +rs6000_lynx178_push_dummy_call (struct gdbarch *gdbarch, struct value *function, > + struct regcache *regcache, CORE_ADDR bp_addr, > + int nargs, struct value **args, CORE_ADDR sp, > + int struct_return, CORE_ADDR struct_addr) > +{ > + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); > + enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); > + int ii; > + int len = 0; > + int argno; /* current argument number */ > + int argbytes; /* current argument byte */ > + gdb_byte tmp_buffer[50]; > + int f_argno = 0; /* current floating point argno */ > + int wordsize = gdbarch_tdep (gdbarch)->wordsize; > + CORE_ADDR func_addr = find_function_addr (function, NULL); > + > + struct value *arg = 0; > + struct type *type; > + > + ULONGEST saved_sp; > + > + /* The calling convention this function implements assumes the > + processor has floating-point registers. We shouldn't be using it > + on PPC variants that lack them. */ > + gdb_assert (ppc_floating_point_unit_p (gdbarch)); > + > + /* The first eight words of ther arguments are passed in registers. > + Copy them appropriately. */ > + ii = 0; > + > + /* If the function is returning a `struct', then the first word > + (which will be passed in r3) is used for struct return address. > + In that case we should advance one word and start from r4 > + register to copy parameters. */ > + if (struct_return) > + { > + regcache_raw_write_unsigned (regcache, tdep->ppc_gp0_regnum + 3, > + struct_addr); > + ii++; > + } > + > + /* Effectively indirect call... gcc does... > + > + return_val example( float, int); > + > + eabi: > + float in fp0, int in r3 > + offset of stack on overflow 8/16 > + for varargs, must go by type. > + power open: > + float in r3&r4, int in r5 > + offset of stack on overflow different > + both: > + return in r3 or f0. If no float, must study how gcc emulates floats; > + pay attention to arg promotion. > + User may have to cast\args to handle promotion correctly > + since gdb won't know if prototype supplied or not. */ > + > + for (argno = 0, argbytes = 0; argno < nargs && ii < 8; ++ii) > + { > + int reg_size = register_size (gdbarch, ii + 3); > + > + arg = args[argno]; > + type = check_typedef (value_type (arg)); > + len = TYPE_LENGTH (type); > + > + if (TYPE_CODE (type) == TYPE_CODE_FLT) > + { > + > + /* Floating point arguments are passed in fpr's, as well as gpr's. > + There are 13 fpr's reserved for passing parameters. At this point > + there is no way we would run out of them. */ > + > + gdb_assert (len <= 8); > + > + regcache_cooked_write (regcache, > + tdep->ppc_fp0_regnum + 1 + f_argno, > + value_contents (arg)); > + ++f_argno; > + } > + > + if (len > reg_size) > + { > + > + /* Argument takes more than one register. */ > + while (argbytes < len) > + { > + gdb_byte word[MAX_REGISTER_SIZE]; > + memset (word, 0, reg_size); > + memcpy (word, > + ((char *) value_contents (arg)) + argbytes, > + (len - argbytes) > reg_size > + ? reg_size : len - argbytes); > + regcache_cooked_write (regcache, > + tdep->ppc_gp0_regnum + 3 + ii, > + word); > + ++ii, argbytes += reg_size; > + > + if (ii >= 8) > + goto ran_out_of_registers_for_arguments; > + } > + argbytes = 0; > + --ii; > + } > + else > + { > + /* Argument can fit in one register. No problem. */ > + int adj = gdbarch_byte_order (gdbarch) > + == BFD_ENDIAN_BIG ? reg_size - len : 0; > + gdb_byte word[MAX_REGISTER_SIZE]; > + > + memset (word, 0, reg_size); > + memcpy (word, value_contents (arg), len); > + regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 3 +ii, word); > + } > + ++argno; > + } > + > +ran_out_of_registers_for_arguments: > + > + regcache_cooked_read_unsigned (regcache, > + gdbarch_sp_regnum (gdbarch), > + &saved_sp); > + > + /* Location for 8 parameters are always reserved. */ > + sp -= wordsize * 8; > + > + /* Another six words for back chain, TOC register, link register, etc. */ > + sp -= wordsize * 6; > + > + /* Stack pointer must be quadword aligned. */ > + sp &= -16; How about 'sp = align_down (sp, 16);'? > + > + /* If there are more arguments, allocate space for them in > + the stack, then push them starting from the ninth one. */ > + > + if ((argno < nargs) || argbytes) > + { > + int space = 0, jj; > + > + if (argbytes) > + { > + space += ((len - argbytes + 3) & -4); > + jj = argno + 1; > + } > + else > + jj = argno; > + > + for (; jj < nargs; ++jj) > + { > + struct value *val = args[jj]; > + space += ((TYPE_LENGTH (value_type (val))) + 3) & -4; > + } > + > + /* Add location required for the rest of the parameters. */ > + space = (space + 15) & -16; How about 'space = align_up (space, 16);'? and we may use 'align_up (XXX, 4)' somewhere else in this patch. > + > +/* PowerPC Lynx178 OSABI sniffer. */ > + > +static enum gdb_osabi > +rs6000_lynx178_osabi_sniffer (bfd *abfd) > +{ > + if (bfd_get_flavour (abfd) != bfd_target_xcoff_flavour) > + return GDB_OSABI_UNKNOWN; > + > + /* The only noticeable difference between Lynx178 XCOFF files and > + AIX XCOFF files comes from the fact that there are no shared > + libraries on Lynx178. So if the number of import files is > + different from zero, it cannot be a Lynx178 binary. */ > + if (xcoff_get_n_import_files (abfd) != 0) > + return GDB_OSABI_UNKNOWN; As your comments said, we need the function returning a flag indicating 'the xcoff file has shared libraries or not', and looks the precise number of import files doesn't matter here. I suggest that rename function 'xcoff_get_n_import_files' to 'xcoff_has_import_files'. > + > diff --git a/gdb/xcoffread.c b/gdb/xcoffread.c > index 10c93cc..7838ac1 100644 > --- a/gdb/xcoffread.c > +++ b/gdb/xcoffread.c > @@ -3113,6 +3113,67 @@ static const struct sym_fns xcoff_sym_fns = > &psym_functions > }; > > + > +/* Return the number of import files (shared libraries) that the given > + BFD depends on. Return -1 if this number could not be computed. */ > + > +extern int > +xcoff_get_n_import_files (bfd *abfd) As I said above, we can define this function: int xcoff_has_import_files (bfd *abfd) which returns 1 when the BFD has the import files and returns 0 when the BFD doesn't. Returns -1 when it is unknown. -- Yao (齐尧)