mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-05-23 22:02:27 +00:00
Add minor improvements and cleanup
This commit is contained in:
parent
9e3e985ae5
commit
feed0d2b0e
163 changed files with 2286 additions and 2245 deletions
|
@ -18,12 +18,12 @@
|
|||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/alg/alg.h"
|
||||
#include "libc/alg/arraylist2.h"
|
||||
#include "libc/elf/elf.h"
|
||||
#include "libc/elf/struct/sym.h"
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/macros.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "tool/build/lib/dis.h"
|
||||
|
||||
|
@ -46,38 +46,51 @@ static int DisSymCompare(const struct DisSym *a, const struct DisSym *b) {
|
|||
}
|
||||
|
||||
static void DisLoadElfLoads(struct Dis *d, struct Elf *elf) {
|
||||
long i;
|
||||
long i, j, n;
|
||||
int64_t addr;
|
||||
uint64_t size;
|
||||
Elf64_Phdr *phdr;
|
||||
struct DisLoad l;
|
||||
d->loads.i = 0;
|
||||
for (i = 0; i < elf->ehdr->e_phnum; ++i) {
|
||||
j = 0;
|
||||
n = elf->ehdr->e_phnum;
|
||||
if (d->loads.n < n) {
|
||||
d->loads.n = n;
|
||||
d->loads.p = realloc(d->loads.p, d->loads.n * sizeof(*d->loads.p));
|
||||
CHECK_NOTNULL(d->loads.p);
|
||||
}
|
||||
for (i = 0; i < n; ++i) {
|
||||
phdr = getelfsegmentheaderaddress(elf->ehdr, elf->size, i);
|
||||
if (phdr->p_type != PT_LOAD) continue;
|
||||
l.addr = phdr->p_vaddr;
|
||||
l.size = phdr->p_memsz;
|
||||
l.istext = (phdr->p_flags & PF_X) == PF_X;
|
||||
APPEND(&d->loads.p, &d->loads.i, &d->loads.n, &l);
|
||||
d->loads.p[j].addr = phdr->p_vaddr;
|
||||
d->loads.p[j].size = phdr->p_memsz;
|
||||
d->loads.p[j].istext = (phdr->p_flags & PF_X) == PF_X;
|
||||
++j;
|
||||
}
|
||||
d->loads.i = j;
|
||||
}
|
||||
|
||||
static void DisLoadElfSyms(struct Dis *d, struct Elf *elf) {
|
||||
size_t i, n;
|
||||
size_t i, j, n;
|
||||
int64_t stablen;
|
||||
struct DisSym t;
|
||||
const Elf64_Sym *st, *sym;
|
||||
bool isabs, iscode, isweak, islocal, ishidden, isprotected, isfunc, isobject;
|
||||
d->syms.i = 0;
|
||||
j = 0;
|
||||
if ((d->syms.stab = getelfstringtable(elf->ehdr, elf->size)) &&
|
||||
(st = getelfsymboltable(elf->ehdr, elf->size, &n))) {
|
||||
stablen = (intptr_t)elf->ehdr + elf->size - (intptr_t)d->syms.stab;
|
||||
if (d->syms.n < n) {
|
||||
d->syms.n = n;
|
||||
d->syms.p = realloc(d->syms.p, d->syms.n * sizeof(*d->syms.p));
|
||||
CHECK_NOTNULL(d->syms.p);
|
||||
}
|
||||
for (i = 0; i < n; ++i) {
|
||||
if (!st[i].st_name) continue;
|
||||
if (!(0 <= st[i].st_name && st[i].st_name < stablen)) continue;
|
||||
if (ELF64_ST_TYPE(st[i].st_info) == STT_SECTION) continue;
|
||||
if (ELF64_ST_TYPE(st[i].st_info) == STT_FILE) continue;
|
||||
if (startswith(d->syms.stab + st[i].st_name, "v_")) continue;
|
||||
if (ELF64_ST_TYPE(st[i].st_info) == STT_SECTION ||
|
||||
ELF64_ST_TYPE(st[i].st_info) == STT_FILE || !st[i].st_name ||
|
||||
startswith(d->syms.stab + st[i].st_name, "v_") ||
|
||||
!(0 <= st[i].st_name && st[i].st_name < stablen) || !st[i].st_value ||
|
||||
!(-0x800000000000 <= (int64_t)st[i].st_value &&
|
||||
(int64_t)st[i].st_value < 0x800000000000)) {
|
||||
continue;
|
||||
}
|
||||
isabs = st[i].st_shndx == SHN_ABS;
|
||||
isweak = ELF64_ST_BIND(st[i].st_info) == STB_WEAK;
|
||||
islocal = ELF64_ST_BIND(st[i].st_info) == STB_LOCAL;
|
||||
|
@ -85,19 +98,51 @@ static void DisLoadElfSyms(struct Dis *d, struct Elf *elf) {
|
|||
isprotected = st[i].st_other == STV_PROTECTED;
|
||||
isfunc = ELF64_ST_TYPE(st[i].st_info) == STT_FUNC;
|
||||
isobject = ELF64_ST_TYPE(st[i].st_info) == STT_OBJECT;
|
||||
t.unique = i;
|
||||
t.size = st[i].st_size;
|
||||
t.name = st[i].st_name;
|
||||
t.addr = st[i].st_value;
|
||||
t.rank = -islocal + -isweak + -isabs + isprotected + isobject + isfunc;
|
||||
t.iscode = DisIsText(d, st[i].st_value) ? !isobject : isfunc;
|
||||
t.isabs = isabs;
|
||||
APPEND(&d->syms.p, &d->syms.i, &d->syms.n, &t);
|
||||
d->syms.p[j].unique = i;
|
||||
d->syms.p[j].size = st[i].st_size;
|
||||
d->syms.p[j].name = st[i].st_name;
|
||||
d->syms.p[j].addr = st[i].st_value;
|
||||
d->syms.p[j].rank =
|
||||
-islocal + -isweak + -isabs + isprotected + isobject + isfunc;
|
||||
d->syms.p[j].iscode = DisIsText(d, st[i].st_value) ? !isobject : isfunc;
|
||||
d->syms.p[j].isabs = isabs;
|
||||
++j;
|
||||
}
|
||||
}
|
||||
d->syms.i = j;
|
||||
}
|
||||
|
||||
static void DisSortSyms(struct Dis *d) {
|
||||
qsort(d->syms.p, d->syms.i, sizeof(struct DisSym), (void *)DisSymCompare);
|
||||
}
|
||||
|
||||
static void DisCanonizeSyms(struct Dis *d) {
|
||||
int64_t i, j, a;
|
||||
if (d->syms.i) {
|
||||
i = 1;
|
||||
j = 1;
|
||||
a = d->syms.p[0].addr;
|
||||
do {
|
||||
if (d->syms.p[j].addr > a) {
|
||||
a = d->syms.p[j].addr;
|
||||
if (j > i) {
|
||||
d->syms.p[i] = d->syms.p[j];
|
||||
}
|
||||
++i;
|
||||
}
|
||||
++j;
|
||||
} while (j < d->syms.i);
|
||||
d->syms.p = realloc(d->syms.p, sizeof(*d->syms.p) * i);
|
||||
d->syms.i = i;
|
||||
d->syms.n = i;
|
||||
}
|
||||
for (i = 0; i < d->syms.i; ++i) {
|
||||
DEBUGF("%p-%p %s", d->syms.p[i].addr,
|
||||
d->syms.p[i].addr + (d->syms.p[i].size ? d->syms.p[i].size - 1 : 0),
|
||||
d->syms.stab + d->syms.p[i].name);
|
||||
}
|
||||
}
|
||||
|
||||
bool DisIsProg(struct Dis *d, int64_t addr) {
|
||||
long i;
|
||||
if (g_disisprog_disable) return true;
|
||||
|
@ -122,36 +167,24 @@ bool DisIsText(struct Dis *d, int64_t addr) {
|
|||
}
|
||||
|
||||
long DisFindSym(struct Dis *d, int64_t addr) {
|
||||
size_t i, l, r, m, n;
|
||||
if (d->syms.p) {
|
||||
if (DisIsProg(d, addr)) {
|
||||
l = 0;
|
||||
r = d->syms.i;
|
||||
while (l < r) {
|
||||
m = (l + r) >> 1;
|
||||
if (d->syms.p[m].addr < addr) {
|
||||
l = m + 1;
|
||||
} else {
|
||||
r = m;
|
||||
}
|
||||
}
|
||||
if (d->syms.p[l].addr == addr) {
|
||||
return l;
|
||||
}
|
||||
l = MAX(0, (long)l - 10);
|
||||
for (n = 0, i = l; i < d->syms.i && n < 20; ++i, ++n) {
|
||||
if (addr >= d->syms.p[i].addr &&
|
||||
addr < d->syms.p[i].addr + d->syms.p[i].size) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
for (n = 0, i = l; i < d->syms.i && n < 20; ++i, ++n) {
|
||||
if (addr >= d->syms.p[i].addr &&
|
||||
(i + 1 == d->syms.i || addr < d->syms.p[i + 1].addr)) {
|
||||
return i;
|
||||
}
|
||||
long l, r, m, n;
|
||||
if (DisIsProg(d, addr)) {
|
||||
l = 0;
|
||||
r = d->syms.i;
|
||||
while (l < r) {
|
||||
m = (l + r) >> 1;
|
||||
if (d->syms.p[m].addr > addr) {
|
||||
r = m;
|
||||
} else {
|
||||
l = m + 1;
|
||||
}
|
||||
}
|
||||
if (r && (addr == d->syms.p[r - 1].addr ||
|
||||
(addr > d->syms.p[r - 1].addr &&
|
||||
(addr <= d->syms.p[r - 1].addr + d->syms.p[r - 1].size ||
|
||||
!d->syms.p[r - 1].size)))) {
|
||||
return r - 1;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
@ -170,4 +203,6 @@ void DisLoadElf(struct Dis *d, struct Elf *elf) {
|
|||
if (!elf || !elf->ehdr) return;
|
||||
DisLoadElfLoads(d, elf);
|
||||
DisLoadElfSyms(d, elf);
|
||||
DisSortSyms(d);
|
||||
DisCanonizeSyms(d);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue