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