aboutsummaryrefslogtreecommitdiff
path: root/libcap/execable.h
diff options
context:
space:
mode:
Diffstat (limited to 'libcap/execable.h')
-rw-r--r--libcap/execable.h49
1 files changed, 34 insertions, 15 deletions
diff --git a/libcap/execable.h b/libcap/execable.h
index 0bcc5d4..7a2d247 100644
--- a/libcap/execable.h
+++ b/libcap/execable.h
@@ -71,23 +71,42 @@ static void __execable_parse_args(int *argc_p, char ***argv_p)
}
/*
+ * Linux x86 ABI requires the stack be 16 byte aligned. Keep things
+ * simple and just force it.
+ */
+#if defined(__i386__) || defined(__x86_64__)
+#define __SO_FORCE_ARG_ALIGNMENT __attribute__((force_align_arg_pointer))
+#else
+#define __SO_FORCE_ARG_ALIGNMENT
+#endif /* def some x86 */
+
+/*
+ * Permit the compiler to override this one.
+ */
+#ifndef EXECABLE_INITIALIZE
+#define EXECABLE_INITIALIZE do { } while(0)
+#endif /* ndef EXECABLE_INITIALIZE */
+
+/*
* Note, to avoid any runtime confusion, SO_MAIN is a void static
* function.
*/
-
-#define SO_MAIN \
-static void __execable_main(int, char**); \
-extern void __so_start(void); \
-void __so_start(void) \
-{ \
- int argc; \
- char **argv; \
- __execable_parse_args(&argc, &argv); \
+#define SO_MAIN \
+static void __execable_main(int, char**); \
+__attribute__((visibility ("hidden"))) \
+void __so_start(void); \
+__SO_FORCE_ARG_ALIGNMENT \
+void __so_start(void) \
+{ \
+ int argc; \
+ char **argv; \
+ __execable_parse_args(&argc, &argv); \
+ EXECABLE_INITIALIZE; \
__execable_main(argc, argv); \
- if (argc != 0) { \
- free(argv[0]); \
- free(argv); \
- } \
- exit(0); \
-} \
+ if (argc != 0) { \
+ free(argv[0]); \
+ free(argv); \
+ } \
+ exit(0); \
+} \
static void __execable_main