OpenCores
URL https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [ld/] [emultempl/] [sunos.em] - Blame information for rev 178

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 145 khays
# This shell script emits a C file. -*- C -*-
2
# It does some substitutions.
3
if [ -z "$MACHINE" ]; then
4
  OUTPUT_ARCH=${ARCH}
5
else
6
  OUTPUT_ARCH=${ARCH}:${MACHINE}
7
fi
8
fragment <
9
/* This file is is generated by a shell script.  DO NOT EDIT! */
10
 
11
/* SunOS emulation code for ${EMULATION_NAME}
12
   Copyright 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
13
   2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
14
   Written by Steve Chamberlain 
15
   SunOS shared library support by Ian Lance Taylor 
16
 
17
   This file is part of the GNU Binutils.
18
 
19
   This program is free software; you can redistribute it and/or modify
20
   it under the terms of the GNU General Public License as published by
21
   the Free Software Foundation; either version 3 of the License, or
22
   (at your option) any later version.
23
 
24
   This program is distributed in the hope that it will be useful,
25
   but WITHOUT ANY WARRANTY; without even the implied warranty of
26
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
27
   GNU General Public License for more details.
28
 
29
   You should have received a copy of the GNU General Public License
30
   along with this program; if not, write to the Free Software
31
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
32
   MA 02110-1301, USA.  */
33
 
34
#define TARGET_IS_${EMULATION_NAME}
35
 
36
#include "sysdep.h"
37
#include "bfd.h"
38
#include "bfdlink.h"
39
#include "libiberty.h"
40
#include "safe-ctype.h"
41
 
42
#include "ld.h"
43
#include "ldmain.h"
44
#include "ldmisc.h"
45
#include "ldexp.h"
46
#include "ldlang.h"
47
#include "ldfile.h"
48
#include "ldemul.h"
49
 
50
#ifdef HAVE_DIRENT_H
51
# include 
52
#else
53
# define dirent direct
54
# ifdef HAVE_SYS_NDIR_H
55
#  include 
56
# endif
57
# ifdef HAVE_SYS_DIR_H
58
#  include 
59
# endif
60
# ifdef HAVE_NDIR_H
61
#  include 
62
# endif
63
#endif
64
 
65
static void gld${EMULATION_NAME}_find_so
66
  (lang_input_statement_type *);
67
static char *gld${EMULATION_NAME}_search_dir
68
  (const char *, const char *, bfd_boolean *);
69
static void gld${EMULATION_NAME}_check_needed
70
  (lang_input_statement_type *);
71
static bfd_boolean gld${EMULATION_NAME}_search_needed
72
  (const char *, const char *);
73
static bfd_boolean gld${EMULATION_NAME}_try_needed
74
  (const char *, const char *);
75
static void gld${EMULATION_NAME}_find_assignment
76
  (lang_statement_union_type *);
77
static void gld${EMULATION_NAME}_find_exp_assignment
78
  (etree_type *);
79
static void gld${EMULATION_NAME}_count_need
80
  (lang_input_statement_type *);
81
static void gld${EMULATION_NAME}_set_need
82
  (lang_input_statement_type *);
83
 
84
static void
85
gld${EMULATION_NAME}_before_parse (void)
86
{
87
  ldfile_set_output_arch ("${OUTPUT_ARCH}", bfd_arch_`echo ${ARCH} | sed -e 's/:.*//'`);
88
  config.dynamic_link = TRUE;
89
  config.has_shared = TRUE;
90
}
91
 
92
/* This is called after the command line arguments have been parsed,
93
   but before the linker script has been read.  If this is a native
94
   linker, we add the directories in LD_LIBRARY_PATH to the search
95
   list.  */
96
 
97
static void
98
gld${EMULATION_NAME}_set_symbols (void)
99
{
100
EOF
101
if [ "x${host}" = "x${target}" ] ; then
102
  case " ${EMULATION_LIBPATH} " in
103
  *" ${EMULATION_NAME} "*)
104
fragment <
105
  const char *env;
106
 
107
  env = (const char *) getenv ("LD_LIBRARY_PATH");
108
  if (env != NULL)
109
    {
110
      char *l;
111
 
112
      l = xstrdup (env);
113
      while (1)
114
        {
115
          char *c;
116
 
117
          c = strchr (l, ':');
118
          if (c != NULL)
119
            *c++ = '\0';
120
          if (*l != '\0')
121
            ldfile_add_library_path (l, FALSE);
122
          if (c == NULL)
123
            break;
124
          l = c;
125
        }
126
    }
127
EOF
128
  ;;
129
  esac
130
fi
131
fragment <
132
}
133
 
