/* Id: platform.c,v 1.4 2011/05/27 06:32:57 plunky Exp */ /* $NetBSD: platform.c,v 1.1.1.1 2016/02/09 20:29:12 plunky Exp $ */ /*- * Copyright (c) 2011 Joerg Sonnenberger . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include #include "driver.h" struct list { int * opt; const char * str; }; static struct { int always; int crt0; int gcrt0; int crt1; int gcrt1; int crt2; int dllcrt2; int crti; int crtbegin; int crtbeginS; int crtbeginT; int crtend; int crtendS; int crtn; } use; static struct list startfiles[] = { { &use.crt0, "crt0.o" }, { &use.gcrt0, "gcrt0.o" }, { &use.crt1, "crt1.o" }, { &use.gcrt1, "gcrt1.o" }, { &use.crt2, "crt2.o" }, { &use.dllcrt2, "dllcrt2.o" }, { &use.crti, "crti.o" }, { &use.crtbegin, "crtbegin.o" }, { &use.crtbeginS, "crtbeginS.o" }, { &use.crtbeginT, "crtbeginT.o" }, }; static struct list endfiles[] = { { &use.crtend, "crtend.o" }, { &use.crtendS, "crtendS.o" }, { &use.crtn, "crtn.o" }, }; struct list early_linker[] = { { &use.always, "-dynamic-linker" }, { &os.netbsd, "/libexec/ld.elf.so" }, { &os.linux, "/lib64/ld-linux-x86-64.so.2" }, { &use.always, "-m" }, { &mach.i386, "elf_386" }, { &mach.amd64, "elf_x86_64" }, }; static const char * const sysincdir_list_values0[] = { "=/usr/include", NULL }; static const char * const sysincdir_list_values1[] = { /* XXX fix up for libpcc? */ "=/usr/lib/gcc/x86_64-linux-gnu/4.4/include", NULL }; static const struct platform_specific sysincdir_list[] = { { ARCH_ANY, OS_ANY, sysincdir_list_values0 }, { ARCH_X86_64, OS_LINUX, sysincdir_list_values1 }, }; static const char * const crtdir_list_values0[] = { "=/usr/lib/i386", "=/usr/lib", NULL }; static const char * const crtdir_list_values1[] = { "=/usr/lib", NULL }; static const char * const crtdir_list_values2[] = { "=/usr/lib64", "=/usr/lib/gcc/x86_64-linux-gnu/4.4", NULL }; static const struct platform_specific crtdir_list[] = { { ARCH_I386, OS_NETBSD, crtdir_list_values0 }, { ARCH_X86_64, OS_NETBSD, crtdir_list_values1 }, { ARCH_X86_64, OS_LINUX, crtdir_list_values2 }, }; static const char * const stdlib_list_values0[] = { "-L/usr/lib/gcc/x86_64-linux-gnu/4.4", NULL }; static const char * const stdlib_list_values1[] = { "-lgcc", "--as-needed", "-lgcc_s", "--no-as-needed", "-lc", "-lgcc", "--as-needed", "-lgcc_s", "--no-as-needed", NULL }; static const struct platform_specific stdlib_list[] = { { ARCH_X86_64, OS_LINUX, stdlib_list_values0 }, { ARCH_ANY, OS_ANY, stdlib_list_values1 }, }; static const char * const program_dirs_values0[] = { LIBEXECDIR, NULL }; static const struct platform_specific program_dirs[] = { { ARCH_ANY, OS_ANY, program_dirs_values0 }, }; #define ARRAYLEN(a) (sizeof(a) / sizeof((a)[0])) #define ARRAYPAIR(a) a, ARRAYLEN(a) static const struct { const struct platform_specific *initializer; size_t len; struct strlist *list; } platform_specific_inits[] = { { ARRAYPAIR(early_program_csu), &early_program_csu_files }, { ARRAYPAIR(late_program_csu), &late_program_csu_files }, { ARRAYPAIR(early_dso_csu), &early_dso_csu_files }, { ARRAYPAIR(late_dso_csu), &late_dso_csu_files }, { ARRAYPAIR(predefined_macros), &preprocessor_flags }, { ARRAYPAIR(early_linker), &early_linker_flags }, { ARRAYPAIR(sysincdir_list), &sysincdirs }, { ARRAYPAIR(crtdir_list), &crtdirs }, { ARRAYPAIR(stdlib_list), &stdlib_flags }, { ARRAYPAIR(program_dirs), &progdirs }, }; void init_platform_specific(const char *os_name, const char *arch_name) { enum os os; enum architecture arch; size_t i, j, len; const struct platform_specific *initializer; struct strlist *l; os = OS_ANY; for (i = 0; i < ARRAYLEN(os_mapping); ++i) { if (strcmp(os_mapping[i].name, os_name) == 0) { os = os_mapping[i].os; break; } } if (os == OS_ANY) error("unknown Operating System: %s", os_name); arch = ARCH_ANY; for (i = 0; i < ARRAYLEN(arch_mapping); ++i) { if (strcmp(arch_mapping[i].name, arch_name) == 0) { arch = arch_mapping[i].arch; break; } } if (arch == ARCH_ANY) error("unknown architecture: %s", arch_name); for (i = 0; i < ARRAYLEN(platform_specific_inits); ++i) { initializer = platform_specific_inits[i].initializer; len = platform_specific_inits[i].len; l = platform_specific_inits[i].list; for (j = 0; j < len; ++j) { if (initializer[j].arch != arch && initializer[j].arch != ARCH_ANY) continue; if (initializer[j].os != os && initializer[j].os != OS_ANY) continue; strlist_append_array(l, initializer[j].values); } } preprocessor = PREPROCESSOR; compiler = C_COMPILER; assembler = ASSEMBLER; linker = LINKER; } .