#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "libdwelfP.h"
const char *
dwelf_elf_gnu_debuglink (Elf *elf, GElf_Word *crc)
{
size_t shstrndx;
if (elf_getshdrstrndx (elf, &shstrndx) < 0)
return NULL;
Elf_Scn *scn = NULL;
while ((scn = elf_nextscn (elf, scn)) != NULL)
{
GElf_Shdr shdr_mem;
GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
if (shdr == NULL)
return NULL;
const char *name = elf_strptr (elf, shstrndx, shdr->sh_name);
if (name == NULL)
return NULL;
if (!strcmp (name, ".gnu_debuglink"))
break;
}
if (scn == NULL)
return NULL;
Elf_Data *rawdata = elf_rawdata (scn, NULL);
if (rawdata == NULL || rawdata->d_buf == NULL)
return NULL;
if (rawdata->d_size <= sizeof *crc
|| memchr (rawdata->d_buf, '\0', rawdata->d_size - sizeof *crc) == NULL)
return NULL;
Elf_Data crcdata =
{
.d_type = ELF_T_WORD,
.d_buf = crc,
.d_size = sizeof *crc,
.d_version = EV_CURRENT,
};
Elf_Data conv =
{
.d_type = ELF_T_WORD,
.d_buf = rawdata->d_buf + rawdata->d_size - sizeof *crc,
.d_size = sizeof *crc,
.d_version = EV_CURRENT,
};
GElf_Ehdr ehdr_mem;
GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
if (ehdr == NULL)
return NULL;
Elf_Data *d = gelf_xlatetom (elf, &crcdata, &conv, ehdr->e_ident[EI_DATA]);
if (d == NULL)
return NULL;
assert (d == &crcdata);
return rawdata->d_buf;
}
INTDEF(dwelf_elf_gnu_debuglink)