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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [binutils-2.18.50/] [ld/] [emultempl/] [sunos.em] - Blame information for rev 450

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

Line No. Rev Author Line
1 38 julius
# 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->is_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
  /* We only need to worry about this when doing a final link.  */
370
  if (link_info.relocatable || link_info.shared)
371
    return;
372
 
373
  /* Get the list of files which appear in ld_need entries in dynamic
374
     objects included in the link.  For each such file, we want to
375
     track down the corresponding library, and include the symbol
376
     table in the link.  This is what the runtime dynamic linker will
377
     do.  Tracking the files down here permits one dynamic object to
378
     include another without requiring special action by the person
379
     doing the link.  Note that the needed list can actually grow
380
     while we are stepping through this loop.  */
381
  needed = bfd_sunos_get_needed_list (link_info.output_bfd, &link_info);
382
  for (l = needed; l != NULL; l = l->next)
383
    {
384
      struct bfd_link_needed_list *ll;
385
      const char *lname;
386
      search_dirs_type *search;
387
 
388
      lname = l->name;
389
 
390
      /* If we've already seen this file, skip it.  */
391
      for (ll = needed; ll != l; ll = ll->next)
392
        if (strcmp (ll->name, lname) == 0)
393
          break;
394
      if (ll != l)
395
        continue;
396
 
397
      /* See if this file was included in the link explicitly.  */
398
      global_needed = l;
399
      global_found = FALSE;
400
      lang_for_each_input_file (gld${EMULATION_NAME}_check_needed);
401
      if (global_found)
402
        continue;
403
 
404
      if (! CONST_STRNEQ (lname, "-l"))
405
        {
406
          bfd *abfd;
407
 
408
          abfd = bfd_openr (lname, bfd_get_target (link_info.output_bfd));
409
          if (abfd != NULL)
410
            {
411
              if (! bfd_check_format (abfd, bfd_object))
412
                {
413
                  (void) bfd_close (abfd);
414
                  abfd = NULL;
415
                }
416
            }
417
          if (abfd != NULL)
418
            {
419
              if ((bfd_get_file_flags (abfd) & DYNAMIC) == 0)
420
                {
421
                  (void) bfd_close (abfd);
422
                  abfd = NULL;
423
                }
424
            }
425
          if (abfd != NULL)
426
            {
427
              /* We've found the needed dynamic object.  */
428
              if (! bfd_link_add_symbols (abfd, &link_info))
429
                einfo ("%F%B: could not read symbols: %E\n", abfd);
430
            }
431
          else
432
            {
433
              einfo ("%P: warning: %s, needed by %B, not found\n",
434
                     lname, l->by);
435
            }
436
 
437
          continue;
438
        }
439
 
440
      lname += 2;
441
 
442
      /* We want to search for the file in the same way that the
443
         dynamic linker will search.  That means that we want to use
444
         rpath_link, rpath or -L, then the environment variable
445
         LD_LIBRARY_PATH (native only), then (if rpath was used) the
446
         linker script LIB_SEARCH_DIRS.  */
447
      if (gld${EMULATION_NAME}_search_needed (command_line.rpath_link,
448
                                              lname))
449
        continue;
450
      if (command_line.rpath != NULL)
451
        {
452
          if (gld${EMULATION_NAME}_search_needed (command_line.rpath, lname))
453
            continue;
454
        }
455
      else
456
        {
457
          for (search = search_head; search != NULL; search = search->next)
458
            if (gld${EMULATION_NAME}_try_needed (search->name, lname))
459
              break;
460
          if (search != NULL)
461
            continue;
462
        }
463
EOF
464
if [ "x${host}" = "x${target}" ] ; then
465
  case " ${EMULATION_LIBPATH} " in
466
  *" ${EMULATION_NAME} "*)
467
fragment <
468
      {
469
        const char *lib_path;
470
 
471
        lib_path = (const char *) getenv ("LD_LIBRARY_PATH");
472
        if (gld${EMULATION_NAME}_search_needed (lib_path, lname))
473
          continue;
474
      }
475
EOF
476
  ;;
477
  esac
478
fi
479
fragment <
480
      if (command_line.rpath != NULL)
