Home | History | Annotate | Download | only in tests
      1 /* Copyright (C) 2012 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 #include <sys/types.h>
     18 #include <sys/stat.h>
     19 #include <stdio.h>
     20 #include <stdlib.h>
     21 #include <unistd.h>
     22 #include <errno.h>
     23 #include <string.h>
     24 #include <fcntl.h>
     25 #include <gelf.h>
     26 #include <libelf.h>
     27 #include <stdbool.h>
     28 #include <inttypes.h>
     29 
     30 int
     31 main (int argc, char *argv[])
     32 {
     33   if (argc != 3)
     34     {
     35       fprintf (stderr, "Needs two arguments.\n");
     36       fprintf (stderr, "First needs to be 'READ', 'MMAP' or 'FDREAD'\n");
     37       fprintf (stderr, "Second is the ELF file to read.\n");
     38       exit (2); /* user error */
     39     }
     40 
     41   bool do_mmap = false;
     42   bool close_fd = false;
     43   if (strcmp (argv[1], "READ") == 0)
     44     {
     45       do_mmap = false;
     46       close_fd = false;
     47     }
     48   else if (strcmp (argv[1], "MMAP") == 0)
     49     {
     50       do_mmap = true;
     51       close_fd = false;
     52     }
     53   else if  (strcmp (argv[1], "FDREAD") == 0)
     54     {
     55       do_mmap = false;
     56       close_fd = true;
     57     }
     58   else
     59     {
     60       fprintf (stderr, "First arg needs to be 'READ', 'MMAP' or 'FDREAD'\n");
     61       exit (2); /* user error */
     62     }
     63 
     64   elf_version (EV_CURRENT);
     65 
     66   int fd = open (argv[2], O_RDONLY);
     67   if (fd < 0)
     68     {
     69       fprintf (stderr, "Cannot open input file %s: %s\n", argv[2],
     70 	       strerror (errno));
     71       exit (2);
     72     }
     73 
     74   Elf *elf = elf_begin (fd, do_mmap ? ELF_C_READ_MMAP : ELF_C_READ, NULL);
     75   if (elf == NULL)
     76     {
     77       fprintf (stderr, "elf_begin failed for %s: %s\n", argv[2],
     78 	       elf_errmsg (-1));
     79       exit (2);
     80     }
     81 
     82   if (! do_mmap && close_fd)
     83     {
     84       if (elf_cntl (elf, ELF_C_FDREAD) < 0)
     85 	{
     86 	  fprintf (stderr, "elf_cntl failed for %s: %s\n", argv[2],
     87 		   elf_errmsg (-1));
     88 	  exit (1);
     89 	}
     90       close (fd);
     91     }
     92 
     93   Elf_Scn *scn = NULL;
     94   while ((scn = elf_nextscn (elf, scn)) != NULL)
     95     {
     96       GElf_Shdr shdr_mem;
     97       GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
     98       printf ("Section at offset %#0" PRIx64 "\n", shdr->sh_offset);
     99     }
    100 
    101   elf_end (elf);
    102   exit (0);
    103 }
    104