Home | History | Annotate | Line # | Download | only in emultempl
beos.em revision 1.1.1.1
      1  1.1  christos # This shell script emits a C file. -*- C -*-
      2  1.1  christos # It does some substitutions.
      3  1.1  christos if [ -z "$MACHINE" ]; then
      4  1.1  christos   OUTPUT_ARCH=${ARCH}
      5  1.1  christos else
      6  1.1  christos   OUTPUT_ARCH=${ARCH}:${MACHINE}
      7  1.1  christos fi
      8  1.1  christos fragment <<EOF
      9  1.1  christos /* This file is part of GLD, the Gnu Linker.
     10  1.1  christos    Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
     11  1.1  christos    2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
     12  1.1  christos 
     13  1.1  christos    This file is part of the GNU Binutils.
     14  1.1  christos 
     15  1.1  christos    This program is free software; you can redistribute it and/or modify
     16  1.1  christos    it under the terms of the GNU General Public License as published by
     17  1.1  christos    the Free Software Foundation; either version 3 of the License, or
     18  1.1  christos    (at your option) any later version.
     19  1.1  christos 
     20  1.1  christos    This program is distributed in the hope that it will be useful,
     21  1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     22  1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     23  1.1  christos    GNU General Public License for more details.
     24  1.1  christos 
     25  1.1  christos    You should have received a copy of the GNU General Public License
     26  1.1  christos    along with this program; if not, write to the Free Software
     27  1.1  christos    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
     28  1.1  christos    MA 02110-1301, USA.  */
     29  1.1  christos 
     30  1.1  christos 
     31  1.1  christos /* For WINDOWS_NT */
     32  1.1  christos /* The original file generated returned different default scripts depending
     33  1.1  christos    on whether certain switches were set, but these switches pertain to the
     34  1.1  christos    Linux system and that particular version of coff.  In the NT case, we
     35  1.1  christos    only determine if the subsystem is console or windows in order to select
     36  1.1  christos    the correct entry point by default. */
     37  1.1  christos 
     38  1.1  christos #include "sysdep.h"
     39  1.1  christos #include "bfd.h"
     40  1.1  christos #include "bfdlink.h"
     41  1.1  christos #include "getopt.h"
     42  1.1  christos #include "libiberty.h"
     43  1.1  christos #include "filenames.h"
     44  1.1  christos #include "ld.h"
     45  1.1  christos #include "ldmain.h"
     46  1.1  christos #include "ldexp.h"
     47  1.1  christos #include "ldlang.h"
     48  1.1  christos #include "ldfile.h"
     49  1.1  christos #include "ldemul.h"
     50  1.1  christos #include <ldgram.h>
     51  1.1  christos #include "ldlex.h"
     52  1.1  christos #include "ldmisc.h"
     53  1.1  christos #include "ldctor.h"
     54  1.1  christos #include "coff/internal.h"
     55  1.1  christos #include "../bfd/libcoff.h"
     56  1.1  christos 
     57  1.1  christos #define TARGET_IS_${EMULATION_NAME}
     58  1.1  christos 
     59  1.1  christos static struct internal_extra_pe_aouthdr pe;
     60  1.1  christos static int dll;
     61  1.1  christos 
     62  1.1  christos extern const char *output_filename;
     63  1.1  christos 
     64  1.1  christos static void
     65  1.1  christos gld_${EMULATION_NAME}_before_parse (void)
     66  1.1  christos {
     67  1.1  christos   ldfile_set_output_arch ("${OUTPUT_ARCH}", bfd_arch_`echo ${ARCH} | sed -e 's/:.*//'`);
     68  1.1  christos   output_filename = "a.exe";
     69  1.1  christos }
     70  1.1  christos 
     72  1.1  christos /* PE format extra command line options.  */
     73  1.1  christos 
     74  1.1  christos /* Used for setting flags in the PE header. */
     75  1.1  christos #define OPTION_BASE_FILE		(300  + 1)
     76  1.1  christos #define OPTION_DLL			(OPTION_BASE_FILE + 1)
     77  1.1  christos #define OPTION_FILE_ALIGNMENT		(OPTION_DLL + 1)
     78  1.1  christos #define OPTION_IMAGE_BASE		(OPTION_FILE_ALIGNMENT + 1)
     79  1.1  christos #define OPTION_MAJOR_IMAGE_VERSION	(OPTION_IMAGE_BASE + 1)
     80  1.1  christos #define OPTION_MAJOR_OS_VERSION		(OPTION_MAJOR_IMAGE_VERSION + 1)
     81  1.1  christos #define OPTION_MAJOR_SUBSYSTEM_VERSION	(OPTION_MAJOR_OS_VERSION + 1)
     82  1.1  christos #define OPTION_MINOR_IMAGE_VERSION	(OPTION_MAJOR_SUBSYSTEM_VERSION + 1)
     83  1.1  christos #define OPTION_MINOR_OS_VERSION		(OPTION_MINOR_IMAGE_VERSION + 1)
     84  1.1  christos #define OPTION_MINOR_SUBSYSTEM_VERSION	(OPTION_MINOR_OS_VERSION + 1)
     85  1.1  christos #define OPTION_SECTION_ALIGNMENT	(OPTION_MINOR_SUBSYSTEM_VERSION + 1)
     86  1.1  christos #define OPTION_STACK                    (OPTION_SECTION_ALIGNMENT + 1)
     87  1.1  christos #define OPTION_SUBSYSTEM                (OPTION_STACK + 1)
     88  1.1  christos #define OPTION_HEAP			(OPTION_SUBSYSTEM + 1)
     89  1.1  christos 
     90  1.1  christos static void
     91  1.1  christos gld${EMULATION_NAME}_add_options
     92  1.1  christos   (int ns ATTRIBUTE_UNUSED, char **shortopts ATTRIBUTE_UNUSED, int nl,
     93  1.1  christos    struct option **longopts, int nrl ATTRIBUTE_UNUSED,
     94  1.1  christos    struct option **really_longopts ATTRIBUTE_UNUSED)
     95  1.1  christos {
     96  1.1  christos   static const struct option xtra_long[] = {
     97  1.1  christos     /* PE options */
     98  1.1  christos     {"base-file", required_argument, NULL, OPTION_BASE_FILE},
     99  1.1  christos     {"dll", no_argument, NULL, OPTION_DLL},
    100  1.1  christos     {"file-alignment", required_argument, NULL, OPTION_FILE_ALIGNMENT},
    101  1.1  christos     {"heap", required_argument, NULL, OPTION_HEAP},
    102  1.1  christos     {"image-base", required_argument, NULL, OPTION_IMAGE_BASE},
    103  1.1  christos     {"major-image-version", required_argument, NULL, OPTION_MAJOR_IMAGE_VERSION},
    104  1.1  christos     {"major-os-version", required_argument, NULL, OPTION_MAJOR_OS_VERSION},
    105  1.1  christos     {"major-subsystem-version", required_argument, NULL, OPTION_MAJOR_SUBSYSTEM_VERSION},
    106  1.1  christos     {"minor-image-version", required_argument, NULL, OPTION_MINOR_IMAGE_VERSION},
    107  1.1  christos     {"minor-os-version", required_argument, NULL, OPTION_MINOR_OS_VERSION},
    108  1.1  christos     {"minor-subsystem-version", required_argument, NULL, OPTION_MINOR_SUBSYSTEM_VERSION},
    109  1.1  christos     {"section-alignment", required_argument, NULL, OPTION_SECTION_ALIGNMENT},
    110  1.1  christos     {"stack", required_argument, NULL, OPTION_STACK},
    111  1.1  christos     {"subsystem", required_argument, NULL, OPTION_SUBSYSTEM},
    112  1.1  christos     {NULL, no_argument, NULL, 0}
    113  1.1  christos   };
    114  1.1  christos 
    115  1.1  christos   *longopts = (struct option *)
    116  1.1  christos     xrealloc (*longopts, nl * sizeof (struct option) + sizeof (xtra_long));
    117  1.1  christos   memcpy (*longopts + nl, &xtra_long, sizeof (xtra_long));
    118  1.1  christos }
    119  1.1  christos 
    120  1.1  christos 
    121  1.1  christos /* PE/WIN32; added routines to get the subsystem type, heap and/or stack
    122  1.1  christos    parameters which may be input from the command line */
    123  1.1  christos 
    124  1.1  christos typedef struct {
    125  1.1  christos   void *ptr;
    126  1.1  christos   int size;
    127  1.1  christos   int value;
    128  1.1  christos   char *symbol;
    129  1.1  christos   int inited;
    130  1.1  christos } definfo;
    131  1.1  christos 
    132  1.1  christos #define D(field,symbol,def)  {&pe.field,sizeof(pe.field), def, symbol,0}
    133  1.1  christos 
    134  1.1  christos static definfo init[] =
    135  1.1  christos {
    136  1.1  christos   /* imagebase must be first */
    137  1.1  christos #define IMAGEBASEOFF 0
    138  1.1  christos   D(ImageBase,"__image_base__", BEOS_EXE_IMAGE_BASE),
    139  1.1  christos #define DLLOFF 1
    140  1.1  christos   {&dll, sizeof(dll), 0, "__dll__", 0},
    141  1.1  christos   D(SectionAlignment,"__section_alignment__", PE_DEF_SECTION_ALIGNMENT),
    142  1.1  christos   D(FileAlignment,"__file_alignment__", PE_DEF_FILE_ALIGNMENT),
    143  1.1  christos   D(MajorOperatingSystemVersion,"__major_os_version__", 4),
    144  1.1  christos   D(MinorOperatingSystemVersion,"__minor_os_version__", 0),
    145  1.1  christos   D(MajorImageVersion,"__major_image_version__", 1),
    146  1.1  christos   D(MinorImageVersion,"__minor_image_version__", 0),
    147  1.1  christos   D(MajorSubsystemVersion,"__major_subsystem_version__", 4),
    148  1.1  christos   D(MinorSubsystemVersion,"__minor_subsystem_version__", 0),
    149  1.1  christos   D(Subsystem,"__subsystem__", 3),
    150  1.1  christos   D(SizeOfStackReserve,"__size_of_stack_reserve__", 0x2000000),
    151  1.1  christos   D(SizeOfStackCommit,"__size_of_stack_commit__", 0x1000),
    152  1.1  christos   D(SizeOfHeapReserve,"__size_of_heap_reserve__", 0x100000),
    153  1.1  christos   D(SizeOfHeapCommit,"__size_of_heap_commit__", 0x1000),
    154  1.1  christos   D(LoaderFlags,"__loader_flags__", 0x0),
    155  1.1  christos   { NULL, 0, 0, NULL, 0 }
    156  1.1  christos };
    157  1.1  christos 
    158  1.1  christos 
    159  1.1  christos static void
    160  1.1  christos set_pe_name (char *name, long val)
    161  1.1  christos {
    162  1.1  christos   int i;
    163  1.1  christos   /* Find the name and set it. */
    164  1.1  christos   for (i = 0; init[i].ptr; i++)
    165  1.1  christos     {
    166  1.1  christos       if (strcmp (name, init[i].symbol) == 0)
    167  1.1  christos 	{
    168  1.1  christos 	  init[i].value = val;
    169  1.1  christos 	  init[i].inited = 1;
    170  1.1  christos 	  return;
    171  1.1  christos 	}
    172  1.1  christos     }
    173  1.1  christos   abort();
    174  1.1  christos }
    175  1.1  christos 
    176  1.1  christos 
    177  1.1  christos static void
    178  1.1  christos set_pe_subsystem (void)
    179  1.1  christos {
    180  1.1  christos   const char *sver;
    181  1.1  christos   int len;
    182  1.1  christos   int i;
    183  1.1  christos   static const struct
    184  1.1  christos     {
    185  1.1  christos       const char *name;
    186  1.1  christos       const int value;
    187  1.1  christos       const char *entry;
    188  1.1  christos     }
    189  1.1  christos   v[] =
    190  1.1  christos     {
    191  1.1  christos       { "native", 1, "_NtProcessStartup" },
    192  1.1  christos       { "windows", 2, "_WinMainCRTStartup" },
    193  1.1  christos       { "wwindows", 2, "_wWinMainCRTStartup" },
    194  1.1  christos       { "console", 3, "_mainCRTStartup" },
    195  1.1  christos       { "wconsole", 3, "_wmainCRTStartup" },
    196  1.1  christos       { "posix", 7, "___PosixProcessStartup"},
    197  1.1  christos       { 0, 0, 0 }
    198  1.1  christos     };
    199  1.1  christos 
    200  1.1  christos   sver = strchr (optarg, ':');
    201  1.1  christos   if (sver == NULL)
    202  1.1  christos     len = strlen (optarg);
    203  1.1  christos   else
    204  1.1  christos     {
    205  1.1  christos       char *end;
    206  1.1  christos 
    207  1.1  christos       len = sver - optarg;
    208  1.1  christos       set_pe_name ("__major_subsystem_version__",
    209  1.1  christos 		   strtoul (sver + 1, &end, 0));
    210  1.1  christos       if (*end == '.')
    211  1.1  christos 	set_pe_name ("__minor_subsystem_version__",
    212  1.1  christos 		     strtoul (end + 1, &end, 0));
    213  1.1  christos       if (*end != '\0')
    214  1.1  christos 	einfo ("%P: warning: bad version number in -subsystem option\n");
    215  1.1  christos     }
    216  1.1  christos 
    217  1.1  christos   for (i = 0; v[i].name; i++)
    218  1.1  christos     {
    219  1.1  christos       if (strncmp (optarg, v[i].name, len) == 0
    220  1.1  christos 	  && v[i].name[len] == '\0')
    221  1.1  christos 	{
    222  1.1  christos 	  set_pe_name ("__subsystem__", v[i].value);
    223  1.1  christos 
    224  1.1  christos 	  /* If the subsystem is windows, we use a different entry
    225  1.1  christos 	     point.  */
    226  1.1  christos 	  lang_default_entry (v[i].entry);
    227  1.1  christos 
    228  1.1  christos 	  return;
    229  1.1  christos 	}
    230  1.1  christos     }
    231  1.1  christos   einfo ("%P%F: invalid subsystem type %s\n", optarg);
    232  1.1  christos }
    233  1.1  christos 
    234  1.1  christos 
    235  1.1  christos static void
    236  1.1  christos set_pe_value (char *name)
    237  1.1  christos {
    238  1.1  christos   char *end;
    239  1.1  christos   set_pe_name (name,  strtoul (optarg, &end, 0));
    240  1.1  christos   if (end == optarg)
    241  1.1  christos     {
    242  1.1  christos       einfo ("%P%F: invalid hex number for PE parameter '%s'\n", optarg);
    243  1.1  christos     }
    244  1.1  christos 
    245  1.1  christos   optarg = end;
    246  1.1  christos }
    247  1.1  christos 
    248  1.1  christos static void
    249  1.1  christos set_pe_stack_heap (char *resname, char *comname)
    250  1.1  christos {
    251  1.1  christos   set_pe_value (resname);
    252  1.1  christos   if (*optarg == ',')
    253  1.1  christos     {
    254  1.1  christos       optarg++;
    255  1.1  christos       set_pe_value (comname);
    256  1.1  christos     }
    257  1.1  christos   else if (*optarg)
    258  1.1  christos     {
    259  1.1  christos       einfo ("%P%F: strange hex info for PE parameter '%s'\n", optarg);
    260  1.1  christos     }
    261  1.1  christos }
    262  1.1  christos 
    263  1.1  christos 
    264  1.1  christos static bfd_boolean
    265  1.1  christos gld${EMULATION_NAME}_handle_option (int optc)
    266  1.1  christos {
    267  1.1  christos   switch (optc)
    268  1.1  christos     {
    269  1.1  christos     default:
    270  1.1  christos       return FALSE;
    271  1.1  christos 
    272  1.1  christos     case OPTION_BASE_FILE:
    273  1.1  christos       link_info.base_file = fopen (optarg, FOPEN_WB);
    274  1.1  christos       if (link_info.base_file == NULL)
    275  1.1  christos 	einfo (_("%F%P: cannot open base file %s\n"), optarg);
    276  1.1  christos       break;
    277  1.1  christos 
    278  1.1  christos       /* PE options */
    279  1.1  christos     case OPTION_HEAP:
    280  1.1  christos       set_pe_stack_heap ("__size_of_heap_reserve__", "__size_of_heap_commit__");
    281  1.1  christos       break;
    282  1.1  christos     case OPTION_STACK:
    283  1.1  christos       set_pe_stack_heap ("__size_of_stack_reserve__", "__size_of_stack_commit__");
    284  1.1  christos       break;
    285  1.1  christos     case OPTION_SUBSYSTEM:
    286  1.1  christos       set_pe_subsystem ();
    287  1.1  christos       break;
    288  1.1  christos     case OPTION_MAJOR_OS_VERSION:
    289  1.1  christos       set_pe_value ("__major_os_version__");
    290  1.1  christos       break;
    291  1.1  christos     case OPTION_MINOR_OS_VERSION:
    292  1.1  christos       set_pe_value ("__minor_os_version__");
    293  1.1  christos       break;
    294  1.1  christos     case OPTION_MAJOR_SUBSYSTEM_VERSION:
    295  1.1  christos       set_pe_value ("__major_subsystem_version__");
    296  1.1  christos       break;
    297  1.1  christos     case OPTION_MINOR_SUBSYSTEM_VERSION:
    298  1.1  christos       set_pe_value ("__minor_subsystem_version__");
    299  1.1  christos       break;
    300  1.1  christos     case OPTION_MAJOR_IMAGE_VERSION:
    301  1.1  christos       set_pe_value ("__major_image_version__");
    302  1.1  christos       break;
    303  1.1  christos     case OPTION_MINOR_IMAGE_VERSION:
    304  1.1  christos       set_pe_value ("__minor_image_version__");
    305  1.1  christos       break;
    306  1.1  christos     case OPTION_FILE_ALIGNMENT:
    307  1.1  christos       set_pe_value ("__file_alignment__");
    308  1.1  christos       break;
    309  1.1  christos     case OPTION_SECTION_ALIGNMENT:
    310  1.1  christos       set_pe_value ("__section_alignment__");
    311  1.1  christos       break;
    312  1.1  christos     case OPTION_DLL:
    313  1.1  christos       set_pe_name ("__dll__", 1);
    314  1.1  christos       break;
    315  1.1  christos     case OPTION_IMAGE_BASE:
    316  1.1  christos       set_pe_value ("__image_base__");
    317  1.1  christos       break;
    318  1.1  christos     }
    319  1.1  christos   return TRUE;
    320  1.1  christos }
    321  1.1  christos 
    323  1.1  christos /* Assign values to the special symbols before the linker script is
    324  1.1  christos    read.  */
    325  1.1  christos 
    326  1.1  christos static void
    327  1.1  christos gld_${EMULATION_NAME}_set_symbols (void)
    328  1.1  christos {
    329  1.1  christos   /* Run through and invent symbols for all the
    330  1.1  christos      names and insert the defaults. */
    331  1.1  christos   int j;
    332  1.1  christos 
    333  1.1  christos   if (!init[IMAGEBASEOFF].inited)
    334  1.1  christos     {
    335  1.1  christos       if (link_info.relocatable)
    336  1.1  christos 	init[IMAGEBASEOFF].value = 0;
    337  1.1  christos       else if (init[DLLOFF].value)
    338  1.1  christos 	init[IMAGEBASEOFF].value = BEOS_DLL_IMAGE_BASE;
    339  1.1  christos       else
    340  1.1  christos 	init[IMAGEBASEOFF].value = BEOS_EXE_IMAGE_BASE;
    341  1.1  christos     }
    342  1.1  christos 
    343  1.1  christos   /* Don't do any symbol assignments if this is a relocatable link.  */
    344  1.1  christos   if (link_info.relocatable)
    345  1.1  christos     return;
    346  1.1  christos 
    347  1.1  christos   /* Glue the assignments into the abs section */
    348  1.1  christos   push_stat_ptr (&abs_output_section->children);
    349  1.1  christos 
    350  1.1  christos   for (j = 0; init[j].ptr; j++)
    351  1.1  christos     {
    352  1.1  christos       long val = init[j].value;
    353  1.1  christos       lang_add_assignment (exp_assign (init[j].symbol, exp_intop (val),
    354  1.1  christos 				       FALSE));
    355  1.1  christos       if (init[j].size == sizeof(short))
    356  1.1  christos 	*(short *)init[j].ptr = val;
    357  1.1  christos       else if (init[j].size == sizeof(int))
    358  1.1  christos 	*(int *)init[j].ptr = val;
    359  1.1  christos       else if (init[j].size == sizeof(long))
    360  1.1  christos 	*(long *)init[j].ptr = val;
    361  1.1  christos       /* This might be a long long or other special type.  */
    362  1.1  christos       else if (init[j].size == sizeof(bfd_vma))
    363  1.1  christos 	*(bfd_vma *)init[j].ptr = val;
    364  1.1  christos       else	abort();
    365  1.1  christos     }
    366  1.1  christos   /* Restore the pointer. */
    367  1.1  christos   pop_stat_ptr ();
    368  1.1  christos 
    369  1.1  christos   if (pe.FileAlignment >
    370  1.1  christos       pe.SectionAlignment)
    371  1.1  christos     {
    372  1.1  christos       einfo ("%P: warning, file alignment > section alignment.\n");
    373  1.1  christos     }
    374  1.1  christos }
    375  1.1  christos 
    376  1.1  christos static void
    377  1.1  christos gld_${EMULATION_NAME}_after_open (void)
    378  1.1  christos {
    379  1.1  christos   after_open_default ();
    380  1.1  christos 
    381  1.1  christos   /* Pass the wacky PE command line options into the output bfd.
    382  1.1  christos      FIXME: This should be done via a function, rather than by
    383  1.1  christos      including an internal BFD header.  */
    384  1.1  christos   if (!coff_data(link_info.output_bfd)->pe)
    385  1.1  christos     {
    386  1.1  christos       einfo ("%F%P: PE operations on non PE file.\n");
    387  1.1  christos     }
    388  1.1  christos 
    389  1.1  christos   pe_data(link_info.output_bfd)->pe_opthdr = pe;
    390  1.1  christos   pe_data(link_info.output_bfd)->dll = init[DLLOFF].value;
    391  1.1  christos 
    392  1.1  christos }
    393  1.1  christos 
    395  1.1  christos /* Callback functions for qsort in sort_sections. */
    396  1.1  christos 
    397  1.1  christos static int
    398  1.1  christos sort_by_file_name (const void *a, const void *b)
    399  1.1  christos {
    400  1.1  christos   const lang_statement_union_type *const *ra = a;
    401  1.1  christos   const lang_statement_union_type *const *rb = b;
    402  1.1  christos   int i, a_sec, b_sec;
    403  1.1  christos 
    404  1.1  christos   i = filename_cmp ((*ra)->input_section.section->owner->my_archive->filename,
    405  1.1  christos 		    (*rb)->input_section.section->owner->my_archive->filename);
    406  1.1  christos   if (i != 0)
    407  1.1  christos     return i;
    408  1.1  christos 
    409  1.1  christos   i = filename_cmp ((*ra)->input_section.section->owner->filename,
    410  1.1  christos 		    (*rb)->input_section.section->owner->filename);
    411  1.1  christos   if (i != 0)
    412  1.1  christos     return i;
    413  1.1  christos   /* the tail idata4/5 are the only ones without relocs to an
    414  1.1  christos      idata$6 section unless we are importing by ordinal,
    415  1.1  christos      so sort them to last to terminate the IAT
    416  1.1  christos      and HNT properly. if no reloc this one is import by ordinal
    417  1.1  christos      so we have to sort by section contents */
    418  1.1  christos 
    419  1.1  christos   if ( ((*ra)->input_section.section->reloc_count + (*rb)->input_section.section->reloc_count) )
    420  1.1  christos     {
    421  1.1  christos        i =  (((*ra)->input_section.section->reloc_count >
    422  1.1  christos 		 (*rb)->input_section.section->reloc_count) ? -1 : 0);
    423  1.1  christos        if ( i != 0)
    424  1.1  christos          return i;
    425  1.1  christos 
    426  1.1  christos         return  (((*ra)->input_section.section->reloc_count >
    427  1.1  christos 		 (*rb)->input_section.section->reloc_count) ? 0 : 1);
    428  1.1  christos     }
    429  1.1  christos   else
    430  1.1  christos     {
    431  1.1  christos        if ( (strcmp( (*ra)->input_section.section->name, ".idata$6") == 0) )
    432  1.1  christos           return 0; /* don't sort .idata$6 or .idata$7 FIXME dlltool eliminate .idata$7 */
    433  1.1  christos 
    434  1.1  christos        if (! bfd_get_section_contents ((*ra)->input_section.section->owner,
    435  1.1  christos          (*ra)->input_section.section, &a_sec, (file_ptr) 0, (bfd_size_type)sizeof(a_sec)))
    436  1.1  christos             einfo ("%F%B: Can't read contents of section .idata: %E\n",
    437  1.1  christos                  (*ra)->input_section.section->owner);
    438  1.1  christos 
    439  1.1  christos        if (! bfd_get_section_contents ((*rb)->input_section.section->owner,
    440  1.1  christos         (*rb)->input_section.section, &b_sec, (file_ptr) 0, (bfd_size_type)sizeof(b_sec) ))
    441  1.1  christos            einfo ("%F%B: Can't read contents of section .idata: %E\n",
    442  1.1  christos                 (*rb)->input_section.section->owner);
    443  1.1  christos 
    444  1.1  christos       i =  ((a_sec < b_sec) ? -1 : 0);
    445  1.1  christos       if ( i != 0)
    446  1.1  christos         return i;
    447  1.1  christos       return  ((a_sec < b_sec) ? 0 : 1);
    448  1.1  christos    }
    449  1.1  christos return 0;
    450  1.1  christos }
    451  1.1  christos 
    452  1.1  christos static int
    453  1.1  christos sort_by_section_name (const void *a, const void *b)
    454  1.1  christos {
    455  1.1  christos   const lang_statement_union_type *const *ra = a;
    456  1.1  christos   const lang_statement_union_type *const *rb = b;
    457  1.1  christos   int i;
    458  1.1  christos   i = strcmp ((*ra)->input_section.section->name,
    459  1.1  christos 	      (*rb)->input_section.section->name);
    460  1.1  christos   /* This is a hack to make .stab and .stabstr last, so we don't have
    461  1.1  christos      to fix strip/objcopy for .reloc sections.
    462  1.1  christos      FIXME stripping images with a .rsrc section still needs to be fixed.  */
    463  1.1  christos   if (i != 0)
    464  1.1  christos     {
    465  1.1  christos       if ((CONST_STRNEQ ((*ra)->input_section.section->name, ".stab"))
    466  1.1  christos            && (! CONST_STRNEQ ((*rb)->input_section.section->name, ".stab")))
    467  1.1  christos          return 1;
    468  1.1  christos     }
    469  1.1  christos   return i;
    470  1.1  christos }
    471  1.1  christos 
    472  1.1  christos /* Subroutine of sort_sections to a contiguous subset of a list of sections.
    473  1.1  christos    NEXT_AFTER is the element after the last one to sort.
    474  1.1  christos    The result is a pointer to the last element's "next" pointer.  */
    475  1.1  christos 
    476  1.1  christos static lang_statement_union_type **
    477  1.1  christos sort_sections_1 (lang_statement_union_type **startptr,
    478  1.1  christos 		 lang_statement_union_type *next_after,
    479  1.1  christos 		 int count,
    480  1.1  christos 		 int (*sort_func) (const void *, const void *))
    481  1.1  christos {
    482  1.1  christos   lang_statement_union_type **vec;
    483  1.1  christos   lang_statement_union_type *p;
    484  1.1  christos   int i;
    485  1.1  christos   lang_statement_union_type **ret;
    486  1.1  christos 
    487  1.1  christos   if (count == 0)
    488  1.1  christos     return startptr;
    489  1.1  christos 
    490  1.1  christos   vec = ((lang_statement_union_type **)
    491  1.1  christos 	 xmalloc (count * sizeof (lang_statement_union_type *)));
    492  1.1  christos 
    493  1.1  christos   for (p = *startptr, i = 0; i < count; i++, p = p->header.next)
    494  1.1  christos     vec[i] = p;
    495  1.1  christos 
    496  1.1  christos   qsort (vec, count, sizeof (vec[0]), sort_func);
    497  1.1  christos 
    498  1.1  christos   /* Fill in the next pointers again. */
    499  1.1  christos   *startptr = vec[0];
    500  1.1  christos   for (i = 0; i < count - 1; i++)
    501  1.1  christos     vec[i]->header.next = vec[i + 1];
    502  1.1  christos   vec[i]->header.next = next_after;
    503  1.1  christos   ret = &vec[i]->header.next;
    504  1.1  christos   free (vec);
    505  1.1  christos   return ret;
    506  1.1  christos }
    507  1.1  christos 
    508  1.1  christos /* Sort the .idata\$foo input sections of archives into filename order.
    509  1.1  christos    The reason is so dlltool can arrange to have the pe dll import information
    510  1.1  christos    generated correctly - the head of the list goes into dh.o, the tail into
    511  1.1  christos    dt.o, and the guts into ds[nnnn].o.  Note that this is only needed for the
    512  1.1  christos    .idata section.
    513  1.1  christos    FIXME: This may no longer be necessary with grouped sections.  Instead of
    514  1.1  christos    sorting on dh.o, ds[nnnn].o, dt.o, one could, for example, have dh.o use
    515  1.1  christos    .idata\$4h, have ds[nnnn].o use .idata\$4s[nnnn], and have dt.o use .idata\$4t.
    516  1.1  christos    This would have to be elaborated upon to handle multiple dll's
    517  1.1  christos    [assuming such an eloboration is possible of course].
    518  1.1  christos 
    519  1.1  christos    We also sort sections in '\$' wild statements.  These are created by the
    520  1.1  christos    place_orphans routine to implement grouped sections.  */
    521  1.1  christos 
    522  1.1  christos static void
    523  1.1  christos sort_sections (lang_statement_union_type *s)
    524  1.1  christos {
    525  1.1  christos   for (; s ; s = s->header.next)
    526  1.1  christos     switch (s->header.type)
    527  1.1  christos       {
    528  1.1  christos       case lang_output_section_statement_enum:
    529  1.1  christos 	sort_sections (s->output_section_statement.children.head);
    530  1.1  christos 	break;
    531  1.1  christos       case lang_wild_statement_enum:
    532  1.1  christos 	{
    533  1.1  christos 	  lang_statement_union_type **p = &s->wild_statement.children.head;
    534  1.1  christos 	  struct wildcard_list *sec;
    535  1.1  christos 
    536  1.1  christos 	  for (sec = s->wild_statement.section_list; sec; sec = sec->next)
    537  1.1  christos 	    {
    538  1.1  christos 	      /* Is this the .idata section?  */
    539  1.1  christos 	      if (sec->spec.name != NULL
    540  1.1  christos 		  && CONST_STRNEQ (sec->spec.name, ".idata"))
    541  1.1  christos 		{
    542  1.1  christos 		  /* Sort the children.  We want to sort any objects in
    543  1.1  christos 		     the same archive.  In order to handle the case of
    544  1.1  christos 		     including a single archive multiple times, we sort
    545  1.1  christos 		     all the children by archive name and then by object
    546  1.1  christos 		     name.  After sorting them, we re-thread the pointer
    547  1.1  christos 		     chain.  */
    548  1.1  christos 
    549  1.1  christos 		  while (*p)
    550  1.1  christos 		    {
    551  1.1  christos 		      lang_statement_union_type *start = *p;
    552  1.1  christos 		      if (start->header.type != lang_input_section_enum
    553  1.1  christos 			  || !start->input_section.section->owner->my_archive)
    554  1.1  christos 			p = &(start->header.next);
    555  1.1  christos 		      else
    556  1.1  christos 			{
    557  1.1  christos 			  lang_statement_union_type *end;
    558  1.1  christos 			  int count;
    559  1.1  christos 
    560  1.1  christos 			  for (end = start, count = 0;
    561  1.1  christos 			       end && (end->header.type
    562  1.1  christos 				       == lang_input_section_enum);
    563  1.1  christos 			       end = end->header.next)
    564  1.1  christos 			    count++;
    565  1.1  christos 
    566  1.1  christos 			  p = sort_sections_1 (p, end, count,
    567  1.1  christos 					       sort_by_file_name);
    568  1.1  christos 			}
    569  1.1  christos 		    }
    570  1.1  christos 		  break;
    571  1.1  christos 		}
    572  1.1  christos 
    573  1.1  christos 	      /* If this is a collection of grouped sections, sort them.
    574  1.1  christos 		 The linker script must explicitly mention "*(.foo\$)" or
    575  1.1  christos 		 "*(.foo\$*)".  Don't sort them if \$ is not the last
    576  1.1  christos 		 character (not sure if this is really useful, but it
    577  1.1  christos 		 allows explicitly mentioning some \$ sections and letting
    578  1.1  christos 		 the linker handle the rest).  */
    579  1.1  christos 	      if (sec->spec.name != NULL)
    580  1.1  christos 		{
    581  1.1  christos 		  char *q = strchr (sec->spec.name, '\$');
    582  1.1  christos 
    583  1.1  christos 		  if (q != NULL
    584  1.1  christos 		      && (q[1] == '\0'
    585  1.1  christos 			  || (q[1] == '*' && q[2] == '\0')))
    586  1.1  christos 		    {
    587  1.1  christos 		      lang_statement_union_type *end;
    588  1.1  christos 		      int count;
    589  1.1  christos 
    590  1.1  christos 		      for (end = *p, count = 0; end; end = end->header.next)
    591  1.1  christos 			{
    592  1.1  christos 			  if (end->header.type != lang_input_section_enum)
    593  1.1  christos 			    abort ();
    594  1.1  christos 			  count++;
    595  1.1  christos 			}
    596  1.1  christos 		      (void) sort_sections_1 (p, end, count,
    597  1.1  christos 					      sort_by_section_name);
    598  1.1  christos 		    }
    599  1.1  christos 		  break;
    600  1.1  christos 		}
    601  1.1  christos 	    }
    602  1.1  christos 	}
    603  1.1  christos 	break;
    604  1.1  christos       default:
    605  1.1  christos 	break;
    606  1.1  christos       }
    607  1.1  christos }
    608  1.1  christos 
    609  1.1  christos static void
    610  1.1  christos gld_${EMULATION_NAME}_before_allocation (void)
    611  1.1  christos {
    612  1.1  christos #ifdef TARGET_IS_ppcpe
    613  1.1  christos   /* Here we rummage through the found bfds to collect toc information */
    614  1.1  christos   {
    615  1.1  christos     LANG_FOR_EACH_INPUT_STATEMENT (is)
    616  1.1  christos       {
    617  1.1  christos 	if (!ppc_process_before_allocation(is->the_bfd, &link_info))
    618  1.1  christos 	  {
    619  1.1  christos 	    einfo("Errors encountered processing file %s\n", is->filename);
    620  1.1  christos 	  }
    621  1.1  christos       }
    622  1.1  christos   }
    623  1.1  christos 
    624  1.1  christos   /* We have seen it all. Allocate it, and carry on */
    625  1.1  christos   ppc_allocate_toc_section (&link_info);
    626  1.1  christos #else
    627  1.1  christos #ifdef TARGET_IS_armpe
    628  1.1  christos   /* FIXME: we should be able to set the size of the interworking stub
    629  1.1  christos      section.
    630  1.1  christos 
    631  1.1  christos      Here we rummage through the found bfds to collect glue
    632  1.1  christos      information.  FIXME: should this be based on a command line
    633  1.1  christos      option?  krk (a] cygnus.com */
    634  1.1  christos   {
    635  1.1  christos     LANG_FOR_EACH_INPUT_STATEMENT (is)
    636  1.1  christos       {
    637  1.1  christos 	if (!arm_process_before_allocation (is->the_bfd, & link_info))
    638  1.1  christos 	  {
    639  1.1  christos 	    einfo ("Errors encountered processing file %s", is->filename);
    640  1.1  christos 	  }
    641  1.1  christos       }
    642  1.1  christos   }
    643  1.1  christos 
    644  1.1  christos   /* We have seen it all. Allocate it, and carry on */
    645  1.1  christos   arm_allocate_interworking_sections (& link_info);
    646  1.1  christos #endif /* TARGET_IS_armpe */
    647  1.1  christos #endif /* TARGET_IS_ppcpe */
    648  1.1  christos 
    649  1.1  christos   sort_sections (stat_ptr->head);
    650  1.1  christos 
    651  1.1  christos   before_allocation_default ();
    652  1.1  christos }
    653  1.1  christos 
    655  1.1  christos /* Place an orphan section.  We use this to put sections with a '\$' in them
    656  1.1  christos    into the right place.  Any section with a '\$' in them (e.g. .text\$foo)
    657  1.1  christos    gets mapped to the output section with everything from the '\$' on stripped
    658  1.1  christos    (e.g. .text).
    659  1.1  christos    See the Microsoft Portable Executable and Common Object File Format
    660  1.1  christos    Specification 4.1, section 4.2, Grouped Sections.
    661  1.1  christos 
    662  1.1  christos    FIXME: This is now handled by the linker script using wildcards,
    663  1.1  christos    but I'm leaving this here in case we want to enable it for sections
    664  1.1  christos    which are not mentioned in the linker script.  */
    665  1.1  christos 
    666  1.1  christos static lang_output_section_statement_type *
    667  1.1  christos gld${EMULATION_NAME}_place_orphan (asection *s,
    668  1.1  christos 				   const char *secname,
    669  1.1  christos 				   int constraint)
    670  1.1  christos {
    671  1.1  christos   char *output_secname, *ps;
    672  1.1  christos   lang_output_section_statement_type *os;
    673  1.1  christos   lang_statement_union_type *l;
    674  1.1  christos 
    675  1.1  christos   if ((s->flags & SEC_ALLOC) == 0)
    676  1.1  christos     return NULL;
    677  1.1  christos 
    678  1.1  christos   /* Don't process grouped sections unless doing a final link.
    679  1.1  christos      If they're marked as COMDAT sections, we don't want .text\$foo to
    680  1.1  christos      end up in .text and then have .text disappear because it's marked
    681  1.1  christos      link-once-discard.  */
    682  1.1  christos   if (link_info.relocatable)
    683  1.1  christos     return NULL;
    684  1.1  christos 
    685  1.1  christos   /* Everything from the '\$' on gets deleted so don't allow '\$' as the
    686  1.1  christos      first character.  */
    687  1.1  christos   if (*secname == '\$')
    688  1.1  christos     einfo ("%P%F: section %s has '\$' as first character\n", secname);
    689  1.1  christos   if (strchr (secname + 1, '\$') == NULL)
    690  1.1  christos     return NULL;
    691  1.1  christos 
    692  1.1  christos   /* Look up the output section.  The Microsoft specs say sections names in
    693  1.1  christos      image files never contain a '\$'.  Fortunately, lang_..._lookup creates
    694  1.1  christos      the section if it doesn't exist.  */
    695  1.1  christos   output_secname = xstrdup (secname);
    696  1.1  christos   ps = strchr (output_secname + 1, '\$');
    697  1.1  christos   *ps = 0;
    698  1.1  christos   os = lang_output_section_statement_lookup (output_secname, constraint, TRUE);
    699  1.1  christos 
    700  1.1  christos   /* Find the '\$' wild statement for this section.  We currently require the
    701  1.1  christos      linker script to explicitly mention "*(.foo\$)".
    702  1.1  christos      FIXME: ppcpe.sc has .CRT\$foo in the .rdata section.  According to the
    703  1.1  christos      Microsoft docs this isn't correct so it's not (currently) handled.  */
    704  1.1  christos 
    705  1.1  christos   ps[0] = '\$';
    706  1.1  christos   ps[1] = 0;
    707  1.1  christos   for (l = os->children.head; l; l = l->header.next)
    708  1.1  christos     if (l->header.type == lang_wild_statement_enum)
    709  1.1  christos       {
    710  1.1  christos 	struct wildcard_list *sec;
    711  1.1  christos 
    712  1.1  christos 	for (sec = l->wild_statement.section_list; sec; sec = sec->next)
    713  1.1  christos 	  if (sec->spec.name && strcmp (sec->spec.name, output_secname) == 0)
    714  1.1  christos 	    break;
    715  1.1  christos 	if (sec)
    716  1.1  christos 	  break;
    717  1.1  christos       }
    718  1.1  christos   ps[0] = 0;
    719  1.1  christos   if (l == NULL)
    720  1.1  christos     einfo ("%P%F: *(%s\$) missing from linker script\n", output_secname);
    721  1.1  christos 
    722  1.1  christos   /* Link the input section in and we're done for now.
    723  1.1  christos      The sections still have to be sorted, but that has to wait until
    724  1.1  christos      all such sections have been processed by us.  The sorting is done by
    725  1.1  christos      sort_sections.  */
    726  1.1  christos   lang_add_section (&l->wild_statement.children, s, NULL, os);
    727  1.1  christos 
    728  1.1  christos   return os;
    729  1.1  christos }
    730  1.1  christos 
    732  1.1  christos static char *
    733  1.1  christos gld_${EMULATION_NAME}_get_script (int *isfile)
    734  1.1  christos EOF
    735  1.1  christos # Scripts compiled in.
    736  1.1  christos # sed commands to quote an ld script as a C string.
    737  1.1  christos sc="-f stringify.sed"
    738  1.1  christos 
    739  1.1  christos fragment <<EOF
    740  1.1  christos {
    741  1.1  christos   *isfile = 0;
    742  1.1  christos 
    743  1.1  christos   if (link_info.relocatable && config.build_constructors)
    744  1.1  christos     return
    745  1.1  christos EOF
    746  1.1  christos sed $sc ldscripts/${EMULATION_NAME}.xu                 >> e${EMULATION_NAME}.c
    747  1.1  christos echo '  ; else if (link_info.relocatable) return'     >> e${EMULATION_NAME}.c
    748  1.1  christos sed $sc ldscripts/${EMULATION_NAME}.xr                 >> e${EMULATION_NAME}.c
    749  1.1  christos echo '  ; else if (!config.text_read_only) return'     >> e${EMULATION_NAME}.c
    750  1.1  christos sed $sc ldscripts/${EMULATION_NAME}.xbn                >> e${EMULATION_NAME}.c
    751  1.1  christos echo '  ; else if (!config.magic_demand_paged) return' >> e${EMULATION_NAME}.c
    752  1.1  christos sed $sc ldscripts/${EMULATION_NAME}.xn                 >> e${EMULATION_NAME}.c
    753  1.1  christos echo '  ; else return'                                 >> e${EMULATION_NAME}.c
    754  1.1  christos sed $sc ldscripts/${EMULATION_NAME}.x                  >> e${EMULATION_NAME}.c
    755  1.1  christos echo '; }'                                             >> e${EMULATION_NAME}.c
    756  1.1  christos 
    757  1.1  christos fragment <<EOF
    758  1.1  christos 
    759  1.1  christos 
    760  1.1  christos struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
    761  1.1  christos {
    762  1.1  christos   gld_${EMULATION_NAME}_before_parse,
    763  1.1  christos   syslib_default,
    764  1.1  christos   hll_default,
    765  1.1  christos   after_parse_default,
    766  1.1  christos   gld_${EMULATION_NAME}_after_open,
    767  1.1  christos   after_allocation_default,
    768  1.1  christos   set_output_arch_default,
    769  1.1  christos   ldemul_default_target,
    770  1.1  christos   gld_${EMULATION_NAME}_before_allocation,
    771  1.1  christos   gld_${EMULATION_NAME}_get_script,
    772  1.1  christos   "${EMULATION_NAME}",
    773  1.1  christos   "${OUTPUT_FORMAT}",
    774  1.1  christos   finish_default,
    775  1.1  christos   NULL, /* create output section statements */
    776  1.1  christos   NULL, /* open dynamic archive */
    777  1.1  christos   gld${EMULATION_NAME}_place_orphan,
    778  1.1  christos   gld_${EMULATION_NAME}_set_symbols,
    779  1.1  christos   NULL, /* parse_args */
    780  1.1  christos   gld${EMULATION_NAME}_add_options,
    781  1.1  christos   gld${EMULATION_NAME}_handle_option,
    782  1.1  christos   NULL,	/* unrecognized file */
    783  1.1  christos   NULL,	/* list options */
    784                  NULL,	/* recognized file */
    785                  NULL,	/* find_potential_libraries */
    786                  NULL	/* new_vers_pattern */
    787                };
    788                EOF
    789