481
        {
482
          for (search = search_head; search != NULL; search = search->next)
483
            {
484
              if (search->cmdline)
485
                continue;
486
              if (gld${EMULATION_NAME}_try_needed (search->name, lname))
487
                break;
488
            }
489
          if (search != NULL)
490
            continue;
491
        }
492
 
493
      einfo ("%P: warning: %s, needed by %B, not found\n",
494
             l->name, l->by);
495
    }
496
}
497
 
498
/* Search for a needed file in a path.  */
499
 
500
static bfd_boolean
501
gld${EMULATION_NAME}_search_needed (const char *path, const char *name)
502
{
503
  const char *s;
504
 
505
  if (path == NULL || *path == '\0')
506
    return FALSE;
507
  while (1)
508
    {
509
      const char *dir;
510
      char *dircopy;
511
 
512
      s = strchr (path, ':');
513
      if (s == NULL)
514
        {
515
          dircopy = NULL;
516
          dir = path;
517
        }
518
      else
519
        {
520
          dircopy = (char *) xmalloc (s - path + 1);
521
          memcpy (dircopy, path, s - path);
522
          dircopy[s - path] = '\0';
523
          dir = dircopy;
524
        }
525
 
526
      if (gld${EMULATION_NAME}_try_needed (dir, name))
527
        return TRUE;
528
 
529
      if (dircopy != NULL)
530
        free (dircopy);
531
 
532
      if (s == NULL)
533
        break;
534
      path = s + 1;
535
    }
536
 
537
  return FALSE;
538
}
539
 
540
/* This function is called for each possible directory for a needed
541
   dynamic object.  */
542
 
543
static bfd_boolean
544
gld${EMULATION_NAME}_try_needed (const char *dir, const char *name)
545
{
546
  char *file;
547
  char *alc;
548
  bfd_boolean ignore;
549
  bfd *abfd;
550
 
551
  file = gld${EMULATION_NAME}_search_dir (dir, name, &ignore);
552
  if (file == NULL)
553
    return FALSE;
554
 
555
  alc = (char *) xmalloc (strlen (dir) + strlen (file) + 2);
556
  sprintf (alc, "%s/%s", dir, file);
557
  free (file);
558
  abfd = bfd_openr (alc, bfd_get_target (link_info.output_bfd));
559
  if (abfd == NULL)
560
    return FALSE;
561
  if (! bfd_check_format (abfd, bfd_object))
562
    {
563
      (void) bfd_close (abfd);
564
      return FALSE;
565
    }
566
  if ((bfd_get_file_flags (abfd) & DYNAMIC) == 0)
567
    {
568
      (void) bfd_close (abfd);
569
      return FALSE;
570
    }
571
 
572
  /* We've found the needed dynamic object.  */
573
 
574
  /* Add this file into the symbol table.  */
575
  if (! bfd_link_add_symbols (abfd, &link_info))
576
    einfo ("%F%B: could not read symbols: %E\n", abfd);
577
 
578
  return TRUE;
579
}
580
 
581
/* See if we have already included a needed object in the link.  This
582
   does not have to be precise, as it does no harm to include a
583
   dynamic object more than once.  */
584
 
585
static void
586
gld${EMULATION_NAME}_check_needed (lang_input_statement_type *s)
587
{
588
  if (s->filename == NULL)
589
    return;
590
  if (! CONST_STRNEQ (global_needed->name, "-l"))
591
    {
592
      if (strcmp (s->filename, global_needed->name) == 0)
593
        global_found = TRUE;
594
    }
595
  else
596
    {
597
      const char *sname, *lname;
598
      const char *sdot, *ldot;
599
      int lmaj, lmin, smaj, smin;
600
 
601
      lname = global_needed->name + 2;
602
 
603
      sname = strrchr (s->filename, '/');
604
      if (sname == NULL)
605
        sname = s->filename;
606
      else
607
        ++sname;
608
 
609
      if (! CONST_STRNEQ (sname, "lib"))
610
        return;
611
      sname += 3;
612
 
613
      ldot = strchr (lname, '.');
614
      if (ldot == NULL)
615
        ldot = lname + strlen (lname);
616
 
617
      sdot = strstr (sname, ".so.");
618
      if (sdot == NULL)
619
        return;
620
 
621
      if (sdot - sname != ldot - lname
622
          || strncmp (lname, sname, sdot - sname) != 0)
623
        return;
624
 
625
      lmaj = lmin = -1;
626
      sscanf (ldot, ".%d.%d", &lmaj, &lmin);
627
      smaj = smin = -1;
628
      sscanf (sdot, ".so.%d.%d", &smaj, &smin);
629
      if ((smaj != lmaj && smaj != -1 && lmaj != -1)
630
          || (smin != lmin && smin != -1 && lmin != -1))
631
        return;
632
 
633
      global_found = TRUE;
634
    }
635
}
636
 