134
/* Despite the name, we use this routine to search for dynamic
135
   libraries.  On SunOS this requires a directory search.  We need to
136
   find the .so file with the highest version number.  The user may
137
   restrict the major version by saying, e.g., -lc.1.  Also, if we
138
   find a .so file, we need to look for a the same file after
139
   replacing .so with .sa; if it exists, it will be an archive which
140
   provide some initializations for data symbols, and we need to
141
   search it after including the .so file.  */
142
 
143
static void
144
gld${EMULATION_NAME}_create_output_section_statements (void)
145
{
146
  lang_for_each_input_file (gld${EMULATION_NAME}_find_so);
147
}
148
 
149
/* Search the directory for a .so file for each library search.  */
150
 
151
static void
152
gld${EMULATION_NAME}_find_so (lang_input_statement_type *inp)
153
{
154
  search_dirs_type *search;
155
  char *found = NULL;
156
  char *alc;
157
  struct stat st;
158
 
159
  if (! inp->search_dirs_flag
160
      || ! inp->maybe_archive
161
      || ! inp->dynamic)
162
    return;
163
 
164
  ASSERT (CONST_STRNEQ (inp->local_sym_name, "-l"));
165
 
166
  for (search = search_head; search != NULL; search = search->next)
167
    {
168
      bfd_boolean found_static;
169
 
170
      found = gld${EMULATION_NAME}_search_dir (search->name, inp->filename,
171
                                               &found_static);
172
      if (found != NULL || found_static)
173
        break;
174
    }
175
 
176
  if (found == NULL)
177
    {
178
      /* We did not find a matching .so file.  This isn't an error,
179
         since there might still be a matching .a file, which will be
180
         found by the usual search.  */
181
      return;
182
    }
183
 
184
  /* Replace the filename with the one we have found.  */
185
  alc = (char *) xmalloc (strlen (search->name) + strlen (found) + 2);
186
  sprintf (alc, "%s/%s", search->name, found);
187
  inp->filename = alc;
188
 
189
  /* Turn off the search_dirs_flag to prevent ldfile_open_file from
190
     searching for this file again.  */
191
  inp->search_dirs_flag = FALSE;
192
 
193
  free (found);
194
 
195
  /* Now look for the same file name, but with .sa instead of .so.  If
196
     found, add it to the list of input files.  */
197
  alc = (char *) xmalloc (strlen (inp->filename) + 1);
198
  strcpy (alc, inp->filename);
199
  strstr (alc + strlen (search->name), ".so")[2] = 'a';
200
  if (stat (alc, &st) != 0)
201
    free (alc);
202
  else
203
    {
204
      lang_input_statement_type *sa;
205
 
206
      /* Add the .sa file to the statement list just before the .so
207
         file.  This is really a hack.  */
208
      sa = ((lang_input_statement_type *)
209
            xmalloc (sizeof (lang_input_statement_type)));
210
      *sa = *inp;
211
 
212
      inp->filename = alc;
213
      inp->local_sym_name = alc;
214
 
215
      inp->header.next = (lang_statement_union_type *) sa;
216
      inp->next_real_file = (lang_statement_union_type *) sa;
217
    }
218
}
219
 
220
/* Search a directory for a .so file.  */
221
 
222
static char *
223
gld${EMULATION_NAME}_search_dir
224
  (const char *dirname, const char *filename, bfd_boolean *found_static)
