From patchwork Thu Apr 6 00:24:09 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Modra X-Patchwork-Id: 79999 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b0ea:0:b0:3b6:4342:cba0 with SMTP id b10csp675285vqo; Wed, 5 Apr 2023 17:24:30 -0700 (PDT) X-Google-Smtp-Source: AKy350ZtBwWHyniMaoMU239fmE0g9mZARwVQylMiP8DCbCufSuXy0kOIbFVCn/JoR7GcBIQAW3c6 X-Received: by 2002:a17:906:5fd2:b0:930:d30a:6c20 with SMTP id k18-20020a1709065fd200b00930d30a6c20mr5487907ejv.17.1680740670072; Wed, 05 Apr 2023 17:24:30 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1680740670; cv=none; d=google.com; s=arc-20160816; b=LSmyxdcGMjZmu4E/cL3vijuCt4RGSSlpvNDEwgn1fAV2Ps3ijpmAOi5E5qvINcV+Av KRneMpaBG6Yron3uJFLrP2D9QJ+eE1InmbKHUGO1HUSm9EFB8uc0SvhVpA2wy3hOV0Tl ue7SC33nTVNXQ3tjdRDkYmw6Zs+Upgck/9bBVyUo7w3Vfbchv3peE9xz3D7bds4xPUol rorgC1lDoCtaeubrMhUo8biTcQm94V4RjQI9xr6fdhVzMSJwKr9+X4pn5JYkJiw8dxeZ +gBr1osV2cic8X5t18knPcgxkSI2JCsOcEobRK+nvuow/VrSRyp7BzpwpGqmWioNL9vF wAAw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:reply-to:from:list-subscribe:list-help:list-post :list-archive:list-unsubscribe:list-id:precedence :content-disposition:mime-version:message-id:subject:to:date :dmarc-filter:delivered-to:dkim-signature:dkim-filter; bh=ZCBBkTR1gdyx/8A8l4I7W6YMCE0Huj5E+yTh8moZMag=; b=UiK8COcZ0I59vvN5/ePDJaqi0DdypXJ2YDM5sKREF6p1VAusccIcVp8JmWSecF5Qvx aAnfHSqGtdogR2NPnZrbHeO22CmDfOnHl9F2osM+SDjJqvolNYS9o4KTUEh2e66Ifmjj nzua+RaExUUCzks1v0WC4CKau6cw45uRdi8xg4jN6rl/EcdcXWR+zUw8j9nT4NUOJLLi xnrSrXxMEekNM8YZ04alM0pgJ8VPEUqfbAYfuDoJSxSy5aWWFXwa7w9iueQLGBgb8eZH x0rnrrJJ6TInT3DrdchMWvSglMZ/edPS4PGbZK7yyAkpnL2wWw+XnqIAOVcjpvXUV8eh E4lg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=V+IcOM8y; spf=pass (google.com: domain of binutils-bounces+ouuuleilei=gmail.com@sourceware.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="binutils-bounces+ouuuleilei=gmail.com@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=sourceware.org Received: from sourceware.org (ip-8-43-85-97.sourceware.org. [8.43.85.97]) by mx.google.com with ESMTPS id e1-20020a056402148100b00501da1db818si37385edv.408.2023.04.05.17.24.29 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 05 Apr 2023 17:24:30 -0700 (PDT) Received-SPF: pass (google.com: domain of binutils-bounces+ouuuleilei=gmail.com@sourceware.org designates 8.43.85.97 as permitted sender) client-ip=8.43.85.97; Authentication-Results: mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=V+IcOM8y; spf=pass (google.com: domain of binutils-bounces+ouuuleilei=gmail.com@sourceware.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="binutils-bounces+ouuuleilei=gmail.com@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 10A43385842C for ; Thu, 6 Apr 2023 00:24:26 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 10A43385842C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1680740666; bh=ZCBBkTR1gdyx/8A8l4I7W6YMCE0Huj5E+yTh8moZMag=; h=Date:To:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=V+IcOM8yMaClz1sP2rx5vyUo1xDn51tF0fnjl2IVPSl8ATEVs5gjz9dTzBJ7FrXIb 6kVfx1s/ia2NINUR/xOq7j+Pud98ifaDrEe2Oe09M7Ejup2s3jJL3hroYN/SOcLgfT TYsBx0dAIqGls5kJ3af1ihS8xq74qRJVpuWNP3+s= X-Original-To: binutils@sourceware.org Delivered-To: binutils@sourceware.org Received: from mail-pl1-x634.google.com (mail-pl1-x634.google.com [IPv6:2607:f8b0:4864:20::634]) by sourceware.org (Postfix) with ESMTPS id C4BD03858D20 for ; Thu, 6 Apr 2023 00:24:14 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org C4BD03858D20 Received: by mail-pl1-x634.google.com with SMTP id kq3so35967879plb.13 for ; Wed, 05 Apr 2023 17:24:14 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680740653; h=content-disposition:mime-version:message-id:subject:to:from:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=ZCBBkTR1gdyx/8A8l4I7W6YMCE0Huj5E+yTh8moZMag=; b=XR7s3YJjC5AfcZuaBfgjDQvuknTbeIH2teISqADsPqGDL5/HseVDgvz9puiYCXREO0 NJDEdcULi5FGT2YUOYKchrRNaDu7lfpDpJLqOSG8+CfbqrKgTcXv+0yxedQ75orVz81f Klwh1a2gG2pFQdUBKE8AUZ8crPOwvkppXBdHFDsYBtnRLAvRN1KHb+3bXYaKenCMIjPQ 4MK4oR4SVRz4ywzdXJ5qX5hvv+3mQ+Xkfk9dK40/IQk9Z01Es0fnApLHGZWotQylV2VZ CBv6EqtIWsqYK73JEstqO0OGqk03jeeojQumjlsoxtnsQNYbffQtJADnhdaaYZ3mQvZ1 tecA== X-Gm-Message-State: AAQBX9cmXRP2rdnwK8IEh7CPA3fwHZ+UMDYI50Avo2B7mz0CqjnfZpNm D65P0s46bsFHD5b/euv9mKwvoIuxEu4= X-Received: by 2002:a05:6a20:1a8a:b0:d6:97e8:c3ed with SMTP id ci10-20020a056a201a8a00b000d697e8c3edmr886215pzb.14.1680740652608; Wed, 05 Apr 2023 17:24:12 -0700 (PDT) Received: from squeak.grove.modra.org ([2406:3400:51d:8cc0:e60c:bee0:cfeb:3a6]) by smtp.gmail.com with ESMTPSA id g21-20020aa78195000000b0062a54ce6b2bsm11209228pfi.108.2023.04.05.17.24.11 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 05 Apr 2023 17:24:11 -0700 (PDT) Received: by squeak.grove.modra.org (Postfix, from userid 1000) id 699681142495; Thu, 6 Apr 2023 09:54:09 +0930 (ACST) Date: Thu, 6 Apr 2023 09:54:09 +0930 To: binutils@sourceware.org Subject: objcopy write_debugging_info memory leaks Message-ID: MIME-Version: 1.0 Content-Disposition: inline X-Spam-Status: No, score=-3033.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, KAM_STOCKGEN, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: binutils@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Binutils mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Alan Modra via Binutils From: Alan Modra Reply-To: Alan Modra Errors-To: binutils-bounces+ouuuleilei=gmail.com@sourceware.org Sender: "Binutils" X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1762384329256983628?= X-GMAIL-MSGID: =?utf-8?q?1762384329256983628?= The old stabs code didn't bother too much about freeing memory. This patch corrects that and avoids some dubious copying of strings. * objcopy.c (write_debugging_info): Free both strings and syms on failure to create sections. * wrstabs.c: Delete unnecessary forward declarations and casts throughout file. (stab_write_symbol_and_free): New function. Use it throughout, simplifying return paths. (stab_push_string): Don't strdup string. Use it thoughout for malloced strings. (stab_push_string_dup): New function. Use it throughout for strings in auto buffers. (write_stabs_in_sections_debugging_info): Free malloced memory. (stab_enum_type): Increase buffer sizing for worst case. (stab_range_type, stab_array_type): Reduce buffer size. (stab_set_type): Likewise. (stab_method_type): Free args on error return. Correct buffer size. (stab_struct_field): Fix memory leaks. (stab_class_static_member, stab_class_baseclass): Likewise. (stab_start_class_type): Likewise. Correct buffer size. (stab_class_start_method): Correct buffer size. (stab_class_method_var): Free memory on error return. (stab_start_function): Fix "rettype" memory leak. diff --git a/binutils/objcopy.c b/binutils/objcopy.c index 957fb851432..d4fc644640c 100644 --- a/binutils/objcopy.c +++ b/binutils/objcopy.c @@ -4667,6 +4667,7 @@ write_debugging_info (bfd *obfd, void *dhandle, flags = SEC_HAS_CONTENTS | SEC_READONLY | SEC_DEBUGGING; stabsec = bfd_make_section_with_flags (obfd, ".stab", flags); stabstrsec = bfd_make_section_with_flags (obfd, ".stabstr", flags); + ret = true; if (stabsec == NULL || stabstrsec == NULL || !bfd_set_section_size (stabsec, symsize) @@ -4676,18 +4677,17 @@ write_debugging_info (bfd *obfd, void *dhandle, { bfd_nonfatal_message (NULL, obfd, NULL, _("can't create debugging section")); - free (strings); - return false; + ret = false; } /* We can get away with setting the section contents now because the next thing the caller is going to do is copy over the real sections. We may someday have to split the contents setting out of this function. */ - ret = true; - if (! bfd_set_section_contents (obfd, stabsec, syms, 0, symsize) - || ! bfd_set_section_contents (obfd, stabstrsec, strings, 0, - stringsize)) + if (ret + && (!bfd_set_section_contents (obfd, stabsec, syms, 0, symsize) + || !bfd_set_section_contents (obfd, stabstrsec, strings, 0, + stringsize))) { bfd_nonfatal_message (NULL, obfd, NULL, _("can't set debugging section contents")); diff --git a/binutils/wrstabs.c b/binutils/wrstabs.c index 53ade2eafbd..b676374558b 100644 --- a/binutils/wrstabs.c +++ b/binutils/wrstabs.c @@ -171,23 +171,6 @@ struct stab_write_handle const char *lineno_filename; }; -static struct bfd_hash_entry *string_hash_newfunc - (struct bfd_hash_entry *, struct bfd_hash_table *, const char *); -static bool stab_write_symbol - (struct stab_write_handle *, int, int, bfd_vma, const char *); -static bool stab_push_string - (struct stab_write_handle *, const char *, long, bool, unsigned int); -static bool stab_push_defined_type - (struct stab_write_handle *, long, unsigned int); -static char *stab_pop_type (struct stab_write_handle *); -static bool stab_modify_type - (struct stab_write_handle *, int, unsigned int, long **, size_t *); -static long stab_get_struct_index - (struct stab_write_handle *, const char *, unsigned int, - enum debug_type_kind, unsigned int *); -static bool stab_class_method_var - (struct stab_write_handle *, const char *, enum debug_visibility, - bool, bool, bool, bfd_vma, bool); static bool stab_start_compilation_unit (void *, const char *); static bool stab_start_source (void *, const char *); static bool stab_empty_type (void *); @@ -379,8 +362,7 @@ stab_write_symbol (struct stab_write_handle *info, int type, int desc, if (info->symbols_size + STAB_SYMBOL_SIZE > info->symbols_alloc) { info->symbols_alloc *= 2; - info->symbols = (bfd_byte *) xrealloc (info->symbols, - info->symbols_alloc); + info->symbols = xrealloc (info->symbols, info->symbols_alloc); } memcpy (info->symbols + info->symbols_size, sym, STAB_SYMBOL_SIZE); @@ -390,16 +372,25 @@ stab_write_symbol (struct stab_write_handle *info, int type, int desc, return true; } +static bool +stab_write_symbol_and_free (struct stab_write_handle *info, int type, int desc, + bfd_vma value, char *string) +{ + bool ret = stab_write_symbol (info, type, desc, value, string); + free (string); + return ret; +} + /* Push a string on to the type stack. */ static bool -stab_push_string (struct stab_write_handle *info, const char *string, +stab_push_string (struct stab_write_handle *info, char *string, long tindex, bool definition, unsigned int size) { struct stab_type_stack *s; - s = (struct stab_type_stack *) xmalloc (sizeof *s); - s->string = xstrdup (string); + s = xmalloc (sizeof *s); + s->string = string; s->index = tindex; s->definition = definition; s->size = size; @@ -415,6 +406,13 @@ stab_push_string (struct stab_write_handle *info, const char *string, return true; } +static bool +stab_push_string_dup (struct stab_write_handle *info, const char *string, + long tindex, bool definition, unsigned int size) +{ + return stab_push_string (info, xstrdup (string), tindex, definition, size); +} + /* Push a type index which has already been defined. */ static bool @@ -424,7 +422,7 @@ stab_push_defined_type (struct stab_write_handle *info, long tindex, char buf[20]; sprintf (buf, "%ld", tindex); - return stab_push_string (info, buf, tindex, false, size); + return stab_push_string_dup (info, buf, tindex, false, size); } /* Pop a type off the type stack. The caller is responsible for @@ -466,14 +464,15 @@ write_stabs_in_sections_debugging_info (bfd *abfd, void *dhandle, bfd_size_type *pstringsize) { struct stab_write_handle info; - struct string_hash_entry *h; + struct string_hash_entry *h, *hnext; bfd_byte *p; + bool ret; memset (&info, 0, sizeof info); info.abfd = abfd; info.symbols_alloc = 500; - info.symbols = (bfd_byte *) xmalloc (info.symbols_alloc); + info.symbols = xmalloc (info.symbols_alloc); /* Reserve 1 byte for a null byte. */ info.strings_size = 1; @@ -519,7 +518,7 @@ write_stabs_in_sections_debugging_info (bfd *abfd, void *dhandle, *psymsize = info.symbols_size; *pstringsize = info.strings_size; - *pstrings = (bfd_byte *) xmalloc (info.strings_size); + *pstrings = xmalloc (info.strings_size); p = *pstrings; *p++ = '\0'; @@ -529,17 +528,43 @@ write_stabs_in_sections_debugging_info (bfd *abfd, void *dhandle, p += strlen ((char *) p) + 1; } - bfd_hash_table_free (&info.typedef_hash.table); - bfd_hash_table_free (&info.strhash.table); - return true; + ret = true; + goto out; fail: + free (info.symbols); + ret = false; + out: + for (h = info.strings; h != NULL; h = hnext) + { + hnext = h->next; + free (h); + } + while (info.type_stack != NULL) + { + struct stab_type_stack *s = info.type_stack; + info.type_stack = s->next; + free (s->string); + free (s->fields); + if (s->baseclasses != NULL) + { + for (int i = 0; s->baseclasses[i] != NULL; i++) + free (s->baseclasses[i]); + free (s->baseclasses); + } + free (s->methods); + free (s->vtable); + free (s); + } + free (info.type_cache.pointer_types); + free (info.type_cache.function_types); + free (info.type_cache.reference_types); + free (info.type_cache.struct_types); if (info.typedef_hash.table.memory) bfd_hash_table_free (&info.typedef_hash.table); if (info.strhash.table.memory) bfd_hash_table_free (&info.strhash.table); - free (info.symbols); - return false; + return ret; } /* Start writing out information for a compilation unit. */ @@ -598,7 +623,7 @@ stab_empty_type (void *p) sprintf (buf, "%ld=%ld", tindex, tindex); - return stab_push_string (info, buf, tindex, false, 0); + return stab_push_string_dup (info, buf, tindex, false, 0); } } @@ -623,7 +648,7 @@ stab_void_type (void *p) sprintf (buf, "%ld=%ld", tindex, tindex); - return stab_push_string (info, buf, tindex, true, 0); + return stab_push_string_dup (info, buf, tindex, true, 0); } } @@ -683,7 +708,7 @@ stab_int_type (void *p, unsigned int size, bool unsignedp) abort (); } - return stab_push_string (info, buf, tindex, true, size); + return stab_push_string_dup (info, buf, tindex, true, size); } } @@ -724,7 +749,7 @@ stab_float_type (void *p, unsigned int size) free (int_type); - return stab_push_string (info, buf, tindex, true, size); + return stab_push_string_dup (info, buf, tindex, true, size); } } @@ -742,7 +767,7 @@ stab_complex_type (void *p, unsigned int size) sprintf (buf, "%ld=r%ld;%u;0;", tindex, tindex, size); - return stab_push_string (info, buf, tindex, true, size * 2); + return stab_push_string_dup (info, buf, tindex, true, size * 2); } /* Push a bool type. We use an XCOFF predefined type, since gdb @@ -795,22 +820,19 @@ stab_enum_type (void *p, const char *tag, const char **names, if (tag == NULL) return false; - buf = (char *) xmalloc (10 + strlen (tag)); + buf = xmalloc (4 + strlen (tag)); sprintf (buf, "xe%s:", tag); /* FIXME: The size is just a guess. */ - if (! stab_push_string (info, buf, 0, false, 4)) - return false; - free (buf); - return true; + return stab_push_string (info, buf, 0, false, 4); } - len = 10; + len = 25; if (tag != NULL) len += strlen (tag); for (pn = names; *pn != NULL; pn++) - len += strlen (*pn) + 20; + len += strlen (*pn) + 22; - buf = (char *) xmalloc (len); + buf = xmalloc (len); if (tag == NULL) strcpy (buf, "e"); @@ -828,20 +850,14 @@ stab_enum_type (void *p, const char *tag, const char **names, if (tag == NULL) { /* FIXME: The size is just a guess. */ - if (! stab_push_string (info, buf, 0, false, 4)) - return false; + return stab_push_string (info, buf, 0, false, 4); } else { /* FIXME: The size is just a guess. */ - if (! stab_write_symbol (info, N_LSYM, 0, 0, buf) - || ! stab_push_defined_type (info, tindex, 4)) - return false; + return (stab_write_symbol_and_free (info, N_LSYM, 0, 0, buf) + && stab_push_defined_type (info, tindex, 4)); } - - free (buf); - - return true; } /* Push a modification of the top type on the stack. Cache the @@ -869,12 +885,10 @@ stab_modify_type (struct stab_write_handle *info, int mod, new type, so we don't bother to define one. */ definition = info->type_stack->definition; s = stab_pop_type (info); - buf = (char *) xmalloc (strlen (s) + 2); + buf = xmalloc (strlen (s) + 2); sprintf (buf, "%c%s", mod, s); free (s); - if (! stab_push_string (info, buf, 0, definition, size)) - return false; - free (buf); + return stab_push_string (info, buf, 0, definition, size); } else { @@ -887,9 +901,9 @@ stab_modify_type (struct stab_write_handle *info, int mod, alloc = 10; while ((size_t) targindex >= alloc) alloc *= 2; - *cache = (long *) xrealloc (*cache, alloc * sizeof (long)); + *cache = xrealloc (*cache, alloc * sizeof (**cache)); memset (*cache + *cache_alloc, 0, - (alloc - *cache_alloc) * sizeof (long)); + (alloc - *cache_alloc) * sizeof (**cache)); *cache_alloc = alloc; } @@ -903,8 +917,7 @@ stab_modify_type (struct stab_write_handle *info, int mod, is a struct which we did not define at the time it was referenced). */ free (stab_pop_type (info)); - if (! stab_push_defined_type (info, tindex, size)) - return false; + return stab_push_defined_type (info, tindex, size); } else { @@ -912,20 +925,15 @@ stab_modify_type (struct stab_write_handle *info, int mod, ++info->type_index; s = stab_pop_type (info); - buf = (char *) xmalloc (strlen (s) + 20); + buf = xmalloc (strlen (s) + 23); sprintf (buf, "%ld=%c%s", tindex, mod, s); free (s); (*cache)[targindex] = tindex; - if (! stab_push_string (info, buf, tindex, true, size)) - return false; - - free (buf); + return stab_push_string (info, buf, tindex, true, size); } } - - return true; } /* Push a pointer type. */ @@ -962,14 +970,11 @@ stab_function_type (void *p, int argcount, s = stab_pop_type (info); - buf = (char *) xmalloc (strlen (s) + 3); + buf = xmalloc (strlen (s) + 3); sprintf (buf, ":t%s", s); free (s); - if (! stab_write_symbol (info, N_LSYM, 0, 0, buf)) - return false; - - free (buf); + return stab_write_symbol_and_free (info, N_LSYM, 0, 0, buf); } } @@ -1003,16 +1008,11 @@ stab_range_type (void *p, bfd_signed_vma low, bfd_signed_vma high) size = info->type_stack->size; s = stab_pop_type (info); - buf = (char *) xmalloc (strlen (s) + 100); + buf = xmalloc (strlen (s) + 45); sprintf (buf, "r%s;%ld;%ld;", s, (long) low, (long) high); free (s); - if (! stab_push_string (info, buf, 0, definition, size)) - return false; - - free (buf); - - return true; + return stab_push_string (info, buf, 0, definition, size); } /* Push an array type. */ @@ -1035,7 +1035,7 @@ stab_array_type (void *p, bfd_signed_vma low, bfd_signed_vma high, element_size = info->type_stack->size; element = stab_pop_type (info); - buf = (char *) xmalloc (strlen (range) + strlen (element) + 100); + buf = xmalloc (strlen (range) + strlen (element) + 70); if (! stringp) { @@ -1061,12 +1061,7 @@ stab_array_type (void *p, bfd_signed_vma low, bfd_signed_vma high, size = 0; else size = element_size * ((high - low) + 1); - if (! stab_push_string (info, buf, tindex, definition, size)) - return false; - - free (buf); - - return true; + return stab_push_string (info, buf, tindex, definition, size); } /* Push a set type. */ @@ -1082,7 +1077,7 @@ stab_set_type (void *p, bool bitstringp) definition = info->type_stack->definition; s = stab_pop_type (info); - buf = (char *) xmalloc (strlen (s) + 30); + buf = xmalloc (strlen (s) + 26); if (! bitstringp) { @@ -1102,12 +1097,7 @@ stab_set_type (void *p, bool bitstringp) sprintf (buf + strlen (buf), "S%s", s); free (s); - if (! stab_push_string (info, buf, tindex, definition, 0)) - return false; - - free (buf); - - return true; + return stab_push_string (info, buf, tindex, definition, 0); } /* Push an offset type. */ @@ -1125,17 +1115,12 @@ stab_offset_type (void *p) definition = definition || info->type_stack->definition; base = stab_pop_type (info); - buf = (char *) xmalloc (strlen (target) + strlen (base) + 3); + buf = xmalloc (strlen (target) + strlen (base) + 3); sprintf (buf, "@%s,%s", base, target); free (base); free (target); - if (! stab_push_string (info, buf, 0, definition, 0)) - return false; - - free (buf); - - return true; + return stab_push_string (info, buf, 0, definition, 0); } /* Push a method type. */ @@ -1180,9 +1165,12 @@ stab_method_type (void *p, bool domainp, int argcount, args = NULL; else { - args = (char **) xmalloc (1 * sizeof (*args)); + args = xmalloc (1 * sizeof (*args)); if (! stab_empty_type (p)) - return false; + { + free (args); + return false; + } definition = definition || info->type_stack->definition; args[0] = stab_pop_type (info); argcount = 1; @@ -1190,7 +1178,7 @@ stab_method_type (void *p, bool domainp, int argcount, } else { - args = (char **) xmalloc ((argcount + 1) * sizeof (*args)); + args = xmalloc ((argcount + 1) * sizeof (*args)); for (i = argcount - 1; i >= 0; i--) { definition = definition || info->type_stack->definition; @@ -1199,7 +1187,12 @@ stab_method_type (void *p, bool domainp, int argcount, if (! varargs) { if (! stab_empty_type (p)) - return false; + { + for (i = 0; i < argcount; i++) + free (args[i]); + free (args); + return false; + } definition = definition || info->type_stack->definition; args[argcount] = stab_pop_type (info); ++argcount; @@ -1209,11 +1202,11 @@ stab_method_type (void *p, bool domainp, int argcount, definition = definition || info->type_stack->definition; return_type = stab_pop_type (info); - len = strlen (domain) + strlen (return_type) + 10; + len = strlen (domain) + strlen (return_type) + 4 + argcount; for (i = 0; i < argcount; i++) len += strlen (args[i]); - buf = (char *) xmalloc (len); + buf = xmalloc (len); sprintf (buf, "#%s,%s", domain, return_type); free (domain); @@ -1228,12 +1221,7 @@ stab_method_type (void *p, bool domainp, int argcount, free (args); - if (! stab_push_string (info, buf, 0, definition, 0)) - return false; - - free (buf); - - return true; + return stab_push_string (info, buf, 0, definition, 0); } /* Push a const version of a type. */ @@ -1276,13 +1264,13 @@ stab_get_struct_index (struct stab_write_handle *info, const char *tag, while (id >= alloc) alloc *= 2; info->type_cache.struct_types = - (struct stab_tag *) xrealloc (info->type_cache.struct_types, - alloc * sizeof (struct stab_tag)); + xrealloc (info->type_cache.struct_types, + alloc * sizeof (*info->type_cache.struct_types)); memset ((info->type_cache.struct_types + info->type_cache.struct_types_alloc), 0, ((alloc - info->type_cache.struct_types_alloc) - * sizeof (struct stab_tag))); + * sizeof (*info->type_cache.struct_types))); info->type_cache.struct_types_alloc = alloc; } @@ -1338,10 +1326,10 @@ stab_start_struct_type (void *p, const char *tag, unsigned int id, structp ? 's' : 'u', size); - if (! stab_push_string (info, buf, tindex, definition, size)) + if (!stab_push_string_dup (info, buf, tindex, definition, size)) return false; - info->type_stack->fields = (char *) xmalloc (1); + info->type_stack->fields = xmalloc (1); info->type_stack->fields[0] = '\0'; return true; @@ -1366,12 +1354,13 @@ stab_struct_field (void *p, const char *name, bfd_vma bitpos, /* Add this field to the end of the current struct fields, which is currently on the top of the stack. */ if (info->type_stack->fields == NULL) - return false; + { + free (s); + return false; + } - n = (char *) xmalloc (strlen (info->type_stack->fields) - + strlen (name) - + strlen (s) - + 50); + n = xmalloc (strlen (info->type_stack->fields) + + strlen (name) + strlen (s) + 50); switch (visibility) { @@ -1403,6 +1392,7 @@ stab_struct_field (void *p, const char *name, bfd_vma bitpos, (long) bitpos, (long) bitsize); free (info->type_stack->fields); + free (s); info->type_stack->fields = n; if (definition) @@ -1431,17 +1421,12 @@ stab_end_struct_type (void *p) fields = info->type_stack->fields; first = stab_pop_type (info); - buf = (char *) xmalloc (strlen (first) + strlen (fields) + 2); + buf = xmalloc (strlen (first) + strlen (fields) + 2); sprintf (buf, "%s%s;", first, fields); free (first); free (fields); - if (! stab_push_string (info, buf, tindex, definition, size)) - return false; - - free (buf); - - return true; + return stab_push_string (info, buf, tindex, definition, size); } /* Start outputting a class. */ @@ -1462,7 +1447,10 @@ stab_start_class_type (void *p, const char *tag, unsigned int id, } if (! stab_start_struct_type (p, tag, id, structp, size)) - return false; + { + free (vstring); + return false; + } if (vptr) { @@ -1472,14 +1460,14 @@ stab_start_class_type (void *p, const char *tag, unsigned int id, { if (info->type_stack->index < 1) return false; - vtable = (char *) xmalloc (20); + vtable = xmalloc (23); sprintf (vtable, "~%%%ld", info->type_stack->index); } else { if (vstring == NULL) return false; - vtable = (char *) xmalloc (strlen (vstring) + 3); + vtable = xmalloc (strlen (vstring) + 3); sprintf (vtable, "~%%%s", vstring); free (vstring); if (definition) @@ -1510,11 +1498,8 @@ stab_class_static_member (void *p, const char *name, const char *physname, if (info->type_stack->fields == NULL) return false; - n = (char *) xmalloc (strlen (info->type_stack->fields) - + strlen (name) - + strlen (s) - + strlen (physname) - + 10); + n = xmalloc (strlen (info->type_stack->fields) + strlen (name) + + strlen (s) + strlen (physname) + 10); switch (visibility) { @@ -1537,6 +1522,7 @@ stab_class_static_member (void *p, const char *name, const char *physname, sprintf (n, "%s%s:%s%s:%s;", info->type_stack->fields, name, vis, s, physname); + free (s); free (info->type_stack->fields); info->type_stack->fields = n; @@ -1564,7 +1550,7 @@ stab_class_baseclass (void *p, bfd_vma bitpos, bool is_virtual, /* Build the base class specifier. */ - buf = (char *) xmalloc (strlen (s) + 25); + buf = xmalloc (strlen (s) + 25); buf[0] = is_virtual ? '1' : '0'; switch (visibility) { @@ -1590,7 +1576,10 @@ stab_class_baseclass (void *p, bfd_vma bitpos, bool is_virtual, /* Add the new baseclass to the existing ones. */ if (info->type_stack == NULL || info->type_stack->fields == NULL) - return false; + { + free (buf); + return false; + } if (info->type_stack->baseclasses == NULL) c = 0; @@ -1601,8 +1590,8 @@ stab_class_baseclass (void *p, bfd_vma bitpos, bool is_virtual, ++c; } - baseclasses = (char **) xrealloc (info->type_stack->baseclasses, - (c + 2) * sizeof (*baseclasses)); + baseclasses = xrealloc (info->type_stack->baseclasses, + (c + 2) * sizeof (*baseclasses)); baseclasses[c] = buf; baseclasses[c + 1] = NULL; @@ -1627,16 +1616,12 @@ stab_class_start_method (void *p, const char *name) if (info->type_stack->methods == NULL) { - m = (char *) xmalloc (strlen (name) + 3); + m = xmalloc (strlen (name) + 3); *m = '\0'; } else - { - m = (char *) xrealloc (info->type_stack->methods, - (strlen (info->type_stack->methods) - + strlen (name) - + 4)); - } + m = xrealloc (info->type_stack->methods, + strlen (info->type_stack->methods) + strlen (name) + 3); sprintf (m + strlen (m), "%s::", name); @@ -1669,7 +1654,11 @@ stab_class_method_var (struct stab_write_handle *info, const char *physname, } if (info->type_stack == NULL || info->type_stack->methods == NULL) - return false; + { + free (type); + free (context); + return false; + } switch (visibility) { @@ -1712,12 +1701,9 @@ stab_class_method_var (struct stab_write_handle *info, const char *physname, typec = '*'; info->type_stack->methods = - (char *) xrealloc (info->type_stack->methods, - (strlen (info->type_stack->methods) - + strlen (type) - + strlen (physname) - + (contextp ? strlen (context) : 0) - + 40)); + xrealloc (info->type_stack->methods, + (strlen (info->type_stack->methods) + strlen (type) + + strlen (physname) + (contextp ? strlen (context) : 0) + 40)); sprintf (info->type_stack->methods + strlen (info->type_stack->methods), "%s:%s;%c%c%c", type, physname, visc, qualc, typec); @@ -1813,7 +1799,7 @@ stab_end_class_type (void *p) /* Build the class definition. */ - buf = (char *) xmalloc (len); + buf = xmalloc (len); strcpy (buf, info->type_stack->string); @@ -1904,7 +1890,7 @@ stab_typdef (void *p, const char *name) size = info->type_stack->size; s = stab_pop_type (info); - buf = (char *) xmalloc (strlen (name) + strlen (s) + 20); + buf = xmalloc (strlen (name) + strlen (s) + 20); if (tindex > 0) sprintf (buf, "%s:t%s", name, s); @@ -1917,11 +1903,9 @@ stab_typdef (void *p, const char *name) free (s); - if (! stab_write_symbol (info, N_LSYM, 0, 0, buf)) + if (!stab_write_symbol_and_free (info, N_LSYM, 0, 0, buf)) return false; - free (buf); - h = string_hash_lookup (&info->typedef_hash, name, true, false); if (h == NULL) { @@ -1948,17 +1932,12 @@ stab_tag (void *p, const char *tag) s = stab_pop_type (info); - buf = (char *) xmalloc (strlen (tag) + strlen (s) + 3); + buf = xmalloc (strlen (tag) + strlen (s) + 3); sprintf (buf, "%s:T%s", tag, s); free (s); - if (! stab_write_symbol (info, N_LSYM, 0, 0, buf)) - return false; - - free (buf); - - return true; + return stab_write_symbol_and_free (info, N_LSYM, 0, 0, buf); } /* Define an integer constant. */ @@ -1969,15 +1948,10 @@ stab_int_constant (void *p, const char *name, bfd_vma val) struct stab_write_handle *info = (struct stab_write_handle *) p; char *buf; - buf = (char *) xmalloc (strlen (name) + 20); + buf = xmalloc (strlen (name) + 20); sprintf (buf, "%s:c=i%ld", name, (long) val); - if (! stab_write_symbol (info, N_LSYM, 0, 0, buf)) - return false; - - free (buf); - - return true; + return stab_write_symbol_and_free (info, N_LSYM, 0, 0, buf); } /* Define a floating point constant. */ @@ -1988,15 +1962,10 @@ stab_float_constant (void *p, const char *name, double val) struct stab_write_handle *info = (struct stab_write_handle *) p; char *buf; - buf = (char *) xmalloc (strlen (name) + 20); + buf = xmalloc (strlen (name) + 20); sprintf (buf, "%s:c=f%g", name, val); - if (! stab_write_symbol (info, N_LSYM, 0, 0, buf)) - return false; - - free (buf); - - return true; + return stab_write_symbol_and_free (info, N_LSYM, 0, 0, buf); } /* Define a typed constant. */ @@ -2009,16 +1978,11 @@ stab_typed_constant (void *p, const char *name, bfd_vma val) s = stab_pop_type (info); - buf = (char *) xmalloc (strlen (name) + strlen (s) + 20); + buf = xmalloc (strlen (name) + strlen (s) + 20); sprintf (buf, "%s:c=e%s,%ld", name, s, (long) val); free (s); - if (! stab_write_symbol (info, N_LSYM, 0, 0, buf)) - return false; - - free (buf); - - return true; + return stab_write_symbol_and_free (info, N_LSYM, 0, 0, buf); } /* Record a variable. */ @@ -2066,7 +2030,7 @@ stab_variable (void *p, const char *name, enum debug_var_kind kind, tindex = info->type_index; ++info->type_index; - n = (char *) xmalloc (strlen (s) + 20); + n = xmalloc (strlen (s) + 20); sprintf (n, "%ld=%s", tindex, s); free (s); s = n; @@ -2079,16 +2043,11 @@ stab_variable (void *p, const char *name, enum debug_var_kind kind, break; } - buf = (char *) xmalloc (strlen (name) + strlen (s) + 3); + buf = xmalloc (strlen (name) + strlen (s) + 3); sprintf (buf, "%s:%s%s", name, kindstr, s); free (s); - if (! stab_write_symbol (info, stab_type, 0, val, buf)) - return false; - - free (buf); - - return true; + return stab_write_symbol_and_free (info, stab_type, 0, val, buf); } /* Start outputting a function. */ @@ -2104,20 +2063,16 @@ stab_start_function (void *p, const char *name, bool globalp) rettype = stab_pop_type (info); - buf = (char *) xmalloc (strlen (name) + strlen (rettype) + 3); + buf = xmalloc (strlen (name) + strlen (rettype) + 3); sprintf (buf, "%s:%c%s", name, globalp ? 'F' : 'f', rettype); + free (rettype); /* We don't know the value now, so we set it in start_block. */ info->fun_offset = info->symbols_size; - if (! stab_write_symbol (info, N_FUN, 0, 0, buf)) - return false; - - free (buf); - - return true; + return stab_write_symbol_and_free (info, N_FUN, 0, 0, buf); } /* Output a function parameter. */ @@ -2158,16 +2113,11 @@ stab_function_parameter (void *p, const char *name, enum debug_parm_kind kind, b break; } - buf = (char *) xmalloc (strlen (name) + strlen (s) + 3); + buf = xmalloc (strlen (name) + strlen (s) + 3); sprintf (buf, "%s:%c%s", name, kindc, s); free (s); - if (! stab_write_symbol (info, stab_type, 0, val, buf)) - return false; - - free (buf); - - return true; + return stab_write_symbol_and_free (info, stab_type, 0, val, buf); } /* Start a block. */