diff --git a/include/ChangeLog b/include/ChangeLog index 8b46056ce3128867c766b1d28be8335033c6fce0..06be0281e26c051eadc0742e5a6fe4de191179b8 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,7 @@ +2016-07-29 Aldy Hernandez <aldyh@redhat.com> + + * libiberty.h (MAX_ALLOCA_SIZE): New macro. + 2016-05-26 Chung-Lin Tang <cltang@codesourcery.com> * gomp-constants.h (GOMP_VERSION): Increment to 1, add comment to diff --git a/include/libiberty.h b/include/libiberty.h index a9c885fc67042fdc4e169fc48d6f788f1d62e6d9..605ff56abd8fc873fd824541b8c8f3b7d60aa8b9 100644 --- a/include/libiberty.h +++ b/include/libiberty.h @@ -397,6 +397,17 @@ extern void hex_init (void); /* Save files used for communication between processes. */ #define PEX_SAVE_TEMPS 0x4 +/* Max number of alloca bytes per call before we must switch to malloc. + + ?? Swiped from gnulib's regex_internal.h header. Is this actually + the case? This number seems arbitrary, though sane. + + The OS usually guarantees only one guard page at the bottom of the stack, + and a page size can be as small as 4096 bytes. So we cannot safely + allocate anything larger than 4096 bytes. Also care for the possibility + of a few compiler-allocated temporary stack slots. */ +#define MAX_ALLOCA_SIZE 4032 + /* Prepare to execute one or more programs, with standard output of each program fed to standard input of the next. FLAGS As above. diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog index 6209195ab38b3ad57d8f87fc6ba07f98aff2664c..a2e49a12cea89a649dec87508325a8fc296eef99 100644 --- a/libiberty/ChangeLog +++ b/libiberty/ChangeLog @@ -1,3 +1,8 @@ +2016-07-29 Aldy Hernandez <aldyh@redhat.com> + + * make-relative-prefix.c (make_relative_prefix_1): Fall back to + malloc if alloca argument is greater than MAX_ALLOCA_SIZE. + 2016-07-15 Jason Merrill <jason@redhat.com> * cp-demangle.c (cplus_demangle_operators): Add f[lrLR]. diff --git a/libiberty/make-relative-prefix.c b/libiberty/make-relative-prefix.c index fe639d18bd2815a5ec33aef28720386725ab1bd5..fa813998be3e97052a5215d1f411586161f64ebc 100644 --- a/libiberty/make-relative-prefix.c +++ b/libiberty/make-relative-prefix.c @@ -233,6 +233,7 @@ make_relative_prefix_1 (const char *progname, const char *bin_prefix, int i, n, common; int needed_len; char *ret = NULL, *ptr, *full_progname; + char *alloc_ptr = NULL; if (progname == NULL || bin_prefix == NULL || prefix == NULL) return NULL; @@ -256,7 +257,10 @@ make_relative_prefix_1 (const char *progname, const char *bin_prefix, #ifdef HAVE_HOST_EXECUTABLE_SUFFIX len += strlen (HOST_EXECUTABLE_SUFFIX); #endif - nstore = (char *) alloca (len); + if (len < MAX_ALLOCA_SIZE) + nstore = (char *) alloca (len); + else + alloc_ptr = nstore = (char *) malloc (len); startp = endp = temp; while (1) @@ -312,12 +316,12 @@ make_relative_prefix_1 (const char *progname, const char *bin_prefix, else full_progname = strdup (progname); if (full_progname == NULL) - return NULL; + goto bailout; prog_dirs = split_directories (full_progname, &prog_num); free (full_progname); if (prog_dirs == NULL) - return NULL; + goto bailout; bin_dirs = split_directories (bin_prefix, &bin_num); if (bin_dirs == NULL) @@ -395,6 +399,7 @@ make_relative_prefix_1 (const char *progname, const char *bin_prefix, free_split_directories (prog_dirs); free_split_directories (bin_dirs); free_split_directories (prefix_dirs); + free (alloc_ptr); return ret; }