Initial import

This commit is contained in:
Justine Tunney 2020-06-15 07:18:57 -07:00
commit c91b3c5006
14915 changed files with 590219 additions and 0 deletions

66
tool/decode/decode.mk Normal file
View 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
View 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
View 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
View 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');
}

View 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)));
}
}

View 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_ */

View 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);
}

View 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_ */

View 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)

View 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);
}

View 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_ */

View 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},
};

View 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
View 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
View 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
View 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
View 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_ */

View 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},
};

View 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_ */

View 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},
};

View 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
View 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},
};

View 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_ */

View 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 ROBSS 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

View 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_ */

View 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},
};

View 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_ */

View 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");
}

View 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_ */

View 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},
};

View 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_ */

View 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},
};

View 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},
};

View 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_ */

View 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},
};

View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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\
/ rrrruuuur");
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;
}