225
{
226
  int force_maj, force_min;
227
  const char *dot;
228
  unsigned int len;
229
  char *alc;
230
  char *found;
231
  int max_maj, max_min;
232
  DIR *dir;
233
  struct dirent *entry;
234
  unsigned int dirnamelen;
235
  char *full_path;
236
  int statval;
237
  struct stat st;
238
 
239
  *found_static = FALSE;
240
 
241
  force_maj = -1;
242
  force_min = -1;
243
  dot = strchr (filename, '.');
244
  if (dot == NULL)
245
    {
246
      len = strlen (filename);
247
      alc = NULL;
248
    }
249
  else
250
    {
251
      force_maj = atoi (dot + 1);
252
 
253
      len = dot - filename;
254
      alc = (char *) xmalloc (len + 1);
255
      strncpy (alc, filename, len);
256
      alc[len] = '\0';
257
      filename = alc;
258
 
259
      dot = strchr (dot + 1, '.');
260
      if (dot != NULL)
261
        force_min = atoi (dot + 1);
262
    }
263
 
264
  found = NULL;
265
  max_maj = max_min = 0;
266
 
267
  dir = opendir (dirname);
268
  if (dir == NULL)
269
    return NULL;
270
  dirnamelen = strlen (dirname);
271
 
272
  while ((entry = readdir (dir)) != NULL)
273
    {
274
      const char *s;
275
      int found_maj, found_min;
276
 
277
      if (! CONST_STRNEQ (entry->d_name, "lib")
278
          || strncmp (entry->d_name + 3, filename, len) != 0)
279
        continue;
280
 
281
      if (dot == NULL
282
          && strcmp (entry->d_name + 3 + len, ".a") == 0)
283
        {
284
          *found_static = TRUE;
285
          continue;
286
        }
287
 
288
      /* We accept libfoo.so without a version number, even though the
289
         native linker does not.  This is more convenient for packages
290
         which just generate .so files for shared libraries, as on ELF
291
         systems.  */
292
      if (! CONST_STRNEQ (entry->d_name + 3 + len, ".so"))
293
        continue;
294
      if (entry->d_name[6 + len] == '\0')
295
        ;
296
      else if (entry->d_name[6 + len] == '.'
297
               && ISDIGIT (entry->d_name[7 + len]))
298
        ;
299
      else
300
        continue;
301
 
302
      for (s = entry->d_name + 6 + len; *s != '\0'; s++)
303
        if (*s != '.' && ! ISDIGIT (*s))
304
          break;
305
      if (*s != '\0')
306
        continue;
307
 
308
      /* We've found a .so file.  Work out the major and minor
309
         version numbers.  */
310
      found_maj = 0;
311
      found_min = 0;
312
      sscanf (entry->d_name + 3 + len, ".so.%d.%d",
313
              &found_maj, &found_min);
314
 
315
      if ((force_maj != -1 && force_maj != found_maj)
316
          || (force_min != -1 && force_min != found_min))
317
        continue;
318
 
319
      /* Make sure the file really exists (ignore broken symlinks).  */
320
      full_path = xmalloc (dirnamelen + 1 + strlen (entry->d_name) + 1);
321
      sprintf (full_path, "%s/%s", dirname, entry->d_name);
322
      statval = stat (full_path, &st);
323
      free (full_path);
324
      if (statval != 0)
325
        continue;
326
 
327
      /* We've found a match for the name we are searching for.  See
328
         if this is the version we should use.  If the major and minor
329
         versions match, we use the last entry in alphabetical order;
330
         I don't know if this is how SunOS distinguishes libc.so.1.8
331
         from libc.so.1.8.1, but it ought to suffice.  */
332
      if (found == NULL
333
          || (found_maj > max_maj)
334
          || (found_maj == max_maj
335
              && (found_min > max_min
336
                  || (found_min == max_min
337
                      && strcmp (entry->d_name, found) > 0))))
338
        {
339
          if (found != NULL)
340
            free (found);
341
          found = (char *) xmalloc (strlen (entry->d_name) + 1);
342
          strcpy (found, entry->d_name);
343
          max_maj = found_maj;
344
          max_min = found_min;
345
        }
346
    }
347
 
348
  closedir (dir);
349
 
350
  if (alc != NULL)
351
    free (alc);
352
 
353
  return found;
354
}
355
 
356
/* These variables are required to pass information back and forth
357
   between after_open and check_needed.  */
358
 
359
static struct bfd_link_needed_list *global_needed;
360
static bfd_boolean global_found;
361
 
362
/* This is called after all the input files have been opened.  */
363
 
