#define PRI_NOT_ENOUGH ": not enough data for %s.\n"
#define PRI_LACK_RELOCATION ": %s seems to lack a relocation.\n"
-struct sec
-{
- enum section_id id;
- GElf_Shdr shdr;
- const char *name;
-};
-
-struct elf_file
-{
- Dwarf *dwarf;
- Ebl *ebl;
- GElf_Ehdr ehdr; /* Header of dwarf->elf. */
- bool addr_64;
-
- struct sec *sec; /* Array of sections. */
- size_t size;
- size_t alloc;
-};
-
struct relocation
{
uint64_t offset;
struct secinfo *secentry = find_secentry (scnname);
struct section_data *secdata = secentry != NULL ? secentry->dataptr : NULL;
+ cursec->scn = scn;
cursec->id = secentry != NULL ? secentry->sec : sec_invalid;
cursec->name = scnname;
struct coverage_map_hole_info *info = (struct coverage_map_hole_info *)user;
struct where where = WHERE (info->info.section, NULL);
+ const char *scnname = sco->sec->name;
- GElf_Ehdr ehdr_mem, *ehdr = gelf_getehdr (info->elf, &ehdr_mem);
- if (ehdr == NULL)
- {
- wr_error (&where, ": invalid ELF, terminating coverage analysis.\n");
- return false;
- }
- const char *scnname = elf_strptr (info->elf, ehdr->e_shstrndx,
- sco->shdr.sh_name) ?: "(unknown)";
-
- Elf_Data *data = elf_getdata (sco->scn, NULL);
+ Elf_Data *data = elf_getdata (sco->sec->scn, NULL);
if (data == NULL)
{
wr_error (&where, ": couldn't read the data of section %s.\n", scnname);
|| strcmp (scnname, ".plt") == 0))
return true;
- uint64_t base = sco->shdr.sh_addr;
+ uint64_t base = sco->sec->shdr.sh_addr;
/* If we get stripped debuginfo file, the data simply may not be
available. In that case simply report the hole. */
if (data->d_buf != NULL)
void
-section_coverage_init (struct section_coverage *sco, Elf_Scn *scn,
- GElf_Shdr *shdr)
+section_coverage_init (struct section_coverage *sco, struct sec *sec)
{
assert (sco != NULL);
- assert (scn != NULL);
- assert (shdr != NULL);
+ assert (sec != NULL);
- sco->scn = scn;
- sco->shdr = *shdr;
+ sco->sec = sec;
WIPE (sco->cov);
sco->hit = false;
}
bool
-coverage_map_init (struct coverage_map *coverage_map, Elf *elf,
+coverage_map_init (struct coverage_map *coverage_map,
+ struct elf_file *elf,
Elf64_Xword mask, bool allow_overlap)
{
assert (coverage_map != NULL);
coverage_map->elf = elf;
coverage_map->allow_overlap = allow_overlap;
- GElf_Ehdr ehdr_mem, *ehdr = gelf_getehdr (elf, &ehdr_mem);
- if (ehdr == NULL)
- return false;
-
- for (size_t i = 0; i < ehdr->e_shnum; ++i)
+ for (size_t i = 0; i < elf->size; ++i)
{
- Elf_Scn *scn = elf_getscn (elf, i);
- if (scn == NULL)
- return false;
-
- GElf_Shdr shdr_mem, *shdr = gelf_getshdr (scn, &shdr_mem);
- if (shdr == NULL)
- return false;
+ struct sec *sec = elf->sec + i;
- if ((shdr->sh_flags & mask) == mask)
+ if ((sec->shdr.sh_flags & mask) == mask)
{
REALLOC (coverage_map, scos);
section_coverage_init (coverage_map->scos + coverage_map->size++,
- scn, shdr);
+ sec);
}
}
for (size_t i = 0; i < coverage_map->size; ++i)
{
struct section_coverage *sco = coverage_map->scos + i;
- GElf_Shdr *shdr = &sco->shdr;
+ GElf_Shdr *shdr = &sco->sec->shdr;
struct coverage *cov = &sco->cov;
Elf64_Addr s_end = shdr->sh_addr + shdr->sh_size;
return cb (h_start, h_start + h_length - 1, sco, h_user);
}
- if (!coverage_find_holes (&sco->cov, 0, sco->shdr.sh_size, wrap_cb, user))
+ if (!coverage_find_holes (&sco->cov, 0, sco->sec->shdr.sh_size,
+ wrap_cb, user))
return false;
}
}
static struct coverage_map *
-coverage_map_alloc_XA (Elf *elf, bool allow_overlap)
+coverage_map_alloc_XA (struct elf_file *elf, bool allow_overlap)
{
struct coverage_map *ret = xmalloc (sizeof (*ret));
if (!coverage_map_init (ret, elf, SHF_ALLOC | SHF_EXECINSTR, allow_overlap))
bool retval = true;
struct coverage_map *coverage_map;
- if ((coverage_map = coverage_map_alloc_XA (data->file->dwarf->elf,
- false)) == NULL)
+ if ((coverage_map = coverage_map_alloc_XA (data->file, false)) == NULL)
{
wr_error (&WHERE (sec_aranges, NULL),
": couldn't read ELF, skipping coverage analysis.\n");
#define DWARFLINT_HL_H
#include "../libdw/libdw.h"
+#include "../libebl/libebl.h"
#ifdef __cplusplus
extern "C"
# include "dwarflint-coverage.h"
- struct section_coverage
+ struct sec
{
Elf_Scn *scn;
GElf_Shdr shdr;
+ enum section_id id;
+ const char *name;
+ };
+
+ struct elf_file
+ {
+ Dwarf *dwarf;
+ Ebl *ebl;
+ GElf_Ehdr ehdr; /* Header of dwarf->elf. */
+ bool addr_64;
+
+ struct sec *sec; /* Array of sections. */
+ size_t size;
+ size_t alloc;
+ };
+
+ struct section_coverage
+ {
+ struct sec *sec;
struct coverage cov;
bool hit; /* true if COV is not pristine. */
};
struct coverage_map
{
- Elf *elf;
- size_t size;
- size_t alloc;
+ struct elf_file *elf;
bool allow_overlap;
+
struct section_coverage *scos;
+ size_t size;
+ size_t alloc;
};
- void section_coverage_init (struct section_coverage *sco, Elf_Scn *scn,
- GElf_Shdr *shdr);
- bool coverage_map_init (struct coverage_map *coverage_map, Elf *elf,
+ void section_coverage_init (struct section_coverage *sco, struct sec *sec);
+ bool coverage_map_init (struct coverage_map *coverage_map,
+ struct elf_file *elf,
Elf64_Xword mask, bool allow_overlap);
void coverage_map_add (struct coverage_map *coverage_map,
uint64_t address, uint64_t length,
struct coverage_map_hole_info
{
struct hole_info info;
- Elf *elf;
+ struct elf_file *elf;
};
/* DATA has to be a pointer to an instance of struct hole_info.