dwarf_begin_elf.c revision 725aad5d2f8b78ed21a5e253fb38f9722c2c8b2d
1b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Create descriptor from ELF descriptor for processing file.
2725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath   Copyright (C) 2002-2011 Red Hat, Inc.
3361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   This file is part of Red Hat elfutils.
4b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
5b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
6361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   Red Hat elfutils is free software; you can redistribute it and/or modify
7361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   it under the terms of the GNU General Public License as published by the
8361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   Free Software Foundation; version 2 of the License.
9b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
10361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   Red Hat elfutils is distributed in the hope that it will be useful, but
11361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   WITHOUT ANY WARRANTY; without even the implied warranty of
12361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   General Public License for more details.
14361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper
15361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   You should have received a copy of the GNU General Public License along
16361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   with Red Hat elfutils; if not, write to the Free Software Foundation,
171e9ef50681e20ef14c2ba38aef37a71ff148be08Ulrich Drepper   Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
18361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper
19361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   In addition, as a special exception, Red Hat, Inc. gives You the
20361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   additional right to link the code of Red Hat elfutils with code licensed
21361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   under any Open Source Initiative certified open source license
22361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   (http://www.opensource.org/licenses/index.php) which requires the
23361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   distribution of source code with any binary distribution and to
24361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   distribute linked combinations of the two.  Non-GPL Code permitted under
25361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   this exception must only link to the code of Red Hat elfutils through
26361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   those well defined interfaces identified in the file named EXCEPTION
27361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   found in the source code files (the "Approved Interfaces").  The files
28361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   of Non-GPL Code may instantiate templates or use macros or inline
29361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   functions from the Approved Interfaces without causing the resulting
30361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   work to be covered by the GNU General Public License.  Only Red Hat,
31361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   Inc. may make changes or additions to the list of Approved Interfaces.
32361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   Red Hat's grant of this exception is conditioned upon your not adding
33361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   any new exceptions.  If you wish to add a new Approved Interface or
34361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   exception, please contact Red Hat.  You must obey the GNU General Public
35361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   License in all respects for all of the Red Hat elfutils code and other
36361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   code used in conjunction with Red Hat elfutils except the Non-GPL Code
37361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   covered by this exception.  If you modify this file, you may extend this
38361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   exception to your version of the file, but you are not obligated to do
39361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   so.  If you do not wish to provide this exception without modification,
40361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   you must delete this exception statement from your version and license
41361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   this file solely under the GPL without exception.
42361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper
43361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   Red Hat elfutils is an included package of the Open Invention Network.
44361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   An included package of the Open Invention Network is a package for which
45361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   Open Invention Network licensees cross-license their patents.  No patent
46361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   license is granted, either expressly or impliedly, by designation as an
47361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   included package.  Should you wish to participate in the Open Invention
48361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   Network licensing program, please visit www.openinventionnetwork.com
49361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   <http://www.openinventionnetwork.com>.  */
50b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
51b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#ifdef HAVE_CONFIG_H
52b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper# include <config.h>
53b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#endif
54b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
55b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <stdbool.h>
56b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <stddef.h>
57b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <stdlib.h>
58b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <string.h>
59b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <unistd.h>
60b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <sys/stat.h>
61b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
62b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include "libdwP.h"
63b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
64725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath#if USE_ZLIB
65725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath# include <endian.h>
66725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath# define crc32		loser_crc32
67725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath# include <zlib.h>
68725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath# undef crc32
69725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath#endif
70725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath
71b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
72b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Section names.  */
73b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic const char dwarf_scnnames[IDX_last][17] =
74b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
75b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  [IDX_debug_info] = ".debug_info",
76827d4d176b989c5d765c7f349edff6f994f8ea78Roland McGrath  [IDX_debug_types] = ".debug_types",
77b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  [IDX_debug_abbrev] = ".debug_abbrev",
78b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  [IDX_debug_aranges] = ".debug_aranges",
79b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  [IDX_debug_line] = ".debug_line",
80b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  [IDX_debug_frame] = ".debug_frame",
81b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  [IDX_debug_loc] = ".debug_loc",
82b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  [IDX_debug_pubnames] = ".debug_pubnames",
83b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  [IDX_debug_str] = ".debug_str",
84b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  [IDX_debug_macinfo] = ".debug_macinfo",
85b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  [IDX_debug_ranges] = ".debug_ranges"
86b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper};
87b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#define ndwarf_scnnames (sizeof (dwarf_scnnames) / sizeof (dwarf_scnnames[0]))
88b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
89b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
90c07fbb3ff74a8c7b4916ff8155060a35f4b08aaaUlrich Drepperstatic Dwarf *
91b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppercheck_section (Dwarf *result, GElf_Ehdr *ehdr, Elf_Scn *scn, bool inscngrp)
92b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
93b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  GElf_Shdr shdr_mem;
94b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  GElf_Shdr *shdr;
95b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
96b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Get the section header data.  */
97b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  shdr = gelf_getshdr (scn, &shdr_mem);
98b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (shdr == NULL)
99b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    /* This should never happen.  If it does something is
100b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper       wrong in the libelf library.  */
101b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    abort ();
102b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
103b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper  /* Ignore any SHT_NOBITS sections.  Debugging sections should not
104b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper     have been stripped, but in case of a corrupt file we won't try
105b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper     to look at the missing data.  */
106b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper  if (unlikely (shdr->sh_type == SHT_NOBITS))
107b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper    return result;
108b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
109b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Make sure the section is part of a section group only iff we
110b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     really need it.  If we are looking for the global (= non-section
111b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     group debug info) we have to ignore all the info in section
112b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     groups.  If we are looking into a section group we cannot look at
113b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     a section which isn't part of the section group.  */
114b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (! inscngrp && (shdr->sh_flags & SHF_GROUP) != 0)
115b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    /* Ignore the section.  */
116c07fbb3ff74a8c7b4916ff8155060a35f4b08aaaUlrich Drepper    return result;
117b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
118b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
119b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* We recognize the DWARF section by their names.  This is not very
120b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     safe and stable but the best we can do.  */
121b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  const char *scnname = elf_strptr (result->elf, ehdr->e_shstrndx,
122b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper				    shdr->sh_name);
123b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (scnname == NULL)
124b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
125b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      /* The section name must be valid.  Otherwise is the ELF file
126b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	 invalid.  */
127725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath      __libdw_free_zdata (result);
128b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      __libdw_seterrno (DWARF_E_INVALID_ELF);
129b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      free (result);
130c07fbb3ff74a8c7b4916ff8155060a35f4b08aaaUlrich Drepper      return NULL;
131b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
132b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
133b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
134b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Recognize the various sections.  Most names start with .debug_.  */
135b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  size_t cnt;
136b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  for (cnt = 0; cnt < ndwarf_scnnames; ++cnt)
137b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    if (strcmp (scnname, dwarf_scnnames[cnt]) == 0)
138b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      {
139b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	/* Found it.  Remember where the data is.  */
140b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	if (unlikely (result->sectiondata[cnt] != NULL))
141b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  /* A section appears twice.  That's bad.  We ignore the section.  */
142b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  break;
143b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
144b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	/* Get the section data.  */
145b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	Elf_Data *data = elf_getdata (scn, NULL);
146b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	if (data != NULL && data->d_size != 0)
147b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  /* Yep, there is actually data available.  */
148b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  result->sectiondata[cnt] = data;
149b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
150b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	break;
151b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      }
152725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath#if USE_ZLIB
153725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath    else if (scnname[0] == '.' && scnname[1] == 'z'
154725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath	     && strcmp (&scnname[2], &dwarf_scnnames[cnt][1]) == 0)
155725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath      {
156725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath	/* A compressed section.  */
157725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath
158725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath	if (unlikely (result->sectiondata[cnt] != NULL))
159725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath	  /* A section appears twice.  That's bad.  We ignore the section.  */
160725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath	  break;
161725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath
162725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath	/* Get the section data.  */
163725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath	Elf_Data *data = elf_getdata (scn, NULL);
164725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath	if (data != NULL && data->d_size != 0)
165725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath	  {
166725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath	    /* There is a 12-byte header of "ZLIB" followed by
167725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath	       an 8-byte big-endian size.  */
168725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath
169725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath	    if (unlikely (data->d_size < 4 + 8)
170725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath		|| unlikely (memcmp (data->d_buf, "ZLIB", 4) != 0))
171725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath	      break;
172725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath
173725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath	    uint64_t size;
174725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath	    memcpy (&size, data->d_buf + 4, sizeof size);
175725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath	    size = be64toh (size);
176725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath
177725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath	    Elf_Data *zdata = malloc (sizeof (Elf_Data) + size);
178725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath	    if (unlikely (zdata == NULL))
179725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath	      break;
180725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath
181725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath	    zdata->d_buf = &zdata[1];
182725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath	    zdata->d_type = ELF_T_BYTE;
183725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath	    zdata->d_version = EV_CURRENT;
184725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath	    zdata->d_size = size;
185725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath	    zdata->d_off = 0;
186725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath	    zdata->d_align = 1;
187725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath
188725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath	    z_stream z =
189725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath	      {
190725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath		.next_in = data->d_buf + 4 + 8,
191725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath		.avail_in = data->d_size - 4 - 8,
192725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath		.next_out = zdata->d_buf,
193725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath		.avail_out = zdata->d_size
194725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath	      };
195725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath	    int zrc = inflateInit (&z);
196725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath	    while (z.avail_in > 0 && likely (zrc == Z_OK))
197725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath	      {
198725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath		z.next_out = zdata->d_buf + (zdata->d_size - z.avail_out);
199725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath		zrc = inflate (&z, Z_FINISH);
200725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath		if (unlikely (zrc != Z_STREAM_END))
201725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath		  {
202725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath		    zrc = Z_DATA_ERROR;
203725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath		    break;
204725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath		  }
205725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath		zrc = inflateReset (&z);
206725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath	      }
207725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath	    if (likely (zrc == Z_OK))
208725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath	      zrc = inflateEnd (&z);
209725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath
210725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath	    if (unlikely (zrc != Z_OK) || unlikely (z.avail_out != 0))
211725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath	      free (zdata);
212725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath	    else
213725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath	      {
214725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath		result->sectiondata[cnt] = zdata;
215725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath		result->sectiondata_gzip_mask |= 1U << cnt;
216725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath	      }
217725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath	  }
218725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath
219725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath	break;
220725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath      }
221725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath#endif
222c07fbb3ff74a8c7b4916ff8155060a35f4b08aaaUlrich Drepper
223c07fbb3ff74a8c7b4916ff8155060a35f4b08aaaUlrich Drepper  return result;
224b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}
225b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
226b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
227b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Check whether all the necessary DWARF information is available.  */
228b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic Dwarf *
229b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppervalid_p (Dwarf *result)
230b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
231b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* We looked at all the sections.  Now determine whether all the
232b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     sections with debugging information we need are there.
233b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
234b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     XXX Which sections are absolutely necessary?  Add tests if
235b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     necessary.  For now we require only .debug_info.  Hopefully this
236b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     is correct.  */
237c07fbb3ff74a8c7b4916ff8155060a35f4b08aaaUlrich Drepper  if (likely (result != NULL)
238c07fbb3ff74a8c7b4916ff8155060a35f4b08aaaUlrich Drepper      && unlikely (result->sectiondata[IDX_debug_info] == NULL))
239b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
240725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath      __libdw_free_zdata (result);
241b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      __libdw_seterrno (DWARF_E_NO_DWARF);
242c07fbb3ff74a8c7b4916ff8155060a35f4b08aaaUlrich Drepper      free (result);
243b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      result = NULL;
244b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
245b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
246b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  return result;
247b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}
248b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
249b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
250b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic Dwarf *
251b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperglobal_read (Dwarf *result, Elf *elf, GElf_Ehdr *ehdr)
252b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
253b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  Elf_Scn *scn = NULL;
254b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
255c07fbb3ff74a8c7b4916ff8155060a35f4b08aaaUlrich Drepper  while (result != NULL && (scn = elf_nextscn (elf, scn)) != NULL)
256c07fbb3ff74a8c7b4916ff8155060a35f4b08aaaUlrich Drepper    result = check_section (result, ehdr, scn, false);
257b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
258b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  return valid_p (result);
259b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}
260b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
261b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
262b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic Dwarf *
263b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperscngrp_read (Dwarf *result, Elf *elf, GElf_Ehdr *ehdr, Elf_Scn *scngrp)
264b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
265b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* SCNGRP is the section descriptor for a section group which might
266b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     contain debug sections.  */
267b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  Elf_Data *data = elf_getdata (scngrp, NULL);
268b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (data == NULL)
269b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
270b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      /* We cannot read the section content.  Fail!  */
271725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath      __libdw_free_zdata (result);
272b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      free (result);
273b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      return NULL;
274b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
275b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
276b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* The content of the section is a number of 32-bit words which
277b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     represent section indices.  The first word is a flag word.  */
278b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  Elf32_Word *scnidx = (Elf32_Word *) data->d_buf;
279b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  size_t cnt;
280b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  for (cnt = 1; cnt * sizeof (Elf32_Word) <= data->d_size; ++cnt)
281b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
282b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      Elf_Scn *scn = elf_getscn (elf, scnidx[cnt]);
283b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (scn == NULL)
284b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	{
285b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  /* A section group refers to a non-existing section.  Should
286b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	     never happen.  */
287725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath	  __libdw_free_zdata (result);
288b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  __libdw_seterrno (DWARF_E_INVALID_ELF);
289b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  free (result);
290b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  return NULL;
291b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	}
292b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
293c07fbb3ff74a8c7b4916ff8155060a35f4b08aaaUlrich Drepper      result = check_section (result, ehdr, scn, true);
294c07fbb3ff74a8c7b4916ff8155060a35f4b08aaaUlrich Drepper      if (result == NULL)
295c07fbb3ff74a8c7b4916ff8155060a35f4b08aaaUlrich Drepper	break;
296b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
297b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
298b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  return valid_p (result);
299b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}
300b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
301b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
302b08d5a8fb42f4586d756068065186b5af7e48daUlrich DrepperDwarf *
303b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperdwarf_begin_elf (elf, cmd, scngrp)
304b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     Elf *elf;
305b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     Dwarf_Cmd cmd;
306b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     Elf_Scn *scngrp;
307b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
308b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  GElf_Ehdr *ehdr;
309b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  GElf_Ehdr ehdr_mem;
310b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
311b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Get the ELF header of the file.  We need various pieces of
312b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     information from it.  */
313b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  ehdr = gelf_getehdr (elf, &ehdr_mem);
314b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (ehdr == NULL)
315b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
316b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (elf_kind (elf) != ELF_K_ELF)
317b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	__libdw_seterrno (DWARF_E_NOELF);
318b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      else
319b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	__libdw_seterrno (DWARF_E_GETEHDR_ERROR);
320b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
321b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      return NULL;
322b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
323b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
324b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
325b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Default memory allocation size.  */
326b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  size_t mem_default_size = sysconf (_SC_PAGESIZE) - 4 * sizeof (void *);
327b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
328b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Allocate the data structure.  */
329b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  Dwarf *result = (Dwarf *) calloc (1, sizeof (Dwarf) + mem_default_size);
3303e0f7d1d1b817040cef82f41879f471ab59b663eRoland McGrath  if (unlikely (result == NULL)
3313e0f7d1d1b817040cef82f41879f471ab59b663eRoland McGrath      || unlikely (Dwarf_Sig8_Hash_init (&result->sig8_hash, 11) < 0))
332b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
3333e0f7d1d1b817040cef82f41879f471ab59b663eRoland McGrath      free (result);
334b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      __libdw_seterrno (DWARF_E_NOMEM);
335b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      return NULL;
336b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
337b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
338b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Fill in some values.  */
339b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if ((BYTE_ORDER == LITTLE_ENDIAN && ehdr->e_ident[EI_DATA] == ELFDATA2MSB)
340b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      || (BYTE_ORDER == BIG_ENDIAN && ehdr->e_ident[EI_DATA] == ELFDATA2LSB))
341b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    result->other_byte_order = true;
342b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
343b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  result->elf = elf;
344b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
345b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Initialize the memory handling.  */
346b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  result->mem_default_size = mem_default_size;
347b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  result->oom_handler = __libdw_oom;
348b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  result->mem_tail = (struct libdw_memblock *) (result + 1);
349b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  result->mem_tail->size = (result->mem_default_size
350b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			    - offsetof (struct libdw_memblock, mem));
351b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  result->mem_tail->remaining = result->mem_tail->size;
352b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  result->mem_tail->prev = NULL;
353b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
354b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (cmd == DWARF_C_READ || cmd == DWARF_C_RDWR)
355b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
356b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      /* If the caller provides a section group we get the DWARF
357b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	 sections only from this setion group.  Otherwise we search
358b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	 for the first section with the required name.  Further
359b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	 sections with the name are ignored.  The DWARF specification
360b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	 does not really say this is allowed.  */
361b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (scngrp == NULL)
362b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	return global_read (result, elf, ehdr);
363b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      else
364b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	return scngrp_read (result, elf, ehdr, scngrp);
365b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
366b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  else if (cmd == DWARF_C_WRITE)
367b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
368b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      __libdw_seterrno (DWARF_E_UNIMPL);
369b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      free (result);
370b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      return NULL;
371b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
372b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
373b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  __libdw_seterrno (DWARF_E_INVALID_CMD);
374b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  free (result);
375b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  return NULL;
376b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}
377b08d5a8fb42f4586d756068065186b5af7e48daUlrich DrepperINTDEF(dwarf_begin_elf)
378