1272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard/* Copyright (C) 2015 Red Hat, Inc.
2272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard   This file is part of elfutils.
3272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard
4272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard   This file is free software; you can redistribute it and/or modify
5272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard   it under the terms of the GNU General Public License as published by
6272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard   the Free Software Foundation; either version 3 of the License, or
7272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard   (at your option) any later version.
8272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard
9272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard   elfutils is distributed in the hope that it will be useful, but
10272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard   WITHOUT ANY WARRANTY; without even the implied warranty of
11272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard   GNU General Public License for more details.
13272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard
14272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard   You should have received a copy of the GNU General Public License
15272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
16272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard
17272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard#ifdef HAVE_CONFIG_H
18272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard# include <config.h>
19272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard#endif
20272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard
21272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard#include <sys/types.h>
22272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard#include <sys/stat.h>
23272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard#include <fcntl.h>
24272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard#include <inttypes.h>
25272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard#include <libelf.h>
26272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard#include <gelf.h>
27272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard#include <stdbool.h>
28272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard#include <stdio.h>
29272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard#include <string.h>
30272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard#include <unistd.h>
31272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard
32272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard
33272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaardint
34272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaardmain (int argc, char *argv[])
35272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard{
36272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard  int result = 0;
37272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard  int cnt;
38272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard
39272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard  if (argc < 3
40272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard      || (strcmp (argv[1], "read") != 0
41272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard          && strcmp (argv[1], "mmap") != 0))
42272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard    {
43272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard      printf ("Usage: (read|mmap) files...\n");
44272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard      return -1;
45272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard    }
46272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard
47272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard  bool mmap = strcmp (argv[1], "mmap") == 0;
48272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard
49272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard  elf_version (EV_CURRENT);
50272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard
51272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard  for (cnt = 2; cnt < argc; ++cnt)
52272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard    {
53272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard      int fd = open (argv[cnt], O_RDONLY);
54272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard
55272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard      Elf *elf = elf_begin (fd, mmap ? ELF_C_READ_MMAP : ELF_C_READ, NULL);
56272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard      if (elf == NULL)
57272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard	{
58272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard	  printf ("%s not usable %s\n", argv[cnt], elf_errmsg (-1));
59272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard	  result = 1;
60272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard	  close (fd);
61272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard	  continue;
62272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard	}
63272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard
64272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard      /* To get the section names.  */
65272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard      size_t strndx;
66272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard      elf_getshdrstrndx (elf, &strndx);
67272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard
68272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard      Elf_Scn *scn = NULL;
69272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard      while ((scn = elf_nextscn (elf, scn)) != NULL)
70272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard	{
71272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard	  size_t idx = elf_ndxscn (scn);
72272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard	  GElf_Shdr mem;
73272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard	  GElf_Shdr *shdr = gelf_getshdr (scn, &mem);
74272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard	  const char *name = elf_strptr (elf, strndx, shdr->sh_name);
75272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard	  if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
76272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard	    {
77272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard	      /* Real compressed section.  */
78272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard	      if (elf_compress (scn, 0, 0) < 0)
79272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard		{
80272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard		  printf ("elf_compress failed for section %zd: %s\n",
81272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard			  idx, elf_errmsg (-1));
82272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard		  return -1;
83272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard		}
84272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard	      Elf_Data *d = elf_getdata (scn, NULL);
85272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard	      printf ("%zd: %s, ELF compressed, size: %zx\n",
86272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard		      idx, name, d->d_size);
87272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard	    }
88272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard	  else
89272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard	    {
90272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard	      /* Maybe an old GNU compressed .z section?  */
91272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard	      if (name[0] == '.' && name[1] == 'z')
92272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard		{
93272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard		  if (elf_compress_gnu (scn, 0, 0) < 0)
94272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard		    {
95272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard		      printf ("elf_compress_gnu failed for section %zd: %s\n",
96272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard			      idx, elf_errmsg (-1));
97272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard		      return -1;
98272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard		    }
99272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard		  Elf_Data *d = elf_getdata (scn, NULL);
100272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard		  printf ("%zd: %s, GNU compressed, size: %zx\n",
101272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard			  idx, name, d->d_size);
102272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard		}
103272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard	      else
104272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard		printf ("%zd: %s, NOT compressed\n", idx, name);
105272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard	    }
106272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard	}
107272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard
108272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard      elf_end (elf);
109272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard      close (fd);
110272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard    }
111272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard
112272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard  return result;
113272018bba1f253bae00b5ba280ad0e0f18c04006Mark Wielaard}
114