summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorA. Wilcox <awilcox@wilcox-tech.com>2019-01-08 01:54:00 +0000
committerA. Wilcox <awilcox@wilcox-tech.com>2019-01-08 01:54:00 +0000
commit70add83428603fe757098a9531a22e611a759017 (patch)
tree9a6b8cb275db8d142924eabc82ec9204a55ae5f9
parente97935b9c3b3c745d6264f9fad8afd912dbd366d (diff)
parentd186323a2db1f8bf65b24236ce8d2ddff1b4385a (diff)
downloadgcompat-70add83428603fe757098a9531a22e611a759017.tar.gz
gcompat-70add83428603fe757098a9531a22e611a759017.tar.bz2
gcompat-70add83428603fe757098a9531a22e611a759017.tar.xz
gcompat-70add83428603fe757098a9531a22e611a759017.zip
Merge branch 'patch-4' into 'master'
New kernel compatibility; obstack; pthread_getname_np The gcompat loader compiled as a static binary doesn't work on Linux since [a4ff8e8620d3f4](https://github.com/torvalds/linux/commit/a4ff8e8620d3f4f50ac4b41e8067b7d395056843), failing with an error like: ``` [349055.473655] 13325 (cmake): Uhuuh, elf segment at 0000000000400000 requested but the memory is mapped already ``` This is because the actual binary we want to run is also loaded at 0x400000. While it's actually okay to overlap the binary, since we're going to call `execve` again, the kernel doesn't allow the overlap anymore. Fix that by compiling the loader as static PIE, so it can be put at a different address. Also add `pthread_getname_np` and the option to link `obstack`. See merge request !4
-rw-r--r--CHANGELOG.rst11
-rw-r--r--Makefile39
-rw-r--r--libgcompat/alias.h4
-rw-r--r--libgcompat/internal.h13
-rw-r--r--libgcompat/pthread.c25
-rw-r--r--libgcompat/wchar.c2
6 files changed, 71 insertions, 23 deletions
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 7c5365c..c494a38 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -11,6 +11,17 @@
0.4.0 (201?-??-??)
==================
+Build system
+------------
+
+* Allow building against libobstack.
+* Fix compatibility with Linux 4.17 and newer.
+
+pthread
+-------
+
+* Add pthread_getname_np.
+
wchar
-----
diff --git a/Makefile b/Makefile
index 934422f..6a36129 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,6 @@
LIBGCOMPAT_INCLUDE = \
- libgcompat/alias.h
+ libgcompat/alias.h \
+ libgcompat/internal.h
LIBGCOMPAT_SRC = \
libgcompat/ctype.c \
libgcompat/cxx_thread.c \
@@ -43,36 +44,50 @@ LOADER_OBJ = ${LOADER_SRC:.c=.o}
LOADER_NAME = ld-linux.so.2
LOADER_PATH = /lib/${LOADER_NAME}
-ifdef WITH_LIBUCONTEXT
+PKG_CONFIG ?= pkg-config
-LIBUCONTEXT_LIBS = -Wl,--no-as-needed -lucontext
+ifdef WITH_LIBUCONTEXT
LIBUCONTEXT_CFLAGS = -DWITH_LIBUCONTEXT
+LIBUCONTEXT_LIBS = -lucontext
+endif
+
+ifndef WITH_OBSTACK
+WITH_OBSTACK = $(shell \
+ for pkg in obstack obstack-standalone; do \
+ ${PKG_CONFIG} --exists "$$pkg" && { echo "$$pkg"; exit 0; } \
+ done; echo "no")
+endif
+ifneq (${WITH_OBSTACK},no)
+OBSTACK_CFLAGS = $(shell ${PKG_CONFIG} --cflags ${WITH_OBSTACK}) -DWITH_OBSTACK
+OBSTACK_LIBS = $(shell ${PKG_CONFIG} --libs ${WITH_OBSTACK})
endif
all: ${LIBGCOMPAT_NAME} ${LOADER_NAME}
${LIBGCOMPAT_NAME}: ${LIBGCOMPAT_OBJ}
- $(CC) -o ${LIBGCOMPAT_NAME} -Wl,-soname,${LIBGCOMPAT_NAME} \
- -shared ${LIBGCOMPAT_OBJ} ${LIBUCONTEXT_LIBS}
+ ${CC} ${CFLAGS} ${LDFLAGS} -shared -Wl,-soname,${LIBGCOMPAT_NAME} \
+ -o ${LIBGCOMPAT_NAME} ${LIBGCOMPAT_OBJ} \
+ -Wl,--no-as-needed ${LIBUCONTEXT_LIBS} ${OBSTACK_LIBS}
${LIBGCOMPAT_OBJ}: ${LIBGCOMPAT_INCLUDE}
${LOADER_NAME}: ${LOADER_OBJ}
- $(CC) -o ${LOADER_NAME} -fPIE -static ${LOADER_OBJ}
+ ${CC} ${CFLAGS} ${LDFLAGS} -static-pie -o ${LOADER_NAME} ${LOADER_OBJ}
.c.o:
- $(CC) -c -D_BSD_SOURCE -DLIBGCOMPAT=\"${LIBGCOMPAT_PATH}\" \
- -DLINKER=\"${LINKER_PATH}\" -DLOADER=\"${LOADER_NAME}\" \
- -Ilibgcompat ${LIBUCONTEXT_CFLAGS} \
- -fPIC -std=c99 -Wall -Wextra -Wno-frame-address \
- -Wno-unused-parameter ${CFLAGS} ${CPPFLAGS} -o $@ $<
+ ${CC} ${CPPFLAGS} ${CFLAGS} -c -D_BSD_SOURCE \
+ -DLIBGCOMPAT='"${LIBGCOMPAT_PATH}"' \
+ -DLINKER='"${LINKER_PATH}"' -DLOADER='"${LOADER_NAME}"' \
+ -fPIC -Ilibgcompat -std=c99 \
+ -Wall -Wextra -Wno-frame-address -Wno-unused-parameter \
+ ${LIBUCONTEXT_CFLAGS} ${OBSTACK_CFLAGS} -o $@ $<
clean:
rm -f libgcompat/*.o loader/*.o ${LIBGCOMPAT_NAME} ${LOADER_NAME}
format:
- clang-format -i ${LIBGCOMPAT_SRC} ${LOADER_SRC}
+ clang-format -i ${LIBGCOMPAT_INCLUDE} ${LIBGCOMPAT_SRC} ${LOADER_SRC}
install: all
install -D -m755 ${LIBGCOMPAT_NAME} ${DESTDIR}/${LIBGCOMPAT_PATH}
diff --git a/libgcompat/alias.h b/libgcompat/alias.h
index 3f54672..bb99690 100644
--- a/libgcompat/alias.h
+++ b/libgcompat/alias.h
@@ -1,9 +1,9 @@
#ifndef _ALIAS_H_
#define _ALIAS_H_
-#define alias(old, new) \
+#define alias(old, new) \
extern __typeof(old) new __attribute__((__alias__(#old)))
-#define weak_alias(old, new) \
+#define weak_alias(old, new) \
extern __typeof(old) new __attribute__((weak, __alias__(#old)))
#endif /* _ALIAS_H_ */
diff --git a/libgcompat/internal.h b/libgcompat/internal.h
index 3b08271..a246547 100644
--- a/libgcompat/internal.h
+++ b/libgcompat/internal.h
@@ -3,12 +3,11 @@
void GCOMPAT__panic(const char *fmt, ...) __attribute__((noreturn));
-#define GCOMPAT__assert_with_reason(chk, ...) \
- do { \
- if (!(chk)) { \
- GCOMPAT__panic(__VA_ARGS__); \
- } \
- } \
- while(0);
+#define GCOMPAT__assert_with_reason(chk, ...) \
+ do { \
+ if (!(chk)) { \
+ GCOMPAT__panic(__VA_ARGS__); \
+ } \
+ } while (0);
#endif
diff --git a/libgcompat/pthread.c b/libgcompat/pthread.c
index 4ebbe6b..0456c40 100644
--- a/libgcompat/pthread.c
+++ b/libgcompat/pthread.c
@@ -1,4 +1,8 @@
-#include <pthread.h>
+#define _GNU_SOURCE
+#include <errno.h> /* errno */
+#include <fcntl.h> /* O_CLOEXEC, O_RDONLY */
+#include <pthread.h> /* pthread_atfork */
+#include <unistd.h> /* open, read */
#include "alias.h" /* weak_alias */
@@ -27,3 +31,22 @@ int __register_atfork(void (*prepare)(void), void (*parent)(void),
return pthread_atfork(prepare, parent, child);
}
weak_alias(__register_atfork, register_atfork);
+
+/**
+ * Get the name of a thread.
+ */
+int pthread_getname_np(pthread_t thread, char *name, size_t len)
+{
+ int fd = open("/proc/thread-self/comm", O_RDONLY | O_CLOEXEC);
+ char dummy;
+
+ if (fd < 0)
+ return errno;
+ if (read(fd, name, len) < 0)
+ return errno;
+ /* If there's more to read, the buffer was too small. */
+ if (read(fd, &dummy, 1) > 0)
+ return ERANGE;
+
+ return 0;
+}
diff --git a/libgcompat/wchar.c b/libgcompat/wchar.c
index 823c3e3..c60963e 100644
--- a/libgcompat/wchar.c
+++ b/libgcompat/wchar.c
@@ -45,7 +45,7 @@ int __vswprintf_chk(wchar_t *s, size_t n, int flag, size_t slen,
* LSB 5.0: LSB-Core-generic/baselib---wcstol-internal-1.html
*/
long int __wcstol_internal(const wchar_t *nptr, wchar_t **endptr, int base,
- int group)
+ int group)
{
assert(group == 0);
return wcstol(nptr, endptr, base);