From patchwork Sat Mar 20 16:26:31 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Harmstone X-Patchwork-Id: 1456136 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=sourceware.org; envelope-from=gcc-patches-bounces@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=sJ3/6F18; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4F2mPW6MkXz9sSC for ; Sun, 21 Mar 2021 03:27:11 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 8816C3857C62; Sat, 20 Mar 2021 16:27:04 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-wm1-x334.google.com (mail-wm1-x334.google.com [IPv6:2a00:1450:4864:20::334]) by sourceware.org (Postfix) with ESMTPS id 018E3385800D for ; Sat, 20 Mar 2021 16:27:00 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 018E3385800D Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=harmstone.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=mark.harmstone@gmail.com Received: by mail-wm1-x334.google.com with SMTP id t5-20020a1c77050000b029010e62cea9deso6859207wmi.0 for ; Sat, 20 Mar 2021 09:27:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=HEJf5prRk0JvC0RfPz+YqSHB2ZYGG9CR2lY359amC3U=; b=sJ3/6F18OJUUiNn31hQTvZ/sU5Fw1V1jElaK2eP03PZmzGr30ehmqQTOytCdp6UO9T EdukzjiC0iszhdJX+C9t/QfPKJh72kEiDFO1/sGVu6gRN61/AwWFQ3RrJNB++reXhn94 I8zmRvBB+hoOE3W29tIA9z5IJl+M48XJub+2xuMOmklzf8uSbPyRKOmt+ya43Dqn9xva hs8f1gU/7sXdIhrpxS1Jf2HD+YzpZN6AsdHQl1MChhJcFl0PCoBuKIDPy3fSe6oyRSYi kjYodNgZpAuD8xyw4Ev0NEfg4xZmNJZaxi2R0iH9jm5ov2HjIn9nSzgTFV8WJ2YVBryt y8dw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=HEJf5prRk0JvC0RfPz+YqSHB2ZYGG9CR2lY359amC3U=; b=PkPQyO1XoaVeGMsU74+DoPb0mg4ioSZt35vYXr9Y/z+CJ4qSkcr0UjDu8cLx/AiDiV SXKxsT48IUIDrJZ9TCPMYfH6uFMhMD/nYO9z1GYKEc34WN78wnIVP2E/ju8OVExa48PE 6o3lOmVdehEefToZpL6//Ll/PBTlsNWVuM645ahUOELA9OTSBf0Xg8bQNhodpUB+L1aq o0a+T3ojqramIp9jh4xhC1icmbZLmaOA4JN0MLeuiYFX9ejxT6aB0SP37BdqblgcrPRL 5kiojXY2Beu7ll+Cu6FLqsULK2MSRTyuND4qOnY0WzilCTAOzIkmHgpDPCxgG/PVLr6l EoYQ== X-Gm-Message-State: AOAM533aa1ft3PrgS/PfH/wRReOT6zC2hiCYWdVyDWjYSO/o7h9ZpQrY h34GGjMgwNt+SvwiBAeqjfE1haK9A/4= X-Google-Smtp-Source: ABdhPJxaOBLVROknegP13PH+148a2zK+xS048s2+Trumd4Yq25SVuatEHC67cEYTXgf2UdeOr7f+cw== X-Received: by 2002:a1c:cc04:: with SMTP id h4mr8360653wmb.142.1616257619836; Sat, 20 Mar 2021 09:26:59 -0700 (PDT) Received: from localhost.localdomain ([2a02:8010:64ea:0:fad1:11ff:fead:57db]) by smtp.gmail.com with ESMTPSA id v18sm14200785wrf.41.2021.03.20.09.26.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 20 Mar 2021 09:26:59 -0700 (PDT) From: Mark Harmstone To: gcc-patches@gcc.gnu.org Subject: [PATCH 03/24] pdbout: Output function details. Date: Sat, 20 Mar 2021 16:26:31 +0000 Message-Id: <20210320162652.23346-3-mark@harmstone.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20210320162652.23346-1-mark@harmstone.com> References: <20210320162652.23346-1-mark@harmstone.com> MIME-Version: 1.0 X-Spam-Status: No, score=-12.4 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_EF, FREEMAIL_FORGED_FROMDOMAIN, FREEMAIL_FROM, GIT_PATCH_0, HEADER_FROM_DIFFERENT_DOMAINS, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Mark Harmstone Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "Gcc-patches" --- gcc/pdbout.c | 149 +++++++++++++++++++++++++++++++++++++++++++++++++-- gcc/pdbout.h | 12 +++++ 2 files changed, 158 insertions(+), 3 deletions(-) diff --git a/gcc/pdbout.c b/gcc/pdbout.c index feaab37cc37..17011134d7a 100644 --- a/gcc/pdbout.c +++ b/gcc/pdbout.c @@ -29,14 +29,25 @@ #include "tree.h" #include "debug.h" #include "pdbout.h" +#include "function.h" #include "output.h" #include "target.h" +#define FUNC_BEGIN_LABEL ".Lstartfunc" +#define FUNC_END_LABEL ".Lendfunc" + +static void pdbout_begin_prologue (unsigned int line ATTRIBUTE_UNUSED, + unsigned int column ATTRIBUTE_UNUSED, + const char *file ATTRIBUTE_UNUSED); +static void pdbout_end_epilogue (unsigned int line ATTRIBUTE_UNUSED, + const char *file ATTRIBUTE_UNUSED); static void pdbout_finish (const char *filename); +static void pdbout_begin_function (tree func); static void pdbout_late_global_decl (tree var); static struct pdb_type *find_type (tree t); +static struct pdb_func *funcs = NULL, *cur_func = NULL; static struct pdb_global_var *global_vars = NULL; static struct pdb_type *types = NULL, *last_type = NULL; static hash_table tree_hash_table (31); @@ -66,11 +77,11 @@ const struct gcc_debug_hooks pdb_debug_hooks = { debug_nothing_int_int, /* end_block */ debug_true_const_tree, /* ignore_block */ debug_nothing_int_int_charstar_int_bool, /* source_line */ - debug_nothing_int_int_charstar, /* begin_prologue */ + pdbout_begin_prologue, debug_nothing_int_charstar, /* end_prologue */ debug_nothing_int_charstar, /* begin_epilogue */ - debug_nothing_int_charstar, /* end_epilogue */ - debug_nothing_tree, /* begin_function */ + pdbout_end_epilogue, + pdbout_begin_function, debug_nothing_int, /* end_function */ debug_nothing_tree, /* register_main_translation_unit */ debug_nothing_tree, /* function_decl */ @@ -93,6 +104,84 @@ const struct gcc_debug_hooks pdb_debug_hooks = { TYPE_SYMTAB_IS_ADDRESS /* tree_type_symtab_field */ }; +/* Add label before function start */ +static void +pdbout_begin_prologue (unsigned int line ATTRIBUTE_UNUSED, + unsigned int column ATTRIBUTE_UNUSED, + const char *file ATTRIBUTE_UNUSED) +{ + fprintf (asm_out_file, FUNC_BEGIN_LABEL "%u:\n", + current_function_funcdef_no); +} + +/* Add label after function end */ +static void +pdbout_end_epilogue (unsigned int line ATTRIBUTE_UNUSED, + const char *file ATTRIBUTE_UNUSED) +{ + fprintf (asm_out_file, FUNC_END_LABEL "%u:\n", current_function_funcdef_no); +} + +/* Output PROCSYM32 structure, which describes a global function (S_GPROC32) + * or a local (i.e. static) one (S_LPROC32). */ +static void +pdbout_proc32 (struct pdb_func *func) +{ + size_t name_len = func->name ? strlen (func->name) : 0; + uint16_t len = 40 + name_len, align; + + // start procedure + + if (len % 4 != 0) + { + align = 4 - (len % 4); + len += 4 - (len % 4); + } + else + align = 0; + + fprintf (asm_out_file, ".Lcvprocstart%u:\n", func->num); + fprintf (asm_out_file, "\t.short\t0x%x\n", + (uint16_t) (len - sizeof (uint16_t))); // reclen + fprintf (asm_out_file, "\t.short\t0x%x\n", + func->public_flag ? S_GPROC32 : S_LPROC32); + fprintf (asm_out_file, "\t.long\t0\n"); // pParent + fprintf (asm_out_file, "\t.long\t[.Lcvprocend%u]-[.debug$S]\n", + func->num); // pEnd + fprintf (asm_out_file, "\t.long\t0\n"); // pNext + fprintf (asm_out_file, + "\t.long\t[" FUNC_END_LABEL "%u]-[" FUNC_BEGIN_LABEL "%u]\n", + func->num, func->num); // len + fprintf (asm_out_file, "\t.long\t0\n"); // DbgStart + fprintf (asm_out_file, "\t.long\t0\n"); // DbgEnd + fprintf (asm_out_file, "\t.short\t0x%x\n", func->type ? func->type->id : 0); + fprintf (asm_out_file, "\t.short\t0\n"); // padding + + fprintf (asm_out_file, "\t.secrel32\t" FUNC_BEGIN_LABEL "%u\n", + func->num); // offset + fprintf (asm_out_file, "\t.secidx\t" FUNC_BEGIN_LABEL "%u\n", + func->num); // section + + fprintf (asm_out_file, "\t.byte\t0\n"); // flags + + if (func->name) + ASM_OUTPUT_ASCII (asm_out_file, func->name, name_len + 1); + else + fprintf (asm_out_file, "\t.byte\t0\n"); + + for (unsigned int i = 0; i < align; i++) + { + fprintf (asm_out_file, "\t.byte\t0\n"); + } + + // end procedure + + fprintf (asm_out_file, ".Lcvprocend%u:\n", func->num); + + fprintf (asm_out_file, "\t.short\t0x2\n"); + fprintf (asm_out_file, "\t.short\t0x%x\n", S_END); +} + /* Output DATASYM32 structure, describing a global variable: either * one with file-level scope (S_LDATA32) or global scope (S_GDATA32). */ static void @@ -138,6 +227,8 @@ pdbout_data32 (struct pdb_global_var *v) static void write_pdb_section (void) { + struct pdb_func *func; + fprintf (asm_out_file, "\t.section\t.debug$S, \"ndr\"\n"); fprintf (asm_out_file, "\t.long\t0x%x\n", CV_SIGNATURE_C13); fprintf (asm_out_file, "\t.long\t0x%x\n", DEBUG_S_SYMBOLS); @@ -164,7 +255,27 @@ write_pdb_section (void) global_vars = n; } + func = funcs; + while (func) + { + pdbout_proc32 (func); + + func = func->next; + } + fprintf (asm_out_file, ".Lsymend:\n"); + + while (funcs) + { + struct pdb_func *n = funcs->next; + + if (funcs->name) + free (funcs->name); + + free (funcs); + + funcs = n; + } } /* We've finished compilation - output the .debug$S section @@ -175,6 +286,38 @@ pdbout_finish (const char *filename ATTRIBUTE_UNUSED) write_pdb_section (); } +/* For a tree t, construct the name. */ +static char * +get_tree_name (tree t) +{ + char *name; + + if (TREE_CODE (t) == FUNCTION_DECL) + name = xstrdup (IDENTIFIER_POINTER (DECL_NAME (t))); + else + return NULL; + + return name; +} + +/* We've been passed a function definition - allocate and initialize a pdb_func + * struct to represent it. */ +static void +pdbout_begin_function (tree func) +{ + struct pdb_func *f = (struct pdb_func *) xmalloc (sizeof (struct pdb_func)); + + f->next = funcs; + f->name = get_tree_name (func); + f->num = current_function_funcdef_no; + f->public_flag = TREE_PUBLIC (func); + f->type = find_type (TREE_TYPE (func)); + + funcs = f; + + cur_func = f; +} + /* We've been passed a late global declaration, i.e. a global variable - * allocate a pdb_global_var struct and add it to the list of globals. */ static void diff --git a/gcc/pdbout.h b/gcc/pdbout.h index e3430793ee7..85a1eb548cb 100644 --- a/gcc/pdbout.h +++ b/gcc/pdbout.h @@ -20,14 +20,26 @@ #ifndef GCC_PDBOUT_H #define GCC_PDBOUT_H 1 +#define S_END 0x0006 #define S_LDATA32 0x110c #define S_GDATA32 0x110d +#define S_LPROC32 0x110f +#define S_GPROC32 0x1110 /* Format version as of MSVC 7 */ #define CV_SIGNATURE_C13 4 #define DEBUG_S_SYMBOLS 0xf1 +struct pdb_func +{ + struct pdb_func *next; + char *name; + int num; + unsigned int public_flag; + struct pdb_type *type; +}; + struct pdb_global_var { struct pdb_global_var *next;