1
0
Fork 0
mirror of https://github.com/tobast/libunwind-eh_elf.git synced 2024-11-30 02:27:38 +01:00

elfxx: Add helper to find a section in ELF image.

This commit is contained in:
Bert Wesarg 2017-02-01 22:13:05 +01:00 committed by Dave Watson
parent a9857bf98b
commit 1b960e54e9
2 changed files with 49 additions and 36 deletions

View file

@ -214,50 +214,17 @@ xz_uncompressed_size (uint8_t *compressed, size_t length)
static int static int
elf_w (extract_minidebuginfo) (struct elf_image *ei, struct elf_image *mdi) elf_w (extract_minidebuginfo) (struct elf_image *ei, struct elf_image *mdi)
{ {
Elf_W (Ehdr) *ehdr = ei->image;
Elf_W (Shdr) *shdr; Elf_W (Shdr) *shdr;
char *strtab;
int i;
uint8_t *compressed = NULL; uint8_t *compressed = NULL;
uint64_t memlimit = UINT64_MAX; /* no memory limit */ uint64_t memlimit = UINT64_MAX; /* no memory limit */
size_t compressed_len, uncompressed_len; size_t compressed_len, uncompressed_len;
if (!elf_w (valid_object) (ei)) shdr = elf_w (find_section) (ei, ".gnu_debugdata");
return 0;
shdr = elf_w (section_table) (ei);
if (!shdr) if (!shdr)
return 0; return 0;
strtab = elf_w (string_table) (ei, ehdr->e_shstrndx);
if (!strtab)
return 0;
for (i = 0; i < ehdr->e_shnum; ++i)
{
if (strcmp (strtab + shdr->sh_name, ".gnu_debugdata") == 0)
{
if (shdr->sh_offset + shdr->sh_size > ei->size)
{
Debug (1, ".gnu_debugdata outside image? (0x%lu > 0x%lu)\n",
(unsigned long) shdr->sh_offset + shdr->sh_size,
(unsigned long) ei->size);
return 0;
}
Debug (16, "found .gnu_debugdata at 0x%lx\n",
(unsigned long) shdr->sh_offset);
compressed = ((uint8_t *) ei->image) + shdr->sh_offset; compressed = ((uint8_t *) ei->image) + shdr->sh_offset;
compressed_len = shdr->sh_size; compressed_len = shdr->sh_size;
break;
}
shdr = (Elf_W (Shdr) *) (((char *) shdr) + ehdr->e_shentsize);
}
/* not found */
if (!compressed)
return 0;
uncompressed_len = xz_uncompressed_size (compressed, compressed_len); uncompressed_len = xz_uncompressed_size (compressed, compressed_len);
if (uncompressed_len == 0) if (uncompressed_len == 0)
@ -357,3 +324,47 @@ elf_w (get_proc_name) (unw_addr_space_t as, pid_t pid, unw_word_t ip,
return ret; return ret;
} }
HIDDEN Elf_W (Shdr)*
elf_w (find_section) (struct elf_image *ei, const char* secname)
{
Elf_W (Ehdr) *ehdr = ei->image;
Elf_W (Shdr) *shdr;
char *strtab;
int i;
if (!elf_w (valid_object) (ei))
return 0;
shdr = elf_w (section_table) (ei);
if (!shdr)
return 0;
strtab = elf_w (string_table) (ei, ehdr->e_shstrndx);
if (!strtab)
return 0;
for (i = 0; i < ehdr->e_shnum; ++i)
{
if (strcmp (strtab + shdr->sh_name, secname) == 0)
{
if (shdr->sh_offset + shdr->sh_size > ei->size)
{
Debug (1, "section \"%s\" outside image? (0x%lu > 0x%lu)\n",
secname,
(unsigned long) shdr->sh_offset + shdr->sh_size,
(unsigned long) ei->size);
return 0;
}
Debug (16, "found section \"%s\" at 0x%lx\n",
secname, (unsigned long) shdr->sh_offset);
return shdr;
}
shdr = (Elf_W (Shdr) *) (((char *) shdr) + ehdr->e_shentsize);
}
/* section not found */
return 0;
}

View file

@ -54,6 +54,8 @@ extern int elf_w (get_proc_name_in_image) (unw_addr_space_t as,
unw_word_t ip, unw_word_t ip,
char *buf, size_t buf_len, unw_word_t *offp); char *buf, size_t buf_len, unw_word_t *offp);
extern Elf_W (Shdr)* elf_w (find_section) (struct elf_image *ei, const char* secname);
static inline int static inline int
elf_w (valid_object) (struct elf_image *ei) elf_w (valid_object) (struct elf_image *ei)
{ {