aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Eggert2011-05-04 00:19:21 -0700
committerPaul Eggert2011-05-04 00:19:21 -0700
commitc378da0b47eb8c26fc8da4d89e128ee3c73537de (patch)
tree69780b09fd68c972f69c1414d48c84cb24a075fa
parent288b08c747644d42c1636c2b469f8c34836ccd35 (diff)
downloademacs-c378da0b47eb8c26fc8da4d89e128ee3c73537de.tar.gz
emacs-c378da0b47eb8c26fc8da4d89e128ee3c73537de.zip
Use C99's va_copy to avoid undefined behavior on x86-64 GNU/Linux.
-rw-r--r--ChangeLog4
-rw-r--r--Makefile.in2
-rw-r--r--lib/gnulib.mk29
-rw-r--r--lib/stdarg.in.h36
-rw-r--r--m4/gl-comp.m49
-rw-r--r--m4/stdarg.m478
-rw-r--r--src/ChangeLog3
-rw-r--r--src/eval.c5
8 files changed, 163 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index a9446476bc6..c1e774c2924 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
12011-05-04 Paul Eggert <eggert@cs.ucla.edu> 12011-05-04 Paul Eggert <eggert@cs.ucla.edu>
2 2
3 Use C99's va_copy to avoid undefined behavior on x86-64 GNU/Linux.
4 * Makefile.in (GNULIB_MODULES): Add stdarg, for va_copy.
5 * lib/stdarg.in.h, m4/stdarg.m4: New files, from gnulib.
6
3 * Makefile.in (GNULIB_TOOL_FLAG): Add --conditional-dependencies. 7 * Makefile.in (GNULIB_TOOL_FLAG): Add --conditional-dependencies.
4 This new gnulib-tool option saves 'configure' the trouble of 8 This new gnulib-tool option saves 'configure' the trouble of
5 checking for strtoull when strtoumax exists. 9 checking for strtoull when strtoumax exists.
diff --git a/Makefile.in b/Makefile.in
index 180f7e5be16..ba2926d2853 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -333,7 +333,7 @@ DOS_gnulib_comp.m4 = gl-comp.m4
333GNULIB_MODULES = \ 333GNULIB_MODULES = \
334 careadlinkat crypto/md5 dtoastr filemode getloadavg getopt-gnu \ 334 careadlinkat crypto/md5 dtoastr filemode getloadavg getopt-gnu \
335 ignore-value intprops lstat mktime readlink \ 335 ignore-value intprops lstat mktime readlink \
336 socklen stdio strftime strtoumax symlink sys_stat 336 socklen stdarg stdio strftime strtoumax symlink sys_stat
337GNULIB_TOOL_FLAGS = \ 337GNULIB_TOOL_FLAGS = \
338 --conditional-dependencies --import --no-changelog --no-vc-files \ 338 --conditional-dependencies --import --no-changelog --no-vc-files \
339 --makefile-name=gnulib.mk 339 --makefile-name=gnulib.mk
diff --git a/lib/gnulib.mk b/lib/gnulib.mk
index faf89aaa0e6..1466e430a4c 100644
--- a/lib/gnulib.mk
+++ b/lib/gnulib.mk
@@ -9,7 +9,7 @@
9# the same distribution terms as the rest of that program. 9# the same distribution terms as the rest of that program.
10# 10#
11# Generated by gnulib-tool. 11# Generated by gnulib-tool.
12# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=. --makefile-name=gnulib.mk --no-libtool --macro-prefix=gl --no-vc-files careadlinkat crypto/md5 dtoastr filemode getloadavg getopt-gnu ignore-value intprops lstat mktime readlink socklen stdio strftime strtoumax symlink sys_stat 12# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=. --makefile-name=gnulib.mk --no-libtool --macro-prefix=gl --no-vc-files careadlinkat crypto/md5 dtoastr filemode getloadavg getopt-gnu ignore-value intprops lstat mktime readlink socklen stdarg stdio strftime strtoumax symlink sys_stat
13 13
14 14
15MOSTLYCLEANFILES += core *.stackdump 15MOSTLYCLEANFILES += core *.stackdump
@@ -258,6 +258,33 @@ EXTRA_libgnu_a_SOURCES += stat.c
258 258
259## end gnulib module stat 259## end gnulib module stat
260 260
261## begin gnulib module stdarg
262
263BUILT_SOURCES += $(STDARG_H)
264
265# We need the following in order to create <stdarg.h> when the system
266# doesn't have one that works with the given compiler.
267if GL_GENERATE_STDARG_H
268stdarg.h: stdarg.in.h $(top_builddir)/config.status
269 $(AM_V_GEN)rm -f $@-t $@ && \
270 { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \
271 sed -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
272 -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
273 -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
274 -e 's|@''NEXT_STDARG_H''@|$(NEXT_STDARG_H)|g' \
275 < $(srcdir)/stdarg.in.h; \
276 } > $@-t && \
277 mv $@-t $@
278else
279stdarg.h: $(top_builddir)/config.status
280 rm -f $@
281endif
282MOSTLYCLEANFILES += stdarg.h stdarg.h-t
283
284EXTRA_DIST += stdarg.in.h
285
286## end gnulib module stdarg
287
261## begin gnulib module stdbool 288## begin gnulib module stdbool
262 289
263BUILT_SOURCES += $(STDBOOL_H) 290BUILT_SOURCES += $(STDBOOL_H)
diff --git a/lib/stdarg.in.h b/lib/stdarg.in.h
new file mode 100644
index 00000000000..4469d54e4f4
--- /dev/null
+++ b/lib/stdarg.in.h
@@ -0,0 +1,36 @@
1/* Substitute for and wrapper around <stdarg.h>.
2 Copyright (C) 2008-2011 Free Software Foundation, Inc.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software Foundation,
16 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
17
18#ifndef _GL_STDARG_H
19
20#if __GNUC__ >= 3
21@PRAGMA_SYSTEM_HEADER@
22#endif
23@PRAGMA_COLUMNS@
24
25/* The include_next requires a split double-inclusion guard. */
26#@INCLUDE_NEXT@ @NEXT_STDARG_H@
27
28#ifndef _GL_STDARG_H
29#define _GL_STDARG_H
30
31#ifndef va_copy
32# define va_copy(a,b) ((a) = (b))
33#endif
34
35#endif /* _GL_STDARG_H */
36#endif /* _GL_STDARG_H */
diff --git a/m4/gl-comp.m4 b/m4/gl-comp.m4
index 4338f2036b1..87d7616f8bb 100644
--- a/m4/gl-comp.m4
+++ b/m4/gl-comp.m4
@@ -51,6 +51,12 @@ AC_DEFUN([gl_EARLY],
51 # Code from module socklen: 51 # Code from module socklen:
52 # Code from module ssize_t: 52 # Code from module ssize_t:
53 # Code from module stat: 53 # Code from module stat:
54 # Code from module stdarg:
55 dnl Some compilers (e.g., AIX 5.3 cc) need to be in c99 mode
56 dnl for the builtin va_copy to work. With Autoconf 2.60 or later,
57 dnl AC_PROG_CC_STDC arranges for this. With older Autoconf AC_PROG_CC_STDC
58 dnl shouldn't hurt, though installers are on their own to set c99 mode.
59 AC_REQUIRE([AC_PROG_CC_STDC])
54 # Code from module stdbool: 60 # Code from module stdbool:
55 # Code from module stddef: 61 # Code from module stddef:
56 # Code from module stdint: 62 # Code from module stdint:
@@ -104,6 +110,7 @@ gl_FUNC_READLINK
104gl_UNISTD_MODULE_INDICATOR([readlink]) 110gl_UNISTD_MODULE_INDICATOR([readlink])
105gl_TYPE_SOCKLEN_T 111gl_TYPE_SOCKLEN_T
106gt_TYPE_SSIZE_T 112gt_TYPE_SSIZE_T
113gl_STDARG_H
107AM_STDBOOL_H 114AM_STDBOOL_H
108gl_STDDEF_H 115gl_STDDEF_H
109gl_STDINT_H 116gl_STDINT_H
@@ -358,6 +365,7 @@ AC_DEFUN([gl_FILE_LIST], [
358 lib/mktime.c 365 lib/mktime.c
359 lib/readlink.c 366 lib/readlink.c
360 lib/stat.c 367 lib/stat.c
368 lib/stdarg.in.h
361 lib/stdbool.in.h 369 lib/stdbool.in.h
362 lib/stddef.in.h 370 lib/stddef.in.h
363 lib/stdint.in.h 371 lib/stdint.in.h
@@ -395,6 +403,7 @@ AC_DEFUN([gl_FILE_LIST], [
395 m4/ssize_t.m4 403 m4/ssize_t.m4
396 m4/st_dm_mode.m4 404 m4/st_dm_mode.m4
397 m4/stat.m4 405 m4/stat.m4
406 m4/stdarg.m4
398 m4/stdbool.m4 407 m4/stdbool.m4
399 m4/stddef_h.m4 408 m4/stddef_h.m4
400 m4/stdint.m4 409 m4/stdint.m4
diff --git a/m4/stdarg.m4 b/m4/stdarg.m4
new file mode 100644
index 00000000000..5705de9ecaa
--- /dev/null
+++ b/m4/stdarg.m4
@@ -0,0 +1,78 @@
1# stdarg.m4 serial 6
2dnl Copyright (C) 2006, 2008-2011 Free Software Foundation, Inc.
3dnl This file is free software; the Free Software Foundation
4dnl gives unlimited permission to copy and/or distribute it,
5dnl with or without modifications, as long as this notice is preserved.
6
7dnl From Bruno Haible.
8dnl Provide a working va_copy in combination with <stdarg.h>.
9
10AC_DEFUN([gl_STDARG_H],
11[
12 STDARG_H=''
13 NEXT_STDARG_H='<stdarg.h>'
14 AC_MSG_CHECKING([for va_copy])
15 AC_CACHE_VAL([gl_cv_func_va_copy], [
16 AC_COMPILE_IFELSE(
17 [AC_LANG_PROGRAM(
18 [[#include <stdarg.h>]],
19 [[
20#ifndef va_copy
21void (*func) (va_list, va_list) = va_copy;
22#endif
23 ]])],
24 [gl_cv_func_va_copy=yes],
25 [gl_cv_func_va_copy=no])])
26 AC_MSG_RESULT([$gl_cv_func_va_copy])
27 if test $gl_cv_func_va_copy = no; then
28 dnl Provide a substitute.
29 dnl Usually a simple definition in <config.h> is enough. Not so on AIX 5
30 dnl with some versions of the /usr/vac/bin/cc compiler. It has an <stdarg.h>
31 dnl which does '#undef va_copy', leading to a missing va_copy symbol. For
32 dnl this platform, we use an <stdarg.h> substitute. But we cannot use this
33 dnl approach on other platforms, because <stdarg.h> often defines only
34 dnl preprocessor macros and gl_ABSOLUTE_HEADER, gl_CHECK_NEXT_HEADERS do
35 dnl not work in this situation.
36 AC_EGREP_CPP([vaccine],
37 [#if defined _AIX && !defined __GNUC__
38 AIX vaccine
39 #endif
40 ], [gl_aixcc=yes], [gl_aixcc=no])
41 if test $gl_aixcc = yes; then
42 dnl Provide a substitute <stdarg.h> file.
43 STDARG_H=stdarg.h
44 gl_NEXT_HEADERS([stdarg.h])
45 dnl Fallback for the case when <stdarg.h> contains only macro definitions.
46 if test "$gl_cv_next_stdarg_h" = '""'; then
47 gl_cv_next_stdarg_h='"///usr/include/stdarg.h"'
48 NEXT_STDARG_H="$gl_cv_next_stdarg_h"
49 fi
50 else
51 dnl Provide a substitute in <config.h>, either __va_copy or as a simple
52 dnl assignment.
53 gl_CACHE_VAL_SILENT([gl_cv_func___va_copy], [
54 AC_COMPILE_IFELSE(
55 [AC_LANG_PROGRAM(
56 [[#include <stdarg.h>]],
57 [[
58#ifndef __va_copy
59error, bail out
60#endif
61 ]])],
62 [gl_cv_func___va_copy=yes],
63 [gl_cv_func___va_copy=no])])
64 if test $gl_cv_func___va_copy = yes; then
65 AC_DEFINE([va_copy], [__va_copy],
66 [Define as a macro for copying va_list variables.])
67 else
68 AH_VERBATIM([gl_VA_COPY], [/* A replacement for va_copy, if needed. */
69#define gl_va_copy(a,b) ((a) = (b))])
70 AC_DEFINE([va_copy], [gl_va_copy],
71 [Define as a macro for copying va_list variables.])
72 fi
73 fi
74 fi
75 AC_SUBST([STDARG_H])
76 AM_CONDITIONAL([GL_GENERATE_STDARG_H], [test -n "$STDARG_H"])
77 AC_SUBST([NEXT_STDARG_H])
78])
diff --git a/src/ChangeLog b/src/ChangeLog
index 9fac265ae48..a1aa19e6f2e 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,8 @@
12011-05-04 Paul Eggert <eggert@cs.ucla.edu> 12011-05-04 Paul Eggert <eggert@cs.ucla.edu>
2 2
3 Use C99's va_copy to avoid undefined behavior on x86-64 GNU/Linux.
4 * eval.c (verror): doprnt a copy of ap, not the original. (Bug#8545)
5
3 * eval.c (verror): OK to create a string of up to MOST_POSITIVE_FIXNUM 6 * eval.c (verror): OK to create a string of up to MOST_POSITIVE_FIXNUM
4 bytes. 7 bytes.
5 8
diff --git a/src/eval.c b/src/eval.c
index 90ef02ef37b..6b4182cb319 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -2002,7 +2002,10 @@ verror (const char *m, va_list ap)
2002 2002
2003 while (1) 2003 while (1)
2004 { 2004 {
2005 used = doprnt (buffer, size, m, m + mlen, ap); 2005 va_list ap_copy;
2006 va_copy (ap_copy, ap);
2007 used = doprnt (buffer, size, m, m + mlen, ap_copy);
2008 va_end (ap_copy);
2006 2009
2007 /* Note: the -1 below is because `doprnt' returns the number of bytes 2010 /* Note: the -1 below is because `doprnt' returns the number of bytes
2008 excluding the terminating null byte, and it always terminates with a 2011 excluding the terminating null byte, and it always terminates with a