xref: /netbsd-src/external/gpl3/gdb/dist/gdbsupport/new-op.cc (revision 5ba1f45f2a09259cc846f20c7c5501604d633c90)
18dffb485Schristos /* Replace operator new/new[], for GDB, the GNU debugger.
28dffb485Schristos 
3*5ba1f45fSchristos    Copyright (C) 2016-2024 Free Software Foundation, Inc.
48dffb485Schristos 
58dffb485Schristos    This file is part of GDB.
68dffb485Schristos 
78dffb485Schristos    This program is free software; you can redistribute it and/or modify
88dffb485Schristos    it under the terms of the GNU General Public License as published by
98dffb485Schristos    the Free Software Foundation; either version 3 of the License, or
108dffb485Schristos    (at your option) any later version.
118dffb485Schristos 
128dffb485Schristos    This program is distributed in the hope that it will be useful,
138dffb485Schristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
148dffb485Schristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
158dffb485Schristos    GNU General Public License for more details.
168dffb485Schristos 
178dffb485Schristos    You should have received a copy of the GNU General Public License
188dffb485Schristos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
198dffb485Schristos 
208dffb485Schristos /* GCC does not understand __has_feature.  */
218dffb485Schristos #if !defined(__has_feature)
228dffb485Schristos # define __has_feature(x) 0
238dffb485Schristos #endif
248dffb485Schristos 
258dffb485Schristos #if !__has_feature(address_sanitizer) && !defined(__SANITIZE_ADDRESS__)
268dffb485Schristos #include "host-defs.h"
278dffb485Schristos #include <new>
288dffb485Schristos 
29*5ba1f45fSchristos /* These are declared in <new> starting C++14, but removing them
30*5ba1f45fSchristos    caused a build failure with clang.  See PR build/31141.  */
314b169a6bSchristos extern void operator delete (void *p, std::size_t) noexcept;
324b169a6bSchristos extern void operator delete[] (void *p, std::size_t) noexcept;
334b169a6bSchristos 
348dffb485Schristos /* Override operator new / operator new[], in order to internal_error
358dffb485Schristos    on allocation failure and thus query the user for abort/core
368dffb485Schristos    dump/continue, just like xmalloc does.  We don't do this from a
378dffb485Schristos    new-handler function instead (std::set_new_handler) because we want
388dffb485Schristos    to catch allocation errors from within global constructors too.
398dffb485Schristos 
408dffb485Schristos    Skip overriding if building with -fsanitize=address though.
418dffb485Schristos    Address sanitizer wants to override operator new/delete too in
428dffb485Schristos    order to detect malloc+delete and new+free mismatches.  Our
438dffb485Schristos    versions would mask out ASan's, with the result of losing that
448dffb485Schristos    useful mismatch detection.
458dffb485Schristos 
468dffb485Schristos    Note that C++ implementations could either have their throw
478dffb485Schristos    versions call the nothrow versions (libstdc++), or the other way
488dffb485Schristos    around (clang/libc++).  For that reason, we replace both throw and
498dffb485Schristos    nothrow variants and call malloc directly.  */
508dffb485Schristos 
518dffb485Schristos void *
528dffb485Schristos operator new (std::size_t sz)
538dffb485Schristos {
548dffb485Schristos   /* malloc (0) is unpredictable; avoid it.  */
558dffb485Schristos   if (sz == 0)
568dffb485Schristos     sz = 1;
578dffb485Schristos 
588dffb485Schristos   void *p = malloc (sz);	/* ARI: malloc */
598dffb485Schristos   if (p == NULL)
608dffb485Schristos     {
618dffb485Schristos       /* If the user decides to continue debugging, throw a
628dffb485Schristos 	 gdb_quit_bad_alloc exception instead of a regular QUIT
638dffb485Schristos 	 gdb_exception.  The former extends both std::bad_alloc and a
648dffb485Schristos 	 QUIT gdb_exception.  This is necessary because operator new
658dffb485Schristos 	 can only ever throw std::bad_alloc, or something that extends
668dffb485Schristos 	 it.  */
678dffb485Schristos       try
688dffb485Schristos 	{
698dffb485Schristos 	  malloc_failure (sz);
708dffb485Schristos 	}
718dffb485Schristos       catch (gdb_exception &ex)
728dffb485Schristos 	{
738dffb485Schristos 	  throw gdb_quit_bad_alloc (std::move (ex));
748dffb485Schristos 	}
758dffb485Schristos     }
768dffb485Schristos   return p;
778dffb485Schristos }
788dffb485Schristos 
798dffb485Schristos void *
808dffb485Schristos operator new (std::size_t sz, const std::nothrow_t&) noexcept
818dffb485Schristos {
828dffb485Schristos   /* malloc (0) is unpredictable; avoid it.  */
838dffb485Schristos   if (sz == 0)
848dffb485Schristos     sz = 1;
858dffb485Schristos   return malloc (sz);		/* ARI: malloc */
868dffb485Schristos }
878dffb485Schristos 
888dffb485Schristos void *
898dffb485Schristos operator new[] (std::size_t sz)
908dffb485Schristos {
918dffb485Schristos    return ::operator new (sz);
928dffb485Schristos }
938dffb485Schristos 
948dffb485Schristos void*
958dffb485Schristos operator new[] (std::size_t sz, const std::nothrow_t&) noexcept
968dffb485Schristos {
978dffb485Schristos   return ::operator new (sz, std::nothrow);
988dffb485Schristos }
994b169a6bSchristos 
1004b169a6bSchristos /* Define also operators delete as one can LD_PRELOAD=libasan.so.*
1014b169a6bSchristos    without recompiling the program with -fsanitize=address and then one would
1024b169a6bSchristos    get false positive alloc-dealloc-mismatch (malloc vs operator delete [])
1034b169a6bSchristos    errors from AddressSanitizers.  */
1044b169a6bSchristos 
1054b169a6bSchristos void
1064b169a6bSchristos operator delete (void *p) noexcept
1074b169a6bSchristos {
1084b169a6bSchristos   free (p);
1094b169a6bSchristos }
1104b169a6bSchristos 
1114b169a6bSchristos void
1124b169a6bSchristos operator delete (void *p, const std::nothrow_t&) noexcept
1134b169a6bSchristos {
1144b169a6bSchristos   return ::operator delete (p);
1154b169a6bSchristos }
1164b169a6bSchristos 
1174b169a6bSchristos void
1184b169a6bSchristos operator delete (void *p, std::size_t) noexcept
1194b169a6bSchristos {
1204b169a6bSchristos   return ::operator delete (p, std::nothrow);
1214b169a6bSchristos }
1224b169a6bSchristos 
1234b169a6bSchristos void
1244b169a6bSchristos operator delete[] (void *p) noexcept
1254b169a6bSchristos {
1264b169a6bSchristos   return ::operator delete (p);
1274b169a6bSchristos }
1284b169a6bSchristos 
1294b169a6bSchristos void
1304b169a6bSchristos operator delete[] (void *p, const std::nothrow_t&) noexcept
1314b169a6bSchristos {
1324b169a6bSchristos   return ::operator delete (p, std::nothrow);
1334b169a6bSchristos }
1344b169a6bSchristos 
1354b169a6bSchristos void
1364b169a6bSchristos operator delete[] (void *p, std::size_t) noexcept
1374b169a6bSchristos {
1384b169a6bSchristos   return ::operator delete[] (p, std::nothrow);
1394b169a6bSchristos }
1404b169a6bSchristos 
1418dffb485Schristos #endif
142