637
/* We need to use static variables to pass information around the call
638
   to lang_for_each_statement.  Ick.  */
639
 
640
static const char *find_assign;
641
static bfd_boolean found_assign;
642
 
643
/* We need to use static variables to pass information around the call
644
   to lang_for_each_input_file.  Ick.  */
645
 
646
static bfd_size_type need_size;
647
static bfd_size_type need_entries;
648
static bfd_byte *need_contents;
649
static bfd_byte *need_pinfo;
650
static bfd_byte *need_pnames;
651
 
652
/* The size of one entry in the .need section, not including the file
653
   name.  */
654
 
655
#define NEED_ENTRY_SIZE (16)
656
 
657
/* This is called after the sections have been attached to output
658
   sections, but before any sizes or addresses have been set.  */
659
 
660
static void
661
gld${EMULATION_NAME}_before_allocation (void)
662
{
663
  struct bfd_link_hash_entry *hdyn = NULL;
664
  asection *sneed;
665
  asection *srules;
666
  asection *sdyn;
667
 
668
  /* The SunOS native linker creates a shared library whenever there
669
     are any undefined symbols in a link, unless -e is used.  This is
670
     pretty weird, but we are compatible.  */
671
  if (! link_info.shared && ! link_info.relocatable && ! entry_from_cmdline)
672
    {
673
      struct bfd_link_hash_entry *h;
674
 
675
      for (h = link_info.hash->undefs; h != NULL; h = h->u.undef.next)
676
        {
677
          if (h->type == bfd_link_hash_undefined
678
              && h->u.undef.abfd != NULL
679
              && (h->u.undef.abfd->flags & DYNAMIC) == 0
680
              && strcmp (h->root.string, "__DYNAMIC") != 0
681
              && strcmp (h->root.string, "__GLOBAL_OFFSET_TABLE_") != 0)
682
            {
683
              find_assign = h->root.string;
684
              found_assign = FALSE;
685
              lang_for_each_statement (gld${EMULATION_NAME}_find_assignment);
686
              if (! found_assign)
687
                {
688
                  link_info.shared = TRUE;
689
                  break;
690
                }
691
            }
692
        }
693
    }
694
 
695
  if (link_info.shared)
696
    {
697
      lang_output_section_statement_type *os;
698
 
699
      /* Set the .text section to start at 0x20, not 0x2020.  FIXME:
700
         This is too magical.  */
701
      os = lang_output_section_statement_lookup (".text");
702
      if (os->addr_tree == NULL)
703
        os->addr_tree = exp_intop (0x20);
704
    }
705
 
706
  /* We need to create a __DYNAMIC symbol.  We don't do this in the
707
     linker script because we want to set the value to the start of
708
     the dynamic section if there is one, or to zero if there isn't
709
     one.  We need to create the symbol before calling
710
     size_dynamic_sections, although we can't set the value until
711
     afterward.  */
712
  if (! link_info.relocatable)
713
    {
714
      hdyn = bfd_link_hash_lookup (link_info.hash, "__DYNAMIC", TRUE, FALSE,
715
                                   FALSE);
716
      if (hdyn == NULL)
717
        einfo ("%P%F: bfd_link_hash_lookup: %E\n");
718
      if (! bfd_sunos_record_link_assignment (link_info.output_bfd, &link_info,
719
                                              "__DYNAMIC"))
720
        einfo ("%P%F: failed to record assignment to __DYNAMIC: %E\n");
721
    }
722
 
723
  /* If we are going to make any variable assignments, we need to let
724
     the backend linker know about them in case the variables are
725
     referred to by dynamic objects.  */
726
  lang_for_each_statement (gld${EMULATION_NAME}_find_assignment);
727
 
728
  /* Let the backend linker work out the sizes of any sections
729
     required by dynamic linking.  */
730
  if (! bfd_sunos_size_dynamic_sections (link_info.output_bfd, &link_info,
731
                                         &sdyn, &sneed, &srules))
732
    einfo ("%P%F: failed to set dynamic section sizes: %E\n");
733
 
734
  if (sneed != NULL)
735
    {
736
      /* Set up the .need section.  See the description of the ld_need
737
         field in include/aout/sun4.h.  */
738
 
739
      need_entries = 0;
740
      need_size = 0;
741
 
742
      lang_for_each_input_file (gld${EMULATION_NAME}_count_need);
743
 
744
      /* We should only have a .need section if we have at least one
745
         dynamic object.  */
746
      ASSERT (need_entries != 0);
747
 
748
      sneed->size = need_size;
749
      sneed->contents = (bfd_byte *) xmalloc (need_size);
750
 
751
      need_contents = sneed->contents;
752
      need_pinfo = sneed->contents;
753
      need_pnames = sneed->contents + need_entries * 16;
754
 
755
      lang_for_each_input_file (gld${EMULATION_NAME}_set_need);
756
 
757
      ASSERT ((bfd_size_type) (need_pnames - sneed->contents) == need_size);
758
    }
759
 
760
  if (srules != NULL)
761
    {
762
      /* Set up the .rules section.  This is just a PATH like string
763
         of the -L arguments given on the command line.  We permit the
764
         user to specify the directories using the -rpath command line
765
         option.  */
766
      if (command_line.rpath)
767
        {
768
          srules->size = strlen (command_line.rpath);
769
          srules->contents = (bfd_byte *) command_line.rpath;
770
        }
771
      else
772
        {
773
          unsigned int size;
774
          search_dirs_type *search;
775
 
776
          size = 0;
777
          for (search = search_head; search != NULL; search = search->next)
778
            if (search->cmdline)
779
              size += strlen (search->name) + 1;
780
          srules->size = size;
781
          if (size > 0)
782
            {
783
              char *p;
784
 
785
              srules->contents = (bfd_byte *) xmalloc (size);
786
              p = (char *) srules->contents;
787
              *p = '\0';
788
              for (search = search_head; search != NULL; search = search->next)
789
                {
790
                  if (search->cmdline)
791
                    {
792
                      if (p != (char *) srules->contents)
793
                        *p++ = ':';
794
                      strcpy (p, search->name);
795
                      p += strlen (p);
796
                    }
797
                }
798
            }
799
        }
800
    }
801
 
802
  /* We must assign a value to __DYNAMIC.  It should be zero if we are
803
     not doing a dynamic link, or the start of the .dynamic section if
804
     we are doing one.  */
805
  if (! link_info.relocatable)
806
    {
807
      hdyn->type = bfd_link_hash_defined;
808
      hdyn->u.def.value = 0;
809
      if (sdyn != NULL)
810
        hdyn->u.def.section = sdyn;
811
      else
812
        hdyn->u.def.section = bfd_abs_section_ptr;
813
    }
814
 
815
  before_allocation_default ();
816
}
817
 
