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