364
static void
365
gld${EMULATION_NAME}_after_open (void)
366
{
367
  struct bfd_link_needed_list *needed, *l;
368
 
369
  after_open_default ();
370
 
371
  /* We only need to worry about this when doing a final link.  */
372
  if (link_info.relocatable || link_info.shared)
373
    return;
374
 
375
  /* Get the list of files which appear in ld_need entries in dynamic
376
     objects included in the link.  For each such file, we want to
377
     track down the corresponding library, and include the symbol
378
     table in the link.  This is what the runtime dynamic linker will
379
     do.  Tracking the files down here permits one dynamic object to
380
     include another without requiring special action by the person
381
     doing the link.  Note that the needed list can actually grow
382
     while we are stepping through this loop.  */
383
  needed = bfd_sunos_get_needed_list (link_info.output_bfd, &link_info);
384
  for (l = needed; l != NULL; l = l->next)
385
    {
386
      struct bfd_link_needed_list *ll;
387
      const char *lname;
388
      search_dirs_type *search;
389
 
390
      lname = l->name;
391
 
392
      /* If we've already seen this file, skip it.  */
393
      for (ll = needed; ll != l; ll = ll->next)
394
        if (strcmp (ll->name, lname) == 0)
395
          break;
396
      if (ll != l)
397
        continue;
398
 
399
      /* See if this file was included in the link explicitly.  */
400
      global_needed = l;
401
      global_found = FALSE;
402
      lang_for_each_input_file (gld${EMULATION_NAME}_check_needed);
403
      if (global_found)
404
        continue;
405
 
406
      if (! CONST_STRNEQ (lname, "-l"))
407
        {
408
          bfd *abfd;
409
 
410
          abfd = bfd_openr (lname, bfd_get_target (link_info.output_bfd));
411
          if (abfd != NULL)
412
            {
413
              if (! bfd_check_format (abfd, bfd_object))
414
                {
415
                  (void) bfd_close (abfd);
416
                  abfd = NULL;
417
                }
418
            }
419
          if (abfd != NULL)
420
            {
421
              if ((bfd_get_file_flags (abfd) & DYNAMIC) == 0)
422
                {
423
                  (void) bfd_close (abfd);
424
                  abfd = NULL;
425
                }
426
            }
427
          if (abfd != NULL)
428
            {
429
              /* We've found the needed dynamic object.  */
430
              if (! bfd_link_add_symbols (abfd, &link_info))
431
                einfo ("%F%B: could not read symbols: %E\n", abfd);
432
            }
433
          else
434
            {
435
              einfo ("%P: warning: %s, needed by %B, not found\n",
436
                     lname, l->by);
437
            }
438
 
439
          continue;
440
        }
441
 
442
      lname += 2;
443
 
444
      /* We want to search for the file in the same way that the
445
         dynamic linker will search.  That means that we want to use
446
         rpath_link, rpath or -L, then the environment variable
447
         LD_LIBRARY_PATH (native only), then (if rpath was used) the
448
         linker script LIB_SEARCH_DIRS.  */
449
      if (gld${EMULATION_NAME}_search_needed (command_line.rpath_link,
450
                                              lname))
451
        continue;
452
      if (command_line.rpath != NULL)
453
        {
454
          if (gld${EMULATION_NAME}_search_needed (command_line.rpath, lname))
455
            continue;
456
        }
457
      else
458
        {
459
          for (search = search_head; search != NULL; search = search->next)
460
            if (gld${EMULATION_NAME}_try_needed (search->name, lname))
461
              break;
462
          if (search != NULL)
463
            continue;
464
        }
465
EOF
466
if [ "x${host}" = "x${target}" ] ; then
467
  case " ${EMULATION_LIBPATH} " in
468
  *" ${EMULATION_NAME} "*)
469
fragment <
470
      {
471
        const char *lib_path;
472
 
473
        lib_path = (const char *) getenv ("LD_LIBRARY_PATH");
474
        if (gld${EMULATION_NAME}_search_needed (lib_path, lname))
475
          continue;
476
      }
477
EOF
478
  ;;
479
  esac
480
fi
481
fragment <
482
      if (command_line.rpath != NULL)
483
        {
484
          for (search = search_head; search != NULL; search = search->next)
485
            {
486
              if (search->cmdline)
487
                continue;
488
              if (gld${EMULATION_NAME}_try_needed (search->name, lname))
489
                break;
490
            }
491
          if (search != NULL)
492
            continue;
493
        }
494
 
495
      einfo ("%P: warning: %s, needed by %B, not found\n",
496
             l->name, l->by);
497
    }
498
}
499
 
500
/* Search for a needed file in a path.  */
501
 
502
static bfd_boolean
503
gld${EMULATION_NAME}_search_needed (const char *path, const char *name)
504
{
505
  const char *s;
506
 
507
  if (path == NULL || *path == '\0')
508
    return FALSE;
509
  while (1)
510
    {
511
      const char *dir;
512
      char *dircopy;
513
 
514
      s = strchr (path, ':');
515
      if (s == NULL)
516
        {
517
          dircopy = NULL;
518
          dir = path;
519
        }
520
      else
521
        {
522
          dircopy = (char *) xmalloc (s - path + 1);
523
          memcpy (dircopy, path, s - path);
524
          dircopy[s - path] = '\0';
525
          dir = dircopy;
526
        }
527
 
528
      if (gld${EMULATION_NAME}_try_needed (dir, name))
529
        return TRUE;
530
 
531
      if (dircopy != NULL)
532
        free (dircopy);
533
 
534
      if (s == NULL)
535
        break;
536
      path = s + 1;
537
    }
538
 
539
  return FALSE;
540
}
541
 
542
/* This function is called for each possible directory for a needed
543
   dynamic object.  */
544
 