818
/* This is called by the before_allocation routine via
819
   lang_for_each_statement.  It does one of two things: if the
820
   variable find_assign is set, it sets found_assign if it finds an
821
   assignment to that variable; otherwise it tells the backend linker
822
   about all assignment statements, in case they are assignments to
823
   symbols which are referred to by dynamic objects.  */
824
 
825
static void
826
gld${EMULATION_NAME}_find_assignment (lang_statement_union_type *s)
827
{
828
  if (s->header.type == lang_assignment_statement_enum
829
      && (find_assign == NULL || ! found_assign))
830
    gld${EMULATION_NAME}_find_exp_assignment (s->assignment_statement.exp);
831
}
832
 
833
/* Look through an expression for an assignment statement.  */
834
 
835
static void
836
gld${EMULATION_NAME}_find_exp_assignment (etree_type *exp)
837
{
838
  switch (exp->type.node_class)
839
    {
840
    case etree_assign:
841
      if (find_assign != NULL)
842
        {
843
          if (strcmp (find_assign, exp->assign.dst) == 0)
844
            found_assign = TRUE;
845
          return;
846
        }
847
 
848
      if (strcmp (exp->assign.dst, ".") != 0)
849
        {
850
          if (! bfd_sunos_record_link_assignment (link_info.output_bfd,
851
                                                  &link_info,
852
                                                  exp->assign.dst))
853
            einfo ("%P%F: failed to record assignment to %s: %E\n",
854
                   exp->assign.dst);
855
        }
856
      gld${EMULATION_NAME}_find_exp_assignment (exp->assign.src);
857
      break;
858
 
859
    case etree_binary:
860
      gld${EMULATION_NAME}_find_exp_assignment (exp->binary.lhs);
861
      gld${EMULATION_NAME}_find_exp_assignment (exp->binary.rhs);
862
      break;
863
 
864
    case etree_trinary:
865
      gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.cond);
866
      gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.lhs);
