1b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Create descriptor from ELF descriptor for processing file.
290659075adc29213ec0f86fd08f39c7e571fb061Jonathan Lebon   Copyright (C) 2002-2011, 2014, 2015 Red Hat, Inc.
3de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard   This file is part of elfutils.
4b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
5b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
6de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard   This file is free software; you can redistribute it and/or modify
7de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard   it under the terms of either
8b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
9de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard     * the GNU Lesser General Public License as published by the Free
10de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard       Software Foundation; either version 3 of the License, or (at
11de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard       your option) any later version
12de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard
13de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard   or
14de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard
15de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard     * the GNU General Public License as published by the Free
16de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard       Software Foundation; either version 2 of the License, or (at
17de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard       your option) any later version
18de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard
19de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard   or both in parallel, as here.
20de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard
21de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard   elfutils is distributed in the hope that it will be useful, but
22361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   WITHOUT ANY WARRANTY; without even the implied warranty of
23361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
24361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper   General Public License for more details.
25361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper
26de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard   You should have received copies of the GNU General Public License and
27de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard   the GNU Lesser General Public License along with this program.  If
28de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard   not, see <http://www.gnu.org/licenses/>.  */
29b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
30b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#ifdef HAVE_CONFIG_H
31b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper# include <config.h>
32b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#endif
33b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
34775375e3bd177cb19acb5020b6e0917551807276Mark Wielaard#include <assert.h>
35b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <stdbool.h>
36b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <stddef.h>
37b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <stdlib.h>
38775375e3bd177cb19acb5020b6e0917551807276Mark Wielaard#include <stdio.h>
39b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <string.h>
40b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <unistd.h>
41775375e3bd177cb19acb5020b6e0917551807276Mark Wielaard#include <sys/types.h>
42b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <sys/stat.h>
43775375e3bd177cb19acb5020b6e0917551807276Mark Wielaard#include <fcntl.h>
44b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
45b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include "libdwP.h"
46b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
47b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
48b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Section names.  */
49efa72a02de8a3bbbc43c8de659697df5d425ea7eFlorian Weimerstatic const char dwarf_scnnames[IDX_last][18] =
50b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
51b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  [IDX_debug_info] = ".debug_info",
52827d4d176b989c5d765c7f349edff6f994f8ea78Roland McGrath  [IDX_debug_types] = ".debug_types",
53b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  [IDX_debug_abbrev] = ".debug_abbrev",
54b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  [IDX_debug_aranges] = ".debug_aranges",
55b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  [IDX_debug_line] = ".debug_line",
56b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  [IDX_debug_frame] = ".debug_frame",
57b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  [IDX_debug_loc] = ".debug_loc",
58b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  [IDX_debug_pubnames] = ".debug_pubnames",
59b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  [IDX_debug_str] = ".debug_str",
60b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  [IDX_debug_macinfo] = ".debug_macinfo",
61a0172d75311f36adb6db58000474d31f8a9cd553Mark Wielaard  [IDX_debug_macro] = ".debug_macro",
62efa72a02de8a3bbbc43c8de659697df5d425ea7eFlorian Weimer  [IDX_debug_ranges] = ".debug_ranges",
63efa72a02de8a3bbbc43c8de659697df5d425ea7eFlorian Weimer  [IDX_gnu_debugaltlink] = ".gnu_debugaltlink"
64b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper};
65b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#define ndwarf_scnnames (sizeof (dwarf_scnnames) / sizeof (dwarf_scnnames[0]))
66b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
67c07fbb3ff74a8c7b4916ff8155060a35f4b08aaaUlrich Drepperstatic Dwarf *
68b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppercheck_section (Dwarf *result, GElf_Ehdr *ehdr, Elf_Scn *scn, bool inscngrp)
69b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
70b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  GElf_Shdr shdr_mem;
71b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  GElf_Shdr *shdr;
72b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
73b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Get the section header data.  */
74b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  shdr = gelf_getshdr (scn, &shdr_mem);
75b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (shdr == NULL)
76dff2a99d84a756792f65d31fa19becce792f2ca5Jan Kratochvil    /* We may read /proc/PID/mem with only program headers mapped and section
77dff2a99d84a756792f65d31fa19becce792f2ca5Jan Kratochvil       headers out of the mapped pages.  */
78dff2a99d84a756792f65d31fa19becce792f2ca5Jan Kratochvil    goto err;
79b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
80b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper  /* Ignore any SHT_NOBITS sections.  Debugging sections should not
81b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper     have been stripped, but in case of a corrupt file we won't try
82b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper     to look at the missing data.  */
83b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper  if (unlikely (shdr->sh_type == SHT_NOBITS))
84b597dfad924980dede10d7c19d87900b6172e599Ulrich Drepper    return result;
85b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
86b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Make sure the section is part of a section group only iff we
87b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     really need it.  If we are looking for the global (= non-section
88b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     group debug info) we have to ignore all the info in section
89b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     groups.  If we are looking into a section group we cannot look at
90b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     a section which isn't part of the section group.  */
91b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (! inscngrp && (shdr->sh_flags & SHF_GROUP) != 0)
92b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    /* Ignore the section.  */
93c07fbb3ff74a8c7b4916ff8155060a35f4b08aaaUlrich Drepper    return result;
94b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
95b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
96b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* We recognize the DWARF section by their names.  This is not very
97b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     safe and stable but the best we can do.  */
98b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  const char *scnname = elf_strptr (result->elf, ehdr->e_shstrndx,
99b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper				    shdr->sh_name);
100b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (scnname == NULL)
101b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
102b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      /* The section name must be valid.  Otherwise is the ELF file
103b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	 invalid.  */
104dff2a99d84a756792f65d31fa19becce792f2ca5Jan Kratochvil    err:
10559254427e7c9eeb697de00069a9cb7dc1c908f86Mark Wielaard      Dwarf_Sig8_Hash_free (&result->sig8_hash);
106b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      __libdw_seterrno (DWARF_E_INVALID_ELF);
107b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      free (result);
108c07fbb3ff74a8c7b4916ff8155060a35f4b08aaaUlrich Drepper      return NULL;
109b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
110b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
111b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Recognize the various sections.  Most names start with .debug_.  */
112b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  size_t cnt;
113c495d754f33bd2ce3eeaaed936d8f045fbf53f30Mark Wielaard  bool gnu_compressed = false;
114b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  for (cnt = 0; cnt < ndwarf_scnnames; ++cnt)
115b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    if (strcmp (scnname, dwarf_scnnames[cnt]) == 0)
11690659075adc29213ec0f86fd08f39c7e571fb061Jonathan Lebon      break;
117725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath    else if (scnname[0] == '.' && scnname[1] == 'z'
118725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath	     && strcmp (&scnname[2], &dwarf_scnnames[cnt][1]) == 0)
119725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath      {
120c495d754f33bd2ce3eeaaed936d8f045fbf53f30Mark Wielaard        gnu_compressed = true;
12190659075adc29213ec0f86fd08f39c7e571fb061Jonathan Lebon        break;
12290659075adc29213ec0f86fd08f39c7e571fb061Jonathan Lebon      }
123725aad5d2f8b78ed21a5e253fb38f9722c2c8b2dRoland McGrath
12490659075adc29213ec0f86fd08f39c7e571fb061Jonathan Lebon  if (cnt >= ndwarf_scnnames)
12590659075adc29213ec0f86fd08f39c7e571fb061Jonathan Lebon    /* Not a debug section; ignore it. */
12690659075adc29213ec0f86fd08f39c7e571fb061Jonathan Lebon    return result;
12790659075adc29213ec0f86fd08f39c7e571fb061Jonathan Lebon
12890659075adc29213ec0f86fd08f39c7e571fb061Jonathan Lebon  if (unlikely (result->sectiondata[cnt] != NULL))
12990659075adc29213ec0f86fd08f39c7e571fb061Jonathan Lebon    /* A section appears twice.  That's bad.  We ignore the section.  */
13090659075adc29213ec0f86fd08f39c7e571fb061Jonathan Lebon    return result;
13190659075adc29213ec0f86fd08f39c7e571fb061Jonathan Lebon
132c495d754f33bd2ce3eeaaed936d8f045fbf53f30Mark Wielaard  /* We cannot know whether or not a GNU compressed section has already
133c495d754f33bd2ce3eeaaed936d8f045fbf53f30Mark Wielaard     been uncompressed or not, so ignore any errors.  */
134c495d754f33bd2ce3eeaaed936d8f045fbf53f30Mark Wielaard  if (gnu_compressed)
135c495d754f33bd2ce3eeaaed936d8f045fbf53f30Mark Wielaard    elf_compress_gnu (scn, 0, 0);
136c495d754f33bd2ce3eeaaed936d8f045fbf53f30Mark Wielaard
137c495d754f33bd2ce3eeaaed936d8f045fbf53f30Mark Wielaard  if ((shdr->sh_flags & SHF_COMPRESSED) != 0)
138c495d754f33bd2ce3eeaaed936d8f045fbf53f30Mark Wielaard    {
139c495d754f33bd2ce3eeaaed936d8f045fbf53f30Mark Wielaard      if (elf_compress (scn, 0, 0) < 0)
140c495d754f33bd2ce3eeaaed936d8f045fbf53f30Mark Wielaard	{
141c495d754f33bd2ce3eeaaed936d8f045fbf53f30Mark Wielaard	  /* If we failed to decompress the section and it's the
142c495d754f33bd2ce3eeaaed936d8f045fbf53f30Mark Wielaard	     debug_info section, then fail with specific error rather
143c495d754f33bd2ce3eeaaed936d8f045fbf53f30Mark Wielaard	     than the generic NO_DWARF. Without debug_info we can't do
144c495d754f33bd2ce3eeaaed936d8f045fbf53f30Mark Wielaard	     anything (see also valid_p()). */
145c495d754f33bd2ce3eeaaed936d8f045fbf53f30Mark Wielaard	  if (cnt == IDX_debug_info)
146c495d754f33bd2ce3eeaaed936d8f045fbf53f30Mark Wielaard	    {
147c495d754f33bd2ce3eeaaed936d8f045fbf53f30Mark Wielaard	      Dwarf_Sig8_Hash_free (&result->sig8_hash);
148c495d754f33bd2ce3eeaaed936d8f045fbf53f30Mark Wielaard	      __libdw_seterrno (DWARF_E_COMPRESSED_ERROR);
149c495d754f33bd2ce3eeaaed936d8f045fbf53f30Mark Wielaard	      free (result);
150c495d754f33bd2ce3eeaaed936d8f045fbf53f30Mark Wielaard	      return NULL;
151c495d754f33bd2ce3eeaaed936d8f045fbf53f30Mark Wielaard	    }
152c495d754f33bd2ce3eeaaed936d8f045fbf53f30Mark Wielaard	  return result;
153c495d754f33bd2ce3eeaaed936d8f045fbf53f30Mark Wielaard	}
154c495d754f33bd2ce3eeaaed936d8f045fbf53f30Mark Wielaard    }
155c495d754f33bd2ce3eeaaed936d8f045fbf53f30Mark Wielaard
15690659075adc29213ec0f86fd08f39c7e571fb061Jonathan Lebon  /* Get the section data.  */
15790659075adc29213ec0f86fd08f39c7e571fb061Jonathan Lebon  Elf_Data *data = elf_getdata (scn, NULL);
158c495d754f33bd2ce3eeaaed936d8f045fbf53f30Mark Wielaard  if (data == NULL)
159c495d754f33bd2ce3eeaaed936d8f045fbf53f30Mark Wielaard    goto err;
160c495d754f33bd2ce3eeaaed936d8f045fbf53f30Mark Wielaard
161c495d754f33bd2ce3eeaaed936d8f045fbf53f30Mark Wielaard  if (data->d_buf == NULL || data->d_size == 0)
16290659075adc29213ec0f86fd08f39c7e571fb061Jonathan Lebon    /* No data actually available, ignore it. */
16390659075adc29213ec0f86fd08f39c7e571fb061Jonathan Lebon    return result;
16490659075adc29213ec0f86fd08f39c7e571fb061Jonathan Lebon
16590659075adc29213ec0f86fd08f39c7e571fb061Jonathan Lebon  /* We can now read the section data into results. */
166c495d754f33bd2ce3eeaaed936d8f045fbf53f30Mark Wielaard  result->sectiondata[cnt] = data;
167987e3d722d1d3879c51f4ed7ab1da03a75f5f38cJonathan Lebon
168c07fbb3ff74a8c7b4916ff8155060a35f4b08aaaUlrich Drepper  return result;
169b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}
170b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
171b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
172b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* Check whether all the necessary DWARF information is available.  */
173b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic Dwarf *
174b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppervalid_p (Dwarf *result)
175b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
176b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* We looked at all the sections.  Now determine whether all the
177b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     sections with debugging information we need are there.
178b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
179b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     XXX Which sections are absolutely necessary?  Add tests if
180b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     necessary.  For now we require only .debug_info.  Hopefully this
181b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     is correct.  */
182c07fbb3ff74a8c7b4916ff8155060a35f4b08aaaUlrich Drepper  if (likely (result != NULL)
183c07fbb3ff74a8c7b4916ff8155060a35f4b08aaaUlrich Drepper      && unlikely (result->sectiondata[IDX_debug_info] == NULL))
184b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
18559254427e7c9eeb697de00069a9cb7dc1c908f86Mark Wielaard      Dwarf_Sig8_Hash_free (&result->sig8_hash);
186b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      __libdw_seterrno (DWARF_E_NO_DWARF);
187c07fbb3ff74a8c7b4916ff8155060a35f4b08aaaUlrich Drepper      free (result);
188b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      result = NULL;
189b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
190b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
1919202665816763fad8524dd78a664dbcaa157b8d4Mark Wielaard  if (result != NULL && result->sectiondata[IDX_debug_loc] != NULL)
1929202665816763fad8524dd78a664dbcaa157b8d4Mark Wielaard    {
1939202665816763fad8524dd78a664dbcaa157b8d4Mark Wielaard      result->fake_loc_cu = (Dwarf_CU *) calloc (1, sizeof (Dwarf_CU));
1949202665816763fad8524dd78a664dbcaa157b8d4Mark Wielaard      if (unlikely (result->fake_loc_cu == NULL))
1959202665816763fad8524dd78a664dbcaa157b8d4Mark Wielaard	{
1969202665816763fad8524dd78a664dbcaa157b8d4Mark Wielaard	  Dwarf_Sig8_Hash_free (&result->sig8_hash);
1979202665816763fad8524dd78a664dbcaa157b8d4Mark Wielaard	  __libdw_seterrno (DWARF_E_NOMEM);
1989202665816763fad8524dd78a664dbcaa157b8d4Mark Wielaard	  free (result);
1999202665816763fad8524dd78a664dbcaa157b8d4Mark Wielaard	  result = NULL;
2009202665816763fad8524dd78a664dbcaa157b8d4Mark Wielaard	}
2019202665816763fad8524dd78a664dbcaa157b8d4Mark Wielaard      else
2029202665816763fad8524dd78a664dbcaa157b8d4Mark Wielaard	{
2039202665816763fad8524dd78a664dbcaa157b8d4Mark Wielaard	  result->fake_loc_cu->dbg = result;
2049202665816763fad8524dd78a664dbcaa157b8d4Mark Wielaard	  result->fake_loc_cu->startp
2059202665816763fad8524dd78a664dbcaa157b8d4Mark Wielaard	    = result->sectiondata[IDX_debug_loc]->d_buf;
2069202665816763fad8524dd78a664dbcaa157b8d4Mark Wielaard	  result->fake_loc_cu->endp
2079202665816763fad8524dd78a664dbcaa157b8d4Mark Wielaard	    = (result->sectiondata[IDX_debug_loc]->d_buf
2089202665816763fad8524dd78a664dbcaa157b8d4Mark Wielaard	       + result->sectiondata[IDX_debug_loc]->d_size);
2099202665816763fad8524dd78a664dbcaa157b8d4Mark Wielaard	}
2109202665816763fad8524dd78a664dbcaa157b8d4Mark Wielaard    }
2119202665816763fad8524dd78a664dbcaa157b8d4Mark Wielaard
212b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  return result;
213b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}
214b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
215b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
216b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic Dwarf *
217b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperglobal_read (Dwarf *result, Elf *elf, GElf_Ehdr *ehdr)
218b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
219b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  Elf_Scn *scn = NULL;
220b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
221c07fbb3ff74a8c7b4916ff8155060a35f4b08aaaUlrich Drepper  while (result != NULL && (scn = elf_nextscn (elf, scn)) != NULL)
222c07fbb3ff74a8c7b4916ff8155060a35f4b08aaaUlrich Drepper    result = check_section (result, ehdr, scn, false);
223b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
224b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  return valid_p (result);
225b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}
226b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
227b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
228b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic Dwarf *
229b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperscngrp_read (Dwarf *result, Elf *elf, GElf_Ehdr *ehdr, Elf_Scn *scngrp)
230b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
231c495d754f33bd2ce3eeaaed936d8f045fbf53f30Mark Wielaard  GElf_Shdr shdr_mem;
232c495d754f33bd2ce3eeaaed936d8f045fbf53f30Mark Wielaard  GElf_Shdr *shdr = gelf_getshdr (scngrp, &shdr_mem);
233c495d754f33bd2ce3eeaaed936d8f045fbf53f30Mark Wielaard  if (shdr == NULL)
234c495d754f33bd2ce3eeaaed936d8f045fbf53f30Mark Wielaard    {
235c495d754f33bd2ce3eeaaed936d8f045fbf53f30Mark Wielaard      Dwarf_Sig8_Hash_free (&result->sig8_hash);
236c495d754f33bd2ce3eeaaed936d8f045fbf53f30Mark Wielaard      __libdw_seterrno (DWARF_E_INVALID_ELF);
237c495d754f33bd2ce3eeaaed936d8f045fbf53f30Mark Wielaard      free (result);
238c495d754f33bd2ce3eeaaed936d8f045fbf53f30Mark Wielaard      return NULL;
239c495d754f33bd2ce3eeaaed936d8f045fbf53f30Mark Wielaard    }
240c495d754f33bd2ce3eeaaed936d8f045fbf53f30Mark Wielaard
241c495d754f33bd2ce3eeaaed936d8f045fbf53f30Mark Wielaard  if ((shdr->sh_flags & SHF_COMPRESSED) != 0
242c495d754f33bd2ce3eeaaed936d8f045fbf53f30Mark Wielaard      && elf_compress (scngrp, 0, 0) < 0)
243c495d754f33bd2ce3eeaaed936d8f045fbf53f30Mark Wielaard    {
244c495d754f33bd2ce3eeaaed936d8f045fbf53f30Mark Wielaard      Dwarf_Sig8_Hash_free (&result->sig8_hash);
245c495d754f33bd2ce3eeaaed936d8f045fbf53f30Mark Wielaard      __libdw_seterrno (DWARF_E_COMPRESSED_ERROR);
246c495d754f33bd2ce3eeaaed936d8f045fbf53f30Mark Wielaard      free (result);
247c495d754f33bd2ce3eeaaed936d8f045fbf53f30Mark Wielaard      return NULL;
248c495d754f33bd2ce3eeaaed936d8f045fbf53f30Mark Wielaard    }
249c495d754f33bd2ce3eeaaed936d8f045fbf53f30Mark Wielaard
250b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* SCNGRP is the section descriptor for a section group which might
251b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     contain debug sections.  */
252b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  Elf_Data *data = elf_getdata (scngrp, NULL);
253b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (data == NULL)
254b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
255b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      /* We cannot read the section content.  Fail!  */
25659254427e7c9eeb697de00069a9cb7dc1c908f86Mark Wielaard      Dwarf_Sig8_Hash_free (&result->sig8_hash);
257b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      free (result);
258b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      return NULL;
259b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
260b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
261b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* The content of the section is a number of 32-bit words which
262b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     represent section indices.  The first word is a flag word.  */
263b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  Elf32_Word *scnidx = (Elf32_Word *) data->d_buf;
264b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  size_t cnt;
265b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  for (cnt = 1; cnt * sizeof (Elf32_Word) <= data->d_size; ++cnt)
266b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
267b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      Elf_Scn *scn = elf_getscn (elf, scnidx[cnt]);
268b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (scn == NULL)
269b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	{
270b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  /* A section group refers to a non-existing section.  Should
271b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	     never happen.  */
27259254427e7c9eeb697de00069a9cb7dc1c908f86Mark Wielaard	  Dwarf_Sig8_Hash_free (&result->sig8_hash);
273b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  __libdw_seterrno (DWARF_E_INVALID_ELF);
274b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  free (result);
275b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	  return NULL;
276b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	}
277b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
278c07fbb3ff74a8c7b4916ff8155060a35f4b08aaaUlrich Drepper      result = check_section (result, ehdr, scn, true);
279c07fbb3ff74a8c7b4916ff8155060a35f4b08aaaUlrich Drepper      if (result == NULL)
280c07fbb3ff74a8c7b4916ff8155060a35f4b08aaaUlrich Drepper	break;
281b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
282b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
283b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  return valid_p (result);
284b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}
285b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
286b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
287b08d5a8fb42f4586d756068065186b5af7e48daUlrich DrepperDwarf *
2881ccdfb683ad6c7e59793136c3a657ddf131cafd1Mark Wielaarddwarf_begin_elf (Elf *elf, Dwarf_Cmd cmd, Elf_Scn *scngrp)
289b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{
290b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  GElf_Ehdr *ehdr;
291b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  GElf_Ehdr ehdr_mem;
292b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
293b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Get the ELF header of the file.  We need various pieces of
294b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper     information from it.  */
295b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  ehdr = gelf_getehdr (elf, &ehdr_mem);
296b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (ehdr == NULL)
297b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
298b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (elf_kind (elf) != ELF_K_ELF)
299b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	__libdw_seterrno (DWARF_E_NOELF);
300b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      else
301b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	__libdw_seterrno (DWARF_E_GETEHDR_ERROR);
302b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
303b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      return NULL;
304b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
305b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
306b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
307b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Default memory allocation size.  */
308b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  size_t mem_default_size = sysconf (_SC_PAGESIZE) - 4 * sizeof (void *);
30985cc9c6c72cb90ae06831b2b6618a2584dd0a827Mark Wielaard  assert (sizeof (struct Dwarf) < mem_default_size);
310b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
311b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Allocate the data structure.  */
312b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  Dwarf *result = (Dwarf *) calloc (1, sizeof (Dwarf) + mem_default_size);
3133e0f7d1d1b817040cef82f41879f471ab59b663eRoland McGrath  if (unlikely (result == NULL)
3143e0f7d1d1b817040cef82f41879f471ab59b663eRoland McGrath      || unlikely (Dwarf_Sig8_Hash_init (&result->sig8_hash, 11) < 0))
315b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
3163e0f7d1d1b817040cef82f41879f471ab59b663eRoland McGrath      free (result);
317b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      __libdw_seterrno (DWARF_E_NOMEM);
318b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      return NULL;
319b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
320b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
321b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Fill in some values.  */
322b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if ((BYTE_ORDER == LITTLE_ENDIAN && ehdr->e_ident[EI_DATA] == ELFDATA2MSB)
323b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      || (BYTE_ORDER == BIG_ENDIAN && ehdr->e_ident[EI_DATA] == ELFDATA2LSB))
324b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    result->other_byte_order = true;
325b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
326b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  result->elf = elf;
327b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
328b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  /* Initialize the memory handling.  */
329b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  result->mem_default_size = mem_default_size;
330b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  result->oom_handler = __libdw_oom;
331b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  result->mem_tail = (struct libdw_memblock *) (result + 1);
332b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  result->mem_tail->size = (result->mem_default_size
333b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper			    - offsetof (struct libdw_memblock, mem));
334b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  result->mem_tail->remaining = result->mem_tail->size;
335b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  result->mem_tail->prev = NULL;
336b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
337b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  if (cmd == DWARF_C_READ || cmd == DWARF_C_RDWR)
338b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
339b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      /* If the caller provides a section group we get the DWARF
340b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	 sections only from this setion group.  Otherwise we search
341b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	 for the first section with the required name.  Further
342b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	 sections with the name are ignored.  The DWARF specification
343b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	 does not really say this is allowed.  */
344b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      if (scngrp == NULL)
345b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	return global_read (result, elf, ehdr);
346b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      else
347b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper	return scngrp_read (result, elf, ehdr, scngrp);
348b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
349b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  else if (cmd == DWARF_C_WRITE)
350b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    {
35159254427e7c9eeb697de00069a9cb7dc1c908f86Mark Wielaard      Dwarf_Sig8_Hash_free (&result->sig8_hash);
352b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      __libdw_seterrno (DWARF_E_UNIMPL);
353b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      free (result);
354b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper      return NULL;
355b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper    }
356b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper
35759254427e7c9eeb697de00069a9cb7dc1c908f86Mark Wielaard  Dwarf_Sig8_Hash_free (&result->sig8_hash);
358b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  __libdw_seterrno (DWARF_E_INVALID_CMD);
359b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  free (result);
360b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper  return NULL;
361b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper}
362b08d5a8fb42f4586d756068065186b5af7e48daUlrich DrepperINTDEF(dwarf_begin_elf)
363