545
static bfd_boolean
546
gld${EMULATION_NAME}_try_needed (const char *dir, const char *name)
547
{
548
  char *file;
549
  char *alc;
550
  bfd_boolean ignore;
551
  bfd *abfd;
552
 
553
  file = gld${EMULATION_NAME}_search_dir (dir, name, &ignore);
554
  if (file == NULL)
555
    return FALSE;
556
 
557
  alc = (char *) xmalloc (strlen (dir) + strlen (file) + 2);
558
  sprintf (alc, "%s/%s", dir, file);
559
  free (file);
560
  abfd = bfd_openr (alc, bfd_get_target (link_info.output_bfd));
561
  if (abfd == NULL)
562
    return FALSE;
563
  if (! bfd_check_format (abfd, bfd_object))
564
    {
565
      (void) bfd_close (abfd);
566
      return FALSE;
567
    }
568
  if ((bfd_get_file_flags (abfd) & DYNAMIC) == 0)
569
    {
570
      (void) bfd_close (abfd);
571
      return FALSE;
572
    }
573
 
574
  /* We've found the needed dynamic object.  */
575
 
576
  /* Add this file into the symbol table.  */
577
  if (! bfd_link_add_symbols (abfd, &link_info))
578
    einfo ("%F%B: could not read symbols: %E\n", abfd);
579
 
580
  return TRUE;
581
}
582
 
583
/* See if we have already included a needed object in the link.  This
584
   does not have to be precise, as it does no harm to include a
585
   dynamic object more than once.  */
586
 
587
static void
588
gld${EMULATION_NAME}_check_needed (lang_input_statement_type *s)
589
{
590
  if (s->filename == NULL)
591
    return;
592
  if (! CONST_STRNEQ (global_needed->name, "-l"))
593
    {
594
      if (strcmp (s->filename, global_needed->name) == 0)
595
        global_found = TRUE;
596
    }
597
  else
598
    {
599
      const char *sname, *lname;
600
      const char *sdot, *ldot;
601
      int lmaj, lmin, smaj, smin;
602
 
603
      lname = global_needed->name + 2;
604
 
605
      sname = strrchr (s->filename, '/');
606
      if (sname == NULL)
607
        sname = s->filename;
608
      else
609
        ++sname;
610
 
611
      if (! CONST_STRNEQ (sname, "lib"))
612
        return;
613
      sname += 3;
614
 
615
      ldot = strchr (lname, '.');
616
      if (ldot == NULL)
617
        ldot = lname + strlen (lname);
618
 
619
      sdot = strstr (sname, ".so.");
620
      if (sdot == NULL)
621
        return;
622
 
623
      if (sdot - sname != ldot - lname
624
          || strncmp (lname, sname, sdot - sname) != 0)
625
        return;
626
 
627
      lmaj = lmin = -1;
628
      sscanf (ldot, ".%d.%d", &lmaj, &lmin);
629
      smaj = smin = -1;
630
      sscanf (sdot, ".so.%d.%d", &smaj, &smin);
631
      if ((smaj != lmaj && smaj != -1 && lmaj != -1)
632
          || (smin != lmin && smin != -1 && lmin != -1))
633
        return;
634
 
635
      global_found = TRUE;
636
    }
637
}
638
 
639
/* We need to use static variables to pass information around the call
640
   to lang_for_each_statement.  Ick.  */
641
 
642
static const char *find_assign;
643
static bfd_boolean found_assign;
644
 
645
/* We need to use static variables to pass information around the call
646
   to lang_for_each_input_file.  Ick.  */
647
 
648
static bfd_size_type need_size;
649
static bfd_size_type need_entries;
650
static bfd_byte *need_contents;
651
static bfd_byte *need_pinfo;
652
static bfd_byte *need_pnames;
653
 
654
/* The size of one entry in the .need section, not including the file
655
   name.  */
656
 
657
#define NEED_ENTRY_SIZE (16)
658
 
659
/* This is called after the sections have been attached to output
660
   sections, but before any sizes or addresses have been set.  */
661
 
