mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-05-28 00:02:28 +00:00
Initial import
This commit is contained in:
commit
c91b3c5006
14915 changed files with 590219 additions and 0 deletions
66
tool/decode/decode.mk
Normal file
66
tool/decode/decode.mk
Normal file
|
@ -0,0 +1,66 @@
|
|||
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
||||
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
|
||||
|
||||
PKGS += TOOL_DECODE
|
||||
|
||||
TOOL_DECODE_FILES := $(wildcard tool/decode/*)
|
||||
TOOL_DECODE_HDRS = $(filter %.h,$(TOOL_DECODE_FILES))
|
||||
TOOL_DECODE_SRCS = $(filter %.c,$(TOOL_DECODE_FILES))
|
||||
TOOL_DECODE_COMS = $(TOOL_DECODE_OBJS:%.o=%.com)
|
||||
|
||||
TOOL_DECODE_OBJS = \
|
||||
$(TOOL_DECODE_SRCS:%=o/$(MODE)/%.zip.o) \
|
||||
$(TOOL_DECODE_SRCS:%.c=o/$(MODE)/%.o)
|
||||
|
||||
TOOL_DECODE_BINS = \
|
||||
$(TOOL_DECODE_COMS) \
|
||||
$(TOOL_DECODE_COMS:%=%.dbg)
|
||||
|
||||
TOOL_DECODE_CHECKS = \
|
||||
$(TOOL_DECODE_HDRS:%=o/$(MODE)/%.ok)
|
||||
|
||||
TOOL_DECODE_DIRECTDEPS = \
|
||||
LIBC_CALLS \
|
||||
LIBC_CONV \
|
||||
LIBC_ELF \
|
||||
LIBC_FMT \
|
||||
LIBC_LOG \
|
||||
LIBC_MEM \
|
||||
LIBC_NEXGEN32E \
|
||||
LIBC_RAND \
|
||||
LIBC_RUNTIME \
|
||||
LIBC_RUNTIME \
|
||||
LIBC_STDIO \
|
||||
LIBC_STR \
|
||||
LIBC_STUBS \
|
||||
LIBC_SYSV \
|
||||
LIBC_UNICODE \
|
||||
LIBC_X \
|
||||
TOOL_DECODE_LIB \
|
||||
THIRD_PARTY_GETOPT \
|
||||
THIRD_PARTY_XED
|
||||
|
||||
TOOL_DECODE_DEPS := \
|
||||
$(call uniq,$(foreach x,$(TOOL_DECODE_DIRECTDEPS),$($(x))))
|
||||
|
||||
o/$(MODE)/tool/decode/decode.pkg: \
|
||||
$(TOOL_DECODE_OBJS) \
|
||||
$(foreach x,$(TOOL_DECODE_DIRECTDEPS),$($(x)_A).pkg)
|
||||
|
||||
o/$(MODE)/tool/decode/%.com.dbg: \
|
||||
$(TOOL_DECODE_DEPS) \
|
||||
o/$(MODE)/tool/decode/%.o \
|
||||
o/$(MODE)/tool/decode/decode.pkg \
|
||||
$(CRT) \
|
||||
$(APE)
|
||||
@$(APELINK)
|
||||
|
||||
$(TOOL_DECODE_OBJS): \
|
||||
$(BUILD_FILES) \
|
||||
tool/decode/decode.mk
|
||||
|
||||
.PHONY: o/$(MODE)/tool/decode
|
||||
o/$(MODE)/tool/decode: \
|
||||
o/$(MODE)/tool/decode/lib \
|
||||
$(TOOL_DECODE_BINS) \
|
||||
$(TOOL_DECODE_CHECKS)
|
329
tool/decode/elf.c
Normal file
329
tool/decode/elf.c
Normal file
|
@ -0,0 +1,329 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/safemacros.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/struct/stat.h"
|
||||
#include "libc/conv/conv.h"
|
||||
#include "libc/elf/elf.h"
|
||||
#include "libc/elf/struct/rela.h"
|
||||
#include "libc/elf/struct/shdr.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/map.h"
|
||||
#include "libc/sysv/consts/o.h"
|
||||
#include "libc/sysv/consts/prot.h"
|
||||
#include "tool/decode/lib/asmcodegen.h"
|
||||
#include "tool/decode/lib/elfidnames.h"
|
||||
#include "tool/decode/lib/flagger.h"
|
||||
#include "tool/decode/lib/titlegen.h"
|
||||
|
||||
/**
|
||||
* @fileoverview ELF executable metadata disassembler.
|
||||
*/
|
||||
|
||||
static const char *path;
|
||||
static struct stat st[1];
|
||||
static Elf64_Ehdr *elf;
|
||||
|
||||
static void startfile(void) {
|
||||
showtitle("αcτµαlly pδrταblε εxεcµταblε", "tool/decode/elf", basename(path),
|
||||
NULL, &kModelineAsm);
|
||||
printf("#include \"libc/elf.h\"\n\n", path);
|
||||
}
|
||||
|
||||
static void printelfehdr(void) {
|
||||
show(".ascii", format(b1, "%`'.*s", 4, (const char *)&elf->e_ident[0]),
|
||||
"magic");
|
||||
show(".byte",
|
||||
firstnonnull(findnamebyid(&kElfClassNames[0], elf->e_ident[EI_CLASS]),
|
||||
format(b1, "%d", elf->e_ident[EI_CLASS])),
|
||||
"elf->e_ident[EI_CLASS]");
|
||||
show(".byte",
|
||||
firstnonnull(findnamebyid(kElfDataNames, elf->e_ident[EI_DATA]),
|
||||
format(b1, "%d", elf->e_ident[EI_DATA])),
|
||||
"elf->e_ident[EI_DATA]");
|
||||
show(".byte", format(b1, "%d", elf->e_ident[EI_VERSION]),
|
||||
"elf->e_ident[EI_VERSION]");
|
||||
show(".byte",
|
||||
firstnonnull(findnamebyid(kElfOsabiNames, elf->e_ident[EI_OSABI]),
|
||||
format(b1, "%d", elf->e_ident[EI_OSABI])),
|
||||
"elf->e_ident[EI_OSABI]");
|
||||
show(".byte", format(b1, "%d", elf->e_ident[EI_ABIVERSION]),
|
||||
"elf->e_ident[EI_ABIVERSION]");
|
||||
show(".byte",
|
||||
format(b1, "%d,%d,%d,%d,%d,%d,%d", elf->e_ident[EI_PAD + 0],
|
||||
elf->e_ident[EI_PAD + 1], elf->e_ident[EI_PAD + 2],
|
||||
elf->e_ident[EI_PAD + 3], elf->e_ident[EI_PAD + 4],
|
||||
elf->e_ident[EI_PAD + 5], elf->e_ident[EI_PAD + 6]),
|
||||
"padding");
|
||||
show(".org", "0x10", NULL);
|
||||
show(".short",
|
||||
firstnonnull(findnamebyid(kElfTypeNames, elf->e_type),
|
||||
format(b1, "%hd", elf->e_type)),
|
||||
"elf->e_type");
|
||||
show(".short",
|
||||
firstnonnull(findnamebyid(kElfMachineNames, elf->e_machine),
|
||||
format(b1, "%hd", elf->e_machine)),
|
||||
"elf->e_machine");
|
||||
show(".long", format(b1, "%d", elf->e_version), "elf->e_version");
|
||||
show(".quad", format(b1, "%#x", elf->e_entry), "elf->e_entry");
|
||||
show(".quad", format(b1, "%#x", elf->e_phoff), "elf->e_phoff");
|
||||
show(".quad", format(b1, "%#x", elf->e_shoff), "elf->e_shoff");
|
||||
show(".long", format(b1, "%#x", elf->e_flags), "elf->e_flags");
|
||||
show(".short", format(b1, "%hd", elf->e_ehsize), "elf->e_ehsize");
|
||||
show(".short", format(b1, "%hd", elf->e_phentsize), "elf->e_phentsize");
|
||||
show(".short", format(b1, "%hd", elf->e_phnum), "elf->e_phnum");
|
||||
show(".short", format(b1, "%hd", elf->e_shentsize), "elf->e_shentsize");
|
||||
show(".short", format(b1, "%hd", elf->e_shnum), "elf->e_shnum");
|
||||
show(".short", format(b1, "%hd", elf->e_shstrndx), "elf->e_shstrndx");
|
||||
}
|
||||
|
||||
static void printelfsegmentheader(int i) {
|
||||
Elf64_Phdr *phdr = getelfsegmentheaderaddress(elf, st->st_size, i);
|
||||
printf("/\tElf64_Phdr *phdr = getelfsegmentheaderaddress(elf, st->st_size, "
|
||||
"%d)\n",
|
||||
i);
|
||||
printf(".Lph%d:", i);
|
||||
show(".long",
|
||||
firstnonnull(findnamebyid(kElfSegmentTypeNames, phdr->p_type),
|
||||
format(b1, "%#x", phdr->p_type)),
|
||||
"phdr->p_type");
|
||||
show(".long", recreateflags(kElfSegmentFlagNames, phdr->p_flags),
|
||||
"phdr->p_flags");
|
||||
show(".quad", format(b1, "%#x", phdr->p_offset), "phdr->p_offset");
|
||||
show(".quad", format(b1, "%#x", phdr->p_vaddr), "phdr->p_vaddr");
|
||||
show(".quad", format(b1, "%#x", phdr->p_paddr), "phdr->p_paddr");
|
||||
show(".quad", format(b1, "%#x", phdr->p_filesz), "phdr->p_filesz");
|
||||
show(".quad", format(b1, "%#x", phdr->p_memsz), "phdr->p_memsz");
|
||||
show(".quad", format(b1, "%#x", phdr->p_align), "phdr->p_align");
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
static void printelfsegmentheaders(void) {
|
||||
printf("\n");
|
||||
printf("\t.org\t%#x\n", elf->e_phoff);
|
||||
for (unsigned i = 0; i < elf->e_phnum; ++i) printelfsegmentheader(i);
|
||||
}
|
||||
|
||||
static void printelfsectionheader(int i, char *shstrtab) {
|
||||
Elf64_Shdr *shdr;
|
||||
shdr = getelfsectionheaderaddress(elf, st->st_size, i);
|
||||
printf("/\tElf64_Shdr *shdr = getelfsectionheaderaddress(elf, st->st_size, "
|
||||
"%d)\n",
|
||||
i);
|
||||
printf(".Lsh%d:", i);
|
||||
show(".long", format(b1, "%d", shdr->sh_name),
|
||||
format(b2,
|
||||
"%`'s == getelfstring(elf, st->st_size, shstrtab, shdr->sh_name)",
|
||||
getelfstring(elf, st->st_size, shstrtab, shdr->sh_name)));
|
||||
show(".long",
|
||||
firstnonnull(findnamebyid(kElfSectionTypeNames, shdr->sh_type),
|
||||
format(b1, "%d", shdr->sh_type)),
|
||||
"shdr->sh_type");
|
||||
show(".long", recreateflags(kElfSectionFlagNames, shdr->sh_flags),
|
||||
"shdr->sh_flags");
|
||||
show(".quad", format(b1, "%#x", shdr->sh_addr), "shdr->sh_addr");
|
||||
show(".quad", format(b1, "%#x", shdr->sh_offset), "shdr->sh_offset");
|
||||
show(".quad", format(b1, "%#x", shdr->sh_size), "shdr->sh_size");
|
||||
show(".long", format(b1, "%#x", shdr->sh_link), "shdr->sh_link");
|
||||
show(".long", format(b1, "%#x", shdr->sh_info), "shdr->sh_info");
|
||||
show(".quad", format(b1, "%#x", shdr->sh_addralign), "shdr->sh_addralign");
|
||||
show(".quad", format(b1, "%#x", shdr->sh_entsize), "shdr->sh_entsize");
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
static void printelfsectionheaders(void) {
|
||||
Elf64_Half i;
|
||||
char *shstrtab = getelfsectionnamestringtable(elf, st->st_size);
|
||||
if (shstrtab) {
|
||||
printf("\n");
|
||||
printf("\t.org\t%#x\n", elf->e_shoff);
|
||||
for (i = 0; i < elf->e_shnum; ++i) {
|
||||
printelfsectionheader(i, shstrtab);
|
||||
}
|
||||
printf("\n/\t%s\n", "elf->e_shstrndx");
|
||||
printf("\t.org\t%#x\n",
|
||||
getelfsectionheaderaddress(elf, st->st_size, elf->e_shstrndx)
|
||||
->sh_offset);
|
||||
for (i = 0; i < elf->e_shnum; ++i) {
|
||||
Elf64_Shdr *shdr = getelfsectionheaderaddress(elf, st->st_size, i);
|
||||
const char *str = getelfstring(elf, st->st_size, shstrtab, shdr->sh_name);
|
||||
show(".asciz", format(b1, "%`'s", str), NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void printelfsymbolinfo(Elf64_Sym *sym) {
|
||||
int bind = (sym->st_info >> 4) & 0xf;
|
||||
const char *bindname = findnamebyid(kElfSymbolBindNames, bind);
|
||||
int type = (sym->st_info >> 0) & 0xf;
|
||||
const char *typename = findnamebyid(kElfSymbolTypeNames, type);
|
||||
show(".byte",
|
||||
format(b1, "%s%s%s", bindname ? format(b2, "%s<<4", bindname) : "",
|
||||
bindname && typename ? "|" : "", firstnonnull(typename, "")),
|
||||
"sym->st_info");
|
||||
}
|
||||
|
||||
static void printelfsymbolother(Elf64_Sym *sym) {
|
||||
int visibility = sym->st_other & 0x3;
|
||||
const char *visibilityname =
|
||||
findnamebyid(kElfSymbolVisibilityNames, visibility);
|
||||
int other = sym->st_other & ~0x3;
|
||||
show(".byte",
|
||||
format(b1, "%s%s%s", firstnonnull(visibilityname, ""),
|
||||
other && visibilityname ? "+" : "",
|
||||
other ? format(b2, "%d", other) : ""),
|
||||
"sym->st_other");
|
||||
}
|
||||
|
||||
static void printelfsymbol(Elf64_Sym *sym, char *strtab, char *shstrtab) {
|
||||
show(".long", format(b1, "%d", sym->st_name),
|
||||
format(b2, "%`'s (sym->st_name)",
|
||||
getelfstring(elf, st->st_size, strtab, sym->st_name)));
|
||||
printelfsymbolinfo(sym);
|
||||
printelfsymbolother(sym);
|
||||
show(".short", format(b1, "%d", sym->st_shndx),
|
||||
format(b2, "%s sym->st_shndx",
|
||||
sym->st_shndx < 0xff00
|
||||
? format(b1, "%`'s",
|
||||
getelfstring(elf, st->st_size, shstrtab,
|
||||
getelfsectionheaderaddress(
|
||||
elf, st->st_size, sym->st_shndx)
|
||||
->sh_name))
|
||||
: findnamebyid(kElfSpecialSectionNames, sym->st_shndx)));
|
||||
show(".quad", format(b1, "%#x", sym->st_value), "sym->st_value");
|
||||
show(".quad", format(b1, "%#x", sym->st_size), "sym->st_size");
|
||||
}
|
||||
|
||||
static void printelfsymboltable(void) {
|
||||
size_t i, symcount = 0;
|
||||
Elf64_Sym *symtab = getelfsymboltable(elf, st->st_size, &symcount);
|
||||
char *strtab = getelfstringtable(elf, st->st_size);
|
||||
char *shstrtab = getelfsectionnamestringtable(elf, st->st_size);
|
||||
if (symtab && strtab) {
|
||||
printf("\n\n");
|
||||
printf("\t.org\t%#x\n", (intptr_t)symtab - (intptr_t)elf);
|
||||
for (i = 0; i < symcount; ++i) {
|
||||
printf(".Lsym%d:\n", i);
|
||||
printelfsymbol(&symtab[i], strtab, shstrtab);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static char *getelfsymbolname(const Elf64_Ehdr *elf, size_t mapsize,
|
||||
const char *strtab, const char *shstrtab,
|
||||
const Elf64_Sym *sym) {
|
||||
char *res;
|
||||
const Elf64_Shdr *shdr;
|
||||
if (elf && sym &&
|
||||
((shstrtab && !sym->st_name &&
|
||||
ELF64_ST_TYPE(sym->st_info) == STT_SECTION &&
|
||||
(shdr = getelfsectionheaderaddress(elf, mapsize, sym->st_shndx)) &&
|
||||
(res = getelfstring(elf, mapsize, shstrtab, shdr->sh_name))) ||
|
||||
(strtab && (res = getelfstring(elf, mapsize, strtab, sym->st_name))))) {
|
||||
return res;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void printelfrelocations(void) {
|
||||
int sym;
|
||||
size_t i, j;
|
||||
const Elf64_Sym *syms;
|
||||
const Elf64_Rela *rela;
|
||||
const Elf64_Shdr *shdr, *boop;
|
||||
char *strtab, *shstrtab, *symbolname;
|
||||
strtab = getelfstringtable(elf, st->st_size);
|
||||
shstrtab = getelfsectionnamestringtable(elf, st->st_size);
|
||||
for (i = 0; i < elf->e_shnum; ++i) {
|
||||
if ((shdr = getelfsectionheaderaddress(elf, st->st_size, i)) &&
|
||||
shdr->sh_type == SHT_RELA &&
|
||||
(rela = getelfsectionaddress(elf, st->st_size, shdr))) {
|
||||
printf("\n/\t%s\n", getelfsectionname(elf, st->st_size, shdr));
|
||||
printf("\t.org\t%#x\n", (intptr_t)rela - (intptr_t)elf);
|
||||
for (j = 0; ((uintptr_t)rela + sizeof(Elf64_Rela) <=
|
||||
min((uintptr_t)elf + st->st_size,
|
||||
(uintptr_t)elf + shdr->sh_offset + shdr->sh_size));
|
||||
++rela, ++j) {
|
||||
boop = getelfsectionheaderaddress(elf, st->st_size, shdr->sh_link);
|
||||
syms = getelfsectionaddress(elf, st->st_size, boop);
|
||||
sym = ELF64_R_SYM(rela->r_info);
|
||||
symbolname =
|
||||
getelfsymbolname(elf, st->st_size, strtab, shstrtab, &syms[sym]);
|
||||
printf("/\t%s+%#lx → %s%c%#lx\n",
|
||||
getelfstring(
|
||||
elf, st->st_size, shstrtab,
|
||||
getelfsectionheaderaddress(elf, st->st_size, shdr->sh_info)
|
||||
->sh_name),
|
||||
rela->r_offset, symbolname, rela->r_addend >= 0 ? '+' : '-',
|
||||
abs(rela->r_addend));
|
||||
printf("%s_%zu_%zu:\n", ".Lrela", i, j);
|
||||
show(".quad", format(b1, "%#lx", rela->r_offset), "rela->r_offset");
|
||||
show(".long",
|
||||
format(b1, "%s%s", "R_X86_64_",
|
||||
findnamebyid(kElfNexgen32eRelocationNames,
|
||||
ELF64_R_TYPE(rela->r_info))),
|
||||
"ELF64_R_TYPE(rela->r_info)");
|
||||
show(".long", format(b1, "%d", ELF64_R_SYM(rela->r_info)),
|
||||
|
||||
"ELF64_R_SYM(rela->r_info)");
|
||||
show(".quad", format(b1, "%#lx", rela->r_addend), "rela->r_addend");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
showcrashreports();
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "usage: %`s FILE: %s\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
path = argv[1];
|
||||
int64_t fd = open(path, O_RDONLY);
|
||||
if (fd == -1) {
|
||||
if (errno == ENOENT) {
|
||||
fprintf(stderr, "error: %`s not found\n", path);
|
||||
exit(1);
|
||||
}
|
||||
perror("open");
|
||||
exit(1);
|
||||
}
|
||||
fstat(fd, st);
|
||||
CHECK_NE(MAP_FAILED,
|
||||
(elf = mmap(NULL, st->st_size, PROT_READ, MAP_SHARED, fd, 0)));
|
||||
if (memcmp(elf->e_ident, ELFMAG, 4) != 0) {
|
||||
fprintf(stderr, "error: not an elf executable: %'s\n", path);
|
||||
exit(1);
|
||||
}
|
||||
startfile();
|
||||
printelfehdr();
|
||||
printelfsegmentheaders();
|
||||
printelfsectionheaders();
|
||||
printelfrelocations();
|
||||
printelfsymboltable();
|
||||
munmap(elf, st->st_size);
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
267
tool/decode/ent.c
Normal file
267
tool/decode/ent.c
Normal file
|
@ -0,0 +1,267 @@
|
|||
/* PUBLIC DOMAIN */
|
||||
/* clang-format off */
|
||||
/*
|
||||
ENT -- Entropy calculation and analysis of putative
|
||||
random sequences.
|
||||
|
||||
Designed and implemented by John "Random" Walker in May 1985.
|
||||
|
||||
Multiple analyses of random sequences added in December 1985.
|
||||
|
||||
Bit stream analysis added in September 1997.
|
||||
|
||||
Terse mode output, getopt() command line processing,
|
||||
optional stdin input, and HTML documentation added in
|
||||
October 1998.
|
||||
|
||||
Documentation for the -t (terse output) option added
|
||||
in July 2006.
|
||||
|
||||
Replaced table look-up for chi square to probability
|
||||
conversion with algorithmic computation in January 2008.
|
||||
|
||||
For additional information and the latest version,
|
||||
see http://www.fourmilab.ch/random/
|
||||
|
||||
*/
|
||||
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/math.h"
|
||||
#include "libc/rand/rand.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "third_party/getopt/getopt.h"
|
||||
|
||||
#define UPDATE "January 28th, 2008"
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
|
||||
#ifdef M_PI
|
||||
#define PI M_PI
|
||||
#else
|
||||
#define PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
/* ISO 8859/1 Latin-1 alphabetic and upper and lower case bit vector tables. */
|
||||
#define isISOspace(x) \
|
||||
((isascii(((unsigned char)(x))) && isspace(((unsigned char)(x)))) || \
|
||||
((x) == 0xA0))
|
||||
#define isISOalpha(x) \
|
||||
((isoalpha[(((unsigned char)(x))) / 8] & \
|
||||
(0x80 >> ((((unsigned char)(x))) % 8))) != 0)
|
||||
#define isISOupper(x) \
|
||||
((isoupper[(((unsigned char)(x))) / 8] & \
|
||||
(0x80 >> ((((unsigned char)(x))) % 8))) != 0)
|
||||
#define isISOlower(x) \
|
||||
((isolower[(((unsigned char)(x))) / 8] & \
|
||||
(0x80 >> ((((unsigned char)(x))) % 8))) != 0)
|
||||
#define isISOprint(x) ((((x) >= ' ') && ((x) <= '~')) || ((x) >= 0xA0))
|
||||
#define toISOupper(x) \
|
||||
(isISOlower(x) \
|
||||
? (isascii(((unsigned char)(x))) ? toupper(x) \
|
||||
: (((((unsigned char)(x)) != 0xDF) && \
|
||||
(((unsigned char)(x)) != 0xFF)) \
|
||||
? (((unsigned char)(x)) - 0x20) \
|
||||
: (x))) \
|
||||
: (x))
|
||||
#define toISOlower(x) \
|
||||
(isISOupper(x) \
|
||||
? (isascii(((unsigned char)(x))) ? tolower(x) \
|
||||
: (((unsigned char)(x)) + 0x20)) \
|
||||
: (x))
|
||||
|
||||
unsigned char isoalpha[32] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 127, 255, 255, 224, 127, 255, 255, 224,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 254, 255, 255, 255, 254, 255};
|
||||
unsigned char isoupper[32] = {0, 0, 0, 0, 0, 0, 0, 0, 127, 255, 255,
|
||||
224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 255, 255, 254, 254, 0, 0, 0, 0};
|
||||
unsigned char isolower[32] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 127, 255, 255, 224, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 1, 255, 255, 254, 255};
|
||||
|
||||
/* HELP -- Print information on how to call */
|
||||
|
||||
static void help(void)
|
||||
{
|
||||
printf("ent -- Calculate entropy of file. Call");
|
||||
printf("\n with ent [options] [input-file]");
|
||||
printf("\n");
|
||||
printf("\n Options: -b Treat input as a stream of bits");
|
||||
printf("\n -c Print occurrence counts");
|
||||
printf("\n -f Fold upper to lower case letters");
|
||||
printf("\n -t Terse output in CSV format");
|
||||
printf("\n -u Print this message\n");
|
||||
printf("\nBy John Walker");
|
||||
printf("\n http://www.fourmilab.ch/");
|
||||
printf("\n %s\n", UPDATE);
|
||||
}
|
||||
|
||||
/* Main program */
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int i, oc, opt;
|
||||
long ccount[256]; /* Bins to count occurrences of values */
|
||||
long totalc = 0; /* Total character count */
|
||||
char *samp;
|
||||
double montepi, chip,
|
||||
scc, ent, mean, chisq;
|
||||
FILE *fp = stdin;
|
||||
int counts = FALSE, /* Print character counts */
|
||||
fold = FALSE, /* Fold upper to lower */
|
||||
binary = FALSE, /* Treat input as a bitstream */
|
||||
terse = FALSE; /* Terse (CSV format) output */
|
||||
|
||||
while ((opt = getopt(argc, argv, "bcftu?BCFTU")) != -1) {
|
||||
switch (toISOlower(opt)) {
|
||||
case 'b':
|
||||
binary = TRUE;
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
counts = TRUE;
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
fold = TRUE;
|
||||
break;
|
||||
|
||||
case 't':
|
||||
terse = TRUE;
|
||||
break;
|
||||
|
||||
case '?':
|
||||
case 'u':
|
||||
help();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (optind < argc) {
|
||||
if (optind != (argc - 1)) {
|
||||
printf("Duplicate file name.\n");
|
||||
help();
|
||||
return 2;
|
||||
}
|
||||
if ((fp = fopen(argv[optind], "rb")) == NULL) {
|
||||
printf("Cannot open file %s\n", argv[optind]);
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
samp = binary ? "bit" : "byte";
|
||||
memset(ccount, 0, sizeof ccount);
|
||||
|
||||
/* Initialise for calculations */
|
||||
|
||||
rt_init(binary);
|
||||
|
||||
/* Scan input file and count character occurrences */
|
||||
|
||||
while ((oc = fgetc(fp)) != EOF) {
|
||||
unsigned char ocb;
|
||||
|
||||
if (fold && isISOalpha(oc) && isISOupper(oc)) {
|
||||
oc = toISOlower(oc);
|
||||
}
|
||||
ocb = (unsigned char) oc;
|
||||
totalc += binary ? 8 : 1;
|
||||
if (binary) {
|
||||
int b;
|
||||
unsigned char ob = ocb;
|
||||
|
||||
for (b = 0; b < 8; b++) {
|
||||
ccount[ob & 1]++;
|
||||
ob >>= 1;
|
||||
}
|
||||
} else {
|
||||
ccount[ocb]++; /* Update counter for this bin */
|
||||
}
|
||||
rt_add(&ocb, 1);
|
||||
}
|
||||
fclose(fp);
|
||||
|
||||
/* Complete calculation and return sequence metrics */
|
||||
|
||||
rt_end(&ent, &chisq, &mean, &montepi, &scc);
|
||||
|
||||
if (terse) {
|
||||
printf("0,File-%ss,Entropy,Chi-square,Mean,Monte-Carlo-Pi,Serial-Correlation\n",
|
||||
binary ? "bit" : "byte");
|
||||
printf("1,%ld,%f,%f,%f,%f,%f\n",
|
||||
totalc, ent, chisq, mean, montepi, scc);
|
||||
}
|
||||
|
||||
/* Calculate probability of observed distribution occurring from
|
||||
the results of the Chi-Square test */
|
||||
|
||||
chip = pochisq(chisq, (binary ? 1 : 255));
|
||||
|
||||
/* Print bin counts if requested */
|
||||
|
||||
if (counts) {
|
||||
if (terse) {
|
||||
printf("2,Value,Occurrences,Fraction\n");
|
||||
} else {
|
||||
printf("Value Char Occurrences Fraction\n");
|
||||
}
|
||||
for (i = 0; i < (binary ? 2 : 256); i++) {
|
||||
if (terse) {
|
||||
printf("3,%d,%ld,%f\n", i,
|
||||
ccount[i], ((double) ccount[i] / totalc));
|
||||
} else {
|
||||
if (ccount[i] > 0) {
|
||||
printf("%3d %c %10ld %f\n", i,
|
||||
/* The following expression shows ISO 8859-1
|
||||
Latin1 characters and blanks out other codes.
|
||||
The test for ISO space replaces the ISO
|
||||
non-blanking space (0xA0) with a regular
|
||||
ASCII space, guaranteeing it's rendered
|
||||
properly even when the font doesn't contain
|
||||
that character, which is the case with many
|
||||
X fonts. */
|
||||
(!isISOprint(i) || isISOspace(i)) ? ' ' : i,
|
||||
ccount[i], ((double) ccount[i] / totalc));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!terse) {
|
||||
printf("\nTotal: %10ld %f\n\n", totalc, 1.0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Print calculated results */
|
||||
|
||||
if (!terse) {
|
||||
printf("Entropy = %f bits per %s.\n", ent, samp);
|
||||
printf("\nOptimum compression would reduce the size\n");
|
||||
printf("of this %ld %s file by %d percent.\n\n", totalc, samp,
|
||||
(short) ((100 * ((binary ? 1 : 8) - ent) /
|
||||
(binary ? 1.0 : 8.0))));
|
||||
printf(
|
||||
"Chi square distribution for %ld samples is %1.2f, and randomly\n",
|
||||
totalc, chisq);
|
||||
if (chip < 0.0001) {
|
||||
printf("would exceed this value less than 0.01 percent of the times.\n\n");
|
||||
} else if (chip > 0.9999) {
|
||||
printf("would exceed this value more than than 99.99 percent of the times.\n\n");
|
||||
} else {
|
||||
printf("would exceed this value %1.2f percent of the times.\n\n",
|
||||
chip * 100);
|
||||
}
|
||||
printf(
|
||||
"Arithmetic mean value of data %ss is %1.4f (%.1f = random).\n",
|
||||
samp, mean, binary ? 0.5 : 127.5);
|
||||
printf("Monte Carlo value for Pi is %1.9f (error %1.2f percent).\n",
|
||||
montepi, 100.0 * (fabs(PI - montepi) / PI));
|
||||
printf("Serial correlation coefficient is ");
|
||||
if (scc >= -99999) {
|
||||
printf("%1.6f (totally uncorrelated = 0.0).\n", scc);
|
||||
} else {
|
||||
printf("undefined (all values equal!).\n");
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
33
tool/decode/hex.c
Normal file
33
tool/decode/hex.c
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/stdio/stdio.h"
|
||||
|
||||
/**
|
||||
* @fileoverview Binary to hex converter program.
|
||||
*/
|
||||
|
||||
int main() {
|
||||
int o;
|
||||
while (0 <= (o = getchar()) && o <= 255) {
|
||||
putchar("0123456789ABCDEF"[o / 16]);
|
||||
putchar("0123456789ABCDEF"[o % 16]);
|
||||
}
|
||||
putchar('\n');
|
||||
}
|
57
tool/decode/lib/asmcodegen.c
Normal file
57
tool/decode/lib/asmcodegen.c
Normal file
|
@ -0,0 +1,57 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/safemacros.h"
|
||||
#include "libc/fmt/fmt.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/runtime/gc.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "tool/decode/lib/asmcodegen.h"
|
||||
|
||||
char b1[BUFSIZ];
|
||||
char b2[BUFSIZ];
|
||||
|
||||
char *format(char *buf, const char *fmt, ...) {
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
vsnprintf(buf, BUFSIZ, fmt, va);
|
||||
va_end(va);
|
||||
return buf;
|
||||
}
|
||||
|
||||
nodiscard char *tabpad(const char *s, unsigned width) {
|
||||
char *p;
|
||||
size_t i, l, need;
|
||||
l = strlen(s);
|
||||
need = width > l ? (roundup(width, 8) - l - 1) / 8 + 1 : 0;
|
||||
p = memcpy(malloc(l + need + 1), s, l);
|
||||
for (i = 0; i < need; ++i) p[l + i] = '\t';
|
||||
p[l + need] = '\0';
|
||||
return p;
|
||||
}
|
||||
|
||||
void show(const char *directive, const char *value, const char *comment) {
|
||||
if (comment) {
|
||||
printf("\t%s\t%s# %s\n", directive, gc(tabpad(value, COLUMN_WIDTH)),
|
||||
comment);
|
||||
} else {
|
||||
printf("\t%s\t%s\n", directive, gc(tabpad(value, COLUMN_WIDTH)));
|
||||
}
|
||||
}
|
27
tool/decode/lib/asmcodegen.h
Normal file
27
tool/decode/lib/asmcodegen.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
#ifndef COSMOPOLITAN_TOOL_DECODE_LIB_ASMCODEGEN_H_
|
||||
#define COSMOPOLITAN_TOOL_DECODE_LIB_ASMCODEGEN_H_
|
||||
#include "tool/decode/lib/idname.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
#define COLUMN_WIDTH 24
|
||||
|
||||
#define showint(x) show(".long", format(b1, "%d", x), #x)
|
||||
#define showint64(x) show(".quad", format(b1, "%ld", x), #x)
|
||||
#define showbyte(x) show(".byte", format(b1, "%hhn", x), #x)
|
||||
#define showshort(x) show(".short", format(b1, "%hn", x), #x)
|
||||
#define showshorthex(x) show(".short", format(b1, "%#-6hX", x), #x)
|
||||
#define showinthex(x) show(".long", format(b1, "%#X", x), #x)
|
||||
#define showint64hex(x) show(".quad", format(b1, "%#lX", x), #x)
|
||||
#define showorg(x) show(".org", format(b1, "%#lX", x), #x)
|
||||
|
||||
extern char b1[BUFSIZ];
|
||||
extern char b2[BUFSIZ];
|
||||
|
||||
char *format(char *buf, const char *fmt, ...);
|
||||
nodiscard char *tabpad(const char *s, unsigned width);
|
||||
void show(const char *directive, const char *value, const char *comment);
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_TOOL_DECODE_LIB_ASMCODEGEN_H_ */
|
76
tool/decode/lib/bitabuilder.c
Normal file
76
tool/decode/lib/bitabuilder.c
Normal file
|
@ -0,0 +1,76 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/bits/bits.h"
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/macros.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "tool/decode/lib/bitabuilder.h"
|
||||
|
||||
/**
|
||||
* @fileoverview Sparse bit array builder.
|
||||
*/
|
||||
|
||||
struct BitaBuilder {
|
||||
size_t i, n;
|
||||
unsigned *p;
|
||||
};
|
||||
|
||||
struct BitaBuilder *bitabuilder_new(void) {
|
||||
return calloc(1, sizeof(struct BitaBuilder));
|
||||
}
|
||||
|
||||
void bitabuilder_free(struct BitaBuilder **bbpp) {
|
||||
if (*bbpp) {
|
||||
free_s(&(*bbpp)->p);
|
||||
free_s(bbpp);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets bit.
|
||||
*
|
||||
* @return false if out of memory
|
||||
*/
|
||||
bool bitabuilder_setbit(struct BitaBuilder *bb, size_t bit) {
|
||||
void *p2;
|
||||
size_t i, n;
|
||||
i = MAX(bb->i, ROUNDUP(bit / CHAR_BIT + 1, __BIGGEST_ALIGNMENT__));
|
||||
if (i > bb->n) {
|
||||
n = i + (i >> 2);
|
||||
if ((p2 = realloc(bb->p, n))) {
|
||||
memset((char *)p2 + bb->n, 0, n - bb->n);
|
||||
bb->n = n;
|
||||
bb->p = p2;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
bb->i = i;
|
||||
bts(bb->p, bit);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool bitabuilder_fwrite(const struct BitaBuilder *bb, FILE *f) {
|
||||
return fwrite(bb->p, bb->i, 1, f);
|
||||
}
|
15
tool/decode/lib/bitabuilder.h
Normal file
15
tool/decode/lib/bitabuilder.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
#ifndef COSMOPOLITAN_TOOL_DECODE_LIB_BITABUILDER_H_
|
||||
#define COSMOPOLITAN_TOOL_DECODE_LIB_BITABUILDER_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
struct FILE;
|
||||
struct BitaBuilder;
|
||||
struct BitaBuilder *bitabuilder_new(void);
|
||||
bool bitabuilder_setbit(struct BitaBuilder *, size_t);
|
||||
bool bitabuilder_fwrite(const struct BitaBuilder *, struct FILE *);
|
||||
void bitabuilder_free(struct BitaBuilder **);
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_TOOL_DECODE_LIB_BITABUILDER_H_ */
|
62
tool/decode/lib/decodelib.mk
Normal file
62
tool/decode/lib/decodelib.mk
Normal file
|
@ -0,0 +1,62 @@
|
|||
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
||||
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
|
||||
|
||||
PKGS += TOOL_DECODE_LIB
|
||||
|
||||
TOOL_DECODE_LIB_ARTIFACTS += TOOL_DECODE_LIB_A
|
||||
TOOL_DECODE_LIB = $(TOOL_DECODE_LIB_A_DEPS) $(TOOL_DECODE_LIB_A)
|
||||
TOOL_DECODE_LIB_A = o/$(MODE)/tool/decode/lib/decodelib.a
|
||||
TOOL_DECODE_LIB_A_FILES := $(wildcard tool/decode/lib/*)
|
||||
TOOL_DECODE_LIB_A_HDRS = $(filter %.h,$(TOOL_DECODE_LIB_A_FILES))
|
||||
TOOL_DECODE_LIB_A_SRCS_S = $(filter %.S,$(TOOL_DECODE_LIB_A_FILES))
|
||||
TOOL_DECODE_LIB_A_SRCS_C = $(filter %.c,$(TOOL_DECODE_LIB_A_FILES))
|
||||
TOOL_DECODE_LIB_A_CHECKS = $(TOOL_DECODE_LIB_A).pkg
|
||||
|
||||
TOOL_DECODE_LIB_A_SRCS = \
|
||||
$(TOOL_DECODE_LIB_A_SRCS_S) \
|
||||
$(TOOL_DECODE_LIB_A_SRCS_C)
|
||||
|
||||
TOOL_DECODE_LIB_A_OBJS = \
|
||||
$(TOOL_DECODE_LIB_A_SRCS:%=o/$(MODE)/%.zip.o) \
|
||||
$(TOOL_DECODE_LIB_A_SRCS_S:%.S=o/$(MODE)/%.o) \
|
||||
$(TOOL_DECODE_LIB_A_SRCS_C:%.c=o/$(MODE)/%.o)
|
||||
|
||||
TOOL_DECODE_LIB_A_DIRECTDEPS = \
|
||||
LIBC_FMT \
|
||||
LIBC_MEM \
|
||||
LIBC_NEXGEN32E \
|
||||
LIBC_RUNTIME \
|
||||
LIBC_STUBS \
|
||||
LIBC_STR \
|
||||
LIBC_STDIO \
|
||||
LIBC_SYSV \
|
||||
LIBC_UNICODE
|
||||
|
||||
TOOL_DECODE_LIB_A_DEPS := \
|
||||
$(call uniq,$(foreach x,$(TOOL_DECODE_LIB_A_DIRECTDEPS),$($(x))))
|
||||
|
||||
$(TOOL_DECODE_LIB_A): \
|
||||
tool/decode/lib/ \
|
||||
$(TOOL_DECODE_LIB_A).pkg \
|
||||
$(TOOL_DECODE_LIB_A_OBJS)
|
||||
|
||||
$(TOOL_DECODE_LIB_A).pkg: \
|
||||
$(TOOL_DECODE_LIB_A_OBJS) \
|
||||
$(foreach x,$(TOOL_DECODE_LIB_A_DIRECTDEPS),$($(x)_A).pkg)
|
||||
|
||||
TOOL_DECODE_LIB_LIBS = $(foreach x,$(TOOL_DECODE_LIB_ARTIFACTS),$($(x)))
|
||||
TOOL_DECODE_LIB_SRCS = $(foreach x,$(TOOL_DECODE_LIB_ARTIFACTS),$($(x)_SRCS))
|
||||
TOOL_DECODE_LIB_HDRS = $(foreach x,$(TOOL_DECODE_LIB_ARTIFACTS),$($(x)_HDRS))
|
||||
TOOL_DECODE_LIB_BINS = $(foreach x,$(TOOL_DECODE_LIB_ARTIFACTS),$($(x)_BINS))
|
||||
TOOL_DECODE_LIB_CHECKS = $(foreach x,$(TOOL_DECODE_LIB_ARTIFACTS),$($(x)_CHECKS))
|
||||
TOOL_DECODE_LIB_OBJS = $(foreach x,$(TOOL_DECODE_LIB_ARTIFACTS),$($(x)_OBJS))
|
||||
TOOL_DECODE_LIB_TESTS = $(foreach x,$(TOOL_DECODE_LIB_ARTIFACTS),$($(x)_TESTS))
|
||||
|
||||
o/$(MODE)/tool/decode/lib/elfidnames.o \
|
||||
o/$(MODE)/tool/decode/lib/machoidnames.o \
|
||||
o/$(MODE)/tool/decode/lib/peidnames.o: \
|
||||
DEFAULT_CFLAGS += \
|
||||
-fdata-sections
|
||||
|
||||
.PHONY: o/$(MODE)/tool/decode/lib
|
||||
o/$(MODE)/tool/decode/lib: $(TOOL_DECODE_LIB_CHECKS)
|
60
tool/decode/lib/disassemblehex.c
Normal file
60
tool/decode/lib/disassemblehex.c
Normal file
|
@ -0,0 +1,60 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "tool/decode/lib/disassemblehex.h"
|
||||
|
||||
static size_t countzeroes(const uint8_t *data, size_t size) {
|
||||
size_t i;
|
||||
for (i = 0; i < size; ++i) {
|
||||
if (data[i] != '\0') break;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
void disassemblehex(uint8_t *data, size_t size, FILE *f) {
|
||||
int col;
|
||||
uint8_t ch;
|
||||
size_t i, z;
|
||||
char16_t glyphs[kDisassembleHexColumns + 1];
|
||||
col = 0;
|
||||
for (i = 0; i < size; ++i) {
|
||||
ch = data[i];
|
||||
if (!col) {
|
||||
z = countzeroes(&data[i], size - i) / kDisassembleHexColumns;
|
||||
if (z > 2) {
|
||||
fprintf(f, "\t.%s\t%zu*%d\n", "zero", z, kDisassembleHexColumns);
|
||||
i += z * kDisassembleHexColumns;
|
||||
if (i == size) break;
|
||||
}
|
||||
fprintf(f, "\t.%s\t", "byte");
|
||||
memset(glyphs, 0, sizeof(glyphs));
|
||||
}
|
||||
/* TODO(jart): Fix Emacs */
|
||||
glyphs[col] = kCp437[ch == '"' || ch == '\\' || ch == '#' ? '.' : ch];
|
||||
if (col) fputc(',', f);
|
||||
fprintf(f, "0x%02x", ch);
|
||||
if (++col == kDisassembleHexColumns) {
|
||||
col = 0;
|
||||
fprintf(f, "\t#%hs\n", glyphs);
|
||||
}
|
||||
}
|
||||
if (col) fputc('\n', f);
|
||||
}
|
13
tool/decode/lib/disassemblehex.h
Normal file
13
tool/decode/lib/disassemblehex.h
Normal file
|
@ -0,0 +1,13 @@
|
|||
#ifndef COSMOPOLITAN_TOOL_DECODE_LIB_DISASSEMBLEHEX_H_
|
||||
#define COSMOPOLITAN_TOOL_DECODE_LIB_DISASSEMBLEHEX_H_
|
||||
|
||||
#define kDisassembleHexColumns 8
|
||||
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
void disassemblehex(uint8_t *data, size_t size, FILE *f);
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_TOOL_DECODE_LIB_DISASSEMBLEHEX_H_ */
|
264
tool/decode/lib/elfidnames.c
Normal file
264
tool/decode/lib/elfidnames.c
Normal file
|
@ -0,0 +1,264 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/elf/elf.h"
|
||||
#include "tool/decode/lib/elfidnames.h"
|
||||
|
||||
const struct IdName kElfTypeNames[] = {
|
||||
{ET_NONE, "ET_NONE"},
|
||||
{ET_REL, "ET_REL"},
|
||||
{ET_EXEC, "ET_EXEC"},
|
||||
{ET_DYN, "ET_DYN"},
|
||||
{ET_CORE, "ET_CORE"},
|
||||
{ET_NUM, "ET_NUM"},
|
||||
{ET_LOOS, "ET_LOOS"},
|
||||
{ET_HIOS, "ET_HIOS"},
|
||||
{ET_LOPROC, "ET_LOPROC"},
|
||||
{ET_HIPROC, "ET_HIPROC"},
|
||||
{0, 0},
|
||||
};
|
||||
|
||||
const struct IdName kElfOsabiNames[] = {
|
||||
{ELFOSABI_NONE, "ELFOSABI_NONE"},
|
||||
{ELFOSABI_SYSV, "ELFOSABI_SYSV"},
|
||||
{ELFOSABI_HPUX, "ELFOSABI_HPUX"},
|
||||
{ELFOSABI_NETBSD, "ELFOSABI_NETBSD"},
|
||||
{ELFOSABI_GNU, "ELFOSABI_GNU"},
|
||||
{ELFOSABI_LINUX, "ELFOSABI_LINUX"},
|
||||
{ELFOSABI_SOLARIS, "ELFOSABI_SOLARIS"},
|
||||
{ELFOSABI_AIX, "ELFOSABI_AIX"},
|
||||
{ELFOSABI_IRIX, "ELFOSABI_IRIX"},
|
||||
{ELFOSABI_FREEBSD, "ELFOSABI_FREEBSD"},
|
||||
{ELFOSABI_TRU64, "ELFOSABI_TRU64"},
|
||||
{ELFOSABI_MODESTO, "ELFOSABI_MODESTO"},
|
||||
{ELFOSABI_OPENBSD, "ELFOSABI_OPENBSD"},
|
||||
{ELFOSABI_ARM, "ELFOSABI_ARM"},
|
||||
{ELFOSABI_STANDALONE, "ELFOSABI_STANDALONE"},
|
||||
{0, 0},
|
||||
};
|
||||
|
||||
const struct IdName kElfClassNames[] = {
|
||||
{ELFCLASSNONE, "ELFCLASSNONE"},
|
||||
{ELFCLASS32, "ELFCLASS32"},
|
||||
{ELFCLASS64, "ELFCLASS64"},
|
||||
{0, 0},
|
||||
};
|
||||
|
||||
const struct IdName kElfDataNames[] = {
|
||||
{ELFDATANONE, "ELFDATANONE"},
|
||||
{ELFDATA2LSB, "ELFDATA2LSB"},
|
||||
{ELFDATA2MSB, "ELFDATA2MSB"},
|
||||
{0, 0},
|
||||
};
|
||||
|
||||
const struct IdName kElfMachineNames[] = {
|
||||
{EM_M32, "EM_M32"},
|
||||
{EM_386, "EM_386"},
|
||||
{EM_S390, "EM_S390"},
|
||||
{EM_ARM, "EM_ARM"},
|
||||
{EM_NEXGEN32E, "EM_NEXGEN32E"},
|
||||
{EM_PDP11, "EM_PDP11"},
|
||||
{EM_CRAYNV2, "EM_CRAYNV2"},
|
||||
{EM_L10M, "EM_L10M"},
|
||||
{EM_K10M, "EM_K10M"},
|
||||
{EM_AARCH64, "EM_AARCH64"},
|
||||
{EM_CUDA, "EM_CUDA"},
|
||||
{EM_Z80, "EM_Z80"},
|
||||
{EM_RISCV, "EM_RISCV"},
|
||||
{EM_BPF, "EM_BPF"},
|
||||
{0, 0},
|
||||
};
|
||||
|
||||
const struct IdName kElfSegmentTypeNames[] = {
|
||||
{PT_NULL, "PT_NULL"}, /* Program header table entry unused */
|
||||
{PT_LOAD, "PT_LOAD"}, /* Loadable program segment */
|
||||
{PT_DYNAMIC, "PT_DYNAMIC"}, /* Dynamic linking information */
|
||||
{PT_INTERP, "PT_INTERP"}, /* Program interpreter */
|
||||
{PT_NOTE, "PT_NOTE"}, /* Auxiliary information */
|
||||
{PT_SHLIB, "PT_SHLIB"}, /* Reserved */
|
||||
{PT_PHDR, "PT_PHDR"}, /* Entry for header table itself */
|
||||
{PT_TLS, "PT_TLS"}, /* Thread-local storage segment */
|
||||
{PT_NUM, "PT_NUM"}, /* Number of defined types */
|
||||
{PT_LOOS, "PT_LOOS"}, /* Start of OS-specific */
|
||||
{PT_GNU_EH_FRAME, "PT_GNU_EH_FRAME"}, /* GCC .eh_frame_hdr segment */
|
||||
{PT_GNU_STACK, "PT_GNU_STACK"}, /* Indicates stack executability */
|
||||
{PT_GNU_RELRO, "PT_GNU_RELRO"}, /* Read-only after relocation */
|
||||
{PT_LOSUNW, "PT_LOSUNW"}, /* <Reserved for Sun Micrososystems> */
|
||||
{PT_SUNWBSS, "PT_SUNWBSS"}, /* Sun Specific segment */
|
||||
{PT_SUNWSTACK, "PT_SUNWSTACK"}, /* Stack segment */
|
||||
{PT_HISUNW, "PT_HISUNW"}, /* </Reserved for Sun Micrososystems> */
|
||||
{PT_HIOS, "PT_HIOS"}, /* End of OS-specific */
|
||||
{PT_LOPROC, "PT_LOPROC"}, /* Start of processor-specific */
|
||||
{PT_HIPROC, "PT_HIPROC"}, /* End of processor-specific */
|
||||
{0, 0},
|
||||
};
|
||||
|
||||
const struct IdName kElfSectionTypeNames[] = {
|
||||
{SHT_NULL, "SHT_NULL"},
|
||||
{SHT_PROGBITS, "SHT_PROGBITS"},
|
||||
{SHT_SYMTAB, "SHT_SYMTAB"},
|
||||
{SHT_STRTAB, "SHT_STRTAB"},
|
||||
{SHT_RELA, "SHT_RELA"},
|
||||
{SHT_HASH, "SHT_HASH"},
|
||||
{SHT_DYNAMIC, "SHT_DYNAMIC"},
|
||||
{SHT_NOTE, "SHT_NOTE"},
|
||||
{SHT_NOBITS, "SHT_NOBITS"},
|
||||
{SHT_REL, "SHT_REL"},
|
||||
{SHT_SHLIB, "SHT_SHLIB"},
|
||||
{SHT_DYNSYM, "SHT_DYNSYM"},
|
||||
{SHT_INIT_ARRAY, "SHT_INIT_ARRAY"},
|
||||
{SHT_FINI_ARRAY, "SHT_FINI_ARRAY"},
|
||||
{SHT_PREINIT_ARRAY, "SHT_PREINIT_ARRAY"},
|
||||
{SHT_GROUP, "SHT_GROUP"},
|
||||
{SHT_SYMTAB_SHNDX, "SHT_SYMTAB_SHNDX"},
|
||||
{SHT_NUM, "SHT_NUM"},
|
||||
{SHT_LOOS, "SHT_LOOS"},
|
||||
{SHT_GNU_ATTRIBUTES, "SHT_GNU_ATTRIBUTES"},
|
||||
{SHT_GNU_HASH, "SHT_GNU_HASH"},
|
||||
{SHT_GNU_LIBLIST, "SHT_GNU_LIBLIST"},
|
||||
{SHT_CHECKSUM, "SHT_CHECKSUM"},
|
||||
{SHT_LOSUNW, "SHT_LOSUNW"},
|
||||
{SHT_SUNW_move, "SHT_SUNW_move"},
|
||||
{SHT_SUNW_COMDAT, "SHT_SUNW_COMDAT"},
|
||||
{SHT_SUNW_syminfo, "SHT_SUNW_syminfo"},
|
||||
{SHT_GNU_verdef, "SHT_GNU_verdef"},
|
||||
{SHT_GNU_verneed, "SHT_GNU_verneed"},
|
||||
{SHT_GNU_versym, "SHT_GNU_versym"},
|
||||
{SHT_HISUNW, "SHT_HISUNW"},
|
||||
{SHT_HIOS, "SHT_HIOS"},
|
||||
{SHT_LOPROC, "SHT_LOPROC"},
|
||||
{SHT_HIPROC, "SHT_HIPROC"},
|
||||
{SHT_LOUSER, "SHT_LOUSER"},
|
||||
{SHT_HIUSER, "SHT_HIUSER"},
|
||||
{0, 0},
|
||||
};
|
||||
|
||||
const struct IdName kElfSegmentFlagNames[] = {
|
||||
{PF_X, "PF_X"},
|
||||
{PF_W, "PF_W"},
|
||||
{PF_R, "PF_R"},
|
||||
{PF_MASKOS, "PF_MASKOS"},
|
||||
{PF_MASKPROC, "PF_MASKPROC"},
|
||||
{0, 0},
|
||||
};
|
||||
|
||||
const struct IdName kElfSectionFlagNames[] = {
|
||||
{SHF_WRITE, "SHF_WRITE"},
|
||||
{SHF_ALLOC, "SHF_ALLOC"},
|
||||
{SHF_EXECINSTR, "SHF_EXECINSTR"},
|
||||
{SHF_MERGE, "SHF_MERGE"},
|
||||
{SHF_STRINGS, "SHF_STRINGS"},
|
||||
{SHF_INFO_LINK, "SHF_INFO_LINK"},
|
||||
{SHF_LINK_ORDER, "SHF_LINK_ORDER"},
|
||||
{SHF_OS_NONCONFORMING, "SHF_OS_NONCONFORMING"},
|
||||
{SHF_GROUP, "SHF_GROUP"},
|
||||
{SHF_TLS, "SHF_TLS"},
|
||||
{SHF_COMPRESSED, "SHF_COMPRESSED"},
|
||||
{SHF_MASKOS, "SHF_MASKOS"},
|
||||
{SHF_MASKPROC, "SHF_MASKPROC"},
|
||||
{SHF_ORDERED, "SHF_ORDERED"},
|
||||
{SHF_EXCLUDE, "SHF_EXCLUDE"},
|
||||
{0, 0},
|
||||
};
|
||||
|
||||
const struct IdName kElfSymbolTypeNames[] = {
|
||||
{STT_NOTYPE, "STT_NOTYPE"}, {STT_OBJECT, "STT_OBJECT"},
|
||||
{STT_FUNC, "STT_FUNC"}, {STT_SECTION, "STT_SECTION"},
|
||||
{STT_FILE, "STT_FILE"}, {STT_COMMON, "STT_COMMON"},
|
||||
{STT_TLS, "STT_TLS"}, {STT_NUM, "STT_NUM"},
|
||||
{STT_LOOS, "STT_LOOS"}, {STT_GNU_IFUNC, "STT_GNU_IFUNC"},
|
||||
{STT_HIOS, "STT_HIOS"}, {STT_LOPROC, "STT_LOPROC"},
|
||||
{STT_HIPROC, "STT_HIPROC"}, {0, 0},
|
||||
};
|
||||
|
||||
const struct IdName kElfSymbolBindNames[] = {
|
||||
{STB_LOCAL, "STB_LOCAL"}, {STB_GLOBAL, "STB_GLOBAL"},
|
||||
{STB_WEAK, "STB_WEAK"}, {STB_NUM, "STB_NUM"},
|
||||
{STB_LOOS, "STB_LOOS"}, {STB_GNU_UNIQUE, "STB_GNU_UNIQUE"},
|
||||
{STB_HIOS, "STB_HIOS"}, {STB_LOPROC, "STB_LOPROC"},
|
||||
{STB_HIPROC, "STB_HIPROC"}, {0, 0},
|
||||
};
|
||||
|
||||
const struct IdName kElfSymbolVisibilityNames[] = {
|
||||
{STV_DEFAULT, "STV_DEFAULT"},
|
||||
{STV_INTERNAL, "STV_INTERNAL"},
|
||||
{STV_HIDDEN, "STV_HIDDEN"},
|
||||
{STV_PROTECTED, "STV_PROTECTED"},
|
||||
{0, 0},
|
||||
};
|
||||
|
||||
const struct IdName kElfSpecialSectionNames[] = {
|
||||
{SHN_UNDEF, "SHN_UNDEF"},
|
||||
{SHN_LORESERVE, "SHN_LORESERVE"},
|
||||
{SHN_LOPROC, "SHN_LOPROC"},
|
||||
{SHN_BEFORE, "SHN_BEFORE"},
|
||||
{SHN_AFTER, "SHN_AFTER"},
|
||||
{SHN_HIPROC, "SHN_HIPROC"},
|
||||
{SHN_LOOS, "SHN_LOOS"},
|
||||
{SHN_HIOS, "SHN_HIOS"},
|
||||
{SHN_ABS, "SHN_ABS"},
|
||||
{SHN_COMMON, "SHN_COMMON"},
|
||||
{SHN_XINDEX, "SHN_XINDEX"},
|
||||
{SHN_HIRESERVE, "SHN_HIRESERVE"},
|
||||
{0, 0},
|
||||
};
|
||||
|
||||
const struct IdName kElfNexgen32eRelocationNames[] = {
|
||||
{R_X86_64_64, "64"},
|
||||
{R_X86_64_PC32, "PC32"},
|
||||
{R_X86_64_GOT32, "GOT32"},
|
||||
{R_X86_64_PLT32, "PLT32"},
|
||||
{R_X86_64_COPY, "COPY"},
|
||||
{R_X86_64_GLOB_DAT, "GLOB_DAT"},
|
||||
{R_X86_64_JUMP_SLOT, "JUMP_SLOT"},
|
||||
{R_X86_64_RELATIVE, "RELATIVE"},
|
||||
{R_X86_64_GOTPCREL, "GOTPCREL"},
|
||||
{R_X86_64_32, "32"},
|
||||
{R_X86_64_32S, "32S"},
|
||||
{R_X86_64_16, "16"},
|
||||
{R_X86_64_PC16, "PC16"},
|
||||
{R_X86_64_8, "8"},
|
||||
{R_X86_64_PC8, "PC8"},
|
||||
{R_X86_64_DTPMOD64, "DTPMOD64"},
|
||||
{R_X86_64_DTPOFF64, "DTPOFF64"},
|
||||
{R_X86_64_TPOFF64, "TPOFF64"},
|
||||
{R_X86_64_TLSGD, "TLSGD"},
|
||||
{R_X86_64_TLSLD, "TLSLD"},
|
||||
{R_X86_64_DTPOFF32, "DTPOFF32"},
|
||||
{R_X86_64_GOTTPOFF, "GOTTPOFF"},
|
||||
{R_X86_64_TPOFF32, "TPOFF32"},
|
||||
{R_X86_64_PC64, "PC64"},
|
||||
{R_X86_64_GOTOFF64, "GOTOFF64"},
|
||||
{R_X86_64_GOTPC32, "GOTPC32"},
|
||||
{R_X86_64_GOT64, "GOT64"},
|
||||
{R_X86_64_GOTPCREL64, "GOTPCREL64"},
|
||||
{R_X86_64_GOTPC64, "GOTPC64"},
|
||||
{R_X86_64_GOTPLT64, "GOTPLT64"},
|
||||
{R_X86_64_PLTOFF64, "PLTOFF64"},
|
||||
{R_X86_64_SIZE32, "SIZE32"},
|
||||
{R_X86_64_SIZE64, "SIZE64"},
|
||||
{R_X86_64_GOTPC32_TLSDESC, "GOTPC32_TLSDESC"},
|
||||
{R_X86_64_TLSDESC_CALL, "TLSDESC_CALL"},
|
||||
{R_X86_64_TLSDESC, "TLSDESC"},
|
||||
{R_X86_64_IRELATIVE, "IRELATIVE"},
|
||||
{R_X86_64_RELATIVE64, "RELATIVE64"},
|
||||
{R_X86_64_GOTPCRELX, "GOTPCRELX"},
|
||||
{R_X86_64_REX_GOTPCRELX, "REX_GOTPCRELX"},
|
||||
{0, 0},
|
||||
};
|
24
tool/decode/lib/elfidnames.h
Normal file
24
tool/decode/lib/elfidnames.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
#ifndef COSMOPOLITAN_TOOL_DECODE_LIB_ELFIDNAMES_H_
|
||||
#define COSMOPOLITAN_TOOL_DECODE_LIB_ELFIDNAMES_H_
|
||||
#include "tool/decode/lib/idname.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
extern const struct IdName kElfTypeNames[];
|
||||
extern const struct IdName kElfOsabiNames[];
|
||||
extern const struct IdName kElfClassNames[];
|
||||
extern const struct IdName kElfDataNames[];
|
||||
extern const struct IdName kElfMachineNames[];
|
||||
extern const struct IdName kElfSegmentTypeNames[];
|
||||
extern const struct IdName kElfSectionTypeNames[];
|
||||
extern const struct IdName kElfSegmentFlagNames[];
|
||||
extern const struct IdName kElfSectionFlagNames[];
|
||||
extern const struct IdName kElfSymbolTypeNames[];
|
||||
extern const struct IdName kElfSymbolBindNames[];
|
||||
extern const struct IdName kElfSymbolVisibilityNames[];
|
||||
extern const struct IdName kElfSpecialSectionNames[];
|
||||
extern const struct IdName kElfNexgen32eRelocationNames[];
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_TOOL_DECODE_LIB_ELFIDNAMES_H_ */
|
62
tool/decode/lib/flagger.c
Normal file
62
tool/decode/lib/flagger.c
Normal file
|
@ -0,0 +1,62 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/alg/arraylist.h"
|
||||
#include "libc/fmt/fmt.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "tool/decode/lib/flagger.h"
|
||||
|
||||
struct FlagNameBuf {
|
||||
size_t i, n;
|
||||
char *p;
|
||||
};
|
||||
|
||||
/**
|
||||
* Formats numeric flags integer as symbolic code.
|
||||
*
|
||||
* @param names maps individual flags to string names in no order
|
||||
* @param id is the flags
|
||||
* @return NUL-terminated string that needs free()
|
||||
*/
|
||||
nodiscard char *recreateflags(const struct IdName *names, unsigned long id) {
|
||||
struct FlagNameBuf buf = {};
|
||||
char extrabuf[20];
|
||||
bool first;
|
||||
first = true;
|
||||
for (; names->name; names++) {
|
||||
if ((id == 0 && names->id == 0) ||
|
||||
(id != 0 && names->id != 0 && (id & names->id) == names->id)) {
|
||||
id &= ~names->id;
|
||||
if (!first) {
|
||||
append(&buf, "|");
|
||||
} else {
|
||||
first = false;
|
||||
}
|
||||
concat(&buf, names->name, strlen(names->name));
|
||||
}
|
||||
}
|
||||
if (id) {
|
||||
if (buf.i) append(&buf, "|");
|
||||
concat(&buf, extrabuf, snprintf(extrabuf, sizeof(extrabuf), "%#x", id));
|
||||
} else if (!buf.i) {
|
||||
append(&buf, "0");
|
||||
}
|
||||
return buf.p;
|
||||
}
|
11
tool/decode/lib/flagger.h
Normal file
11
tool/decode/lib/flagger.h
Normal file
|
@ -0,0 +1,11 @@
|
|||
#ifndef COSMOPOLITAN_TOOL_DECODE_LIB_FLAGGER_H_
|
||||
#define COSMOPOLITAN_TOOL_DECODE_LIB_FLAGGER_H_
|
||||
#include "tool/decode/lib/idname.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
char *recreateflags(const struct IdName *, unsigned long) nodiscard;
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_TOOL_DECODE_LIB_FLAGGER_H_ */
|
29
tool/decode/lib/idname.c
Normal file
29
tool/decode/lib/idname.c
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "tool/decode/lib/idname.h"
|
||||
|
||||
const char *findnamebyid(const struct IdName *names, unsigned long id) {
|
||||
for (; names->name; names++) {
|
||||
if (names->id == id) {
|
||||
return names->name;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
15
tool/decode/lib/idname.h
Normal file
15
tool/decode/lib/idname.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
#ifndef COSMOPOLITAN_TOOL_DECODE_LIB_IDNAME_H_
|
||||
#define COSMOPOLITAN_TOOL_DECODE_LIB_IDNAME_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
struct IdName {
|
||||
unsigned long id;
|
||||
const char *const name;
|
||||
};
|
||||
|
||||
const char *findnamebyid(const struct IdName *names, unsigned long id);
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_TOOL_DECODE_LIB_IDNAME_H_ */
|
150
tool/decode/lib/machoidnames.c
Normal file
150
tool/decode/lib/machoidnames.c
Normal file
|
@ -0,0 +1,150 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macho.h"
|
||||
#include "tool/decode/lib/machoidnames.h"
|
||||
|
||||
const struct IdName kMachoFileTypeNames[] = {
|
||||
{MAC_OBJECT, "MAC_OBJECT"},
|
||||
{MAC_EXECUTE, "MAC_EXECUTE"},
|
||||
{MAC_FVMLIB, "MAC_FVMLIB"},
|
||||
{MAC_CORE, "MAC_CORE"},
|
||||
{MAC_PRELOAD, "MAC_PRELOAD"},
|
||||
{MAC_DYLIB, "MAC_DYLIB"},
|
||||
{MAC_DYLINKER, "MAC_DYLINKER"},
|
||||
{MAC_BUNDLE, "MAC_BUNDLE"},
|
||||
{0, 0},
|
||||
};
|
||||
|
||||
const struct IdName kMachoFlagNames[] = {
|
||||
{MAC_NOUNDEFS, "MAC_NOUNDEFS"},
|
||||
{MAC_INCRLINK, "MAC_INCRLINK"},
|
||||
{MAC_DYLDLINK, "MAC_DYLDLINK"},
|
||||
{MAC_BINDATLOAD, "MAC_BINDATLOAD"},
|
||||
{MAC_PREBOUND, "MAC_PREBOUND"},
|
||||
{MAC_SPLIT_SEGS, "MAC_SPLIT_SEGS"},
|
||||
{MAC_LAZY_INIT, "MAC_LAZY_INIT"},
|
||||
{MAC_TWOLEVEL, "MAC_TWOLEVEL"},
|
||||
{MAC_FORCE_FLAT, "MAC_FORCE_FLAT"},
|
||||
{MAC_NOMULTIDEFS, "MAC_NOMULTIDEFS"},
|
||||
{MAC_NOFIXPREBINDING, "MAC_NOFIXPREBINDING"},
|
||||
{MAC_PREBINDABLE, "MAC_PREBINDABLE"},
|
||||
{MAC_ALLMODSBOUND, "MAC_ALLMODSBOUND"},
|
||||
{MAC_SUBSECTIONS_VIA_SYMBOLS, "MAC_SUBSECTIONS_VIA_SYMBOLS"},
|
||||
{MAC_CANONICAL, "MAC_CANONICAL"},
|
||||
{0, 0},
|
||||
};
|
||||
|
||||
const struct IdName kMachoSegmentFlagNames[] = {
|
||||
{MAC_SG_HIGHVM, "MAC_SG_HIGHVM"},
|
||||
{MAC_SG_FVMLIB, "MAC_SG_FVMLIB"},
|
||||
{MAC_SG_NORELOC, "MAC_SG_NORELOC"},
|
||||
{0, 0},
|
||||
};
|
||||
|
||||
const struct IdName kMachoSectionTypeNames[] = {
|
||||
{MAC_S_REGULAR, "MAC_S_REGULAR"},
|
||||
{MAC_S_ZEROFILL, "MAC_S_ZEROFILL"},
|
||||
{MAC_S_CSTRING_LITERALS, "MAC_S_CSTRING_LITERALS"},
|
||||
{MAC_S_4BYTE_LITERALS, "MAC_S_4BYTE_LITERALS"},
|
||||
{MAC_S_8BYTE_LITERALS, "MAC_S_8BYTE_LITERALS"},
|
||||
{MAC_S_LITERAL_POINTERS, "MAC_S_LITERAL_POINTERS"},
|
||||
{MAC_S_NON_LAZY_SYMBOL_POINTERS, "MAC_S_NON_LAZY_SYMBOL_POINTERS"},
|
||||
{MAC_S_LAZY_SYMBOL_POINTERS, "MAC_S_LAZY_SYMBOL_POINTERS"},
|
||||
{MAC_S_SYMBOL_STUBS, "MAC_S_SYMBOL_STUBS"},
|
||||
{MAC_S_MOD_INIT_FUNC_POINTERS, "MAC_S_MOD_INIT_FUNC_POINTERS"},
|
||||
{MAC_S_MOD_TERM_FUNC_POINTERS, "MAC_S_MOD_TERM_FUNC_POINTERS"},
|
||||
{MAC_S_COALESCED, "MAC_S_COALESCED"},
|
||||
{MAC_S_GB_ZEROFILL, "MAC_S_GB_ZEROFILL"},
|
||||
{MAC_S_INTERPOSING, "MAC_S_INTERPOSING"},
|
||||
{MAC_S_16BYTE_LITERALS, "MAC_S_16BYTE_LITERALS"},
|
||||
{0, 0},
|
||||
};
|
||||
|
||||
const struct IdName kMachoSectionAttributeNames[] = {
|
||||
{MAC_SECTION_ATTRIBUTES_USR, "MAC_SECTION_ATTRIBUTES_USR"},
|
||||
{MAC_S_ATTR_PURE_INSTRUCTIONS, "MAC_S_ATTR_PURE_INSTRUCTIONS"},
|
||||
{MAC_S_ATTR_NO_TOC, "MAC_S_ATTR_NO_TOC"},
|
||||
{MAC_S_ATTR_STRIP_STATIC_SYMS, "MAC_S_ATTR_STRIP_STATIC_SYMS"},
|
||||
{MAC_S_ATTR_NO_DEAD_STRIP, "MAC_S_ATTR_NO_DEAD_STRIP"},
|
||||
{MAC_S_ATTR_LIVE_SUPPORT, "MAC_S_ATTR_LIVE_SUPPORT"},
|
||||
{MAC_S_ATTR_SELF_MODIFYING_CODE, "MAC_S_ATTR_SELF_MODIFYING_CODE"},
|
||||
{MAC_S_ATTR_DEBUG, "MAC_S_ATTR_DEBUG"},
|
||||
{MAC_SECTION_ATTRIBUTES_SYS, "MAC_SECTION_ATTRIBUTES_SYS"},
|
||||
{MAC_S_ATTR_SOME_INSTRUCTIONS, "MAC_S_ATTR_SOME_INSTRUCTIONS"},
|
||||
{MAC_S_ATTR_EXT_RELOC, "MAC_S_ATTR_EXT_RELOC"},
|
||||
{MAC_S_ATTR_LOC_RELOC, "MAC_S_ATTR_LOC_RELOC"},
|
||||
{0, 0},
|
||||
};
|
||||
|
||||
const struct IdName kMachoLoadCommandNames[] = {
|
||||
{MAC_LC_REQ_DYLD, "MAC_LC_REQ_DYLD"},
|
||||
{MAC_LC_SEGMENT, "MAC_LC_SEGMENT"},
|
||||
{MAC_LC_SYMTAB, "MAC_LC_SYMTAB"},
|
||||
{MAC_LC_SYMSEG, "MAC_LC_SYMSEG"},
|
||||
{MAC_LC_THREAD, "MAC_LC_THREAD"},
|
||||
{MAC_LC_UNIXTHREAD, "MAC_LC_UNIXTHREAD"},
|
||||
{MAC_LC_LOADFVMLIB, "MAC_LC_LOADFVMLIB"},
|
||||
{MAC_LC_IDFVMLIB, "MAC_LC_IDFVMLIB"},
|
||||
{MAC_LC_IDENT, "MAC_LC_IDENT"},
|
||||
{MAC_LC_FVMFILE, "MAC_LC_FVMFILE"},
|
||||
{MAC_LC_PREPAGE, "MAC_LC_PREPAGE"},
|
||||
{MAC_LC_DYSYMTAB, "MAC_LC_DYSYMTAB"},
|
||||
{MAC_LC_LOAD_DYLIB, "MAC_LC_LOAD_DYLIB"},
|
||||
{MAC_LC_ID_DYLIB, "MAC_LC_ID_DYLIB"},
|
||||
{MAC_LC_LOAD_DYLINKER, "MAC_LC_LOAD_DYLINKER"},
|
||||
{MAC_LC_ID_DYLINKER, "MAC_LC_ID_DYLINKER"},
|
||||
{MAC_LC_PREBOUND_DYLIB, "MAC_LC_PREBOUND_DYLIB"},
|
||||
{MAC_LC_ROUTINES, "MAC_LC_ROUTINES"},
|
||||
{MAC_LC_SUB_FRAMEWORK, "MAC_LC_SUB_FRAMEWORK"},
|
||||
{MAC_LC_SUB_UMBRELLA, "MAC_LC_SUB_UMBRELLA"},
|
||||
{MAC_LC_SUB_CLIENT, "MAC_LC_SUB_CLIENT"},
|
||||
{MAC_LC_SUB_LIBRARY, "MAC_LC_SUB_LIBRARY"},
|
||||
{MAC_LC_TWOLEVEL_HINTS, "MAC_LC_TWOLEVEL_HINTS"},
|
||||
{MAC_LC_PREBIND_CKSUM, "MAC_LC_PREBIND_CKSUM"},
|
||||
{MAC_LC_LOAD_WEAK_DYLIB, "MAC_LC_LOAD_WEAK_DYLIB"},
|
||||
{MAC_LC_SEGMENT_64, "MAC_LC_SEGMENT_64"},
|
||||
{MAC_LC_ROUTINES_64, "MAC_LC_ROUTINES_64"},
|
||||
{MAC_LC_UUID, "MAC_LC_UUID"},
|
||||
{MAC_LC_CODE_SIGNATURE, "MAC_LC_CODE_SIGNATURE"},
|
||||
{MAC_LC_SEGMENT_SPLIT_INFO, "MAC_LC_SEGMENT_SPLIT_INFO"},
|
||||
{MAC_LC_LAZY_LOAD_DYLIB, "MAC_LC_LAZY_LOAD_DYLIB"},
|
||||
{MAC_LC_ENCRYPTION_INFO, "MAC_LC_ENCRYPTION_INFO"},
|
||||
{MAC_LC_DYLD_INFO, "MAC_LC_DYLD_INFO"},
|
||||
{MAC_LC_VERSION_MIN_MACOSX, "MAC_LC_VERSION_MIN_MACOSX"},
|
||||
{MAC_LC_VERSION_MIN_IPHONEOS, "MAC_LC_VERSION_MIN_IPHONEOS"},
|
||||
{MAC_LC_FUNCTION_STARTS, "MAC_LC_FUNCTION_STARTS"},
|
||||
{MAC_LC_DYLD_ENVIRONMENT, "MAC_LC_DYLD_ENVIRONMENT"},
|
||||
{MAC_LC_DATA_IN_CODE, "MAC_LC_DATA_IN_CODE"},
|
||||
{MAC_LC_SOURCE_VERSION, "MAC_LC_SOURCE_VERSION"},
|
||||
{MAC_LC_RPATH, "MAC_LC_RPATH"},
|
||||
{MAC_LC_MAIN, "MAC_LC_MAIN"},
|
||||
{0, 0},
|
||||
};
|
||||
|
||||
const struct IdName kMachoVmProtNames[] = {
|
||||
{VM_PROT_READ, "VM_PROT_READ"},
|
||||
{VM_PROT_WRITE, "VM_PROT_WRITE"},
|
||||
{VM_PROT_EXECUTE, "VM_PROT_EXECUTE"},
|
||||
{VM_PROT_NO_CHANGE, "VM_PROT_NO_CHANGE"},
|
||||
{VM_PROT_COPY, "VM_PROT_COPY"},
|
||||
{VM_PROT_TRUSTED, "VM_PROT_TRUSTED"},
|
||||
{VM_PROT_STRIP_READ, "VM_PROT_STRIP_READ"},
|
||||
{0, 0},
|
||||
};
|
17
tool/decode/lib/machoidnames.h
Normal file
17
tool/decode/lib/machoidnames.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
#ifndef COSMOPOLITAN_TOOL_DECODE_LIB_MACHOIDNAMES_H_
|
||||
#define COSMOPOLITAN_TOOL_DECODE_LIB_MACHOIDNAMES_H_
|
||||
#include "tool/decode/lib/idname.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
extern const struct IdName kMachoFileTypeNames[];
|
||||
extern const struct IdName kMachoFlagNames[];
|
||||
extern const struct IdName kMachoSegmentFlagNames[];
|
||||
extern const struct IdName kMachoSectionTypeNames[];
|
||||
extern const struct IdName kMachoSectionAttributeNames[];
|
||||
extern const struct IdName kMachoLoadCommandNames[];
|
||||
extern const struct IdName kMachoVmProtNames[];
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_TOOL_DECODE_LIB_MACHOIDNAMES_H_ */
|
51
tool/decode/lib/ntfileflagnames.c
Normal file
51
tool/decode/lib/ntfileflagnames.c
Normal file
|
@ -0,0 +1,51 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/nt/enum/fileflagandattributes.h"
|
||||
#include "tool/decode/lib/ntfileflagnames.h"
|
||||
|
||||
const struct IdName kNtFileFlagNames[] = {
|
||||
{kNtFileAttributeReadonly, "kNtFileAttributeReadonly"},
|
||||
{kNtFileAttributeHidden, "kNtFileAttributeHidden"},
|
||||
{kNtFileAttributeSystem, "kNtFileAttributeSystem"},
|
||||
{kNtFileAttributeVolumelabel, "kNtFileAttributeVolumelabel"},
|
||||
{kNtFileAttributeDirectory, "kNtFileAttributeDirectory"},
|
||||
{kNtFileAttributeArchive, "kNtFileAttributeArchive"},
|
||||
{kNtFileAttributeDevice, "kNtFileAttributeDevice"},
|
||||
{kNtFileAttributeNormal, "kNtFileAttributeNormal"},
|
||||
{kNtFileAttributeTemporary, "kNtFileAttributeTemporary"},
|
||||
{kNtFileAttributeSparseFile, "kNtFileAttributeSparseFile"},
|
||||
{kNtFileAttributeReparsePoint, "kNtFileAttributeReparsePoint"},
|
||||
{kNtFileAttributeCompressed, "kNtFileAttributeCompressed"},
|
||||
{kNtFileAttributeOffline, "kNtFileAttributeOffline"},
|
||||
{kNtFileAttributeNotContentIndexed, "kNtFileAttributeNotContentIndexed"},
|
||||
{kNtFileAttributeEncrypted, "kNtFileAttributeEncrypted"},
|
||||
{kNtFileFlagWriteThrough, "kNtFileFlagWriteThrough"},
|
||||
{kNtFileFlagOverlapped, "kNtFileFlagOverlapped"},
|
||||
{kNtFileFlagNoBuffering, "kNtFileFlagNoBuffering"},
|
||||
{kNtFileFlagRandomAccess, "kNtFileFlagRandomAccess"},
|
||||
{kNtFileFlagSequentialScan, "kNtFileFlagSequentialScan"},
|
||||
{kNtFileFlagDeleteOnClose, "kNtFileFlagDeleteOnClose"},
|
||||
{kNtFileFlagBackupSemantics, "kNtFileFlagBackupSemantics"},
|
||||
{kNtFileFlagPosixSemantics, "kNtFileFlagPosixSemantics"},
|
||||
{kNtFileFlagOpenReparsePoint, "kNtFileFlagOpenReparsePoint"},
|
||||
{kNtFileFlagOpenNoRecall, "kNtFileFlagOpenNoRecall"},
|
||||
{kNtFileFlagFirstPipeInstance, "kNtFileFlagFirstPipeInstance"},
|
||||
{0, 0},
|
||||
};
|
11
tool/decode/lib/ntfileflagnames.h
Normal file
11
tool/decode/lib/ntfileflagnames.h
Normal file
|
@ -0,0 +1,11 @@
|
|||
#ifndef COSMOPOLITAN_TOOL_DECODE_LIB_NTFILEFLAGNAMES_H_
|
||||
#define COSMOPOLITAN_TOOL_DECODE_LIB_NTFILEFLAGNAMES_H_
|
||||
#include "tool/decode/lib/idname.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
extern const struct IdName kNtFileFlagNames[];
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_TOOL_DECODE_LIB_NTFILEFLAGNAMES_H_ */
|
179
tool/decode/lib/peidnames.c
Normal file
179
tool/decode/lib/peidnames.c
Normal file
|
@ -0,0 +1,179 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/pe.h"
|
||||
#include "tool/decode/lib/peidnames.h"
|
||||
|
||||
const struct IdName kNtImageFileMachineNames[] = {
|
||||
{kNtImageFileMachineUnknown, "kNtImageFileMachineUnknown"},
|
||||
{kNtImageFileMachineTargetHost, "kNtImageFileMachineTargetHost"},
|
||||
{kNtImageFileMachineI386, "kNtImageFileMachineI386"},
|
||||
{kNtImageFileMachineR3000, "kNtImageFileMachineR3000"},
|
||||
{kNtImageFileMachineR4000, "kNtImageFileMachineR4000"},
|
||||
{kNtImageFileMachineR10000, "kNtImageFileMachineR10000"},
|
||||
{kNtImageFileMachineWcemipsv2, "kNtImageFileMachineWcemipsv2"},
|
||||
{kNtImageFileMachineAlpha, "kNtImageFileMachineAlpha"},
|
||||
{kNtImageFileMachineSh3, "kNtImageFileMachineSh3"},
|
||||
{kNtImageFileMachineSh3dsp, "kNtImageFileMachineSh3dsp"},
|
||||
{kNtImageFileMachineSh3e, "kNtImageFileMachineSh3e"},
|
||||
{kNtImageFileMachineSh4, "kNtImageFileMachineSh4"},
|
||||
{kNtImageFileMachineSh5, "kNtImageFileMachineSh5"},
|
||||
{kNtImageFileMachineArm, "kNtImageFileMachineArm"},
|
||||
{kNtImageFileMachineThumb, "kNtImageFileMachineThumb"},
|
||||
{kNtImageFileMachineArmnt, "kNtImageFileMachineArmnt"},
|
||||
{kNtImageFileMachineAm33, "kNtImageFileMachineAm33"},
|
||||
{kNtImageFileMachinePowerpc, "kNtImageFileMachinePowerpc"},
|
||||
{kNtImageFileMachinePowerpcfp, "kNtImageFileMachinePowerpcfp"},
|
||||
{kNtImageFileMachineIa64, "kNtImageFileMachineIa64"},
|
||||
{kNtImageFileMachineMips16, "kNtImageFileMachineMips16"},
|
||||
{kNtImageFileMachineAlpha64, "kNtImageFileMachineAlpha64"},
|
||||
{kNtImageFileMachineMipsfpu, "kNtImageFileMachineMipsfpu"},
|
||||
{kNtImageFileMachineMipsfpu16, "kNtImageFileMachineMipsfpu16"},
|
||||
{kNtImageFileMachineAxp64, "kNtImageFileMachineAxp64"},
|
||||
{kNtImageFileMachineTricore, "kNtImageFileMachineTricore"},
|
||||
{kNtImageFileMachineCef, "kNtImageFileMachineCef"},
|
||||
{kNtImageFileMachineEbc, "kNtImageFileMachineEbc"},
|
||||
{kNtImageFileMachineNexgen32e, "kNtImageFileMachineNexgen32e"},
|
||||
{kNtImageFileMachineM32r, "kNtImageFileMachineM32r"},
|
||||
{kNtImageFileMachineArm64, "kNtImageFileMachineArm64"},
|
||||
{kNtImageFileMachineCee, "kNtImageFileMachineCee"},
|
||||
{0, 0},
|
||||
};
|
||||
|
||||
const struct IdName kNtPeOptionalHeaderMagicNames[] = {
|
||||
{kNtPe32bit, "kNtPe32bit"},
|
||||
{kNtPe64bit, "kNtPe64bit"},
|
||||
{0, 0},
|
||||
};
|
||||
|
||||
const struct IdName kNtImageDllcharacteristicNames[] = {
|
||||
{kNtImageDllcharacteristicsHighEntropyVa,
|
||||
"kNtImageDllcharacteristicsHighEntropyVa"},
|
||||
{kNtImageDllcharacteristicsDynamicBase,
|
||||
"kNtImageDllcharacteristicsDynamicBase"},
|
||||
{kNtImageDllcharacteristicsForceIntegrity,
|
||||
"kNtImageDllcharacteristicsForceIntegrity"},
|
||||
{kNtImageDllcharacteristicsNxCompat, "kNtImageDllcharacteristicsNxCompat"},
|
||||
{kNtImageDllcharacteristicsNoIsolation,
|
||||
"kNtImageDllcharacteristicsNoIsolation"},
|
||||
{kNtImageDllcharacteristicsNoSeh, "kNtImageDllcharacteristicsNoSeh"},
|
||||
{kNtImageDllcharacteristicsNoBind, "kNtImageDllcharacteristicsNoBind"},
|
||||
{kNtImageDllcharacteristicsAppcontainer,
|
||||
"kNtImageDllcharacteristicsAppcontainer"},
|
||||
{kNtImageDllcharacteristicsWdmDriver,
|
||||
"kNtImageDllcharacteristicsWdmDriver"},
|
||||
{kNtImageDllcharacteristicsGuardCf, "kNtImageDllcharacteristicsGuardCf"},
|
||||
{kNtImageDllcharacteristicsTerminalServerAware,
|
||||
"kNtImageDllcharacteristicsTerminalServerAware"},
|
||||
{0, 0},
|
||||
};
|
||||
|
||||
const struct IdName kNtImageSubsystemNames[] = {
|
||||
{kNtImageSubsystemUnknown, "kNtImageSubsystemUnknown"},
|
||||
{kNtImageSubsystemNative, "kNtImageSubsystemNative"},
|
||||
{kNtImageSubsystemWindowsGui, "kNtImageSubsystemWindowsGui"},
|
||||
{kNtImageSubsystemWindowsCui, "kNtImageSubsystemWindowsCui"},
|
||||
{kNtImageSubsystemOs2Cui, "kNtImageSubsystemOs2Cui"},
|
||||
{kNtImageSubsystemPosixCui, "kNtImageSubsystemPosixCui"},
|
||||
{kNtImageSubsystemNativeWindows, "kNtImageSubsystemNativeWindows"},
|
||||
{kNtImageSubsystemWindowsCeGui, "kNtImageSubsystemWindowsCeGui"},
|
||||
{kNtImageSubsystemEfiApplication, "kNtImageSubsystemEfiApplication"},
|
||||
{kNtImageSubsystemEfiBootServiceDriver,
|
||||
"kNtImageSubsystemEfiBootServiceDriver"},
|
||||
{kNtImageSubsystemEfiRuntimeDriver, "kNtImageSubsystemEfiRuntimeDriver"},
|
||||
{kNtImageSubsystemEfiRom, "kNtImageSubsystemEfiRom"},
|
||||
{kNtImageSubsystemXbox, "kNtImageSubsystemXbox"},
|
||||
{kNtImageSubsystemWindowsBootApplication,
|
||||
"kNtImageSubsystemWindowsBootApplication"},
|
||||
{kNtImageSubsystemXboxCodeCatalog, "kNtImageSubsystemXboxCodeCatalog"},
|
||||
{0, 0},
|
||||
};
|
||||
|
||||
const struct IdName kNtImageScnNames[] = {
|
||||
{kNtImageScnTypeNoPad, "kNtImageScnTypeNoPad"},
|
||||
{kNtImageScnCntCode, "kNtImageScnCntCode"},
|
||||
{kNtImageScnCntInitializedData, "kNtImageScnCntInitializedData"},
|
||||
{kNtImageScnCntUninitializedData, "kNtImageScnCntUninitializedData"},
|
||||
{kNtImageScnLnkOther, "kNtImageScnLnkOther"},
|
||||
{kNtImageScnLnkInfo, "kNtImageScnLnkInfo"},
|
||||
{kNtImageScnLnkRemove, "kNtImageScnLnkRemove"},
|
||||
{kNtImageScnLnkComdat, "kNtImageScnLnkComdat"},
|
||||
{kNtImageScnNoDeferSpecExc, "kNtImageScnNoDeferSpecExc"},
|
||||
{kNtImageScnGprel, "kNtImageScnGprel"},
|
||||
{kNtImageScnMemFardata, "kNtImageScnMemFardata"},
|
||||
{kNtImageScnMemPurgeable, "kNtImageScnMemPurgeable"},
|
||||
{kNtImageScnMem16bit, "kNtImageScnMem16bit"},
|
||||
{kNtImageScnMemLocked, "kNtImageScnMemLocked"},
|
||||
{kNtImageScnMemPreload, "kNtImageScnMemPreload"},
|
||||
{0, 0},
|
||||
};
|
||||
|
||||
const struct IdName kNtImageDirectoryEntryNames[] = {
|
||||
{kNtImageDirectoryEntryExport, "kNtImageDirectoryEntryExport"},
|
||||
{kNtImageDirectoryEntryImport, "kNtImageDirectoryEntryImport"},
|
||||
{kNtImageDirectoryEntryResource, "kNtImageDirectoryEntryResource"},
|
||||
{kNtImageDirectoryEntryException, "kNtImageDirectoryEntryException"},
|
||||
{kNtImageDirectoryEntrySecurity, "kNtImageDirectoryEntrySecurity"},
|
||||
{kNtImageDirectoryEntryBasereloc, "kNtImageDirectoryEntryBasereloc"},
|
||||
{kNtImageDirectoryEntryDebug, "kNtImageDirectoryEntryDebug"},
|
||||
{kNtImageDirectoryEntryArchitecture, "kNtImageDirectoryEntryArchitecture"},
|
||||
{kNtImageDirectoryEntryGlobalptr, "kNtImageDirectoryEntryGlobalptr"},
|
||||
{kNtImageDirectoryEntryTls, "kNtImageDirectoryEntryTls"},
|
||||
{kNtImageDirectoryEntryLoadConfig, "kNtImageDirectoryEntryLoadConfig"},
|
||||
{kNtImageDirectoryEntryBoundImport, "kNtImageDirectoryEntryBoundImport"},
|
||||
{kNtImageDirectoryEntryIat, "kNtImageDirectoryEntryIat"},
|
||||
{kNtImageDirectoryEntryDelayImport, "kNtImageDirectoryEntryDelayImport"},
|
||||
{kNtImageDirectoryEntryComDescriptor,
|
||||
"kNtImageDirectoryEntryComDescriptor"},
|
||||
{0, 0},
|
||||
};
|
||||
|
||||
const struct IdName kNtImageCharacteristicNames[] = {
|
||||
{kNtImageFileRelocsStripped, "kNtImageFileRelocsStripped"},
|
||||
{kNtImageFileExecutableImage, "kNtImageFileExecutableImage"},
|
||||
{kNtImageFileLineNumsStripped, "kNtImageFileLineNumsStripped"},
|
||||
{kNtImageFileLocalSymsStripped, "kNtImageFileLocalSymsStripped"},
|
||||
{kNtImageFileAggresiveWsTrim, "kNtImageFileAggresiveWsTrim"},
|
||||
{kNtImageFileLargeAddressAware, "kNtImageFileLargeAddressAware"},
|
||||
{kNtImageFileBytesReversedLo, "kNtImageFileBytesReversedLo"},
|
||||
{kNtImageFile32bitMachine, "kNtImageFile32bitMachine"},
|
||||
{kNtImageFileDebugStripped, "kNtImageFileDebugStripped"},
|
||||
{kNtImageFileRemovableRunFromSwap, "kNtImageFileRemovableRunFromSwap"},
|
||||
{kNtImageFileNetRunFromSwap, "kNtImageFileNetRunFromSwap"},
|
||||
{kNtImageFileSystem, "kNtImageFileSystem"},
|
||||
{kNtImageFileDll, "kNtImageFileDll"},
|
||||
{kNtImageFileUpSystemOnly, "kNtImageFileUpSystemOnly"},
|
||||
{kNtImageFileBytesReversedHi, "kNtImageFileBytesReversedHi"},
|
||||
{0, 0},
|
||||
};
|
||||
|
||||
const struct IdName kNtPeSectionNames[] = {
|
||||
{kNtPeSectionCntCode, "kNtPeSectionCntCode"},
|
||||
{kNtPeSectionCntInitializedData, "kNtPeSectionCntInitializedData"},
|
||||
{kNtPeSectionCntUninitializedData, "kNtPeSectionCntUninitializedData"},
|
||||
{kNtPeSectionGprel, "kNtPeSectionGprel"},
|
||||
{kNtPeSectionMemDiscardable, "kNtPeSectionMemDiscardable"},
|
||||
{kNtPeSectionMemNotCached, "kNtPeSectionMemNotCached"},
|
||||
{kNtPeSectionMemNotPaged, "kNtPeSectionMemNotPaged"},
|
||||
{kNtPeSectionMemShared, "kNtPeSectionMemShared"},
|
||||
{kNtPeSectionMemExecute, "kNtPeSectionMemExecute"},
|
||||
{kNtPeSectionMemRead, "kNtPeSectionMemRead"},
|
||||
{kNtPeSectionMemWrite, "kNtPeSectionMemWrite"},
|
||||
{0, 0},
|
||||
};
|
18
tool/decode/lib/peidnames.h
Normal file
18
tool/decode/lib/peidnames.h
Normal file
|
@ -0,0 +1,18 @@
|
|||
#ifndef COSMOPOLITAN_TOOL_DECODE_LIB_PEIDNAMES_H_
|
||||
#define COSMOPOLITAN_TOOL_DECODE_LIB_PEIDNAMES_H_
|
||||
#include "tool/decode/lib/idname.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
extern const struct IdName kNtImageFileMachineNames[];
|
||||
extern const struct IdName kNtPeOptionalHeaderMagicNames[];
|
||||
extern const struct IdName kNtImageCharacteristicNames[];
|
||||
extern const struct IdName kNtImageDllcharacteristicNames[];
|
||||
extern const struct IdName kNtImageSubsystemNames[];
|
||||
extern const struct IdName kNtImageScnNames[];
|
||||
extern const struct IdName kNtImageDirectoryEntryNames[];
|
||||
extern const struct IdName kNtPeSectionNames[];
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_TOOL_DECODE_LIB_PEIDNAMES_H_ */
|
73
tool/decode/lib/pollnames.S
Normal file
73
tool/decode/lib/pollnames.S
Normal file
|
@ -0,0 +1,73 @@
|
|||
/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "ape/relocations.h"
|
||||
#include "ape/relocations.h"
|
||||
#include "libc/macros.h"
|
||||
|
||||
.Lrows = 0 # w/ 2 cols
|
||||
|
||||
.macro .tab sym:req str
|
||||
.pushsection .rodata.str1.1,"aSM",@progbits,1
|
||||
.L\@: .asciz "\str"
|
||||
.popsection
|
||||
.long RVA(\sym)
|
||||
.long RVA(.L\@)
|
||||
.Lrows = .Lrows + 1
|
||||
.endm
|
||||
|
||||
.initro 301,_init_kPollNames
|
||||
kPollNamesRo:
|
||||
.tab POLLNVAL "POLLNVAL"
|
||||
.tab POLLWRNORM "POLLWRNORM"
|
||||
.tab POLLWRBAND "POLLWRBAND"
|
||||
.tab POLLRDNORM "POLLRDNORM"
|
||||
.tab POLLRDHUP "POLLRDHUP"
|
||||
.tab POLLRDBAND "POLLRDBAND"
|
||||
.tab POLLHUP "POLLHUP"
|
||||
.tab POLLERR "POLLERR"
|
||||
.tab POLLPRI "POLLPRI"
|
||||
.tab POLLOUT "POLLOUT"
|
||||
.tab POLLIN "POLLIN"
|
||||
.endobj kPollNamesRo,globl,hidden
|
||||
.previous
|
||||
|
||||
/ Mapping of poll() flags to their string names.
|
||||
/ @see recreateflags()
|
||||
.initbss 301,_init_kPollNames
|
||||
kPollNames:
|
||||
.rept .Lrows
|
||||
.quad 0 # unsigned long id
|
||||
.quad 0 # const char *const name
|
||||
.endr
|
||||
.quad 0,0 # terminator row
|
||||
.endobj kPollNames,globl
|
||||
.previous
|
||||
|
||||
.init.start 301,_init_kPollNames
|
||||
pushpop .Lrows,%rcx # relocate RO→BSS b/c -fPIE crap
|
||||
0: lodsl
|
||||
mov (%rbx,%rax),%rax # read what systemfive.S decoded
|
||||
stosq
|
||||
lodsl
|
||||
add %rbx,%rax # %rbx is image base (cosmo abi)
|
||||
stosq
|
||||
loop 0b
|
||||
add $16,%rdi
|
||||
.init.end 301,_init_kPollNames
|
11
tool/decode/lib/pollnames.h
Normal file
11
tool/decode/lib/pollnames.h
Normal file
|
@ -0,0 +1,11 @@
|
|||
#ifndef COSMOPOLITAN_TOOL_DECODE_LIB_POLLNAMES_H_
|
||||
#define COSMOPOLITAN_TOOL_DECODE_LIB_POLLNAMES_H_
|
||||
#include "tool/decode/lib/idname.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
extern struct IdName kPollNames[];
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_TOOL_DECODE_LIB_POLLNAMES_H_ */
|
55
tool/decode/lib/socknames.c
Normal file
55
tool/decode/lib/socknames.c
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/dns/dns.h"
|
||||
#include "libc/sock/sock.h"
|
||||
#include "libc/sysv/consts/af.h"
|
||||
#include "libc/sysv/consts/ai.h"
|
||||
#include "libc/sysv/consts/ipproto.h"
|
||||
#include "libc/sysv/consts/sock.h"
|
||||
#include "tool/decode/lib/socknames.h"
|
||||
|
||||
const struct IdName kAddressFamilyNames[] = {
|
||||
{AF_UNSPEC, "AF_UNSPEC"},
|
||||
{AF_UNIX, "AF_UNIX"},
|
||||
{AF_INET, "AF_INET"},
|
||||
{0, 0},
|
||||
};
|
||||
|
||||
const struct IdName kSockTypeNames[] = {
|
||||
{SOCK_STREAM, "SOCK_STREAM"},
|
||||
{SOCK_DGRAM, "SOCK_DGRAM"},
|
||||
{SOCK_RAW, "SOCK_RAW"},
|
||||
{SOCK_RDM, "SOCK_RDM"},
|
||||
{SOCK_SEQPACKET, "SOCK_SEQPACKET"},
|
||||
{0, 0},
|
||||
};
|
||||
|
||||
const struct IdName kAddrInfoFlagNames[] = {
|
||||
{AI_PASSIVE, "AI_PASSIVE"},
|
||||
{AI_CANONNAME, "AI_CANONNAME"},
|
||||
{AI_NUMERICHOST, "AI_NUMERICHOST"},
|
||||
{0, 0},
|
||||
};
|
||||
|
||||
const struct IdName kProtocolNames[] = {
|
||||
{IPPROTO_IP, "IPPROTO_IP"}, {IPPROTO_ICMP, "IPPROTO_ICMP"},
|
||||
{IPPROTO_TCP, "IPPROTO_TCP"}, {IPPROTO_UDP, "IPPROTO_UDP"},
|
||||
{IPPROTO_RAW, "IPPROTO_RAW"}, {0, 0},
|
||||
};
|
14
tool/decode/lib/socknames.h
Normal file
14
tool/decode/lib/socknames.h
Normal file
|
@ -0,0 +1,14 @@
|
|||
#ifndef COSMOPOLITAN_TOOL_DECODE_LIB_SOCKNAMES_H_
|
||||
#define COSMOPOLITAN_TOOL_DECODE_LIB_SOCKNAMES_H_
|
||||
#include "tool/decode/lib/idname.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
extern const struct IdName kAddressFamilyNames[];
|
||||
extern const struct IdName kSockTypeNames[];
|
||||
extern const struct IdName kAddrInfoFlagNames[];
|
||||
extern const struct IdName kProtocolNames[];
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_TOOL_DECODE_LIB_SOCKNAMES_H_ */
|
60
tool/decode/lib/titlegen.c
Normal file
60
tool/decode/lib/titlegen.c
Normal file
|
@ -0,0 +1,60 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/fmt/fmt.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "tool/decode/lib/titlegen.h"
|
||||
|
||||
const struct Modeline kModelineAsm = {
|
||||
" mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 ",
|
||||
" set et ft=asm ts=8 sw=8 fenc=utf-8 "};
|
||||
|
||||
/**
|
||||
* Displays one of those ANSI block source dividers we love so much.
|
||||
*/
|
||||
void showtitle(const char *brand, const char *tool, const char *title,
|
||||
const char *description, const struct Modeline *modeline) {
|
||||
char buf[512], *p;
|
||||
p = stpcpy(buf, brand);
|
||||
if (tool) {
|
||||
p = stpcpy(stpcpy(p, " § "), tool);
|
||||
if (title) {
|
||||
p = stpcpy(stpcpy(p, " » "), title);
|
||||
}
|
||||
}
|
||||
printf("/*");
|
||||
if (modeline) {
|
||||
printf("-*-%-71s-*-│\n│vi:%-72s:vi│\n╞", modeline->emacs, modeline->vim);
|
||||
for (unsigned i = 0; i < 78; ++i) printf("═");
|
||||
printf("╡\n│ %-76s ", buf);
|
||||
} else {
|
||||
for (unsigned i = 0; i < 75; ++i) printf("─");
|
||||
printf("│─╗\n│ %-73s ─╬─", buf);
|
||||
}
|
||||
printf("│\n╚─");
|
||||
for (unsigned i = 0; i < 75; ++i) printf("─");
|
||||
printf("%s", modeline ? "─" : "│");
|
||||
if (description) {
|
||||
/* TODO(jart): paragraph fill */
|
||||
printf("─╝\n%s ", description);
|
||||
} else {
|
||||
}
|
||||
printf("*/\n");
|
||||
}
|
18
tool/decode/lib/titlegen.h
Normal file
18
tool/decode/lib/titlegen.h
Normal file
|
@ -0,0 +1,18 @@
|
|||
#ifndef COSMOPOLITAN_TOOL_DECODE_LIB_TITLEGEN_H_
|
||||
#define COSMOPOLITAN_TOOL_DECODE_LIB_TITLEGEN_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
struct Modeline {
|
||||
const char *emacs;
|
||||
const char *vim;
|
||||
};
|
||||
|
||||
extern const struct Modeline kModelineAsm;
|
||||
|
||||
void showtitle(const char *brand, const char *tool, const char *title,
|
||||
const char *description, const struct Modeline *modeline);
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_TOOL_DECODE_LIB_TITLEGEN_H_ */
|
29
tool/decode/lib/x86gradenames.c
Normal file
29
tool/decode/lib/x86gradenames.c
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/nexgen32e/x86info.h"
|
||||
#include "tool/decode/lib/x86idnames.h"
|
||||
|
||||
const struct IdName kX86GradeNames[] = {
|
||||
{X86_GRADE_UNKNOWN, "Unknown"}, {X86_GRADE_APPLIANCE, "Appliance"},
|
||||
{X86_GRADE_MOBILE, "Mobile"}, {X86_GRADE_TABLET, "Tablet"},
|
||||
{X86_GRADE_DESKTOP, "Desktop"}, {X86_GRADE_CLIENT, "Client"},
|
||||
{X86_GRADE_DENSITY, "Density"}, {X86_GRADE_SERVER, "Server"},
|
||||
{X86_GRADE_SCIENCE, "Science"}, {0, 0},
|
||||
};
|
12
tool/decode/lib/x86idnames.h
Normal file
12
tool/decode/lib/x86idnames.h
Normal file
|
@ -0,0 +1,12 @@
|
|||
#ifndef COSMOPOLITAN_TOOL_DECODE_LIB_X86IDNAMES_H_
|
||||
#define COSMOPOLITAN_TOOL_DECODE_LIB_X86IDNAMES_H_
|
||||
#include "tool/decode/lib/idname.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
extern const struct IdName kX86MarchNames[];
|
||||
extern const struct IdName kX86GradeNames[];
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_TOOL_DECODE_LIB_X86IDNAMES_H_ */
|
47
tool/decode/lib/x86marchnames.c
Normal file
47
tool/decode/lib/x86marchnames.c
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/nexgen32e/x86info.h"
|
||||
#include "tool/decode/lib/x86idnames.h"
|
||||
|
||||
const struct IdName kX86MarchNames[] = {
|
||||
{X86_MARCH_UNKNOWN, "Unknown"},
|
||||
{X86_MARCH_CORE2, "Core 2"},
|
||||
{X86_MARCH_NEHALEM, "Nehalem"},
|
||||
{X86_MARCH_WESTMERE, "Westmere"},
|
||||
{X86_MARCH_SANDYBRIDGE, "Sandybridge"},
|
||||
{X86_MARCH_IVYBRIDGE, "Ivybridge"},
|
||||
{X86_MARCH_HASWELL, "Haswell"},
|
||||
{X86_MARCH_BROADWELL, "Broadwell"},
|
||||
{X86_MARCH_SKYLAKE, "Skylake"},
|
||||
{X86_MARCH_KABYLAKE, "Kabylake"},
|
||||
{X86_MARCH_CANNONLAKE, "Cannonlake"},
|
||||
{X86_MARCH_ICELAKE, "Icelake"},
|
||||
{X86_MARCH_TIGERLAKE, "Tigerlake"},
|
||||
{X86_MARCH_BONNELL, "Bonnell"},
|
||||
{X86_MARCH_SALTWELL, "Saltwell"},
|
||||
{X86_MARCH_SILVERMONT, "Silvermont"},
|
||||
{X86_MARCH_AIRMONT, "Airmont"},
|
||||
{X86_MARCH_GOLDMONT, "Goldmont"},
|
||||
{X86_MARCH_GOLDMONTPLUS, "Goldmont Plus"},
|
||||
{X86_MARCH_TREMONT, "Tremont"},
|
||||
{X86_MARCH_KNIGHTSLANDING, "Knights Landing"},
|
||||
{X86_MARCH_KNIGHTSMILL, "Knights Mill"},
|
||||
{0, 0},
|
||||
};
|
47
tool/decode/lib/xederrors.c
Normal file
47
tool/decode/lib/xederrors.c
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "third_party/xed/x86.h"
|
||||
#include "tool/decode/lib/idname.h"
|
||||
|
||||
const struct IdName kXedErrorNames[] = {
|
||||
{XED_ERROR_NONE, "NONE"},
|
||||
{XED_ERROR_BUFFER_TOO_SHORT, "BUFFER_TOO_SHORT"},
|
||||
{XED_ERROR_GENERAL_ERROR, "GENERAL_ERROR"},
|
||||
{XED_ERROR_INVALID_FOR_CHIP, "INVALID_FOR_CHIP"},
|
||||
{XED_ERROR_BAD_REGISTER, "BAD_REGISTER"},
|
||||
{XED_ERROR_BAD_LOCK_PREFIX, "BAD_LOCK_PREFIX"},
|
||||
{XED_ERROR_BAD_REP_PREFIX, "BAD_REP_PREFIX"},
|
||||
{XED_ERROR_BAD_LEGACY_PREFIX, "BAD_LEGACY_PREFIX"},
|
||||
{XED_ERROR_BAD_REX_PREFIX, "BAD_REX_PREFIX"},
|
||||
{XED_ERROR_BAD_EVEX_UBIT, "BAD_EVEX_UBIT"},
|
||||
{XED_ERROR_BAD_MAP, "BAD_MAP"},
|
||||
{XED_ERROR_BAD_EVEX_V_PRIME, "BAD_EVEX_V_PRIME"},
|
||||
{XED_ERROR_BAD_EVEX_Z_NO_MASKING, "BAD_EVEX_Z_NO_MASKING"},
|
||||
{XED_ERROR_NO_OUTPUT_POINTER, "NO_OUTPUT_POINTER"},
|
||||
{XED_ERROR_NO_AGEN_CALL_BACK_REGISTERED, "NO_AGEN_CALL_BACK_REGISTERED"},
|
||||
{XED_ERROR_BAD_MEMOP_INDEX, "BAD_MEMOP_INDEX"},
|
||||
{XED_ERROR_CALLBACK_PROBLEM, "CALLBACK_PROBLEM"},
|
||||
{XED_ERROR_GATHER_REGS, "GATHER_REGS"},
|
||||
{XED_ERROR_INSTR_TOO_LONG, "INSTR_TOO_LONG"},
|
||||
{XED_ERROR_INVALID_MODE, "INVALID_MODE"},
|
||||
{XED_ERROR_BAD_EVEX_LL, "BAD_EVEX_LL"},
|
||||
{XED_ERROR_UNIMPLEMENTED, "UNIMPLEMENTED"},
|
||||
{0, 0},
|
||||
};
|
11
tool/decode/lib/xederrors.h
Normal file
11
tool/decode/lib/xederrors.h
Normal file
|
@ -0,0 +1,11 @@
|
|||
#ifndef COSMOPOLITAN_TOOL_DECODE_LIB_XEDERRORS_H_
|
||||
#define COSMOPOLITAN_TOOL_DECODE_LIB_XEDERRORS_H_
|
||||
#include "tool/decode/lib/idname.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
extern const struct IdName kXedErrorNames[];
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_TOOL_DECODE_LIB_XEDERRORS_H_ */
|
71
tool/decode/lib/zipnames.c
Normal file
71
tool/decode/lib/zipnames.c
Normal file
|
@ -0,0 +1,71 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/nt/enum/fileflagandattributes.h"
|
||||
#include "libc/zip.h"
|
||||
#include "tool/decode/lib/zipnames.h"
|
||||
|
||||
const struct IdName kZipCompressionNames[] = {
|
||||
{kZipCompressionNone, "kZipCompressionNone"},
|
||||
{kZipCompressionDeflate, "kZipCompressionDeflate"},
|
||||
{0, 0},
|
||||
};
|
||||
|
||||
const struct IdName kZipExtraNames[] = {
|
||||
{kZipExtraZip64, "kZipExtraZip64"},
|
||||
{kZipExtraNtfs, "kZipExtraNtfs"},
|
||||
{0, 0},
|
||||
};
|
||||
|
||||
const struct IdName kZipIattrNames[] = {
|
||||
{kZipIattrBinary, "kZipIattrBinary"},
|
||||
{kZipIattrAscii, "kZipIattrAscii"},
|
||||
{0, 0},
|
||||
};
|
||||
|
||||
const struct IdName kZipOsNames[] = {
|
||||
{kZipOsDos, "kZipOsDos"},
|
||||
{kZipOsAmiga, "kZipOsAmiga"},
|
||||
{kZipOsOpenvms, "kZipOsOpenvms"},
|
||||
{kZipOsUnix, "kZipOsUnix"},
|
||||
{kZipOsVmcms, "kZipOsVmcms"},
|
||||
{kZipOsAtarist, "kZipOsAtarist"},
|
||||
{kZipOsOs2hpfs, "kZipOsOs2hpfs"},
|
||||
{kZipOsMacintosh, "kZipOsMacintosh"},
|
||||
{kZipOsZsystem, "kZipOsZsystem"},
|
||||
{kZipOsCpm, "kZipOsCpm"},
|
||||
{kZipOsWindowsntfs, "kZipOsWindowsntfs"},
|
||||
{kZipOsMvsos390zos, "kZipOsMvsos390zos"},
|
||||
{kZipOsVse, "kZipOsVse"},
|
||||
{kZipOsAcornrisc, "kZipOsAcornrisc"},
|
||||
{kZipOsVfat, "kZipOsVfat"},
|
||||
{kZipOsAltmvs, "kZipOsAltmvs"},
|
||||
{kZipOsBeos, "kZipOsBeos"},
|
||||
{kZipOsTandem, "kZipOsTandem"},
|
||||
{kZipOsOs400, "kZipOsOs400"},
|
||||
{kZipOsOsxdarwin, "kZipOsOsxdarwin"},
|
||||
{0, 0},
|
||||
};
|
||||
|
||||
const struct IdName kZipEraNames[] = {
|
||||
{kZipEra1989, "kZipEra1989"},
|
||||
{kZipEra1993, "kZipEra1993"},
|
||||
{kZipEra2001, "kZipEra2001"},
|
||||
{0, 0},
|
||||
};
|
15
tool/decode/lib/zipnames.h
Normal file
15
tool/decode/lib/zipnames.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
#ifndef COSMOPOLITAN_TOOL_DECODE_LIB_ZIPNAMES_H_
|
||||
#define COSMOPOLITAN_TOOL_DECODE_LIB_ZIPNAMES_H_
|
||||
#include "tool/decode/lib/idname.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
extern const struct IdName kZipCompressionNames[];
|
||||
extern const struct IdName kZipExtraNames[];
|
||||
extern const struct IdName kZipIattrNames[];
|
||||
extern const struct IdName kZipOsNames[];
|
||||
extern const struct IdName kZipEraNames[];
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_TOOL_DECODE_LIB_ZIPNAMES_H_ */
|
263
tool/decode/macho.c
Normal file
263
tool/decode/macho.c
Normal file
|
@ -0,0 +1,263 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/bits/safemacros.h"
|
||||
#include "libc/conv/conv.h"
|
||||
#include "libc/macho.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/calls/struct/stat.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/sysv/consts/map.h"
|
||||
#include "libc/sysv/consts/o.h"
|
||||
#include "libc/sysv/consts/prot.h"
|
||||
#include "tool/decode/lib/asmcodegen.h"
|
||||
#include "tool/decode/lib/flagger.h"
|
||||
#include "tool/decode/lib/machoidnames.h"
|
||||
#include "tool/decode/lib/titlegen.h"
|
||||
|
||||
/**
|
||||
* @fileoverview Apple Mach-O metadata disassembler.
|
||||
*/
|
||||
|
||||
static const char *path;
|
||||
static struct MachoHeader *macho;
|
||||
static size_t machosize;
|
||||
|
||||
static void startfile(void) {
|
||||
showtitle("αcτµαlly pδrταblε εxεcµταblε", "tool/decode/macho", NULL, NULL,
|
||||
&kModelineAsm);
|
||||
printf("#include \"libc/macho.h\"\n\n", path);
|
||||
}
|
||||
|
||||
static void showmachoheader(void) {
|
||||
#if !defined(TRUSTWORTHY) && !defined(MACHO_TRUSTWORTHY)
|
||||
if (sizeof(struct MachoHeader) > machosize) {
|
||||
fprintf(stderr, "error: %'s: MachoHeader overruns eof\n", path);
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
showtitle(basename(path), "macho", "header", NULL, NULL);
|
||||
printf("\n");
|
||||
showinthex(macho->magic);
|
||||
showinthex(macho->arch);
|
||||
showinthex(macho->arch2);
|
||||
show(".long",
|
||||
firstnonnull(findnamebyid(kMachoFileTypeNames, macho->filetype),
|
||||
format(b1, "%#x", macho->filetype)),
|
||||
"macho->filetype");
|
||||
showinthex(macho->loadcount);
|
||||
showinthex(macho->loadsize);
|
||||
show(".long",
|
||||
firstnonnull(recreateflags(kMachoFlagNames, macho->flags),
|
||||
format(b1, "%#x", macho->flags)),
|
||||
"macho->flags");
|
||||
showinthex(macho->__reserved);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static void showmachosection(struct MachoSection *section) {
|
||||
show(".ascin", format(b1, "%`'s,16", section->name), "section->name");
|
||||
show(".ascin", format(b1, "%`'s,16", section->commandname),
|
||||
"section->commandname");
|
||||
showint64hex(section->vaddr);
|
||||
showint64hex(section->memsz);
|
||||
showinthex(section->offset);
|
||||
showinthex(section->alignlog2);
|
||||
showinthex(section->relotaboff);
|
||||
showinthex(section->relocount);
|
||||
showinthex(section->attr);
|
||||
show(".long",
|
||||
format(b1, "%d,%d,%d", section->__reserved[0], section->__reserved[1],
|
||||
section->__reserved[2]),
|
||||
"section->__reserved");
|
||||
}
|
||||
|
||||
static void showmacholoadsegment(unsigned i, struct MachoLoadSegment *loadseg) {
|
||||
assert(loadseg->size ==
|
||||
sizeof(struct MachoLoadSegment) +
|
||||
loadseg->sectioncount * sizeof(struct MachoSection));
|
||||
#if !defined(TRUSTWORTHY) && !defined(MACHO_TRUSTWORTHY)
|
||||
if ((intptr_t)loadseg + sizeof(struct MachoLoadSegment) +
|
||||
loadseg->sectioncount * sizeof(struct MachoSection) >
|
||||
(intptr_t)macho + machosize) {
|
||||
abort();
|
||||
}
|
||||
#endif
|
||||
show(".ascin", format(b1, "%`'s,16", loadseg->name), "loadseg->name");
|
||||
showint64hex(loadseg->vaddr);
|
||||
showint64hex(loadseg->memsz);
|
||||
showint64hex(loadseg->offset);
|
||||
showint64hex(loadseg->filesz);
|
||||
show(".long",
|
||||
firstnonnull(recreateflags(kMachoVmProtNames, loadseg->maxprot),
|
||||
format(b1, "%#x", loadseg->maxprot)),
|
||||
"loadseg->maxprot");
|
||||
show(".long",
|
||||
firstnonnull(recreateflags(kMachoVmProtNames, loadseg->initprot),
|
||||
format(b1, "%#x", loadseg->initprot)),
|
||||
"loadseg->initprot");
|
||||
showinthex(loadseg->sectioncount);
|
||||
show(".long",
|
||||
firstnonnull(recreateflags(kMachoSegmentFlagNames, loadseg->flags),
|
||||
format(b1, "%#x", loadseg->flags)),
|
||||
"loadseg->flags");
|
||||
for (unsigned j = 0; j < loadseg->sectioncount; ++j) {
|
||||
printf("%d:", (i + 1) * 100 + (j + 1) * 10);
|
||||
showmachosection((struct MachoSection *)((intptr_t)loadseg +
|
||||
sizeof(struct MachoLoadSegment) +
|
||||
j * sizeof(struct MachoSection)));
|
||||
}
|
||||
}
|
||||
|
||||
static void showmacholoadsymtabshowall(struct MachoLoadSymtab *ls) {
|
||||
assert(ls->size == sizeof(struct MachoLoadSymtab));
|
||||
#if !defined(TRUSTWORTHY) && !defined(MACHO_TRUSTWORTHY)
|
||||
if ((intptr_t)ls + sizeof(struct MachoLoadSymtab) >
|
||||
(intptr_t)macho + machosize) {
|
||||
abort();
|
||||
}
|
||||
#endif
|
||||
showinthex(ls->offset);
|
||||
showinthex(ls->count);
|
||||
showinthex(ls->stroff);
|
||||
showinthex(ls->strsize);
|
||||
}
|
||||
|
||||
static void showmacholoaduuid(struct MachoLoadUuid *lu) {
|
||||
assert(lu->size == sizeof(struct MachoLoadUuid));
|
||||
#if !defined(TRUSTWORTHY) && !defined(MACHO_TRUSTWORTHY)
|
||||
if ((intptr_t)lu + sizeof(struct MachoLoadUuid) >
|
||||
(intptr_t)macho + machosize) {
|
||||
abort();
|
||||
}
|
||||
#endif
|
||||
printf("\t.byte\t");
|
||||
for (unsigned i = 0; i < 16; ++i) {
|
||||
if (i) {
|
||||
if (i == 8) {
|
||||
printf("\n\t.byte\t");
|
||||
} else {
|
||||
printf(",");
|
||||
}
|
||||
}
|
||||
printf("%#hhx", lu->uuid[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static void showmacholoadsourceversion(
|
||||
struct MachoLoadSourceVersionCommand *sv) {
|
||||
assert(sv->size == sizeof(struct MachoLoadSourceVersionCommand));
|
||||
#if !defined(TRUSTWORTHY) && !defined(MACHO_TRUSTWORTHY)
|
||||
if ((intptr_t)sv + sizeof(struct MachoLoadSourceVersionCommand) >
|
||||
(intptr_t)macho + machosize) {
|
||||
abort();
|
||||
}
|
||||
#endif
|
||||
showint64hex(sv->version);
|
||||
}
|
||||
|
||||
static void showmacholoadunixthread(struct MachoLoadThreadCommand *lc) {
|
||||
assert(lc->size == 4 + 4 + 4 + 4 + lc->count * 4);
|
||||
showinthex(lc->flavor);
|
||||
showint(lc->count);
|
||||
for (unsigned i = 0; i < lc->count; ++i) {
|
||||
showinthex(lc->wut[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void showmacholoadcommand(struct MachoLoadCommand *lc, unsigned i) {
|
||||
#if !defined(TRUSTWORTHY) && !defined(MACHO_TRUSTWORTHY)
|
||||
if ((intptr_t)lc > (intptr_t)macho + machosize ||
|
||||
(intptr_t)lc + lc->size > (intptr_t)macho + machosize) {
|
||||
abort();
|
||||
}
|
||||
#endif
|
||||
showorg((intptr_t)lc - (intptr_t)macho);
|
||||
printf("%d:", (i + 1) * 10);
|
||||
show(".long",
|
||||
firstnonnull(findnamebyid(kMachoLoadCommandNames, lc->command),
|
||||
format(b1, "%#x", lc->command)),
|
||||
"lc->command");
|
||||
showinthex(lc->size);
|
||||
switch (lc->command) {
|
||||
case MAC_LC_SEGMENT_64:
|
||||
showmacholoadsegment(i, (struct MachoLoadSegment *)lc);
|
||||
break;
|
||||
case MAC_LC_SYMTAB:
|
||||
showmacholoadsymtabshowall((struct MachoLoadSymtab *)lc);
|
||||
break;
|
||||
case MAC_LC_UUID:
|
||||
showmacholoaduuid((struct MachoLoadUuid *)lc);
|
||||
break;
|
||||
case MAC_LC_SOURCE_VERSION:
|
||||
showmacholoadsourceversion((struct MachoLoadSourceVersionCommand *)lc);
|
||||
break;
|
||||
case MAC_LC_UNIXTHREAD:
|
||||
showmacholoadunixthread((struct MachoLoadThreadCommand *)lc);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static void showmacholoadcommands(void) {
|
||||
#if !defined(TRUSTWORTHY) && !defined(MACHO_TRUSTWORTHY)
|
||||
if (sizeof(struct MachoHeader) + macho->loadsize > machosize) {
|
||||
fprintf(stderr, "error: %'s: macho->loadsize overruns eof\n", path);
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
unsigned i = 0;
|
||||
const unsigned count = macho->loadcount;
|
||||
for (struct MachoLoadCommand *lc =
|
||||
(void *)((intptr_t)macho + sizeof(struct MachoHeader));
|
||||
i < count; ++i, lc = (void *)((intptr_t)lc + lc->size)) {
|
||||
showmacholoadcommand(lc, i);
|
||||
}
|
||||
}
|
||||
|
||||
void showall(void) {
|
||||
startfile();
|
||||
showmachoheader();
|
||||
showmacholoadcommands();
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int64_t fd;
|
||||
struct stat st[1];
|
||||
if (argc != 2) fprintf(stderr, "usage: %s FILE\n", argv[0]), exit(1);
|
||||
if ((fd = open((path = argv[1]), O_RDONLY)) == -1 || fstat(fd, st) == -1 ||
|
||||
(macho = mmap(NULL, (machosize = st->st_size), PROT_READ, MAP_SHARED, fd,
|
||||
0)) == MAP_FAILED) {
|
||||
fprintf(stderr, "error: %'s %m\n", path);
|
||||
exit(1);
|
||||
}
|
||||
if (macho->magic != 0xFEEDFACF) {
|
||||
fprintf(stderr, "error: %'s not a macho x64 executable\n", path);
|
||||
exit(1);
|
||||
}
|
||||
showall();
|
||||
munmap(macho, machosize);
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
121
tool/decode/mkcombos.c
Normal file
121
tool/decode/mkcombos.c
Normal file
|
@ -0,0 +1,121 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/safemacros.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/conv/conv.h"
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/ex.h"
|
||||
#include "libc/sysv/consts/exit.h"
|
||||
#include "libc/sysv/consts/fileno.h"
|
||||
#include "third_party/getopt/getopt.h"
|
||||
#include "third_party/zlib/zlib.h"
|
||||
#include "tool/decode/lib/bitabuilder.h"
|
||||
|
||||
static size_t linecap;
|
||||
static FILE *fin, *fout;
|
||||
static uint32_t bit, maxbit;
|
||||
static struct BitaBuilder *bitset;
|
||||
static char *line, *tok, *s1, *category, *g_inpath, *g_outpath;
|
||||
|
||||
noreturn void ShowUsage(FILE *f, int rc) {
|
||||
fprintf(f, "Usage: %s [-o OUTPUT] [INPUT]\n", "Usage",
|
||||
program_invocation_name);
|
||||
exit(rc);
|
||||
}
|
||||
|
||||
void GetOpts(int argc, char *argv[]) {
|
||||
int opt;
|
||||
g_inpath = "/dev/stdin";
|
||||
g_outpath = "/dev/stdout";
|
||||
while ((opt = getopt(argc, argv, "?ho:")) != -1) {
|
||||
switch (opt) {
|
||||
case 'o':
|
||||
g_outpath = optarg;
|
||||
break;
|
||||
case 'h':
|
||||
case '?':
|
||||
ShowUsage(stdout, EXIT_SUCCESS);
|
||||
default:
|
||||
ShowUsage(stderr, EX_USAGE);
|
||||
}
|
||||
}
|
||||
if (argc - optind) {
|
||||
g_inpath = argv[optind];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds sparse unicode dataset for combining codepoints, e.g.
|
||||
*
|
||||
* UNDERLINING
|
||||
*
|
||||
* - COMBINING MACRON BELOW U+0331 (\xCC\xB1)
|
||||
* e.g. A̱ḆC̱Ḏ (too short) 41CCB1 42CCB1 43CCB1 44CCB1
|
||||
*
|
||||
* - COMBINING DOUBLE MACRON BELOW U+035F (\xCD\x9F)
|
||||
* e.g. A͟B͟C͟D͟ (too long) 41CD9F 42CD9F 43CD9F 44CD9F
|
||||
*
|
||||
* - DOUBLE PLUS COMBINING MACRON BELOW 3×U+035F + 1×U+0331
|
||||
* e.g. A͟B͟C͟Ḏ (just right) 41CCB1 42CCB1 43CCB1 44CD9F
|
||||
*
|
||||
* STRIKETHROUGH
|
||||
*
|
||||
* - COMBINING LONG STROKE OVERLAY U+0336 (\xCC\xB6)
|
||||
* e.g. A̶B̶C̶D̶ 41CCB6 42CCB6 43CCB6 44CCB6
|
||||
*
|
||||
* - COMBINING SHORT STROKE OVERLAY U+0335 (\xCC\xB5)
|
||||
* e.g. A̵B̵C̵D̵ 41CCB5 42CCB5 43CCB5 44CCB5
|
||||
*
|
||||
* - COMBINING SHORT SOLIDUS OVERLAY U+0337 (\xCC\xB7)
|
||||
* e.g. A̷B̷C̷D̷ 41CCB7 42CCB7 43CCB7 44CCB7
|
||||
*
|
||||
* - COMBINING LONG SOLIDUS OVERLAY U+0338 (\xCC\xB8)
|
||||
* e.g. A̸B̸C̸D̸ 41CCB8 42CCB8 43CCB8 44CCB8
|
||||
*
|
||||
* @see unicode.org/reports/tr11/#Definitions
|
||||
*/
|
||||
int main(int argc, char *argv[]) {
|
||||
GetOpts(argc, argv);
|
||||
CHECK_NOTNULL(fin = fopen(g_inpath, "r"));
|
||||
bitset = bitabuilder_new();
|
||||
while ((getline(&line, &linecap, fin)) != -1) {
|
||||
tok = line;
|
||||
s1 = strsep(&tok, ";");
|
||||
strsep(&tok, ";");
|
||||
category = strsep(&tok, ";");
|
||||
if (!s1 || !category) continue;
|
||||
bit = strtoimax(s1, NULL, 16);
|
||||
if (bit != 0x00AD &&
|
||||
((0x1160 <= bit && bit <= 0x11FF) ||
|
||||
(strcmp(category, "Me") == 0 || strcmp(category, "Mn") == 0 ||
|
||||
strcmp(category, "Cf") == 0 || strcmp(category, "Sk") == 0))) {
|
||||
maxbit = max(bit, maxbit);
|
||||
CHECK(bitabuilder_setbit(bitset, bit));
|
||||
}
|
||||
}
|
||||
CHECK_NOTNULL(fout = fopen(g_outpath, "wb"));
|
||||
CHECK(bitabuilder_fwrite(bitset, fout));
|
||||
bitabuilder_free(&bitset);
|
||||
return fclose(fin) | fclose(fout);
|
||||
}
|
104
tool/decode/mkwides.c
Normal file
104
tool/decode/mkwides.c
Normal file
|
@ -0,0 +1,104 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/safemacros.h"
|
||||
#include "libc/fmt/fmt.h"
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/ex.h"
|
||||
#include "libc/sysv/consts/exit.h"
|
||||
#include "third_party/getopt/getopt.h"
|
||||
#include "tool/decode/lib/bitabuilder.h"
|
||||
|
||||
static FILE *fin, *fout;
|
||||
static char width, *line;
|
||||
static size_t linecap, i, x, y;
|
||||
static struct BitaBuilder *bitset;
|
||||
static char *g_inpath, *g_outpath;
|
||||
|
||||
noreturn void ShowUsage(FILE *f, int rc) {
|
||||
fprintf(f, "Usage: %s [-o OUTPUT] [INPUT]\n", "Usage",
|
||||
program_invocation_name);
|
||||
exit(rc);
|
||||
}
|
||||
|
||||
void GetOpts(int argc, char *argv[]) {
|
||||
int opt;
|
||||
g_inpath = "/dev/stdin";
|
||||
g_outpath = "/dev/stdout";
|
||||
while ((opt = getopt(argc, argv, "?ho:")) != -1) {
|
||||
switch (opt) {
|
||||
case 'o':
|
||||
g_outpath = optarg;
|
||||
break;
|
||||
case 'h':
|
||||
case '?':
|
||||
ShowUsage(stdout, EXIT_SUCCESS);
|
||||
default:
|
||||
ShowUsage(stderr, EX_USAGE);
|
||||
}
|
||||
}
|
||||
if (argc - optind) {
|
||||
g_inpath = argv[optind];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts official UNICODE ‘monospace widths’ (yup) to a bitset.
|
||||
*
|
||||
* (╯°□°)╯︵ ̲┻̲━̲┻
|
||||
* 要依法治国是赞美那些谁是公义的和惩罚恶人。 - 韩非
|
||||
*
|
||||
* 172kB TXT → 32kB bits → 525 bytes lz4
|
||||
*
|
||||
* @note this tool may print binary to stdout
|
||||
* @see libc/kompressor/lz4decode.c
|
||||
* @see tool/viz/bing.c
|
||||
* @see tool/viz/fold.c
|
||||
* @see unicode.org/reports/tr11/#Definitions
|
||||
*/
|
||||
int main(int argc, char *argv[]) {
|
||||
GetOpts(argc, argv);
|
||||
bitset = bitabuilder_new();
|
||||
CHECK_NOTNULL(fin = fopen(g_inpath, "r"));
|
||||
while ((getline(&line, &linecap, fin)) != -1) {
|
||||
x = 0;
|
||||
y = 0;
|
||||
if (sscanf(line, "%x..%x;%c", &x, &y, &width) != 3) {
|
||||
if (sscanf(line, "%x;%c", &x, &width) == 2) {
|
||||
y = x;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
CHECK_LE(x, y);
|
||||
if (width == 'F' /* full-width */ || width == 'W' /* wide */) {
|
||||
for (i = x; i <= y; ++i) {
|
||||
CHECK(bitabuilder_setbit(bitset, i));
|
||||
}
|
||||
}
|
||||
}
|
||||
CHECK_NOTNULL(fout = fopen(g_outpath, "wb"));
|
||||
CHECK(bitabuilder_fwrite(bitset, fout));
|
||||
bitabuilder_free(&bitset);
|
||||
return fclose(fin) | fclose(fout);
|
||||
}
|
228
tool/decode/pe2.c
Normal file
228
tool/decode/pe2.c
Normal file
|
@ -0,0 +1,228 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/safemacros.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/struct/stat.h"
|
||||
#include "libc/conv/conv.h"
|
||||
#include "libc/nt/struct/imagentheaders.h"
|
||||
#include "libc/nt/struct/imageoptionalheader.h"
|
||||
#include "libc/pe.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/sysv/consts/map.h"
|
||||
#include "libc/sysv/consts/o.h"
|
||||
#include "libc/sysv/consts/prot.h"
|
||||
#include "third_party/xed/x86.h"
|
||||
#include "tool/decode/lib/asmcodegen.h"
|
||||
#include "tool/decode/lib/flagger.h"
|
||||
#include "tool/decode/lib/peidnames.h"
|
||||
#include "tool/decode/lib/titlegen.h"
|
||||
|
||||
/**
|
||||
* @fileoverview Portable executable metadata disassembler.
|
||||
* @see https://www.aldeid.com/wiki/PE-Portable-executable
|
||||
*/
|
||||
|
||||
static const char *path;
|
||||
static struct NtImageDosHeader *mz;
|
||||
static size_t mzsize;
|
||||
|
||||
static struct XedDecodedInst *ildreal(void *addr) {
|
||||
static struct XedDecodedInst xedd;
|
||||
if (xed_instruction_length_decode(
|
||||
xed_decoded_inst_zero_set_mode(&xedd, XED_MACHINE_MODE_REAL), addr,
|
||||
XED_MAX_INSTRUCTION_BYTES) != XED_ERROR_NONE ||
|
||||
!xedd.decoded_length) {
|
||||
xedd.decoded_length = 1;
|
||||
}
|
||||
return &xedd;
|
||||
}
|
||||
|
||||
static void startfile(void) {
|
||||
showtitle("αcτµαlly pδrταblε εxεcµταblε", "tool/decode/pe", NULL, NULL,
|
||||
&kModelineAsm);
|
||||
printf("#include \"libc/pe.h\"\n\n", path);
|
||||
}
|
||||
|
||||
static void showmzheader(void) {
|
||||
showtitle(basename(path), "dos", "mz header",
|
||||
"\tMZ = Mark 'Zibo' Joseph Zbikowski\n"
|
||||
"\te_cblp: bytes on last page\n"
|
||||
"\te_cp: 512-byte pages in file\n"
|
||||
"\te_crlc: reloc table entry count\n"
|
||||
"\te_cparhdr: data segment file offset / 16\n"
|
||||
"\te_{min,max}alloc: lowers upper bound load / 16\n"
|
||||
"\te_ss: lower bound on stack segment\n"
|
||||
"\te_sp: initialize stack pointer\n"
|
||||
"\te_csum: ∑bₙ checksum don't bother\n"
|
||||
"\te_ip: initial ip value\n"
|
||||
"\te_cs: increases cs load lower bound\n"
|
||||
"\te_lfarlc: reloc table offset\n"
|
||||
"\te_ovno: overlay number\n"
|
||||
"\te_lfanew: portable executable header rva",
|
||||
NULL);
|
||||
printf("\n");
|
||||
show(".ascii", format(b1, "%`'.*s", 2, (const char *)&mz->e_magic),
|
||||
"mz->e_magic");
|
||||
showshorthex(mz->e_cblp);
|
||||
showshorthex(mz->e_cp);
|
||||
showshorthex(mz->e_crlc);
|
||||
showshorthex(mz->e_cparhdr);
|
||||
showshorthex(mz->e_minalloc);
|
||||
showshorthex(mz->e_maxalloc);
|
||||
showshorthex(mz->e_ss);
|
||||
showshorthex(mz->e_sp);
|
||||
showshorthex(mz->e_csum);
|
||||
showshorthex(mz->e_ip);
|
||||
showshorthex(mz->e_cs);
|
||||
showshorthex(mz->e_lfarlc);
|
||||
showshorthex(mz->e_ovno);
|
||||
show(".short",
|
||||
format(b1, "%hn,%hn,%hn,%hn", mz->e_res[0], mz->e_res[1], mz->e_res[2],
|
||||
mz->e_res[3]),
|
||||
"mz->e_res");
|
||||
showshorthex(mz->e_oemid);
|
||||
showshorthex(mz->e_oeminfo);
|
||||
show(".short",
|
||||
format(b1, "%hn,%hn,%hn,%hn,%hn,%hn,%hn,%hn,%hn,%hn", mz->e_res2[0],
|
||||
mz->e_res2[1], mz->e_res2[2], mz->e_res2[3], mz->e_res2[4],
|
||||
mz->e_res2[5], mz->e_res2[6], mz->e_res2[7], mz->e_res2[8],
|
||||
mz->e_res2[9]),
|
||||
"mz->e_res2");
|
||||
showinthex(mz->e_lfanew);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static void showdosstub(void) {
|
||||
unsigned char *p = (unsigned char *)mz + sizeof(struct NtImageDosHeader);
|
||||
unsigned char *pe = (mz->e_lfanew ? p + mz->e_lfanew : p + mzsize);
|
||||
pe = min(pe, p + mzsize - XED_MAX_INSTRUCTION_BYTES);
|
||||
while (p < pe) {
|
||||
struct XedDecodedInst *inst = ildreal(p);
|
||||
if (p + inst->decoded_length > pe) break;
|
||||
printf("\t.byte\t");
|
||||
for (unsigned i = 0; i < inst->decoded_length; ++i) {
|
||||
if (i) printf(",");
|
||||
printf("%#hhx", xed_decoded_inst_get_byte(inst, i));
|
||||
}
|
||||
printf("\n");
|
||||
p += inst->decoded_length;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static void showpeoptionalheader(struct NtImageOptionalHeader *opt) {
|
||||
showtitle(basename(path), "windows", "pe \"optional\" header", NULL, NULL);
|
||||
printf("\n");
|
||||
show(".short",
|
||||
firstnonnull(findnamebyid(kNtPeOptionalHeaderMagicNames, opt->Magic),
|
||||
format(b1, "%#hx", opt->Magic)),
|
||||
"opt->Magic");
|
||||
showint(opt->MajorLinkerVersion);
|
||||
showint(opt->MinorLinkerVersion);
|
||||
showinthex(opt->SizeOfCode);
|
||||
showinthex(opt->SizeOfInitializedData);
|
||||
showinthex(opt->SizeOfUninitializedData);
|
||||
showinthex(opt->AddressOfEntryPoint);
|
||||
showinthex(opt->BaseOfCode);
|
||||
showint64hex(opt->ImageBase);
|
||||
showinthex(opt->SectionAlignment);
|
||||
showinthex(opt->FileAlignment);
|
||||
showshort(opt->MajorOperatingSystemVersion);
|
||||
showshort(opt->MinorOperatingSystemVersion);
|
||||
showshort(opt->MajorImageVersion);
|
||||
showshort(opt->MinorImageVersion);
|
||||
showshort(opt->MajorSubsystemVersion);
|
||||
showshort(opt->MinorSubsystemVersion);
|
||||
showint(opt->Win32VersionValue);
|
||||
showinthex(opt->SizeOfImage);
|
||||
showinthex(opt->SizeOfHeaders);
|
||||
showinthex(opt->CheckSum);
|
||||
show(".short",
|
||||
firstnonnull(findnamebyid(kNtImageSubsystemNames, opt->Subsystem),
|
||||
format(b1, "%#hx", opt->Subsystem)),
|
||||
"opt->Subsystem");
|
||||
show(".short",
|
||||
firstnonnull(recreateflags(kNtImageDllcharacteristicNames,
|
||||
opt->DllCharacteristics),
|
||||
format(b1, "%#hx", opt->DllCharacteristics)),
|
||||
"opt->DllCharacteristics");
|
||||
showint64hex(opt->SizeOfStackReserve);
|
||||
showint64hex(opt->SizeOfStackCommit);
|
||||
showint64hex(opt->SizeOfHeapReserve);
|
||||
showint64hex(opt->SizeOfHeapCommit);
|
||||
showinthex(opt->LoaderFlags);
|
||||
showinthex(opt->NumberOfRvaAndSizes);
|
||||
}
|
||||
|
||||
static void showpeheader(struct NtImageNtHeaders *pe) {
|
||||
showtitle(basename(path), "windows", "pe header", NULL, NULL);
|
||||
printf("\n");
|
||||
showorg(mz->e_lfanew);
|
||||
show(".ascii", format(b1, "%`'.*s", 4, (const char *)&pe->Signature),
|
||||
"pe->Signature");
|
||||
show(".short",
|
||||
firstnonnull(
|
||||
findnamebyid(kNtImageFileMachineNames, pe->FileHeader.Machine),
|
||||
format(b1, "%#hx", pe->FileHeader.Machine)),
|
||||
"pe->FileHeader.Machine");
|
||||
showshort(pe->FileHeader.NumberOfSections);
|
||||
showinthex(pe->FileHeader.TimeDateStamp);
|
||||
showinthex(pe->FileHeader.PointerToSymbolTable);
|
||||
showint(pe->FileHeader.NumberOfSymbols);
|
||||
showshort(pe->FileHeader.SizeOfOptionalHeader);
|
||||
show(".short",
|
||||
firstnonnull(recreateflags(kNtImageCharacteristicNames,
|
||||
pe->FileHeader.Characteristics),
|
||||
format(b1, "%#hx", pe->FileHeader.Characteristics)),
|
||||
"pe->FileHeader.Characteristics");
|
||||
printf("\n");
|
||||
showpeoptionalheader(pecheckaddress(mz, mzsize, &pe->OptionalHeader,
|
||||
pe->FileHeader.SizeOfOptionalHeader));
|
||||
}
|
||||
|
||||
static void showall(void) {
|
||||
startfile();
|
||||
showmzheader();
|
||||
showdosstub();
|
||||
if (mz->e_lfanew) {
|
||||
showpeheader(pecomputerva(mz, mzsize, mz->e_lfanew,
|
||||
sizeof(struct NtImageFileHeader)));
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int64_t fd;
|
||||
struct stat st[1];
|
||||
if (argc != 2) fprintf(stderr, "usage: %s FILE\n", argv[0]), exit(1);
|
||||
if ((fd = open((path = argv[1]), O_RDONLY)) == -1 || fstat(fd, st) == -1 ||
|
||||
(mz = mmap(NULL, (mzsize = st->st_size), PROT_READ, MAP_SHARED, fd, 0)) ==
|
||||
MAP_FAILED) {
|
||||
fprintf(stderr, "error: %'s %m\n", path);
|
||||
exit(1);
|
||||
}
|
||||
if (mz->e_magic != kNtImageDosSignature) {
|
||||
fprintf(stderr, "error: %'s not a dos executable\n", path);
|
||||
exit(1);
|
||||
}
|
||||
showall();
|
||||
munmap(mz, mzsize);
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
101
tool/decode/peboff.c
Normal file
101
tool/decode/peboff.c
Normal file
|
@ -0,0 +1,101 @@
|
|||
#include "libc/nt/struct/peb.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
|
||||
int main() {
|
||||
printf("InheritedAddressSpace = 0x%x\n",
|
||||
offsetof(struct NtPeb, InheritedAddressSpace));
|
||||
printf("ReadImageFileExecOptions = 0x%x\n",
|
||||
offsetof(struct NtPeb, ReadImageFileExecOptions));
|
||||
printf("BeingDebugged = 0x%x\n", offsetof(struct NtPeb, BeingDebugged));
|
||||
printf("Mutant = 0x%x\n", offsetof(struct NtPeb, Mutant));
|
||||
printf("ImageBaseAddress = 0x%x\n", offsetof(struct NtPeb, ImageBaseAddress));
|
||||
printf("Ldr = 0x%x\n", offsetof(struct NtPeb, Ldr));
|
||||
printf("ProcessParameters = 0x%x\n",
|
||||
offsetof(struct NtPeb, ProcessParameters));
|
||||
printf("SubSystemData = 0x%x\n", offsetof(struct NtPeb, SubSystemData));
|
||||
printf("ProcessHeap = 0x%x\n", offsetof(struct NtPeb, ProcessHeap));
|
||||
printf("FastPebLock = 0x%x\n", offsetof(struct NtPeb, FastPebLock));
|
||||
printf("KernelCallbackTable = 0x%x\n",
|
||||
offsetof(struct NtPeb, KernelCallbackTable));
|
||||
printf("UserSharedInfoPtr = 0x%x\n",
|
||||
offsetof(struct NtPeb, UserSharedInfoPtr));
|
||||
printf("SystemReserved = 0x%x\n", offsetof(struct NtPeb, SystemReserved));
|
||||
printf("__wut6 = 0x%x\n", offsetof(struct NtPeb, __wut6));
|
||||
printf("__wut7 = 0x%x\n", offsetof(struct NtPeb, __wut7));
|
||||
printf("TlsExpansionCounter = 0x%x\n",
|
||||
offsetof(struct NtPeb, TlsExpansionCounter));
|
||||
printf("TlsBitmap = 0x%x\n", offsetof(struct NtPeb, TlsBitmap));
|
||||
printf("TlsBitmapBits = 0x%x\n", offsetof(struct NtPeb, TlsBitmapBits));
|
||||
printf("ReadOnlySharedMemoryBase = 0x%x\n",
|
||||
offsetof(struct NtPeb, ReadOnlySharedMemoryBase));
|
||||
printf("ReadOnlyStaticServerData = 0x%x\n",
|
||||
offsetof(struct NtPeb, ReadOnlyStaticServerData));
|
||||
printf("AnsiCodePageData = 0x%x\n", offsetof(struct NtPeb, AnsiCodePageData));
|
||||
printf("OemCodePageData = 0x%x\n", offsetof(struct NtPeb, OemCodePageData));
|
||||
printf("UnicodeCaseTableData = 0x%x\n",
|
||||
offsetof(struct NtPeb, UnicodeCaseTableData));
|
||||
printf("NumberOfProcessors = 0x%x\n",
|
||||
offsetof(struct NtPeb, NumberOfProcessors));
|
||||
printf("NtGlobalFlag = 0x%x\n", offsetof(struct NtPeb, NtGlobalFlag));
|
||||
printf("CriticalSectionTimeout = 0x%x\n",
|
||||
offsetof(struct NtPeb, CriticalSectionTimeout));
|
||||
printf("HeapSegmentReserve = 0x%x\n",
|
||||
offsetof(struct NtPeb, HeapSegmentReserve));
|
||||
printf("HeapSegmentCommit = 0x%x\n",
|
||||
offsetof(struct NtPeb, HeapSegmentCommit));
|
||||
printf("HeapDeCommitTotalFreeThreshold = 0x%x\n",
|
||||
offsetof(struct NtPeb, HeapDeCommitTotalFreeThreshold));
|
||||
printf("HeapDeCommitFreeBlockThreshold = 0x%x\n",
|
||||
offsetof(struct NtPeb, HeapDeCommitFreeBlockThreshold));
|
||||
printf("NumberOfHeaps = 0x%x\n", offsetof(struct NtPeb, NumberOfHeaps));
|
||||
printf("MaximumNumberOfHeaps = 0x%x\n",
|
||||
offsetof(struct NtPeb, MaximumNumberOfHeaps));
|
||||
printf("ProcessHeaps = 0x%x\n", offsetof(struct NtPeb, ProcessHeaps));
|
||||
printf("GdiSharedHandleTable = 0x%x\n",
|
||||
offsetof(struct NtPeb, GdiSharedHandleTable));
|
||||
printf("ProcessStarterHelper = 0x%x\n",
|
||||
offsetof(struct NtPeb, ProcessStarterHelper));
|
||||
printf("GdiDCAttributeList = 0x%x\n",
|
||||
offsetof(struct NtPeb, GdiDCAttributeList));
|
||||
printf("LoaderLock = 0x%x\n", offsetof(struct NtPeb, LoaderLock));
|
||||
printf("OSMajorVersion = 0x%x\n", offsetof(struct NtPeb, OSMajorVersion));
|
||||
printf("OSMinorVersion = 0x%x\n", offsetof(struct NtPeb, OSMinorVersion));
|
||||
printf("OSVersion = 0x%x\n", offsetof(struct NtPeb, OSVersion));
|
||||
printf("OSBuildNumber = 0x%x\n", offsetof(struct NtPeb, OSBuildNumber));
|
||||
printf("OSCSDVersion = 0x%x\n", offsetof(struct NtPeb, OSCSDVersion));
|
||||
printf("OSPlatformId = 0x%x\n", offsetof(struct NtPeb, OSPlatformId));
|
||||
printf("ImageSubsystem = 0x%x\n", offsetof(struct NtPeb, ImageSubsystem));
|
||||
printf("ImageSubsystemMajorVersion = 0x%x\n",
|
||||
offsetof(struct NtPeb, ImageSubsystemMajorVersion));
|
||||
printf("ImageSubsystemMinorVersion = 0x%x\n",
|
||||
offsetof(struct NtPeb, ImageSubsystemMinorVersion));
|
||||
printf("ImageProcessAffinityMask = 0x%x\n",
|
||||
offsetof(struct NtPeb, ImageProcessAffinityMask));
|
||||
printf("ActiveProcessAffinityMask = 0x%x\n",
|
||||
offsetof(struct NtPeb, ActiveProcessAffinityMask));
|
||||
printf("GdiHandleBuffer = 0x%x\n", offsetof(struct NtPeb, GdiHandleBuffer));
|
||||
printf("PostProcessInitRoutine = 0x%x\n",
|
||||
offsetof(struct NtPeb, PostProcessInitRoutine));
|
||||
printf("TlsExpansionBitmap = 0x%x\n",
|
||||
offsetof(struct NtPeb, TlsExpansionBitmap));
|
||||
printf("TlsExpansionBitmapBits = 0x%x\n",
|
||||
offsetof(struct NtPeb, TlsExpansionBitmapBits));
|
||||
printf("SessionId = 0x%x\n", offsetof(struct NtPeb, SessionId));
|
||||
printf("AppCompatFlags = 0x%x\n", offsetof(struct NtPeb, AppCompatFlags));
|
||||
printf("AppCompatFlagsUser = 0x%x\n",
|
||||
offsetof(struct NtPeb, AppCompatFlagsUser));
|
||||
printf("pShimData = 0x%x\n", offsetof(struct NtPeb, pShimData));
|
||||
printf("AppCompatInfo = 0x%x\n", offsetof(struct NtPeb, AppCompatInfo));
|
||||
printf("CSDVersion = 0x%x\n", offsetof(struct NtPeb, CSDVersion));
|
||||
printf("ActivationContextData = 0x%x\n",
|
||||
offsetof(struct NtPeb, ActivationContextData));
|
||||
printf("ProcessAssemblyStorageMap = 0x%x\n",
|
||||
offsetof(struct NtPeb, ProcessAssemblyStorageMap));
|
||||
printf("SystemDefaultActivationContextData = 0x%x\n",
|
||||
offsetof(struct NtPeb, SystemDefaultActivationContextData));
|
||||
printf("SystemAssemblyStorageMap = 0x%x\n",
|
||||
offsetof(struct NtPeb, SystemAssemblyStorageMap));
|
||||
printf("MinimumStackCommit = 0x%x\n",
|
||||
offsetof(struct NtPeb, MinimumStackCommit));
|
||||
return 0;
|
||||
}
|
28
tool/decode/unhex.c
Normal file
28
tool/decode/unhex.c
Normal file
|
@ -0,0 +1,28 @@
|
|||
/*─────────────────────────────────────────────────────────────────╗
|
||||
│ To the extent possible under law, Justine Tunney has waived │
|
||||
│ all copyright and related or neighboring rights to this file, │
|
||||
│ as it is written in the following disclaimers: │
|
||||
│ • http://unlicense.org/ │
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
/**
|
||||
* @fileoverview Hex to binary converter program.
|
||||
* Non-hex bytes are ignored. If you've got imposter syndrome you could
|
||||
* call this a compiler and start coding in hex.
|
||||
*/
|
||||
|
||||
int main() {
|
||||
int o, t = -1;
|
||||
while (0 <= (o = getchar()) && o <= 255) {
|
||||
if (!isxdigit(o)) continue;
|
||||
int h = hextoint(o);
|
||||
if (t != -1) putchar(t * 16 + h), h = -1;
|
||||
t = h;
|
||||
}
|
||||
if (ferror(stdout)) return 1;
|
||||
if (t != -1) return 2;
|
||||
return 0;
|
||||
}
|
209
tool/decode/x86opinfo.c
Normal file
209
tool/decode/x86opinfo.c
Normal file
|
@ -0,0 +1,209 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/bits.h"
|
||||
#include "libc/macros.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/ex.h"
|
||||
#include "libc/sysv/consts/exit.h"
|
||||
#include "third_party/getopt/getopt.h"
|
||||
#include "third_party/xed/x86.h"
|
||||
#include "tool/decode/lib/idname.h"
|
||||
#include "tool/decode/lib/xederrors.h"
|
||||
|
||||
const struct IdName kXedModeNames[] = {
|
||||
{XED_MACHINE_MODE_LONG_64, "long"},
|
||||
{XED_MACHINE_MODE_LONG_COMPAT_32, "long32"},
|
||||
{XED_MACHINE_MODE_LONG_COMPAT_16, "long16"},
|
||||
{XED_MACHINE_MODE_LEGACY_32, "legacy"},
|
||||
{XED_MACHINE_MODE_LEGACY_16, "legacy16"},
|
||||
{XED_MACHINE_MODE_REAL, "real"},
|
||||
{XED_MACHINE_MODE_UNREAL, "unreal"},
|
||||
};
|
||||
|
||||
enum XedMachineMode g_mode;
|
||||
struct XedDecodedInst g_xedd;
|
||||
|
||||
noreturn void ShowUsage(int rc, FILE *f) {
|
||||
size_t i;
|
||||
fputs("Usage: ", f);
|
||||
fputs(program_invocation_name, f);
|
||||
fputs(" [-r] [-m MODE] HEX\n MODE ∊ {", f);
|
||||
fputs(kXedModeNames[0].name, f);
|
||||
for (i = 1; i < ARRAYLEN(kXedModeNames); ++i) {
|
||||
fputc(',', f);
|
||||
fputs(kXedModeNames[i].name, f);
|
||||
}
|
||||
fputs("}\n", f);
|
||||
exit(rc);
|
||||
}
|
||||
|
||||
void SetMachineMode(const char *s) {
|
||||
size_t i;
|
||||
for (i = 0; i < ARRAYLEN(kXedModeNames); ++i) {
|
||||
if (strcasecmp(s, kXedModeNames[i].name) == 0) {
|
||||
g_mode = kXedModeNames[i].id;
|
||||
return;
|
||||
}
|
||||
}
|
||||
fputs("error: bad mode\n", stderr);
|
||||
ShowUsage(EXIT_FAILURE, stderr);
|
||||
}
|
||||
|
||||
void GetOpts(int argc, char *argv[]) {
|
||||
int opt;
|
||||
g_mode = XED_MACHINE_MODE_LONG_64;
|
||||
while ((opt = getopt(argc, argv, "?hrm:")) != -1) {
|
||||
switch (opt) {
|
||||
case 'r':
|
||||
g_mode = XED_MACHINE_MODE_REAL;
|
||||
break;
|
||||
case 'm':
|
||||
SetMachineMode(optarg);
|
||||
break;
|
||||
case '?':
|
||||
case 'h':
|
||||
ShowUsage(EXIT_SUCCESS, stdout);
|
||||
default:
|
||||
ShowUsage(EX_USAGE, stderr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CheckHex(const char *s) {
|
||||
size_t i, n;
|
||||
if ((n = strlen(s)) % 2 == 1) {
|
||||
ShowUsage(EX_DATAERR, stderr);
|
||||
}
|
||||
for (i = 0; i < n; ++i) {
|
||||
if (!isxdigit(s[i + 0])) {
|
||||
ShowUsage(EX_DATAERR, stderr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ShowField(const char *name, uint64_t value) {
|
||||
if (value) {
|
||||
printf("/\t%-20s = %#lx\n", name, value);
|
||||
}
|
||||
}
|
||||
|
||||
void ShowOffset(const char *name, uint64_t off) {
|
||||
printf("/\t%-20s = %#lx\n", name, off);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int err;
|
||||
size_t i, j, k;
|
||||
uint8_t buf[XED_MAX_INSTRUCTION_BYTES];
|
||||
|
||||
GetOpts(argc, argv);
|
||||
|
||||
for (k = 0, i = optind; i < argc; ++i) {
|
||||
CheckHex(argv[i]);
|
||||
for (j = 0; argv[i][j]; j += 2) {
|
||||
if (++k > XED_MAX_INSTRUCTION_BYTES) ShowUsage(EX_DATAERR, stderr);
|
||||
buf[k - 1] = hextoint(argv[i][j + 0]) << 4 | hextoint(argv[i][j + 1]);
|
||||
}
|
||||
}
|
||||
|
||||
xed_decoded_inst_zero_set_mode(&g_xedd, g_mode);
|
||||
if ((err = xed_instruction_length_decode(&g_xedd, buf, k)) !=
|
||||
XED_ERROR_NONE) {
|
||||
fputs("XED_ERROR_", stderr);
|
||||
fputs(findnamebyid(kXedErrorNames, err), stderr);
|
||||
fputc('\n', stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
#define SHOWOP(F) ShowField(#F, g_xedd.operands.F)
|
||||
SHOWOP(amd3dnow);
|
||||
SHOWOP(asz);
|
||||
SHOWOP(bcrc);
|
||||
SHOWOP(chip);
|
||||
SHOWOP(cldemote);
|
||||
SHOWOP(disp);
|
||||
SHOWOP(disp_width);
|
||||
SHOWOP(error);
|
||||
SHOWOP(esrc);
|
||||
SHOWOP(first_f2f3);
|
||||
SHOWOP(has_modrm);
|
||||
SHOWOP(has_sib);
|
||||
SHOWOP(hint);
|
||||
SHOWOP(ild_f2);
|
||||
SHOWOP(ild_f3);
|
||||
SHOWOP(ild_seg);
|
||||
SHOWOP(imm1_bytes);
|
||||
SHOWOP(imm_width);
|
||||
SHOWOP(last_f2f3);
|
||||
SHOWOP(llrc);
|
||||
SHOWOP(lock);
|
||||
SHOWOP(map);
|
||||
SHOWOP(mask);
|
||||
SHOWOP(max_bytes);
|
||||
SHOWOP(mod);
|
||||
SHOWOP(mode);
|
||||
SHOWOP(mode_first_prefix);
|
||||
SHOWOP(modep5);
|
||||
SHOWOP(modep55c);
|
||||
SHOWOP(modrm_byte);
|
||||
SHOWOP(nominal_opcode);
|
||||
SHOWOP(nprefixes);
|
||||
SHOWOP(nrexes);
|
||||
SHOWOP(nseg_prefixes);
|
||||
SHOWOP(osz);
|
||||
SHOWOP(out_of_bytes);
|
||||
SHOWOP(pos_disp);
|
||||
SHOWOP(pos_imm);
|
||||
SHOWOP(pos_imm1);
|
||||
SHOWOP(pos_modrm);
|
||||
SHOWOP(pos_nominal_opcode);
|
||||
SHOWOP(pos_sib);
|
||||
SHOWOP(prefix66);
|
||||
SHOWOP(realmode);
|
||||
SHOWOP(reg);
|
||||
SHOWOP(rep);
|
||||
SHOWOP(rex);
|
||||
SHOWOP(rexb);
|
||||
SHOWOP(rexr);
|
||||
SHOWOP(rexrr);
|
||||
SHOWOP(rexw);
|
||||
SHOWOP(rexx);
|
||||
SHOWOP(rm);
|
||||
SHOWOP(seg_ovd);
|
||||
SHOWOP(sibbase);
|
||||
SHOWOP(sibindex);
|
||||
SHOWOP(sibscale);
|
||||
SHOWOP(srm);
|
||||
SHOWOP(ubit);
|
||||
SHOWOP(uimm0);
|
||||
SHOWOP(uimm1);
|
||||
SHOWOP(vex_prefix);
|
||||
SHOWOP(vexdest210);
|
||||
SHOWOP(vexdest3);
|
||||
SHOWOP(vexdest4);
|
||||
SHOWOP(vexvalid);
|
||||
SHOWOP(vl);
|
||||
SHOWOP(wbnoinvd);
|
||||
SHOWOP(zeroing);
|
||||
|
||||
return 0;
|
||||
}
|
38
tool/decode/xor.c
Normal file
38
tool/decode/xor.c
Normal file
|
@ -0,0 +1,38 @@
|
|||
/*─────────────────────────────────────────────────────────────────╗
|
||||
│ To the extent possible under law, Justine Tunney has waived │
|
||||
│ all copyright and related or neighboring rights to this file, │
|
||||
│ as it is written in the following disclaimers: │
|
||||
│ • http://unlicense.org/ │
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/runtime/gc.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/x/x.h"
|
||||
|
||||
/**
|
||||
* @fileoverview Hex to binary converter program.
|
||||
* Non-hex bytes are ignored. If you've got imposter syndrome you could
|
||||
* call this a compiler and start coding in hex.
|
||||
*/
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
size_t i, j, l;
|
||||
uint8_t *buf;
|
||||
if (argc == 1) return 1;
|
||||
buf = gc(xmalloc((l = strlen(argv[1]) / 2)));
|
||||
for (j = 0; j < l; ++j) {
|
||||
buf[j] = 0;
|
||||
}
|
||||
for (i = 1; i < argc; ++i) {
|
||||
for (j = 0; j < l; ++j) {
|
||||
buf[j] ^= hextoint(argv[i][j + 0]) << 4 | hextoint(argv[i][j + 1]);
|
||||
}
|
||||
}
|
||||
for (j = 0; j < l; ++j) {
|
||||
putchar("0123456789abcdef"[(buf[j] >> 4) & 0xf]);
|
||||
putchar("0123456789abcdef"[(buf[j] >> 0) & 0xf]);
|
||||
}
|
||||
putchar('\n');
|
||||
return 0;
|
||||
}
|
324
tool/decode/zip.c
Normal file
324
tool/decode/zip.c
Normal file
|
@ -0,0 +1,324 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/bits.h"
|
||||
#include "libc/bits/safemacros.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/struct/stat.h"
|
||||
#include "libc/conv/conv.h"
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/nt/struct/filetime.h"
|
||||
#include "libc/runtime/gc.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/map.h"
|
||||
#include "libc/sysv/consts/o.h"
|
||||
#include "libc/sysv/consts/prot.h"
|
||||
#include "libc/x/x.h"
|
||||
#include "libc/zip.h"
|
||||
#include "tool/decode/lib/asmcodegen.h"
|
||||
#include "tool/decode/lib/disassemblehex.h"
|
||||
#include "tool/decode/lib/flagger.h"
|
||||
#include "tool/decode/lib/idname.h"
|
||||
#include "tool/decode/lib/ntfileflagnames.h"
|
||||
#include "tool/decode/lib/titlegen.h"
|
||||
#include "tool/decode/lib/zipnames.h"
|
||||
|
||||
/**
|
||||
* @fileoverview Zip File Disassembler.
|
||||
*/
|
||||
|
||||
nodiscard char *formatdosdate(uint16_t dosdate) {
|
||||
return xasprintf("%04u-%02u-%02u", ((dosdate >> 9) & 0b1111111) + 1980,
|
||||
(dosdate >> 5) & 0b1111, dosdate & 0b11111);
|
||||
}
|
||||
|
||||
nodiscard char *formatdostime(uint16_t dostime) {
|
||||
return xasprintf("%02u:%02u:%02u", (dostime >> 11) & 0b11111,
|
||||
(dostime >> 5) & 0b111111, (dostime << 1) & 0b111110);
|
||||
}
|
||||
|
||||
void advancepos(uint8_t *map, size_t *pos, size_t off) {
|
||||
CHECK_GE(off, *pos);
|
||||
if (off > *pos) {
|
||||
printf("\n/\t<%s>\n", "LIMBO");
|
||||
disassemblehex(&map[*pos], off - *pos, stdout);
|
||||
printf("/\t</%s>\n", "LIMBO");
|
||||
}
|
||||
*pos = off;
|
||||
}
|
||||
|
||||
void showgeneralflag(uint16_t generalflag) {
|
||||
puts("\
|
||||
/ ┌─utf8\n\
|
||||
/ │ ┌─strong encryption\n\
|
||||
/ │ │┌─compressed patch data\n\
|
||||
/ │ ││ ┌─crc and size go after file content\n\
|
||||
/ │ ││ │┌─{normal,max,fast,superfast}\n\
|
||||
/ │ ││ ││ ┌─encrypted\n\
|
||||
/ rrrr│uuuu││r│├┐│");
|
||||
show(".short", format(b1, "0b%016b", generalflag), "generalflag");
|
||||
}
|
||||
|
||||
void showtimestamp(uint16_t time, uint16_t date) {
|
||||
show(".short", format(b1, "%#04hx", time),
|
||||
gc(xasprintf("%s (%s)", "lastmodifiedtime", gc(formatdostime(time)))));
|
||||
show(".short", format(b1, "%#04hx", date),
|
||||
gc(xasprintf("%s (%s)", "lastmodifieddate", gc(formatdosdate(date)))));
|
||||
}
|
||||
|
||||
void showcompressmethod(uint16_t compressmethod) {
|
||||
show(".short",
|
||||
firstnonnull(findnamebyid(kZipCompressionNames, compressmethod),
|
||||
format(b1, "%hu", compressmethod)),
|
||||
"compressionmethod");
|
||||
}
|
||||
|
||||
void showextrantfs(uint8_t *ntfs) {
|
||||
struct timespec mtime, atime, ctime;
|
||||
filetimetotimespec(
|
||||
&mtime, (struct NtFileTime){read32le(ntfs + 8), read32le(ntfs + 12)});
|
||||
filetimetotimespec(
|
||||
&atime, (struct NtFileTime){read32le(ntfs + 16), read32le(ntfs + 20)});
|
||||
filetimetotimespec(
|
||||
&ctime, (struct NtFileTime){read32le(ntfs + 24), read32le(ntfs + 30)});
|
||||
show(".long", gc(xasprintf("%d", read32le(ntfs))), "ntfs reserved");
|
||||
show(".short", gc(xasprintf("0x%04x", read16le(ntfs + 4))),
|
||||
"ntfs attribute tag value #1");
|
||||
show(".short", gc(xasprintf("%hu", read16le(ntfs + 6))),
|
||||
"ntfs attribute tag size");
|
||||
show(".quad", gc(xasprintf("%lu", read64le(ntfs + 8))),
|
||||
gc(xasprintf("%s (%s)", "ntfs last modified time",
|
||||
gc(xiso8601(&mtime)))));
|
||||
show(".quad", gc(xasprintf("%lu", read64le(ntfs + 16))),
|
||||
gc(xasprintf("%s (%s)", "ntfs last access time", gc(xiso8601(&atime)))));
|
||||
show(".quad", gc(xasprintf("%lu", read64le(ntfs + 24))),
|
||||
gc(xasprintf("%s (%s)", "ntfs creation time", gc(xiso8601(&ctime)))));
|
||||
}
|
||||
|
||||
void showextra(uint8_t *extra) {
|
||||
switch (ZIP_EXTRA_HEADERID(extra)) {
|
||||
case kZipExtraNtfs:
|
||||
showextrantfs(ZIP_EXTRA_CONTENT(extra));
|
||||
break;
|
||||
case kZipExtraZip64:
|
||||
/* TODO */
|
||||
default:
|
||||
disassemblehex(ZIP_EXTRA_CONTENT(extra), ZIP_EXTRA_CONTENTSIZE(extra),
|
||||
stdout);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void showexternalattributes(uint8_t *cf) {
|
||||
uint32_t ea;
|
||||
ea = ZIP_CFILE_EXTERNALATTRIBUTES(cf);
|
||||
if (ZIP_CFILE_FILEATTRCOMPAT(cf) == kZipOsUnix) {
|
||||
show(".short", recreateflags(kNtFileFlagNames, ea & 0xffff),
|
||||
"dos file flags");
|
||||
show(".short", format(b1, "%#o", ea >> 16), "st_mode");
|
||||
} else {
|
||||
show(".long", recreateflags(kNtFileFlagNames, ea), "externalattributes");
|
||||
}
|
||||
}
|
||||
|
||||
void showextras(uint8_t *extras, uint16_t extrassize) {
|
||||
int i;
|
||||
bool first;
|
||||
uint8_t *p, *pe;
|
||||
if (extrassize) {
|
||||
first = true;
|
||||
for (p = extras, pe = extras + extrassize, i = 0; p < pe;
|
||||
p += ZIP_EXTRA_SIZE(p), ++i) {
|
||||
show(".short",
|
||||
firstnonnull(findnamebyid(kZipExtraNames, ZIP_EXTRA_HEADERID(p)),
|
||||
gc(xasprintf("0x%04hx", ZIP_EXTRA_HEADERID(p)))),
|
||||
gc(xasprintf("%s[%d].%s", "extras", i, "headerid")));
|
||||
show(".short", gc(xasprintf("%df-%df", (i + 2) * 10, (i + 1) * 10)),
|
||||
gc(xasprintf("%s[%d].%s (%hd %s)", "extras", i, "contentsize",
|
||||
ZIP_EXTRA_CONTENTSIZE(p), "bytes")));
|
||||
if (first) {
|
||||
first = false;
|
||||
printf("%d:", (i + 1) * 10);
|
||||
}
|
||||
showextra(p);
|
||||
printf("%d:", (i + 2) * 10);
|
||||
}
|
||||
}
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
void showlocalfileheader(uint8_t *lf, uint16_t idx) {
|
||||
printf("\n/\t%s #%hu (%zu %s)\n", "local file", idx + 1,
|
||||
ZIP_LFILE_HDRSIZE(lf), "bytes");
|
||||
show(".ascii", format(b1, "%`'.*s", 4, lf), "magic");
|
||||
show(".byte",
|
||||
firstnonnull(findnamebyid(kZipEraNames, ZIP_LFILE_VERSIONNEED(lf)),
|
||||
gc(xasprintf("%d", ZIP_LFILE_VERSIONNEED(lf)))),
|
||||
"pkzip version need");
|
||||
show(".byte",
|
||||
firstnonnull(findnamebyid(kZipOsNames, ZIP_LFILE_OSNEED(lf)),
|
||||
gc(xasprintf("%d", ZIP_LFILE_OSNEED(lf)))),
|
||||
"os need");
|
||||
showgeneralflag(ZIP_LFILE_GENERALFLAG(lf));
|
||||
showcompressmethod(ZIP_LFILE_COMPRESSIONMETHOD(lf));
|
||||
showtimestamp(ZIP_LFILE_LASTMODIFIEDTIME(lf), ZIP_LFILE_LASTMODIFIEDDATE(lf));
|
||||
show(".long", format(b1, "%#x", ZIP_LFILE_CRC32(lf)),
|
||||
gc(xasprintf(
|
||||
"%s (%#x)", "crc32z",
|
||||
crc32_z(0, ZIP_LFILE_CONTENT(lf), ZIP_LFILE_COMPRESSEDSIZE(lf)))));
|
||||
show(".long", "3f-2f",
|
||||
format(b1, "%s (%u %s)", "compressedsize", ZIP_LFILE_COMPRESSEDSIZE(lf),
|
||||
"bytes"));
|
||||
show(".long", format(b1, "%u", ZIP_LFILE_UNCOMPRESSEDSIZE(lf)),
|
||||
"uncompressedsize");
|
||||
show(".short", "1f-0f",
|
||||
format(b1, "%s (%hu %s)", "namesize", ZIP_LFILE_NAMESIZE(lf), "bytes"));
|
||||
show(
|
||||
".short", "2f-1f",
|
||||
format(b1, "%s (%hu %s)", "extrasize", ZIP_LFILE_EXTRASIZE(lf), "bytes"));
|
||||
printf("0:");
|
||||
show(".ascii",
|
||||
format(b1, "%`'s",
|
||||
gc(strndup(ZIP_LFILE_NAME(lf), ZIP_LFILE_NAMESIZE(lf)))),
|
||||
"name");
|
||||
printf("1:");
|
||||
showextras(ZIP_LFILE_EXTRA(lf), ZIP_LFILE_EXTRASIZE(lf));
|
||||
printf("2:");
|
||||
disassemblehex(ZIP_LFILE_CONTENT(lf), ZIP_LFILE_COMPRESSEDSIZE(lf), stdout);
|
||||
printf("3:\n");
|
||||
}
|
||||
|
||||
void showcentralfileheader(uint8_t *cf) {
|
||||
printf("\n/\t%s (%zu %s)\n", "central directory file header",
|
||||
ZIP_CFILE_HDRSIZE(cf), "bytes");
|
||||
show(".ascii", format(b1, "%`'.*s", 4, cf), "magic");
|
||||
show(".byte", gc(xasprintf("%d", ZIP_CFILE_VERSIONMADE(cf))), "version made");
|
||||
show(".byte",
|
||||
firstnonnull(findnamebyid(kZipOsNames, ZIP_CFILE_FILEATTRCOMPAT(cf)),
|
||||
gc(xasprintf("%d", ZIP_CFILE_FILEATTRCOMPAT(cf)))),
|
||||
"file attr compat");
|
||||
show(".byte",
|
||||
firstnonnull(findnamebyid(kZipEraNames, ZIP_CFILE_VERSIONNEED(cf)),
|
||||
gc(xasprintf("%d", ZIP_CFILE_VERSIONNEED(cf)))),
|
||||
"pkzip version need");
|
||||
show(".byte",
|
||||
firstnonnull(findnamebyid(kZipOsNames, ZIP_CFILE_OSNEED(cf)),
|
||||
gc(xasprintf("%d", ZIP_CFILE_OSNEED(cf)))),
|
||||
"os need");
|
||||
showgeneralflag(ZIP_CFILE_GENERALFLAG(cf));
|
||||
showcompressmethod(ZIP_CFILE_COMPRESSIONMETHOD(cf));
|
||||
showtimestamp(ZIP_CFILE_LASTMODIFIEDTIME(cf), ZIP_CFILE_LASTMODIFIEDDATE(cf));
|
||||
show(".long", format(b1, "%#x", ZIP_CFILE_CRC32(cf)), "crc32z");
|
||||
show(".long", format(b1, "%u", ZIP_CFILE_COMPRESSEDSIZE(cf)),
|
||||
"compressedsize");
|
||||
show(".long", format(b1, "%u", ZIP_CFILE_UNCOMPRESSEDSIZE(cf)),
|
||||
"uncompressedsize");
|
||||
show(".short", "1f-0f",
|
||||
format(b1, "%s (%hu %s)", "namesize", ZIP_CFILE_NAMESIZE(cf), "bytes"));
|
||||
show(
|
||||
".short", "2f-1f",
|
||||
format(b1, "%s (%hu %s)", "extrasize", ZIP_CFILE_EXTRASIZE(cf), "bytes"));
|
||||
show(".short", "3f-2f",
|
||||
format(b1, "%s (%hu %s)", "commentsize", ZIP_CFILE_COMMENTSIZE(cf),
|
||||
"bytes"));
|
||||
show(".short", format(b1, "%hu", ZIP_CFILE_DISK(cf)), "disk");
|
||||
show(".short",
|
||||
recreateflags(kZipIattrNames, ZIP_CFILE_INTERNALATTRIBUTES(cf)),
|
||||
"internalattributes");
|
||||
showexternalattributes(cf);
|
||||
show(".long", format(b1, "%u", ZIP_CFILE_OFFSET(cf)), "lfile hdr offset");
|
||||
printf("0:");
|
||||
show(".ascii",
|
||||
format(b1, "%`'s",
|
||||
gc(strndup(ZIP_CFILE_NAME(cf), ZIP_CFILE_NAMESIZE(cf)))),
|
||||
"name");
|
||||
printf("1:");
|
||||
showextras(ZIP_CFILE_EXTRA(cf), ZIP_CFILE_EXTRASIZE(cf));
|
||||
printf("2:");
|
||||
disassemblehex(ZIP_CFILE_COMMENT(cf), ZIP_CFILE_COMMENTSIZE(cf), stdout);
|
||||
printf("3:\n");
|
||||
}
|
||||
|
||||
void showcentraldirheader(uint8_t *cd) {
|
||||
printf("\n/\t%s (%zu %s)\n", "end of central directory header",
|
||||
ZIP_CDIR_HDRSIZE(cd), "bytes");
|
||||
show(".ascii", format(b1, "%`'.*s", 4, cd), "magic");
|
||||
show(".short", format(b1, "%hd", ZIP_CDIR_DISK(cd)), "disk");
|
||||
show(".short", format(b1, "%hd", ZIP_CDIR_STARTINGDISK(cd)), "startingdisk");
|
||||
show(".short", format(b1, "%hu", ZIP_CDIR_RECORDSONDISK(cd)),
|
||||
"recordsondisk");
|
||||
show(".short", format(b1, "%hu", ZIP_CDIR_RECORDS(cd)), "records");
|
||||
show(".long", format(b1, "%u", ZIP_CDIR_SIZE(cd)), "size");
|
||||
show(".long", format(b1, "%u", ZIP_CDIR_OFFSET(cd)), "cfile hdrs offset");
|
||||
show(".short", "1f-0f",
|
||||
format(b1, "%s (%hu %s)", "commentsize", ZIP_CDIR_COMMENTSIZE(cd),
|
||||
"bytes"));
|
||||
printf("0:");
|
||||
disassemblehex(ZIP_CDIR_COMMENT(cd), ZIP_CDIR_COMMENTSIZE(cd), stdout);
|
||||
printf("1:\n");
|
||||
}
|
||||
|
||||
void disassemblezip(uint8_t *map, size_t mapsize) {
|
||||
size_t pos;
|
||||
uint16_t i;
|
||||
static int records;
|
||||
uint8_t *cd, *cf, *lf;
|
||||
CHECK_NOTNULL((cd = zipfindcentraldir(map, mapsize)));
|
||||
pos = 0;
|
||||
records = ZIP_CDIR_RECORDS(cd);
|
||||
for (i = 0, cf = map + ZIP_CDIR_OFFSET(cd); i < records;
|
||||
++i, cf += ZIP_CFILE_HDRSIZE(cf)) {
|
||||
lf = map + ZIP_CFILE_OFFSET(cf);
|
||||
CHECK_EQ(kZipLfileHdrMagic, ZIP_LFILE_MAGIC(lf));
|
||||
advancepos(map, &pos, lf - map);
|
||||
showlocalfileheader(lf, i);
|
||||
pos = (lf - map) + ZIP_LFILE_SIZE(lf);
|
||||
}
|
||||
for (i = 0, cf = map + ZIP_CDIR_OFFSET(cd); i < records;
|
||||
++i, cf += ZIP_CFILE_HDRSIZE(cf)) {
|
||||
CHECK_EQ(kZipCfileHdrMagic, ZIP_CFILE_MAGIC(cf));
|
||||
advancepos(map, &pos, cf - map);
|
||||
showcentralfileheader(cf);
|
||||
pos = (cf - map) + ZIP_CFILE_HDRSIZE(cf);
|
||||
}
|
||||
advancepos(map, &pos, cd - map);
|
||||
showcentraldirheader(cd);
|
||||
pos = (cd - map) + ZIP_CDIR_HDRSIZE(cd);
|
||||
advancepos(map, &pos, mapsize);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int fd;
|
||||
uint8_t *map;
|
||||
struct stat st;
|
||||
CHECK_EQ(2, argc);
|
||||
CHECK_NE(-1, (fd = open(argv[1], O_RDONLY)));
|
||||
CHECK_NE(-1, fstat(fd, &st));
|
||||
CHECK_GE(st.st_size, kZipCdirHdrMinSize);
|
||||
CHECK_NE(MAP_FAILED,
|
||||
(map = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0)));
|
||||
showtitle("αcτµαlly pδrταblε εxεcµταblε", "tool/decode/zip",
|
||||
basename(argv[1]), NULL, &kModelineAsm);
|
||||
disassemblezip(map, st.st_size);
|
||||
CHECK_NE(-1, munmap(map, st.st_size));
|
||||
CHECK_NE(-1, close(fd));
|
||||
return 0;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue