1/* Copyright (C) 2007 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 <ar.h> 22#include <fcntl.h> 23#include <libelf.h> 24#include <stdio.h> 25#include <unistd.h> 26 27 28static int handle (const char *fname); 29 30 31int 32main (int argc, char *argv[]) 33{ 34 elf_version (EV_CURRENT); 35 36 int result = 0; 37 if (argc == 1) 38 result = handle ("a.out"); 39 else 40 for (int i = 1; i < argc; ++i) 41 result |= handle (argv[1]); 42 43 return result; 44} 45 46 47static int 48handle (const char *fname) 49{ 50 int fd = open (fname, O_RDONLY); 51 if (fd == -1) 52 { 53 printf ("cannot open '%s': %m\n", fname); 54 return 1; 55 } 56 57 Elf *elf = elf_begin (fd, ELF_C_READ_MMAP, NULL); 58 if (elf == NULL) 59 { 60 printf ("cannot get ELF handling for '%s': %s\n", 61 fname, elf_errmsg (-1)); 62 close (fd); 63 return 1; 64 } 65 66 if (elf_kind (elf) != ELF_K_AR) 67 { 68 printf ("'%s' is no archive\n", fname); 69 elf_end (elf); 70 close (fd); 71 return 1; 72 } 73 74 printf ("%s:\n", fname); 75 Elf *subelf = NULL; 76 Elf_Cmd cmd = ELF_C_READ_MMAP; 77 while ((subelf = elf_begin (fd, cmd, elf)) != NULL) 78 { 79 Elf_Arhdr *arhdr = elf_getarhdr (subelf); 80 if (arhdr == NULL) 81 { 82 printf ("cannot get archive header in '%s': %s\n", 83 fname, elf_errmsg (-1)); 84 elf_end (subelf); 85 elf_end (elf); 86 close (fd); 87 return 1; 88 } 89 90 off_t off = elf_getaroff (subelf); 91 92 printf ("\nOffset %llu\n" 93 " Name %s\n" 94 " Date %ld\n" 95 " UID %d\n" 96 " GID %d\n" 97 " Mode %o\n" 98 " Size %lld\n", 99 (unsigned long long int) off, 100 arhdr->ar_name, (long int) arhdr->ar_date, (int) arhdr->ar_uid, 101 (int) arhdr->ar_gid, 102 (int) arhdr->ar_mode, (long long int) arhdr->ar_size); 103 104 cmd = elf_next (subelf); 105 elf_end (subelf); 106 } 107 108 close (fd); 109 110 return 0; 111} 112