diff options
author | Nick Clifton <nickc@redhat.com> | 1998-03-26 00:00:54 +0000 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 1998-03-26 00:00:54 +0000 |
commit | 3535c3c04433d0b88e55338b240c25101a9bb8e0 (patch) | |
tree | fb3c00f641420d28901a9ffef03850f959a9eb34 /ld/emultempl/pe.em | |
parent | 38c574bbd3142416766620fe2b5a1fa276a811b7 (diff) | |
download | gdb-3535c3c04433d0b88e55338b240c25101a9bb8e0.zip gdb-3535c3c04433d0b88e55338b240c25101a9bb8e0.tar.gz gdb-3535c3c04433d0b88e55338b240c25101a9bb8e0.tar.bz2 |
Add interworking support for arm-pe/thumb-pe targets.
Diffstat (limited to 'ld/emultempl/pe.em')
-rw-r--r-- | ld/emultempl/pe.em | 172 |
1 files changed, 120 insertions, 52 deletions
diff --git a/ld/emultempl/pe.em b/ld/emultempl/pe.em index 838a010..bee6798 100644 --- a/ld/emultempl/pe.em +++ b/ld/emultempl/pe.em @@ -1,15 +1,8 @@ # This shell script emits a C file. -*- C -*- # It does some substitutions. cat >e${EMULATION_NAME}.c <<EOF -/* For WINDOWS_NT */ -/* The original file generated returned different default scripts depending - on whether certain switches were set, but these switches pertain to the - Linux system and that particular version of coff. In the NT case, we - only determine if the subsystem is console or windows in order to select - the correct entry point by default. */ - - /* This file is part of GLD, the Gnu Linker. + Copyright 1995, 96, 97, 1998 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -25,11 +18,18 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* For WINDOWS_NT */ +/* The original file generated returned different default scripts depending + on whether certain switches were set, but these switches pertain to the + Linux system and that particular version of coff. In the NT case, we + only determine if the subsystem is console or windows in order to select + the correct entry point by default. */ + #include "bfd.h" #include "sysdep.h" #include "bfdlink.h" #include "getopt.h" -#include "ld.h" +#include "libiberty.h" #include "ld.h" #include "ldmain.h" #include "ldgram.h" @@ -66,9 +66,12 @@ static void sort_sections PARAMS ((lang_statement_union_type *)); static struct internal_extra_pe_aouthdr pe; static int dll; +extern const char *output_filename; + static void gld_${EMULATION_NAME}_before_parse() { + output_filename = "a.exe"; ldfile_output_architecture = bfd_arch_${ARCH}; } @@ -144,7 +147,7 @@ static definfo init[] = D(SizeOfHeapReserve,"__size_of_heap_reserve__", 0x100000), D(SizeOfHeapCommit,"__size_of_heap_commit__", 0x1000), D(LoaderFlags,"__loader_flags__", 0x0), - 0 + { NULL, 0, 0, NULL, 0 } }; @@ -171,25 +174,49 @@ set_pe_name (name, val) static void set_pe_subsystem () { + const char *sver; + int len; int i; - static struct + static const struct { - char *name ; - int value; + const char *name; + const int value; + const char *entry; } v[] = { - {"native", 1}, - {"windows",2}, - {"console",3}, - {"os2",5}, - {"posix", 7}, - {0,0} + { "native", 1, "_NtProcessStartup" }, + { "windows", 2, "_WinMainCRTStartup" }, + { "console", 3, "_mainCRTStartup" }, +#if 0 + /* The Microsoft linker does not recognize this. */ + { "os2", 5, "" }, +#endif + { "posix", 7, "___PosixProcessStartup"}, + { 0, 0, 0 } }; + sver = strchr (optarg, ':'); + if (sver == NULL) + len = strlen (optarg); + else + { + char *end; + + len = sver - optarg; + set_pe_name ("__major_subsystem_version__", + strtoul (sver + 1, &end, 0)); + if (*end == '.') + set_pe_name ("__minor_subsystem_version__", + strtoul (end + 1, &end, 0)); + if (*end != '\0') + einfo ("%P: warning: bad version number in -subsystem option\n"); + } + for (i = 0; v[i].name; i++) { - if (!strcmp (optarg, v[i].name)) + if (strncmp (optarg, v[i].name, len) == 0 + && v[i].name[len] == '\0') { set_pe_name ("__subsystem__", v[i].value); @@ -209,11 +236,8 @@ set_pe_subsystem () name specified forces the correct .obj to be used. We can avoid making the user do this by always adding the entry point name as an undefined symbol. */ - if (v[i].value == 2) - { - lang_add_entry ("_WinMainCRTStartup", 1); - ldlang_add_undef ("_WinMainCRTStartup"); - } + lang_add_entry (v[i].entry, 1); + ldlang_add_undef (v[i].entry); return; } @@ -243,9 +267,6 @@ set_pe_stack_heap (resname, comname) char *resname; char *comname; { - char *begin_commit; - char *end; - set_pe_value (resname); if (*optarg == ',') { @@ -343,6 +364,9 @@ gld_${EMULATION_NAME}_parse_args(argc, argv) return 1; } +/* Assign values to the special symbols before the linker script is + read. */ + static void gld_${EMULATION_NAME}_set_symbols() { @@ -352,8 +376,18 @@ gld_${EMULATION_NAME}_set_symbols() lang_statement_list_type *save; if (!init[IMAGEBASEOFF].inited) - init[IMAGEBASEOFF].value = init[DLLOFF].value - ? NT_DLL_IMAGE_BASE : NT_EXE_IMAGE_BASE; + { + if (link_info.relocateable) + init[IMAGEBASEOFF].value = 0; + else if (init[DLLOFF].value) + init[IMAGEBASEOFF].value = NT_DLL_IMAGE_BASE; + else + init[IMAGEBASEOFF].value = NT_EXE_IMAGE_BASE; + } + + /* Don't do any symbol assignments if this is a relocateable link. */ + if (link_info.relocateable) + return; /* Glue the assignments into the abs section */ save = stat_ptr; @@ -370,6 +404,9 @@ gld_${EMULATION_NAME}_set_symbols() *(int *)init[j].ptr = val; else if (init[j].size == sizeof(long)) *(long *)init[j].ptr = val; + /* This might be a long long or other special type. */ + else if (init[j].size == sizeof(bfd_vma)) + *(bfd_vma *)init[j].ptr = val; else abort(); } /* Restore the pointer. */ @@ -385,8 +422,9 @@ gld_${EMULATION_NAME}_set_symbols() static void gld_${EMULATION_NAME}_after_open() { - /* Pass the wacky PE command line options into the output bfd */ - struct internal_extra_pe_aouthdr *i; + /* Pass the wacky PE command line options into the output bfd. + FIXME: This should be done via a function, rather than by + including an internal BFD header. */ if (!coff_data(output_bfd)->pe) { einfo ("%F%P: PE operations on non PE file.\n"); @@ -406,6 +444,13 @@ sort_by_file_name (a, b) { lang_statement_union_type **ra = a; lang_statement_union_type **rb = b; + int i; + + i = strcmp ((*ra)->input_section.ifile->the_bfd->my_archive->filename, + (*rb)->input_section.ifile->the_bfd->my_archive->filename); + if (i != 0) + return i; + return strcmp ((*ra)->input_section.ifile->filename, (*rb)->input_section.ifile->filename); } @@ -434,12 +479,13 @@ sort_sections_1 (startptr, next_after, count, sort_func) lang_statement_union_type **vec; lang_statement_union_type *p; int i; + lang_statement_union_type **ret; if (count == 0) return startptr; - vec = (lang_statement_union_type **) - alloca (count * sizeof (lang_statement_union_type *)); + vec = ((lang_statement_union_type **) + xmalloc (count * sizeof (lang_statement_union_type *))); for (p = *startptr, i = 0; i < count; i++, p = p->next) vec[i] = p; @@ -451,7 +497,9 @@ sort_sections_1 (startptr, next_after, count, sort_func) for (i = 0; i < count - 1; i++) vec[i]->header.next = vec[i + 1]; vec[i]->header.next = next_after; - return &(vec[i]->header.next); + ret = &vec[i]->header.next; + free (vec); + return ret; } /* Sort the .idata\$foo input sections of archives into filename order. @@ -486,12 +534,12 @@ sort_sections (s) if (s->wild_statement.section_name != NULL && strncmp (s->wild_statement.section_name, ".idata", 6) == 0) { - /* Sort any children in the same archive. Run through all - the children of this wild statement, when an - input_section in an archive is found, scan forward to - find all input_sections which are in the same archive. - Sort them by their filename and then re-thread the - pointer chain. */ + /* Sort the children. We want to sort any objects in + the same archive. In order to handle the case of + including a single archive multiple times, we sort + all the children by archive name and then by object + name. After sorting them, we re-thread the pointer + chain. */ while (*p) { @@ -505,9 +553,7 @@ sort_sections (s) int count; for (end = start, count = 0; - end && end->header.type == lang_input_section_enum - && (end->input_section.ifile->the_bfd->my_archive - == start->input_section.ifile->the_bfd->my_archive); + end && end->header.type == lang_input_section_enum; end = end->next) count++; @@ -518,15 +564,18 @@ sort_sections (s) } /* If this is a collection of grouped sections, sort them. - The linker script must explicitly mention "*(.foo\$)". - Don't sort them if \$ is not the last character (not sure if - this is really useful, but it allows explicitly mentioning - some \$ sections and letting the linker handle the rest). */ + The linker script must explicitly mention "*(.foo\$)" or + "*(.foo\$*)". Don't sort them if \$ is not the last + character (not sure if this is really useful, but it + allows explicitly mentioning some \$ sections and letting + the linker handle the rest). */ if (s->wild_statement.section_name != NULL) { char *q = strchr (s->wild_statement.section_name, '\$'); - if (q && q[1] == 0) + if (q != NULL + && (q[1] == '\0' + || (q[1] == '*' && q[2] == '\0'))) { lang_statement_union_type *end; int count; @@ -560,13 +609,29 @@ gld_${EMULATION_NAME}_before_allocation() { if (!ppc_process_before_allocation(is->the_bfd, &link_info)) { - einfo("Errors encountered processing file %s", is->filename); + einfo("Errors encountered processing file %s\n", is->filename); } } } /* We have seen it all. Allocate it, and carry on */ ppc_allocate_toc_section (&link_info); +#else + /* FIXME: we should be able to set the size of the interworking stub section */ + /* Here we rummage through the found bfds to collect glue information. */ + /* FIXME: should this be based on a command line option? krk@cygnus.com */ + { + LANG_FOR_EACH_INPUT_STATEMENT (is) + { + if (!arm_process_before_allocation (is->the_bfd, & link_info)) + { + einfo ("Errors encountered processing file %s", is->filename); + } + } + } + + /* We have seen it all. Allocate it, and carry on */ + arm_allocate_interworking_sections (& link_info); #endif sort_sections (stat_ptr->head); @@ -577,7 +642,11 @@ gld_${EMULATION_NAME}_before_allocation() gets mapped to the output section with everything from the '\$' on stripped (e.g. .text). See the Microsoft Portable Executable and Common Object File Format - Specification 4.1, section 4.2, Grouped Sections. */ + Specification 4.1, section 4.2, Grouped Sections. + + FIXME: This is now handled by the linker script using wildcards, + but I'm leaving this here in case we want to enable it for sections + which are not mentioned in the linker script. */ /*ARGSUSED*/ static boolean @@ -588,7 +657,6 @@ gld${EMULATION_NAME}_place_orphan (file, s) const char *secname; char *output_secname, *ps; lang_output_section_statement_type *os; - lang_statement_list_type *ptr; lang_statement_union_type *l; if ((s->flags & SEC_ALLOC) == 0) |