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 (at) 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 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