125b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Functions to handle creation of Linux archives. 225b3c049e70834cf33790a28643ab058b507b35cBen Cheng Copyright (C) 2007-2012 Red Hat, Inc. 325b3c049e70834cf33790a28643ab058b507b35cBen Cheng Written by Ulrich Drepper <drepper@redhat.com>, 2007. 425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 525b3c049e70834cf33790a28643ab058b507b35cBen Cheng Red Hat elfutils is free software; you can redistribute it and/or modify 625b3c049e70834cf33790a28643ab058b507b35cBen Cheng it under the terms of the GNU General Public License as published by the 725b3c049e70834cf33790a28643ab058b507b35cBen Cheng Free Software Foundation; version 2 of the License. 825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 925b3c049e70834cf33790a28643ab058b507b35cBen Cheng Red Hat elfutils is distributed in the hope that it will be useful, but 1025b3c049e70834cf33790a28643ab058b507b35cBen Cheng WITHOUT ANY WARRANTY; without even the implied warranty of 1125b3c049e70834cf33790a28643ab058b507b35cBen Cheng MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1225b3c049e70834cf33790a28643ab058b507b35cBen Cheng General Public License for more details. 1325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 1425b3c049e70834cf33790a28643ab058b507b35cBen Cheng You should have received a copy of the GNU General Public License along 1525b3c049e70834cf33790a28643ab058b507b35cBen Cheng with Red Hat elfutils; if not, write to the Free Software Foundation, 1625b3c049e70834cf33790a28643ab058b507b35cBen Cheng Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. 1725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 1825b3c049e70834cf33790a28643ab058b507b35cBen Cheng Red Hat elfutils is an included package of the Open Invention Network. 1925b3c049e70834cf33790a28643ab058b507b35cBen Cheng An included package of the Open Invention Network is a package for which 2025b3c049e70834cf33790a28643ab058b507b35cBen Cheng Open Invention Network licensees cross-license their patents. No patent 2125b3c049e70834cf33790a28643ab058b507b35cBen Cheng license is granted, either expressly or impliedly, by designation as an 2225b3c049e70834cf33790a28643ab058b507b35cBen Cheng included package. Should you wish to participate in the Open Invention 2325b3c049e70834cf33790a28643ab058b507b35cBen Cheng Network licensing program, please visit www.openinventionnetwork.com 2425b3c049e70834cf33790a28643ab058b507b35cBen Cheng <http://www.openinventionnetwork.com>. */ 2525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 2625b3c049e70834cf33790a28643ab058b507b35cBen Cheng#ifdef HAVE_CONFIG_H 2725b3c049e70834cf33790a28643ab058b507b35cBen Cheng# include <config.h> 2825b3c049e70834cf33790a28643ab058b507b35cBen Cheng#endif 2925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 3025b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <assert.h> 3125b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <error.h> 3225b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <gelf.h> 3325b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <libintl.h> 3425b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <stdio.h> 3525b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <stdlib.h> 3625b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <time.h> 3725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 3825b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include <system.h> 3925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 4025b3c049e70834cf33790a28643ab058b507b35cBen Cheng#include "arlib.h" 4125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 4225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 4325b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* The one symbol table we hanble. */ 4425b3c049e70834cf33790a28643ab058b507b35cBen Chengstruct arlib_symtab symtab; 4525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 4625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 4725b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Initialize ARLIB_SYMTAB structure. */ 4825b3c049e70834cf33790a28643ab058b507b35cBen Chengvoid 4925b3c049e70834cf33790a28643ab058b507b35cBen Chengarlib_init (void) 5025b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 5125b3c049e70834cf33790a28643ab058b507b35cBen Cheng#define obstack_chunk_alloc xmalloc 5225b3c049e70834cf33790a28643ab058b507b35cBen Cheng#define obstack_chunk_free free 5325b3c049e70834cf33790a28643ab058b507b35cBen Cheng obstack_init (&symtab.symsoffob); 5425b3c049e70834cf33790a28643ab058b507b35cBen Cheng obstack_init (&symtab.symsnameob); 5525b3c049e70834cf33790a28643ab058b507b35cBen Cheng obstack_init (&symtab.longnamesob); 5625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 5725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We add the archive header here as well, that avoids allocating 5825b3c049e70834cf33790a28643ab058b507b35cBen Cheng another memory block. */ 5925b3c049e70834cf33790a28643ab058b507b35cBen Cheng struct ar_hdr ar_hdr; 6025b3c049e70834cf33790a28643ab058b507b35cBen Cheng memcpy (ar_hdr.ar_name, "/ ", sizeof (ar_hdr.ar_name)); 6125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Using snprintf here has a problem: the call always wants to add a 6225b3c049e70834cf33790a28643ab058b507b35cBen Cheng NUL byte. We could use a trick whereby we specify the target 6325b3c049e70834cf33790a28643ab058b507b35cBen Cheng buffer size longer than it is and this would not actually fail, 6425b3c049e70834cf33790a28643ab058b507b35cBen Cheng since all the fields are consecutive and we fill them in 6525b3c049e70834cf33790a28643ab058b507b35cBen Cheng sequence (i.e., the NUL byte gets overwritten). But 6625b3c049e70834cf33790a28643ab058b507b35cBen Cheng _FORTIFY_SOURCE=2 would not let us play these games. Therefore 6725b3c049e70834cf33790a28643ab058b507b35cBen Cheng we play it safe. */ 6825b3c049e70834cf33790a28643ab058b507b35cBen Cheng char tmpbuf[sizeof (ar_hdr.ar_date) + 1]; 6925b3c049e70834cf33790a28643ab058b507b35cBen Cheng memcpy (ar_hdr.ar_date, tmpbuf, 7025b3c049e70834cf33790a28643ab058b507b35cBen Cheng snprintf (tmpbuf, sizeof (tmpbuf), "%-*lld", 7125b3c049e70834cf33790a28643ab058b507b35cBen Cheng (int) sizeof (ar_hdr.ar_date), 7225b3c049e70834cf33790a28643ab058b507b35cBen Cheng (arlib_deterministic_output ? 0 7325b3c049e70834cf33790a28643ab058b507b35cBen Cheng : (long long int) time (NULL)))); 7425b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert ((sizeof (struct ar_hdr) % sizeof (uint32_t)) == 0); 7525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 7625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Note the string for the ar_uid and ar_gid cases is longer than 7725b3c049e70834cf33790a28643ab058b507b35cBen Cheng necessary. This does not matter since we copy only as much as 7825b3c049e70834cf33790a28643ab058b507b35cBen Cheng necessary but it helps the compiler to use the same string for 7925b3c049e70834cf33790a28643ab058b507b35cBen Cheng the ar_mode case. */ 8025b3c049e70834cf33790a28643ab058b507b35cBen Cheng memcpy (ar_hdr.ar_uid, "0 ", sizeof (ar_hdr.ar_uid)); 8125b3c049e70834cf33790a28643ab058b507b35cBen Cheng memcpy (ar_hdr.ar_gid, "0 ", sizeof (ar_hdr.ar_gid)); 8225b3c049e70834cf33790a28643ab058b507b35cBen Cheng memcpy (ar_hdr.ar_mode, "0 ", sizeof (ar_hdr.ar_mode)); 8325b3c049e70834cf33790a28643ab058b507b35cBen Cheng memcpy (ar_hdr.ar_fmag, ARFMAG, sizeof (ar_hdr.ar_fmag)); 8425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 8525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Add the archive header to the file content. */ 8625b3c049e70834cf33790a28643ab058b507b35cBen Cheng obstack_grow (&symtab.symsoffob, &ar_hdr, sizeof (ar_hdr)); 8725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 8825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* The first word in the offset table specifies the size. Create 8925b3c049e70834cf33790a28643ab058b507b35cBen Cheng such an entry now. The real value will be filled-in later. For 9025b3c049e70834cf33790a28643ab058b507b35cBen Cheng all supported platforms the following is true. */ 9125b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (sizeof (uint32_t) == sizeof (int)); 9225b3c049e70834cf33790a28643ab058b507b35cBen Cheng obstack_int_grow (&symtab.symsoffob, 0); 9325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 9425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* The long name obstack also gets its archive header. As above, 9525b3c049e70834cf33790a28643ab058b507b35cBen Cheng some of the input strings are longer than required but we only 9625b3c049e70834cf33790a28643ab058b507b35cBen Cheng copy the necessary part. */ 9725b3c049e70834cf33790a28643ab058b507b35cBen Cheng memcpy (ar_hdr.ar_name, "// ", sizeof (ar_hdr.ar_name)); 9825b3c049e70834cf33790a28643ab058b507b35cBen Cheng memcpy (ar_hdr.ar_date, " ", sizeof (ar_hdr.ar_date)); 9925b3c049e70834cf33790a28643ab058b507b35cBen Cheng memcpy (ar_hdr.ar_uid, " ", sizeof (ar_hdr.ar_uid)); 10025b3c049e70834cf33790a28643ab058b507b35cBen Cheng memcpy (ar_hdr.ar_gid, " ", sizeof (ar_hdr.ar_gid)); 10125b3c049e70834cf33790a28643ab058b507b35cBen Cheng memcpy (ar_hdr.ar_mode, " ", sizeof (ar_hdr.ar_mode)); 10225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* The ar_size field will be filled in later and ar_fmag is already OK. */ 10325b3c049e70834cf33790a28643ab058b507b35cBen Cheng obstack_grow (&symtab.longnamesob, &ar_hdr, sizeof (ar_hdr)); 10425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 10525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* All other members are zero. */ 10625b3c049e70834cf33790a28643ab058b507b35cBen Cheng symtab.symsofflen = 0; 10725b3c049e70834cf33790a28643ab058b507b35cBen Cheng symtab.symsoff = NULL; 10825b3c049e70834cf33790a28643ab058b507b35cBen Cheng symtab.symsnamelen = 0; 10925b3c049e70834cf33790a28643ab058b507b35cBen Cheng symtab.symsname = NULL; 11025b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 11125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 11225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 11325b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Finalize ARLIB_SYMTAB content. */ 11425b3c049e70834cf33790a28643ab058b507b35cBen Chengvoid 11525b3c049e70834cf33790a28643ab058b507b35cBen Chengarlib_finalize (void) 11625b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 11725b3c049e70834cf33790a28643ab058b507b35cBen Cheng char tmpbuf[sizeof (((struct ar_hdr *) NULL)->ar_size) + 1]; 11825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 11925b3c049e70834cf33790a28643ab058b507b35cBen Cheng symtab.longnameslen = obstack_object_size (&symtab.longnamesob); 12025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (symtab.longnameslen != sizeof (struct ar_hdr)) 12125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 12225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if ((symtab.longnameslen & 1) != 0) 12325b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 12425b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Add one more byte to make length even. */ 12525b3c049e70834cf33790a28643ab058b507b35cBen Cheng obstack_grow (&symtab.longnamesob, "\n", 1); 12625b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++symtab.longnameslen; 12725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 12825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 12925b3c049e70834cf33790a28643ab058b507b35cBen Cheng symtab.longnames = obstack_finish (&symtab.longnamesob); 13025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 13125b3c049e70834cf33790a28643ab058b507b35cBen Cheng memcpy (&((struct ar_hdr *) symtab.longnames)->ar_size, tmpbuf, 13225b3c049e70834cf33790a28643ab058b507b35cBen Cheng snprintf (tmpbuf, sizeof (tmpbuf), "%-*zu", 13325b3c049e70834cf33790a28643ab058b507b35cBen Cheng (int) sizeof (((struct ar_hdr *) NULL)->ar_size), 13425b3c049e70834cf33790a28643ab058b507b35cBen Cheng symtab.longnameslen - sizeof (struct ar_hdr))); 13525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 13625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 13725b3c049e70834cf33790a28643ab058b507b35cBen Cheng symtab.symsofflen = obstack_object_size (&symtab.symsoffob); 13825b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (symtab.symsofflen % sizeof (uint32_t) == 0); 13925b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (symtab.symsofflen != 0) 14025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 14125b3c049e70834cf33790a28643ab058b507b35cBen Cheng symtab.symsoff = (uint32_t *) obstack_finish (&symtab.symsoffob); 14225b3c049e70834cf33790a28643ab058b507b35cBen Cheng 14325b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Fill in the number of offsets now. */ 14425b3c049e70834cf33790a28643ab058b507b35cBen Cheng symtab.symsoff[AR_HDR_WORDS] = le_bswap_32 ((symtab.symsofflen 14525b3c049e70834cf33790a28643ab058b507b35cBen Cheng - sizeof (struct ar_hdr)) 14625b3c049e70834cf33790a28643ab058b507b35cBen Cheng / sizeof (uint32_t) - 1); 14725b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 14825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 14925b3c049e70834cf33790a28643ab058b507b35cBen Cheng symtab.symsnamelen = obstack_object_size (&symtab.symsnameob); 15025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if ((symtab.symsnamelen & 1) != 0) 15125b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 15225b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Add one more NUL byte to make length even. */ 15325b3c049e70834cf33790a28643ab058b507b35cBen Cheng obstack_grow (&symtab.symsnameob, "", 1); 15425b3c049e70834cf33790a28643ab058b507b35cBen Cheng ++symtab.symsnamelen; 15525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 15625b3c049e70834cf33790a28643ab058b507b35cBen Cheng symtab.symsname = obstack_finish (&symtab.symsnameob); 15725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 15825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Determine correction for the offsets in the symbol table. */ 15925b3c049e70834cf33790a28643ab058b507b35cBen Cheng off_t disp = 0; 16025b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (symtab.symsnamelen > 0) 16125b3c049e70834cf33790a28643ab058b507b35cBen Cheng disp = symtab.symsofflen + symtab.symsnamelen; 16225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (symtab.longnameslen > sizeof (struct ar_hdr)) 16325b3c049e70834cf33790a28643ab058b507b35cBen Cheng disp += symtab.longnameslen; 16425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 16525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (disp != 0 && symtab.symsoff != NULL) 16625b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 16725b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint32_t nsyms = le_bswap_32 (symtab.symsoff[AR_HDR_WORDS]); 16825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 16925b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (uint32_t cnt = 1; cnt <= nsyms; ++cnt) 17025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 17125b3c049e70834cf33790a28643ab058b507b35cBen Cheng uint32_t val = le_bswap_32 (symtab.symsoff[AR_HDR_WORDS + cnt]); 17225b3c049e70834cf33790a28643ab058b507b35cBen Cheng val += disp; 17325b3c049e70834cf33790a28643ab058b507b35cBen Cheng symtab.symsoff[AR_HDR_WORDS + cnt] = le_bswap_32 (val); 17425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 17525b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 17625b3c049e70834cf33790a28643ab058b507b35cBen Cheng 17725b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* See comment for ar_date above. */ 17825b3c049e70834cf33790a28643ab058b507b35cBen Cheng memcpy (&((struct ar_hdr *) symtab.symsoff)->ar_size, tmpbuf, 17925b3c049e70834cf33790a28643ab058b507b35cBen Cheng snprintf (tmpbuf, sizeof (tmpbuf), "%-*zu", 18025b3c049e70834cf33790a28643ab058b507b35cBen Cheng (int) sizeof (((struct ar_hdr *) NULL)->ar_size), 18125b3c049e70834cf33790a28643ab058b507b35cBen Cheng symtab.symsofflen + symtab.symsnamelen 18225b3c049e70834cf33790a28643ab058b507b35cBen Cheng - sizeof (struct ar_hdr))); 18325b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 18425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 18525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 18625b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Free resources for ARLIB_SYMTAB. */ 18725b3c049e70834cf33790a28643ab058b507b35cBen Chengvoid 18825b3c049e70834cf33790a28643ab058b507b35cBen Chengarlib_fini (void) 18925b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 19025b3c049e70834cf33790a28643ab058b507b35cBen Cheng obstack_free (&symtab.symsoffob, NULL); 19125b3c049e70834cf33790a28643ab058b507b35cBen Cheng obstack_free (&symtab.symsnameob, NULL); 19225b3c049e70834cf33790a28643ab058b507b35cBen Cheng obstack_free (&symtab.longnamesob, NULL); 19325b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 19425b3c049e70834cf33790a28643ab058b507b35cBen Cheng 19525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 19625b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Add name a file offset of a symbol. */ 19725b3c049e70834cf33790a28643ab058b507b35cBen Chengvoid 19825b3c049e70834cf33790a28643ab058b507b35cBen Chengarlib_add_symref (const char *symname, off_t symoff) 19925b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 20025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* For all supported platforms the following is true. */ 20125b3c049e70834cf33790a28643ab058b507b35cBen Cheng assert (sizeof (uint32_t) == sizeof (int)); 20225b3c049e70834cf33790a28643ab058b507b35cBen Cheng obstack_int_grow (&symtab.symsoffob, (int) le_bswap_32 (symoff)); 20325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 20425b3c049e70834cf33790a28643ab058b507b35cBen Cheng size_t symname_len = strlen (symname) + 1; 20525b3c049e70834cf33790a28643ab058b507b35cBen Cheng obstack_grow (&symtab.symsnameob, symname, symname_len); 20625b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 20725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 20825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 20925b3c049e70834cf33790a28643ab058b507b35cBen Cheng/* Add symbols from ELF with value OFFSET to the symbol table SYMTAB. */ 21025b3c049e70834cf33790a28643ab058b507b35cBen Chengvoid 21125b3c049e70834cf33790a28643ab058b507b35cBen Chengarlib_add_symbols (Elf *elf, const char *arfname, const char *membername, 21225b3c049e70834cf33790a28643ab058b507b35cBen Cheng off_t off) 21325b3c049e70834cf33790a28643ab058b507b35cBen Cheng{ 21425b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (sizeof (off) > sizeof (uint32_t) && off > ~((uint32_t) 0)) 21525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* The archive is too big. */ 21625b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, gettext ("the archive '%s' is too large"), 21725b3c049e70834cf33790a28643ab058b507b35cBen Cheng arfname); 21825b3c049e70834cf33790a28643ab058b507b35cBen Cheng 21925b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We only add symbol tables for ELF files. It makes not much sense 22025b3c049e70834cf33790a28643ab058b507b35cBen Cheng to add symbols from executables but we do so for compatibility. 22125b3c049e70834cf33790a28643ab058b507b35cBen Cheng For DSOs and executables we use the dynamic symbol table, for 22225b3c049e70834cf33790a28643ab058b507b35cBen Cheng relocatable files all the DT_SYMTAB tables. */ 22325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (elf_kind (elf) != ELF_K_ELF) 22425b3c049e70834cf33790a28643ab058b507b35cBen Cheng return; 22525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 22625b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Ehdr ehdr_mem; 22725b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem); 22825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ehdr == NULL) 22925b3c049e70834cf33790a28643ab058b507b35cBen Cheng error (EXIT_FAILURE, 0, gettext ("cannot read ELF header of %s(%s): %s"), 23025b3c049e70834cf33790a28643ab058b507b35cBen Cheng arfname, membername, elf_errmsg (-1)); 23125b3c049e70834cf33790a28643ab058b507b35cBen Cheng 23225b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Word symtype; 23325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ehdr->e_type == ET_REL) 23425b3c049e70834cf33790a28643ab058b507b35cBen Cheng symtype = SHT_SYMTAB; 23525b3c049e70834cf33790a28643ab058b507b35cBen Cheng else if (ehdr->e_type == ET_EXEC || ehdr->e_type == ET_DYN) 23625b3c049e70834cf33790a28643ab058b507b35cBen Cheng symtype = SHT_DYNSYM; 23725b3c049e70834cf33790a28643ab058b507b35cBen Cheng else 23825b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* We do not handle that type. */ 23925b3c049e70834cf33790a28643ab058b507b35cBen Cheng return; 24025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 24125b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Iterate over all sections. */ 24225b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Scn *scn = NULL; 24325b3c049e70834cf33790a28643ab058b507b35cBen Cheng while ((scn = elf_nextscn (elf, scn)) != NULL) 24425b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 24525b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Get the section header. */ 24625b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr shdr_mem; 24725b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem); 24825b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (shdr == NULL) 24925b3c049e70834cf33790a28643ab058b507b35cBen Cheng continue; 25025b3c049e70834cf33790a28643ab058b507b35cBen Cheng 25125b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (shdr->sh_type != symtype) 25225b3c049e70834cf33790a28643ab058b507b35cBen Cheng continue; 25325b3c049e70834cf33790a28643ab058b507b35cBen Cheng 25425b3c049e70834cf33790a28643ab058b507b35cBen Cheng Elf_Data *data = elf_getdata (scn, NULL); 25525b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (data == NULL) 25625b3c049e70834cf33790a28643ab058b507b35cBen Cheng continue; 25725b3c049e70834cf33790a28643ab058b507b35cBen Cheng 25825b3c049e70834cf33790a28643ab058b507b35cBen Cheng int nsyms = shdr->sh_size / shdr->sh_entsize; 25925b3c049e70834cf33790a28643ab058b507b35cBen Cheng for (int ndx = shdr->sh_info; ndx < nsyms; ++ndx) 26025b3c049e70834cf33790a28643ab058b507b35cBen Cheng { 26125b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Sym sym_mem; 26225b3c049e70834cf33790a28643ab058b507b35cBen Cheng GElf_Sym *sym = gelf_getsym (data, ndx, &sym_mem); 26325b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (sym == NULL) 26425b3c049e70834cf33790a28643ab058b507b35cBen Cheng continue; 26525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 26625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Ignore undefined symbols. */ 26725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (sym->st_shndx == SHN_UNDEF) 26825b3c049e70834cf33790a28643ab058b507b35cBen Cheng continue; 26925b3c049e70834cf33790a28643ab058b507b35cBen Cheng 27025b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Use this symbol. */ 27125b3c049e70834cf33790a28643ab058b507b35cBen Cheng const char *symname = elf_strptr (elf, shdr->sh_link, sym->st_name); 27225b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (symname != NULL) 27325b3c049e70834cf33790a28643ab058b507b35cBen Cheng arlib_add_symref (symname, off); 27425b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 27525b3c049e70834cf33790a28643ab058b507b35cBen Cheng 27625b3c049e70834cf33790a28643ab058b507b35cBen Cheng /* Only relocatable files can have more than one symbol table. */ 27725b3c049e70834cf33790a28643ab058b507b35cBen Cheng if (ehdr->e_type != ET_REL) 27825b3c049e70834cf33790a28643ab058b507b35cBen Cheng break; 27925b3c049e70834cf33790a28643ab058b507b35cBen Cheng } 28025b3c049e70834cf33790a28643ab058b507b35cBen Cheng} 281