/* Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
   Written by Ulrich Drepper <drepper@redhat.com>, 1998.

   This program is Open Source software; you can redistribute it and/or
   modify it under the terms of the Open Software License version 1.0 as
   published by the Open Source Initiative.

   You should have received a copy of the Open Software License along
   with this program; if not, you may obtain a copy of the Open Software
   License version 1.0 from http://www.opensource.org/licenses/osl.php or
   by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
   3001 King Ranch Road, Ukiah, CA 95482.   */

#include <config.h>

#include <errno.h>
#include <error.h>
#include <fcntl.h>
#include <gelf.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>


/* Prototypes for local functions.  */
static int handle_section (Elf *elf, Elf_Scn *scn);
static void print_bytes (Elf_Data *data);
static void print_symtab (Elf *elf, Elf_Data *data);


int
main (int argc, char *argv[])
{
  Elf *elf;
  int fd;
  int cnt;

  if (argc <= 1)
    exit (1);

  /* Open the test file.  This is given as the first parameter to the
     program.  */
  fd = open (argv[1], O_RDONLY);
  if (fd == -1)
    error (EXIT_FAILURE, errno, "cannot open input file `%s'", argv[1]);

  /* Set the library versio we expect.  */
  elf_version (EV_CURRENT);

  /* Create the ELF descriptor.  */
  elf = elf_begin (fd, ELF_C_READ, NULL);
  if (elf == NULL)
    error (EXIT_FAILURE, 0, "cannot create ELF descriptor: %s",
	   elf_errmsg (0));

  /* Now proces all the sections mentioned in the rest of the command line.  */
  for (cnt = 2; cnt < argc; ++cnt)
    if (handle_section (elf, elf_getscn (elf, atoi (argv[cnt]))) != 0)
      /* When we encounter an error stop immediately.  */
      error (EXIT_FAILURE, 0, "while processing section %d: %s", cnt,
	   elf_errmsg (0));

  /* Close the descriptor.  */
  if (elf_end (elf) != 0)
    error (EXIT_FAILURE, 0, "failure while closing ELF descriptor: %s",
	   elf_errmsg (0));

  return 0;
}


static int
handle_section (Elf *elf, Elf_Scn *scn)
{
  GElf_Ehdr *ehdr;
  GElf_Ehdr ehdr_mem;
  GElf_Shdr *shdr;
  GElf_Shdr shdr_mem;
  Elf_Data *data;

  /* First get the ELF and section header.  */
  ehdr = gelf_getehdr (elf, &ehdr_mem);
  shdr = gelf_getshdr (scn, &shdr_mem);
  if (ehdr == NULL || shdr == NULL)
    return 1;

  /* Print the information from the ELF section header.   */
  printf ("name      = %s\n"
	  "type      = %" PRId32 "\n"
	  "flags     = %" PRIx64 "\n"
	  "addr      = %" PRIx64 "\n"
	  "offset    = %" PRIx64 "\n"
	  "size      = %" PRId64 "\n"
	  "link      = %" PRId32 "\n"
	  "info      = %" PRIx32 "\n"
	  "addralign = %" PRIx64 "\n"
	  "entsize   = %" PRId64 "\n",
	  elf_strptr (elf, ehdr->e_shstrndx, shdr->sh_name),
	  shdr->sh_type,
	  shdr->sh_flags,
	  shdr->sh_addr,
	  shdr->sh_offset,
	  shdr->sh_size,
	  shdr->sh_link,
	  shdr->sh_info,
	  shdr->sh_addralign,
	  shdr->sh_entsize);

  /* Get the section data now.  */
  data = elf_getdata (scn, NULL);
  if (data == NULL)
    return 1;

  /* Now proces the different section types accordingly.  */
  switch (shdr->sh_type)
    {
    case SHT_SYMTAB:
      print_symtab (elf, data);
      break;

    case SHT_PROGBITS:
    default:
      print_bytes (data);
      break;
    }

  /* Separate form the next section.  */
  puts ("");

  /* All done correctly.  */
  return 0;
}


static void
print_bytes (Elf_Data *data)
{
  size_t size = data->d_size;
  off_t offset = data->d_off;
  unsigned char *buf = (unsigned char *) data->d_buf;
  size_t cnt;

  for (cnt = 0; cnt < size; cnt += 16)
    {
      size_t inner;

      printf ("%*Zx: ", sizeof (size_t) == 4 ? 8 : 16, (size_t) offset + cnt);

      for (inner = 0; inner < 16 && cnt + inner < size; ++inner)
	printf (" %02hhx", buf[cnt + inner]);

      puts ("");
    }
}


static void
print_symtab (Elf *elf, Elf_Data *data)
{
  int class = gelf_getclass (elf);
  size_t nsym = data->d_size / (class == ELFCLASS32
				? sizeof (Elf32_Sym) : sizeof (Elf64_Sym));
  size_t cnt;

  for (cnt = 0; cnt < nsym; ++cnt)
    {
      GElf_Sym sym_mem;
      GElf_Sym *sym = gelf_getsym (data, cnt, &sym_mem);

      printf ("%5Zu: %*" PRIx64 " %6" PRIx64 " %4d\n",
	      cnt,
	      class == ELFCLASS32 ? 8 : 16,
	      sym->st_value,
	      sym->st_size,
	      GELF_ST_TYPE (sym->st_info));
    }
}
