aboutsummaryrefslogtreecommitdiffstats
path: root/main/apk-tools/0001-finally-fix-building-PIE-binaries.patch
blob: b1316f682e2e65a3dc86a73719100ed5c51dc86b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
From 1e36692a8aee88564b19e6855febd91b4feea5eb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timo=20Ter=C3=A4s?= <timo.teras@iki.fi>
Date: Mon, 12 May 2014 19:42:32 +0300
Subject: [PATCH] finally fix building PIE binaries

the dynamic applet registration never worked with PIE, and as
a temporary hack -nopie was added to default link flags in 2008.

this commit reworks the applet registration mechanism to something
that is compatible with PIE, and removes the hack. finally!
---
 src/Makefile     |  4 ++--
 src/apk.c        | 38 +++++++++++++++++++++++++++++---------
 src/apk_applet.h |  9 ++++++---
 3 files changed, 37 insertions(+), 14 deletions(-)

diff --git a/src/Makefile b/src/Makefile
index 4487007..8fdaf4b 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -62,8 +62,8 @@ progs-$(STATIC)		+= apk.static
 apk.static-objs		:= $(filter-out apk.o,$(apk-objs)) apk-static.o
 LDFLAGS_apk.static	:= -static
 LIBS_apk.static		:= -Wl,--as-needed -ldl -Wl,--no-as-needed
-LDFLAGS_apk		+= -nopie -L$(obj)
-LDFLAGS_apk-test	+= -nopie -L$(obj)
+LDFLAGS_apk		+= -L$(obj)
+LDFLAGS_apk-test	+= -L$(obj)
 
 CFLAGS_ALL		+= $(shell $(PKG_CONFIG) --cflags $(PKGDEPS))
 LIBS			:= -Wl,--as-needed \
diff --git a/src/apk.c b/src/apk.c
index 6cd01de..daf4d7f 100644
--- a/src/apk.c
+++ b/src/apk.c
@@ -33,6 +33,9 @@
 #include "apk_print.h"
 #include "apk_io.h"
 
+static struct list_head apk_applet_list;
+#define foreach_applet(iter) list_for_each_entry(iter, &apk_applet_list, node)
+
 char **apk_argv;
 
 static struct apk_option generic_options[] = {
@@ -150,17 +153,16 @@ static int usage(struct apk_applet *applet)
 {
 	version();
 	if (applet == NULL) {
-		struct apk_applet **a;
+		struct apk_applet *a;
 
 		print_usage("COMMAND", "[ARGS]...",
 			    ARRAY_SIZE(generic_options), generic_options);
 
 		printf("\nThe following commands are available:\n");
-		for (a = &__start_apkapplets; a < &__stop_apkapplets; a++) {
+		foreach_applet(a) {
 			struct apk_indent indent = { .indent = 12 };
-
-			indent.x = printf("  %-*s", indent.indent - 3, (*a)->name);
-			apk_print_indented_words(&indent, (*a)->help);
+			indent.x = printf("  %-*s", indent.indent - 3, a->name);
+			apk_print_indented_words(&indent, a->help);
 			printf("\n");
 		}
 	} else {
@@ -186,11 +188,11 @@ static int usage(struct apk_applet *applet)
 
 static struct apk_applet *find_applet(const char *name)
 {
-	struct apk_applet **a;
+	struct apk_applet *a;
 
-	for (a = &__start_apkapplets; a < &__stop_apkapplets; a++) {
-		if (strcmp(name, (*a)->name) == 0)
-			return *a;
+	foreach_applet(a) {
+		if (strcmp(name, a->name) == 0)
+			return a;
 	}
 
 	return NULL;
@@ -289,6 +291,22 @@ static void setup_automatic_flags(void)
 		apk_flags |= APK_INTERACTIVE;
 }
 
+void apk_applet_register(struct apk_applet *applet)
+{
+	list_init(&applet->node);
+	list_add_tail(&applet->node, &apk_applet_list);
+}
+
+static void apk_applet_register_builtin(void)
+{
+	extern apk_init_func_t __start_initapplets[], __stop_initapplets[];
+	apk_init_func_t *p;
+
+	list_init(&apk_applet_list);
+	for (p = __start_initapplets; p < __stop_initapplets; p++)
+		(*p)();
+}
+
 int main(int argc, char **argv)
 {
 	struct apk_applet *applet;
@@ -309,6 +327,8 @@ int main(int argc, char **argv)
 	apk_string_array_init(&test_repos);
 #endif
 
+	apk_applet_register_builtin();
+
 	apk_argv = malloc(sizeof(char*[argc+2]));
 	memcpy(apk_argv, argv, sizeof(char*[argc]));
 	apk_argv[argc] = NULL;
diff --git a/src/apk_applet.h b/src/apk_applet.h
index fa690fc..d11c259 100644
--- a/src/apk_applet.h
+++ b/src/apk_applet.h
@@ -25,6 +25,8 @@ struct apk_option {
 };
 
 struct apk_applet {
+	struct list_head node;
+
 	const char *name;
 	const char *arguments;
 	const char *help;
@@ -39,10 +41,11 @@ struct apk_applet {
 	int (*main)(void *ctx, struct apk_database *db, struct apk_string_array *args);
 };
 
-extern struct apk_applet *__start_apkapplets, *__stop_apkapplets;
+void apk_applet_register(struct apk_applet *);
+typedef void (*apk_init_func_t)(void);
 
 #define APK_DEFINE_APPLET(x) \
-	static struct apk_applet *__applet_##x \
-	__attribute__((__section__("apkapplets"))) __attribute((used)) = &x;
+static void __register_##x(void) { apk_applet_register(&x); } \
+static apk_init_func_t __regfunc_##x __attribute__((__section__("initapplets"))) __attribute((used)) = __register_##x;
 
 #endif
-- 
1.9.2