From dc27aea4b88283415703ab781476f49b4caa65fd Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Mon, 26 Mar 2007 11:10:44 +0000 Subject: [PATCH] * Makefile.am: Add dependency on ldemul-list.h for powerpc and spu target emul files. * configure.in: Check for mkstemp and waitpid. * Makefile.in: Regenerate. * configure: Regenerate. * config.in: Regenerate. * ldlang.c (input_file_chain): Make global. (lang_add_input_file): Don't set lang_has_input_file here. * ldlang.h (input_file_chain): Declare. * emultempl/ppc32elf.em (ppc_recognized_file): New function. (LDEMUL_RECOGNIZED_FILE): Define. * emultempl/ppc64elf.em (ppc64_recognized_file): New function. (LDEMUL_RECOGNIZED_FILE): Define. * emultempl/spuelf.em (struct tflist): New. (tmp_file_list): New var. --- ld/Makefile.am | 11 +++ ld/Makefile.in | 19 +++-- ld/config.in | 6 ++ ld/configure | 4 +- ld/configure.in | 2 +- ld/emultempl/ppc32elf.em | 19 +++++ ld/emultempl/ppc64elf.em | 18 +++++ ld/emultempl/spuelf.em | 149 +++++++++++++++++++++++++++++++++++++++ ld/ldlang.c | 3 +- ld/ldlang.h | 1 + 10 files changed, 224 insertions(+), 8 deletions(-) diff --git a/ld/Makefile.am b/ld/Makefile.am index 67026aefcac..d911f0cc061 100644 --- a/ld/Makefile.am +++ b/ld/Makefile.am @@ -722,6 +722,7 @@ eelf32_sparc_vxworks.c: $(srcdir)/emulparams/elf32_sparc_vxworks.sh \ ${GENSCRIPTS} elf32_sparc_vxworks "$(tdir_elf32_sparc_vxworks)" eelf32_spu.c: $(srcdir)/emulparams/elf32_spu.sh $(srcdir)/emultempl/spuelf.em \ $(srcdir)/emultempl/spu_ovl.o \ + ldemul-list.h \ $(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} ${GENSCRIPTS} elf32_spu "$(tdir_elf32_spu)" $(srcdir)/emultempl/spu_ovl.o: @MAINT@ $(srcdir)/emultempl/spu_ovl.S @@ -819,21 +820,25 @@ eelf32mt.c: $(srcdir)/emulparams/elf32mt.sh \ eelf32lppc.c: $(srcdir)/emulparams/elf32lppc.sh \ $(srcdir)/emulparams/elf32ppccommon.sh \ $(srcdir)/emulparams/elf32ppc.sh $(srcdir)/emultempl/ppc32elf.em \ + ldemul-list.h \ $(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} ${GENSCRIPTS} elf32lppc "$(tdir_elf32lppc)" eelf32lppcnto.c: $(srcdir)/emulparams/elf32lppcnto.sh \ $(srcdir)/emulparams/elf32ppc.sh $(srcdir)/emulparams/elf32ppccommon.sh \ $(srcdir)/emultempl/ppc32elf.em $(ELF_DEPS) \ + ldemul-list.h \ $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} ${GENSCRIPTS} elf32lppcnto "$(tdir_elf32lppcnto)" eelf32lppcsim.c: $(srcdir)/emulparams/elf32lppcsim.sh \ $(srcdir)/emulparams/elf32lppc.sh $(srcdir)/emulparams/elf32ppc.sh \ $(srcdir)/emulparams/elf32ppccommon.sh $(srcdir)/emultempl/ppc32elf.em \ + ldemul-list.h \ $(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} ${GENSCRIPTS} elf32lppcsim "$(tdir_elf32lppcsim)" eelf32ppcnto.c: $(srcdir)/emulparams/elf32ppcnto.sh \ $(srcdir)/emulparams/elf32ppc.sh $(srcdir)/emulparams/elf32ppccommon.sh \ $(srcdir)/emultempl/ppc32elf.em $(ELF_DEPS) \ + ldemul-list.h \ $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} ${GENSCRIPTS} elf32ppcnto "$(tdir_elf32ppcnto)" eelf32ppcwindiss.c: $(srcdir)/emulparams/elf32ppcwindiss.sh \ @@ -854,28 +859,34 @@ eelf32openrisc.c: $(srcdir)/emulparams/elf32openrisc.sh \ ${GENSCRIPTS} elf32openrisc "$(tdir_openrisc)" eelf32ppc.c: $(srcdir)/emulparams/elf32ppc.sh \ $(srcdir)/emulparams/elf32ppccommon.sh $(srcdir)/emultempl/ppc32elf.em \ + ldemul-list.h \ $(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} ${GENSCRIPTS} elf32ppc "$(tdir_elf32ppc)" eelf32ppc_fbsd.c: $(srcdir)/emulparams/elf32ppc_fbsd.sh \ $(srcdir)/emulparams/elf32ppc.sh $(srcdir)/emulparams/elf32ppccommon.sh \ $(srcdir)/emultempl/ppc32elf.em $(ELF_DEPS) \ + ldemul-list.h \ $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} ${GENSCRIPTS} elf32ppc_fbsd "$(tdir_elf32ppc_fbsd)" eelf32ppcsim.c: $(srcdir)/emulparams/elf32ppcsim.sh \ $(srcdir)/emulparams/elf32ppc.sh $(srcdir)/emulparams/elf32ppccommon.sh \ $(srcdir)/emultempl/ppc32elf.em $(ELF_DEPS) \ + ldemul-list.h \ $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} ${GENSCRIPTS} elf32ppcsim "$(tdir_elf32ppcsim)" eelf32ppclinux.c: $(srcdir)/emulparams/elf32ppclinux.sh \ $(srcdir)/emulparams/elf32ppc.sh $(srcdir)/emulparams/elf32ppccommon.sh \ $(srcdir)/emultempl/ppc32elf.em $(ELF_DEPS) \ + ldemul-list.h \ $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} ${GENSCRIPTS} elf32ppclinux "$(tdir_elf32ppclinux)" eelf64ppc.c: $(srcdir)/emulparams/elf64ppc.sh $(srcdir)/emultempl/ppc64elf.em \ + ldemul-list.h \ $(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} ${GENSCRIPTS} elf64ppc "$(tdir_elf64ppc)" eelf64lppc.c: $(srcdir)/emulparams/elf64lppc.sh \ $(srcdir)/emulparams/elf64ppc.sh $(srcdir)/emultempl/ppc64elf.em \ + ldemul-list.h \ $(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} ${GENSCRIPTS} elf64lppc "$(tdir_elf64lppc)" eelf32i370.c: $(srcdir)/emulparams/elf32i370.sh \ diff --git a/ld/Makefile.in b/ld/Makefile.in index 1c2d4ceabcb..de5f6c1774f 100644 --- a/ld/Makefile.in +++ b/ld/Makefile.in @@ -721,15 +721,15 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ - echo ' cd $(srcdir) && $(AUTOMAKE) --cygnus '; \ - cd $(srcdir) && $(AUTOMAKE) --cygnus \ + echo ' cd $(srcdir) && $(AUTOMAKE) --foreign '; \ + cd $(srcdir) && $(AUTOMAKE) --foreign \ && exit 0; \ exit 1;; \ esac; \ done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --cygnus Makefile'; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ cd $(top_srcdir) && \ - $(AUTOMAKE) --cygnus Makefile + $(AUTOMAKE) --foreign Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ @@ -1536,6 +1536,7 @@ eelf32_sparc_vxworks.c: $(srcdir)/emulparams/elf32_sparc_vxworks.sh \ ${GENSCRIPTS} elf32_sparc_vxworks "$(tdir_elf32_sparc_vxworks)" eelf32_spu.c: $(srcdir)/emulparams/elf32_spu.sh $(srcdir)/emultempl/spuelf.em \ $(srcdir)/emultempl/spu_ovl.o \ + ldemul-list.h \ $(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} ${GENSCRIPTS} elf32_spu "$(tdir_elf32_spu)" $(srcdir)/emultempl/spu_ovl.o: @MAINT@ $(srcdir)/emultempl/spu_ovl.S @@ -1633,21 +1634,25 @@ eelf32mt.c: $(srcdir)/emulparams/elf32mt.sh \ eelf32lppc.c: $(srcdir)/emulparams/elf32lppc.sh \ $(srcdir)/emulparams/elf32ppccommon.sh \ $(srcdir)/emulparams/elf32ppc.sh $(srcdir)/emultempl/ppc32elf.em \ + ldemul-list.h \ $(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} ${GENSCRIPTS} elf32lppc "$(tdir_elf32lppc)" eelf32lppcnto.c: $(srcdir)/emulparams/elf32lppcnto.sh \ $(srcdir)/emulparams/elf32ppc.sh $(srcdir)/emulparams/elf32ppccommon.sh \ $(srcdir)/emultempl/ppc32elf.em $(ELF_DEPS) \ + ldemul-list.h \ $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} ${GENSCRIPTS} elf32lppcnto "$(tdir_elf32lppcnto)" eelf32lppcsim.c: $(srcdir)/emulparams/elf32lppcsim.sh \ $(srcdir)/emulparams/elf32lppc.sh $(srcdir)/emulparams/elf32ppc.sh \ $(srcdir)/emulparams/elf32ppccommon.sh $(srcdir)/emultempl/ppc32elf.em \ + ldemul-list.h \ $(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} ${GENSCRIPTS} elf32lppcsim "$(tdir_elf32lppcsim)" eelf32ppcnto.c: $(srcdir)/emulparams/elf32ppcnto.sh \ $(srcdir)/emulparams/elf32ppc.sh $(srcdir)/emulparams/elf32ppccommon.sh \ $(srcdir)/emultempl/ppc32elf.em $(ELF_DEPS) \ + ldemul-list.h \ $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} ${GENSCRIPTS} elf32ppcnto "$(tdir_elf32ppcnto)" eelf32ppcwindiss.c: $(srcdir)/emulparams/elf32ppcwindiss.sh \ @@ -1668,28 +1673,34 @@ eelf32openrisc.c: $(srcdir)/emulparams/elf32openrisc.sh \ ${GENSCRIPTS} elf32openrisc "$(tdir_openrisc)" eelf32ppc.c: $(srcdir)/emulparams/elf32ppc.sh \ $(srcdir)/emulparams/elf32ppccommon.sh $(srcdir)/emultempl/ppc32elf.em \ + ldemul-list.h \ $(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} ${GENSCRIPTS} elf32ppc "$(tdir_elf32ppc)" eelf32ppc_fbsd.c: $(srcdir)/emulparams/elf32ppc_fbsd.sh \ $(srcdir)/emulparams/elf32ppc.sh $(srcdir)/emulparams/elf32ppccommon.sh \ $(srcdir)/emultempl/ppc32elf.em $(ELF_DEPS) \ + ldemul-list.h \ $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} ${GENSCRIPTS} elf32ppc_fbsd "$(tdir_elf32ppc_fbsd)" eelf32ppcsim.c: $(srcdir)/emulparams/elf32ppcsim.sh \ $(srcdir)/emulparams/elf32ppc.sh $(srcdir)/emulparams/elf32ppccommon.sh \ $(srcdir)/emultempl/ppc32elf.em $(ELF_DEPS) \ + ldemul-list.h \ $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} ${GENSCRIPTS} elf32ppcsim "$(tdir_elf32ppcsim)" eelf32ppclinux.c: $(srcdir)/emulparams/elf32ppclinux.sh \ $(srcdir)/emulparams/elf32ppc.sh $(srcdir)/emulparams/elf32ppccommon.sh \ $(srcdir)/emultempl/ppc32elf.em $(ELF_DEPS) \ + ldemul-list.h \ $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} ${GENSCRIPTS} elf32ppclinux "$(tdir_elf32ppclinux)" eelf64ppc.c: $(srcdir)/emulparams/elf64ppc.sh $(srcdir)/emultempl/ppc64elf.em \ + ldemul-list.h \ $(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} ${GENSCRIPTS} elf64ppc "$(tdir_elf64ppc)" eelf64lppc.c: $(srcdir)/emulparams/elf64lppc.sh \ $(srcdir)/emulparams/elf64ppc.sh $(srcdir)/emultempl/ppc64elf.em \ + ldemul-list.h \ $(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS} ${GENSCRIPTS} elf64lppc "$(tdir_elf64lppc)" eelf32i370.c: $(srcdir)/emulparams/elf32i370.sh \ diff --git a/ld/config.in b/ld/config.in index 46fbb98c4df..87308e28cc8 100644 --- a/ld/config.in +++ b/ld/config.in @@ -49,6 +49,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H +/* Define to 1 if you have the `mkstemp' function. */ +#undef HAVE_MKSTEMP + /* Define to 1 if you have the header file, and it defines `DIR'. */ #undef HAVE_NDIR_H @@ -90,6 +93,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H +/* Define to 1 if you have the `waitpid' function. */ +#undef HAVE_WAITPID + /* Name of package */ #undef PACKAGE diff --git a/ld/configure b/ld/configure index 8a81d9a7c02..d34367de176 100755 --- a/ld/configure +++ b/ld/configure @@ -6496,7 +6496,9 @@ done -for ac_func in sbrk realpath glob + + +for ac_func in glob mkstemp realpath sbrk waitpid do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_func" >&5 diff --git a/ld/configure.in b/ld/configure.in index d2dd6f75229..3fd64c068f2 100644 --- a/ld/configure.in +++ b/ld/configure.in @@ -102,7 +102,7 @@ AC_SUBST(HOSTING_LIBS) AC_SUBST(NATIVE_LIB_DIRS) AC_CHECK_HEADERS(string.h strings.h stdlib.h unistd.h elf-hints.h limits.h sys/param.h) -AC_CHECK_FUNCS(sbrk realpath glob) +AC_CHECK_FUNCS(glob mkstemp realpath sbrk waitpid) AC_HEADER_DIRENT AC_MSG_CHECKING(for a known getopt prototype in unistd.h) diff --git a/ld/emultempl/ppc32elf.em b/ld/emultempl/ppc32elf.em index 10f91074dfe..cee14c0c53d 100644 --- a/ld/emultempl/ppc32elf.em +++ b/ld/emultempl/ppc32elf.em @@ -124,6 +124,25 @@ ppc_before_allocation (void) EOF +if grep -q 'ld_elf32_spu_emulation' ldemul-list.h; then + cat >>e${EMULATION_NAME}.c <>e${EMULATION_NAME}.c <>e${EMULATION_NAME}.c < +#include + +struct tflist { + struct tflist *next; + char name[9]; +}; + +static struct tflist *tmp_file_list; + +static void clean_tmp (void) +{ + for (; tmp_file_list != NULL; tmp_file_list = tmp_file_list->next) + unlink (tmp_file_list->name); +} + +/* This function is called when building a ppc32 or ppc64 executable + to handle embedded spu images. */ +extern bfd_boolean embedded_spu_file (lang_input_statement_type *, const char *); + +bfd_boolean +embedded_spu_file (lang_input_statement_type *entry, const char *flags) +{ + const char *cmd[6]; + const char *sym; + char *handle, *p; + struct tflist *tf; + char *oname; + int fd; + pid_t pid; + int status; + union lang_statement_union **old_stat_tail; + union lang_statement_union **old_file_tail; + union lang_statement_union *new_ent; + + if (entry->the_bfd->format != bfd_object + || strcmp (entry->the_bfd->xvec->name, "elf32-spu") != 0 + || (entry->the_bfd->tdata.elf_obj_data->elf_header->e_type != ET_EXEC + && entry->the_bfd->tdata.elf_obj_data->elf_header->e_type != ET_DYN)) + return FALSE; + + /* Use the filename as the symbol marking the program handle struct. */ + sym = strrchr (entry->the_bfd->filename, '/'); +#ifdef HAVE_DOS_BASED_FILE_SYSTEM + { + char *bslash = strrchr (entry->the_bfd->filename, '\\'); + + if (sym == NULL || (bslash != NULL && bslash > sym)) + sym = bslash; + if (sym == NULL + && entry->the_bfd->filename[0] != '\0' + && entry->the_bfd->filename[1] == ':') + sym = entry->the_bfd->filename + 1; + } +#endif + if (sym == NULL) + sym = entry->the_bfd->filename; + else + ++sym; + + handle = xstrdup (sym); + for (p = handle; *p; ++p) + if (!(ISALNUM (*p) || *p == '$' || *p == '.')) + *p = '_'; + + if (tmp_file_list == NULL) + atexit (clean_tmp); + tf = xmalloc (sizeof (*tf)); + tf->next = tmp_file_list; + tmp_file_list = tf; + oname = tf->name; + memcpy (tf->name, "ldXXXXXX", sizeof (tf->name)); + +#ifdef HAVE_MKSTEMP + fd = mkstemp (oname); +#else + oname = mktemp (oname); + if (oname == NULL) + return FALSE; + fd = open (oname, O_RDWR | O_CREAT | O_EXCL, 0600); +#endif + if (fd == -1) + return FALSE; + close (fd); + + /* Use fork() and exec() rather than system() so that we don't + need to worry about quoting args. */ + cmd[0] = "embedspu"; + cmd[1] = flags; + cmd[2] = handle; + cmd[3] = entry->the_bfd->filename; + cmd[4] = oname; + cmd[5] = NULL; + if (trace_file_tries) + { + info_msg (_("running: %s \"%s\" \"%s\" \"%s\" \"%s\"\n"), + cmd[0], cmd[1], cmd[2], cmd[3], cmd[4]); + fflush (stdout); + } + + pid = fork (); + if (pid == -1) + return FALSE; + if (pid == 0) + { + execvp (cmd[0], (char *const *) cmd); + perror (cmd[0]); + _exit (127); + } +#ifdef HAVE_WAITPID +#define WAITFOR(PID, STAT) waitpid (PID, STAT, 0) +#else +#define WAITFOR(PID, STAT) wait (STAT) +#endif + if (WAITFOR (pid, &status) != pid + || !WIFEXITED (status) + || WEXITSTATUS (status) != 0) + return FALSE; +#undef WAITFOR + + old_stat_tail = stat_ptr->tail; + old_file_tail = input_file_chain.tail; + if (lang_add_input_file (oname, lang_input_file_is_file_enum, NULL) == NULL) + return FALSE; + + /* lang_add_input_file put the new list entry at the end of the statement + and input file lists. Move it to just after the current entry. */ + new_ent = *old_stat_tail; + *old_stat_tail = NULL; + stat_ptr->tail = old_stat_tail; + *old_file_tail = NULL; + input_file_chain.tail = old_file_tail; + new_ent->header.next = entry->header.next; + entry->header.next = new_ent; + new_ent->input_statement.next_real_file = entry->next_real_file; + entry->next_real_file = new_ent; + + /* Ensure bfd sections are excluded from the output. */ + bfd_section_list_clear (entry->the_bfd); + entry->loaded = TRUE; + return TRUE; +} + +EOF +fi + # Define some shell vars to insert bits of code into the standard elf # parse_args and list_options functions. # diff --git a/ld/ldlang.c b/ld/ldlang.c index b223b5830dc..85dd2719380 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -52,7 +52,6 @@ static struct obstack map_obstack; #define obstack_chunk_alloc xmalloc #define obstack_chunk_free free static const char *startup_file; -static lang_statement_list_type input_file_chain; static bfd_boolean placed_commons = FALSE; static bfd_boolean stripped_excluded_sections = FALSE; static lang_output_section_statement_type *default_common_section; @@ -89,6 +88,7 @@ lang_output_section_statement_type *abs_output_section; lang_statement_list_type lang_output_section_statement; lang_statement_list_type *stat_ptr = &statement_list; lang_statement_list_type file_chain = { NULL, NULL }; +lang_statement_list_type input_file_chain; struct bfd_sym_chain entry_symbol = { NULL, NULL }; static const char *entry_symbol_default = "start"; const char *entry_section = ".text"; @@ -988,7 +988,6 @@ lang_add_input_file (const char *name, lang_input_file_enum_type file_type, const char *target) { - lang_has_input_file = TRUE; return new_afile (name, file_type, target, TRUE); } diff --git a/ld/ldlang.h b/ld/ldlang.h index d34ea6894d7..33abf9f2a73 100644 --- a/ld/ldlang.h +++ b/ld/ldlang.h @@ -456,6 +456,7 @@ extern struct bfd_sym_chain entry_symbol; extern const char *entry_section; extern bfd_boolean entry_from_cmdline; extern lang_statement_list_type file_chain; +extern lang_statement_list_type input_file_chain; extern int lang_statement_iteration; -- 2.30.2