Home | History | Annotate | Line # | Download | only in driver
      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