867
      gld${EMULATION_NAME}_find_exp_assignment (exp->trinary.rhs);
868
      break;
869
 
870
    case etree_unary:
871
      gld${EMULATION_NAME}_find_exp_assignment (exp->unary.child);
872
      break;
873
 
874
    default:
875
      break;
876
    }
877
}
878
 
879
/* Work out the size of the .need section, and the number of entries.
880
   The backend will set the ld_need field of the dynamic linking
881
   information to point to the .need section.  See include/aout/sun4.h
882
   for more information.  */
883
 
884
static void
885
gld${EMULATION_NAME}_count_need (lang_input_statement_type *inp)
886
{
887
  if (inp->the_bfd != NULL
888
      && (inp->the_bfd->flags & DYNAMIC) != 0)
889
    {
890
      ++need_entries;
891
      need_size += NEED_ENTRY_SIZE;
892
      if (! inp->is_archive)
893
        need_size += strlen (inp->filename) + 1;
894
      else
895
        {
896
          ASSERT (inp->local_sym_name[0] == '-'
897
                  && inp->local_sym_name[1] == 'l');
898
          need_size += strlen (inp->local_sym_name + 2) + 1;
899
        }
900
    }
901
}
902
 
903
/* Fill in the contents of the .need section.  */
904
 
905
static void
906
gld${EMULATION_NAME}_set_need (lang_input_statement_type *inp)
907
{
908
  if (inp->the_bfd != NULL
909
      && (inp->the_bfd->flags & DYNAMIC) != 0)
910
    {
911
      bfd_size_type c;
912
 
913
      /* To really fill in the .need section contents, we need to know
914
         the final file position of the section, but we don't.
915
         Instead, we use offsets, and rely on the BFD backend to
916
         finish the section up correctly.  FIXME: Talk about lack of
917
         referential locality.  */
918
      bfd_put_32 (link_info.output_bfd, need_pnames - need_contents,
919
                  need_pinfo);
920
      if (! inp->is_archive)
921
        {
922
          bfd_put_32 (link_info.output_bfd, (bfd_vma) 0, need_pinfo + 4);
923
          bfd_put_16 (link_info.output_bfd, (bfd_vma) 0, need_pinfo + 8);
924
          bfd_put_16 (link_info.output_bfd, (bfd_vma) 0, need_pinfo + 10);
925
          strcpy ((char *) need_pnames, inp->filename);
926
        }
927
      else
928
        {
929
          char *verstr;
930
          int maj, min;
931
 
932
          bfd_put_32 (link_info.output_bfd, (bfd_vma) 0x80000000,
933
                      need_pinfo + 4);
934
          maj = 0;
935
          min = 0;
936
          verstr = strstr (inp->filename, ".so.");
937
          if (verstr != NULL)
938
            sscanf (verstr, ".so.%d.%d", &maj, &min);
939
          bfd_put_16 (link_info.output_bfd, (bfd_vma) maj, need_pinfo + 8);
940
          bfd_put_16 (link_info.output_bfd, (bfd_vma) min, need_pinfo + 10);
941
          strcpy ((char *) need_pnames, inp->local_sym_name + 2);
942
        }
943
 
944
      c = (need_pinfo - need_contents) / NEED_ENTRY_SIZE;
945
      if (c + 1 >= need_entries)
946
        bfd_put_32 (link_info.output_bfd, (bfd_vma) 0, need_pinfo + 12);
947
      else
948
        bfd_put_32 (link_info.output_bfd, (bfd_vma) (c + 1) * NEED_ENTRY_SIZE,
949
                    need_pinfo + 12);
950
 
951
      need_pinfo += NEED_ENTRY_SIZE;
952
      need_pnames += strlen ((char *) need_pnames) + 1;
953
    }
954
}
955
 