662
static void
663
gld${EMULATION_NAME}_before_allocation (void)
664
{
665
  struct bfd_link_hash_entry *hdyn = NULL;
666
  asection *sneed;
667
  asection *srules;
668
  asection *sdyn;
669
 
670
  /* The SunOS native linker creates a shared library whenever there
671
     are any undefined symbols in a link, unless -e is used.  This is
672
     pretty weird, but we are compatible.  */
673
  if (! link_info.shared && ! link_info.relocatable && ! entry_from_cmdline)
674
    {
675
      struct bfd_link_hash_entry *h;
676
 
677
      for (h = link_info.hash->undefs; h != NULL; h = h->u.undef.next)
678
        {
679
          if (h->type == bfd_link_hash_undefined
680
              && h->u.undef.abfd != NULL
681
              && (h->u.undef.abfd->flags & DYNAMIC) == 0
682
              && strcmp (h->root.string, "__DYNAMIC") != 0
683
              && strcmp (h->root.string, "__GLOBAL_OFFSET_TABLE_") != 0)
684
            {
685
              find_assign = h->root.string;
686
              found_assign = FALSE;
687
              lang_for_each_statement (gld${EMULATION_NAME}_find_assignment);
688
              if (! found_assign)
689
                {
690
                  link_info.shared = TRUE;
691
                  break;
692
                }
693
            }
694
        }
695
    }
696
 
697
  if (link_info.shared)
698
    {
699
      lang_output_section_statement_type *os;
700
 
701
      /* Set the .text section to start at 0x20, not 0x2020.  FIXME:
702
         This is too magical.  */
703
      os = lang_output_section_statement_lookup (".text", 0, TRUE);
704
      if (os->addr_tree == NULL)
705
        os->addr_tree = exp_intop (0x20);
706
    }
707
 
708
  /* We need to create a __DYNAMIC symbol.  We don't do this in the
709
     linker script because we want to set the value to the start of
710
     the dynamic section if there is one, or to zero if there isn't
711
     one.  We need to create the symbol before calling
712
     size_dynamic_sections, although we can't set the value until
713
     afterward.  */
714
  if (! link_info.relocatable)
715
    {
716
      hdyn = bfd_link_hash_lookup (link_info.hash, "__DYNAMIC", TRUE, FALSE,
717
                                   FALSE);
718
      if (hdyn == NULL)
719
        einfo ("%P%F: bfd_link_hash_lookup: %E\n");
720
      if (! bfd_sunos_record_link_assignment (link_info.output_bfd, &link_info,
721
                                              "__DYNAMIC"))
722
        einfo ("%P%F: failed to record assignment to __DYNAMIC: %E\n");
723
    }
724
 
725
  /* If we are going to make any variable assignments, we need to let
726
     the backend linker know about them in case the variables are
727
     referred to by dynamic objects.  */
728
  lang_for_each_statement (gld${EMULATION_NAME}_find_assignment);
729
 
730
  /* Let the backend linker work out the sizes of any sections
731
     required by dynamic linking.  */
732
  if (! bfd_sunos_size_dynamic_sections (link_info.output_bfd, &link_info,
733
                                         &sdyn, &sneed, &srules))
734
    einfo ("%P%F: failed to set dynamic section sizes: %E\n");
735
 
736
  if (sneed != NULL)
737
    {
738
      /* Set up the .need section.  See the description of the ld_need
739
         field in include/aout/sun4.h.  */
740
 
741
      need_entries = 0;
742
      need_size = 0;
743
 
744
      lang_for_each_input_file (gld${EMULATION_NAME}_count_need);
745
 
746
      /* We should only have a .need section if we have at least one
747
         dynamic object.  */
748
      ASSERT (need_entries != 0);
749
 
750
      sneed->size = need_size;
751
      sneed->contents = (bfd_byte *) xmalloc (need_size);
752
 
753
      need_contents = sneed->contents;
754
      need_pinfo = sneed->contents;
755
      need_pnames = sneed->contents + need_entries * 16;
756
 
757
      lang_for_each_input_file (gld${EMULATION_NAME}_set_need);
758
 
759
      ASSERT ((bfd_size_type) (need_pnames - sneed->contents) == need_size);
760
    }
761
 
762
  if (srules != NULL)
763
    {
764
      /* Set up the .rules section.  This is just a PATH like string
765
         of the -L arguments given on the command line.  We permit the
766
         user to specify the directories using the -rpath command line
767
         option.  */
768
      if (command_line.rpath)
769
        {
770
          srules->size = strlen (command_line.rpath);
771
          srules->contents = (bfd_byte *) command_line.rpath;
772
        }
773
      else
774
        {
775
          unsigned int size;
776
          search_dirs_type *search;
777
 
778
          size = 0;
779
          for (search = search_head; search != NULL; search = search->next)
780
            if (search->cmdline)
781
              size += strlen (search->name) + 1;
782
          srules->size = size;
783
          if (size > 0)
784
            {
785
              char *p;
786
 
787
              srules->contents = (bfd_byte *) xmalloc (size);
788
              p = (char *) srules->contents;
789
              *p = '\0';
790
              for (search = search_head; search != NULL; search = search->next)
791
                {
792
                  if (search->cmdline)
793
                    {
794
                      if (p != (char *) srules->contents)
795
                        *p++ = ':';
796
                      strcpy (p, search->name);
797
                      p += strlen (p);
798
                    }
799
                }
800
            }
801
        }
802
    }
803
 
804
  /* We must assign a value to __DYNAMIC.  It should be zero if we are
805
     not doing a dynamic link, or the start of the .dynamic section if
806
     we are doing one.  */
807
  if (! link_info.relocatable)
808
    {
809
      hdyn->type = bfd_link_hash_defined;
810
      hdyn->u.def.value = 0;
811
      if (sdyn != NULL)
812
        hdyn->u.def.section = sdyn;
813
      else
814
        hdyn->u.def.section = bfd_abs_section_ptr;
815
    }
816
 
817
  before_allocation_default ();
818
}
819
 
