version 1.24, 2019/09/03 10:32:15 |
version 1.25, 2022/02/10 23:40:09 |
|
|
int |
int |
isctf(const char *p, size_t filesize) |
isctf(const char *p, size_t filesize) |
{ |
{ |
struct ctf_header *cth = (struct ctf_header *)p; |
struct ctf_header cth; |
off_t dlen; |
off_t dlen; |
|
|
if (filesize < sizeof(struct ctf_header)) { |
if (filesize < sizeof(struct ctf_header)) { |
warnx("file too small to be CTF"); |
warnx("file too small to be CTF"); |
return 0; |
return 0; |
} |
} |
|
|
if (cth->cth_magic != CTF_MAGIC || cth->cth_version != CTF_VERSION) |
memcpy(&cth, p, sizeof(struct ctf_header)); |
|
if (cth.cth_magic != CTF_MAGIC || cth.cth_version != CTF_VERSION) |
return 0; |
return 0; |
|
|
dlen = (off_t)cth->cth_stroff + cth->cth_strlen; |
dlen = (off_t)cth.cth_stroff + cth.cth_strlen; |
if (dlen > (off_t)filesize && !(cth->cth_flags & CTF_F_COMPRESS)) { |
if (dlen > (off_t)filesize && !(cth.cth_flags & CTF_F_COMPRESS)) { |
warnx("bogus file size"); |
warnx("bogus file size"); |
return 0; |
return 0; |
} |
} |
|
|
if ((cth->cth_lbloff & 3) || (cth->cth_objtoff & 1) || |
if ((cth.cth_lbloff & 3) || (cth.cth_objtoff & 1) || |
(cth->cth_funcoff & 1) || (cth->cth_typeoff & 3)) { |
(cth.cth_funcoff & 1) || (cth.cth_typeoff & 3)) { |
warnx("wrongly aligned offset"); |
warnx("wrongly aligned offset"); |
return 0; |
return 0; |
} |
} |
|
|
if ((cth->cth_lbloff >= dlen) || (cth->cth_objtoff >= dlen) || |
if ((cth.cth_lbloff >= dlen) || (cth.cth_objtoff >= dlen) || |
(cth->cth_funcoff >= dlen) || (cth->cth_typeoff >= dlen)) { |
(cth.cth_funcoff >= dlen) || (cth.cth_typeoff >= dlen)) { |
warnx("truncated file"); |
warnx("truncated file"); |
return 0; |
return 0; |
} |
} |
|
|
if ((cth->cth_lbloff > cth->cth_objtoff) || |
if ((cth.cth_lbloff > cth.cth_objtoff) || |
(cth->cth_objtoff > cth->cth_funcoff) || |
(cth.cth_objtoff > cth.cth_funcoff) || |
(cth->cth_funcoff > cth->cth_typeoff) || |
(cth.cth_funcoff > cth.cth_typeoff) || |
(cth->cth_typeoff > cth->cth_stroff)) { |
(cth.cth_typeoff > cth.cth_stroff)) { |
warnx("corrupted file"); |
warnx("corrupted file"); |
return 0; |
return 0; |
} |
} |
|
|
int |
int |
ctf_dump(const char *p, size_t size, uint8_t flags) |
ctf_dump(const char *p, size_t size, uint8_t flags) |
{ |
{ |
struct ctf_header *cth = (struct ctf_header *)p; |
struct ctf_header cth; |
off_t dlen; |
off_t dlen; |
char *data; |
char *data; |
|
|
dlen = (off_t)cth->cth_stroff + cth->cth_strlen; |
memcpy(&cth, p, sizeof(struct ctf_header)); |
if (cth->cth_flags & CTF_F_COMPRESS) { |
dlen = (off_t)cth.cth_stroff + cth.cth_strlen; |
data = decompress(p + sizeof(*cth), size - sizeof(*cth), dlen); |
if (cth.cth_flags & CTF_F_COMPRESS) { |
|
data = decompress(p + sizeof(cth), size - sizeof(cth), dlen); |
if (data == NULL) |
if (data == NULL) |
return 1; |
return 1; |
} else { |
} else { |
data = (char *)p + sizeof(*cth); |
data = (char *)p + sizeof(cth); |
} |
} |
|
|
if (flags & DUMP_HEADER) { |
if (flags & DUMP_HEADER) { |
printf(" cth_magic = 0x%04x\n", cth->cth_magic); |
printf(" cth_magic = 0x%04x\n", cth.cth_magic); |
printf(" cth_version = %u\n", cth->cth_version); |
printf(" cth_version = %u\n", cth.cth_version); |
printf(" cth_flags = 0x%02x\n", cth->cth_flags); |
printf(" cth_flags = 0x%02x\n", cth.cth_flags); |
printf(" cth_parlabel = %s\n", |
printf(" cth_parlabel = %s\n", |
ctf_off2name(cth, data, dlen, cth->cth_parlabel)); |
ctf_off2name(&cth, data, dlen, cth.cth_parlabel)); |
printf(" cth_parname = %s\n", |
printf(" cth_parname = %s\n", |
ctf_off2name(cth, data, dlen, cth->cth_parname)); |
ctf_off2name(&cth, data, dlen, cth.cth_parname)); |
printf(" cth_lbloff = %u\n", cth->cth_lbloff); |
printf(" cth_lbloff = %u\n", cth.cth_lbloff); |
printf(" cth_objtoff = %u\n", cth->cth_objtoff); |
printf(" cth_objtoff = %u\n", cth.cth_objtoff); |
printf(" cth_funcoff = %u\n", cth->cth_funcoff); |
printf(" cth_funcoff = %u\n", cth.cth_funcoff); |
printf(" cth_typeoff = %u\n", cth->cth_typeoff); |
printf(" cth_typeoff = %u\n", cth.cth_typeoff); |
printf(" cth_stroff = %u\n", cth->cth_stroff); |
printf(" cth_stroff = %u\n", cth.cth_stroff); |
printf(" cth_strlen = %u\n", cth->cth_strlen); |
printf(" cth_strlen = %u\n", cth.cth_strlen); |
printf("\n"); |
printf("\n"); |
} |
} |
|
|
if (flags & DUMP_LABEL) { |
if (flags & DUMP_LABEL) { |
uint32_t lbloff = cth->cth_lbloff; |
uint32_t lbloff = cth.cth_lbloff; |
struct ctf_lblent *ctl; |
struct ctf_lblent *ctl; |
|
|
while (lbloff < cth->cth_objtoff) { |
while (lbloff < cth.cth_objtoff) { |
ctl = (struct ctf_lblent *)(data + lbloff); |
ctl = (struct ctf_lblent *)(data + lbloff); |
|
|
printf(" %5u %s\n", ctl->ctl_typeidx, |
printf(" %5u %s\n", ctl->ctl_typeidx, |
ctf_off2name(cth, data, dlen, ctl->ctl_label)); |
ctf_off2name(&cth, data, dlen, ctl->ctl_label)); |
|
|
lbloff += sizeof(*ctl); |
lbloff += sizeof(*ctl); |
} |
} |
|
|
} |
} |
|
|
if (flags & DUMP_OBJECT) { |
if (flags & DUMP_OBJECT) { |
uint32_t objtoff = cth->cth_objtoff; |
uint32_t objtoff = cth.cth_objtoff; |
size_t idx = 0, i = 0; |
size_t idx = 0, i = 0; |
uint16_t *dsp; |
uint16_t *dsp; |
const char *s; |
const char *s; |
int l; |
int l; |
|
|
while (objtoff < cth->cth_funcoff) { |
while (objtoff < cth.cth_funcoff) { |
dsp = (uint16_t *)(data + objtoff); |
dsp = (uint16_t *)(data + objtoff); |
|
|
l = printf(" [%zu] %u", i++, *dsp); |
l = printf(" [%zu] %u", i++, *dsp); |
|
|
const char *s; |
const char *s; |
int l; |
int l; |
|
|
fstart = (uint16_t *)(data + cth->cth_funcoff); |
fstart = (uint16_t *)(data + cth.cth_funcoff); |
fend = (uint16_t *)(data + cth->cth_typeoff); |
fend = (uint16_t *)(data + cth.cth_typeoff); |
|
|
fsp = fstart; |
fsp = fstart; |
while (fsp < fend) { |
while (fsp < fend) { |
|
|
} |
} |
|
|
if (flags & DUMP_TYPE) { |
if (flags & DUMP_TYPE) { |
uint32_t idx = 1, offset = cth->cth_typeoff; |
uint32_t idx = 1, offset = cth.cth_typeoff; |
uint32_t stroff = cth->cth_stroff; |
uint32_t stroff = cth.cth_stroff; |
|
|
while (offset < stroff) { |
while (offset < stroff) { |
ctf_dump_type(cth, data, dlen, stroff, &offset, idx++); |
ctf_dump_type(&cth, data, dlen, stroff, &offset, idx++); |
} |
} |
printf("\n"); |
printf("\n"); |
} |
} |
|
|
uint32_t offset = 0; |
uint32_t offset = 0; |
const char *str; |
const char *str; |
|
|
while (offset < cth->cth_strlen) { |
while (offset < cth.cth_strlen) { |
str = ctf_off2name(cth, data, dlen, offset); |
str = ctf_off2name(&cth, data, dlen, offset); |
|
|
printf(" [%u] ", offset); |
printf(" [%u] ", offset); |
if (strcmp(str, "(anon)")) |
if (strcmp(str, "(anon)")) |
|
|
printf("\n"); |
printf("\n"); |
} |
} |
|
|
if (cth->cth_flags & CTF_F_COMPRESS) |
if (cth.cth_flags & CTF_F_COMPRESS) |
free(data); |
free(data); |
|
|
return 0; |
return 0; |