Global Metrics
path: .metrics.halstead.difficulty
old: 5.555555555555555
new: 35.857142857142854
path: .metrics.halstead.level
old: 0.18
new: 0.027888446215139445
path: .metrics.halstead.purity_ratio
old: 1.027798125448147
new: 1.2067917988678205
path: .metrics.halstead.N2
old: 50.0
new: 251.0
path: .metrics.halstead.length
old: 140.0
new: 592.0
path: .metrics.halstead.n2
old: 27.0
new: 91.0
path: .metrics.halstead.effort
old: 3923.417648389908
new: 145840.1763446196
path: .metrics.halstead.n1
old: 6.0
new: 26.0
path: .metrics.halstead.estimated_program_length
old: 143.8917375627406
new: 714.4207449297497
path: .metrics.halstead.volume
old: 706.2151767101835
new: 4067.255913993375
path: .metrics.halstead.bugs
old: 0.08291920052627293
new: 0.9235566344847896
path: .metrics.halstead.vocabulary
old: 33.0
new: 117.0
path: .metrics.halstead.N1
old: 90.0
new: 341.0
path: .metrics.halstead.time
old: 217.96764713277267
new: 8102.232019145533
path: .metrics.loc.lloc
old: 0.0
new: 41.0
path: .metrics.loc.cloc
old: 49.0
new: 10.0
path: .metrics.loc.sloc
old: 83.0
new: 128.0
path: .metrics.loc.ploc
old: 24.0
new: 107.0
path: .metrics.loc.blank
old: 10.0
new: 11.0
path: .metrics.nom.total
old: 0.0
new: 1.0
path: .metrics.nom.functions
old: 0.0
new: 1.0
path: .metrics.mi.mi_sei
old: 64.24618586185468
new: 10.713199186096729
path: .metrics.mi.mi_original
old: 64.61319828924877
new: 43.66134581661258
path: .metrics.mi.mi_visual_studio
old: 37.78549607558408
new: 25.53295076994888
path: .metrics.cognitive.sum
old: 0.0
new: 36.0
path: .metrics.cognitive.average
old: null
new: 36.0
path: .metrics.nexits.average
old: null
new: 0.0
path: .metrics.nargs.sum
old: 0.0
new: 1.0
path: .metrics.nargs.average
old: null
new: 1.0
path: .metrics.cyclomatic.sum
old: 3.0
new: 24.0
path: .metrics.cyclomatic.average
old: 1.0
new: 12.0
Spaces Data
Minimal test - lines (17, 126)
path: .spaces[0].metrics.halstead.bugs
old: 0.07370327030700347
new: 0.9244753205073072
path: .spaces[0].metrics.halstead.estimated_program_length
old: 96.22039775975506
new: 698.5517080276778
path: .spaces[0].metrics.halstead.n1
old: 6.0
new: 26.0
path: .spaces[0].metrics.halstead.vocabulary
old: 25.0
new: 115.0
path: .spaces[0].metrics.halstead.effort
old: 3287.8501823605047
new: 146057.83702674278
path: .spaces[0].metrics.halstead.level
old: 0.16666666666666666
new: 0.02760545905707196
path: .spaces[0].metrics.halstead.volume
old: 547.9750303934175
new: 4031.993640006237
path: .spaces[0].metrics.halstead.length
old: 118.0
new: 589.0
path: .spaces[0].metrics.halstead.time
old: 182.6583434644725
new: 8114.324279263488
path: .spaces[0].metrics.halstead.difficulty
old: 6.0
new: 36.2247191011236
path: .spaces[0].metrics.halstead.n2
old: 19.0
new: 89.0
path: .spaces[0].metrics.halstead.N1
old: 80.0
new: 341.0
path: .spaces[0].metrics.halstead.purity_ratio
old: 0.8154270996589412
new: 1.185996108705735
path: .spaces[0].metrics.halstead.N2
old: 38.0
new: 248.0
path: .spaces[0].metrics.nargs.average
old: null
new: 1.0
path: .spaces[0].metrics.nargs.sum
old: 0.0
new: 1.0
path: .spaces[0].metrics.nom.functions
old: 0.0
new: 1.0
path: .spaces[0].metrics.nom.total
old: 0.0
new: 1.0
path: .spaces[0].metrics.cyclomatic.sum
old: 1.0
new: 23.0
path: .spaces[0].metrics.cyclomatic.average
old: 1.0
new: 23.0
path: .spaces[0].metrics.loc.lloc
old: 0.0
new: 41.0
path: .spaces[0].metrics.loc.sloc
old: 32.0
new: 110.0
path: .spaces[0].metrics.loc.ploc
old: 10.0
new: 97.0
path: .spaces[0].metrics.loc.blank
old: 6.0
new: 7.0
path: .spaces[0].metrics.loc.cloc
old: 16.0
new: 6.0
path: .spaces[0].metrics.nexits.average
old: null
new: 0.0
path: .spaces[0].metrics.mi.mi_original
old: 81.83268382578565
new: 46.39173366583596
path: .spaces[0].metrics.mi.mi_visual_studio
old: 47.85537065835418
new: 27.12966881043038
path: .spaces[0].metrics.mi.mi_sei
old: 86.91717721185134
new: 11.268679277403216
path: .spaces[0].metrics.cognitive.sum
old: 0.0
new: 36.0
path: .spaces[0].metrics.cognitive.average
old: null
new: 36.0
Code
void leaky::readSymbols(const char* fileName) {
int fd = ::open(fileName, O_RDONLY);
if (fd < 0) {
fprintf(stderr, "%s: unable to open \"%s\"\n", applicationName, fileName);
exit(-1);
}
elf_version(EV_CURRENT);
Elf* elf = elf_begin(fd, ELF_C_READ, 0);
if (!elf) {
fprintf(stderr, "%s: \"%s\": has no symbol table\n", applicationName,
fileName);
exit(-1);
}
long alloced = 10000;
Symbol* syms = (Symbol*)malloc(sizeof(Symbol) * 10000);
Symbol* sp = syms;
Symbol* last = syms + alloced;
// Get each of the relevant sections and add them to the list of
// symbols.
Elf32_Ehdr* ehdr = elf32_getehdr(elf);
if (!ehdr) {
fprintf(stderr, "%s: elf library lossage\n", applicationName);
exit(-1);
}
# if 0
Elf32_Half ndx = ehdr->e_shstrndx;
# endif
Elf_Scn* scn = 0;
int strtabndx = -1;
for (int i = 1; (scn = elf_nextscn(elf, scn)) != 0; i++) {
Elf32_Shdr* shdr = elf32_getshdr(scn);
# if 0
char *name = elf_strptr(elf, ndx, (size_t) shdr->sh_name);
printf("Section %s (%d 0x%x)\n", name ? name : "(null)",
shdr->sh_type, shdr->sh_type);
# endif
if (shdr->sh_type == SHT_STRTAB) {
/* We assume here that string tables preceed symbol tables... */
strtabndx = i;
continue;
}
# if 0
if (shdr->sh_type == SHT_DYNAMIC) {
/* Dynamic */
Elf_Data *data = elf_getdata(scn, 0);
if (!data || !data->d_size) {
printf("No data...");
continue;
}
Elf32_Dyn *dyn = (Elf32_Dyn*) data->d_buf;
Elf32_Dyn *lastdyn =
(Elf32_Dyn*) ((char*) data->d_buf + data->d_size);
for (; dyn < lastdyn; dyn++) {
printf("tag=%d value=0x%x\n", dyn->d_tag, dyn->d_un.d_val);
}
} else
# endif
if ((shdr->sh_type == SHT_SYMTAB) || (shdr->sh_type == SHT_DYNSYM)) {
/* Symbol table */
Elf_Data* data = elf_getdata(scn, 0);
if (!data || !data->d_size) {
printf("No data...");
continue;
}
/* In theory we now have the symbols... */
Elf32_Sym* esym = (Elf32_Sym*)data->d_buf;
Elf32_Sym* lastsym = (Elf32_Sym*)((char*)data->d_buf + data->d_size);
for (; esym < lastsym; esym++) {
# if 0
char *nm = elf_strptr(elf, strtabndx, (size_t)esym->st_name);
printf("%20s 0x%08x %02x %02x\n",
nm, esym->st_value, ELF32_ST_BIND(esym->st_info),
ELF32_ST_TYPE(esym->st_info));
# endif
if ((esym->st_value == 0) ||
(ELF32_ST_BIND(esym->st_info) == STB_WEAK) ||
(ELF32_ST_BIND(esym->st_info) == STB_NUM) ||
(ELF32_ST_TYPE(esym->st_info) != STT_FUNC)) {
continue;
}
# if 1
char* nm = elf_strptr(elf, strtabndx, (size_t)esym->st_name);
# endif
sp->name = nm ? strdup(nm) : "(no name)";
sp->address = esym->st_value;
sp++;
if (sp >= last) {
long n = alloced + 10000;
syms = (Symbol*)realloc(syms, (size_t)(sizeof(Symbol) * n));
last = syms + n;
sp = syms + alloced;
alloced = n;
}
}
}
}
int interesting = sp - syms;
if (!quiet) {
printf("Total of %d symbols\n", interesting);
}
usefulSymbols = interesting;
externalSymbols = syms;
}