diff options
author | Alan Modra <amodra@gmail.com> | 2007-03-26 11:10:44 +0000 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2007-03-26 11:10:44 +0000 |
commit | dc27aea4b88283415703ab781476f49b4caa65fd (patch) | |
tree | 250c0f58b283a174f5664c7fa324c83a6d2a2d4b /ld/emultempl | |
parent | 2d82d84d7dce3978d4c116a63aa4b86364efbfb7 (diff) | |
download | gdb-dc27aea4b88283415703ab781476f49b4caa65fd.zip gdb-dc27aea4b88283415703ab781476f49b4caa65fd.tar.gz gdb-dc27aea4b88283415703ab781476f49b4caa65fd.tar.bz2 |
* 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.
Diffstat (limited to 'ld/emultempl')
-rw-r--r-- | ld/emultempl/ppc32elf.em | 19 | ||||
-rw-r--r-- | ld/emultempl/ppc64elf.em | 18 | ||||
-rw-r--r-- | ld/emultempl/spuelf.em | 149 |
3 files changed, 186 insertions, 0 deletions
diff --git a/ld/emultempl/ppc32elf.em b/ld/emultempl/ppc32elf.em index 10f9107..cee14c0 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 <<EOF +/* Special handling for embedded SPU executables. */ +extern bfd_boolean embedded_spu_file (lang_input_statement_type *, const char *); +static bfd_boolean gld${EMULATION_NAME}_load_symbols (lang_input_statement_type *); + +static bfd_boolean +ppc_recognized_file (lang_input_statement_type *entry) +{ + if (embedded_spu_file (entry, "-m32")) + return TRUE; + + return gld${EMULATION_NAME}_load_symbols (entry); +} + +EOF +LDEMUL_RECOGNIZED_FILE=ppc_recognized_file +fi + # Define some shell vars to insert bits of code into the standard elf # parse_args and list_options functions. # diff --git a/ld/emultempl/ppc64elf.em b/ld/emultempl/ppc64elf.em index deefe41..1fcf3ab 100644 --- a/ld/emultempl/ppc64elf.em +++ b/ld/emultempl/ppc64elf.em @@ -459,6 +459,24 @@ ppc_lang_for_each_input_file (void (*func) (lang_input_statement_type *)) EOF +if grep -q 'ld_elf32_spu_emulation' ldemul-list.h; then + cat >>e${EMULATION_NAME}.c <<EOF +/* Special handling for embedded SPU executables. */ +extern bfd_boolean embedded_spu_file (lang_input_statement_type *, const char *); +static bfd_boolean gld${EMULATION_NAME}_load_symbols (lang_input_statement_type *); + +static bfd_boolean +ppc64_recognized_file (lang_input_statement_type *entry) +{ + if (embedded_spu_file (entry, "-m64")) + return TRUE; + + return gld${EMULATION_NAME}_load_symbols (entry); +} +EOF +LDEMUL_RECOGNIZED_FILE=ppc64_recognized_file +fi + # Define some shell vars to insert bits of code into the standard elf # parse_args and list_options functions. # diff --git a/ld/emultempl/spuelf.em b/ld/emultempl/spuelf.em index d6681ad..2dd34ea 100644 --- a/ld/emultempl/spuelf.em +++ b/ld/emultempl/spuelf.em @@ -238,6 +238,155 @@ gld${EMULATION_NAME}_finish (void) EOF +if grep -q 'ld_elf.*ppc.*_emulation' ldemul-list.h; then + cat >>e${EMULATION_NAME}.c <<EOF +#include "filenames.h" +#include <fcntl.h> +#include <sys/wait.h> + +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. # |