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