|
Packit Service |
97d2fb |
/* Get CFI from ELF file's exception-handling info.
|
|
Packit Service |
97d2fb |
Copyright (C) 2009-2010, 2014, 2015 Red Hat, Inc.
|
|
Packit Service |
97d2fb |
This file is part of elfutils.
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
This file is free software; you can redistribute it and/or modify
|
|
Packit Service |
97d2fb |
it under the terms of either
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
* the GNU Lesser General Public License as published by the Free
|
|
Packit Service |
97d2fb |
Software Foundation; either version 3 of the License, or (at
|
|
Packit Service |
97d2fb |
your option) any later version
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
or
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
* the GNU General Public License as published by the Free
|
|
Packit Service |
97d2fb |
Software Foundation; either version 2 of the License, or (at
|
|
Packit Service |
97d2fb |
your option) any later version
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
or both in parallel, as here.
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
elfutils is distributed in the hope that it will be useful, but
|
|
Packit Service |
97d2fb |
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
97d2fb |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit Service |
97d2fb |
General Public License for more details.
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
You should have received copies of the GNU General Public License and
|
|
Packit Service |
97d2fb |
the GNU Lesser General Public License along with this program. If
|
|
Packit Service |
97d2fb |
not, see <http://www.gnu.org/licenses/>. */
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
#ifdef HAVE_CONFIG_H
|
|
Packit Service |
97d2fb |
# include <config.h>
|
|
Packit Service |
97d2fb |
#endif
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
#include <stdlib.h>
|
|
Packit Service |
97d2fb |
#include <string.h>
|
|
Packit Service |
97d2fb |
#include <assert.h>
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
#include "libdwP.h"
|
|
Packit Service |
97d2fb |
#include "cfi.h"
|
|
Packit Service |
97d2fb |
#include "encoded-value.h"
|
|
Packit Service |
97d2fb |
#include <dwarf.h>
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
static Dwarf_CFI *
|
|
Packit Service |
97d2fb |
allocate_cfi (Elf *elf, const GElf_Ehdr *ehdr, GElf_Addr vaddr)
|
|
Packit Service |
97d2fb |
{
|
|
Packit Service |
97d2fb |
Dwarf_CFI *cfi = calloc (1, sizeof *cfi);
|
|
Packit Service |
97d2fb |
if (cfi == NULL)
|
|
Packit Service |
97d2fb |
{
|
|
Packit Service |
97d2fb |
__libdw_seterrno (DWARF_E_NOMEM);
|
|
Packit Service |
97d2fb |
return NULL;
|
|
Packit Service |
97d2fb |
}
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
cfi->e_ident = (unsigned char *) elf_getident (elf, NULL);
|
|
Packit Service |
97d2fb |
if (cfi->e_ident == NULL)
|
|
Packit Service |
97d2fb |
{
|
|
Packit Service |
97d2fb |
free (cfi);
|
|
Packit Service |
97d2fb |
__libdw_seterrno (DWARF_E_GETEHDR_ERROR);
|
|
Packit Service |
97d2fb |
return NULL;
|
|
Packit Service |
97d2fb |
}
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
cfi->e_machine = ehdr->e_machine;
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
if ((BYTE_ORDER == LITTLE_ENDIAN && cfi->e_ident[EI_DATA] == ELFDATA2MSB)
|
|
Packit Service |
97d2fb |
|| (BYTE_ORDER == BIG_ENDIAN && cfi->e_ident[EI_DATA] == ELFDATA2LSB))
|
|
Packit Service |
97d2fb |
cfi->other_byte_order = true;
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
cfi->frame_vaddr = vaddr;
|
|
Packit Service |
97d2fb |
cfi->textrel = 0; /* XXX ? */
|
|
Packit Service |
97d2fb |
cfi->datarel = 0; /* XXX ? */
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
return cfi;
|
|
Packit Service |
97d2fb |
}
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
static const uint8_t *
|
|
Packit Service |
97d2fb |
parse_eh_frame_hdr (const uint8_t *hdr, size_t hdr_size, GElf_Addr hdr_vaddr,
|
|
Packit Service |
97d2fb |
const GElf_Ehdr *ehdr, GElf_Addr *eh_frame_vaddr,
|
|
Packit Service |
97d2fb |
size_t *table_entries, uint8_t *table_encoding)
|
|
Packit Service |
97d2fb |
{
|
|
Packit Service |
97d2fb |
const uint8_t *h = hdr;
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
if (hdr_size < 4 || *h++ != 1) /* version */
|
|
Packit Service |
97d2fb |
return (void *) -1l;
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
uint8_t eh_frame_ptr_encoding = *h++;
|
|
Packit Service |
97d2fb |
uint8_t fde_count_encoding = *h++;
|
|
Packit Service |
97d2fb |
uint8_t fde_table_encoding = *h++;
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
if (eh_frame_ptr_encoding == DW_EH_PE_omit)
|
|
Packit Service |
97d2fb |
return (void *) -1l;
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
/* Dummy used by read_encoded_value. */
|
|
Packit Service |
97d2fb |
Elf_Data_Scn dummy_cfi_hdr_data =
|
|
Packit Service |
97d2fb |
{
|
|
Packit Service |
97d2fb |
.d = { .d_buf = (void *) hdr, .d_size = hdr_size }
|
|
Packit Service |
97d2fb |
};
|
|
Packit Service |
97d2fb |
Dwarf_CFI dummy_cfi =
|
|
Packit Service |
97d2fb |
{
|
|
Packit Service |
97d2fb |
.e_ident = ehdr->e_ident,
|
|
Packit Service |
97d2fb |
.datarel = hdr_vaddr,
|
|
Packit Service |
97d2fb |
.frame_vaddr = hdr_vaddr,
|
|
Packit Service |
97d2fb |
.data = &dummy_cfi_hdr_data,
|
|
Packit Service |
97d2fb |
};
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
if (unlikely (read_encoded_value (&dummy_cfi, eh_frame_ptr_encoding, &h,
|
|
Packit Service |
97d2fb |
eh_frame_vaddr)))
|
|
Packit Service |
97d2fb |
return (void *) -1l;
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
if (fde_count_encoding != DW_EH_PE_omit)
|
|
Packit Service |
97d2fb |
{
|
|
Packit Service |
97d2fb |
Dwarf_Word fde_count;
|
|
Packit Service |
97d2fb |
if (unlikely (read_encoded_value (&dummy_cfi, fde_count_encoding, &h,
|
|
Packit Service |
97d2fb |
&fde_count)))
|
|
Packit Service |
97d2fb |
return (void *) -1l;
|
|
Packit Service |
97d2fb |
if (fde_count != 0 && (size_t) fde_count == fde_count
|
|
Packit Service |
97d2fb |
&& fde_table_encoding != DW_EH_PE_omit
|
|
Packit Service |
97d2fb |
&& (fde_table_encoding &~ DW_EH_PE_signed) != DW_EH_PE_uleb128)
|
|
Packit Service |
97d2fb |
{
|
|
Packit Service |
97d2fb |
*table_entries = fde_count;
|
|
Packit Service |
97d2fb |
*table_encoding = fde_table_encoding;
|
|
Packit Service |
97d2fb |
return h;
|
|
Packit Service |
97d2fb |
}
|
|
Packit Service |
97d2fb |
}
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
return NULL;
|
|
Packit Service |
97d2fb |
}
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
static Dwarf_CFI *
|
|
Packit Service |
97d2fb |
getcfi_gnu_eh_frame (Elf *elf, const GElf_Ehdr *ehdr, const GElf_Phdr *phdr)
|
|
Packit Service |
97d2fb |
{
|
|
Packit Service |
97d2fb |
Elf_Data *data = elf_getdata_rawchunk (elf, phdr->p_offset, phdr->p_filesz,
|
|
Packit Service |
97d2fb |
ELF_T_BYTE);
|
|
Packit Service |
97d2fb |
if (data == NULL || data->d_buf == NULL)
|
|
Packit Service |
97d2fb |
{
|
|
Packit Service |
97d2fb |
invalid_hdr:
|
|
Packit Service |
97d2fb |
/* XXX might be read error or corrupt phdr */
|
|
Packit Service |
97d2fb |
__libdw_seterrno (DWARF_E_INVALID_CFI);
|
|
Packit Service |
97d2fb |
return NULL;
|
|
Packit Service |
97d2fb |
}
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
size_t vsize, dmax;
|
|
Packit Service |
97d2fb |
Dwarf_Addr eh_frame_ptr;
|
|
Packit Service |
97d2fb |
size_t search_table_entries = 0;
|
|
Packit Service |
97d2fb |
uint8_t search_table_encoding = 0;
|
|
Packit Service |
97d2fb |
const uint8_t *search_table = parse_eh_frame_hdr (data->d_buf, phdr->p_filesz,
|
|
Packit Service |
97d2fb |
phdr->p_vaddr, ehdr,
|
|
Packit Service |
97d2fb |
&eh_frame_ptr,
|
|
Packit Service |
97d2fb |
&search_table_entries,
|
|
Packit Service |
97d2fb |
&search_table_encoding);
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
/* Make sure there is enough room for the entries in the table,
|
|
Packit Service |
97d2fb |
each entry consists of 2 encoded values. */
|
|
Packit Service |
97d2fb |
vsize = encoded_value_size (data, ehdr->e_ident, search_table_encoding,
|
|
Packit Service |
97d2fb |
NULL);
|
|
Packit Service |
97d2fb |
dmax = phdr->p_filesz - (search_table - (const uint8_t *) data->d_buf);
|
|
Packit Service |
97d2fb |
if (unlikely (search_table == (void *) -1l
|
|
Packit Service |
97d2fb |
|| vsize == 0
|
|
Packit Service |
97d2fb |
|| search_table_entries > (dmax / vsize) / 2))
|
|
Packit Service |
97d2fb |
goto invalid_hdr;
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
Dwarf_Off eh_frame_offset = eh_frame_ptr - phdr->p_vaddr + phdr->p_offset;
|
|
Packit Service |
97d2fb |
Dwarf_Word eh_frame_size = 0;
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
/* XXX we have no way without section headers to know the size
|
|
Packit Service |
97d2fb |
of the .eh_frame data. Calculate the largest it might possibly be.
|
|
Packit Service |
97d2fb |
This won't be wasteful if the file is already mmap'd, but if it isn't
|
|
Packit Service |
97d2fb |
it might be quite excessive. */
|
|
Packit Service |
97d2fb |
size_t filesize;
|
|
Packit Service |
97d2fb |
if (elf_rawfile (elf, &filesize) != NULL)
|
|
Packit Service |
97d2fb |
eh_frame_size = filesize - eh_frame_offset;
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
data = elf_getdata_rawchunk (elf, eh_frame_offset, eh_frame_size, ELF_T_BYTE);
|
|
Packit Service |
97d2fb |
if (data == NULL)
|
|
Packit Service |
97d2fb |
{
|
|
Packit Service |
97d2fb |
__libdw_seterrno (DWARF_E_INVALID_ELF); /* XXX might be read error */
|
|
Packit Service |
97d2fb |
return NULL;
|
|
Packit Service |
97d2fb |
}
|
|
Packit Service |
97d2fb |
Dwarf_CFI *cfi = allocate_cfi (elf, ehdr, eh_frame_ptr);
|
|
Packit Service |
97d2fb |
if (cfi != NULL)
|
|
Packit Service |
97d2fb |
{
|
|
Packit Service |
97d2fb |
cfi->data = (Elf_Data_Scn *) data;
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
if (search_table != NULL)
|
|
Packit Service |
97d2fb |
{
|
|
Packit Service |
97d2fb |
cfi->search_table = search_table;
|
|
Packit Service |
97d2fb |
cfi->search_table_len = phdr->p_filesz;
|
|
Packit Service |
97d2fb |
cfi->search_table_vaddr = phdr->p_vaddr;
|
|
Packit Service |
97d2fb |
cfi->search_table_encoding = search_table_encoding;
|
|
Packit Service |
97d2fb |
cfi->search_table_entries = search_table_entries;
|
|
Packit Service |
97d2fb |
}
|
|
Packit Service |
97d2fb |
}
|
|
Packit Service |
97d2fb |
return cfi;
|
|
Packit Service |
97d2fb |
}
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
/* Search the phdrs for PT_GNU_EH_FRAME. */
|
|
Packit Service |
97d2fb |
static Dwarf_CFI *
|
|
Packit Service |
97d2fb |
getcfi_phdr (Elf *elf, const GElf_Ehdr *ehdr)
|
|
Packit Service |
97d2fb |
{
|
|
Packit Service |
97d2fb |
size_t phnum;
|
|
Packit Service |
97d2fb |
if (unlikely (elf_getphdrnum (elf, &phnum) != 0))
|
|
Packit Service |
97d2fb |
return NULL;
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
for (size_t i = 0; i < phnum; ++i)
|
|
Packit Service |
97d2fb |
{
|
|
Packit Service |
97d2fb |
GElf_Phdr phdr_mem;
|
|
Packit Service |
97d2fb |
GElf_Phdr *phdr = gelf_getphdr (elf, i, &phdr_mem);
|
|
Packit Service |
97d2fb |
if (unlikely (phdr == NULL))
|
|
Packit Service |
97d2fb |
return NULL;
|
|
Packit Service |
97d2fb |
if (phdr->p_type == PT_GNU_EH_FRAME)
|
|
Packit Service |
97d2fb |
return getcfi_gnu_eh_frame (elf, ehdr, phdr);
|
|
Packit Service |
97d2fb |
}
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
__libdw_seterrno (DWARF_E_NO_DWARF);
|
|
Packit Service |
97d2fb |
return NULL;
|
|
Packit Service |
97d2fb |
}
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
static Dwarf_CFI *
|
|
Packit Service |
97d2fb |
getcfi_scn_eh_frame (Elf *elf, const GElf_Ehdr *ehdr,
|
|
Packit Service |
97d2fb |
Elf_Scn *scn, GElf_Shdr *shdr,
|
|
Packit Service |
97d2fb |
Elf_Scn *hdr_scn, GElf_Addr hdr_vaddr)
|
|
Packit Service |
97d2fb |
{
|
|
Packit Service |
97d2fb |
Elf_Data *data = elf_rawdata (scn, NULL);
|
|
Packit Service |
97d2fb |
if (data == NULL || data->d_buf == NULL)
|
|
Packit Service |
97d2fb |
{
|
|
Packit Service |
97d2fb |
__libdw_seterrno (DWARF_E_INVALID_ELF);
|
|
Packit Service |
97d2fb |
return NULL;
|
|
Packit Service |
97d2fb |
}
|
|
Packit Service |
97d2fb |
Dwarf_CFI *cfi = allocate_cfi (elf, ehdr, shdr->sh_addr);
|
|
Packit Service |
97d2fb |
if (cfi != NULL)
|
|
Packit Service |
97d2fb |
{
|
|
Packit Service |
97d2fb |
cfi->data = (Elf_Data_Scn *) data;
|
|
Packit Service |
97d2fb |
if (hdr_scn != NULL)
|
|
Packit Service |
97d2fb |
{
|
|
Packit Service |
97d2fb |
Elf_Data *hdr_data = elf_rawdata (hdr_scn, NULL);
|
|
Packit Service |
97d2fb |
if (hdr_data != NULL && hdr_data->d_buf != NULL)
|
|
Packit Service |
97d2fb |
{
|
|
Packit Service |
97d2fb |
size_t vsize, dmax;
|
|
Packit Service |
97d2fb |
GElf_Addr eh_frame_vaddr;
|
|
Packit Service |
97d2fb |
cfi->search_table_vaddr = hdr_vaddr;
|
|
Packit Service |
97d2fb |
cfi->search_table
|
|
Packit Service |
97d2fb |
= parse_eh_frame_hdr (hdr_data->d_buf, hdr_data->d_size,
|
|
Packit Service |
97d2fb |
hdr_vaddr, ehdr, &eh_frame_vaddr,
|
|
Packit Service |
97d2fb |
&cfi->search_table_entries,
|
|
Packit Service |
97d2fb |
&cfi->search_table_encoding);
|
|
Packit Service |
97d2fb |
cfi->search_table_len = hdr_data->d_size;
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
/* Make sure there is enough room for the entries in the table,
|
|
Packit Service |
97d2fb |
each entry consists of 2 encoded values. */
|
|
Packit Service |
97d2fb |
vsize = encoded_value_size (hdr_data, ehdr->e_ident,
|
|
Packit Service |
97d2fb |
cfi->search_table_encoding, NULL);
|
|
Packit Service |
97d2fb |
dmax = hdr_data->d_size - (cfi->search_table
|
|
Packit Service |
97d2fb |
- (const uint8_t *) hdr_data->d_buf);
|
|
Packit Service |
97d2fb |
if (unlikely (cfi->search_table == (void *) -1l
|
|
Packit Service |
97d2fb |
|| vsize == 0
|
|
Packit Service |
97d2fb |
|| cfi->search_table_entries > (dmax / vsize) / 2))
|
|
Packit Service |
97d2fb |
{
|
|
Packit Service |
97d2fb |
free (cfi);
|
|
Packit Service |
97d2fb |
/* XXX might be read error or corrupt phdr */
|
|
Packit Service |
97d2fb |
__libdw_seterrno (DWARF_E_INVALID_CFI);
|
|
Packit Service |
97d2fb |
return NULL;
|
|
Packit Service |
97d2fb |
}
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
/* Sanity check. */
|
|
Packit Service |
97d2fb |
if (unlikely (eh_frame_vaddr != shdr->sh_addr))
|
|
Packit Service |
97d2fb |
cfi->search_table = NULL;
|
|
Packit Service |
97d2fb |
}
|
|
Packit Service |
97d2fb |
}
|
|
Packit Service |
97d2fb |
}
|
|
Packit Service |
97d2fb |
return cfi;
|
|
Packit Service |
97d2fb |
}
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
/* Search for the sections named ".eh_frame" and ".eh_frame_hdr". */
|
|
Packit Service |
97d2fb |
static Dwarf_CFI *
|
|
Packit Service |
97d2fb |
getcfi_shdr (Elf *elf, const GElf_Ehdr *ehdr)
|
|
Packit Service |
97d2fb |
{
|
|
Packit Service |
97d2fb |
size_t shstrndx;
|
|
Packit Service |
97d2fb |
if (elf_getshdrstrndx (elf, &shstrndx) != 0)
|
|
Packit Service |
97d2fb |
{
|
|
Packit Service |
97d2fb |
__libdw_seterrno (DWARF_E_GETEHDR_ERROR);
|
|
Packit Service |
97d2fb |
return NULL;
|
|
Packit Service |
97d2fb |
}
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
if (shstrndx != 0)
|
|
Packit Service |
97d2fb |
{
|
|
Packit Service |
97d2fb |
Elf_Scn *hdr_scn = NULL;
|
|
Packit Service |
97d2fb |
GElf_Addr hdr_vaddr = 0;
|
|
Packit Service |
97d2fb |
Elf_Scn *scn = NULL;
|
|
Packit Service |
97d2fb |
while ((scn = elf_nextscn (elf, scn)) != NULL)
|
|
Packit Service |
97d2fb |
{
|
|
Packit Service |
97d2fb |
GElf_Shdr shdr_mem;
|
|
Packit Service |
97d2fb |
GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
|
|
Packit Service |
97d2fb |
if (shdr == NULL)
|
|
Packit Service |
97d2fb |
continue;
|
|
Packit Service |
97d2fb |
const char *name = elf_strptr (elf, shstrndx, shdr->sh_name);
|
|
Packit Service |
97d2fb |
if (name == NULL)
|
|
Packit Service |
97d2fb |
continue;
|
|
Packit Service |
97d2fb |
if (!strcmp (name, ".eh_frame_hdr"))
|
|
Packit Service |
97d2fb |
{
|
|
Packit Service |
97d2fb |
hdr_scn = scn;
|
|
Packit Service |
97d2fb |
hdr_vaddr = shdr->sh_addr;
|
|
Packit Service |
97d2fb |
}
|
|
Packit Service |
97d2fb |
else if (!strcmp (name, ".eh_frame"))
|
|
Packit Service |
97d2fb |
{
|
|
Packit Service |
97d2fb |
if (shdr->sh_type != SHT_NOBITS)
|
|
Packit Service |
97d2fb |
return getcfi_scn_eh_frame (elf, ehdr, scn, shdr,
|
|
Packit Service |
97d2fb |
hdr_scn, hdr_vaddr);
|
|
Packit Service |
97d2fb |
else
|
|
Packit Service |
97d2fb |
return NULL;
|
|
Packit Service |
97d2fb |
}
|
|
Packit Service |
97d2fb |
}
|
|
Packit Service |
97d2fb |
}
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
return (void *) -1l;
|
|
Packit Service |
97d2fb |
}
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
Dwarf_CFI *
|
|
Packit Service |
97d2fb |
dwarf_getcfi_elf (Elf *elf)
|
|
Packit Service |
97d2fb |
{
|
|
Packit Service |
97d2fb |
if (elf_kind (elf) != ELF_K_ELF)
|
|
Packit Service |
97d2fb |
{
|
|
Packit Service |
97d2fb |
__libdw_seterrno (DWARF_E_NOELF);
|
|
Packit Service |
97d2fb |
return NULL;
|
|
Packit Service |
97d2fb |
}
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
GElf_Ehdr ehdr_mem;
|
|
Packit Service |
97d2fb |
GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
|
|
Packit Service |
97d2fb |
if (unlikely (ehdr == NULL))
|
|
Packit Service |
97d2fb |
{
|
|
Packit Service |
97d2fb |
__libdw_seterrno (DWARF_E_INVALID_ELF);
|
|
Packit Service |
97d2fb |
return NULL;
|
|
Packit Service |
97d2fb |
}
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
Dwarf_CFI *result = getcfi_shdr (elf, ehdr);
|
|
Packit Service |
97d2fb |
if (result == (void *) -1l)
|
|
Packit Service |
97d2fb |
result = getcfi_phdr (elf, ehdr);
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
return result;
|
|
Packit Service |
97d2fb |
}
|
|
Packit Service |
97d2fb |
INTDEF (dwarf_getcfi_elf)
|