Add tool for viewing memory

https://justine.storage.googleapis.com/memzoom/index.html
This commit is contained in:
Justine Tunney 2020-11-06 20:02:53 -08:00
parent 2d80bbc802
commit 9fe95ef12b
22 changed files with 1511 additions and 1028 deletions

View file

@ -49,13 +49,16 @@ void AppendStr(struct Buffer *b, const char *s) {
}
void AppendWide(struct Buffer *b, wint_t wc) {
unsigned i;
uint64_t wb;
wb = wc;
if (!isascii(wb)) wb = tpenc(wb);
char buf[8];
i = 0;
wb = tpenc(wc);
do {
AppendChar(b, wb & 0xFF);
buf[i++] = wb & 0xFF;
wb >>= 8;
} while (wb);
AppendData(b, buf, i);
}
int AppendFmt(struct Buffer *b, const char *fmt, ...) {
@ -72,24 +75,31 @@ int AppendFmt(struct Buffer *b, const char *fmt, ...) {
}
/**
* Writes buffer until completion, interrupt, or error occurs.
* Writes buffer until completion, or error occurs.
*/
ssize_t WriteBuffer(struct Buffer *b, int fd) {
bool t;
char *p;
ssize_t rc;
size_t wrote, n;
p = b->p;
n = b->i;
t = false;
do {
if ((rc = write(fd, p, n)) != -1) {
wrote = rc;
p += wrote;
n -= wrote;
} else if (errno == EINTR) {
break;
t = true;
} else {
return -1;
}
} while (n);
return 0;
if (!t) {
return 0;
} else {
errno = EINTR;
return -1;
}
}

View file

@ -28,6 +28,7 @@
#include "libc/runtime/runtime.h"
#include "libc/sysv/consts/map.h"
#include "libc/sysv/consts/mremap.h"
#include "libc/sysv/consts/msync.h"
#include "libc/sysv/consts/o.h"
#include "libc/sysv/consts/ok.h"
#include "libc/sysv/consts/prot.h"
@ -177,6 +178,7 @@ struct ElfWriter *elfwriter_open(const char *path, int mode) {
void elfwriter_close(struct ElfWriter *elf) {
size_t i;
FlushTables(elf);
CHECK_NE(-1, msync(elf->map, elf->wrote, MS_SYNC));
CHECK_NE(-1, munmap(elf->map, elf->mapsize));
CHECK_NE(-1, ftruncate(elf->fd, elf->wrote));
CHECK_NE(-1, close(elf->fd));

View file

@ -1632,6 +1632,7 @@ static void OpMovRqCq(struct Machine *m, uint32_t rde) {
}
static void OpMovCqRq(struct Machine *m, uint32_t rde) {
int64_t cr3;
switch (ModrmReg(rde)) {
case 0:
m->cr0 = Read64(RegRexbRm(m, rde));
@ -1640,7 +1641,12 @@ static void OpMovCqRq(struct Machine *m, uint32_t rde) {
m->cr2 = Read64(RegRexbRm(m, rde));
break;
case 3:
m->cr3 = Read64(RegRexbRm(m, rde));
cr3 = Read64(RegRexbRm(m, rde));
if (0 <= cr3 && cr3 + 512 * 8 <= m->real.n) {
m->cr3 = cr3;
} else {
ThrowProtectionFault(m);
}
break;
case 4:
m->cr4 = Read64(RegRexbRm(m, rde));

63
tool/build/lib/pml4t.c Normal file
View file

@ -0,0 +1,63 @@
/*-*- 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/arraylist2.h"
#include "tool/build/lib/endian.h"
#include "tool/build/lib/machine.h"
#include "tool/build/lib/pml4t.h"
static void AppendContiguousMemoryRange(struct ContiguousMemoryRanges *ranges,
int64_t a, int64_t b) {
APPEND(&ranges->p, &ranges->i, &ranges->n,
(&(struct ContiguousMemoryRange){a, b}));
}
static void FindContiguousMemoryRangesImpl(
struct Machine *m, struct ContiguousMemoryRanges *ranges, int64_t addr,
unsigned level, int64_t pt, int64_t a, int64_t b) {
int64_t i, page, entry;
for (i = a; i < b; ++i) {
entry = Read64(m->real.p + pt + i * 8);
if (!(entry & 1)) continue;
entry &= 0x7ffffffff000;
page = (addr | i << level) << 16 >> 16;
if (level == 12) {
if (ranges->i && page == ranges->p[ranges->i - 1].b) {
ranges->p[ranges->i - 1].b += 0x1000;
} else {
AppendContiguousMemoryRange(ranges, page, page + 0x1000);
}
} else if (entry + 512 * 8 <= m->real.n) {
FindContiguousMemoryRangesImpl(m, ranges, page, level - 9, entry, 0, 512);
}
}
}
void FindContiguousMemoryRanges(struct Machine *m,
struct ContiguousMemoryRanges *ranges) {
uint64_t cr3;
ranges->i = 0;
if ((m->mode & 3) == XED_MODE_LONG) {
cr3 = m->cr3 & 0x7ffffffff000;
FindContiguousMemoryRangesImpl(m, ranges, 0, 39, cr3, 256, 512);
FindContiguousMemoryRangesImpl(m, ranges, 0, 39, cr3, 0, 256);
} else {
AppendContiguousMemoryRange(ranges, 0, m->real.n);
}
}

View file

@ -8,6 +8,17 @@ COSMOPOLITAN_C_START_
#define UnmaskPageAddr(x) SignExtendAddr(MaskPageAddr(x))
#define SignExtendAddr(x) ((int64_t)((uint64_t)(x) << 16) >> 16)
struct ContiguousMemoryRanges {
size_t i, n;
struct ContiguousMemoryRange {
int64_t a;
int64_t b;
} * p;
};
void FindContiguousMemoryRanges(struct Machine *,
struct ContiguousMemoryRanges *);
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_TOOL_BUILD_LIB_PML4T_H_ */

179
tool/build/lib/xmmtype.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 "tool/build/lib/modrm.h"
#include "tool/build/lib/xmmtype.h"
static void UpdateXmmTypes(struct Machine *m, struct XmmType *xt, int regtype,
int rmtype) {
xt->type[RexrReg(m->xedd->op.rde)] = regtype;
if (IsModrmRegister(m->xedd->op.rde)) {
xt->type[RexbRm(m->xedd->op.rde)] = rmtype;
}
}
static void UpdateXmmSizes(struct Machine *m, struct XmmType *xt, int regsize,
int rmsize) {
xt->size[RexrReg(m->xedd->op.rde)] = regsize;
if (IsModrmRegister(m->xedd->op.rde)) {
xt->size[RexbRm(m->xedd->op.rde)] = rmsize;
}
}
void UpdateXmmType(struct Machine *m, struct XmmType *xt) {
switch (m->xedd->op.dispatch) {
case 0x12E: // UCOMIS
case 0x12F: // COMIS
case 0x151: // SQRT
case 0x152: // RSQRT
case 0x153: // RCP
case 0x158: // ADD
case 0x159: // MUL
case 0x15C: // SUB
case 0x15D: // MIN
case 0x15E: // DIV
case 0x15F: // MAX
case 0x1C2: // CMP
if (Osz(m->xedd->op.rde) || Rep(m->xedd->op.rde) == 2) {
UpdateXmmTypes(m, xt, kXmmDouble, kXmmDouble);
} else {
UpdateXmmTypes(m, xt, kXmmFloat, kXmmFloat);
}
break;
case 0x12A: // CVTPI2PS,CVTSI2SS,CVTPI2PD,CVTSI2SD
if (Osz(m->xedd->op.rde) || Rep(m->xedd->op.rde) == 2) {
UpdateXmmSizes(m, xt, 8, 4);
UpdateXmmTypes(m, xt, kXmmDouble, kXmmIntegral);
} else {
UpdateXmmSizes(m, xt, 4, 4);
UpdateXmmTypes(m, xt, kXmmFloat, kXmmIntegral);
}
break;
case 0x15A: // CVT{P,S}{S,D}2{P,S}{S,D}
if (Osz(m->xedd->op.rde) || Rep(m->xedd->op.rde) == 2) {
UpdateXmmTypes(m, xt, kXmmFloat, kXmmDouble);
} else {
UpdateXmmTypes(m, xt, kXmmDouble, kXmmFloat);
}
break;
case 0x15B: // CVT{,T}{DQ,PS}2{PS,DQ}
UpdateXmmSizes(m, xt, 4, 4);
if (Osz(m->xedd->op.rde) || Rep(m->xedd->op.rde) == 3) {
UpdateXmmTypes(m, xt, kXmmIntegral, kXmmFloat);
} else {
UpdateXmmTypes(m, xt, kXmmFloat, kXmmIntegral);
}
break;
case 0x17C: // HADD
case 0x17D: // HSUB
case 0x1D0: // ADDSUB
if (Osz(m->xedd->op.rde)) {
UpdateXmmTypes(m, xt, kXmmDouble, kXmmDouble);
} else {
UpdateXmmTypes(m, xt, kXmmFloat, kXmmFloat);
}
break;
case 0x164: // PCMPGTB
case 0x174: // PCMPEQB
case 0x1D8: // PSUBUSB
case 0x1DA: // PMINUB
case 0x1DC: // PADDUSB
case 0x1DE: // PMAXUB
case 0x1E0: // PAVGB
case 0x1E8: // PSUBSB
case 0x1EC: // PADDSB
case 0x1F8: // PSUBB
case 0x1FC: // PADDB
UpdateXmmSizes(m, xt, 1, 1);
UpdateXmmTypes(m, xt, kXmmIntegral, kXmmIntegral);
break;
case 0x165: // PCMPGTW
case 0x175: // PCMPEQW
case 0x171: // PSRLW,PSRAW,PSLLW
case 0x1D1: // PSRLW
case 0x1D5: // PMULLW
case 0x1D9: // PSUBUSW
case 0x1DD: // PADDUSW
case 0x1E1: // PSRAW
case 0x1E3: // PAVGW
case 0x1E4: // PMULHUW
case 0x1E5: // PMULHW
case 0x1E9: // PSUBSW
case 0x1EA: // PMINSW
case 0x1ED: // PADDSW
case 0x1EE: // PMAXSW
case 0x1F1: // PSLLW
case 0x1F6: // PSADBW
case 0x1F9: // PSUBW
case 0x1FD: // PADDW
UpdateXmmSizes(m, xt, 2, 2);
UpdateXmmTypes(m, xt, kXmmIntegral, kXmmIntegral);
break;
case 0x166: // PCMPGTD
case 0x176: // PCMPEQD
case 0x172: // PSRLD,PSRAD,PSLLD
case 0x1D2: // PSRLD
case 0x1E2: // PSRAD
case 0x1F2: // PSLLD
case 0x1FA: // PSUBD
case 0x1FE: // PADDD
UpdateXmmSizes(m, xt, 4, 4);
UpdateXmmTypes(m, xt, kXmmIntegral, kXmmIntegral);
break;
case 0x173: // PSRLQ,PSRLQ,PSRLDQ,PSLLQ,PSLLDQ
case 0x1D3: // PSRLQ
case 0x1D4: // PADDQ
case 0x1F3: // PSLLQ
case 0x1F4: // PMULUDQ
case 0x1FB: // PSUBQ
UpdateXmmSizes(m, xt, 8, 8);
UpdateXmmTypes(m, xt, kXmmIntegral, kXmmIntegral);
break;
case 0x16B: // PACKSSDW
case 0x1F5: // PMADDWD
UpdateXmmSizes(m, xt, 4, 2);
UpdateXmmTypes(m, xt, kXmmIntegral, kXmmIntegral);
break;
case 0x163: // PACKSSWB
case 0x167: // PACKUSWB
UpdateXmmSizes(m, xt, 1, 2);
UpdateXmmTypes(m, xt, kXmmIntegral, kXmmIntegral);
break;
case 0x128: // MOVAPS Vps Wps
if (IsModrmRegister(m->xedd->op.rde)) {
xt->type[RexrReg(m->xedd->op.rde)] = xt->type[RexbRm(m->xedd->op.rde)];
xt->size[RexrReg(m->xedd->op.rde)] = xt->size[RexbRm(m->xedd->op.rde)];
}
break;
case 0x129: // MOVAPS Wps Vps
if (IsModrmRegister(m->xedd->op.rde)) {
xt->type[RexbRm(m->xedd->op.rde)] = xt->type[RexrReg(m->xedd->op.rde)];
xt->size[RexbRm(m->xedd->op.rde)] = xt->size[RexrReg(m->xedd->op.rde)];
}
break;
case 0x16F: // MOVDQA Vdq Wdq
if (Osz(m->xedd->op.rde) && IsModrmRegister(m->xedd->op.rde)) {
xt->type[RexrReg(m->xedd->op.rde)] = xt->type[RexbRm(m->xedd->op.rde)];
xt->size[RexrReg(m->xedd->op.rde)] = xt->size[RexbRm(m->xedd->op.rde)];
}
break;
default:
return;
}
}

21
tool/build/lib/xmmtype.h Normal file
View file

@ -0,0 +1,21 @@
#ifndef COSMOPOLITAN_TOOL_BUILD_LIB_XMMTYPE_H_
#define COSMOPOLITAN_TOOL_BUILD_LIB_XMMTYPE_H_
#include "tool/build/lib/machine.h"
#define kXmmIntegral 0
#define kXmmDouble 1
#define kXmmFloat 2
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
struct XmmType {
uint8_t type[16];
uint8_t size[16];
};
void UpdateXmmType(struct Machine *, struct XmmType *);
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_TOOL_BUILD_LIB_XMMTYPE_H_ */