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