dwarf_begin_elf.c revision b08d5a8fb42f4586d756068065186b5af7e48da
1/* Create descriptor from ELF descriptor for processing file. 2 Copyright (C) 2002, 2003, 2004, 2005 Red Hat, Inc. 3 Written by Ulrich Drepper <drepper@redhat.com>, 2002. 4 5 This program is Open Source software; you can redistribute it and/or 6 modify it under the terms of the Open Software License version 1.0 as 7 published by the Open Source Initiative. 8 9 You should have received a copy of the Open Software License along 10 with this program; if not, you may obtain a copy of the Open Software 11 License version 1.0 from http://www.opensource.org/licenses/osl.php or 12 by writing the Open Source Initiative c/o Lawrence Rosen, Esq., 13 3001 King Ranch Road, Ukiah, CA 95482. */ 14 15#ifdef HAVE_CONFIG_H 16# include <config.h> 17#endif 18 19#include <stdbool.h> 20#include <stddef.h> 21#include <stdlib.h> 22#include <string.h> 23#include <unistd.h> 24#include <sys/stat.h> 25 26#include "libdwP.h" 27 28 29/* Section names. */ 30static const char dwarf_scnnames[IDX_last][17] = 31{ 32 [IDX_debug_info] = ".debug_info", 33 [IDX_debug_abbrev] = ".debug_abbrev", 34 [IDX_debug_aranges] = ".debug_aranges", 35 [IDX_debug_line] = ".debug_line", 36 [IDX_debug_frame] = ".debug_frame", 37 [IDX_eh_frame] = ".eh_frame", 38 [IDX_debug_loc] = ".debug_loc", 39 [IDX_debug_pubnames] = ".debug_pubnames", 40 [IDX_debug_str] = ".debug_str", 41 [IDX_debug_funcnames] = ".debug_funcnames", 42 [IDX_debug_typenames] = ".debug_typenames", 43 [IDX_debug_varnames] = ".debug_varnames", 44 [IDX_debug_weaknames] = ".debug_weaknames", 45 [IDX_debug_macinfo] = ".debug_macinfo", 46 [IDX_debug_ranges] = ".debug_ranges" 47}; 48#define ndwarf_scnnames (sizeof (dwarf_scnnames) / sizeof (dwarf_scnnames[0])) 49 50 51static void 52check_section (Dwarf *result, GElf_Ehdr *ehdr, Elf_Scn *scn, bool inscngrp) 53{ 54 GElf_Shdr shdr_mem; 55 GElf_Shdr *shdr; 56 57 /* Get the section header data. */ 58 shdr = gelf_getshdr (scn, &shdr_mem); 59 if (shdr == NULL) 60 /* This should never happen. If it does something is 61 wrong in the libelf library. */ 62 abort (); 63 64 65 /* Make sure the section is part of a section group only iff we 66 really need it. If we are looking for the global (= non-section 67 group debug info) we have to ignore all the info in section 68 groups. If we are looking into a section group we cannot look at 69 a section which isn't part of the section group. */ 70 if (! inscngrp && (shdr->sh_flags & SHF_GROUP) != 0) 71 /* Ignore the section. */ 72 return; 73 74 75 /* We recognize the DWARF section by their names. This is not very 76 safe and stable but the best we can do. */ 77 const char *scnname = elf_strptr (result->elf, ehdr->e_shstrndx, 78 shdr->sh_name); 79 if (scnname == NULL) 80 { 81 /* The section name must be valid. Otherwise is the ELF file 82 invalid. */ 83 __libdw_seterrno (DWARF_E_INVALID_ELF); 84 free (result); 85 return; 86 } 87 88 89 /* Recognize the various sections. Most names start with .debug_. */ 90 size_t cnt; 91 for (cnt = 0; cnt < ndwarf_scnnames; ++cnt) 92 if (strcmp (scnname, dwarf_scnnames[cnt]) == 0) 93 { 94 /* Found it. Remember where the data is. */ 95 if (unlikely (result->sectiondata[cnt] != NULL)) 96 /* A section appears twice. That's bad. We ignore the section. */ 97 break; 98 99 /* Get the section data. */ 100 Elf_Data *data = elf_getdata (scn, NULL); 101 if (data != NULL && data->d_size != 0) 102 /* Yep, there is actually data available. */ 103 result->sectiondata[cnt] = data; 104 105 break; 106 } 107} 108 109 110/* Check whether all the necessary DWARF information is available. */ 111static Dwarf * 112valid_p (Dwarf *result) 113{ 114 /* We looked at all the sections. Now determine whether all the 115 sections with debugging information we need are there. 116 117 XXX Which sections are absolutely necessary? Add tests if 118 necessary. For now we require only .debug_info. Hopefully this 119 is correct. */ 120 if (unlikely (result->sectiondata[IDX_debug_info] == NULL)) 121 { 122 __libdw_seterrno (DWARF_E_NO_DWARF); 123 result = NULL; 124 } 125 126 return result; 127} 128 129 130static Dwarf * 131global_read (Dwarf *result, Elf *elf, GElf_Ehdr *ehdr) 132{ 133 Elf_Scn *scn = NULL; 134 135 while ((scn = elf_nextscn (elf, scn)) != NULL) 136 check_section (result, ehdr, scn, false); 137 138 return valid_p (result); 139} 140 141 142static Dwarf * 143scngrp_read (Dwarf *result, Elf *elf, GElf_Ehdr *ehdr, Elf_Scn *scngrp) 144{ 145 /* SCNGRP is the section descriptor for a section group which might 146 contain debug sections. */ 147 Elf_Data *data = elf_getdata (scngrp, NULL); 148 if (data == NULL) 149 { 150 /* We cannot read the section content. Fail! */ 151 free (result); 152 return NULL; 153 } 154 155 /* The content of the section is a number of 32-bit words which 156 represent section indices. The first word is a flag word. */ 157 Elf32_Word *scnidx = (Elf32_Word *) data->d_buf; 158 size_t cnt; 159 for (cnt = 1; cnt * sizeof (Elf32_Word) <= data->d_size; ++cnt) 160 { 161 Elf_Scn *scn = elf_getscn (elf, scnidx[cnt]); 162 if (scn == NULL) 163 { 164 /* A section group refers to a non-existing section. Should 165 never happen. */ 166 __libdw_seterrno (DWARF_E_INVALID_ELF); 167 free (result); 168 return NULL; 169 } 170 171 check_section (result, ehdr, scn, true); 172 } 173 174 return valid_p (result); 175} 176 177 178Dwarf * 179dwarf_begin_elf (elf, cmd, scngrp) 180 Elf *elf; 181 Dwarf_Cmd cmd; 182 Elf_Scn *scngrp; 183{ 184 GElf_Ehdr *ehdr; 185 GElf_Ehdr ehdr_mem; 186 187 /* Get the ELF header of the file. We need various pieces of 188 information from it. */ 189 ehdr = gelf_getehdr (elf, &ehdr_mem); 190 if (ehdr == NULL) 191 { 192 if (elf_kind (elf) != ELF_K_ELF) 193 __libdw_seterrno (DWARF_E_NOELF); 194 else 195 __libdw_seterrno (DWARF_E_GETEHDR_ERROR); 196 197 return NULL; 198 } 199 200 201 /* Default memory allocation size. */ 202 size_t mem_default_size = sysconf (_SC_PAGESIZE) - 4 * sizeof (void *); 203 204 /* Allocate the data structure. */ 205 Dwarf *result = (Dwarf *) calloc (1, sizeof (Dwarf) + mem_default_size); 206 if (result == NULL) 207 { 208 __libdw_seterrno (DWARF_E_NOMEM); 209 return NULL; 210 } 211 212 /* Fill in some values. */ 213 if ((BYTE_ORDER == LITTLE_ENDIAN && ehdr->e_ident[EI_DATA] == ELFDATA2MSB) 214 || (BYTE_ORDER == BIG_ENDIAN && ehdr->e_ident[EI_DATA] == ELFDATA2LSB)) 215 result->other_byte_order = true; 216 217 result->elf = elf; 218 219 /* Initialize the memory handling. */ 220 result->mem_default_size = mem_default_size; 221 result->oom_handler = __libdw_oom; 222 result->mem_tail = (struct libdw_memblock *) (result + 1); 223 result->mem_tail->size = (result->mem_default_size 224 - offsetof (struct libdw_memblock, mem)); 225 result->mem_tail->remaining = result->mem_tail->size; 226 result->mem_tail->prev = NULL; 227 228 229 if (cmd == DWARF_C_READ || cmd == DWARF_C_RDWR) 230 { 231 /* If the caller provides a section group we get the DWARF 232 sections only from this setion group. Otherwise we search 233 for the first section with the required name. Further 234 sections with the name are ignored. The DWARF specification 235 does not really say this is allowed. */ 236 if (scngrp == NULL) 237 return global_read (result, elf, ehdr); 238 else 239 return scngrp_read (result, elf, ehdr, scngrp); 240 } 241 else if (cmd == DWARF_C_WRITE) 242 { 243 __libdw_seterrno (DWARF_E_UNIMPL); 244 free (result); 245 return NULL; 246 } 247 248 __libdw_seterrno (DWARF_E_INVALID_CMD); 249 free (result); 250 return NULL; 251} 252INTDEF(dwarf_begin_elf) 253