1441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
2441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project   Written by Ulrich Drepper <drepper@redhat.com>, 1998.
3441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
4441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project   This program is Open Source software; you can redistribute it and/or
5441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project   modify it under the terms of the Open Software License version 1.0 as
6441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project   published by the Open Source Initiative.
7441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
8441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project   You should have received a copy of the Open Software License along
9441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project   with this program; if not, you may obtain a copy of the Open Software
10441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project   License version 1.0 from http://www.opensource.org/licenses/osl.php or
11441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project   by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
12441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project   3001 King Ranch Road, Ukiah, CA 95482.   */
13441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
14441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <config.h>
15441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
16441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <errno.h>
17441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <error.h>
18441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <fcntl.h>
19441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <gelf.h>
20441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <inttypes.h>
21441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <stdio.h>
22441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <stdlib.h>
23441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <unistd.h>
24441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
25441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
26441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Prototypes for local functions.  */
27441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic int handle_section (Elf *elf, Elf_Scn *scn);
28441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void print_bytes (Elf_Data *data);
29441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void print_symtab (Elf *elf, Elf_Data *data);
30441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
31441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
32441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectint
33441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectmain (int argc, char *argv[])
34441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{
35441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  Elf *elf;
36441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  int fd;
37441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  int cnt;
38441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
39441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  if (argc <= 1)
40441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    exit (1);
41441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
42441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  /* Open the test file.  This is given as the first parameter to the
43441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project     program.  */
44441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  fd = open (argv[1], O_RDONLY);
45441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  if (fd == -1)
46441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    error (EXIT_FAILURE, errno, "cannot open input file `%s'", argv[1]);
47441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
48441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  /* Set the library versio we expect.  */
49441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  elf_version (EV_CURRENT);
50441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
51441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  /* Create the ELF descriptor.  */
52441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  elf = elf_begin (fd, ELF_C_READ, NULL);
53441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  if (elf == NULL)
54441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    error (EXIT_FAILURE, 0, "cannot create ELF descriptor: %s",
55441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	   elf_errmsg (0));
56441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
57441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  /* Now proces all the sections mentioned in the rest of the command line.  */
58441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  for (cnt = 2; cnt < argc; ++cnt)
59441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    if (handle_section (elf, elf_getscn (elf, atoi (argv[cnt]))) != 0)
60441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      /* When we encounter an error stop immediately.  */
61441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      error (EXIT_FAILURE, 0, "while processing section %d: %s", cnt,
62441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	   elf_errmsg (0));
63441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
64441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  /* Close the descriptor.  */
65441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  if (elf_end (elf) != 0)
66441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    error (EXIT_FAILURE, 0, "failure while closing ELF descriptor: %s",
67441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	   elf_errmsg (0));
68441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
69441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  return 0;
70441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project}
71441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
72441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
73441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic int
74441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projecthandle_section (Elf *elf, Elf_Scn *scn)
75441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{
76441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  GElf_Ehdr *ehdr;
77441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  GElf_Ehdr ehdr_mem;
78441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  GElf_Shdr *shdr;
79441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  GElf_Shdr shdr_mem;
80441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  Elf_Data *data;
81441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
82441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  /* First get the ELF and section header.  */
83441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  ehdr = gelf_getehdr (elf, &ehdr_mem);
84441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  shdr = gelf_getshdr (scn, &shdr_mem);
85441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  if (ehdr == NULL || shdr == NULL)
86441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    return 1;
87441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
88441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  /* Print the information from the ELF section header.   */
89441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  printf ("name      = %s\n"
90441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  "type      = %" PRId32 "\n"
91441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  "flags     = %" PRIx64 "\n"
92441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  "addr      = %" PRIx64 "\n"
93441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  "offset    = %" PRIx64 "\n"
94441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  "size      = %" PRId64 "\n"
95441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  "link      = %" PRId32 "\n"
96441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  "info      = %" PRIx32 "\n"
97441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  "addralign = %" PRIx64 "\n"
98441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  "entsize   = %" PRId64 "\n",
99441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  elf_strptr (elf, ehdr->e_shstrndx, shdr->sh_name),
100441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  shdr->sh_type,
101441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  shdr->sh_flags,
102441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  shdr->sh_addr,
103441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  shdr->sh_offset,
104441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  shdr->sh_size,
105441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  shdr->sh_link,
106441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  shdr->sh_info,
107441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  shdr->sh_addralign,
108441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  shdr->sh_entsize);
109441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
110441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  /* Get the section data now.  */
111441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  data = elf_getdata (scn, NULL);
112441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  if (data == NULL)
113441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    return 1;
114441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
115441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  /* Now proces the different section types accordingly.  */
116441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  switch (shdr->sh_type)
117441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    {
118441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    case SHT_SYMTAB:
119441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      print_symtab (elf, data);
120441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      break;
121441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
122441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    case SHT_PROGBITS:
123441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    default:
124441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      print_bytes (data);
125441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      break;
126441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    }
127441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
128441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  /* Separate form the next section.  */
129441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  puts ("");
130441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
131441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  /* All done correctly.  */
132441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  return 0;
133441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project}
134441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
135441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
136441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void
137441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectprint_bytes (Elf_Data *data)
138441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{
139441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  size_t size = data->d_size;
140441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  off_t offset = data->d_off;
141441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  unsigned char *buf = (unsigned char *) data->d_buf;
142441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  size_t cnt;
143441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
144441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  for (cnt = 0; cnt < size; cnt += 16)
145441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    {
146441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      size_t inner;
147441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
148441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      printf ("%*Zx: ", sizeof (size_t) == 4 ? 8 : 16, (size_t) offset + cnt);
149441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
150441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      for (inner = 0; inner < 16 && cnt + inner < size; ++inner)
151441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	printf (" %02hhx", buf[cnt + inner]);
152441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
153441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      puts ("");
154441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    }
155441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project}
156441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
157441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
158441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic void
159441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectprint_symtab (Elf *elf, Elf_Data *data)
160441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{
161441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  int class = gelf_getclass (elf);
162441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  size_t nsym = data->d_size / (class == ELFCLASS32
163441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project				? sizeof (Elf32_Sym) : sizeof (Elf64_Sym));
164441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  size_t cnt;
165441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
166441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  for (cnt = 0; cnt < nsym; ++cnt)
167441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    {
168441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      GElf_Sym sym_mem;
169441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      GElf_Sym *sym = gelf_getsym (data, cnt, &sym_mem);
170441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
171441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      printf ("%5Zu: %*" PRIx64 " %6" PRIx64 " %4d\n",
172441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      cnt,
173441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      class == ELFCLASS32 ? 8 : 16,
174441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      sym->st_value,
175441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      sym->st_size,
176441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      GELF_ST_TYPE (sym->st_info));
177441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    }
178441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project}
179