ld.c revision cc6695e2684ce93cdf8bd2da63d55d2cf49ff076
1cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng/* Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 Red Hat, Inc.
2cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   This file is part of Red Hat elfutils.
3441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project   Written by Ulrich Drepper <drepper@redhat.com>, 2001.
4441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
5cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   Red Hat elfutils is free software; you can redistribute it and/or modify
6cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   it under the terms of the GNU General Public License as published by the
7cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   Free Software Foundation; version 2 of the License.
8441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
9cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   Red Hat elfutils is distributed in the hope that it will be useful, but
10cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   WITHOUT ANY WARRANTY; without even the implied warranty of
11cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   General Public License for more details.
13cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
14cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   You should have received a copy of the GNU General Public License along
15cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   with Red Hat elfutils; if not, write to the Free Software Foundation,
16cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
17cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
18cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   Red Hat elfutils is an included package of the Open Invention Network.
19cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   An included package of the Open Invention Network is a package for which
20cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   Open Invention Network licensees cross-license their patents.  No patent
21cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   license is granted, either expressly or impliedly, by designation as an
22cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   included package.  Should you wish to participate in the Open Invention
23cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   Network licensing program, please visit www.openinventionnetwork.com
24cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   <http://www.openinventionnetwork.com>.  */
25441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
26441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#ifdef HAVE_CONFIG_H
27441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project# include <config.h>
28441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#endif
29441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
30441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <argp.h>
31441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <assert.h>
32441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <error.h>
33441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <fcntl.h>
34441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <libelf.h>
35441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <libintl.h>
36441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <locale.h>
37441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <mcheck.h>
38441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <stdio.h>
39441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <stdio_ext.h>
40441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <stdlib.h>
41441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <string.h>
42441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <unistd.h>
43441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
44441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <system.h>
45441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include "ld.h"
46441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include "list.h"
47441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
48441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
49441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Name and version of program.  */
50441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void print_version (FILE *stream, struct argp_state *state);
51441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectvoid (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version;
52441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
53cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng/* Bug report address.  */
54cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengconst char *argp_program_bug_address = PACKAGE_BUGREPORT;
55cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
56441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
57441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Values for the various options.  */
58441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectenum
59441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  {
60441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    ARGP_whole_archive = 300,
61441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    ARGP_no_whole_archive,
62441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    ARGP_static,
63441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    ARGP_dynamic,
64441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    ARGP_pagesize,
65441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    ARGP_rpath_link,
66441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    ARGP_runpath,
67441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    ARGP_runpath_link,
68441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    ARGP_version_script,
69441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    ARGP_gc_sections,
70441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    ARGP_no_gc_sections,
71441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    ARGP_no_undefined,
72441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    ARGP_conserve,
73cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    ARGP_as_needed,
74cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    ARGP_no_as_needed,
75cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    ARGP_eh_frame_hdr,
76cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    ARGP_hash_style,
77cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    ARGP_build_id,
78441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#if YYDEBUG
79441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    ARGP_yydebug,
80441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#endif
81441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  };
82441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
83441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
84441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Definitions of arguments for argp functions.  */
85441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic const struct argp_option options[] =
86441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{
87cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  { NULL, 0, NULL, 0, N_("Input File Control:"), 0 },
88441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  { "whole-archive", ARGP_whole_archive, NULL, 0,
89cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    N_("Include whole archives in the output from now on."), 0 },
90441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  { "no-whole-archive", ARGP_no_whole_archive, NULL, 0,
91cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    N_("Stop including the whole arhives in the output."), 0 },
92cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  { NULL, 'l', N_("FILE"), OPTION_HIDDEN, NULL, 0 },
93cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  { "start-group", '(', NULL, 0, N_("Start a group."), 0 },
94cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  { "end-group", ')', NULL, 0, N_("End a group."), 0 },
95cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  { NULL, 'L', N_("PATH"), 0,
96cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    N_("Add PATH to list of directories files are searched in."), 0 },
97cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  { "as-needed", ARGP_as_needed, NULL, 0,
98cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    N_("Only set DT_NEEDED for following dynamic libs if actually used"), 0 },
99cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  { "no-as-needed", ARGP_no_as_needed, NULL, 0,
100cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    N_("Always set DT_NEEDED for following dynamic libs"), 0 },
101cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  { "rpath-link", ARGP_rpath_link, "PATH", OPTION_HIDDEN, NULL, 0 },
102cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  { NULL, 'i', NULL, 0, N_("Ignore LD_LIBRARY_PATH environment variable."),
103cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    0 },
104cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
105cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  { NULL, 0, NULL, 0, N_("Output File Control:"), 0 },
106cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  { "output", 'o', N_("FILE"), 0, N_("Place output in FILE."), 0 },
107cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  { NULL, 'z', "KEYWORD", OPTION_HIDDEN, NULL, 0 },
108441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  { "-z nodefaultlib", '\0', NULL, OPTION_DOC,
109cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    N_("Object is marked to not use default search path at runtime."), 0 },
110441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  { "-z allextract", '\0', NULL, OPTION_DOC,
111cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    N_("Same as --whole-archive."), 0 },
112441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  { "-z defaultextract", '\0', NULL, OPTION_DOC, N_("\
113cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben ChengDefault rules of extracting from archive; weak references are not enough."),
114cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    0 },
115441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  { "-z weakextract", '\0', NULL, OPTION_DOC,
116cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    N_("Weak references cause extraction from archive."), 0 },
117441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  { "-z muldefs", '\0', NULL, OPTION_DOC,
118cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    N_("Allow multiple definitions; first is used."), 0 },
119441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  { "-z defs | nodefs", '\0', NULL, OPTION_DOC,
120cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    N_("Disallow/allow undefined symbols in DSOs."), 0 },
121cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    { "no-undefined", ARGP_no_undefined, NULL, OPTION_HIDDEN, NULL, 0 },
122441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  { "-z origin", '\0', NULL, OPTION_DOC,
123cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    N_("Object requires immediate handling of $ORIGIN."), 0 },
124441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  { "-z now", '\0', NULL, OPTION_DOC,
125cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    N_("Relocation will not be processed lazily."), 0 },
126441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  { "-z nodelete", '\0', NULL, OPTION_DOC,
127cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    N_("Object cannot be unloaded at runtime."), 0 },
128441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  { "-z initfirst", '\0', NULL, OPTION_DOC,
129cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    N_("Mark object to be initialized first."), 0 },
130441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  { "-z lazyload | nolazyload", '\0', NULL, OPTION_DOC,
131cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    N_("Enable/disable lazy-loading flag for following dependencies."), 0 },
132441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  { "-z nodlopen", '\0', NULL, OPTION_DOC,
133cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    N_("Mark object as not loadable with 'dlopen'."), 0 },
134441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  { "-z ignore | record", '\0', NULL, OPTION_DOC,
135cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    N_("Ignore/record dependencies on unused DSOs."), 0 },
136441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  { "-z systemlibrary", '\0', NULL, OPTION_DOC,
137cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    N_("Generated DSO will be a system library."), 0 },
138cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  { "entry", 'e', N_("ADDRESS"), 0, N_("Set entry point address."), 0 },
139cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  { "static", ARGP_static, NULL, OPTION_HIDDEN, NULL, 0 },
140441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  { "-B static", ARGP_static, NULL, OPTION_DOC,
141cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    N_("Do not link against shared libraries."), 0 },
142cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  { "dynamic", ARGP_dynamic, NULL, OPTION_HIDDEN, NULL, 0 },
143441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  { "-B dynamic", ARGP_dynamic, NULL, OPTION_DOC,
144cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    N_("Prefer linking against shared libraries."), 0 },
145cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  { "export-dynamic", 'E', NULL, 0, N_("Export all dynamic symbols."), 0 },
146cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  { "strip-all", 's', NULL, 0, N_("Strip all symbols."), 0 },
147cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  { "strip-debug", 'S', NULL, 0, N_("Strip debugging symbols."), 0 },
148441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  { "pagesize", ARGP_pagesize, "SIZE", 0,
149cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    N_("Assume pagesize for the target system to be SIZE."), 0 },
150cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  { "rpath", 'R', "PATH", OPTION_HIDDEN, NULL, 0 },
151cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  { "runpath", ARGP_runpath, "PATH", 0, N_("Set runtime DSO search path."),
152cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    0 },
153441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  { "runpath-link", ARGP_runpath_link, "PATH", 0,
154cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    N_("Set link time DSO search path."), 0 },
155cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  { "shared", 'G', NULL, 0, N_("Generate dynamic shared object."), 0 },
156cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  { NULL, 'r', NULL, 0L, N_("Generate relocatable object."), 0 },
157cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  { NULL, 'B', "KEYWORD", OPTION_HIDDEN, "", 0 },
158441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  { "-B local", 'B', NULL, OPTION_DOC,
159cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    N_("Causes symbol not assigned to a version be reduced to local."), 0 },
160cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  { "gc-sections", ARGP_gc_sections, NULL, 0, N_("Remove unused sections."),
161cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    0 },
162441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  { "no-gc-sections", ARGP_no_gc_sections, NULL, 0,
163cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    N_("Don't remove unused sections."), 0 },
164cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  { "soname", 'h', "NAME", 0, N_("Set soname of shared object."), 0 },
165cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  { "dynamic-linker", 'I', "NAME", 0, N_("Set the dynamic linker name."), 0 },
166cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  { NULL, 'Q', "YN", OPTION_HIDDEN, NULL, 0 },
167441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  { "-Q y | n", 'Q', NULL, OPTION_DOC,
168cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    N_("Add/suppress addition indentifying link-editor to .comment section."),
169cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    0 },
170cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  { "eh-frame-hdr", ARGP_eh_frame_hdr, NULL, 0,
171cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    N_("Create .eh_frame_hdr section"), 0 },
172cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  { "hash-style", ARGP_hash_style, "STYLE", 0,
173cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    N_("Set hash style to sysv, gnu or both."), 0 },
174cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  { "build-id", ARGP_build_id, "STYLE", OPTION_ARG_OPTIONAL,
175cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    N_("Generate build ID note (md5, sha1 (default), uuid)."), 0 },
176cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
177cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  { NULL, 0, NULL, 0, N_("Linker Operation Control:"), 0 },
178cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  { "verbose", 'v', NULL, 0, N_("Verbose messages."), 0 },
179cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  { "trace", 't', NULL, 0, N_("Trace file opens."), 0 },
180cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  { "conserve-memory", ARGP_conserve, NULL, 0,
181cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    N_("Trade speed for less memory usage"), 0 },
182cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  { NULL, 'O', N_("LEVEL"), OPTION_ARG_OPTIONAL,
183cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    N_("Set optimization level to LEVEL."), 0 },
184cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  { NULL, 'c', N_("FILE"), 0, N_("Use linker script in FILE."), 0 },
185441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#if YYDEBUG
186441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  { "yydebug", ARGP_yydebug, NULL, 0,
187cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    N_("Select to get parser debug information"), 0 },
188441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#endif
189cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  { "version-script", ARGP_version_script, "FILE", 0,
190cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    N_("Read version information from FILE."), 0 },
191cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  { "emulation", 'm', "NAME", 0, N_("Set emulation to NAME."), 0 },
192441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
193cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  { NULL, 0, NULL, 0, NULL, 0 }
194441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project};
195441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
196441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Short description of program.  */
197441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic const char doc[] = N_("Combine object and archive files.");
198441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
199441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Strings for arguments in help texts.  */
200441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic const char args_doc[] = N_("[FILE]...");
201441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
202441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Prototype for option handler.  */
203cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic void replace_args (int argc, char *argv[]);
204441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic error_t parse_opt_1st (int key, char *arg, struct argp_state *state);
205441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic error_t parse_opt_2nd (int key, char *arg, struct argp_state *state);
206441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
207441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Data structure to communicate with argp functions.  */
208441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic struct argp argp_1st =
209441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{
210cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  options, parse_opt_1st, args_doc, doc, NULL, NULL, NULL
211441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project};
212441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic struct argp argp_2nd =
213441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{
214cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  options, parse_opt_2nd, args_doc, doc, NULL, NULL, NULL
215441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project};
216441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
217441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
218441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Linker state.  This contains all global information.  */
219441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstruct ld_state ld_state;
220441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
221441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* List of the input files.  */
222441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic struct file_list
223441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{
224441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  const char *name;
225441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  struct file_list *next;
226441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} *input_file_list;
227441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
228441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* If nonzero be verbose.  */
229441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectint verbose;
230441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
231441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* If nonzero, trade speed for less memory/address space usage.  */
232441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectint conserve_memory;
233441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
234441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* The emulation name to use.  */
235441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic const char *emulation;
236441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
237441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Keep track of the nesting level.  Even though we don't handle nested
238441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project   groups we still keep track to improve the error messages.  */
239441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic int group_level;
240441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
241441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* The last file we processed.  */
242441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic struct usedfiles *last_file;
243441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
244441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* The default linker script.  */
245441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* XXX We'll do this a bit different in the real solution.  */
246441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic const char *linker_script = SRCDIR "/elf32-i386.script";
247441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
248441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Nonzero if an error occurred while loading the input files.  */
249441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic int error_loading;
250441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
251441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
252441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Intermediate storage for the LD_LIBRARY_PATH information from the
253441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project   environment.  */
254441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic char *ld_library_path1;
255441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
256441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Flag used to communicate with the scanner.  */
257441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectint ld_scan_version_script;
258441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
259441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Name of the input file.  */
260441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectconst char *ldin_fname;
261441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
262441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Define by parser if required.  */
263441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectextern int lddebug;
264441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
265441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
266441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Prototypes for local functions.  */
267441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void parse_z_option (const char *arg);
268441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void parse_z_option_2 (const char *arg);
269441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void parse_B_option (const char *arg);
270441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void parse_B_option_2 (const char *arg);
271441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void determine_output_format (void);
272441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void load_needed (void);
273441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void collect_sections (void);
274441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void add_rxxpath (struct pathelement **pathp, const char *str);
275441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void gen_rxxpath_data (void);
276441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void read_version_script (const char *fname);
277441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void create_lscript_symbols (void);
278441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void create_special_section_symbol (struct symbol **symp,
279441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project					   const char *name);
280441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
281441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
282441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectint
283441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectmain (int argc, char *argv[])
284441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{
285441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  int remaining;
286441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  int err;
287441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
288441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#ifndef NDEBUG
289441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  /* Enable memory debugging.  */
290441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  mtrace ();
291441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#endif
292441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
293441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  /* Sanity check.  We always want to use the LFS functionality.  */
294441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  if (sizeof (off_t) != sizeof (off64_t))
295441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    abort ();
296441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
297441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  /* We use no threads here which can interfere with handling a stream.  */
298441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  __fsetlocking (stdin, FSETLOCKING_BYCALLER);
299441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  __fsetlocking (stdout, FSETLOCKING_BYCALLER);
300441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  __fsetlocking (stderr, FSETLOCKING_BYCALLER);
301441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
302441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  /* Set locale.  */
303441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  setlocale (LC_ALL, "");
304441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
305441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  /* Make sure the message catalog can be found.  */
306cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  bindtextdomain (PACKAGE_TARNAME, LOCALEDIR);
307441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
308441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  /* Initialize the message catalog.  */
309cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  textdomain (PACKAGE_TARNAME);
310441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
311441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  /* Before we start tell the ELF library which version we are using.  */
312441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  elf_version (EV_CURRENT);
313441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
314441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  /* The user can use the LD_LIBRARY_PATH environment variable to add
315441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project     additional lookup directories.  */
316441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  ld_library_path1 = getenv ("LD_LIBRARY_PATH");
317441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
318441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  /* Initialize the memory handling.  */
319441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#define obstack_chunk_alloc xmalloc
320441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#define obstack_chunk_free free
321441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  obstack_init (&ld_state.smem);
322441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
323cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  /* Recognize old-style parameters for compatibility.  */
324cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  replace_args (argc, argv);
325cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
326441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  /* One quick pass over the parameters which allows us to scan for options
327441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project     with global effect which influence the rest of the processing.  */
328441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  argp_parse (&argp_1st, argc, argv, ARGP_IN_ORDER, &remaining, NULL);
329441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
330441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  /* We need at least one input file.  */
331441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  if (input_file_list == NULL)
332441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    {
333441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      error (0, 0, gettext ("At least one input file needed"));
334441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      argp_help (&argp_1st, stderr, ARGP_HELP_SEE, "ld");
335441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      exit (EXIT_FAILURE);
336441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    }
337441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
338441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  /* Determine which ELF backend to use.  */
339441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  determine_output_format ();
340441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
341cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  /* If no hash style was specific default to the oldand slow SysV
342cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng     method.  */
343cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  if (unlikely (ld_state.hash_style == hash_style_none))
344cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    ld_state.hash_style = hash_style_sysv;
345cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
346441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  /* Prepare state.  */
347441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  err = ld_prepare_state (emulation);
348441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  if (err != 0)
349441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    error (EXIT_FAILURE, 0, gettext ("error while preparing linking"));
350441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
351441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  /* XXX Read the linker script now.  Since we later will have the linker
352441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project     script built in we don't go into trouble to make sure we handle GROUP
353441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project     statements in the script.  This simply must not happen.  */
354441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  ldin = fopen (linker_script, "r");
355441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  if (ldin == NULL)
356cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    error (EXIT_FAILURE, errno, gettext ("cannot open linker script '%s'"),
357441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	   linker_script);
358441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  /* No need for locking.  */
359441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  __fsetlocking (ldin, FSETLOCKING_BYCALLER);
360441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
361441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  ld_state.srcfiles = NULL;
362441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  ldlineno = 1;
363441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  ld_scan_version_script = 0;
364441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  ldin_fname = linker_script;
365441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  if (ldparse () != 0)
366441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    /* Something went wrong during parsing.  */
367441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    exit (EXIT_FAILURE);
368441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  fclose (ldin);
369441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
370441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  /* We now might have a list of directories to look for libraries in
371441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project     named by the linker script.  Put them in a different list so that
372441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project     they are searched after all paths given by the user on the
373441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project     command line.  */
374441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  ld_state.default_paths = ld_state.paths;
375441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  ld_state.paths = ld_state.tailpaths = NULL;
376441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
377441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  /* Get runpath/rpath information in usable form.  */
378441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  gen_rxxpath_data ();
379441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
380441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  /* Parse and process arguments for real.  */
381441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  argp_parse (&argp_2nd, argc, argv, ARGP_IN_ORDER, &remaining, NULL);
382441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  /* All options should have been processed by the argp parser.  */
383441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  assert (remaining == argc);
384441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
385441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  /* Process the last file.  */
386441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  while (last_file != NULL)
387441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    /* Try to open the file.  */
388441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    error_loading |= FILE_PROCESS (-1, last_file, &ld_state, &last_file);
389441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
390441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  /* Stop if there has been a problem while reading the input files.  */
391441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  if (error_loading)
392441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    exit (error_loading);
393441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
394441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  /* See whether all opened -( were closed.  */
395441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  if (group_level > 0)
396441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    {
397441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      error (0, 0, gettext ("-( without matching -)"));
398441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      argp_help (&argp_1st, stderr, ARGP_HELP_SEE, "ld");
399441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      exit (EXIT_FAILURE);
400441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    }
401441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
402441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  /* When we create a relocatable file we don't have to look for the
403441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project     DT_NEEDED DSOs and we also don't test for undefined symbols.  */
404441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  if (ld_state.file_type != relocatable_file_type)
405441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    {
406441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      /* At this point we have loaded all the direct dependencies.  What
407441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	 remains to be done is find the indirect dependencies.  These are
408441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	 DSOs which are referenced by the DT_NEEDED entries in the DSOs
409441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	 which are direct dependencies.  We have to transitively find and
410441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	 load all these dependencies.  */
411441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      load_needed ();
412441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
413441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      /* At this point all object files and DSOs are read.  If there
414441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project         are still undefined symbols left they might have to be
415441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project         synthesized from the linker script.  */
416441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      create_lscript_symbols ();
417441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
418441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      /* Now that we have loaded all the object files we can determine
419441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	 whether we have any non-weak unresolved references left.  If
420441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	 there are any we stop.  If the user used the '-z nodefs' option
421441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	 and we are creating a DSO don't perform the tests.  */
422441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      if (FLAG_UNRESOLVED (&ld_state) != 0)
423441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	exit (1);
424441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    }
425441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
426441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  /* Collect information about the relocations which will be carried
427441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project     forward into the output.  We have to do this here and now since
428441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project     we need to know which sections have to be created.  */
429441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  if (ld_state.file_type != relocatable_file_type)
430441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    {
431441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      void *p ;
432441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      struct scnhead *h;
433441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
434441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      p = NULL;
435441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      while ((h = ld_section_tab_iterate (&ld_state.section_tab, &p)) != NULL)
436441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	if (h->type == SHT_REL || h->type == SHT_RELA)
437441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  {
438441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	    struct scninfo *runp = h->last;
439441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	    do
440441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      {
441441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		/* If we are processing the relocations determine how
442441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		   many will be in the output file.  Also determine
443441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		   how many GOT entries are needed.  */
444441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		COUNT_RELOCATIONS (&ld_state, runp);
445441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
446441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		ld_state.relsize_total += runp->relsize;
447441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      }
448441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	    while ((runp = runp->next) != h->last);
449441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  }
450441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    }
451441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
452441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  /* Not part of the gABI, but part of every psABI: the symbols for the
453441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project     GOT section.  Add the symbol if necessary.  */
454441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  if (ld_state.need_got)
455441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    create_special_section_symbol (&ld_state.got_symbol,
456441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project				   "_GLOBAL_OFFSET_TABLE_");
457441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  /* Similarly for the _DYNAMIC symbol which points to the dynamic
458441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project     section.  */
459441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  if (dynamically_linked_p ())
460441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    create_special_section_symbol (&ld_state.dyn_symbol, "_DYNAMIC");
461441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
462441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  /* We are ready to start working on the output file.  Not all
463441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project     information has been gather or created yet.  This will be done as
464441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project     we go.  Open the file now.  */
465441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  if (OPEN_OUTFILE (&ld_state, EM_NONE, ELFCLASSNONE, ELFDATANONE) != 0)
466441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    exit (1);
467441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
468441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  /* Create the sections which are generated by the linker and are not
469441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project     present in the input file.  The output file must already have
470441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project     been opened since we need the ELF descriptor to deduce type
471441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project     sizes.  */
472441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  GENERATE_SECTIONS (&ld_state);
473441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
474441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  /* At this point we have read all the files and know all the
475441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project     sections which have to be linked into the application.  We do now
476441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project     create an array listing all the sections.  We will than pass this
477441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project     array to a system specific function which can reorder it at will.
478441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project     The functions can also merge sections if this is what is
479441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project     wanted.  */
480441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  collect_sections ();
481441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
482441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  /* Create the output sections now.  This may requires sorting them
483441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project     first.  */
484441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  CREATE_SECTIONS (&ld_state);
485441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
486441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  /* Create the output file data.  Appropriate code for the selected
487441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project     output file type is called.  */
488441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  if (CREATE_OUTFILE (&ld_state) != 0)
489441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    exit (1);
490441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
491441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  /* Finalize the output file, write the data out.  */
492441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  err |= FINALIZE (&ld_state);
493441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
494441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  /* Return with an non-zero exit status also if any error message has
495441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project     been printed.  */
496441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  return err | (error_message_count != 0);
497441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project}
498441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
499441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
500cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic void
501cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengreplace_args (int argc, char *argv[])
502441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{
503cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  static const struct
504cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  {
505cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    const char *from;
506cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    const char *to;
507cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  } args[] =
508cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      {
509cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	{ "-export-dynamic", "--export-dynamic" },
510cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	{ "-dynamic-linker", "--dynamic-linker" },
511cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	{ "-static", "--static" },
512cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      };
513cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  const size_t nargs = sizeof (args) / sizeof (args[0]);
514cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
515cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  for (int i = 1; i < argc; ++i)
516cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    if (argv[i][0] == '-' && islower (argv[i][1]) && argv[i][2] != '\0')
517cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      for (size_t j = 0; j < nargs; ++j)
518cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	if (strcmp (argv[i], args[j].from) == 0)
519cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  {
520cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	    argv[i] = (char *) args[j].to;
521cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	    break;
522cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  }
523cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng}
524441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
525441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
526cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengstatic int
527cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengvalid_hexarg (const char *arg)
528cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng{
529cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  if (strncasecmp (arg, "0x", 2) != 0)
530cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    return 0;
531cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
532cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  arg += 2;
533cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  do
534cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    {
535cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      if (isxdigit (arg[0]) && isxdigit (arg[1]))
536cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	{
537cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  arg += 2;
538cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  if (arg[0] == '-' || arg[0] == ':')
539cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	    ++arg;
540cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	}
541cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      else
542cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	return 0;
543441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    }
544cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  while (*arg != '\0');
545cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
546cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  return 1;
547441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project}
548441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
549441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
550441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Quick scan of the parameter list for options with global effect.  */
551441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic error_t
552cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengparse_opt_1st (int key, char *arg,
553cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	       struct argp_state *state __attribute__ ((unused)))
554441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{
555441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  switch (key)
556441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    {
557441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    case 'B':
558441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      parse_B_option (arg);
559441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      break;
560441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
561441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    case 'c':
562441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      linker_script = arg;
563441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      break;
564441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
565441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    case 'E':
566441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      ld_state.export_all_dynamic = true;
567441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      break;
568441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
569441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    case 'G':
570441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      if (ld_state.file_type != no_file_type)
571441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	error (EXIT_FAILURE, 0,
572441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	       gettext ("only one option of -G and -r is allowed"));
573441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      ld_state.file_type = dso_file_type;
574441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
575441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      /* If we generate a DSO we have to export all symbols.  */
576441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      ld_state.export_all_dynamic = true;
577441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      break;
578441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
579441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    case 'h':
580441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      ld_state.soname = arg;
581441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      break;
582441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
583441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    case 'i':
584441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      /* Discard the LD_LIBRARY_PATH value we found.  */
585441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      ld_library_path1 = NULL;
586441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      break;
587441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
588441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    case 'I':
589441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      ld_state.interp = arg;
590441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      break;
591441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
592441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    case 'm':
593441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      if (emulation != NULL)
594441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	error (EXIT_FAILURE, 0, gettext ("more than one '-m' parameter"));
595441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      emulation = arg;
596441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      break;
597441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
598441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    case 'Q':
599441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      if (arg[1] == '\0' && (arg[0] == 'y' || arg[0] == 'Y'))
600441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	ld_state.add_ld_comment = true;
601441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      else if (arg[1] == '\0' && (arg[0] == 'n' || arg[0] == 'N'))
602441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	ld_state.add_ld_comment = true;
603441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      else
604441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	error (EXIT_FAILURE, 0, gettext ("unknown option `-%c %s'"), 'Q', arg);
605441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      break;
606441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
607441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    case 'r':
608441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      if (ld_state.file_type != no_file_type)
609441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	error (EXIT_FAILURE, 0,
610441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	       gettext ("only one option of -G and -r is allowed"));
611441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      ld_state.file_type = relocatable_file_type;
612441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      break;
613441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
614441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    case 'S':
615441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      ld_state.strip = strip_debug;
616441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      break;
617441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
618441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    case 't':
619441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      ld_state.trace_files = true;
620441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      break;
621441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
622441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    case 'v':
623441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      verbose = 1;
624441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      break;
625441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
626441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    case 'z':
627441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      /* The SysV linker used 'z' to pass various flags to the linker.
628441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	 We follow this.  See 'parse_z_option' for the options we
629441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	 recognize.  */
630441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      parse_z_option (arg);
631441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      break;
632441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
633441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    case ARGP_pagesize:
634441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      {
635441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	char *endp;
636441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	ld_state.pagesize = strtoul (arg, &endp, 0);
637441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	if (*endp != '\0')
638441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  {
639441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	    if (endp[1] == '\0' && tolower (*endp) == 'k')
640441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      ld_state.pagesize *= 1024;
641441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	    else if (endp[1] == '\0' && tolower (*endp) == 'm')
642441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      ld_state.pagesize *= 1024 * 1024;
643441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	    else
644441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      {
645441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		error (0, 0,
646cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng		       gettext ("invalid page size value '%s': ignored"),
647441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		       arg);
648441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		ld_state.pagesize = 0;
649441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      }
650441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  }
651441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      }
652441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      break;
653441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
654cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    case 'R':
655441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      add_rxxpath (&ld_state.rpath, arg);
656441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      break;
657441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
658441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    case ARGP_rpath_link:
659441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      add_rxxpath (&ld_state.rpath_link, arg);
660441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      break;
661441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
662441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    case ARGP_runpath:
663441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      add_rxxpath (&ld_state.runpath, arg);
664441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      break;
665441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
666441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    case ARGP_runpath_link:
667441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      add_rxxpath (&ld_state.runpath_link, arg);
668441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      break;
669441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
670441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    case ARGP_gc_sections:
671441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    case ARGP_no_gc_sections:
672441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      ld_state.gc_sections = key == ARGP_gc_sections;
673441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      break;
674441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
675cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    case ARGP_eh_frame_hdr:
676cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      ld_state.eh_frame_hdr = true;
677cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      break;
678cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
679cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    case ARGP_hash_style:
680cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      if (strcmp (arg, "gnu") == 0)
681cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	ld_state.hash_style = hash_style_gnu;
682cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      else if (strcmp (arg, "both") == 0)
683cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	ld_state.hash_style = hash_style_gnu | hash_style_sysv;
684cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      else if (strcmp (arg, "sysv") == 0)
685cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	ld_state.hash_style = hash_style_sysv;
686cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      else
687cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	error (EXIT_FAILURE, 0, gettext ("invalid hash style '%s'"), arg);
688cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      break;
689cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
690cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    case ARGP_build_id:
691cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      if (arg == NULL)
692cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	ld_state.build_id = "sha1";
693cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      else if (strcmp (arg, "uuid") != 0
694cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	       && strcmp (arg, "md5") != 0
695cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	       && strcmp (arg, "sha1") != 0
696cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	       && !valid_hexarg (arg))
697cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	error (EXIT_FAILURE, 0, gettext ("invalid build-ID style '%s'"), arg);
698cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      else
699cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	ld_state.build_id = arg;
700cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      break;
701cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
702441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    case 's':
703441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      if (arg == NULL)
704441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	{
705441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  if (ld_state.strip == strip_all)
706441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	    ld_state.strip = strip_everything;
707441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  else
708441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	    ld_state.strip = strip_all;
709441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  break;
710441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	}
711441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      /* FALLTHROUGH */
712441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
713441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    case 'e':
714441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    case 'o':
715441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    case 'O':
716441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    case ARGP_whole_archive:
717441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    case ARGP_no_whole_archive:
718cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    case ARGP_as_needed:
719cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    case ARGP_no_as_needed:
720441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    case 'L':
721441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    case '(':
722441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    case ')':
723441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    case 'l':
724441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    case ARGP_static:
725441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    case ARGP_dynamic:
726441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    case ARGP_version_script:
727441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      /* We'll handle these in the second pass.  */
728441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      break;
729441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
730441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    case ARGP_KEY_ARG:
731441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      {
732441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	struct file_list *newp;
733441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
734441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	newp = (struct file_list *) xmalloc (sizeof (struct file_list));
735441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	newp->name = arg;
736441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#ifndef NDEBUG
737441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	newp->next = NULL;
738441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#endif
739441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	CSNGL_LIST_ADD_REAR (input_file_list, newp);
740441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      }
741441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      break;
742441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
743441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#if YYDEBUG
744441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    case ARGP_yydebug:
745441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      lddebug = 1;
746441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      break;
747441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#endif
748441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
749441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    case ARGP_no_undefined:
750441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      ld_state.nodefs = false;
751441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      break;
752441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
753441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    case ARGP_conserve:
754441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      conserve_memory = 1;
755441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      break;
756441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
757441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    default:
758441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      return ARGP_ERR_UNKNOWN;
759441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    }
760441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  return 0;
761441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project}
762441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
763441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
764441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Handle program arguments for real.  */
765441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic error_t
766cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengparse_opt_2nd (int key, char *arg,
767cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	       struct argp_state *state __attribute__ ((unused)))
768441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{
769441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  static bool group_start_requested;
770441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  static bool group_end_requested;
771441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
772441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  switch (key)
773441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    {
774441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    case 'B':
775441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      parse_B_option_2 (arg);
776441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      break;
777441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
778441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    case 'e':
779441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      ld_state.entry = arg;
780441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      break;
781441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
782441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    case 'o':
783441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      if (ld_state.outfname != NULL)
784441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	{
785441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  error (0, 0, gettext ("More than one output file name given."));
786441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	see_help:
787441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  argp_help (&argp_2nd, stderr, ARGP_HELP_SEE, "ld");
788441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  exit (EXIT_FAILURE);
789441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	}
790441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      ld_state.outfname = arg;
791441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      break;
792441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
793441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    case 'O':
794441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      if (arg == NULL)
795441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	ld_state.optlevel = 1;
796441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      else
797441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	{
798441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  char *endp;
799441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  unsigned long int level = strtoul (arg, &endp, 10);
800441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  if (*endp != '\0')
801441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	    {
802441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      error (0, 0, gettext ("Invalid optimization level `%s'"), arg);
803441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      goto see_help;
804441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	    }
805441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  ld_state.optlevel = level;
806441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	}
807441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      break;
808441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
809441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    case ARGP_whole_archive:
810441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      ld_state.extract_rule = allextract;
811441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      break;
812441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    case ARGP_no_whole_archive:
813441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      ld_state.extract_rule = defaultextract;
814441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      break;
815441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
816cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    case ARGP_as_needed:
817cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      ld_state.as_needed = true;
818cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      break;
819cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    case ARGP_no_as_needed:
820cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      ld_state.as_needed = false;
821cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng      break;
822cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
823441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    case ARGP_static:
824441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    case ARGP_dynamic:
825441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      /* Enable/disable use for DSOs.  */
826441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      ld_state.statically = key == ARGP_static;
827441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      break;
828441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
829441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    case 'z':
830441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      /* The SysV linker used 'z' to pass various flags to the linker.
831441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	 We follow this.  See 'parse_z_option' for the options we
832441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	 recognize.  */
833441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      parse_z_option_2 (arg);
834441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      break;
835441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
836441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    case ARGP_version_script:
837441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      read_version_script (arg);
838441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      break;
839441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
840441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    case 'L':
841441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      /* Add a new search directory.  */
842441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      ld_new_searchdir (arg);
843441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      break;
844441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
845441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    case '(':
846441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      /* Start a link group.  We have to be able to determine the object
847441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	 file which is named next.  Do this by remembering a pointer to
848441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	 the pointer which will point to the next object.  */
849441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      if (verbose && (group_start_requested || !group_end_requested))
850441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	error (0, 0, gettext ("nested -( -) groups are not allowed"));
851441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
852441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      /* Increment the nesting level.  */
853441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      ++group_level;
854441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
855441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      /* Record group start.  */
856441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      group_start_requested = true;
857441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      group_end_requested = false;
858441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      break;
859441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
860441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    case ')':
861441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      /* End a link group.  If there is no group open this is clearly
862441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	 a bug.  If there is a group open insert a back reference
863441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	 pointer in the record for the last object of the group.  If
864441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	 there is no new object or just one don't do anything.  */
865441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      if (!group_end_requested)
866441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	{
867441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  if (group_level == 0)
868441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	    {
869441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      error (0, 0, gettext ("-) without matching -("));
870441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      goto see_help;
871441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	    }
872441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	}
873441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      else
874441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	last_file->group_end = true;
875441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
876441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      if (group_level > 0)
877441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	--group_level;
878441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      break;
879441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
880441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    case 'l':
881441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    case ARGP_KEY_ARG:
882441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      {
883441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	while (last_file != NULL)
884441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  /* Try to open the file.  */
885441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  error_loading |= FILE_PROCESS (-1, last_file, &ld_state, &last_file);
886441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
887441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	last_file = ld_new_inputfile (arg,
888441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project				      key == 'l'
889441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project				      ? archive_file_type
890441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project				      : relocatable_file_type);
891441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	if (group_start_requested)
892441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  {
893441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	    last_file->group_start = true;
894441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
895441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	    group_start_requested = false;
896441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	    group_end_requested = true;
897441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  }
898441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      }
899441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      break;
900441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
901441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    default:
902441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      /* We can catch all other options here.  They either have
903441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	 already been handled or, if the parameter was not correct,
904441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	 the error has been reported.  */
905441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      break;
906441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    }
907441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  return 0;
908441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project}
909441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
910441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
911441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Load all the DSOs named as dependencies in other DSOs we already
912441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project   loaded.  */
913441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void
914441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectload_needed (void)
915441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{
916441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  struct usedfiles *first;
917441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  struct usedfiles *runp;
918441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
919441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  /* XXX There is one problem here: do we allow references from
920441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project     regular object files to be satisfied by these implicit
921441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project     dependencies?  The old linker allows this and several libraries
922441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project     depend on this.  Solaris' linker does not allow this; it provides
923441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project     the user with a comprehensive error message explaining the
924441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project     situation.
925441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
926441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project     XXX IMO the old ld behavior is correct since this is also how the
927441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project     dynamic linker will work.  It will look for unresolved references
928441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project     in all loaded DSOs.
929441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
930441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project     XXX Should we add an option to get Solaris compatibility?  */
931441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  if (ld_state.needed == NULL)
932441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    return;
933441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
934441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  runp = first = ld_state.needed->next;
935441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  do
936441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    {
937441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      struct usedfiles *ignore;
938441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      struct usedfiles *next = runp->next;
939441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      int err;
940441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
941441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      err = FILE_PROCESS (-1, runp, &ld_state, &ignore);
942441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      if (err != 0)
943441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	/* Something went wrong.  */
944441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	exit (err);
945441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
946441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      runp = next;
947441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    }
948441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  while (runp != first);
949441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project}
950441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
951441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
952441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Print the version information.  */
953441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void
954cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chengprint_version (FILE *stream, struct argp_state *state __attribute__ ((unused)))
955441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{
956cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  fprintf (stream, "ld (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION);
957441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  fprintf (stream, gettext ("\
958441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source ProjectCopyright (C) %s Red Hat, Inc.\n\
959441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source ProjectThis is free software; see the source for copying conditions.  There is NO\n\
960441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectwarranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
961cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng"), "2008");
962441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper");
963441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project}
964441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
965441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
966441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* There are a lot of -z options, parse them here.  Some of them have
967441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project   to be parsed in the first pass, others must be handled in the
968441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project   second pass.  */
969441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void
970441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectparse_z_option (const char *arg)
971441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{
972441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  if (strcmp (arg, "nodefaultlib") == 0
973441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      /* This is only meaningful if we create a DSO.  */
974441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      && ld_state.file_type == dso_file_type)
975441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    ld_state.dt_flags_1 |= DF_1_NODEFLIB;
976441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  else if (strcmp (arg, "muldefs") == 0)
977441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    ld_state.muldefs = true;
978441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  else if (strcmp (arg, "nodefs") == 0)
979441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    ld_state.nodefs = true;
980441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  else if (strcmp (arg, "defs") == 0)
981441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    ld_state.nodefs = false;
982441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  else if (strcmp (arg, "now") == 0)
983441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    /* We could also set the DF_1_NOW flag in DT_FLAGS_1 but this isn't
984441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project       necessary.  */
985441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    ld_state.dt_flags |= DF_BIND_NOW;
986441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  else if (strcmp (arg, "origin") == 0)
987441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    /* We could also set the DF_1_ORIGIN flag in DT_FLAGS_1 but this isn't
988441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project       necessary.  */
989441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    ld_state.dt_flags |= DF_ORIGIN;
990441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  else if (strcmp (arg, "nodelete") == 0
991441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	   /* This is only meaningful if we create a DSO.  */
992441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	   && ld_state.file_type == dso_file_type)
993441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    ld_state.dt_flags_1 |= DF_1_NODELETE;
994441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  else if (strcmp (arg, "initfirst") == 0)
995441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    ld_state.dt_flags_1 |= DF_1_INITFIRST;
996441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  else if (strcmp (arg, "nodlopen") == 0
997441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	   /* This is only meaningful if we create a DSO.  */
998441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	   && ld_state.file_type == dso_file_type)
999441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    ld_state.dt_flags_1 |= DF_1_NOOPEN;
1000441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  else if (strcmp (arg, "systemlibrary") == 0)
1001441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    ld_state.is_system_library = true;
1002cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  else if (strcmp (arg, "execstack") == 0)
1003cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    ld_state.execstack = execstack_true;
1004cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  else if (strcmp (arg, "noexecstack") == 0)
1005cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    ld_state.execstack = execstack_false_force;
1006441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  else if (strcmp (arg, "allextract") != 0
1007441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	   && strcmp (arg, "defaultextract") != 0
1008441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	   && strcmp (arg, "weakextract") != 0
1009441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	   && strcmp (arg, "lazyload") != 0
1010cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	   && strcmp (arg, "nolazyload") != 0
1011cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	   && strcmp (arg, "ignore") != 0
1012cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	   && strcmp (arg, "record") != 0)
1013441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    error (0, 0, gettext ("unknown option `-%c %s'"), 'z', arg);
1014441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project}
1015441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1016441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1017441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void
1018441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectparse_z_option_2 (const char *arg)
1019441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{
1020441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  if (strcmp (arg, "allextract") == 0)
1021441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    ld_state.extract_rule = allextract;
1022441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  else if (strcmp (arg, "defaultextract") == 0)
1023441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    ld_state.extract_rule = defaultextract;
1024441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  else if (strcmp (arg, "weakextract") == 0)
1025441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    ld_state.extract_rule = weakextract;
1026441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  else if (strcmp (arg, "lazyload") == 0)
1027441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    ld_state.lazyload = true;
1028441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  else if (strcmp (arg, "nolazyload") == 0)
1029441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    ld_state.lazyload = false;
1030cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  else if (strcmp (arg, "ignore") == 0)
1031cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    ld_state.as_needed = true;
1032cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  else if (strcmp (arg, "record") == 0)
1033cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    ld_state.as_needed = false;
1034441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project}
1035441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1036441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1037441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* There are a lot of -B options, parse them here.  */
1038441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void
1039441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectparse_B_option (const char *arg)
1040441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{
1041441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  if (strcmp (arg, "local") == 0)
1042441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    ld_state.default_bind_local = true;
1043441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  else if (strcmp (arg, "symbolic") != 0
1044441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	   && strcmp (arg, "static") != 0
1045441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	   && strcmp (arg, "dynamic") != 0)
1046441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    error (0, 0, gettext ("unknown option '-%c %s'"), 'B', arg);
1047441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project}
1048441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1049441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1050441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* The same functionality, but called in the second pass over the
1051441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project   parameters.  */
1052441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void
1053441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectparse_B_option_2 (const char *arg)
1054441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{
1055441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  if (strcmp (arg, "static") == 0)
1056441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    ld_state.statically = true;
1057441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  else if (strcmp (arg, "dynamic") == 0)
1058441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    ld_state.statically = false;
1059441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  else if (strcmp (arg, "symbolic") == 0
1060441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	   /* This is only meaningful if we create a DSO.  */
1061441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	   && ld_state.file_type == dso_file_type)
1062441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    ld_state.dt_flags |= DF_SYMBOLIC;
1063441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project}
1064441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1065441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1066441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void
1067441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectdetermine_output_format (void)
1068441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{
1069441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  /* First change the 'input_file_list' variable in a simple
1070441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project     single-linked list.  */
1071441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  struct file_list *last = input_file_list;
1072441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  input_file_list = input_file_list->next;
1073441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  last->next = NULL;
1074441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1075441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  /* Determine the target configuration which we are supposed to use.
1076441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project     The user can use the '-m' option to select one.  If this is
1077441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project     missing we are trying to load one file and determine the
1078441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project     architecture from that.  */
1079441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  if (emulation != NULL)
1080441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    {
1081441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      ld_state.ebl = ebl_openbackend_emulation (emulation);
1082441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1083441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      assert (ld_state.ebl != NULL);
1084441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    }
1085441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  else
1086441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    {
1087441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      /* Find an ELF input file and let it determine the ELf backend.  */
1088441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      struct file_list *runp = input_file_list;
1089441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1090441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      while (runp != NULL)
1091441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	{
1092441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  int fd = open (runp->name, O_RDONLY);
1093441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  if (fd != -1)
1094441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	    {
1095441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      int try (Elf *elf)
1096441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		{
1097441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		  int result = 0;
1098441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1099441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		  if (elf == NULL)
1100441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		    return 0;
1101441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1102441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		  if (elf_kind (elf) == ELF_K_ELF)
1103441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		    {
1104441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		      /* We have an ELF file.  We now can find out
1105441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project			 what the output format should be.  */
1106441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		      XElf_Ehdr_vardef(ehdr);
1107441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1108441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		      /* Get the ELF header of the object.  */
1109441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		      xelf_getehdr (elf, ehdr);
1110441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		      if (ehdr != NULL)
1111441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project			ld_state.ebl =
1112441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project			  ebl_openbackend_machine (ehdr->e_machine);
1113441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1114441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		      result = 1;
1115441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		    }
1116441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		  else if (elf_kind (elf) == ELF_K_AR)
1117441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		    {
1118441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		      /* Try the archive members.  This could
1119441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project			 potentially lead to wrong results if the
1120441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project			 archive contains files for more than one
1121441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project			 architecture.  But this is the user's
1122441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project			 problem.  */
1123441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		      Elf *subelf;
1124441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		      Elf_Cmd cmd = ELF_C_READ_MMAP;
1125441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1126441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		      while ((subelf = elf_begin (fd, cmd, elf)) != NULL)
1127441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project			{
1128441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project			  cmd = elf_next (subelf);
1129441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1130441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project			  if (try (subelf) != 0)
1131441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project			    break;
1132441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project			}
1133441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		    }
1134441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1135441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		  elf_end (elf);
1136441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1137441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		  return result;
1138441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		}
1139441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1140441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      if (try (elf_begin (fd, ELF_C_READ_MMAP, NULL)) != 0)
1141441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		/* Found a file.  */
1142441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		break;
1143441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	    }
1144441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1145441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  runp = runp->next;
1146441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	}
1147441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1148441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      if (ld_state.ebl == NULL)
1149441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	{
1150441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  error (0, 0, gettext ("\
1151441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectcould not find input file to determine output file format"));
1152441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  error (EXIT_FAILURE, 0, gettext ("\
1153441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projecttry again with an appropriate '-m' parameter"));
1154441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	}
1155441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    }
1156441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1157441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  /* We don't need the list of input files anymore.  The second run over
1158441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project     the parameters will handle them.  */
1159441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  while (input_file_list != NULL)
1160441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    {
1161441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      struct file_list *oldp = input_file_list;
1162441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      input_file_list = input_file_list->next;
1163441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      free (oldp);
1164441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    }
1165441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1166441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  /* We also know now what kind of file we are supposed to create.  If
1167441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project     the user hasn't selected anythign we create and executable.  */
1168441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  if (ld_state.file_type == no_file_type)
1169441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    ld_state.file_type = executable_file_type;
1170441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project}
1171441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1172441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Add DIR to the list of directories searched for object files and
1173441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project   libraries.  */
1174441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectvoid
1175441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectld_new_searchdir (const char *dir)
1176441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{
1177441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  struct pathelement *newpath;
1178441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1179441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  newpath = (struct pathelement *)
1180441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    obstack_calloc (&ld_state.smem, sizeof (struct pathelement));
1181441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1182441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  newpath->pname = dir;
1183441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1184441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  /* Enqueue the file.  */
1185441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  if (ld_state.tailpaths == NULL)
1186441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    ld_state.paths = ld_state.tailpaths = newpath;
1187441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  else
1188441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    {
1189441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      ld_state.tailpaths->next = newpath;
1190441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      ld_state.tailpaths = newpath;
1191441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    }
1192441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project}
1193441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1194441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1195441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstruct usedfiles *
1196441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectld_new_inputfile (const char *fname, enum file_type type)
1197441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{
1198441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  struct usedfiles *newfile = (struct usedfiles *)
1199441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    obstack_calloc (&ld_state.smem, sizeof (struct usedfiles));
1200441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1201441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  newfile->soname = newfile->fname = newfile->rfname = fname;
1202441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  newfile->file_type = type;
1203441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  newfile->extract_rule = ld_state.extract_rule;
1204cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  newfile->as_needed = ld_state.as_needed;
1205441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  newfile->lazyload = ld_state.lazyload;
1206441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  newfile->status = not_opened;
1207441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1208441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  return newfile;
1209441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project}
1210441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1211441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1212441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Create an array listing all the sections.  We will than pass this
1213441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project   array to a system specific function which can reorder it at will.
1214441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project   The functions can also merge sections if this is what is
1215441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project   wanted.  */
1216441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void
1217441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectcollect_sections (void)
1218441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{
1219441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  void *p ;
1220441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  struct scnhead *h;
1221441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  size_t cnt;
1222441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1223441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  /* We have that many sections.  At least for now.  */
1224441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  ld_state.nallsections = ld_state.section_tab.filled;
1225441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1226441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  /* Allocate the array.  We allocate one more entry than computed so
1227441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project     far since we might need a new section for the copy relocations.  */
1228441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  ld_state.allsections =
1229441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    (struct scnhead **) obstack_alloc (&ld_state.smem,
1230441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project				       (ld_state.nallsections + 1)
1231441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project				       * sizeof (struct scnhead *));
1232441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1233441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  /* Fill the array.  We rely here on the hash table iterator to
1234441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project     return the entries in the order they were added.  */
1235441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  cnt = 0;
1236441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  p = NULL;
1237441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  while ((h = ld_section_tab_iterate (&ld_state.section_tab, &p)) != NULL)
1238441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    {
1239441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      struct scninfo *runp;
1240441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      bool used = false;
1241441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1242441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      if (h->kind == scn_normal)
1243441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	{
1244441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  runp = h->last;
1245441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  do
1246441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	    {
1247441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      if (h->type == SHT_REL || h->type == SHT_RELA)
1248441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		{
1249441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		  if (runp->used)
1250441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		    /* This is a relocation section.  If the section
1251441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		       it is relocating is used in the result so must
1252441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		       the relocation section.  */
1253441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		    runp->used
1254441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		      = runp->fileinfo->scninfo[SCNINFO_SHDR (runp->shdr).sh_info].used;
1255441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		}
1256441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1257441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      /* Accumulate the result.  */
1258441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      used |= runp->used;
1259441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1260441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      /* Next input section.  */
1261441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      runp = runp->next;
1262441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	    }
1263441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  while (runp != h->last);
1264441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1265441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  h->used = used;
1266441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	}
1267441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1268441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      ld_state.allsections[cnt++] = h;
1269441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    }
1270441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  ld_state.nusedsections = cnt;
1271441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1272441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  assert (cnt == ld_state.nallsections);
1273441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project}
1274441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1275441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1276441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Add given path to the end of list.  */
1277441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void
1278441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectadd_rxxpath (struct pathelement **pathp, const char *str)
1279441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{
1280441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  struct pathelement *newp;
1281441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1282441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  /* The path elements can in theory be freed after we read all the
1283441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project     files.  But the amount of memory we are talking about is small
1284441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project     and the cost of free() calls is not neglectable.  */
1285441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  newp = (struct pathelement *) obstack_alloc (&ld_state.smem, sizeof (*newp));
1286441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  newp->pname = str;
1287441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  newp->exist = 0;
1288441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#ifndef NDEBUG
1289441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  newp->next = NULL;
1290441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#endif
1291441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1292441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  CSNGL_LIST_ADD_REAR (*pathp, newp);
1293441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project}
1294441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1295441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1296441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Convert lists of possibly colon-separated directory lists into lists
1297441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project   where each entry is for a single directory.  */
1298441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void
1299441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectnormalize_dirlist (struct pathelement **pathp)
1300441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{
1301441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  struct pathelement *firstp = *pathp;
1302441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1303441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  do
1304441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    {
1305441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      const char *pname = (*pathp)->pname;
1306441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      const char *colonp = strchrnul (pname, ':');
1307441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1308441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      if (colonp != NULL)
1309441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	{
1310441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  struct pathelement *lastp = *pathp;
1311441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  struct pathelement *newp;
1312441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1313441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  while (1)
1314441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	    {
1315441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      if (colonp == pname)
1316441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		lastp->pname = ".";
1317441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      else
1318441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		lastp->pname = obstack_strndup (&ld_state.smem, pname,
1319441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project						colonp - pname);
1320441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1321441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      if (*colonp == '\0')
1322441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		break;
1323441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      pname = colonp + 1;
1324441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1325441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      newp = (struct pathelement *) obstack_alloc (&ld_state.smem,
1326441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project							   sizeof (*newp));
1327441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      newp->next = lastp->next;
1328441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      newp->exist = 0;
1329441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      lastp = lastp->next = newp;
1330441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1331441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      colonp = strchrnul (pname, ':');
1332441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	    }
1333441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1334441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  pathp = &lastp->next;
1335441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	}
1336441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      else
1337441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	pathp = &(*pathp)->next;
1338441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    }
1339441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  while (*pathp != firstp);
1340441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project}
1341441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1342441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1343441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Called after all parameters are parsed to bring the runpath/rpath
1344441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project   information into a usable form.  */
1345441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void
1346441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectgen_rxxpath_data (void)
1347441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{
1348441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  char *ld_library_path2;
1349441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1350441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  /* Convert the information in true single-linked lists for easy use.
1351441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project     At this point we also discard the rpath information if runpath
1352441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project     information is provided.  rpath is deprecated and should not be
1353441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project     used (or ever be invented for that matter).  */
1354441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  if (ld_state.rpath != NULL)
1355441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    {
1356441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      struct pathelement *endp = ld_state.rpath;
1357441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      ld_state.rpath = ld_state.rpath->next;
1358441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      endp->next = NULL;
1359441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    }
1360441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  if (ld_state.rpath_link != NULL)
1361441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    {
1362441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      struct pathelement *endp = ld_state.rpath_link;
1363441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      ld_state.rpath_link = ld_state.rpath_link->next;
1364441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      endp->next = NULL;
1365441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    }
1366441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1367441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  if (ld_state.runpath != NULL)
1368441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    {
1369441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      struct pathelement *endp = ld_state.runpath;
1370441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      ld_state.runpath = ld_state.runpath->next;
1371441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      endp->next = NULL;
1372441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1373441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      /* If rpath information is also available discard it.
1374441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	 XXX Should there be a possibility to avoid this?  */
1375441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      while (ld_state.rpath != NULL)
1376441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	{
1377441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  struct pathelement *old = ld_state.rpath;
1378441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  ld_state.rpath = ld_state.rpath->next;
1379441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  free (old);
1380441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	}
1381441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    }
1382441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  if (ld_state.runpath_link != NULL)
1383441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    {
1384441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      struct pathelement *endp = ld_state.runpath_link;
1385441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      ld_state.runpath_link = ld_state.runpath_link->next;
1386441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      endp->next = NULL;
1387441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1388441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      /* If rpath information is also available discard it.
1389441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	 XXX Should there be a possibility to avoid this?  */
1390441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      while (ld_state.rpath_link != NULL)
1391441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	{
1392441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  struct pathelement *old = ld_state.rpath_link;
1393441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  ld_state.rpath_link = ld_state.rpath_link->next;
1394441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  free (old);
1395441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	}
1396441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1397441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      /* The information in the strings in the list can actually be
1398441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	 directory lists themselves, with entries separated by colons.
1399441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	 Convert the list now to a list with one list entry for each
1400441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	 directory.  */
1401441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      normalize_dirlist (&ld_state.runpath_link);
1402441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    }
1403441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  else if (ld_state.rpath_link != NULL)
1404441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    /* Same as for the runpath_link above.  */
1405441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    normalize_dirlist (&ld_state.rpath_link);
1406441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1407441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1408441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  /* As a related task, handle the LD_LIBRARY_PATH value here.  First
1409441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project     we have to possibly split the value found (if it contains a
1410441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project     semicolon).  Then we have to split the value in list of
1411441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project     directories, i.e., split at the colons.  */
1412441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  if (ld_library_path1 != NULL)
1413441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    {
1414441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      ld_library_path2 = strchr (ld_library_path1, ';');
1415441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      if (ld_library_path2 == NULL)
1416441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	{
1417441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  /* If no semicolon is present the directories are looked at
1418441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	     after the -L parameters (-> ld_library_path2).  */
1419441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  ld_library_path2 = ld_library_path1;
1420441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  ld_library_path1 = NULL;
1421441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	}
1422441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      else
1423441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	{
1424441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  /* NUL terminate the first part.  */
1425441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  *ld_library_path2++ = '\0';
1426441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1427441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  /* Convert the string value in a list.  */
1428441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  add_rxxpath (&ld_state.ld_library_path1, ld_library_path1);
1429441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  normalize_dirlist (&ld_state.ld_library_path1);
1430441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	}
1431441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1432441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      add_rxxpath (&ld_state.ld_library_path2, ld_library_path2);
1433441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      normalize_dirlist (&ld_state.ld_library_path2);
1434441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    }
1435441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project}
1436441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1437441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1438441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void
1439441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectread_version_script (const char *fname)
1440441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{
1441441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  /* Open the file.  The name is supposed to be the complete (relative
1442441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project     or absolute) path.  No search along a path will be performed.  */
1443441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  ldin = fopen (fname, "r");
1444441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  if (ldin == NULL)
1445cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng    error (EXIT_FAILURE, errno, gettext ("cannot read version script '%s'"),
1446441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	   fname);
1447441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  /* No need for locking.  */
1448441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  __fsetlocking (ldin, FSETLOCKING_BYCALLER);
1449441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1450441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  /* Tell the parser that this is a version script.  */
1451441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  ld_scan_version_script = 1;
1452441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1453441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  ldlineno = 1;
1454441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  ldin_fname = fname;
1455441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  if (ldparse () != 0)
1456441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    /* Something went wrong during parsing.  */
1457441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    exit (EXIT_FAILURE);
1458441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1459441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  fclose (ldin);
1460441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project}
1461441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1462441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1463441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void
1464441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectcreate_lscript_symbols (void)
1465441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{
1466441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  /* Walk through the data from the linker script and generate all the
1467441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project     symbols which are required to be present and and those marked
1468441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project     with PROVIDE if there is a undefined reference.  */
1469441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  if (ld_state.output_segments == NULL)
1470441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    return;
1471441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1472441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  struct output_segment *segment = ld_state.output_segments->next;
1473441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  do
1474441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    {
1475441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      struct output_rule *orule;
1476441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1477441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      for (orule = segment->output_rules; orule != NULL; orule = orule->next)
1478441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	if (orule->tag == output_assignment
1479441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	    /* The assignments to "." (i.e., the PC) have to be
1480441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project               ignored here.  */
1481441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	    && strcmp (orule->val.assignment->variable, ".") != 0)
1482441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  {
1483441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	    struct symbol *s = ld_state.unresolved;
1484441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1485441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	    /* Check whether the symbol is needed.  */
1486441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	    if (likely (s != NULL))
1487441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      {
1488441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		struct symbol *first = s;
1489441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		const char *providename = orule->val.assignment->variable;
1490441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1491441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		/* Determine whether the provided symbol is still
1492441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		   undefined.  */
1493441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		// XXX TODO Loop inside a loop.  Gag!  Must rewrite.  */
1494441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		do
1495441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		  if (strcmp (s->name, providename) == 0)
1496441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		    {
1497441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		      /* Not defined but referenced.  */
1498441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		      if (unlikely (!s->defined))
1499441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project			{
1500441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project			  /* Put on the list of symbols.  First remove it from
1501441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project			     whatever list it currently is on.  */
1502441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project			  CDBL_LIST_DEL (ld_state.unresolved, s);
1503441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project			  --ld_state.nunresolved;
1504441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project			  goto use_it;
1505441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project			}
1506441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1507441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		      if (unlikely (!orule->val.assignment->provide_flag))
1508441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project			{
1509441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project			  /* The symbol is already defined and now again
1510441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project			     in the linker script.  This is an error.  */
1511441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project			  error (0, 0, gettext ("\
1512441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectduplicate definition of '%s' in linker script"),
1513441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project				 providename);
1514441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project			  goto next_rule;
1515441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project			}
1516441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		    }
1517441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		while ((s = s->next) != first);
1518441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      }
1519441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1520441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	    /* If the symbol only has to be provided if it is needed,
1521441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project               ignore it here since it is not undefined.  */
1522441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	    if (orule->val.assignment->provide_flag)
1523441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      continue;
1524441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1525441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	    /* Allocate memory for this new symbol.  */
1526441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	    s = (struct symbol *)
1527441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      obstack_calloc (&ld_state.smem, sizeof (struct symbol));
1528441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1529441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	    /* Initialize it.  */
1530441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	    s->name = orule->val.assignment->variable;
1531441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1532441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	    /* Insert it into the symbol hash table.  */
1533441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	    unsigned long int hval = elf_hash (s->name);
1534441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	    if (unlikely (ld_symbol_tab_insert (&ld_state.symbol_tab,
1535441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project						hval, s) != 0))
1536441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      {
1537441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		/* This means the symbol is defined somewhere else.
1538441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		   Maybe it comes from a DSO or so.  Get the
1539441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		   definition.  */
1540441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		free (s);
1541441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		struct symbol *old = ld_symbol_tab_find (&ld_state.symbol_tab,
1542441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project							 hval, s);
1543441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		assert (old != NULL);
1544441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		free (s);
1545441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1546441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		/* If this is a definition from the application itself
1547441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		   this means a duplicate definition.  */
1548441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		if (! old->in_dso)
1549441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		  {
1550441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		    error (0, 0, gettext ("\
1551441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectduplicate definition of '%s' in linker script"),
1552441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project			   s->name);
1553441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		    goto next_rule;
1554441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		  }
1555441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1556441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		/* We use the definition from the linker script.  */
1557441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		s = old;
1558441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      }
1559441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1560441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  use_it:
1561441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	    /* The symbol is (now) defined.  */
1562441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	    s->defined = 1;
1563441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	    s->type = STT_NOTYPE;
1564441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1565441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	    /* Add a reference to the symbol record.  We will come
1566441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	       across it when creating the output file.  */
1567441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	    orule->val.assignment->sym = s;
1568441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1569441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	    SNGL_LIST_PUSH (ld_state.lscript_syms, s);
1570441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	    ++ld_state.nlscript_syms;
1571441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1572441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  next_rule:
1573441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	    ;
1574441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  }
1575441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1576441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      segment = segment->next;
1577441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    }
1578441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  while (segment != ld_state.output_segments->next);
1579441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project}
1580441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1581441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1582441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Create creation of spection section symbols representing sections in the
1583441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project   output file.  This is done for symbols like _GLOBAL_OFFSET_TABLE_ and
1584441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project   _DYNAMIC.  */
1585441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void
1586441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectcreate_special_section_symbol (struct symbol **symp, const char *name)
1587441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{
1588441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  if (*symp == NULL)
1589441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    {
1590441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      /* No symbol defined found yet.  Create one.  */
1591441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      struct symbol *newsym = (struct symbol *)
1592441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	obstack_calloc (&ld_state.smem, sizeof (*newsym));
1593441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1594441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      newsym->name = name;
1595441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      // XXX Should we mark the symbol hidden?  They are hardly useful
1596441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      // used outside the current object.
1597441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1598441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      /* Add to the symbol table.  */
1599441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      if (unlikely (ld_symbol_tab_insert (&ld_state.symbol_tab,
1600441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project					  elf_hash (name), newsym) != 0))
1601441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	abort ();
1602441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1603441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      *symp = newsym;
1604441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    }
1605441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  else if ((*symp)->defined)
1606441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    /* Cannot happen.  We do use this symbol from any input file.  */
1607441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    abort ();
1608441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1609441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  (*symp)->defined = 1;
1610cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  (*symp)->local = 1;
1611cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  (*symp)->hidden = 1;
1612441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  (*symp)->type = STT_OBJECT;
1613441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
1614441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  ++ld_state.nsymtab;
1615441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project}
1616cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
1617cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
1618cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng#include "debugpred.h"
1619