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