blob: 976c541db5b71f79602b6e33af5a466a9905d9fb [file] [log] [blame]
From 521fbe9135ce7eefd190f8a2c50b00be428def6c Mon Sep 17 00:00:00 2001
From: Jon Turney <jon.turney@dronecode.org.uk>
Date: Wed, 9 Apr 2014 23:49:03 +0100
Subject: [PATCH 17/29] Provide a working strtok_r for MinGW
Prior to mingW-w64 3.3.0, strtok_r was a macro using strtok, which causes the
processor to not work, as re-entrancy is required
v2:
Link various unit tests with @LIBOBJS@ for strtok_r
Signed-off-by: Jon Turney <jon.turney@dronecode.org.uk>
---
Makefile.am | 28 +++++-----
compat/strtok_r.c | 85 +++++++++++++++++++++++++++++
configure.ac | 3 +
src/processor/basic_source_line_resolver.cc | 4 ++
src/processor/cfi_frame_info.cc | 6 +-
src/processor/tokenize.cc | 6 +-
6 files changed, 116 insertions(+), 16 deletions(-)
create mode 100644 compat/strtok_r.c
diff --git a/Makefile.am b/Makefile.am
index 39aec328..43d28f6a 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -833,7 +833,7 @@ src_processor_basic_source_line_resolver_unittest_LDADD = \
src/processor/source_line_resolver_base.o \
src/processor/tokenize.o \
$(TEST_LIBS) \
- $(PTHREAD_CFLAGS) $(PTHREAD_LIBS)
+ $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) @LIBOBJS@
src_processor_cfi_frame_info_unittest_SOURCES = \
src/processor/cfi_frame_info_unittest.cc
@@ -842,7 +842,7 @@ src_processor_cfi_frame_info_unittest_LDADD = \
src/processor/logging.o \
src/processor/pathname_stripper.o \
$(TEST_LIBS) \
- $(PTHREAD_CFLAGS) $(PTHREAD_LIBS)
+ $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) @LIBOBJS@
src_processor_cfi_frame_info_unittest_CPPFLAGS = \
$(AM_CPPFLAGS) $(TEST_CFLAGS)
@@ -891,7 +891,7 @@ src_processor_exploitability_unittest_LDADD = \
src/processor/tokenize.o \
src/third_party/libdisasm/libdisasm.a \
$(TEST_LIBS) \
- $(PTHREAD_CFLAGS) $(PTHREAD_LIBS)
+ $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) @LIBOBJS@
src_processor_disassembler_x86_unittest_SOURCES = \
src/processor/disassembler_x86_unittest.cc
@@ -918,7 +918,7 @@ src_processor_fast_source_line_resolver_unittest_LDADD = \
src/processor/source_line_resolver_base.o \
src/processor/tokenize.o \
$(TEST_LIBS) \
- $(PTHREAD_CFLAGS) $(PTHREAD_LIBS)
+ $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) @LIBOBJS@
src_processor_map_serializers_unittest_SOURCES = \
src/processor/map_serializers_unittest.cc
@@ -961,7 +961,7 @@ src_processor_microdump_processor_unittest_LDADD = \
src/processor/stackwalker_x86.o \
src/processor/tokenize.o \
$(TEST_LIBS) \
- $(PTHREAD_CFLAGS) $(PTHREAD_LIBS)
+ $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) @LIBOBJS@
src_processor_minidump_processor_unittest_SOURCES = \
src/processor/minidump_processor_unittest.cc
@@ -1001,7 +1001,7 @@ src_processor_minidump_processor_unittest_LDADD = \
src/processor/tokenize.o \
src/third_party/libdisasm/libdisasm.a \
$(TEST_LIBS) \
- $(PTHREAD_CFLAGS) $(PTHREAD_LIBS)
+ $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) @LIBOBJS@
src_processor_minidump_unittest_SOURCES = \
src/common/test_assembler.cc \
@@ -1138,7 +1138,7 @@ src_processor_stackwalker_amd64_unittest_SOURCES = \
src_processor_stackwalker_amd64_unittest_LDADD = \
src/libbreakpad.a \
$(TEST_LIBS) \
- $(PTHREAD_CFLAGS) $(PTHREAD_LIBS)
+ $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) @LIBOBJS@
src_processor_stackwalker_amd64_unittest_CPPFLAGS = \
$(AM_CPPFLAGS) $(TEST_CFLAGS)
@@ -1148,7 +1148,7 @@ src_processor_stackwalker_arm_unittest_SOURCES = \
src_processor_stackwalker_arm_unittest_LDADD = \
src/libbreakpad.a \
$(TEST_LIBS) \
- $(PTHREAD_CFLAGS) $(PTHREAD_LIBS)
+ $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) @LIBOBJS@
src_processor_stackwalker_arm_unittest_CPPFLAGS = \
$(AM_CPPFLAGS) $(TEST_CFLAGS)
@@ -1158,7 +1158,7 @@ src_processor_stackwalker_arm64_unittest_SOURCES = \
src_processor_stackwalker_arm64_unittest_LDADD = \
src/libbreakpad.a \
$(TEST_LIBS) \
- $(PTHREAD_CFLAGS) $(PTHREAD_LIBS)
+ $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) @LIBOBJS@
src_processor_stackwalker_arm64_unittest_CPPFLAGS = \
$(AM_CPPFLAGS) $(TEST_CFLAGS)
@@ -1168,7 +1168,7 @@ src_processor_stackwalker_address_list_unittest_SOURCES = \
src_processor_stackwalker_address_list_unittest_LDADD = \
src/libbreakpad.a \
$(TEST_LIBS) \
- $(PTHREAD_CFLAGS) $(PTHREAD_LIBS)
+ $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) @LIBOBJS@
src_processor_stackwalker_address_list_unittest_CPPFLAGS = \
$(AM_CPPFLAGS) $(TEST_CFLAGS)
@@ -1178,7 +1178,7 @@ src_processor_stackwalker_mips_unittest_SOURCES = \
src_processor_stackwalker_mips_unittest_LDADD = \
src/libbreakpad.a \
$(TEST_LIBS) \
- $(PTHREAD_CFLAGS) $(PTHREAD_LIBS)
+ $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) @LIBOBJS@
src_processor_stackwalker_mips_unittest_CPPFLAGS = \
$(AM_CPPFLAGS) $(TEST_CFLAGS)
@@ -1198,7 +1198,7 @@ src_processor_stackwalker_x86_unittest_SOURCES = \
src_processor_stackwalker_x86_unittest_LDADD = \
src/libbreakpad.a \
$(TEST_LIBS) \
- $(PTHREAD_CFLAGS) $(PTHREAD_LIBS)
+ $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) @LIBOBJS@
src_processor_stackwalker_x86_unittest_CPPFLAGS = \
$(AM_CPPFLAGS) $(TEST_CFLAGS)
@@ -1273,7 +1273,7 @@ src_processor_microdump_stackwalk_LDADD = \
src/processor/stackwalker_x86.o \
src/processor/tokenize.o \
src/third_party/libdisasm/libdisasm.a \
- $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) $(SOCKET_LIBS)
+ $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) $(SOCKET_LIBS) @LIBOBJS@
src_processor_minidump_stackwalk_SOURCES = \
src/processor/minidump_stackwalk.cc
@@ -1313,7 +1313,7 @@ src_processor_minidump_stackwalk_LDADD = \
src/processor/symbolic_constants_win.o \
src/processor/tokenize.o \
src/third_party/libdisasm/libdisasm.a \
- $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) $(SOCKET_LIBS)
+ $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) $(SOCKET_LIBS) @LIBOBJS@
endif !DISABLE_PROCESSOR
diff --git a/compat/strtok_r.c b/compat/strtok_r.c
new file mode 100644
index 00000000..ec7b6379
--- /dev/null
+++ b/compat/strtok_r.c
@@ -0,0 +1,85 @@
+/*-
+ * Copyright (c) 1998 Softweyr LLC. All rights reserved.
+ *
+ * strtok_r, from Berkeley strtok
+ * Oct 13, 1998 by Wes Peters <wes@softweyr.com>
+ *
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notices, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notices, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Softweyr LLC, the
+ * University of California, Berkeley, and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY SOFTWEYR LLC, THE REGENTS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SOFTWEYR LLC, THE
+ * REGENTS, OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+
+char *
+strtok_r(char *s, const char *delim, char **last)
+{
+ char *spanp, *tok;
+ int c, sc;
+
+ if (s == NULL && (s = *last) == NULL)
+ return (NULL);
+
+ /*
+ * Skip (span) leading delimiters (s += strspn(s, delim), sort of).
+ */
+cont:
+ c = *s++;
+ for (spanp = (char *)delim; (sc = *spanp++) != 0;) {
+ if (c == sc)
+ goto cont;
+ }
+
+ if (c == 0) { /* no non-delimiter characters */
+ *last = NULL;
+ return (NULL);
+ }
+ tok = s - 1;
+
+ /*
+ * Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
+ * Note that delim must have one NUL; we stop if we see that, too.
+ */
+ for (;;) {
+ c = *s++;
+ spanp = (char *)delim;
+ do {
+ if ((sc = *spanp++) == c) {
+ if (c == 0)
+ s = NULL;
+ else
+ s[-1] = '\0';
+ *last = s;
+ return (tok);
+ }
+ } while (sc != 0);
+ }
+ /* NOTREACHED */
+}
diff --git a/configure.ac b/configure.ac
index 93635de5..da8c49a3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -78,6 +78,9 @@ AC_CHECK_FUNCS([arc4random getrandom])
AX_CXX_COMPILE_STDCXX(11, noext, mandatory)
+AC_CONFIG_LIBOBJ_DIR([compat])
+AC_REPLACE_FUNCS([strtok_r])
+
dnl Test supported warning flags.
WARN_CXXFLAGS=
dnl This warning flag is used by clang. Its default behavior is to warn when
diff --git a/src/processor/basic_source_line_resolver.cc b/src/processor/basic_source_line_resolver.cc
index aa66e159..b7ee7d17 100644
--- a/src/processor/basic_source_line_resolver.cc
+++ b/src/processor/basic_source_line_resolver.cc
@@ -49,6 +49,10 @@
#include "processor/tokenize.h"
+#ifndef HAVE_STRTOK_R
+extern "C" char *strtok_r(char *, const char *, char **);
+#endif
+
using std::map;
using std::vector;
using std::make_pair;
diff --git a/src/processor/cfi_frame_info.cc b/src/processor/cfi_frame_info.cc
index 0c4af7ba..dd2b438b 100644
--- a/src/processor/cfi_frame_info.cc
+++ b/src/processor/cfi_frame_info.cc
@@ -41,12 +41,16 @@
#include "common/scoped_ptr.h"
#include "processor/postfix_evaluator-inl.h"
-namespace google_breakpad {
+#ifndef HAVE_STRTOK_R
+extern "C" char *strtok_r(char *, const char *, char **);
+#endif
#ifdef _MSC_VER
#define strtok_r strtok_s
#endif
+namespace google_breakpad {
+
template<typename V>
bool CFIFrameInfo::FindCallerRegs(const RegisterValueMap<V> &registers,
const MemoryRegion &memory,
diff --git a/src/processor/tokenize.cc b/src/processor/tokenize.cc
index 8fce87a2..e6213ac3 100644
--- a/src/processor/tokenize.cc
+++ b/src/processor/tokenize.cc
@@ -34,12 +34,16 @@
#include "common/using_std_string.h"
-namespace google_breakpad {
+#ifndef HAVE_STRTOK_R
+extern "C" char *strtok_r(char *, const char *, char **);
+#endif
#ifdef _MSC_VER
#define strtok_r strtok_s
#endif
+namespace google_breakpad {
+
using std::vector;
bool Tokenize(char *line,
--
2.15.0