1/* Copyright (C) 1999, 2000, 2002 Red Hat, Inc.
2   This file is part of Red Hat elfutils.
3   Written by Ulrich Drepper <drepper@redhat.com>, 1999.
4
5   Red Hat elfutils is free software; you can redistribute it and/or modify
6   it under the terms of the GNU General Public License as published by the
7   Free Software Foundation; version 2 of the License.
8
9   Red Hat elfutils is distributed in the hope that it will be useful, but
10   WITHOUT ANY WARRANTY; without even the implied warranty of
11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12   General Public License for more details.
13
14   You should have received a copy of the GNU General Public License along
15   with Red Hat elfutils; if not, write to the Free Software Foundation,
16   Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
17
18   Red Hat elfutils is an included package of the Open Invention Network.
19   An included package of the Open Invention Network is a package for which
20   Open Invention Network licensees cross-license their patents.  No patent
21   license is granted, either expressly or impliedly, by designation as an
22   included package.  Should you wish to participate in the Open Invention
23   Network licensing program, please visit www.openinventionnetwork.com
24   <http://www.openinventionnetwork.com>.  */
25
26#include <config.h>
27
28#include <fcntl.h>
29#include <libelf.h>
30#include <stdio.h>
31#include <stdlib.h>
32#include <unistd.h>
33
34
35int
36main (int argc, char *argv[])
37{
38  int fd;
39  FILE *fp;
40  Elf *elf;
41  Elf_Arsym *arsym;
42  size_t narsym;
43
44  if (argc < 3)
45    exit (1);
46
47  /* Open the archive.  */
48  fd = open (argv[1], O_RDONLY);
49  if (fd == -1)
50    {
51      printf ("Cannot open input file: %m");
52      exit (1);
53    }
54
55  /* Open the output file.  */
56  fp = fopen (argv[2], "w");
57  if (fp == NULL)
58    {
59      printf ("Cannot open output file: %m");
60      exit (1);
61    }
62
63  /* Set the ELF version.  */
64  elf_version (EV_CURRENT);
65
66  /* Create an ELF descriptor.  */
67  elf = elf_begin (fd, ELF_C_READ, NULL);
68  if (elf == NULL)
69    {
70      printf ("Cannot create ELF descriptor: %s\n", elf_errmsg (-1));
71      exit (1);
72    }
73
74  /* If it is no archive punt.  */
75  if (elf_kind (elf) != ELF_K_AR)
76    {
77      printf ("`%s' is no archive\n", argv[1]);
78      exit (1);
79    }
80
81  /* Now get the index of the archive.  */
82  arsym = elf_getarsym (elf, &narsym);
83  if (arsym == NULL)
84    {
85      printf ("Cannot get archive index: %s\n", elf_errmsg (-1));
86      exit (1);
87    }
88
89  /* If there is no element in the index do nothing.  There always is
90     an empty entry at the end which is included in the count and
91     which we want to skip.  */
92  if (narsym-- > 1)
93    while (narsym-- > 0)
94      {
95	Elf *subelf;
96	Elf_Arhdr *arhdr;
97
98	if (elf_rand (elf, arsym[narsym].as_off) != arsym[narsym].as_off)
99	  {
100	    printf ("random access for symbol `%s' fails: %s\n",
101		    arsym[narsym].as_name, elf_errmsg (-1));
102	    exit (1);
103	  }
104
105	subelf = elf_begin (fd, ELF_C_READ, elf);
106	if (subelf == NULL)
107	  {
108	    printf ("Cannot create ELF descriptor for archive member: %s\n",
109		    elf_errmsg (-1));
110	    exit (1);
111	  }
112
113	arhdr = elf_getarhdr (subelf);
114	if (arhdr == NULL)
115	  {
116	    printf ("Cannot get archive header for element `%s': %s\n",
117		    arsym[narsym].as_name, elf_errmsg (-1));
118	    exit (1);
119	  }
120
121	/* Now print what we actually want.  */
122	fprintf (fp, "%s in %s\n", arsym[narsym].as_name, arhdr->ar_name);
123
124	/* Free the ELF descriptor.  */
125	if (elf_end (subelf) != 0)
126	  {
127	    printf ("Error while freeing subELF descriptor: %s\n",
128		    elf_errmsg (-1));
129	    exit (1);
130	  }
131      }
132
133  /* Free the ELF descriptor.  */
134  if (elf_end (elf) != 0)
135    {
136      printf ("Error while freeing ELF descriptor: %s\n", elf_errmsg (-1));
137      exit (1);
138    }
139
140  close (fd);
141  fclose (fp);
142
143  return 0;
144}
145