956
static char *
957
gld${EMULATION_NAME}_get_script (int *isfile)
958
EOF
959
 
960
if test -n "$COMPILE_IN"
961
then
962
# Scripts compiled in.
963
 
964
# sed commands to quote an ld script as a C string.
965
sc="-f stringify.sed"
966
 
967
fragment <
968
{
969
  *isfile = 0;
970
 
971
  if (link_info.relocatable && config.build_constructors)
972
    return
973
EOF
974
sed $sc ldscripts/${EMULATION_NAME}.xu                     >> e${EMULATION_NAME}.c
975
echo '  ; else if (link_info.relocatable) return'         >> e${EMULATION_NAME}.c
976
sed $sc ldscripts/${EMULATION_NAME}.xr                     >> e${EMULATION_NAME}.c
977
echo '  ; else if (!config.text_read_only) return'         >> e${EMULATION_NAME}.c
978
sed $sc ldscripts/${EMULATION_NAME}.xbn                    >> e${EMULATION_NAME}.c
979
echo '  ; else if (!config.magic_demand_paged) return'     >> e${EMULATION_NAME}.c
980
sed $sc ldscripts/${EMULATION_NAME}.xn                     >> e${EMULATION_NAME}.c
981
echo '  ; else return'                                     >> e${EMULATION_NAME}.c
982
sed $sc ldscripts/${EMULATION_NAME}.x                      >> e${EMULATION_NAME}.c
983
echo '; }'                                                 >> e${EMULATION_NAME}.c
984
 
985
else
986
# Scripts read from the filesystem.
987
 
988
fragment <
989
{
990
  *isfile = 1;
991
 
992
  if (link_info.relocatable && config.build_constructors)
993
    return "ldscripts/${EMULATION_NAME}.xu";
994
  else if (link_info.relocatable)
995
    return "ldscripts/${EMULATION_NAME}.xr";
996
  else if (!config.text_read_only)
997
    return "ldscripts/${EMULATION_NAME}.xbn";
998
  else if (!config.magic_demand_paged)
999
    return "ldscripts/${EMULATION_NAME}.xn";
1000
  else
1001
    return "ldscripts/${EMULATION_NAME}.x";
1002
}
1003
EOF
1004
 
1005
fi
1006
 
1007
fragment <
1008
 
1009
struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
1010
{
1011
  gld${EMULATION_NAME}_before_parse,
1012
  syslib_default,
1013
  hll_default,
1014
  after_parse_default,
1015
  gld${EMULATION_NAME}_after_open,
1016
  after_allocation_default,
1017
  set_output_arch_default,
1018
  ldemul_default_target,
1019
  gld${EMULATION_NAME}_before_allocation,
1020
  gld${EMULATION_NAME}_get_script,
1021
  "${EMULATION_NAME}",
1022
  "${OUTPUT_FORMAT}",
1023
  finish_default,
1024
  gld${EMULATION_NAME}_create_output_section_statements,
1025
  NULL, /* open dynamic archive */
1026
  NULL, /* place orphan */
1027
  gld${EMULATION_NAME}_set_symbols,
1028
  NULL, /* parse args */
1029
  NULL, /* add_options */
1030
  NULL, /* handle_option */
1031
  NULL, /* unrecognized file */
1032
  NULL, /* list options */
1033
  NULL, /* recognized file */
1034
  NULL, /* find_potential_libraries */
1035
  NULL  /* new_vers_pattern */
1036
};
1037
EOF

powered by: WebSVN 2.1.0

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