[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 4/5] 64-bit obstack support, part 3
From: |
Alan Modra |
Subject: |
[PATCH 4/5] 64-bit obstack support, part 3 |
Date: |
Sat, 26 Jul 2014 15:27:11 +0930 |
This finally enables full 64-bit obstack support. Renaming the
_obstack_* functions to _obstack2_* is necessary to prevent a shared
library using version 1 obstack functions from having these functions
overridden by version 2 functions in the main executable. Not all
shared libraries are created with as much care as glibc in this
regard. Moving __OBSTACK_INTERFACE_VERSION to obstack.h allows glibc
to compile obstack.c twice, once to provide version 1 compat
functions, and once for 64-bit obstack support. For 32-bit targets
where version 1 and version 2 code is ABI compatible, I've put
machinery in place so that we only get one copy of the obstack.c
functions.
* lib/obstack.h (__OBSTACK_INTERFACE_VERSION): Define.
(__OBSTACK_ELIDE_CODE): Define.
(__OBSTACK_ALIAS_VER2): Define.
(__OBSTACK_SIZE_T, __CHUNK_SIZE_T): Define as size_t for version 2.
(_obstack_allocated_p, _obstack_begin, _obstack_begin_1,
_obstack_free, _obstack_memory_used, _obstack_newchunk): Define
for version 2.
(_obstack2_begin, _obstack2_begin_1, _obstack2_free,
_obstack2_memory_used, _obstack2_newchunk): Declare function aliases.
* lib/obstack.c (__OBSTACK_INTERFACE_VERSION): Delete.
(ELIDE_CODE): Delete, test __OBSTACK_ELIDE_CODE instead.
(_obstack2_begin, _obstack2_begin_1, _obstack2_free,
_obstack2_memory_used, _obstack2_newchunk): Emit aliases for glibc.
(obstack_alloc_failed_handler, print_and_abort, _obstack_compat):
Arrange for libc to emit definitions only for one obstack version.
* module/obstack: Add obstack.o to libgnu.a.
---
lib/obstack.c | 88 ++++++++++++++++++++++++++-----------------------------
lib/obstack.h | 74 ++++++++++++++++++++++++++++++++++++++++++++--
modules/obstack | 1 +
3 files changed, 115 insertions(+), 48 deletions(-)
diff --git a/lib/obstack.c b/lib/obstack.c
index 98b955e..1ac0e5d 100644
--- a/lib/obstack.c
+++ b/lib/obstack.c
@@ -25,30 +25,11 @@
# include "obstack.h"
#endif
-/* NOTE BEFORE MODIFYING THIS FILE: This version number must be
- incremented whenever callers compiled using an old obstack.h can no
- longer properly call the functions in this obstack.c. */
-#define OBSTACK_INTERFACE_VERSION 1
-
-/* Comment out all this code if we are using the GNU C Library, and are not
- actually compiling the library itself, and the installed library
- supports the same library interface we do. This code is part of the GNU
- C Library, but also included in many other GNU distributions. Compiling
- and linking in this code is a waste when using the GNU C library
- (especially if it is a shared library). Rather than having every GNU
- program understand 'configure --with-gnu-libc' and omit the object
- files, it is simpler to just do this in the source for each such file. */
-
-#include <stdio.h> /* Random thing to get __GNU_LIBRARY__. */
-#if !defined _LIBC && defined __GNU_LIBRARY__ && __GNU_LIBRARY__ > 1
-# include <gnu-versions.h>
-# if _GNU_OBSTACK_INTERFACE_VERSION == OBSTACK_INTERFACE_VERSION
-# define ELIDE_CODE
-# endif
-#endif
-
-#ifndef ELIDE_CODE
+/* NOTE BEFORE MODIFYING THIS FILE: __OBSTACK_INTERFACE_VERSION in
+ obstack.h must be incremented whenever callers compiled using an old
+ obstack.h can no longer properly call the functions in this file. */
+#ifndef __OBSTACK_ELIDE_CODE
# include <stdint.h>
# include <stdlib.h>
@@ -293,7 +274,7 @@ _obstack_free (struct obstack *h, void *obj)
/* obj is not in any of the chunks! */
abort ();
}
-# ifdef _LIBC
+# if defined _LIBC && __OBSTACK_INTERFACE_VERSION == 1
/* Older versions of libc defined both _obstack_free and obstack_free. */
strong_alias (_obstack_free, obstack_free)
# endif
@@ -311,28 +292,42 @@ _obstack_memory_used (struct obstack *h)
return nbytes;
}
+# ifdef __OBSTACK_ALIAS_VER2
+/* If sizeof(int) == sizeof(size_t) then version 2 obstack code is ABI
+ compatible with version 1. */
+strong_alias (_obstack_allocated_p, _obstack2_allocated_p)
+strong_alias (_obstack_begin, _obstack2_begin)
+strong_alias (_obstack_begin_1, _obstack2_begin_1)
+strong_alias (_obstack_free, _obstack2_free)
+strong_alias (_obstack_memory_used, _obstack2_memory_used)
+strong_alias (_obstack_newchunk, _obstack2_newchunk)
+libc_hidden_def (_obstack2_newchunk)
+# endif
+
+
/* Define the error handler. */
+# if !defined _LIBC || __OBSTACK_INTERFACE_VERSION == 1
/* Exit value used when 'print_and_abort' is used. */
-# ifdef _LIBC
+# ifdef _LIBC
int obstack_exit_failure = EXIT_FAILURE;
-# else
-# include "exitfail.h"
-# define obstack_exit_failure exit_failure
-# endif
+# else
+# include "exitfail.h"
+# define obstack_exit_failure exit_failure
+# endif
-# ifdef _LIBC
-# include <libintl.h>
-# else
-# include "gettext.h"
-# endif
-# ifndef _
-# define _(msgid) gettext (msgid)
-# endif
+# ifdef _LIBC
+# include <libintl.h>
+# else
+# include "gettext.h"
+# endif
+# ifndef _
+# define _(msgid) gettext (msgid)
+# endif
-# ifdef _LIBC
-# include <libio/iolibio.h>
-# endif
+# ifdef _LIBC
+# include <libio/iolibio.h>
+# endif
static _Noreturn void
print_and_abort (void)
@@ -342,11 +337,11 @@ print_and_abort (void)
happen because the "memory exhausted" message appears in other places
like this and the translation should be reused instead of creating
a very similar string which requires a separate translation. */
-# ifdef _LIBC
+# ifdef _LIBC
(void) __fxprintf (NULL, "%s\n", _("memory exhausted"));
-# else
+# else
fprintf (stderr, "%s\n", _("memory exhausted"));
-# endif
+# endif
exit (obstack_exit_failure);
}
@@ -358,14 +353,15 @@ print_and_abort (void)
'print_and_abort'. */
void (*obstack_alloc_failed_handler) (void) = print_and_abort;
-# ifdef _LIBC
-# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4)
+# ifdef _LIBC
+# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4)
/* A looong time ago (before 1994, anyway; we're not sure) this global variable
was used by non-GNU-C macros to avoid multiple evaluation. The GNU C
library still exports it because somebody might use it. */
struct obstack *_obstack_compat = 0;
compat_symbol (libc, _obstack_compat, _obstack, GLIBC_2_0);
+# endif
# endif
# endif
-#endif /* !ELIDE_CODE */
+#endif /* !__OBSTACK_ELIDE_CODE */
diff --git a/lib/obstack.h b/lib/obstack.h
index daf28bd..19a8eb2 100644
--- a/lib/obstack.h
+++ b/lib/obstack.h
@@ -104,10 +104,69 @@
#ifndef _OBSTACK_H
#define _OBSTACK_H 1
+#ifndef __OBSTACK_INTERFACE_VERSION
+# define __OBSTACK_INTERFACE_VERSION 2
+#endif
+
+/* Comment out all the obstack.c code if we are using the GNU C
+ Library, and are not actually compiling the library itself, and the
+ installed library supports the same library interface we do. This
+ code is part of the GNU C Library, but also included in many other
+ GNU distributions. Compiling and linking in obstack.c code is a
+ waste when using the GNU C library (especially if it is a shared
+ library). Rather than having every GNU program understand
+ 'configure --with-gnu-libc' and omit the object files, it is
+ simpler to just do this in the source for each such file. */
+
+#include <stdio.h> /* Random thing to get __GNU_LIBRARY__. */
+#if defined __GNU_LIBRARY__ && __GNU_LIBRARY__ > 1
+# include <gnu-versions.h>
+# if (!defined _LIBC \
+ && (_GNU_OBSTACK_INTERFACE_VERSION >= __OBSTACK_INTERFACE_VERSION
\
+ || (_GNU_OBSTACK_INTERFACE_VERSION == 1 \
+ && __OBSTACK_INTERFACE_VERSION == 2 \
+ && defined SIZEOF_INT && defined SIZEOF_SIZE_T \
+ && SIZEOF_INT == SIZEOF_SIZE_T)))
+# define __OBSTACK_ELIDE_CODE
+# endif
+# if (defined _LIBC \
+ && _GNU_OBSTACK_INTERFACE_VERSION >= 2 \
+ && defined SIZEOF_INT && defined SIZEOF_SIZE_T \
+ && SIZEOF_INT == SIZEOF_SIZE_T)
+/* We are currently building for glibc, and the version 1 code is ABI
+ compatible with version 2. When building version 2, don't emit any
+ code. When building version 1, emit aliases for version 2. */
+# if __OBSTACK_INTERFACE_VERSION == 2
+# define __OBSTACK_ELIDE_CODE
+# endif
+# if __OBSTACK_INTERFACE_VERSION == 1
+# define __OBSTACK_ALIAS_VER2
+# endif
+# endif
+#endif
+
#include <stddef.h>
-#define __OBSTACK_SIZE_T unsigned int
-#define __CHUNK_SIZE_T unsigned long
+#if __OBSTACK_INTERFACE_VERSION == 1
+/* For binary compatibility with obstack version 1, which used "int"
+ and "long" for these two types. */
+# define __OBSTACK_SIZE_T unsigned int
+# define __CHUNK_SIZE_T unsigned long
+#else
+/* Version 2 with sane types, especially for 64-bit hosts. */
+# define __OBSTACK_SIZE_T size_t
+# define __CHUNK_SIZE_T size_t
+
+/* The functions in obstack.c are renamed for version 2 so old shared
+ libraries that want version 1 code won't accidentally be overridden
+ by obstack functions with an incompatible ABI. */
+# define _obstack_allocated_p _obstack2_allocated_p
+# define _obstack_begin _obstack2_begin
+# define _obstack_begin_1 _obstack2_begin_1
+# define _obstack_free _obstack2_free
+# define _obstack_memory_used _obstack2_memory_used
+# define _obstack_newchunk _obstack2_newchunk
+#endif
/* If B is the base of an object addressed by P, return the result of
aligning P to the next multiple of A + 1. B and P must be of type
@@ -184,6 +243,17 @@ extern int _obstack_begin_1 (struct obstack *,
__OBSTACK_SIZE_T, int,
extern __OBSTACK_SIZE_T _obstack_memory_used (struct obstack *)
__attribute_pure__;
+#ifdef __OBSTACK_ALIAS_VER2
+extern void _obstack2_newchunk (struct obstack *, __OBSTACK_SIZE_T);
+extern void _obstack2_free (struct obstack *, void *);
+extern int _obstack2_begin (struct obstack *, __OBSTACK_SIZE_T, int,
+ void *(*)(size_t), void (*)(void *));
+extern int _obstack2_begin_1 (struct obstack *, __OBSTACK_SIZE_T, int,
+ void *(*)(void *, size_t),
+ void (*)(void *, void *), void *);
+extern __OBSTACK_SIZE_T _obstack2_memory_used (struct obstack *)
+ __attribute_pure__;
+#endif
/* Error handler called when 'obstack_chunk_alloc' failed to allocate
more memory. This can be set to a user defined function which
diff --git a/modules/obstack b/modules/obstack
index bceecdc..b2b8382 100644
--- a/modules/obstack
+++ b/modules/obstack
@@ -14,6 +14,7 @@ stdlib
configure.ac:
AC_FUNC_OBSTACK
dnl Note: AC_FUNC_OBSTACK does AC_LIBSOURCES([obstack.h, obstack.c]).
+AC_LIBOBJ([obstack])
Makefile.am:
[PATCH 4/5] 64-bit obstack support, part 3,
Alan Modra <=
[PATCH 2/5] 64-bit obstack support, part 1, Alan Modra, 2014/07/26