820
/* This is called by the before_allocation routine via
821
   lang_for_each_statement.  It does one of two things: if the
822
   variable find_assign is set, it sets found_assign if it finds an
823
   assignment to that variable; otherwise it tells the backend linker
824
   about all assignment statements, in case they are assignments to
825
   symbols which are referred to by dynamic objects.  */
826
 
827
static void
828
gld${EMULATION_NAME}_find_assignment (lang_statement_union_type *s)
829
{
830
  if (s->header.type == lang_assignment_statement_enum
831
      && (find_assign == NULL || ! found_assign))
832
    gld${EMULATION_NAME}_find_exp_assignment (s->assignment_statement.exp);
833
}
834
 
835
/* Look through an expression for an assignment statement.  */
836
 
837
static void
838
gld${EMULATION_NAME}_find_exp_assignment (etree_type *exp)
839
{
840
  switch (exp->type.node_class)
841
    {
842
    case etree_assign:
843
      if (find_assign != NULL)
844
        {
845
          if (strcmp (find_assign, exp->assign.dst) == 0)
846
            found_assign = TRUE;
847
          return;
848
        }
849
 
850
      if (strcmp (exp->assign.dst, ".") != 0)
851
        {
852
          if (! bfd_sunos_record_link_assignment (link_info.output_bfd,
853
                                                  &link_info,
854
                                                  exp->assign.dst))
855
            einfo ("%P%F: failed to record assignment to %s: %E\n",
856
                   exp->assign.dst);
857
        }
858
      gld${EMULATION_NAME}_find_exp_assignment (exp->assign.src);
859
      break;
860
 
861
    case etree_binary:
862
      gld${EMULATION_NAME}_find_exp_assignment (exp->binary.lhs);
863
      gld${EMULATION_NAME}_find_exp_assignment (exp->binary.rhs);
864
      break;
865
 
866
    case etree_trinary:
867
      gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.cond);
868
      gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.lhs);
869
      gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.rhs);
870
      break;
871
 
872
    case etree_unary:
873
      gld${EMULATION_NAME}_find_exp_assignment (exp->unary.child);
874
      break;
875
 
876
    default:
877
      break;
878
    }
879
}
880
 
881
/* Work out the size of the .need section, and the number of entries.
882
   The backend will set the ld_need field of the dynamic linking
883
   information to point to the .need section.  See include/aout/sun4.h
884
   for more information.  */
885
 
886
static void
887
gld${EMULATION_NAME}_count_need (lang_input_statement_type *inp)
888
{
889
  if (inp->the_bfd != NULL
890
      && (inp->the_bfd->flags & DYNAMIC) != 0)
891
    {
892
      ++need_entries;
893
      need_size += NEED_ENTRY_SIZE;
894
      if (! inp->maybe_archive)
895
        need_size += strlen (inp->filename) + 1;
896
      else
897
        {
898
          ASSERT (inp->local_sym_name[0] == '-'
899
                  && inp->local_sym_name[1] == 'l');
900
          need_size += strlen (inp->local_sym_name + 2) + 1;
901
        }
902
    }
903
}
904
 
905
/* Fill in the contents of the .need section.  */
906
 
907
static void
908
gld${EMULATION_NAME}_set_need (lang_input_statement_type *inp)
909
{
910
  if (inp->the_bfd != NULL
911
      && (inp->the_bfd->flags & DYNAMIC) != 0)
912
    {
913
      bfd_size_type c;
914
 
915
      /* To really fill in the .need section contents, we need to know
916
         the final file position of the section, but we don't.
917
         Instead, we use offsets, and rely on the BFD backend to
918
         finish the section up correctly.  FIXME: Talk about lack of
919
         referential locality.  */
920
      bfd_put_32 (link_info.output_bfd, need_pnames - need_contents,
921
                  need_pinfo);
922
      if (! inp->maybe_archive)
923
        {
924
          bfd_put_32 (link_info.output_bfd, (bfd_vma) 0, need_pinfo + 4);
925
          bfd_put_16 (link_info.output_bfd, (bfd_vma) 0, need_pinfo + 8);
926
          bfd_put_16 (link_info.output_bfd, (bfd_vma) 0, need_pinfo + 10);
927
          strcpy ((char *) need_pnames, inp->filename);
928
        }
929
      else
930
        {
931
          char *verstr;
932
          int maj, min;
933
 
934
          bfd_put_32 (link_info.output_bfd, (bfd_vma) 0x80000000,
935
                      need_pinfo + 4);
936
          maj = 0;
937
          min = 0;
938
          verstr = strstr (inp->filename, ".so.");
939
          if (verstr != NULL)
940
            sscanf (verstr, ".so.%d.%d", &maj, &min);
941
          bfd_put_16 (link_info.output_bfd, (bfd_vma) maj, need_pinfo + 8);
942
          bfd_put_16 (link_info.output_bfd, (bfd_vma) min, need_pinfo + 10);
943
          strcpy ((char *) need_pnames, inp->local_sym_name + 2);
944
        }
945
 
946
      c = (need_pinfo - need_contents) / NEED_ENTRY_SIZE;
947
      if (c + 1 >= need_entries)
948
        bfd_put_32 (link_info.output_bfd, (bfd_vma) 0, need_pinfo + 12);
949
      else
950
        bfd_put_32 (link_info.output_bfd, (bfd_vma) (c + 1) * NEED_ENTRY_SIZE,
951
                    need_pinfo + 12);
952
 
953
      need_pinfo += NEED_ENTRY_SIZE;
954
      need_pnames += strlen ((char *) need_pnames) + 1;
955
    }
956
}
957
 
