1/* Copyright (C) 2015 Red Hat, Inc. 2 This file is part of elfutils. 3 4 This file is free software; you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation; either version 3 of the License, or 7 (at your option) any later version. 8 9 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 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 16 17#ifdef HAVE_CONFIG_H 18# include <config.h> 19#endif 20 21#include <sys/types.h> 22#include <sys/stat.h> 23#include <fcntl.h> 24#include <inttypes.h> 25#include <libelf.h> 26#include <gelf.h> 27#include <stdbool.h> 28#include <stdio.h> 29#include <string.h> 30#include <unistd.h> 31 32 33int 34main (int argc, char *argv[]) 35{ 36 int result = 0; 37 int cnt; 38 39 if (argc < 3 40 || (strcmp (argv[1], "read") != 0 41 && strcmp (argv[1], "mmap") != 0)) 42 { 43 printf ("Usage: (read|mmap) files...\n"); 44 return -1; 45 } 46 47 bool mmap = strcmp (argv[1], "mmap") == 0; 48 49 elf_version (EV_CURRENT); 50 51 for (cnt = 2; cnt < argc; ++cnt) 52 { 53 int fd = open (argv[cnt], O_RDONLY); 54 55 Elf *elf = elf_begin (fd, mmap ? ELF_C_READ_MMAP : ELF_C_READ, NULL); 56 if (elf == NULL) 57 { 58 printf ("%s not usable %s\n", argv[cnt], elf_errmsg (-1)); 59 result = 1; 60 close (fd); 61 continue; 62 } 63 64 /* To get the section names. */ 65 size_t strndx; 66 elf_getshdrstrndx (elf, &strndx); 67 68 Elf_Scn *scn = NULL; 69 while ((scn = elf_nextscn (elf, scn)) != NULL) 70 { 71 size_t idx = elf_ndxscn (scn); 72 GElf_Shdr mem; 73 GElf_Shdr *shdr = gelf_getshdr (scn, &mem); 74 const char *name = elf_strptr (elf, strndx, shdr->sh_name); 75 if ((shdr->sh_flags & SHF_COMPRESSED) != 0) 76 { 77 /* Real compressed section. */ 78 if (elf_compress (scn, 0, 0) < 0) 79 { 80 printf ("elf_compress failed for section %zd: %s\n", 81 idx, elf_errmsg (-1)); 82 return -1; 83 } 84 Elf_Data *d = elf_getdata (scn, NULL); 85 printf ("%zd: %s, ELF compressed, size: %zx\n", 86 idx, name, d->d_size); 87 } 88 else 89 { 90 /* Maybe an old GNU compressed .z section? */ 91 if (name[0] == '.' && name[1] == 'z') 92 { 93 if (elf_compress_gnu (scn, 0, 0) < 0) 94 { 95 printf ("elf_compress_gnu failed for section %zd: %s\n", 96 idx, elf_errmsg (-1)); 97 return -1; 98 } 99 Elf_Data *d = elf_getdata (scn, NULL); 100 printf ("%zd: %s, GNU compressed, size: %zx\n", 101 idx, name, d->d_size); 102 } 103 else 104 printf ("%zd: %s, NOT compressed\n", idx, name); 105 } 106 } 107 108 elf_end (elf); 109 close (fd); 110 } 111 112 return result; 113} 114