Home | History | Annotate | Download | only in tests
      1 /* Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
      2    Written by Ulrich Drepper <drepper (at) redhat.com>, 1998.
      3 
      4    This program is Open Source software; you can redistribute it and/or
      5    modify it under the terms of the Open Software License version 1.0 as
      6    published by the Open Source Initiative.
      7 
      8    You should have received a copy of the Open Software License along
      9    with this program; if not, you may obtain a copy of the Open Software
     10    License version 1.0 from http://www.opensource.org/licenses/osl.php or
     11    by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
     12    3001 King Ranch Road, Ukiah, CA 95482.   */
     13 
     14 #include <config.h>
     15 
     16 #include <errno.h>
     17 #include <fcntl.h>
     18 #include <gelf.h>
     19 #include <stdio.h>
     20 #include <stdlib.h>
     21 #include <string.h>
     22 
     23 int
     24 main (int argc, char *argv[])
     25 {
     26   Elf *elf;
     27   int fd;
     28   GElf_Ehdr ehdr;
     29   int cnt;
     30 
     31   fd = open (argv[1], O_RDONLY);
     32   if (fd == -1)
     33     {
     34       printf ("cannot open \"%s\": %s\n", argv[1], strerror (errno));
     35       exit (1);
     36     }
     37 
     38   elf_version (EV_CURRENT);
     39 
     40   elf = elf_begin (fd, ELF_C_READ, NULL);
     41   if (elf == NULL)
     42     {
     43       printf ("cannot open ELF file: %s\n", elf_errmsg (-1));
     44       exit (1);
     45     }
     46 
     47   if (elf_kind (elf) != ELF_K_ELF)
     48     {
     49       printf ("\"%s\" is not an ELF file\n", argv[1]);
     50       exit (1);
     51     }
     52 
     53   if (gelf_getehdr (elf, &ehdr) == NULL)
     54     {
     55       printf ("cannot get the ELF header: %s\n", elf_errmsg (-1));
     56       exit (1);
     57     }
     58 
     59   printf ("idx type    %*s %*s %*s %*s %*s  align flags\n",
     60 	  gelf_getclass (elf) == ELFCLASS32 ? 9 : 17, "offset",
     61 	  gelf_getclass (elf) == ELFCLASS32 ? 10 : 18, "vaddr",
     62 	  gelf_getclass (elf) == ELFCLASS32 ? 10 : 18, "paddr",
     63 	  gelf_getclass (elf) == ELFCLASS32 ? 9 : 12, "filesz",
     64 	  gelf_getclass (elf) == ELFCLASS32 ? 9 : 12, "memsz");
     65 
     66   for (cnt = 0; cnt < ehdr.e_phnum; ++cnt)
     67     {
     68       static const char *typenames[] =
     69       {
     70 	[PT_NULL] = "NULL",
     71 	[PT_LOAD] = "LOAD",
     72 	[PT_DYNAMIC] = "DYNAMIC",
     73 	[PT_INTERP] = "INTERP",
     74 	[PT_NOTE] = "NOTE",
     75 	[PT_SHLIB] = "SHLIB",
     76 	[PT_PHDR] = "PHDR"
     77       };
     78       GElf_Phdr mem;
     79       GElf_Phdr *phdr = gelf_getphdr (elf, cnt, &mem);
     80       char buf[19];
     81       const char *p_type = typenames[phdr->p_type];
     82 
     83       /* If we don't know the name of the type we use the number value.  */
     84       if (phdr->p_type >= PT_NUM)
     85 	{
     86 	  snprintf (buf, sizeof (buf), "%x", phdr->p_type);
     87 	  p_type = buf;
     88 	}
     89 
     90       printf ("%3d %-7s %#0*llx %#0*llx %#0*llx %#0*llx %#0*llx %#6llx ",
     91 	      cnt, p_type,
     92 	      gelf_getclass (elf) == ELFCLASS32 ? 9 : 17,
     93 	      (unsigned long long int) phdr->p_offset,
     94 	      gelf_getclass (elf) == ELFCLASS32 ? 10 : 18,
     95 	      (unsigned long long int) phdr->p_vaddr,
     96 	      gelf_getclass (elf) == ELFCLASS32 ? 10 : 18,
     97 	      (unsigned long long int) phdr->p_paddr,
     98 	      gelf_getclass (elf) == ELFCLASS32 ? 9 : 12,
     99 	      (unsigned long long int) phdr->p_filesz,
    100 	      gelf_getclass (elf) == ELFCLASS32 ? 9 : 12,
    101 	      (unsigned long long int) phdr->p_memsz,
    102 	      (unsigned long long int) phdr->p_align);
    103 
    104       putc_unlocked ((phdr->p_flags & PF_X) ? 'X' : ' ', stdout);
    105       putc_unlocked ((phdr->p_flags & PF_W) ? 'W' : ' ', stdout);
    106       putc_unlocked ((phdr->p_flags & PF_R) ? 'R' : ' ', stdout);
    107 
    108       putc_unlocked ('\n', stdout);
    109 
    110       if (phdr->p_type == PT_INTERP)
    111 	{
    112 	  /* We can show the user the name of the interpreter.  */
    113 	  size_t maxsize;
    114 	  char *filedata = elf_rawfile (elf, &maxsize);
    115 
    116 	  if (filedata != NULL && phdr->p_offset < maxsize)
    117 	    printf ("\t[Requesting program interpreter: %s]\n",
    118 		    filedata + phdr->p_offset);
    119 	}
    120     }
    121 
    122   if (elf_end (elf) != 0)
    123     {
    124       printf ("error while freeing ELF descriptor: %s\n", elf_errmsg (-1));
    125       exit (1);
    126     }
    127 
    128   return 0;
    129 }
    130