[PATCH] support C libs w/out System V shared memory/ipc

Mike Frysinger vapier at gentoo.org
Sat Oct 31 04:47:53 UTC 2015


Some systems (like Bionic) omit support for SysV related code.  That means
no C library headers for strace to include.  Add configure tests to probe
the headers from the kernel and use them when they're available.

It might make more sense to never rely on the C library's headers as there
is no guarantee or requirement that the structure layout between apps and
the C library match that what is passed to the kernel.

* configure.ac (AC_CHECK_HEADERS): Check for asm/{ipc,msg,sem,shm}buf.h,
linux/ipc.h, linux/mqueue.h, linux/msg.h, linux/sem.h, linux/shm.h, sys/ipc.h,
sys/msg.h, sys/sem.h, and sys/shm.h.
* ipc_defs.h: Include sys/ipc.h and linux/ipc.h depending on what's available.
* ipc_msg.c: Replace ipc/msg headers with ipc_defs.h.
* ipc_msgctl.c: Include sys/msg.h, asm/msgbuf.h, or linux/msg.h based on what's
available.  Note missing support for old ipc structs.
* ipc_sem.c: Include sys/sem.h and linux/sem.h depending on what's available.
Only decode sembuf when available.
* ipc_shm.c: Drop unused sys/shm.h include.
* ipc_shmctl.c: Include sys/shm.h, asm/shmbuf.h, or linux/shm.h based on what's
available.  Note missing support for old ipc structs.
* print_mq_attr.c: Fallback to linux/mqueue.h when available.
---
 configure.ac    | 13 +++++++++++++
 ipc_defs.h      |  8 +++++++-
 ipc_msg.c       |  4 +---
 ipc_msgctl.c    | 16 ++++++++++++++--
 ipc_sem.c       | 12 +++++++++++-
 ipc_shm.c       |  2 --
 ipc_shmctl.c    | 16 +++++++++++++---
 print_mq_attr.c |  3 +++
 8 files changed, 62 insertions(+), 12 deletions(-)

