From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 1291 invoked by alias); 23 Nov 2016 22:11:31 -0000 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 Received: (qmail 130243 invoked by uid 89); 23 Nov 2016 22:11:29 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.9 required=5.0 tests=AWL,BAYES_00,FREEMAIL_FROM,RCVD_IN_DNSWL_NONE,SPF_PASS autolearn=ham version=3.3.2 spammy=bits_per_word, 1304,6, sk:gdbarch, 13046 X-HELO: mail-pg0-f65.google.com Received: from mail-pg0-f65.google.com (HELO mail-pg0-f65.google.com) (74.125.83.65) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 23 Nov 2016 22:11:22 +0000 Received: by mail-pg0-f65.google.com with SMTP id e9so1920989pgc.1 for ; Wed, 23 Nov 2016 14:11:21 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=K3pVO0a57iVMiSNT4Q89WsG1stCxcCUPDdk+DhsMNBE=; b=O9JuXeX5wkTLPx7OOPRthFof9S1F7M7Jolsac997xZ68dYW6IAWOBOPkY5nngpkHnG FI7wq7I6JTgSXKVxMlej9UxoeiexE/f66SplmaZGpVY/XzK6i24BZJ9x7Z9fqASWtrF9 a0+xGBZ188SAwKrNbxY3NSnRnefv+2IyNbSlzzHj9dXmlRscKGRi9mj0Y6sbv76dkPek RZ5ahFxVI92mYaeFKYE5G3kVy3MpFbDVqC3hcXgB38Dz0Qlo3o4ZDdwbUB0gY6KA3nr+ he2fEnyt8ppLs2I01hF9a/siWxp4Lr+RAbCGb1lYXzRNWOTuO7QDTrcd2imZww/7Mk6s Uaag== X-Gm-Message-State: AKaTC02adheoNrup5AtJCGApEkKItGfyFt6HvATvMR3Tj3g6z3ubD2XfxOOqtsgHE/RLOw== X-Received: by 10.98.63.148 with SMTP id z20mr4951090pfj.151.1479939080131; Wed, 23 Nov 2016 14:11:20 -0800 (PST) Received: from lianli.shorne-pla.net (z14.124-44-185.ppp.wakwak.ne.jp. [124.44.185.14]) by smtp.gmail.com with ESMTPSA id w24sm54967451pfa.9.2016.11.23.14.11.18 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 23 Nov 2016 14:11:18 -0800 (PST) Received: from lianli.shorne-pla.net (localhost [127.0.0.1]) by lianli.shorne-pla.net (8.15.2/8.15.2) with ESMTPS id uANMBGnN001519 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Thu, 24 Nov 2016 07:11:16 +0900 Received: (from shorne@localhost) by lianli.shorne-pla.net (8.15.2/8.15.2/Submit) id uANMBGDK001515; Thu, 24 Nov 2016 07:11:16 +0900 From: Stafford Horne To: gdb-patches@sourceware.org Cc: openrisc@lists.librecores.org, Stafford Horne Subject: [PATCH 15/18] gdb: or1k: Update calling conventions to help pass tests Date: Wed, 23 Nov 2016 22:11:00 -0000 Message-Id: <1479939044-1341-16-git-send-email-shorne@gmail.com> In-Reply-To: <1479939044-1341-1-git-send-email-shorne@gmail.com> References: <1479939044-1341-1-git-send-email-shorne@gmail.com> X-IsSubscribed: yes X-SW-Source: 2016-11/txt/msg00697.txt.bz2 The calling conventions for handling struct/array return, large scalars and variadic args were incomplete and causing several gdb testsuite tests to fail. These changes were developed with help from olofk. --- gdb/or1k-tdep.c | 78 +++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 53 insertions(+), 25 deletions(-) diff --git a/gdb/or1k-tdep.c b/gdb/or1k-tdep.c index 8cfa440..a0fd651 100644 --- a/gdb/or1k-tdep.c +++ b/gdb/or1k-tdep.c @@ -439,12 +439,12 @@ or1k_return_value (struct gdbarch *gdbarch, unsigned int rv_size = TYPE_LENGTH (valtype); unsigned int bpw = (gdbarch_tdep (gdbarch))->bytes_per_word; - /* Deal with struct/union first. If this won't fit in a single register it - is returned in memory. Large (2 word) scalars are returned in r11 and r12 - (this is a change from GCC 4.2.2, when they were apparently returned in - memory). */ - if (((TYPE_CODE_STRUCT == rv_type) || (TYPE_CODE_UNION == rv_type)) && - (rv_size > bpw)) + /* Deal with struct/union as addresses. If an array won't fit in a single + register it is returned as address. Anything larger than 2 registers needs + to also be passed as address (this is from gcc default_return_in_memory) */ + if ((TYPE_CODE_STRUCT == rv_type) || (TYPE_CODE_UNION == rv_type) || + ((TYPE_CODE_ARRAY == rv_type) && rv_size > bpw) || + (rv_size > 2*bpw)) { if (readbuf) { @@ -1225,9 +1225,12 @@ or1k_push_dummy_call (struct gdbarch *gdbarch, int argnum; int first_stack_arg; int stack_offset = 0; + int heap_offset = 0; + CORE_ADDR heap_sp = sp - 128; unsigned int bpa = (gdbarch_tdep (gdbarch))->bytes_per_address; unsigned int bpw = (gdbarch_tdep (gdbarch))->bytes_per_word; + struct type *func_type = value_type (function); /* Return address */ regcache_cooked_write_unsigned (regcache, OR1K_LR_REGNUM, bp_addr); @@ -1237,7 +1240,6 @@ or1k_push_dummy_call (struct gdbarch *gdbarch, /* Location for a returned structure. This is passed as a silent first argument. */ - if (struct_return) { regcache_cooked_write_unsigned (regcache, OR1K_FIRST_ARG_REGNUM, @@ -1256,13 +1258,31 @@ or1k_push_dummy_call (struct gdbarch *gdbarch, int len = arg_type->length; enum type_code typecode = arg_type->main_type->code; - /* Handle the different argument types. */ - if((TYPE_CODE_STRUCT == typecode) || (TYPE_CODE_UNION == typecode)) + if (TYPE_VARARGS (func_type) && argnum >= TYPE_NFIELDS(func_type)) + { + break; /* end or regular args, varargs go to stack */ + } + + /* Extract the value, either a reference or the data */ + if ((TYPE_CODE_STRUCT == typecode) || (TYPE_CODE_UNION == typecode) || (len > bpw*2)) { - /* The ABI passes all structures by reference, so get its address. */ - store_unsigned_integer (valbuf, bpa, byte_order, value_address (arg)); - len = bpa; - val = valbuf; + CORE_ADDR valaddr = value_address (arg); + + /* if the arg is fabricated (i.e. 3*i, instead of i) valaddr is undefined */ + if (valaddr == 0) { + /* The argument needs to be copied into the target space. Since + the bottom of the stack is reserved for function arguments + we store this at the these at the top growing down. */ + heap_offset += align_up (len, bpw); + valaddr = heap_sp + heap_offset; + + write_memory (valaddr, value_contents(arg), len); + } + + /* The ABI passes all structures by reference, so get its address. */ + store_unsigned_integer (valbuf, bpa, byte_order, valaddr); + len = bpa; + val = valbuf; } else { @@ -1273,9 +1293,7 @@ or1k_push_dummy_call (struct gdbarch *gdbarch, /* Stick the value in a register */ if(len > bpw) { - /* Big scalars use two registers, but need NOT be pair aligned. This - code breaks if we can have quad-word scalars (e.g. long - double). */ + /* Big scalars use two registers, but need NOT be pair aligned. */ if (argreg <= (OR1K_LAST_ARG_REGNUM - 1)) { @@ -1286,8 +1304,6 @@ or1k_push_dummy_call (struct gdbarch *gdbarch, ULONGEST lo = regval & mask; ULONGEST hi = regval >> bits_per_word; - gdb_assert (len <= (bpw * 2)); - regcache_cooked_write_unsigned (regcache, argreg, hi); regcache_cooked_write_unsigned (regcache, argreg + 1, lo); argreg += 2; @@ -1328,7 +1344,7 @@ or1k_push_dummy_call (struct gdbarch *gdbarch, int len = arg_type->length; enum type_code typecode = arg_type->main_type->code; - if((TYPE_CODE_STRUCT == typecode) || (TYPE_CODE_UNION == typecode)) + if ((TYPE_CODE_STRUCT == typecode) || (TYPE_CODE_UNION == typecode) || (len > bpw*2)) { /* Structures are passed as addresses */ sp -= bpa; @@ -1337,8 +1353,12 @@ or1k_push_dummy_call (struct gdbarch *gdbarch, { /* Big scalars use more than one word. Code here allows for future quad-word entities (e.g. long double) */ - sp -= ((len + bpw - 1) / bpw) * bpw; + sp -= align_up(len, bpw); } + + /* ensure our dummy heap doesn't touch the stack, this could only happen + if we have many arguments including fabricated arguments */ + gdb_assert(heap_offset == 0 || ((heap_sp + heap_offset) < sp)); } sp = gdbarch_frame_align (gdbarch, sp); @@ -1354,10 +1374,9 @@ or1k_push_dummy_call (struct gdbarch *gdbarch, struct type *arg_type = check_typedef (value_type (arg)); int len = arg_type->length; enum type_code typecode = arg_type->main_type->code; - /* The EABI passes structures that do not fit in a register by reference. In all other cases, pass the structure by value. */ - if((TYPE_CODE_STRUCT == typecode) || (TYPE_CODE_UNION == typecode)) + if ((TYPE_CODE_STRUCT == typecode) || (TYPE_CODE_UNION == typecode) || (len > bpw*2)) { store_unsigned_integer (valbuf, bpa, byte_order, value_address (arg)); len = bpa; @@ -1368,15 +1387,24 @@ or1k_push_dummy_call (struct gdbarch *gdbarch, val = value_contents (arg); } - gdb_assert (len <= (bpw * 2)); + while (len > 0) + { + int partial_len = (len < bpw ? len : bpw); - write_memory (sp + stack_offset, val, len); - stack_offset += ((len + bpw - 1) / bpw) * bpw; + write_memory (sp + stack_offset, val, partial_len); + stack_offset += align_up (partial_len, bpw); + len -= partial_len; + val += partial_len; + } } /* Save the updated stack pointer */ regcache_cooked_write_unsigned (regcache, OR1K_SP_REGNUM, sp); + if (heap_offset > 0) { + sp = heap_sp; + } + return sp; } /* or1k_push_dummy_call() */ -- 2.7.4