xref: /netbsd-src/external/bsd/pcc/dist/pcc/driver/platform.c (revision 411dcbec990c8aa9c57d3bd2f4bcacadec0b1ab5)
1 /*	Id: platform.c,v 1.4 2011/05/27 06:32:57 plunky Exp 	*/
2 /*	$NetBSD: platform.c,v 1.1.1.1 2016/02/09 20:29:12 plunky Exp $	*/
3 
4 /*-
5  * Copyright (c) 2011 Joerg Sonnenberger <joerg@NetBSD.org>.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in
16  *    the documentation and/or other materials provided with the
17  *    distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
23  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
25  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
27  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
29  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  */
32 
33 #include <string.h>
34 
35 #include "driver.h"
36 
37 struct list {
38 	int *		opt;
39 	const char *	str;
40 };
41 
42 static struct {
43 	int always;
44 	int crt0;
45 	int gcrt0;
46 	int crt1;
47 	int gcrt1;
48 	int crt2;
49 	int dllcrt2;
50 	int crti;
51 	int crtbegin;
52 	int crtbeginS;
53 	int crtbeginT;
54 	int crtend;
55 	int crtendS;
56 	int crtn;
57 } use;
58 
59 static struct list startfiles[] = {
60     { &use.crt0,	"crt0.o"					},
61     { &use.gcrt0,	"gcrt0.o"					},
62     { &use.crt1,	"crt1.o"					},
63     { &use.gcrt1,	"gcrt1.o"					},
64     { &use.crt2,	"crt2.o"					},
65     { &use.dllcrt2,	"dllcrt2.o"					},
66     { &use.crti,	"crti.o"					},
67     { &use.crtbegin,	"crtbegin.o"					},
68     { &use.crtbeginS,	"crtbeginS.o"					},
69     { &use.crtbeginT,	"crtbeginT.o"					},
70 };
71 
72 static struct list endfiles[] = {
73     { &use.crtend,	"crtend.o"					},
74     { &use.crtendS,	"crtendS.o"					},
75     { &use.crtn,	"crtn.o"					},
76 };
77 
78 struct list early_linker[] = {
79     { &use.always,	"-dynamic-linker"				},
80     { &os.netbsd,	"/libexec/ld.elf.so"				},
81     { &os.linux,	"/lib64/ld-linux-x86-64.so.2"			},
82     { &use.always,	"-m"						},
83     { &mach.i386,	"elf_386"					},
84     { &mach.amd64,	"elf_x86_64"					},
85 };
86 
87 
88 static const char * const sysincdir_list_values0[] = {
89     "=/usr/include", NULL
90 };
91 static const char * const sysincdir_list_values1[] = {
92     /* XXX fix up for libpcc? */
93     "=/usr/lib/gcc/x86_64-linux-gnu/4.4/include", NULL
94 };
95 static const struct platform_specific sysincdir_list[] = {
96     { ARCH_ANY, OS_ANY, sysincdir_list_values0 },
97     { ARCH_X86_64, OS_LINUX, sysincdir_list_values1 },
98 };
99 
100 static const char * const crtdir_list_values0[] = {
101     "=/usr/lib/i386", "=/usr/lib", NULL
102 };
103 static const char * const crtdir_list_values1[] = {
104     "=/usr/lib", NULL
105 };
106 static const char * const crtdir_list_values2[] = {
107     "=/usr/lib64", "=/usr/lib/gcc/x86_64-linux-gnu/4.4", NULL
108 };
109 static const struct platform_specific crtdir_list[] = {
110     { ARCH_I386, OS_NETBSD, crtdir_list_values0 },
111     { ARCH_X86_64, OS_NETBSD, crtdir_list_values1 },
112     { ARCH_X86_64, OS_LINUX, crtdir_list_values2 },
113 };
114 
115 static const char * const stdlib_list_values0[] = {
116     "-L/usr/lib/gcc/x86_64-linux-gnu/4.4", NULL
117 };
118 static const char * const stdlib_list_values1[] = {
119     "-lgcc", "--as-needed", "-lgcc_s", "--no-as-needed",
120     "-lc", "-lgcc", "--as-needed", "-lgcc_s", "--no-as-needed", NULL
121 };
122 static const struct platform_specific stdlib_list[] = {
123     { ARCH_X86_64, OS_LINUX, stdlib_list_values0 },
124     { ARCH_ANY, OS_ANY, stdlib_list_values1 },
125 };
126 
127 static const char * const program_dirs_values0[] = {
128     LIBEXECDIR, NULL
129 };
130 static const struct platform_specific program_dirs[] = {
131     { ARCH_ANY, OS_ANY, program_dirs_values0 },
132 };
133 
134 #define	ARRAYLEN(a)	(sizeof(a) / sizeof((a)[0]))
135 #define	ARRAYPAIR(a)	a, ARRAYLEN(a)
136 
137 static const struct {
138 	const struct platform_specific *initializer;
139 	size_t len;
140 	struct strlist *list;
141 } platform_specific_inits[] = {
142     { ARRAYPAIR(early_program_csu), &early_program_csu_files },
143     { ARRAYPAIR(late_program_csu), &late_program_csu_files },
144     { ARRAYPAIR(early_dso_csu), &early_dso_csu_files },
145     { ARRAYPAIR(late_dso_csu), &late_dso_csu_files },
146     { ARRAYPAIR(predefined_macros), &preprocessor_flags },
147     { ARRAYPAIR(early_linker), &early_linker_flags },
148     { ARRAYPAIR(sysincdir_list), &sysincdirs },
149     { ARRAYPAIR(crtdir_list), &crtdirs },
150     { ARRAYPAIR(stdlib_list), &stdlib_flags },
151     { ARRAYPAIR(program_dirs), &progdirs },
152 };
153 
154 void
init_platform_specific(const char * os_name,const char * arch_name)155 init_platform_specific(const char *os_name, const char *arch_name)
156 {
157 	enum os os;
158 	enum architecture arch;
159 	size_t i, j, len;
160 	const struct platform_specific *initializer;
161 	struct strlist *l;
162 
163 	os = OS_ANY;
164 	for (i = 0; i < ARRAYLEN(os_mapping); ++i) {
165 		if (strcmp(os_mapping[i].name, os_name) == 0) {
166 			os = os_mapping[i].os;
167 			break;
168 		}
169 	}
170 	if (os == OS_ANY)
171 		error("unknown Operating System: %s", os_name);
172 
173 	arch = ARCH_ANY;
174 	for (i = 0; i < ARRAYLEN(arch_mapping); ++i) {
175 		if (strcmp(arch_mapping[i].name, arch_name) == 0) {
176 			arch = arch_mapping[i].arch;
177 			break;
178 		}
179 	}
180 	if (arch == ARCH_ANY)
181 		error("unknown architecture: %s", arch_name);
182 
183 	for (i = 0; i < ARRAYLEN(platform_specific_inits); ++i) {
184 		initializer = platform_specific_inits[i].initializer;
185 		len = platform_specific_inits[i].len;
186 		l = platform_specific_inits[i].list;
187 		for (j = 0; j < len; ++j) {
188 			if (initializer[j].arch != arch &&
189 			    initializer[j].arch != ARCH_ANY)
190 				continue;
191 			if (initializer[j].os != os &&
192 			    initializer[j].os != OS_ANY)
193 				continue;
194 
195 			strlist_append_array(l, initializer[j].values);
196 		}
197 	}
198 
199 	preprocessor = PREPROCESSOR;
200 	compiler = C_COMPILER;
201 	assembler = ASSEMBLER;
202 	linker = LINKER;
203 }
204