diff --git a/configure.ac b/configure.ac
index 334dd6f..8071f57 100644
--- a/configure.ac
+++ b/configure.ac
@@ -260,6 +260,10 @@ AC_CHECK_FUNCS(m4_normalize([
 ]))
 AC_CHECK_HEADERS(m4_normalize([
 	asm/cachectl.h
+	asm/ipcbuf.h
+	asm/msgbuf.h
+	asm/sembuf.h
+	asm/shmbuf.h
 	asm/sysmips.h
 	bluetooth/bluetooth.h
 	elf.h
@@ -270,10 +274,15 @@ AC_CHECK_HEADERS(m4_normalize([
 	linux/filter.h
 	linux/hiddev.h
 	linux/ip_vs.h
+	linux/ipc.h
 	linux/mmtimer.h
+	linux/mqueue.h
+	linux/msg.h
 	linux/perf_event.h
 	linux/seccomp.h
 	linux/securebits.h
+	linux/sem.h
+	linux/shm.h
 	linux/utsname.h
 	mqueue.h
 	netinet/sctp.h
@@ -284,7 +293,11 @@ AC_CHECK_HEADERS(m4_normalize([
 	sys/eventfd.h
 	sys/fanotify.h
 	sys/ioctl.h
+	sys/ipc.h
+	sys/msg.h
 	sys/reg.h
+	sys/sem.h
+	sys/shm.h
 	sys/signalfd.h
 	sys/vfs.h
 	sys/xattr.h
diff --git a/ipc_defs.h b/ipc_defs.h
index 31f7ab3..3781b95 100644
--- a/ipc_defs.h
+++ b/ipc_defs.h
@@ -25,7 +25,13 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include <sys/ipc.h>
+#ifdef HAVE_SYS_IPC_H
+# include <sys/ipc.h>
+#elif defined(HAVE_LINUX_IPC_H)
+# include <linux/ipc.h>
+/* While glibc uses __key, the kernel uses key. */
+# define __key key
+#endif
 
 #if !defined IPC_64
 # define IPC_64 0x100
diff --git a/ipc_msg.c b/ipc_msg.c
index 55747cb..2fc7470 100644
--- a/ipc_msg.c
+++ b/ipc_msg.c
@@ -31,9 +31,7 @@
  */
 
 #include "defs.h"
-
-#include <sys/ipc.h>
-#include <sys/msg.h>
+#include "ipc_defs.h"
 
 #include "xlat/ipc_msg_flags.h"
 #include "xlat/resource_flags.h"
diff --git a/ipc_msgctl.c b/ipc_msgctl.c
index a97dd1a..8c83806 100644
--- a/ipc_msgctl.c
+++ b/ipc_msgctl.c
@@ -33,9 +33,20 @@
 #include "defs.h"
 #include "ipc_defs.h"
 
-#include <sys/msg.h>
-#include DEF_MPERS_TYPE(msqid_ds_t)
+#ifdef HAVE_SYS_MSG_H
+/* The C library generally exports the struct the current kernel expects. */
+# include <sys/msg.h>
 typedef struct msqid_ds msqid_ds_t;
+#elif defined(HAVE_ASM_MSGBUF_H)
+/* The asm header provides the 64bit struct directly for us. */
+# include <asm/msgbuf.h>
+typedef struct msqid64_ds msqid_ds_t;
+#elif defined(HAVE_LINUX_MSG_H)
+/* The linux header might provide the right struct. */
+# include <linux/msg.h>
+typedef struct msqid64_ds msqid_ds_t;
+#endif
+#include DEF_MPERS_TYPE(msqid_ds_t)
 #include MPERS_DEFS
 
 #include "xlat/msgctl_flags.h"
@@ -43,6 +54,7 @@ typedef struct msqid_ds msqid_ds_t;
 static void
 print_msqid_ds(struct tcb *tcp, const long addr, int cmd)
 {
+	/* TODO: We don't properly decode old compat ipc calls. */
 	if (cmd & IPC_64)
 		cmd &= ~IPC_64;
 	msqid_ds_t msqid_ds;
diff --git a/ipc_sem.c b/ipc_sem.c
index e98f8ef..3fd2ded 100644
--- a/ipc_sem.c
+++ b/ipc_sem.c
@@ -33,11 +33,16 @@
 #include "defs.h"
 #include "ipc_defs.h"
 
-#include <sys/sem.h>
+#ifdef HAVE_SYS_SEM_H
+# include <sys/sem.h>
+#elif defined(HAVE_LINUX_SEM_H)
+# include <linux/sem.h>
+#endif
 
 #include "xlat/semctl_flags.h"
 #include "xlat/semop_flags.h"
 
+#if defined(HAVE_SYS_SHM_H) || defined(HAVE_LINUX_SEM_H)
 static void
 tprint_sembuf(const struct sembuf *sb)
 {
@@ -45,10 +50,12 @@ tprint_sembuf(const struct sembuf *sb)
 	printflags(semop_flags, sb->sem_flg, "SEM_???");
 	tprints("}");
 }
+#endif
 
 static void
 tprint_sembuf_array(struct tcb *tcp, const long addr, const unsigned long count)
 {
+#if defined(HAVE_SYS_SHM_H) || defined(HAVE_LINUX_SEM_H)
 	unsigned long max_count;
 	struct sembuf sb;
 
@@ -78,6 +85,9 @@ tprint_sembuf_array(struct tcb *tcp, const long addr, const unsigned long count)
 
 		tprints("]");
 	}
+#else
+	printaddr(addr);
+#endif
 	tprintf(", %lu", count);
 }
 
diff --git a/ipc_shm.c b/ipc_shm.c
index 4a41690..03f38ab 100644
--- a/ipc_shm.c
+++ b/ipc_shm.c
@@ -32,8 +32,6 @@
 
 #include "defs.h"
 
-#include <sys/shm.h>
-
 #include "xlat/shm_resource_flags.h"
 #include "xlat/shm_flags.h"
 
diff --git a/ipc_shmctl.c b/ipc_shmctl.c
index 4bd6c85..c4b9f75 100644
--- a/ipc_shmctl.c
+++ b/ipc_shmctl.c
@@ -33,11 +33,20 @@
 #include "defs.h"
 #include "ipc_defs.h"
 
-#include <sys/shm.h>
-
 #include DEF_MPERS_TYPE(shmid_ds_t)
-#include <sys/shm.h>
+#ifdef HAVE_SYS_SHM_H
+/* The C library generally exports the struct the current kernel expects. */
+# include <sys/shm.h>
 typedef struct shmid_ds shmid_ds_t;
+#elif defined(HAVE_ASM_SHMBUF_H)
+/* The asm header provides the 64bit struct directly for us. */
+# include <asm/shmbuf.h>
+typedef struct shmid64_ds shmid_ds_t;
+#elif defined(HAVE_LINUX_SHM_H)
+/* The linux header might provide the right struct. */
+# include <linux/shm.h>
+typedef struct shmid64_ds shmid_ds_t;
+#endif
 #include MPERS_DEFS
 
 #include "xlat/shmctl_flags.h"
@@ -45,6 +54,7 @@ typedef struct shmid_ds shmid_ds_t;
 static void
 print_shmid_ds(struct tcb *tcp, const long addr, int cmd)
 {
+	/* TODO: We don't properly decode old compat ipc calls. */
 	if (cmd & IPC_64)
 		cmd &= ~IPC_64;
 	shmid_ds_t shmid_ds;
diff --git a/print_mq_attr.c b/print_mq_attr.c
index f9bff34..41334fa 100644
--- a/print_mq_attr.c
+++ b/print_mq_attr.c
@@ -32,6 +32,9 @@
 #ifdef HAVE_MQUEUE_H
 # include <mqueue.h>
 typedef struct mq_attr mq_attr_t;
+#elif defined(HAVE_LINUX_MQUEUE_H)
+# include <linux/mqueue.h>
+typedef struct mq_attr mq_attr_t;
 #endif
 #include MPERS_DEFS
 
-- 
2.5.2





More information about the Strace-devel mailing list