Skip to content

Commit 6706dda

Browse files
committed
Add wrapper for llvm-strip
1 parent 358a9e0 commit 6706dda

1 file changed

Lines changed: 384 additions & 0 deletions

File tree

tools/gcc-wrapper/strip.c

Lines changed: 384 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,384 @@
1+
#include <stdlib.h>
2+
#include <stdio.h>
3+
#include <string.h>
4+
#include <ctype.h>
5+
#include <errno.h>
6+
7+
#include <unistd.h>
8+
#include <sys/wait.h>
9+
10+
#include "fs/getexec.h"
11+
#include "fs/parentpath.h"
12+
#include "fs/sep.h"
13+
#include "fstream.h"
14+
#include "errors.h"
15+
#include "obggcc.h"
16+
#include "query.h"
17+
18+
static const char HYPHEN[] = "-";
19+
static const char BINUTILS_STRIP[] = "strip";
20+
21+
#define BINFMT_X86_64 (0x01)
22+
#define BINFMT_i386 (0x02)
23+
#define BINFMT_MIPS64EL (0x03)
24+
#define BINFMT_MIPSEL (0x04)
25+
#define BINFMT_RISCV64 (0x05)
26+
#define BINFMT_AARCH64 (0x06)
27+
#define BINFMT_ARM (0x07)
28+
29+
#define BINFMT_SIZE (40)
30+
31+
struct binfmt {
32+
int type;
33+
const char* name;
34+
unsigned char magic[BINFMT_SIZE];
35+
unsigned char mask[BINFMT_SIZE];
36+
};
37+
38+
static const struct binfmt binfmts[] = {
39+
{
40+
.type = BINFMT_X86_64,
41+
.name = "x86_64",
42+
.magic = {0x7f, 0x45, 0x4c, 0x46, 0x2, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x3e, 0x0},
43+
.mask = {0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff}
44+
},
45+
{
46+
.type = BINFMT_i386,
47+
.name = "i386",
48+
.magic = {0x7f, 0x45, 0x4c, 0x46, 0x1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x3, 0x0},
49+
.mask = {0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff}
50+
},
51+
{
52+
.type = BINFMT_MIPS64EL,
53+
.name = "mips64el",
54+
.magic = {0x7f, 0x45, 0x4c, 0x46, 0x2, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x8, 0x0},
55+
.mask = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff}
56+
},
57+
{
58+
.type = BINFMT_MIPSEL,
59+
.name = "mipsel",
60+
.magic = {0x7f, 0x45, 0x4c, 0x46, 0x1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
61+
.mask = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20}
62+
},
63+
{
64+
.type = BINFMT_RISCV64,
65+
.name = "riscv64",
66+
.magic = {0x7f, 0x45, 0x4c, 0x46, 0x2, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0xf3, 0x0},
67+
.mask = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff}
68+
},
69+
{
70+
.type = BINFMT_AARCH64,
71+
.name = "aarch64",
72+
.magic = {0x7f, 0x45, 0x4c, 0x46, 0x2, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0xb7},
73+
.mask = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff}
74+
},
75+
{
76+
.type = BINFMT_ARM,
77+
.name = "arm",
78+
.magic = {0x7f, 0x45, 0x4c, 0x46, 0x1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x28, 0x0},
79+
.mask = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff}
80+
}
81+
};
82+
83+
static const struct binfmt* binfmt_guess(const char* const filename) {
84+
85+
unsigned char chunk[BINFMT_SIZE];
86+
87+
unsigned char a[BINFMT_SIZE];
88+
unsigned char b[BINFMT_SIZE];
89+
90+
const struct binfmt* fmt = NULL;
91+
92+
size_t index = 0;
93+
size_t offset = 0;
94+
95+
fstream_t* stream = NULL;
96+
97+
int status = 0;
98+
99+
memset(chunk, '\0', sizeof(chunk));
100+
memset(a, '\0', sizeof(a));
101+
memset(b, '\0', sizeof(b));
102+
103+
stream = fstream_open(filename, FSTREAM_READ);
104+
105+
if (stream == NULL) {
106+
goto end;
107+
}
108+
109+
if (fstream_read(stream, chunk, sizeof(chunk)) == FSTREAM_ERROR) {
110+
goto end;
111+
}
112+
113+
for (index = 0; index < sizeof(binfmts) / sizeof(*binfmts); index++) {
114+
fmt = &binfmts[index];
115+
116+
for (offset = 0; offset < BINFMT_SIZE; offset++) {
117+
a[offset] = (fmt->magic[offset] & fmt->mask[offset]);
118+
}
119+
120+
for (offset = 0; offset < BINFMT_SIZE; offset++) {
121+
b[offset] = (chunk[offset] & fmt->mask[offset]);
122+
}
123+
124+
if (memcmp(a, b, BINFMT_SIZE) == 0) {
125+
goto end;
126+
}
127+
}
128+
129+
fmt = NULL;
130+
131+
end:;
132+
133+
fstream_close(stream);
134+
135+
return fmt;
136+
137+
}
138+
139+
static const char* binfmt_get_triplet(const struct binfmt* const fmt) {
140+
141+
switch (fmt->type) {
142+
case BINFMT_X86_64:
143+
#if defined(OBGGCC)
144+
return "x86_64-unknown-linux-gnu";
145+
#elif defined(PINO)
146+
return "x86_64-unknown-linux-android";
147+
#endif
148+
case BINFMT_i386:
149+
#if defined(OBGGCC)
150+
return "i386-unknown-linux-gnu";
151+
#elif defined(PINO)
152+
return "i686-unknown-linux-android";
153+
#endif
154+
case BINFMT_MIPS64EL:
155+
#if defined(OBGGCC)
156+
return "mips64el-unknown-linux-gnuabi64";
157+
#elif defined(PINO)
158+
return "mips64el-unknown-linux-android";
159+
#endif
160+
case BINFMT_MIPSEL:
161+
#if defined(OBGGCC)
162+
return "mipsel-unknown-linux-gnu";
163+
#elif defined(PINO)
164+
return "mipsel-unknown-linux-android";
165+
#endif
166+
case BINFMT_RISCV64:
167+
#if defined(PINO)
168+
return "riscv64-unknown-linux-android";
169+
#endif
170+
case BINFMT_AARCH64:
171+
#if defined(OBGGCC)
172+
return "aarch64-unknown-linux-gnu";
173+
#elif defined(PINO)
174+
return "aarch64-unknown-linux-android";
175+
#endif
176+
case BINFMT_ARM:
177+
#if defined(OBGGCC)
178+
return "arm-unknown-linux-gnueabihf";
179+
#elif defined(PINO)
180+
return "armv7-unknown-linux-androideabi";
181+
#endif
182+
}
183+
184+
return NULL;
185+
186+
}
187+
188+
int main(int argc, char* argv[], char* envp[]) {
189+
190+
hquery_t query = {0};
191+
192+
pid_t pid = 0;
193+
int wstatus = 0;
194+
195+
int verbose = 0;
196+
197+
int err = ERR_SUCCESS;
198+
199+
const struct binfmt* fmt = NULL;
200+
201+
const char* triplet = NULL;
202+
203+
char* parent_directory = NULL;
204+
char* app_filename = NULL;
205+
206+
char* cur = NULL;
207+
char* executable = NULL;
208+
209+
size_t index = 0;
210+
211+
char** args = NULL;
212+
213+
size_t kargc = 0;
214+
char** kargv = NULL;
215+
216+
size_t inputsc = 0;
217+
char** inputs = NULL;
218+
219+
kargv = malloc(
220+
sizeof(*argv) * (
221+
argc +
222+
1 /* NULL */
223+
)
224+
);
225+
226+
if (kargv == NULL) {
227+
err = ERR_MEM_ALLOC_FAILURE;
228+
goto end;
229+
}
230+
231+
inputs = malloc(sizeof(*argv) * (argc + 1));
232+
233+
if (inputs == NULL) {
234+
err = ERR_MEM_ALLOC_FAILURE;
235+
goto end;
236+
}
237+
238+
query_load_environ(&query);
239+
240+
verbose = query_get_bool(&query, ENV_VERBOSE) == 1;
241+
242+
for (index = 1; index < (size_t) argc; index++) {
243+
cur = argv[index];
244+
245+
if (cur[0] == '-') {
246+
kargv[kargc++] = cur;
247+
} else {
248+
inputs[inputsc++] = cur;
249+
}
250+
}
251+
252+
if (inputsc == 0) {
253+
fprintf(stderr, "nothing here but crickets\n");
254+
goto end;
255+
}
256+
257+
kargv[kargc++] = NULL;
258+
259+
app_filename = get_app_filename();
260+
261+
if (app_filename == NULL) {
262+
err = ERR_GET_APP_FILENAME_FAILURE;
263+
goto end;
264+
}
265+
266+
parent_directory = malloc(strlen(app_filename) + 1);
267+
268+
if (parent_directory == NULL) {
269+
err = ERR_MEM_ALLOC_FAILURE;
270+
goto end;
271+
}
272+
273+
/* Get the directory where our executable is (i.e., <prefix>/bin) */
274+
get_parent_path(app_filename, parent_directory, 1);
275+
276+
args = malloc(
277+
sizeof(*kargv) * (
278+
kargc +
279+
1 + /* <triplet>-<strip> */
280+
1 + /* <input> */
281+
1 /* NULL */
282+
)
283+
);
284+
285+
if (args == NULL) {
286+
err = ERR_MEM_ALLOC_FAILURE;
287+
goto end;
288+
}
289+
290+
memcpy(&args[1], kargv, kargc * sizeof(*kargv));
291+
292+
for (index = 0; index < inputsc; index++) {
293+
cur = inputs[index];
294+
295+
fmt = binfmt_guess(cur);
296+
297+
if (fmt == NULL) {
298+
err = ERR_BINFMT_GUESS_FAILURE;
299+
goto end;
300+
}
301+
302+
triplet = binfmt_get_triplet(fmt);
303+
304+
if (triplet == NULL) {
305+
err = ERR_BINFMT_GUESS_FAILURE;
306+
goto end;
307+
}
308+
309+
free(executable);
310+
311+
executable = malloc(strlen(parent_directory) + strlen(PATHSEP_S) + strlen(triplet) + strlen(HYPHEN) + strlen(BINUTILS_STRIP) + 1);
312+
313+
if (executable == NULL) {
314+
err = ERR_MEM_ALLOC_FAILURE;
315+
goto end;
316+
}
317+
318+
strcpy(executable, parent_directory);
319+
strcat(executable, PATHSEP_S);
320+
strcat(executable, triplet);
321+
strcat(executable, HYPHEN);
322+
strcat(executable, BINUTILS_STRIP);
323+
324+
args[0] = executable;
325+
args[kargc] = cur;
326+
args[kargc + 1] = NULL;
327+
puts(cur);
328+
if (verbose) {
329+
obggcc_print_args(args);
330+
}
331+
332+
pid = fork();
333+
334+
if (pid == 0) {
335+
if (execve(executable, args, environ) == -1) {
336+
fprintf(stderr, "fatal error: %s: %s\n", obggcc_strerror(ERR_EXECVE_FAILURE), strerror(errno));
337+
_exit(EXIT_FAILURE);
338+
}
339+
} else if (pid > 0) {
340+
wait(&wstatus);
341+
wstatus = WIFSIGNALED(wstatus) ? 128 + WTERMSIG(wstatus) : WEXITSTATUS(wstatus);
342+
343+
if (wstatus != EXIT_SUCCESS) {
344+
err = ERR_EXECVE_SUBPROCESS_FAILURE;
345+
goto end;
346+
}
347+
} else {
348+
err = ERR_FORK_FAILURE;
349+
goto end;
350+
}
351+
}
352+
353+
end:;
354+
355+
free(executable);
356+
free(kargv);
357+
free(args);
358+
free(parent_directory);
359+
free(app_filename);
360+
361+
query_free(&query);
362+
363+
if (err != ERR_SUCCESS) {
364+
cur = strerror(errno);
365+
366+
fprintf(stderr, "fatal error: %s", obggcc_strerror(err));
367+
368+
switch (err) {
369+
case ERR_EXECVE_FAILURE:
370+
case ERR_COPY_FILE_FAILURE:
371+
case ERR_GET_APP_FILENAME_FAILURE:
372+
case ERR_MEM_ALLOC_FAILURE:
373+
fprintf(stderr, ": %s", cur);
374+
break;
375+
}
376+
377+
fprintf(stderr, "\n");
378+
379+
return EXIT_FAILURE;
380+
}
381+
382+
return EXIT_SUCCESS;
383+
384+
}

0 commit comments

Comments
 (0)