13a64a3087f53ab860c7de04da0e53dabef459520Ulrich Drepper/* Copyright (C) 2001-2010, 2012 Red Hat, Inc.
2de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard   This file is part of elfutils.
3b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper   Written by Ulrich Drepper <drepper@redhat.com>, 2001.
4b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
5de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard   This file is free software; you can redistribute it and/or modify
6de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard   it under the terms of the GNU General Public License as published by
7de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard   the Free Software Foundation; either version 3 of the License, or
8de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard   (at your option) any later version.
9361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper
10de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard   elfutils is distributed in the hope that it will be useful, but
11361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   WITHOUT ANY WARRANTY; without even the implied warranty of
12de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard   GNU General Public License for more details.
14361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper
15de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard   You should have received a copy of the GNU General Public License
16de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
17b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
18b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#ifdef HAVE_CONFIG_H
19b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper# include <config.h>
20b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#endif
21b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
22b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <argp.h>
23b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <assert.h>
24b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <error.h>
25b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <fcntl.h>
26b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <libelf.h>
27b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <libintl.h>
28b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <locale.h>
29b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <stdio.h>
30b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <stdio_ext.h>
31b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <stdlib.h>
32b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <string.h>
33b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <unistd.h>
34b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
35b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <system.h>
36b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include "ld.h"
37b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include "list.h"
38b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
39b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
40b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Name and version of program.  */
41b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void print_version (FILE *stream, struct argp_state *state);
42fdc93e12a77866cafd1aae4463d89cef2c01d9b1Ulrich DrepperARGP_PROGRAM_VERSION_HOOK_DEF = print_version;
43b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
44b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Bug report address.  */
45fdc93e12a77866cafd1aae4463d89cef2c01d9b1Ulrich DrepperARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT;
46b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
47b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
48b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Values for the various options.  */
49b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperenum
50b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  {
51b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    ARGP_whole_archive = 300,
52b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    ARGP_no_whole_archive,
53b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    ARGP_static,
54b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    ARGP_dynamic,
55b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    ARGP_pagesize,
56b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    ARGP_rpath_link,
57b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    ARGP_runpath,
58b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    ARGP_runpath_link,
59b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    ARGP_version_script,
60b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    ARGP_gc_sections,
61b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    ARGP_no_gc_sections,
62b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    ARGP_no_undefined,
63b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    ARGP_conserve,
648c56fe3b2c753234beb6f58a81c8b96f008226efUlrich Drepper    ARGP_as_needed,
658c56fe3b2c753234beb6f58a81c8b96f008226efUlrich Drepper    ARGP_no_as_needed,
6654f33a779527d6764b4fc4068267715a718c422cUlrich Drepper    ARGP_eh_frame_hdr,
670e864dd86871c809668c557985ca19344dfff787Ulrich Drepper    ARGP_hash_style,
6889759c76ee1e3231ee89d4aafed3a88772ce2245Ulrich Drepper    ARGP_build_id,
69b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#if YYDEBUG
70b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    ARGP_yydebug,
71b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#endif
72b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  };
73b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
74b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
75b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Definitions of arguments for argp functions.  */
76b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic const struct argp_option options[] =
77b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
78cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper  { NULL, 0, NULL, 0, N_("Input File Control:"), 0 },
79b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  { "whole-archive", ARGP_whole_archive, NULL, 0,
80b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    N_("Include whole archives in the output from now on."), 0 },
81b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  { "no-whole-archive", ARGP_no_whole_archive, NULL, 0,
823b495d8e963eead963a37b5be5b063c96bb58c63Roland McGrath    N_("Stop including the whole archives in the output."), 0 },
83cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper  { NULL, 'l', N_("FILE"), OPTION_HIDDEN, NULL, 0 },
84d9488292be8c78615163eb4733e105143cb7b7baUlrich Drepper  { "start-group", '(', NULL, 0, N_("Start a group."), 0 },
85d9488292be8c78615163eb4733e105143cb7b7baUlrich Drepper  { "end-group", ')', NULL, 0, N_("End a group."), 0 },
86cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper  { NULL, 'L', N_("PATH"), 0,
87cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper    N_("Add PATH to list of directories files are searched in."), 0 },
88cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper  { "as-needed", ARGP_as_needed, NULL, 0,
89cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper    N_("Only set DT_NEEDED for following dynamic libs if actually used"), 0 },
90cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper  { "no-as-needed", ARGP_no_as_needed, NULL, 0,
91cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper    N_("Always set DT_NEEDED for following dynamic libs"), 0 },
92cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper  { "rpath-link", ARGP_rpath_link, "PATH", OPTION_HIDDEN, NULL, 0 },
93cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper  { NULL, 'i', NULL, 0, N_("Ignore LD_LIBRARY_PATH environment variable."),
94cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper    0 },
95b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
96cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper  { NULL, 0, NULL, 0, N_("Output File Control:"), 0 },
97b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  { "output", 'o', N_("FILE"), 0, N_("Place output in FILE."), 0 },
98b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  { NULL, 'z', "KEYWORD", OPTION_HIDDEN, NULL, 0 },
99b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  { "-z nodefaultlib", '\0', NULL, OPTION_DOC,
100b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    N_("Object is marked to not use default search path at runtime."), 0 },
101b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  { "-z allextract", '\0', NULL, OPTION_DOC,
102b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    N_("Same as --whole-archive."), 0 },
103b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  { "-z defaultextract", '\0', NULL, OPTION_DOC, N_("\
104b08d5a8fb42f4586d756068065186b5af7e48daUlrich DrepperDefault rules of extracting from archive; weak references are not enough."),
105b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    0 },
106b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  { "-z weakextract", '\0', NULL, OPTION_DOC,
107b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    N_("Weak references cause extraction from archive."), 0 },
108b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  { "-z muldefs", '\0', NULL, OPTION_DOC,
109b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    N_("Allow multiple definitions; first is used."), 0 },
110b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  { "-z defs | nodefs", '\0', NULL, OPTION_DOC,
111b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    N_("Disallow/allow undefined symbols in DSOs."), 0 },
112b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    { "no-undefined", ARGP_no_undefined, NULL, OPTION_HIDDEN, NULL, 0 },
113b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  { "-z origin", '\0', NULL, OPTION_DOC,
114b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    N_("Object requires immediate handling of $ORIGIN."), 0 },
115b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  { "-z now", '\0', NULL, OPTION_DOC,
116b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    N_("Relocation will not be processed lazily."), 0 },
117b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  { "-z nodelete", '\0', NULL, OPTION_DOC,
118b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    N_("Object cannot be unloaded at runtime."), 0 },
119b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  { "-z initfirst", '\0', NULL, OPTION_DOC,
120b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    N_("Mark object to be initialized first."), 0 },
121b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  { "-z lazyload | nolazyload", '\0', NULL, OPTION_DOC,
122b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    N_("Enable/disable lazy-loading flag for following dependencies."), 0 },
123b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  { "-z nodlopen", '\0', NULL, OPTION_DOC,
124b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    N_("Mark object as not loadable with 'dlopen'."), 0 },
125b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  { "-z ignore | record", '\0', NULL, OPTION_DOC,
126b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    N_("Ignore/record dependencies on unused DSOs."), 0 },
127b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  { "-z systemlibrary", '\0', NULL, OPTION_DOC,
128b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    N_("Generated DSO will be a system library."), 0 },
129b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  { "entry", 'e', N_("ADDRESS"), 0, N_("Set entry point address."), 0 },
130b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  { "static", ARGP_static, NULL, OPTION_HIDDEN, NULL, 0 },
131b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  { "-B static", ARGP_static, NULL, OPTION_DOC,
132b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    N_("Do not link against shared libraries."), 0 },
133b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  { "dynamic", ARGP_dynamic, NULL, OPTION_HIDDEN, NULL, 0 },
134b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  { "-B dynamic", ARGP_dynamic, NULL, OPTION_DOC,
135b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    N_("Prefer linking against shared libraries."), 0 },
136b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  { "export-dynamic", 'E', NULL, 0, N_("Export all dynamic symbols."), 0 },
137b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  { "strip-all", 's', NULL, 0, N_("Strip all symbols."), 0 },
138b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  { "strip-debug", 'S', NULL, 0, N_("Strip debugging symbols."), 0 },
139b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  { "pagesize", ARGP_pagesize, "SIZE", 0,
140b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    N_("Assume pagesize for the target system to be SIZE."), 0 },
141cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper  { "rpath", 'R', "PATH", OPTION_HIDDEN, NULL, 0 },
142b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  { "runpath", ARGP_runpath, "PATH", 0, N_("Set runtime DSO search path."),
143b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    0 },
144b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  { "runpath-link", ARGP_runpath_link, "PATH", 0,
145b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    N_("Set link time DSO search path."), 0 },
146b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  { "shared", 'G', NULL, 0, N_("Generate dynamic shared object."), 0 },
147b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  { NULL, 'r', NULL, 0L, N_("Generate relocatable object."), 0 },
148b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  { NULL, 'B', "KEYWORD", OPTION_HIDDEN, "", 0 },
149b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  { "-B local", 'B', NULL, OPTION_DOC,
150b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    N_("Causes symbol not assigned to a version be reduced to local."), 0 },
151b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  { "gc-sections", ARGP_gc_sections, NULL, 0, N_("Remove unused sections."),
152b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    0 },
153b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  { "no-gc-sections", ARGP_no_gc_sections, NULL, 0,
154b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    N_("Don't remove unused sections."), 0 },
155b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  { "soname", 'h', "NAME", 0, N_("Set soname of shared object."), 0 },
156b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  { "dynamic-linker", 'I', "NAME", 0, N_("Set the dynamic linker name."), 0 },
157b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  { NULL, 'Q', "YN", OPTION_HIDDEN, NULL, 0 },
158b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  { "-Q y | n", 'Q', NULL, OPTION_DOC,
15989759c76ee1e3231ee89d4aafed3a88772ce2245Ulrich Drepper    N_("Add/suppress addition indentifying link-editor to .comment section."),
160b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    0 },
16154f33a779527d6764b4fc4068267715a718c422cUlrich Drepper  { "eh-frame-hdr", ARGP_eh_frame_hdr, NULL, 0,
16254f33a779527d6764b4fc4068267715a718c422cUlrich Drepper    N_("Create .eh_frame_hdr section"), 0 },
1630e864dd86871c809668c557985ca19344dfff787Ulrich Drepper  { "hash-style", ARGP_hash_style, "STYLE", 0,
1640e864dd86871c809668c557985ca19344dfff787Ulrich Drepper    N_("Set hash style to sysv, gnu or both."), 0 },
16589759c76ee1e3231ee89d4aafed3a88772ce2245Ulrich Drepper  { "build-id", ARGP_build_id, "STYLE", OPTION_ARG_OPTIONAL,
166c54785af87adcac067f90b1dbc238c29062cf683Ulrich Drepper    N_("Generate build ID note (md5, sha1 (default), uuid)."), 0 },
16754f33a779527d6764b4fc4068267715a718c422cUlrich Drepper
168cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper  { NULL, 0, NULL, 0, N_("Linker Operation Control:"), 0 },
169cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper  { "verbose", 'v', NULL, 0, N_("Verbose messages."), 0 },
170cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper  { "trace", 't', NULL, 0, N_("Trace file opens."), 0 },
171cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper  { "conserve-memory", ARGP_conserve, NULL, 0,
172cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper    N_("Trade speed for less memory usage"), 0 },
173cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper  { NULL, 'O', N_("LEVEL"), OPTION_ARG_OPTIONAL,
174cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper    N_("Set optimization level to LEVEL."), 0 },
175cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper  { NULL, 'c', N_("FILE"), 0, N_("Use linker script in FILE."), 0 },
176b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#if YYDEBUG
177b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  { "yydebug", ARGP_yydebug, NULL, 0,
178b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    N_("Select to get parser debug information"), 0 },
179b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#endif
180cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper  { "version-script", ARGP_version_script, "FILE", 0,
181cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper    N_("Read version information from FILE."), 0 },
182cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper  { "emulation", 'm', "NAME", 0, N_("Set emulation to NAME."), 0 },
183b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
184b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  { NULL, 0, NULL, 0, NULL, 0 }
185b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper};
186b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
187b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Short description of program.  */
188b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic const char doc[] = N_("Combine object and archive files.");
189b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
190b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Strings for arguments in help texts.  */
191b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic const char args_doc[] = N_("[FILE]...");
192b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
193b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Prototype for option handler.  */
194b61c4cc4ab5d61d5d7c1a31e700bff8ad39fa079Ulrich Drepperstatic void replace_args (int argc, char *argv[]);
195b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic error_t parse_opt_1st (int key, char *arg, struct argp_state *state);
196b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic error_t parse_opt_2nd (int key, char *arg, struct argp_state *state);
197b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
198b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Data structure to communicate with argp functions.  */
199b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic struct argp argp_1st =
200b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
201b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  options, parse_opt_1st, args_doc, doc, NULL, NULL, NULL
202b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper};
203b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic struct argp argp_2nd =
204b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
205b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  options, parse_opt_2nd, args_doc, doc, NULL, NULL, NULL
206b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper};
207b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
208b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
209b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Linker state.  This contains all global information.  */
210b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstruct ld_state ld_state;
211b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
212b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* List of the input files.  */
213b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic struct file_list
214b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
215b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  const char *name;
216b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  struct file_list *next;
217b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} *input_file_list;
218b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
219b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* If nonzero be verbose.  */
220b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperint verbose;
221b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
222b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* If nonzero, trade speed for less memory/address space usage.  */
223b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperint conserve_memory;
224b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
225b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* The emulation name to use.  */
226b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic const char *emulation;
227b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
228b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Keep track of the nesting level.  Even though we don't handle nested
229b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper   groups we still keep track to improve the error messages.  */
230b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic int group_level;
231b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
232b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* The last file we processed.  */
233b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic struct usedfiles *last_file;
234b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
235b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* The default linker script.  */
236b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* XXX We'll do this a bit different in the real solution.  */
237b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic const char *linker_script = SRCDIR "/elf32-i386.script";
238b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
239b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Nonzero if an error occurred while loading the input files.  */
240b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic int error_loading;
241b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
242b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
243b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Intermediate storage for the LD_LIBRARY_PATH information from the
244b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper   environment.  */
245b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic char *ld_library_path1;
246b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
247b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Flag used to communicate with the scanner.  */
248b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperint ld_scan_version_script;
249b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
250b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Name of the input file.  */
251b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperconst char *ldin_fname;
252b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
253b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Define by parser if required.  */
254b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperextern int lddebug;
255b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
256b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
257b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Prototypes for local functions.  */
258b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void parse_z_option (const char *arg);
259b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void parse_z_option_2 (const char *arg);
260b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void parse_B_option (const char *arg);
261b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void parse_B_option_2 (const char *arg);
262b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void determine_output_format (void);
263b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void load_needed (void);
264b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void collect_sections (void);
265b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void add_rxxpath (struct pathelement **pathp, const char *str);
266b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void gen_rxxpath_data (void);
267b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void read_version_script (const char *fname);
268b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void create_lscript_symbols (void);
269b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void create_special_section_symbol (struct symbol **symp,
270b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper					   const char *name);
271b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
272b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
273b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperint
274b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppermain (int argc, char *argv[])
275b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
276b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  int remaining;
277b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  int err;
278b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
279b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Sanity check.  We always want to use the LFS functionality.  */
2803425454a10d307fae891fb667cf7969e945cde79Josh Stone  if (sizeof (off_t) != 8)
281b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    abort ();
282b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
283b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* We use no threads here which can interfere with handling a stream.  */
284b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  __fsetlocking (stdin, FSETLOCKING_BYCALLER);
285b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  __fsetlocking (stdout, FSETLOCKING_BYCALLER);
286b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  __fsetlocking (stderr, FSETLOCKING_BYCALLER);
287b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
288b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Set locale.  */
289b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  setlocale (LC_ALL, "");
290b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
291b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Make sure the message catalog can be found.  */
292b0243863149acde9e42b25688c7c2959830e69a9Ulrich Drepper  bindtextdomain (PACKAGE_TARNAME, LOCALEDIR);
293b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
294b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Initialize the message catalog.  */
295b0243863149acde9e42b25688c7c2959830e69a9Ulrich Drepper  textdomain (PACKAGE_TARNAME);
296b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
297b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Before we start tell the ELF library which version we are using.  */
298b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  elf_version (EV_CURRENT);
299b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
300b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* The user can use the LD_LIBRARY_PATH environment variable to add
301b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     additional lookup directories.  */
302b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  ld_library_path1 = getenv ("LD_LIBRARY_PATH");
303b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
304b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Initialize the memory handling.  */
305b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#define obstack_chunk_alloc xmalloc
306b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#define obstack_chunk_free free
307b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  obstack_init (&ld_state.smem);
308b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
309b61c4cc4ab5d61d5d7c1a31e700bff8ad39fa079Ulrich Drepper  /* Recognize old-style parameters for compatibility.  */
310b61c4cc4ab5d61d5d7c1a31e700bff8ad39fa079Ulrich Drepper  replace_args (argc, argv);
311b61c4cc4ab5d61d5d7c1a31e700bff8ad39fa079Ulrich Drepper
312b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* One quick pass over the parameters which allows us to scan for options
313b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     with global effect which influence the rest of the processing.  */
314b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  argp_parse (&argp_1st, argc, argv, ARGP_IN_ORDER, &remaining, NULL);
315b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
316b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* We need at least one input file.  */
317b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (input_file_list == NULL)
318b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
319b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      error (0, 0, gettext ("At least one input file needed"));
320b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      argp_help (&argp_1st, stderr, ARGP_HELP_SEE, "ld");
321b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      exit (EXIT_FAILURE);
322b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
323b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
324b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Determine which ELF backend to use.  */
325b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  determine_output_format ();
326b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
3270e864dd86871c809668c557985ca19344dfff787Ulrich Drepper  /* If no hash style was specific default to the oldand slow SysV
3280e864dd86871c809668c557985ca19344dfff787Ulrich Drepper     method.  */
3290e864dd86871c809668c557985ca19344dfff787Ulrich Drepper  if (unlikely (ld_state.hash_style == hash_style_none))
3300e864dd86871c809668c557985ca19344dfff787Ulrich Drepper    ld_state.hash_style = hash_style_sysv;
3310e864dd86871c809668c557985ca19344dfff787Ulrich Drepper
332b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Prepare state.  */
333b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  err = ld_prepare_state (emulation);
334b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (err != 0)
335b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    error (EXIT_FAILURE, 0, gettext ("error while preparing linking"));
336b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
337b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* XXX Read the linker script now.  Since we later will have the linker
338b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     script built in we don't go into trouble to make sure we handle GROUP
339b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     statements in the script.  This simply must not happen.  */
340b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  ldin = fopen (linker_script, "r");
341b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (ldin == NULL)
342e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper    error (EXIT_FAILURE, errno, gettext ("cannot open linker script '%s'"),
343b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	   linker_script);
344b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* No need for locking.  */
345b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  __fsetlocking (ldin, FSETLOCKING_BYCALLER);
346b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
347b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  ld_state.srcfiles = NULL;
348b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  ldlineno = 1;
349b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  ld_scan_version_script = 0;
350b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  ldin_fname = linker_script;
351b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (ldparse () != 0)
352b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    /* Something went wrong during parsing.  */
353b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    exit (EXIT_FAILURE);
354b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  fclose (ldin);
355b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
356b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* We now might have a list of directories to look for libraries in
357b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     named by the linker script.  Put them in a different list so that
358b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     they are searched after all paths given by the user on the
359b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     command line.  */
360b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  ld_state.default_paths = ld_state.paths;
361b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  ld_state.paths = ld_state.tailpaths = NULL;
362b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
363b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Get runpath/rpath information in usable form.  */
364b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  gen_rxxpath_data ();
365b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
366b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Parse and process arguments for real.  */
367b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  argp_parse (&argp_2nd, argc, argv, ARGP_IN_ORDER, &remaining, NULL);
368b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* All options should have been processed by the argp parser.  */
369b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  assert (remaining == argc);
370b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
371b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Process the last file.  */
372b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  while (last_file != NULL)
373b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    /* Try to open the file.  */
374b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    error_loading |= FILE_PROCESS (-1, last_file, &ld_state, &last_file);
375b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
376b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Stop if there has been a problem while reading the input files.  */
377b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (error_loading)
378b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    exit (error_loading);
379b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
380b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* See whether all opened -( were closed.  */
381b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (group_level > 0)
382b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
383b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      error (0, 0, gettext ("-( without matching -)"));
384b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      argp_help (&argp_1st, stderr, ARGP_HELP_SEE, "ld");
385b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      exit (EXIT_FAILURE);
386b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
387b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
388b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* When we create a relocatable file we don't have to look for the
389b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     DT_NEEDED DSOs and we also don't test for undefined symbols.  */
390b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (ld_state.file_type != relocatable_file_type)
391b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
392b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      /* At this point we have loaded all the direct dependencies.  What
393b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	 remains to be done is find the indirect dependencies.  These are
394b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	 DSOs which are referenced by the DT_NEEDED entries in the DSOs
395b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	 which are direct dependencies.  We have to transitively find and
396b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	 load all these dependencies.  */
397b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      load_needed ();
398b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
399b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      /* At this point all object files and DSOs are read.  If there
4003a64a3087f53ab860c7de04da0e53dabef459520Ulrich Drepper	 are still undefined symbols left they might have to be
4013a64a3087f53ab860c7de04da0e53dabef459520Ulrich Drepper	 synthesized from the linker script.  */
402b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      create_lscript_symbols ();
403b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
404b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      /* Now that we have loaded all the object files we can determine
405b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	 whether we have any non-weak unresolved references left.  If
406b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	 there are any we stop.  If the user used the '-z nodefs' option
407b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	 and we are creating a DSO don't perform the tests.  */
408b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (FLAG_UNRESOLVED (&ld_state) != 0)
409b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	exit (1);
410b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
411b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
412b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Collect information about the relocations which will be carried
413b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     forward into the output.  We have to do this here and now since
414b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     we need to know which sections have to be created.  */
415b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (ld_state.file_type != relocatable_file_type)
416b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
417b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      void *p ;
418b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      struct scnhead *h;
419b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
420b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      p = NULL;
421b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      while ((h = ld_section_tab_iterate (&ld_state.section_tab, &p)) != NULL)
422b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	if (h->type == SHT_REL || h->type == SHT_RELA)
423b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  {
424b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    struct scninfo *runp = h->last;
425b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    do
426b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      {
427b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		/* If we are processing the relocations determine how
428b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		   many will be in the output file.  Also determine
429b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		   how many GOT entries are needed.  */
430b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		COUNT_RELOCATIONS (&ld_state, runp);
431b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
432b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		ld_state.relsize_total += runp->relsize;
433b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      }
434b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    while ((runp = runp->next) != h->last);
435b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  }
436b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
437b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
438b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Not part of the gABI, but part of every psABI: the symbols for the
439b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     GOT section.  Add the symbol if necessary.  */
440b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (ld_state.need_got)
441b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    create_special_section_symbol (&ld_state.got_symbol,
442b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper				   "_GLOBAL_OFFSET_TABLE_");
443b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Similarly for the _DYNAMIC symbol which points to the dynamic
444b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     section.  */
445b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (dynamically_linked_p ())
446b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    create_special_section_symbol (&ld_state.dyn_symbol, "_DYNAMIC");
447b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
448b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* We are ready to start working on the output file.  Not all
449b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     information has been gather or created yet.  This will be done as
450b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     we go.  Open the file now.  */
451b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (OPEN_OUTFILE (&ld_state, EM_NONE, ELFCLASSNONE, ELFDATANONE) != 0)
452b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    exit (1);
453b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
454b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Create the sections which are generated by the linker and are not
455b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     present in the input file.  The output file must already have
456b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     been opened since we need the ELF descriptor to deduce type
457b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     sizes.  */
458b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  GENERATE_SECTIONS (&ld_state);
459b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
460b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* At this point we have read all the files and know all the
461b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     sections which have to be linked into the application.  We do now
462b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     create an array listing all the sections.  We will than pass this
463b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     array to a system specific function which can reorder it at will.
464b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     The functions can also merge sections if this is what is
465b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     wanted.  */
466b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  collect_sections ();
467b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
468b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Create the output sections now.  This may requires sorting them
469b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     first.  */
470b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  CREATE_SECTIONS (&ld_state);
471b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
472b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Create the output file data.  Appropriate code for the selected
473b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     output file type is called.  */
474b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (CREATE_OUTFILE (&ld_state) != 0)
475b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    exit (1);
476b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
477b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Finalize the output file, write the data out.  */
478b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  err |= FINALIZE (&ld_state);
479b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
480b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Return with an non-zero exit status also if any error message has
481b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     been printed.  */
482b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  return err | (error_message_count != 0);
483b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}
484b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
485b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
486b61c4cc4ab5d61d5d7c1a31e700bff8ad39fa079Ulrich Drepperstatic void
487b61c4cc4ab5d61d5d7c1a31e700bff8ad39fa079Ulrich Drepperreplace_args (int argc, char *argv[])
488b61c4cc4ab5d61d5d7c1a31e700bff8ad39fa079Ulrich Drepper{
489b61c4cc4ab5d61d5d7c1a31e700bff8ad39fa079Ulrich Drepper  static const struct
490b61c4cc4ab5d61d5d7c1a31e700bff8ad39fa079Ulrich Drepper  {
491b61c4cc4ab5d61d5d7c1a31e700bff8ad39fa079Ulrich Drepper    const char *from;
492b61c4cc4ab5d61d5d7c1a31e700bff8ad39fa079Ulrich Drepper    const char *to;
493b61c4cc4ab5d61d5d7c1a31e700bff8ad39fa079Ulrich Drepper  } args[] =
494b61c4cc4ab5d61d5d7c1a31e700bff8ad39fa079Ulrich Drepper      {
495b61c4cc4ab5d61d5d7c1a31e700bff8ad39fa079Ulrich Drepper	{ "-export-dynamic", "--export-dynamic" },
496834de6f38901b6add14b6f5f7dda8550638d98ecUlrich Drepper	{ "-dynamic-linker", "--dynamic-linker" },
497834de6f38901b6add14b6f5f7dda8550638d98ecUlrich Drepper	{ "-static", "--static" },
498b61c4cc4ab5d61d5d7c1a31e700bff8ad39fa079Ulrich Drepper      };
499b61c4cc4ab5d61d5d7c1a31e700bff8ad39fa079Ulrich Drepper  const size_t nargs = sizeof (args) / sizeof (args[0]);
500b61c4cc4ab5d61d5d7c1a31e700bff8ad39fa079Ulrich Drepper
501b61c4cc4ab5d61d5d7c1a31e700bff8ad39fa079Ulrich Drepper  for (int i = 1; i < argc; ++i)
5027cd1bf7b762f0b7d3b1158e52c800d299ed5333fUlrich Drepper    if (argv[i][0] == '-' && islower (argv[i][1]) && argv[i][2] != '\0')
503b61c4cc4ab5d61d5d7c1a31e700bff8ad39fa079Ulrich Drepper      for (size_t j = 0; j < nargs; ++j)
504b61c4cc4ab5d61d5d7c1a31e700bff8ad39fa079Ulrich Drepper	if (strcmp (argv[i], args[j].from) == 0)
505b61c4cc4ab5d61d5d7c1a31e700bff8ad39fa079Ulrich Drepper	  {
506b61c4cc4ab5d61d5d7c1a31e700bff8ad39fa079Ulrich Drepper	    argv[i] = (char *) args[j].to;
507b61c4cc4ab5d61d5d7c1a31e700bff8ad39fa079Ulrich Drepper	    break;
508b61c4cc4ab5d61d5d7c1a31e700bff8ad39fa079Ulrich Drepper	  }
509b61c4cc4ab5d61d5d7c1a31e700bff8ad39fa079Ulrich Drepper}
510b61c4cc4ab5d61d5d7c1a31e700bff8ad39fa079Ulrich Drepper
511b61c4cc4ab5d61d5d7c1a31e700bff8ad39fa079Ulrich Drepper
51289759c76ee1e3231ee89d4aafed3a88772ce2245Ulrich Drepperstatic int
51389759c76ee1e3231ee89d4aafed3a88772ce2245Ulrich Dreppervalid_hexarg (const char *arg)
51489759c76ee1e3231ee89d4aafed3a88772ce2245Ulrich Drepper{
51589759c76ee1e3231ee89d4aafed3a88772ce2245Ulrich Drepper  if (strncasecmp (arg, "0x", 2) != 0)
51689759c76ee1e3231ee89d4aafed3a88772ce2245Ulrich Drepper    return 0;
51789759c76ee1e3231ee89d4aafed3a88772ce2245Ulrich Drepper
51889759c76ee1e3231ee89d4aafed3a88772ce2245Ulrich Drepper  arg += 2;
51989759c76ee1e3231ee89d4aafed3a88772ce2245Ulrich Drepper  do
52089759c76ee1e3231ee89d4aafed3a88772ce2245Ulrich Drepper    {
52189759c76ee1e3231ee89d4aafed3a88772ce2245Ulrich Drepper      if (isxdigit (arg[0]) && isxdigit (arg[1]))
52289759c76ee1e3231ee89d4aafed3a88772ce2245Ulrich Drepper	{
52389759c76ee1e3231ee89d4aafed3a88772ce2245Ulrich Drepper	  arg += 2;
52489759c76ee1e3231ee89d4aafed3a88772ce2245Ulrich Drepper	  if (arg[0] == '-' || arg[0] == ':')
52589759c76ee1e3231ee89d4aafed3a88772ce2245Ulrich Drepper	    ++arg;
52689759c76ee1e3231ee89d4aafed3a88772ce2245Ulrich Drepper	}
52789759c76ee1e3231ee89d4aafed3a88772ce2245Ulrich Drepper      else
52889759c76ee1e3231ee89d4aafed3a88772ce2245Ulrich Drepper	return 0;
52989759c76ee1e3231ee89d4aafed3a88772ce2245Ulrich Drepper    }
53089759c76ee1e3231ee89d4aafed3a88772ce2245Ulrich Drepper  while (*arg != '\0');
53189759c76ee1e3231ee89d4aafed3a88772ce2245Ulrich Drepper
53289759c76ee1e3231ee89d4aafed3a88772ce2245Ulrich Drepper  return 1;
53389759c76ee1e3231ee89d4aafed3a88772ce2245Ulrich Drepper}
53489759c76ee1e3231ee89d4aafed3a88772ce2245Ulrich Drepper
53589759c76ee1e3231ee89d4aafed3a88772ce2245Ulrich Drepper
536b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Quick scan of the parameter list for options with global effect.  */
537b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic error_t
538b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperparse_opt_1st (int key, char *arg,
539b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	       struct argp_state *state __attribute__ ((unused)))
540b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
541b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  switch (key)
542b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
543b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case 'B':
544b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      parse_B_option (arg);
545b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      break;
546b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
547b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case 'c':
548b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      linker_script = arg;
549b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      break;
550b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
551b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case 'E':
552b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      ld_state.export_all_dynamic = true;
553b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      break;
554b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
555b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case 'G':
556b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (ld_state.file_type != no_file_type)
557b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	error (EXIT_FAILURE, 0,
558b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	       gettext ("only one option of -G and -r is allowed"));
559b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      ld_state.file_type = dso_file_type;
560b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
561b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      /* If we generate a DSO we have to export all symbols.  */
562b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      ld_state.export_all_dynamic = true;
563b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      break;
564b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
565b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case 'h':
566b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      ld_state.soname = arg;
567b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      break;
568b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
569b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case 'i':
570b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      /* Discard the LD_LIBRARY_PATH value we found.  */
571b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      ld_library_path1 = NULL;
572b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      break;
573b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
574b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case 'I':
575b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      ld_state.interp = arg;
576b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      break;
577b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
578b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case 'm':
579b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (emulation != NULL)
580b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	error (EXIT_FAILURE, 0, gettext ("more than one '-m' parameter"));
581b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      emulation = arg;
582b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      break;
583b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
584b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case 'Q':
585b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (arg[1] == '\0' && (arg[0] == 'y' || arg[0] == 'Y'))
586b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	ld_state.add_ld_comment = true;
587b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      else if (arg[1] == '\0' && (arg[0] == 'n' || arg[0] == 'N'))
588b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	ld_state.add_ld_comment = true;
589b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      else
590b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	error (EXIT_FAILURE, 0, gettext ("unknown option `-%c %s'"), 'Q', arg);
591b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      break;
592b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
593b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case 'r':
594b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (ld_state.file_type != no_file_type)
595b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	error (EXIT_FAILURE, 0,
596b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	       gettext ("only one option of -G and -r is allowed"));
597b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      ld_state.file_type = relocatable_file_type;
598b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      break;
599b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
600b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case 'S':
601b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      ld_state.strip = strip_debug;
602b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      break;
603b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
604b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case 't':
605b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      ld_state.trace_files = true;
606b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      break;
607b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
608b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case 'v':
609b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      verbose = 1;
610b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      break;
611b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
612b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case 'z':
613b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      /* The SysV linker used 'z' to pass various flags to the linker.
614b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	 We follow this.  See 'parse_z_option' for the options we
615b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	 recognize.  */
616b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      parse_z_option (arg);
617b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      break;
618b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
619b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case ARGP_pagesize:
620b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      {
621b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	char *endp;
622b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	ld_state.pagesize = strtoul (arg, &endp, 0);
623b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	if (*endp != '\0')
624b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  {
625b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    if (endp[1] == '\0' && tolower (*endp) == 'k')
626b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      ld_state.pagesize *= 1024;
627b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    else if (endp[1] == '\0' && tolower (*endp) == 'm')
628b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      ld_state.pagesize *= 1024 * 1024;
629b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    else
630b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      {
631b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		error (0, 0,
632e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper		       gettext ("invalid page size value '%s': ignored"),
633b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		       arg);
634b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		ld_state.pagesize = 0;
635b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      }
636b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  }
637b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      }
638b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      break;
639b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
640cbb51e5253e05d98af8bdaf2217fed00b2e489b9Ulrich Drepper    case 'R':
641b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      add_rxxpath (&ld_state.rpath, arg);
642b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      break;
643b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
644b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case ARGP_rpath_link:
645b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      add_rxxpath (&ld_state.rpath_link, arg);
646b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      break;
647b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
648b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case ARGP_runpath:
649b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      add_rxxpath (&ld_state.runpath, arg);
650b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      break;
651b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
652b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case ARGP_runpath_link:
653b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      add_rxxpath (&ld_state.runpath_link, arg);
654b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      break;
655b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
656b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case ARGP_gc_sections:
657b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case ARGP_no_gc_sections:
658b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      ld_state.gc_sections = key == ARGP_gc_sections;
659b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      break;
660b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
66154f33a779527d6764b4fc4068267715a718c422cUlrich Drepper    case ARGP_eh_frame_hdr:
66254f33a779527d6764b4fc4068267715a718c422cUlrich Drepper      ld_state.eh_frame_hdr = true;
66354f33a779527d6764b4fc4068267715a718c422cUlrich Drepper      break;
66454f33a779527d6764b4fc4068267715a718c422cUlrich Drepper
6650e864dd86871c809668c557985ca19344dfff787Ulrich Drepper    case ARGP_hash_style:
6660e864dd86871c809668c557985ca19344dfff787Ulrich Drepper      if (strcmp (arg, "gnu") == 0)
6670e864dd86871c809668c557985ca19344dfff787Ulrich Drepper	ld_state.hash_style = hash_style_gnu;
6680e864dd86871c809668c557985ca19344dfff787Ulrich Drepper      else if (strcmp (arg, "both") == 0)
6690e864dd86871c809668c557985ca19344dfff787Ulrich Drepper	ld_state.hash_style = hash_style_gnu | hash_style_sysv;
6700e864dd86871c809668c557985ca19344dfff787Ulrich Drepper      else if (strcmp (arg, "sysv") == 0)
6710e864dd86871c809668c557985ca19344dfff787Ulrich Drepper	ld_state.hash_style = hash_style_sysv;
6720e864dd86871c809668c557985ca19344dfff787Ulrich Drepper      else
6730e864dd86871c809668c557985ca19344dfff787Ulrich Drepper	error (EXIT_FAILURE, 0, gettext ("invalid hash style '%s'"), arg);
6740e864dd86871c809668c557985ca19344dfff787Ulrich Drepper      break;
6750e864dd86871c809668c557985ca19344dfff787Ulrich Drepper
67689759c76ee1e3231ee89d4aafed3a88772ce2245Ulrich Drepper    case ARGP_build_id:
67789759c76ee1e3231ee89d4aafed3a88772ce2245Ulrich Drepper      if (arg == NULL)
678c54785af87adcac067f90b1dbc238c29062cf683Ulrich Drepper	ld_state.build_id = "sha1";
67989759c76ee1e3231ee89d4aafed3a88772ce2245Ulrich Drepper      else if (strcmp (arg, "uuid") != 0
68089759c76ee1e3231ee89d4aafed3a88772ce2245Ulrich Drepper	       && strcmp (arg, "md5") != 0
681c54785af87adcac067f90b1dbc238c29062cf683Ulrich Drepper	       && strcmp (arg, "sha1") != 0
68289759c76ee1e3231ee89d4aafed3a88772ce2245Ulrich Drepper	       && !valid_hexarg (arg))
68389759c76ee1e3231ee89d4aafed3a88772ce2245Ulrich Drepper	error (EXIT_FAILURE, 0, gettext ("invalid build-ID style '%s'"), arg);
68489759c76ee1e3231ee89d4aafed3a88772ce2245Ulrich Drepper      else
68589759c76ee1e3231ee89d4aafed3a88772ce2245Ulrich Drepper	ld_state.build_id = arg;
68689759c76ee1e3231ee89d4aafed3a88772ce2245Ulrich Drepper      break;
68789759c76ee1e3231ee89d4aafed3a88772ce2245Ulrich Drepper
688b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case 's':
689b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (arg == NULL)
690b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	{
691b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  if (ld_state.strip == strip_all)
692b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    ld_state.strip = strip_everything;
693b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  else
694b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    ld_state.strip = strip_all;
695b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  break;
696b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	}
697b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      /* FALLTHROUGH */
698b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
699b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case 'e':
700b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case 'o':
701b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case 'O':
702b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case ARGP_whole_archive:
703b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case ARGP_no_whole_archive:
7048c56fe3b2c753234beb6f58a81c8b96f008226efUlrich Drepper    case ARGP_as_needed:
7058c56fe3b2c753234beb6f58a81c8b96f008226efUlrich Drepper    case ARGP_no_as_needed:
706b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case 'L':
707b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case '(':
708b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case ')':
709b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case 'l':
710b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case ARGP_static:
711b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case ARGP_dynamic:
712b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case ARGP_version_script:
713b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      /* We'll handle these in the second pass.  */
714b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      break;
715b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
716b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case ARGP_KEY_ARG:
717b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      {
718b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	struct file_list *newp;
719b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
720b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	newp = (struct file_list *) xmalloc (sizeof (struct file_list));
721b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	newp->name = arg;
722b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#ifndef NDEBUG
723b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	newp->next = NULL;
724b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#endif
725b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	CSNGL_LIST_ADD_REAR (input_file_list, newp);
726b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      }
727b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      break;
728b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
729b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#if YYDEBUG
730b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case ARGP_yydebug:
731b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      lddebug = 1;
732b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      break;
733b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#endif
734b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
735b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case ARGP_no_undefined:
736b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      ld_state.nodefs = false;
737b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      break;
738b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
739b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case ARGP_conserve:
740b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      conserve_memory = 1;
741b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      break;
742b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
743b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    default:
744b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      return ARGP_ERR_UNKNOWN;
745b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
746b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  return 0;
747b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}
748b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
749b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
750b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Handle program arguments for real.  */
751b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic error_t
752b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperparse_opt_2nd (int key, char *arg,
753b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	       struct argp_state *state __attribute__ ((unused)))
754b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
755b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  static bool group_start_requested;
756b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  static bool group_end_requested;
757b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
758b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  switch (key)
759b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
760b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case 'B':
761b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      parse_B_option_2 (arg);
762b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      break;
763b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
764b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case 'e':
765b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      ld_state.entry = arg;
766b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      break;
767b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
768b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case 'o':
769b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (ld_state.outfname != NULL)
770b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	{
771b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  error (0, 0, gettext ("More than one output file name given."));
772b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	see_help:
773b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  argp_help (&argp_2nd, stderr, ARGP_HELP_SEE, "ld");
774b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  exit (EXIT_FAILURE);
775b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	}
776b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      ld_state.outfname = arg;
777b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      break;
778b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
779b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case 'O':
780b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (arg == NULL)
781b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	ld_state.optlevel = 1;
782b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      else
783b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	{
784b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  char *endp;
785b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  unsigned long int level = strtoul (arg, &endp, 10);
786b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  if (*endp != '\0')
787b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    {
788b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      error (0, 0, gettext ("Invalid optimization level `%s'"), arg);
789b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      goto see_help;
790b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    }
791b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  ld_state.optlevel = level;
792b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	}
793b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      break;
794b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
795b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case ARGP_whole_archive:
796b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      ld_state.extract_rule = allextract;
797b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      break;
798b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case ARGP_no_whole_archive:
799b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      ld_state.extract_rule = defaultextract;
800b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      break;
801b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
8028c56fe3b2c753234beb6f58a81c8b96f008226efUlrich Drepper    case ARGP_as_needed:
8038c56fe3b2c753234beb6f58a81c8b96f008226efUlrich Drepper      ld_state.as_needed = true;
8048c56fe3b2c753234beb6f58a81c8b96f008226efUlrich Drepper      break;
8058c56fe3b2c753234beb6f58a81c8b96f008226efUlrich Drepper    case ARGP_no_as_needed:
8068c56fe3b2c753234beb6f58a81c8b96f008226efUlrich Drepper      ld_state.as_needed = false;
8078c56fe3b2c753234beb6f58a81c8b96f008226efUlrich Drepper      break;
8088c56fe3b2c753234beb6f58a81c8b96f008226efUlrich Drepper
809b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case ARGP_static:
810b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case ARGP_dynamic:
811b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      /* Enable/disable use for DSOs.  */
812b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      ld_state.statically = key == ARGP_static;
813b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      break;
814b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
815b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case 'z':
816b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      /* The SysV linker used 'z' to pass various flags to the linker.
817b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	 We follow this.  See 'parse_z_option' for the options we
818b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	 recognize.  */
819b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      parse_z_option_2 (arg);
820b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      break;
821b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
822b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case ARGP_version_script:
823b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      read_version_script (arg);
824b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      break;
825b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
826b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case 'L':
827b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      /* Add a new search directory.  */
828b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      ld_new_searchdir (arg);
829b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      break;
830b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
831b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case '(':
832b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      /* Start a link group.  We have to be able to determine the object
833b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	 file which is named next.  Do this by remembering a pointer to
834b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	 the pointer which will point to the next object.  */
835b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (verbose && (group_start_requested || !group_end_requested))
836b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	error (0, 0, gettext ("nested -( -) groups are not allowed"));
837b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
838b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      /* Increment the nesting level.  */
839b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      ++group_level;
840b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
841b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      /* Record group start.  */
842b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      group_start_requested = true;
843b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      group_end_requested = false;
844b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      break;
845b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
846b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case ')':
847b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      /* End a link group.  If there is no group open this is clearly
848b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	 a bug.  If there is a group open insert a back reference
849b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	 pointer in the record for the last object of the group.  If
850b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	 there is no new object or just one don't do anything.  */
851b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (!group_end_requested)
852b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	{
853b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  if (group_level == 0)
854b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    {
855b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      error (0, 0, gettext ("-) without matching -("));
856b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      goto see_help;
857b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    }
858b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	}
859b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      else
860b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	last_file->group_end = true;
861b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
862b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (group_level > 0)
863b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	--group_level;
864b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      break;
865b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
866b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case 'l':
867b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    case ARGP_KEY_ARG:
868b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      {
869b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	while (last_file != NULL)
870b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  /* Try to open the file.  */
871b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  error_loading |= FILE_PROCESS (-1, last_file, &ld_state, &last_file);
872b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
873b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	last_file = ld_new_inputfile (arg,
874b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper				      key == 'l'
875b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper				      ? archive_file_type
876b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper				      : relocatable_file_type);
877b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	if (group_start_requested)
878b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  {
879b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    last_file->group_start = true;
880b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
881b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    group_start_requested = false;
882b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    group_end_requested = true;
883b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  }
884b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      }
885b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      break;
886b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
887b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    default:
888b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      /* We can catch all other options here.  They either have
889b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	 already been handled or, if the parameter was not correct,
890b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	 the error has been reported.  */
891b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      break;
892b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
893b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  return 0;
894b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}
895b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
896b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
897b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Load all the DSOs named as dependencies in other DSOs we already
898b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper   loaded.  */
899b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void
900b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperload_needed (void)
901b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
902b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  struct usedfiles *first;
903b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  struct usedfiles *runp;
904b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
905b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* XXX There is one problem here: do we allow references from
906b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     regular object files to be satisfied by these implicit
907b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     dependencies?  The old linker allows this and several libraries
908b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     depend on this.  Solaris' linker does not allow this; it provides
909b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     the user with a comprehensive error message explaining the
910b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     situation.
911b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
912b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     XXX IMO the old ld behavior is correct since this is also how the
913b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     dynamic linker will work.  It will look for unresolved references
914b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     in all loaded DSOs.
915b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
916b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     XXX Should we add an option to get Solaris compatibility?  */
917b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (ld_state.needed == NULL)
918b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    return;
919b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
920b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  runp = first = ld_state.needed->next;
921b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  do
922b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
923b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      struct usedfiles *ignore;
924b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      struct usedfiles *next = runp->next;
925b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      int err;
926b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
927b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      err = FILE_PROCESS (-1, runp, &ld_state, &ignore);
928b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (err != 0)
929b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	/* Something went wrong.  */
930b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	exit (err);
931b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
932b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      runp = next;
933b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
934b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  while (runp != first);
935b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}
936b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
937b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
938b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Print the version information.  */
939b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void
940b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperprint_version (FILE *stream, struct argp_state *state __attribute__ ((unused)))
941b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
942b0243863149acde9e42b25688c7c2959830e69a9Ulrich Drepper  fprintf (stream, "ld (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION);
943b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  fprintf (stream, gettext ("\
944b08d5a8fb42f4586d756068065186b5af7e48daUlrich DrepperCopyright (C) %s Red Hat, Inc.\n\
945b08d5a8fb42f4586d756068065186b5af7e48daUlrich DrepperThis is free software; see the source for copying conditions.  There is NO\n\
946b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperwarranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
9473a64a3087f53ab860c7de04da0e53dabef459520Ulrich Drepper"), "2012");
948b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper");
949b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}
950b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
951b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
952b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* There are a lot of -z options, parse them here.  Some of them have
953b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper   to be parsed in the first pass, others must be handled in the
954b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper   second pass.  */
955b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void
956b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperparse_z_option (const char *arg)
957b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
958b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (strcmp (arg, "nodefaultlib") == 0
959b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      /* This is only meaningful if we create a DSO.  */
960b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      && ld_state.file_type == dso_file_type)
961b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    ld_state.dt_flags_1 |= DF_1_NODEFLIB;
962b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  else if (strcmp (arg, "muldefs") == 0)
963b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    ld_state.muldefs = true;
964b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  else if (strcmp (arg, "nodefs") == 0)
965b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    ld_state.nodefs = true;
966b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  else if (strcmp (arg, "defs") == 0)
967b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    ld_state.nodefs = false;
968b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  else if (strcmp (arg, "now") == 0)
969b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    /* We could also set the DF_1_NOW flag in DT_FLAGS_1 but this isn't
970b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper       necessary.  */
971b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    ld_state.dt_flags |= DF_BIND_NOW;
972b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  else if (strcmp (arg, "origin") == 0)
973b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    /* We could also set the DF_1_ORIGIN flag in DT_FLAGS_1 but this isn't
974b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper       necessary.  */
975b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    ld_state.dt_flags |= DF_ORIGIN;
976b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  else if (strcmp (arg, "nodelete") == 0
977b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	   /* This is only meaningful if we create a DSO.  */
978b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	   && ld_state.file_type == dso_file_type)
979b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    ld_state.dt_flags_1 |= DF_1_NODELETE;
980b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  else if (strcmp (arg, "initfirst") == 0)
981b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    ld_state.dt_flags_1 |= DF_1_INITFIRST;
982b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  else if (strcmp (arg, "nodlopen") == 0
983b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	   /* This is only meaningful if we create a DSO.  */
984b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	   && ld_state.file_type == dso_file_type)
985b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    ld_state.dt_flags_1 |= DF_1_NOOPEN;
986b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  else if (strcmp (arg, "systemlibrary") == 0)
987b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    ld_state.is_system_library = true;
9882d88028a7b30d9e9be8e5af089cd6dcc22f80ce1Ulrich Drepper  else if (strcmp (arg, "execstack") == 0)
9892d88028a7b30d9e9be8e5af089cd6dcc22f80ce1Ulrich Drepper    ld_state.execstack = execstack_true;
9902d88028a7b30d9e9be8e5af089cd6dcc22f80ce1Ulrich Drepper  else if (strcmp (arg, "noexecstack") == 0)
9912d88028a7b30d9e9be8e5af089cd6dcc22f80ce1Ulrich Drepper    ld_state.execstack = execstack_false_force;
992b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  else if (strcmp (arg, "allextract") != 0
993b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	   && strcmp (arg, "defaultextract") != 0
994b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	   && strcmp (arg, "weakextract") != 0
995b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	   && strcmp (arg, "lazyload") != 0
9964f0a7a89be199fa86d9c5c7a56f4be9c5cfb2a4eUlrich Drepper	   && strcmp (arg, "nolazyload") != 0
9974f0a7a89be199fa86d9c5c7a56f4be9c5cfb2a4eUlrich Drepper	   && strcmp (arg, "ignore") != 0
9984f0a7a89be199fa86d9c5c7a56f4be9c5cfb2a4eUlrich Drepper	   && strcmp (arg, "record") != 0)
999b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    error (0, 0, gettext ("unknown option `-%c %s'"), 'z', arg);
1000b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}
1001b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1002b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1003b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void
1004b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperparse_z_option_2 (const char *arg)
1005b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
1006b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (strcmp (arg, "allextract") == 0)
1007b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    ld_state.extract_rule = allextract;
1008b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  else if (strcmp (arg, "defaultextract") == 0)
1009b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    ld_state.extract_rule = defaultextract;
1010b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  else if (strcmp (arg, "weakextract") == 0)
1011b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    ld_state.extract_rule = weakextract;
1012b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  else if (strcmp (arg, "lazyload") == 0)
1013b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    ld_state.lazyload = true;
1014b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  else if (strcmp (arg, "nolazyload") == 0)
1015b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    ld_state.lazyload = false;
10164f0a7a89be199fa86d9c5c7a56f4be9c5cfb2a4eUlrich Drepper  else if (strcmp (arg, "ignore") == 0)
10174f0a7a89be199fa86d9c5c7a56f4be9c5cfb2a4eUlrich Drepper    ld_state.as_needed = true;
10184f0a7a89be199fa86d9c5c7a56f4be9c5cfb2a4eUlrich Drepper  else if (strcmp (arg, "record") == 0)
10194f0a7a89be199fa86d9c5c7a56f4be9c5cfb2a4eUlrich Drepper    ld_state.as_needed = false;
1020b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}
1021b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1022b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1023b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* There are a lot of -B options, parse them here.  */
1024b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void
1025b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperparse_B_option (const char *arg)
1026b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
1027b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (strcmp (arg, "local") == 0)
1028b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    ld_state.default_bind_local = true;
1029b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  else if (strcmp (arg, "symbolic") != 0
1030b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	   && strcmp (arg, "static") != 0
1031b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	   && strcmp (arg, "dynamic") != 0)
1032b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    error (0, 0, gettext ("unknown option '-%c %s'"), 'B', arg);
1033b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}
1034b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1035b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1036b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* The same functionality, but called in the second pass over the
1037b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper   parameters.  */
1038b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void
1039b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperparse_B_option_2 (const char *arg)
1040b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
1041b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (strcmp (arg, "static") == 0)
1042b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    ld_state.statically = true;
1043b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  else if (strcmp (arg, "dynamic") == 0)
1044b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    ld_state.statically = false;
1045b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  else if (strcmp (arg, "symbolic") == 0
1046b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	   /* This is only meaningful if we create a DSO.  */
1047b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	   && ld_state.file_type == dso_file_type)
1048b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    ld_state.dt_flags |= DF_SYMBOLIC;
1049b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}
1050b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1051b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
105257fa86e08bdd901c0b42cc97947e620334f6ef68Chih-Hung Hsiehstatic inline int
105357fa86e08bdd901c0b42cc97947e620334f6ef68Chih-Hung Hsiehtry (int fd, Elf *elf)
105457fa86e08bdd901c0b42cc97947e620334f6ef68Chih-Hung Hsieh{
105557fa86e08bdd901c0b42cc97947e620334f6ef68Chih-Hung Hsieh  int result = 0;
105657fa86e08bdd901c0b42cc97947e620334f6ef68Chih-Hung Hsieh
105757fa86e08bdd901c0b42cc97947e620334f6ef68Chih-Hung Hsieh  if (elf == NULL)
105857fa86e08bdd901c0b42cc97947e620334f6ef68Chih-Hung Hsieh    return 0;
105957fa86e08bdd901c0b42cc97947e620334f6ef68Chih-Hung Hsieh
106057fa86e08bdd901c0b42cc97947e620334f6ef68Chih-Hung Hsieh  if (elf_kind (elf) == ELF_K_ELF)
106157fa86e08bdd901c0b42cc97947e620334f6ef68Chih-Hung Hsieh    {
106257fa86e08bdd901c0b42cc97947e620334f6ef68Chih-Hung Hsieh      /* We have an ELF file.  We now can find out
106357fa86e08bdd901c0b42cc97947e620334f6ef68Chih-Hung Hsieh	 what the output format should be.  */
106457fa86e08bdd901c0b42cc97947e620334f6ef68Chih-Hung Hsieh      XElf_Ehdr_vardef(ehdr);
106557fa86e08bdd901c0b42cc97947e620334f6ef68Chih-Hung Hsieh
106657fa86e08bdd901c0b42cc97947e620334f6ef68Chih-Hung Hsieh      /* Get the ELF header of the object.  */
106757fa86e08bdd901c0b42cc97947e620334f6ef68Chih-Hung Hsieh      xelf_getehdr (elf, ehdr);
106857fa86e08bdd901c0b42cc97947e620334f6ef68Chih-Hung Hsieh      if (ehdr != NULL)
106957fa86e08bdd901c0b42cc97947e620334f6ef68Chih-Hung Hsieh	ld_state.ebl =
107057fa86e08bdd901c0b42cc97947e620334f6ef68Chih-Hung Hsieh	  ebl_openbackend_machine (ehdr->e_machine);
107157fa86e08bdd901c0b42cc97947e620334f6ef68Chih-Hung Hsieh
107257fa86e08bdd901c0b42cc97947e620334f6ef68Chih-Hung Hsieh      result = 1;
107357fa86e08bdd901c0b42cc97947e620334f6ef68Chih-Hung Hsieh    }
107457fa86e08bdd901c0b42cc97947e620334f6ef68Chih-Hung Hsieh  else if (elf_kind (elf) == ELF_K_AR)
107557fa86e08bdd901c0b42cc97947e620334f6ef68Chih-Hung Hsieh    {
107657fa86e08bdd901c0b42cc97947e620334f6ef68Chih-Hung Hsieh      /* Try the archive members.  This could
107757fa86e08bdd901c0b42cc97947e620334f6ef68Chih-Hung Hsieh	 potentially lead to wrong results if the
107857fa86e08bdd901c0b42cc97947e620334f6ef68Chih-Hung Hsieh	 archive contains files for more than one
107957fa86e08bdd901c0b42cc97947e620334f6ef68Chih-Hung Hsieh	 architecture.  But this is the user's
108057fa86e08bdd901c0b42cc97947e620334f6ef68Chih-Hung Hsieh	 problem.  */
108157fa86e08bdd901c0b42cc97947e620334f6ef68Chih-Hung Hsieh      Elf *subelf;
108257fa86e08bdd901c0b42cc97947e620334f6ef68Chih-Hung Hsieh      Elf_Cmd cmd = ELF_C_READ_MMAP;
108357fa86e08bdd901c0b42cc97947e620334f6ef68Chih-Hung Hsieh
108457fa86e08bdd901c0b42cc97947e620334f6ef68Chih-Hung Hsieh      while ((subelf = elf_begin (fd, cmd, elf)) != NULL)
108557fa86e08bdd901c0b42cc97947e620334f6ef68Chih-Hung Hsieh	{
108657fa86e08bdd901c0b42cc97947e620334f6ef68Chih-Hung Hsieh	  cmd = elf_next (subelf);
108757fa86e08bdd901c0b42cc97947e620334f6ef68Chih-Hung Hsieh
108857fa86e08bdd901c0b42cc97947e620334f6ef68Chih-Hung Hsieh	  if (try (fd, subelf) != 0)
108957fa86e08bdd901c0b42cc97947e620334f6ef68Chih-Hung Hsieh	    break;
109057fa86e08bdd901c0b42cc97947e620334f6ef68Chih-Hung Hsieh	}
109157fa86e08bdd901c0b42cc97947e620334f6ef68Chih-Hung Hsieh    }
109257fa86e08bdd901c0b42cc97947e620334f6ef68Chih-Hung Hsieh
109357fa86e08bdd901c0b42cc97947e620334f6ef68Chih-Hung Hsieh  elf_end (elf);
109457fa86e08bdd901c0b42cc97947e620334f6ef68Chih-Hung Hsieh
109557fa86e08bdd901c0b42cc97947e620334f6ef68Chih-Hung Hsieh  return result;
109657fa86e08bdd901c0b42cc97947e620334f6ef68Chih-Hung Hsieh}
109757fa86e08bdd901c0b42cc97947e620334f6ef68Chih-Hung Hsieh
109857fa86e08bdd901c0b42cc97947e620334f6ef68Chih-Hung Hsieh
1099b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void
1100b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperdetermine_output_format (void)
1101b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
1102b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* First change the 'input_file_list' variable in a simple
1103b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     single-linked list.  */
1104b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  struct file_list *last = input_file_list;
1105b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  input_file_list = input_file_list->next;
1106b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  last->next = NULL;
1107b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1108b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Determine the target configuration which we are supposed to use.
1109b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     The user can use the '-m' option to select one.  If this is
1110b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     missing we are trying to load one file and determine the
1111b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     architecture from that.  */
1112b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (emulation != NULL)
1113b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
1114b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      ld_state.ebl = ebl_openbackend_emulation (emulation);
1115b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1116b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      assert (ld_state.ebl != NULL);
1117b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
1118b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  else
1119b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
1120b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      /* Find an ELF input file and let it determine the ELf backend.  */
1121b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      struct file_list *runp = input_file_list;
1122b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1123b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      while (runp != NULL)
1124b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	{
1125b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  int fd = open (runp->name, O_RDONLY);
1126b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  if (fd != -1)
1127b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    {
112857fa86e08bdd901c0b42cc97947e620334f6ef68Chih-Hung Hsieh	      if (try (fd, elf_begin (fd, ELF_C_READ_MMAP, NULL)) != 0)
1129b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		/* Found a file.  */
1130b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		break;
1131b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    }
1132b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1133b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  runp = runp->next;
1134b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	}
1135b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1136b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (ld_state.ebl == NULL)
1137b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	{
1138b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  error (0, 0, gettext ("\
1139b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppercould not find input file to determine output file format"));
1140b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  error (EXIT_FAILURE, 0, gettext ("\
1141b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppertry again with an appropriate '-m' parameter"));
1142b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	}
1143b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
1144b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1145b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* We don't need the list of input files anymore.  The second run over
1146b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     the parameters will handle them.  */
1147b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  while (input_file_list != NULL)
1148b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
1149b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      struct file_list *oldp = input_file_list;
1150b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      input_file_list = input_file_list->next;
1151b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      free (oldp);
1152b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
1153b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1154b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* We also know now what kind of file we are supposed to create.  If
1155b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     the user hasn't selected anythign we create and executable.  */
1156b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (ld_state.file_type == no_file_type)
1157b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    ld_state.file_type = executable_file_type;
1158b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}
1159b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1160b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Add DIR to the list of directories searched for object files and
1161b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper   libraries.  */
1162b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppervoid
1163b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperld_new_searchdir (const char *dir)
1164b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
1165b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  struct pathelement *newpath;
1166b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1167b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  newpath = (struct pathelement *)
1168b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    obstack_calloc (&ld_state.smem, sizeof (struct pathelement));
1169b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1170b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  newpath->pname = dir;
1171b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1172b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Enqueue the file.  */
1173b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (ld_state.tailpaths == NULL)
117487cf5834841d0d85277234138b53aba032015ca8Ulrich Drepper    ld_state.paths = ld_state.tailpaths = newpath->next = newpath;
1175b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  else
1176b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
1177b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      ld_state.tailpaths->next = newpath;
1178b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      ld_state.tailpaths = newpath;
117987cf5834841d0d85277234138b53aba032015ca8Ulrich Drepper      newpath->next = ld_state.paths;
1180b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
1181b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}
1182b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1183b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1184b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstruct usedfiles *
1185b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperld_new_inputfile (const char *fname, enum file_type type)
1186b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
1187b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  struct usedfiles *newfile = (struct usedfiles *)
1188b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    obstack_calloc (&ld_state.smem, sizeof (struct usedfiles));
1189b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1190b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  newfile->soname = newfile->fname = newfile->rfname = fname;
1191b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  newfile->file_type = type;
1192b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  newfile->extract_rule = ld_state.extract_rule;
11938c56fe3b2c753234beb6f58a81c8b96f008226efUlrich Drepper  newfile->as_needed = ld_state.as_needed;
1194b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  newfile->lazyload = ld_state.lazyload;
1195b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  newfile->status = not_opened;
1196b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1197b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  return newfile;
1198b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}
1199b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1200b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1201b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Create an array listing all the sections.  We will than pass this
1202b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper   array to a system specific function which can reorder it at will.
1203b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper   The functions can also merge sections if this is what is
1204b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper   wanted.  */
1205b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void
1206b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppercollect_sections (void)
1207b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
1208b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  void *p ;
1209b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  struct scnhead *h;
1210b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  size_t cnt;
1211b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1212b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* We have that many sections.  At least for now.  */
1213b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  ld_state.nallsections = ld_state.section_tab.filled;
1214b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1215b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Allocate the array.  We allocate one more entry than computed so
1216b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     far since we might need a new section for the copy relocations.  */
1217b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  ld_state.allsections =
1218b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    (struct scnhead **) obstack_alloc (&ld_state.smem,
1219b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper				       (ld_state.nallsections + 1)
1220b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper				       * sizeof (struct scnhead *));
1221b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1222b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Fill the array.  We rely here on the hash table iterator to
1223b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     return the entries in the order they were added.  */
1224b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  cnt = 0;
1225b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  p = NULL;
1226b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  while ((h = ld_section_tab_iterate (&ld_state.section_tab, &p)) != NULL)
1227b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
1228b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      struct scninfo *runp;
1229b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      bool used = false;
1230b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1231b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (h->kind == scn_normal)
1232b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	{
1233b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  runp = h->last;
1234b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  do
1235b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    {
1236b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      if (h->type == SHT_REL || h->type == SHT_RELA)
1237b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		{
1238b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		  if (runp->used)
1239b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		    /* This is a relocation section.  If the section
1240b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		       it is relocating is used in the result so must
1241b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		       the relocation section.  */
1242b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		    runp->used
1243b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		      = runp->fileinfo->scninfo[SCNINFO_SHDR (runp->shdr).sh_info].used;
1244b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		}
1245b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1246b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      /* Accumulate the result.  */
1247b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      used |= runp->used;
1248b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1249b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      /* Next input section.  */
1250b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      runp = runp->next;
1251b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    }
1252b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  while (runp != h->last);
1253b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1254b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  h->used = used;
1255b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	}
1256b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1257b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      ld_state.allsections[cnt++] = h;
1258b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
1259b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  ld_state.nusedsections = cnt;
1260b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1261b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  assert (cnt == ld_state.nallsections);
1262b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}
1263b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1264b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1265b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Add given path to the end of list.  */
1266b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void
1267b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperadd_rxxpath (struct pathelement **pathp, const char *str)
1268b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
1269b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  struct pathelement *newp;
1270b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1271b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* The path elements can in theory be freed after we read all the
1272b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     files.  But the amount of memory we are talking about is small
1273b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     and the cost of free() calls is not neglectable.  */
1274b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  newp = (struct pathelement *) obstack_alloc (&ld_state.smem, sizeof (*newp));
1275b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  newp->pname = str;
1276b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  newp->exist = 0;
1277b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#ifndef NDEBUG
1278b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  newp->next = NULL;
1279b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#endif
1280b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1281b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  CSNGL_LIST_ADD_REAR (*pathp, newp);
1282b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}
1283b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1284b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1285b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Convert lists of possibly colon-separated directory lists into lists
1286b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper   where each entry is for a single directory.  */
1287b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void
1288b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppernormalize_dirlist (struct pathelement **pathp)
1289b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
1290b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  struct pathelement *firstp = *pathp;
1291b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1292b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  do
1293b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
1294b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      const char *pname = (*pathp)->pname;
1295b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      const char *colonp = strchrnul (pname, ':');
1296b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1297b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (colonp != NULL)
1298b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	{
1299b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  struct pathelement *lastp = *pathp;
1300b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  struct pathelement *newp;
1301b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1302b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  while (1)
1303b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    {
1304b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      if (colonp == pname)
1305b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		lastp->pname = ".";
1306b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      else
1307b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		lastp->pname = obstack_strndup (&ld_state.smem, pname,
1308b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper						colonp - pname);
1309b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1310b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      if (*colonp == '\0')
1311b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		break;
1312b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      pname = colonp + 1;
1313b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1314b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      newp = (struct pathelement *) obstack_alloc (&ld_state.smem,
1315b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper							   sizeof (*newp));
1316b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      newp->next = lastp->next;
1317b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      newp->exist = 0;
1318b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      lastp = lastp->next = newp;
1319b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1320b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      colonp = strchrnul (pname, ':');
1321b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    }
1322b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1323b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  pathp = &lastp->next;
1324b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	}
1325b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      else
1326b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	pathp = &(*pathp)->next;
1327b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
1328b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  while (*pathp != firstp);
1329b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}
1330b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1331b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1332b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Called after all parameters are parsed to bring the runpath/rpath
1333b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper   information into a usable form.  */
1334b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void
1335b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppergen_rxxpath_data (void)
1336b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
1337b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  char *ld_library_path2;
1338b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1339b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Convert the information in true single-linked lists for easy use.
1340b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     At this point we also discard the rpath information if runpath
1341b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     information is provided.  rpath is deprecated and should not be
1342b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     used (or ever be invented for that matter).  */
1343b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (ld_state.rpath != NULL)
1344b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
1345b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      struct pathelement *endp = ld_state.rpath;
1346b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      ld_state.rpath = ld_state.rpath->next;
1347b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      endp->next = NULL;
1348b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
1349b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (ld_state.rpath_link != NULL)
1350b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
1351b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      struct pathelement *endp = ld_state.rpath_link;
1352b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      ld_state.rpath_link = ld_state.rpath_link->next;
1353b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      endp->next = NULL;
1354b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
1355b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1356b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (ld_state.runpath != NULL)
1357b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
1358b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      struct pathelement *endp = ld_state.runpath;
1359b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      ld_state.runpath = ld_state.runpath->next;
1360b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      endp->next = NULL;
1361b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1362b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      /* If rpath information is also available discard it.
1363b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	 XXX Should there be a possibility to avoid this?  */
1364b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      while (ld_state.rpath != NULL)
1365b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	{
1366b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  struct pathelement *old = ld_state.rpath;
1367b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  ld_state.rpath = ld_state.rpath->next;
1368b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  free (old);
1369b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	}
1370b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
1371b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (ld_state.runpath_link != NULL)
1372b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
1373b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      struct pathelement *endp = ld_state.runpath_link;
1374b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      ld_state.runpath_link = ld_state.runpath_link->next;
1375b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      endp->next = NULL;
1376b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1377b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      /* If rpath information is also available discard it.
1378b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	 XXX Should there be a possibility to avoid this?  */
1379b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      while (ld_state.rpath_link != NULL)
1380b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	{
1381b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  struct pathelement *old = ld_state.rpath_link;
1382b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  ld_state.rpath_link = ld_state.rpath_link->next;
1383b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  free (old);
1384b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	}
1385b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1386b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      /* The information in the strings in the list can actually be
1387b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	 directory lists themselves, with entries separated by colons.
1388b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	 Convert the list now to a list with one list entry for each
1389b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	 directory.  */
1390b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      normalize_dirlist (&ld_state.runpath_link);
1391b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
1392b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  else if (ld_state.rpath_link != NULL)
1393b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    /* Same as for the runpath_link above.  */
1394b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    normalize_dirlist (&ld_state.rpath_link);
1395b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1396b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1397b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* As a related task, handle the LD_LIBRARY_PATH value here.  First
1398b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     we have to possibly split the value found (if it contains a
1399b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     semicolon).  Then we have to split the value in list of
1400b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     directories, i.e., split at the colons.  */
1401b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (ld_library_path1 != NULL)
1402b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
1403b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      ld_library_path2 = strchr (ld_library_path1, ';');
1404b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (ld_library_path2 == NULL)
1405b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	{
1406b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  /* If no semicolon is present the directories are looked at
1407b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	     after the -L parameters (-> ld_library_path2).  */
1408b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  ld_library_path2 = ld_library_path1;
1409b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  ld_library_path1 = NULL;
1410b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	}
1411b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      else
1412b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	{
1413b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  /* NUL terminate the first part.  */
1414b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  *ld_library_path2++ = '\0';
1415b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1416b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  /* Convert the string value in a list.  */
1417b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  add_rxxpath (&ld_state.ld_library_path1, ld_library_path1);
1418b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  normalize_dirlist (&ld_state.ld_library_path1);
1419b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	}
1420b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1421b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      add_rxxpath (&ld_state.ld_library_path2, ld_library_path2);
1422b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      normalize_dirlist (&ld_state.ld_library_path2);
1423b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
1424b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}
1425b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1426b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1427b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void
1428b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperread_version_script (const char *fname)
1429b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
1430b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Open the file.  The name is supposed to be the complete (relative
1431b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     or absolute) path.  No search along a path will be performed.  */
1432b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  ldin = fopen (fname, "r");
1433b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (ldin == NULL)
1434e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper    error (EXIT_FAILURE, errno, gettext ("cannot read version script '%s'"),
1435b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	   fname);
1436b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* No need for locking.  */
1437b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  __fsetlocking (ldin, FSETLOCKING_BYCALLER);
1438b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1439b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Tell the parser that this is a version script.  */
1440b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  ld_scan_version_script = 1;
1441b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1442b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  ldlineno = 1;
1443b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  ldin_fname = fname;
1444b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (ldparse () != 0)
1445b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    /* Something went wrong during parsing.  */
1446b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    exit (EXIT_FAILURE);
1447b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1448b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  fclose (ldin);
1449b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}
1450b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1451b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1452b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void
1453b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppercreate_lscript_symbols (void)
1454b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
1455b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Walk through the data from the linker script and generate all the
1456ed52618203ac78179e3a0cf36db5bdca8958da1dMarek Polacek     symbols which are required to be present and those marked
1457b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     with PROVIDE if there is a undefined reference.  */
1458b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (ld_state.output_segments == NULL)
1459b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    return;
1460b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1461b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  struct output_segment *segment = ld_state.output_segments->next;
1462b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  do
1463b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
1464b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      struct output_rule *orule;
1465b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1466b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      for (orule = segment->output_rules; orule != NULL; orule = orule->next)
1467b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	if (orule->tag == output_assignment
1468b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    /* The assignments to "." (i.e., the PC) have to be
14693a64a3087f53ab860c7de04da0e53dabef459520Ulrich Drepper	       ignored here.  */
1470b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    && strcmp (orule->val.assignment->variable, ".") != 0)
1471b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  {
1472b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    struct symbol *s = ld_state.unresolved;
1473b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1474b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    /* Check whether the symbol is needed.  */
1475b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    if (likely (s != NULL))
1476b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      {
1477b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		struct symbol *first = s;
1478b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		const char *providename = orule->val.assignment->variable;
1479b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1480b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		/* Determine whether the provided symbol is still
1481b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		   undefined.  */
1482b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		// XXX TODO Loop inside a loop.  Gag!  Must rewrite.  */
1483b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		do
1484b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		  if (strcmp (s->name, providename) == 0)
1485b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		    {
1486b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		      /* Not defined but referenced.  */
1487b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		      if (unlikely (!s->defined))
1488b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			{
1489b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			  /* Put on the list of symbols.  First remove it from
1490b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			     whatever list it currently is on.  */
1491b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			  CDBL_LIST_DEL (ld_state.unresolved, s);
1492b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			  --ld_state.nunresolved;
1493b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			  goto use_it;
1494b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			}
1495b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1496b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		      if (unlikely (!orule->val.assignment->provide_flag))
1497b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			{
1498b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			  /* The symbol is already defined and now again
1499b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			     in the linker script.  This is an error.  */
1500b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			  error (0, 0, gettext ("\
1501b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperduplicate definition of '%s' in linker script"),
1502b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper				 providename);
1503b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			  goto next_rule;
1504b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			}
1505b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		    }
1506b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		while ((s = s->next) != first);
1507b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      }
1508b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1509b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    /* If the symbol only has to be provided if it is needed,
15103a64a3087f53ab860c7de04da0e53dabef459520Ulrich Drepper	       ignore it here since it is not undefined.  */
1511b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    if (orule->val.assignment->provide_flag)
1512b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      continue;
1513b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1514b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    /* Allocate memory for this new symbol.  */
1515b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    s = (struct symbol *)
1516b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      obstack_calloc (&ld_state.smem, sizeof (struct symbol));
1517b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1518b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    /* Initialize it.  */
1519b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    s->name = orule->val.assignment->variable;
1520b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1521b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    /* Insert it into the symbol hash table.  */
1522b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    unsigned long int hval = elf_hash (s->name);
1523b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    if (unlikely (ld_symbol_tab_insert (&ld_state.symbol_tab,
1524b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper						hval, s) != 0))
1525b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      {
1526b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		/* This means the symbol is defined somewhere else.
1527b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		   Maybe it comes from a DSO or so.  Get the
1528b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		   definition.  */
1529b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		free (s);
1530b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		struct symbol *old = ld_symbol_tab_find (&ld_state.symbol_tab,
1531b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper							 hval, s);
1532b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		assert (old != NULL);
1533b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		free (s);
1534b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1535b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		/* If this is a definition from the application itself
1536b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		   this means a duplicate definition.  */
1537b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		if (! old->in_dso)
1538b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		  {
1539b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		    error (0, 0, gettext ("\
1540b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperduplicate definition of '%s' in linker script"),
1541b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			   s->name);
1542b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		    goto next_rule;
1543b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		  }
1544b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1545b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		/* We use the definition from the linker script.  */
1546b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper		s = old;
1547b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	      }
1548b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1549b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  use_it:
1550b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    /* The symbol is (now) defined.  */
1551b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    s->defined = 1;
1552b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    s->type = STT_NOTYPE;
1553b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1554b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    /* Add a reference to the symbol record.  We will come
1555b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	       across it when creating the output file.  */
1556b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    orule->val.assignment->sym = s;
1557b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1558b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    SNGL_LIST_PUSH (ld_state.lscript_syms, s);
1559b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    ++ld_state.nlscript_syms;
1560b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1561b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  next_rule:
1562b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	    ;
1563b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  }
1564b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1565b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      segment = segment->next;
1566b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
1567b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  while (segment != ld_state.output_segments->next);
1568b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}
1569b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1570b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1571b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Create creation of spection section symbols representing sections in the
1572b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper   output file.  This is done for symbols like _GLOBAL_OFFSET_TABLE_ and
1573b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper   _DYNAMIC.  */
1574b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic void
1575b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppercreate_special_section_symbol (struct symbol **symp, const char *name)
1576b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
1577b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (*symp == NULL)
1578b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
1579b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      /* No symbol defined found yet.  Create one.  */
1580b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      struct symbol *newsym = (struct symbol *)
1581b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	obstack_calloc (&ld_state.smem, sizeof (*newsym));
1582b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1583b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      newsym->name = name;
1584b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      // XXX Should we mark the symbol hidden?  They are hardly useful
1585b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      // used outside the current object.
1586b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1587b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      /* Add to the symbol table.  */
1588b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (unlikely (ld_symbol_tab_insert (&ld_state.symbol_tab,
1589b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper					  elf_hash (name), newsym) != 0))
1590b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	abort ();
1591b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1592b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      *symp = newsym;
1593b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
1594b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  else if ((*symp)->defined)
1595b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    /* Cannot happen.  We do use this symbol from any input file.  */
1596b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    abort ();
1597b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1598b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  (*symp)->defined = 1;
159928ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper  (*symp)->local = 1;
160028ed895fdc303b2a793506bb1fcdd35d5fd14e70Ulrich Drepper  (*symp)->hidden = 1;
1601b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  (*symp)->type = STT_OBJECT;
1602b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1603b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  ++ld_state.nsymtab;
1604b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}
16053cbdd387c752999255aea91600b5cfdefbeac7d0Ulrich Drepper
16063cbdd387c752999255aea91600b5cfdefbeac7d0Ulrich Drepper
16073cbdd387c752999255aea91600b5cfdefbeac7d0Ulrich Drepper#include "debugpred.h"
1608