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