diff -Nuar binutils-2.11.93.0.2.orig/gas/as.c binutils-2.11.93.0.2/gas/as.c --- binutils-2.11.93.0.2.orig/gas/as.c Sun Feb 3 22:22:31 2002 +++ binutils-2.11.93.0.2/gas/as.c Fri Dec 27 17:26:24 2002 @@ -808,6 +808,10 @@ myname = argv[0]; xmalloc_set_program_name (myname); +#ifdef CHECK_ENVIRONMENT + CHECK_ENVIRONMENT +#endif + START_PROGRESS (myname, 0); #ifndef OBJ_DEFAULT_OUTPUT_FILE_NAME diff -Nuar binutils-2.11.93.0.2.orig/gas/config/tc-arm.c binutils-2.11.93.0.2/gas/config/tc-arm.c --- binutils-2.11.93.0.2.orig/gas/config/tc-arm.c Sun Feb 3 22:22:31 2002 +++ binutils-2.11.93.0.2/gas/config/tc-arm.c Fri Dec 27 17:26:24 2002 @@ -9209,6 +9209,9 @@ mfpu_opt = march_fpu_opt; } + if (mcpu_cpu_opt == -1) + set_default_cpu(); + if (mfpu_opt == -1) { if (mcpu_cpu_opt == -1) @@ -10483,6 +10486,65 @@ as_bad (_("bad instruction `%s'"), start); } +static int find_family_cpu + PARAMS ((char ** ptr)); + +static int +find_family_cpu (family_cpu) + char **family_cpu; +{ + char *p; + int len; + + p = getenv("CROSS_COMPILE"); + if (p && *p) + { + p = basename(p); + len = strlen(p); + *family_cpu = (char *) xmalloc(len + 1); + strcpy(*family_cpu, p); + if ((*family_cpu)[len - 1] == '-') + (*family_cpu)[len - 1] = '\0'; + return 1; + } + return 0; +} + +/* set_default_cpu + If the CROSS_COMPILE environment variable is set + set cpu-dependent flags. They will be overridden by command-line + flags */ +void +set_default_cpu () +{ + char * family_cpu; + int i; + char * cpu; + + struct target_cpu { + char * target_arch; + int cpu; + } target_cpu_tbl[] = { + {"920TDI", ARM_ARCH_V4T} + }; + + if (! find_family_cpu(&family_cpu)) + as_fatal (_("The CROSS_COMPILE environment variable is not set")); + + if (!strncasecmp(family_cpu, "arm_", 4)) + { + cpu = family_cpu + 4; + for (i = 0; i < sizeof(target_cpu_tbl)/sizeof(target_cpu_tbl[0]); i++) + { + if (!strcmp(target_cpu_tbl[i].target_arch, cpu)) + { + mcpu_cpu_opt = target_cpu_tbl[i].cpu; + break; + } + } + } +} + /* md_parse_option Invocation line includes a switch not recognized by the base assembler. See if it's a processor-specific option. diff -Nuar binutils-2.11.93.0.2.orig/gas/config/tc-mips.c binutils-2.11.93.0.2/gas/config/tc-mips.c --- binutils-2.11.93.0.2.orig/gas/config/tc-mips.c Sun Feb 3 22:22:31 2002 +++ binutils-2.11.93.0.2/gas/config/tc-mips.c Fri Dec 27 17:27:11 2002 @@ -9738,6 +9738,65 @@ }; size_t md_longopts_size = sizeof (md_longopts); +static int find_family_cpu + PARAMS ((char ** ptr)); + +/* set_default_cpu + If the CROSS_COMPILE environment variable is set + set cpu-dependent flags. They will be overridden by command-line + flags */ +void +set_default_cpu () +{ + char * family_cpu; + int i; + char * cpu; + + struct target_cpu { + char * target_arch; + int cpu; + } target_cpu_tbl[] = { + {"4KC", CPU_MIPS32 } + }; + + if (! find_family_cpu(&family_cpu)) + as_fatal (_("The CROSS_COMPILE environment variable is not set")); + + if (!strncasecmp(family_cpu, "mips_", 5)) + { + cpu = family_cpu + 5; + for (i = 0; i < sizeof(target_cpu_tbl)/sizeof(target_cpu_tbl[0]); i++) + { + if (!strcmp(target_cpu_tbl[i].target_arch, cpu)) + { + mips_cpu = target_cpu_tbl[i].cpu; mips_arch=mips_cpu; + break; + } + } + } +} + +static int +find_family_cpu (family_cpu) + char **family_cpu; +{ + char *p; + int len; + + p = getenv("CROSS_COMPILE"); + if (p && *p) + { + p = basename(p); + len = strlen(p); + *family_cpu = (char *) xmalloc(len + 1); + strcpy(*family_cpu, p); + if ((*family_cpu)[len - 1] == '-') + (*family_cpu)[len - 1] = '\0'; + return 1; + } + return 0; +} + int md_parse_option (c, arg) int c; @@ -13168,6 +13227,7 @@ { "mipsisa32", 0, ISA_MIPS32, CPU_MIPS32, }, { "Generic-MIPS32", 0, ISA_MIPS32, CPU_MIPS32, }, { "4kc", 0, ISA_MIPS32, CPU_MIPS32, }, + { "r4kc", 0, ISA_MIPS32, CPU_MIPS32, }, { "4km", 0, ISA_MIPS32, CPU_MIPS32, }, { "4kp", 0, ISA_MIPS32, CPU_MIPS32, }, diff -Nuar binutils-2.11.93.0.2.orig/gas/config/tc-mips.h binutils-2.11.93.0.2/gas/config/tc-mips.h --- binutils-2.11.93.0.2.orig/gas/config/tc-mips.h Sun Feb 3 22:22:31 2002 +++ binutils-2.11.93.0.2/gas/config/tc-mips.h Fri Dec 27 17:26:24 2002 @@ -149,4 +149,7 @@ extern void mips_enable_auto_align PARAMS ((void)); #define md_elf_section_change_hook() mips_enable_auto_align() +#define CHECK_ENVIRONMENT set_default_cpu(); + extern void set_default_cpu PARAMS (( )); + #endif /* TC_MIPS */ diff -Nuar binutils-2.11.93.0.2.orig/gas/config/tc-ppc.c binutils-2.11.93.0.2/gas/config/tc-ppc.c --- binutils-2.11.93.0.2.orig/gas/config/tc-ppc.c Sun Feb 3 22:22:31 2002 +++ binutils-2.11.93.0.2/gas/config/tc-ppc.c Fri Dec 27 17:26:24 2002 @@ -805,6 +805,70 @@ }; const size_t md_longopts_size = sizeof (md_longopts); +static int find_family_cpu + PARAMS ((char ** ptr)); + +/* set_default_cpu + If the CROSS_COMPILE environment variable is set + set cpu-dependent flags. They will be overridden by command-line + flags */ +void +set_default_cpu () +{ + char * family_cpu; + int i; + char * cpu; + + struct target_cpu { + char * target_arch; + int flags; + } target_cpu_tbl[] = { + {"4xx", PPC_OPCODE_PPC }, + {"4xxFP", PPC_OPCODE_PPC }, + {"74xx", PPC_OPCODE_PPC | PPC_OPCODE_ALTIVEC}, + {"7xx", PPC_OPCODE_PPC }, + {"82xx", PPC_OPCODE_PPC }, + {"8xx", PPC_OPCODE_PPC } + }; + + if (! find_family_cpu(&family_cpu)) + as_fatal (_("The CROSS_COMPILE environment variable is not set")); + + if (!strncasecmp(family_cpu, "ppc_", 4)) + { + cpu = family_cpu + 4; + for (i = 0; i < sizeof(target_cpu_tbl)/sizeof(target_cpu_tbl[0]); i++) + { + if (!strcmp(target_cpu_tbl[i].target_arch, cpu)) + { + ppc_cpu = target_cpu_tbl[i].flags; + break; + } + } + } +} + +static int +find_family_cpu (family_cpu) + char **family_cpu; +{ + char *p; + int len; + + p = getenv("CROSS_COMPILE"); + if (p && *p) + { + p = basename(p); + len = strlen(p); + *family_cpu = (char *) xmalloc(len + 1); + strcpy(*family_cpu, p); + if ((*family_cpu)[len - 1] == '-') + (*family_cpu)[len - 1] = '\0'; + return 1; + } + return 0; +} + int md_parse_option (c, arg) int c; diff -Nuar binutils-2.11.93.0.2.orig/gas/config/tc-ppc.h binutils-2.11.93.0.2/gas/config/tc-ppc.h --- binutils-2.11.93.0.2.orig/gas/config/tc-ppc.h Sat Nov 17 01:05:52 2001 +++ binutils-2.11.93.0.2/gas/config/tc-ppc.h Fri Dec 27 17:26:24 2002 @@ -297,3 +297,7 @@ extern int ppc_parse_name PARAMS ((const char *, struct expressionS *)); #define md_operand(x) + +#define CHECK_ENVIRONMENT set_default_cpu(); + extern void set_default_cpu PARAMS (( )); + diff -Nuar binutils-2.11.93.0.2.orig/ld/Makefile.in binutils-2.11.93.0.2/ld/Makefile.in --- binutils-2.11.93.0.2.orig/ld/Makefile.in Fri Dec 27 17:25:45 2002 +++ binutils-2.11.93.0.2/ld/Makefile.in Fri Dec 27 17:26:24 2002 @@ -1775,8 +1775,7 @@ n=`echo ld | sed '$(transform)'`; \ if [ "$(bindir)/$$n$(EXEEXT)" != "$(tooldir)/bin/ld$(EXEEXT)" ]; then \ rm -f $(tooldir)/bin/ld$(EXEEXT); \ - ln $(bindir)/$$n$(EXEEXT) $(tooldir)/bin/ld$(EXEEXT) >/dev/null 2>/dev/null \ - || $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) ld-new$(EXEEXT) $(tooldir)/bin/ld$(EXEEXT); \ + ln -s ../../bin/$$n$(EXEEXT) $(tooldir)/bin/ld$(EXEEXT) >/dev/null 2>/dev/null; \ fi install-data-local: diff -Nuar binutils-2.11.93.0.2.orig/ld/ldfile.c binutils-2.11.93.0.2/ld/ldfile.c --- binutils-2.11.93.0.2.orig/ld/ldfile.c Sat Nov 17 01:05:53 2001 +++ binutils-2.11.93.0.2/ld/ldfile.c Fri Dec 27 17:26:24 2002 @@ -36,6 +36,9 @@ #include "ldemul.h" #include "libiberty.h" +extern char *cross_dir; +extern char *replace(char *, char *); + const char *ldfile_input_filename; boolean ldfile_assumed_script = false; const char *ldfile_output_machine_name = ""; @@ -90,6 +93,9 @@ new = (search_dirs_type *) xmalloc (sizeof (search_dirs_type)); new->name = name; new->cmdline = cmdline; + if (cross_dir && !cmdline) + new->name = replace(cross_dir, name); + if (append) { new->next = NULL; diff -Nuar binutils-2.11.93.0.2.orig/ld/ldmain.c binutils-2.11.93.0.2/ld/ldmain.c --- binutils-2.11.93.0.2.orig/ld/ldmain.c Fri Dec 27 17:25:45 2002 +++ binutils-2.11.93.0.2/ld/ldmain.c Fri Dec 27 17:26:24 2002 @@ -47,6 +47,7 @@ #endif #include +#include #ifdef HAVE_SBRK #ifdef NEED_DECLARATION_SBRK @@ -54,6 +55,14 @@ #endif #endif +char *cross_dir; +static char *family_cpu; +static void find_cross_dir(char *, char **); +static void remove_relative_paths (char *); +static int find_family_cpu(char **); +static void set_target_dir(); +char *replace (char *, char *); + static char *get_emulation PARAMS ((int, char **)); static void set_scripts_dir PARAMS ((void)); @@ -178,6 +187,10 @@ program_name = argv[0]; xmalloc_set_program_name (program_name); + if (!find_family_cpu(&family_cpu)) { + einfo (_("%P%F: the CROSS_COMPILE environment variable is not set\n")); + } + START_PROGRESS (program_name, 0); bfd_init (); @@ -219,6 +232,8 @@ command_line.check_section_addresses = true; command_line.multilib_dir = NULL; + find_cross_dir(program_name, &cross_dir); + /* We initialize DEMANGLING based on the environment variable COLLECT_NO_DEMANGLE. The gcc collect2 program will demangle the output of the linker, unless COLLECT_NO_DEMANGLE is set in the @@ -311,6 +326,10 @@ the -L's in argv have been processed. */ set_scripts_dir (); + /* Add target-specific directories */ + set_target_dir (); + + /* If we have not already opened and parsed a linker script read the emulation's appropriate default script. */ if (saved_script_handle == NULL) @@ -620,7 +639,12 @@ struct stat s; boolean res; + if (cross_dir) + { + dir = replace(cross_dir, dir); + } dirlen = strlen (dir); + /* sizeof counts the terminating NUL. */ buf = (char *) xmalloc (dirlen + sizeof ("/ldscripts")); sprintf (buf, "%s/ldscripts", dir); @@ -1427,3 +1451,254 @@ return true; } + +#ifndef DIR_SEPARATOR +#define DIR_SEPARATOR '/' +#endif + +#ifndef PATH_SEPARATOR +#define PATH_SEPARATOR ':' +#endif + +/* Remove relative paths -- .. and . */ +static void +remove_relative_paths (char * path) +{ + char *p, *s; + + p = path; + while ((p = strchr (p, DIR_SEPARATOR))) + { + p++; + if (*p == '.') + { + p++; + if (*p == DIR_SEPARATOR) + { + /* Translate "/./" ==> "/" */ + strcpy (p-2, p); + } + else if (*p == '.' && *(p+1) == DIR_SEPARATOR) + { + /* Translate "//../" ==> "/" */ + s = p + 1; + p -= 3; + while ( p > path && *p != DIR_SEPARATOR) + p--; + strcpy (p, s); + } + } + } +} + +/* Find cross directory root */ +static void +find_cross_dir(char *progname, char **ptr) +{ + char *fullpath = xmalloc(MAXPATHLEN); + char *linkfile = xmalloc(MAXPATHLEN); + char *realpath = xmalloc(MAXPATHLEN); + struct stat file; + int ret = 0; + char *p; + int i; + + *ptr = 0; + + if (strchr (progname, '/')) + { + if (progname[0] == '/') + { + /* We have absolute path */ + strcpy (fullpath, progname); + } else { + /* We have relative path, prepend $cwd */ + getcwd (fullpath, MAXPATHLEN); + strcat (fullpath, "/"); + strcat (fullpath, progname); + } + } else { + /* Search pathlist for matching progname */ + char *path; + char *beg, *end; + + path = getenv("PATH"); + beg = path; + while (1) + { + for (end = beg; *end && *end != PATH_SEPARATOR; end++) ; + strncpy (fullpath, beg, end - beg); + fullpath[end - beg] = '\0'; + if (fullpath[end - beg - 1] == DIR_SEPARATOR) + fullpath[end - beg - 1] = '\0'; + if (strcmp (fullpath, ".") == 0) + getcwd (fullpath, MAXPATHLEN); + strcat (fullpath, "/"); + strcat (fullpath, progname); + if ((lstat (fullpath, &file) == 0) && + (S_ISREG(file.st_mode) || S_ISLNK(file.st_mode))) break; + if (*end == '\0') { + free(realpath); + goto RET; /* Not found on path */ + } + beg = end + 1; + } + } + + /* Resolve all symbolic links in the full path */ + while (fullpath[0]) + { + char *t, *s, *q; + int len, off; + + while ((ret = lstat (fullpath, &file)) == 0 && S_ISLNK(file.st_mode)) + { + /* fullpath is a link */ + linkfile[readlink (fullpath, linkfile, MAXPATHLEN)] = '\0'; + if (linkfile[0] == DIR_SEPARATOR) + { + /* Link replaces path */ + strcpy (fullpath, linkfile); + } + else + { + /* Link is relative to current directory */ + q = strrchr (fullpath, DIR_SEPARATOR); + *(q + 1) = '\0'; + strcat (fullpath, linkfile); + } + /* We might have added more relative paths -- remove them */ + remove_relative_paths (fullpath); + } + if (ret) + { + free(realpath); + goto RET; + } + /* Strip off the last segment of the path */ + if ((q = strrchr (fullpath, DIR_SEPARATOR))) + *q++ = '\0'; + else + q = fullpath; + + /* Shift realpath right to make room for new segment and slash */ + off = strlen (q) + 1; + len = strlen (realpath); + for (i = len; i >= 0; i--) + realpath [off + i] = realpath [i]; + + /* Copy new segment to realpath */ + s = q; + t = realpath + 1; + while (*s) + *t++ = *s++; + + /* Stick in separator at beginning of segment. */ + realpath[0] = DIR_SEPARATOR; + } + + /* Split executable name from path */ + p = strrchr (realpath, DIR_SEPARATOR); + *++p = '\0'; + + remove_relative_paths (realpath); + + /* Exclude trailing segments to get to the cross root directory */ + p = realpath; + for (i = 0; i< 2 ; i++) + { + if (!(p = strrchr(realpath, '/'))) + { + free(realpath); + goto RET; + } + *p = '\0'; + } + *ptr = realpath; + +RET: + free (fullpath); + free (linkfile); +} + +/* Replace the initial occurance of PREFIX by the specified prefix */ + +char * +replace (char *new_prefix, char *path) +{ + char prefix[MAXPATHLEN]; + int len; + int i; + char *p; + + strcpy(prefix, SCRIPTDIR); + + /* Find cross dir defined while building */ + for(i = 0; i < 2; i++) + { + if (! (p = strrchr(prefix,'/'))) + return path; + *p = '\0'; + } + len = strlen(prefix); + + if (strcmp(new_prefix, prefix) && + ! strncmp (path, prefix, len)) + { + char *new = xmalloc(strlen(new_prefix) + + strlen(path) - len + 1); + strcpy(new, new_prefix); + strcat(new, path + len); + return new; + } + return path; +} + +static int +find_family_cpu(char **family_cpu) +{ + char *p; + int len; + + p = getenv("CROSS_COMPILE"); + if (p && *p) + { + p = basename(p); + len = strlen(p); + *family_cpu = (char *) xmalloc(len + 1); + strcpy(*family_cpu, p); + if ((*family_cpu)[len - 1] == '-') + (*family_cpu)[len - 1] = '\0'; + return 1; + } + return 0; +} + +static void +set_target_dir() +{ + char prefix[MAXPATHLEN]; + char *target_lib; + char *target_ulib; + char *p; + int i, len; + + strcpy(prefix, SCRIPTDIR); + + /* Find cross dir defined while building */ + for(i = 0; i < 2; i++) + { + if (! (p = strrchr(prefix,'/'))) + return; + *p = '\0'; + } + len = strlen(prefix); + + target_lib = xmalloc(len + 4 + strlen(family_cpu) + 5); + target_ulib = xmalloc(len + 4 + strlen(family_cpu) + 9); + sprintf(target_lib,"%s/../%s/lib", prefix, family_cpu); + sprintf(target_ulib,"%s/../%s/usr/lib", prefix, family_cpu); + ldfile_add_library_path(target_lib, 0, 1); + ldfile_add_library_path(target_ulib, 0, 1); +} +