958
static char *
959
gld${EMULATION_NAME}_get_script (int *isfile)
960
EOF
961
 
962
if test -n "$COMPILE_IN"
963
then
964
# Scripts compiled in.
965
 
966
# sed commands to quote an ld script as a C string.
967
sc="-f stringify.sed"
968
 
969
fragment <
970
{
971
  *isfile = 0;
972
 
973
  if (link_info.relocatable && config.build_constructors)
974
    return
975
EOF
976
sed $sc ldscripts/${EMULATION_NAME}.xu                     >> e${EMULATION_NAME}.c
977
echo '  ; else if (link_info.relocatable) return'         >> e${EMULATION_NAME}.c
978
sed $sc ldscripts/${EMULATION_NAME}.xr                     >> e${EMULATION_NAME}.c
979
echo '  ; else if (!config.text_read_only) return'         >> e${EMULATION_NAME}.c
980
sed $sc ldscripts/${EMULATION_NAME}.xbn                    >> e${EMULATION_NAME}.c
981
echo '  ; else if (!config.magic_demand_paged) return'     >> e${EMULATION_NAME}.c
982
sed $sc ldscripts/${EMULATION_NAME}.xn                     >> e${EMULATION_NAME}.c
983
echo '  ; else return'                                     >> e${EMULATION_NAME}.c
984
sed $sc ldscripts/${EMULATION_NAME}.x                      >> e${EMULATION_NAME}.c
985
echo '; }'                                                 >> e${EMULATION_NAME}.c
986
 
987
else
988
# Scripts read from the filesystem.
989
 
990
fragment <
991
{
992
  *isfile = 1;
993
 
994
  if (link_info.relocatable && config.build_constructors)
995
    return "ldscripts/${EMULATION_NAME}.xu";
996
  else if (link_info.relocatable)
997
    return "ldscripts/${EMULATION_NAME}.xr";
998
  else if (!config.text_read_only)
999
    return "ldscripts/${EMULATION_NAME}.xbn";
1000
  else if (!config.magic_demand_paged)
1001
    return "ldscripts/${EMULATION_NAME}.xn";
1002
  else
1003
    return "ldscripts/${EMULATION_NAME}.x";
1004
}
1005
EOF
1006
 
1007
fi
1008
 
1009
fragment <
1010
 
1011
struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
1012
{
1013
  gld${EMULATION_NAME}_before_parse,
1014
  syslib_default,
1015
  hll_default,
1016
  after_parse_default,
1017
  gld${EMULATION_NAME}_after_open,
1018
  after_allocation_default,
1019
  set_output_arch_default,
1020
  ldemul_default_target,
1021
  gld${EMULATION_NAME}_before_allocation,
1022
  gld${EMULATION_NAME}_get_script,
1023
  "${EMULATION_NAME}",
1024
  "${OUTPUT_FORMAT}",
1025
  finish_default,
1026
  gld${EMULATION_NAME}_create_output_section_statements,
1027
  NULL, /* open dynamic archive */
1028
  NULL, /* place orphan */
1029
  gld${EMULATION_NAME}_set_symbols,
1030
  NULL, /* parse args */
1031
  NULL, /* add_options */
1032
  NULL, /* handle_option */
1033
  NULL, /* unrecognized file */
1034
  NULL, /* list options */
1035
  NULL, /* recognized file */
1036
  NULL, /* find_potential_libraries */
1037
  NULL  /* new_vers_pattern */
1038
};
1039
EOF

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.