| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471 |
- /*
- ** $Id: lundump.c,v 2.44.1.1 2017/04/19 17:20:42 roberto Exp $
- ** load precompiled Lua chunks
- ** See Copyright Notice in lua.h
- */
- #define lundump_c
- #define LUA_CORE
- #include "lprefix.h"
- #include <string.h>
- #include "lua.h"
- #include "ldebug.h"
- #include "ldo.h"
- #include "lfunc.h"
- #include "lmem.h"
- #include "lobject.h"
- #include "lstring.h"
- #include "lundump.h"
- #include "lzio.h"
- #include "ltable.h"
- #include "luat_base.h"
- #include "luat_fs.h"
- #define LUAT_LOG_TAG "undump"
- #include "luat_log.h"
- #define LUF_SIGNATURE "\x1cLUF"
- #if !defined(luai_verifycode)
- #define luai_verifycode(L,b,f) /* empty */
- #endif
- typedef struct {
- lua_State *L;
- ZIO *Z;
- const char *name;
- } LoadState;
- static void dumpHex(const char* tag, void* ptr, size_t len) {
- uint8_t* c = (uint8_t*)ptr;
- for (size_t i = 0; i < len / 8; i++)
- {
- LLOGD("%s %p %02X %02X %02X %02X %02X %02X %02X %02X", tag, &c[i*8], c[i*8], c[i*8+1], c[i*8+2], c[i*8+3],
- c[i*8+4], c[i*8+5], c[i*8+6], c[i*8+7]);
- }
- }
- static l_noret error(LoadState *S, const char *why) {
- luaO_pushfstring(S->L, "luf %s: %s precompiled chunk", S->name, why);
- luaD_throw(S->L, LUA_ERRSYNTAX);
- }
- /*
- ** All high-level loads go through LoadVector; you can change it to
- ** adapt to the endianness of the input
- */
- #define LoadVector(S,b,n) LoadBlock(S,b,(n)*sizeof((b)[0]))
- static void LoadBlock (LoadState *S, void *b, size_t size) {
- if (luaZ_read(S->Z, b, size) != 0)
- error(S, "truncated");
- }
- static void* DistBlock (LoadState *S, size_t size) {
- uint8_t b = 0;
- const char* p = S->Z->p;
- for (size_t i = 0; i < size; i++)
- {
- if (luaZ_read(S->Z, &b, 1) != 0)
- error(S, "truncated");
- }
- return (void*)p;
- }
- #define LoadVar(S,x) LoadVector(S,&x,1)
- static lu_byte LoadByte (LoadState *S) {
- lu_byte x;
- LoadVar(S, x);
- return x;
- }
- static int LoadInt (LoadState *S) {
- int x;
- LoadVar(S, x);
- return x;
- }
- static lua_Number LoadNumber (LoadState *S) {
- lua_Number x;
- LoadVar(S, x);
- return x;
- }
- static lua_Integer LoadInteger (LoadState *S) {
- lua_Integer x;
- LoadVar(S, x);
- return x;
- }
- // static TString *LoadString (LoadState *S, Proto *p) {
- // lu_byte t = LoadByte(S);
- // if (t == 0)
- // return NULL;
- // TString * ts = (TString*)S->Z->p;
- // // LLOGD("LoadString >> %d %p", tsslen(ts), ts);
- // DistBlock(S, sizeof(TString) + tsslen(ts) + 1);
- // // LLOGD("LoadString >> %s", getstr(ts));
- // return ts;
- // }
- static void LoadCode (LoadState *S, Proto *f) {
- // int n = LoadInt(S);
- // LLOGD("LoadCode %d %d", n, sizeof(Instruction) * n);
- // f->sizecode = n;
- // f->code = luat_heap_malloc(sizeof(Instruction) * f->sizecode);
- // memcpy(f->code, S->Z->p, sizeof(Instruction) * f->sizecode);
- f->code = DistBlock(S, sizeof(Instruction) * f->sizecode);
- //f->code = ((uint8_t*)f->code) + 2;
- LLOGD("f->code %p", f->code);
- for (size_t i = 0; i < f->sizecode; i++)
- {
- LLOGD("Code %02X -> %08X", i, f->code[i]);
- }
-
- }
- static void LoadFunction(LoadState *S, Proto *f, TString *psource);
- static void LoadConstants (LoadState *S, Proto *f) {
- // int i;
- // int n = LoadInt(S);
- // LLOGD("LoadConstants %d %d", n, sizeof(TValue) * n);
- // f->sizek = n;
- // 指向常数数组
- f->k = DistBlock(S, sizeof(TValue) * f->sizek);
- // 跳过字符串段
- for (size_t i = 0; i < f->sizek; i++)
- {
- TValue *t = &f->k[i];
- switch (ttype(t))
- {
- case LUA_TSHRSTR:
- case LUA_TLNGSTR:
- LLOGD("const string %p %s", tsvalue(t), getstr(tsvalue(t)));
- break;
- default:
- break;
- }
- }
-
-
-
- // LLOGD("1>>LoadConstants %02X %02X %02X %02X", *(S->Z->p), *(S->Z->p + 1), *(S->Z->p + 2), *(S->Z->p + 3));
- // n = LoadInt(S);
- // LLOGD("LoadConstants skip Strings %d", n);
- // DistBlock(S, sizeof(char) * n);
- // LLOGD("2>>LoadConstants %02X %02X %02X %02X", *(S->Z->p), *(S->Z->p + 1), *(S->Z->p + 2), *(S->Z->p + 3));
- }
- static void LoadProtos (LoadState *S, Proto *f) {
- int i;
- // int n = LoadInt(S);
- f->p = luaM_newvector(S->L, f->sizep, Proto *);
- // f->sizep = n;
- for (i = 0; i < f->sizep; i++)
- f->p[i] = NULL;
- for (i = 0; i < f->sizep; i++) {
- f->p[i] = luaF_newproto(S->L);
- luaC_objbarrier(S->L, f, f->p[i]);
- LoadFunction(S, f->p[i], f->source);
- }
- // LLOGD("LoadProtos %d %d", n, sizeof(Proto *) * n);
- }
- static void LoadUpvalues (LoadState *S, Proto *f) {
- int i, n;
- // n = LoadInt(S);
- // f->sizeupvalues = n;
- // LLOGD("LoadUpvalues %d %d", n, sizeof(Upvaldesc) * n);
- f->upvalues = DistBlock(S, sizeof(Upvaldesc) * f->sizeupvalues);
- // char* tmp = luaM_newvector(S->L, n, Upvaldesc);
- // memcpy(tmp, f->upvalues, sizeof(Upvaldesc) * n);
- // f->upvalues = tmp;
- // 跳过字符串段
- // n = LoadInt(S);
- // LLOGD("LoadUpvalues skip Strings %d", n);
- // DistBlock(S, sizeof(char) * n);
- }
- static void LoadDebug (LoadState *S, Proto *f) {
- int i, n;
-
- // n = LoadInt(S);
- // f->sizelineinfo = n;
- // LLOGD("LoadDebug sizelineinfo %d %d", n, sizeof(int) * n);
- f->lineinfo = DistBlock(S, sizeof(int) * f->sizelineinfo);
-
- // n = LoadInt(S);
- // f->sizelocvars = n;
- // LLOGD("LoadDebug sizelocvars %d %d", n, sizeof(LocVar) * n);
- f->locvars = DistBlock(S, sizeof(LocVar) * f->sizelocvars);
- // n = LoadInt(S);
- // DistBlock(S, sizeof(char) * n);
- }
- static void LoadFunction (LoadState *S, Proto *f, TString *psource) {
- //LLOGD(">> %02X %02X %02X %02X", *(S->Z->p), *(S->Z->p + 1), *(S->Z->p + 2), *(S->Z->p + 3));
- f->source = psource; /* reuse parent's source */
- if (f->source)
- LLOGI("%s %d source %s", __FILE__, __LINE__, getstr(f->source));
- else
- LLOGD("no source ?");
- f->linedefined = LoadInt(S);
- f->lastlinedefined = LoadInt(S);
- f->numparams = LoadByte(S);
- f->is_vararg = LoadByte(S);
- f->maxstacksize = LoadByte(S);
- LoadByte(S); // f->source != NULL ?
- // LLOGD("linedefined %d", f->linedefined);
- // LLOGD("lastlinedefined %d", f->lastlinedefined);
- // LLOGD("numparams %d", f->numparams);
- // LLOGD("is_vararg %d", f->is_vararg);
- // LLOGD("maxstacksize %d", f->maxstacksize);
- f->sizecode = LoadInt(S);
- f->sizek = LoadInt(S);
- f->sizeupvalues = LoadInt(S);
- f->sizep = LoadInt(S);
- f->sizelineinfo = LoadInt(S);
- f->sizelocvars = LoadInt(S);
- // LLOGD("sizecode %d", f->sizecode);
- // LLOGD("sizek %d", f->sizek);
- // LLOGD("sizeupvalues %d", f->sizeupvalues);
- // LLOGD("sizep %d", f->sizep);
- // LLOGD("sizelineinfo %d", f->sizelineinfo);
- // LLOGD("sizelocvars %d", f->sizelocvars);
- LoadCode(S, f);
- LoadConstants(S, f);
- LoadUpvalues(S, f);
- LoadProtos(S, f);
- LoadDebug(S, f);
- // for (size_t i = 0; i < f->sizelineinfo; i++)
- // {
- // LLOGD("lineinfo %d %p", f->lineinfo[i], &f->lineinfo[i]);
- // }
- // for (size_t i = 0; i < f->sizek; i++)
- // {
- // switch (f->k[i].tt_)
- // {
- // case LUA_TSHRSTR:
- // case LUA_TLNGSTR:
- // // LLOGD("const string %s", getstr(tsvalue(&f->k[i])));
- // LLOGD("const string %s", getstr(tsvalue(&f->k[i])));
- // break;
- // }
- // }
- // for (size_t i = 0; i < f->sizelocvars; i++)
- // {
- // LLOGD("locval string %s", getstr(f->locvars[i].varname));
- // }
- LLOGD("f->upvalues %p %08X", f->upvalues, (uint32_t)f->upvalues);
- for (size_t i = 0; i < f->sizeupvalues; i++)
- {
- // LLOGD("upval string %s", getstr(f->upvalues[i].name));
- LLOGD("upval string %p", f->upvalues[i].name);
- }
- }
- static void checkliteral (LoadState *S, const char *s, const char *msg) {
- char buff[sizeof(LUA_SIGNATURE) + sizeof(LUAC_DATA)]; /* larger than both */
- size_t len = strlen(s);
- // buff[len] = 0;
- LoadVector(S, buff, len);
- // LLOGD("buff>> %02X %02X %02X %02X", buff[0], buff[1], buff[2], buff[3]);
- // LLOGD("s>> %02X %02X %02X %02X", s[0], s[1], s[2], s[3]);
- if (memcmp(s, buff, len) != 0)
- error(S, msg);
- }
- static void fchecksize (LoadState *S, size_t size, const char *tname) {
- if (LoadByte(S) != size)
- error(S, luaO_pushfstring(S->L, "%s size mismatch in", tname));
- }
- #define checksize(S,t) fchecksize(S,sizeof(t),#t)
- static void checkHeader (LoadState *S) {
- checkliteral(S, LUF_SIGNATURE + 1, "not a"); /* 1st char already checked */
- if (LoadByte(S) != LUAC_VERSION)
- error(S, "version mismatch in");
- if (LoadByte(S) != 1)
- error(S, "format mismatch in");
- checkliteral(S, LUAC_DATA, "corrupted");
- checksize(S, int);
- checksize(S, size_t);
- checksize(S, Instruction);
- checksize(S, lua_Integer);
- checksize(S, lua_Number);
- if (LoadInteger(S) != LUAC_INT)
- error(S, "endianness mismatch in");
- if (LoadNumber(S) != LUAC_NUM)
- error(S, "float format mismatch in");
- }
- extern void luat_os_print_heapinfo(const char* tag);
- typedef struct LoadS {
- const char *s;
- size_t size;
- } LoadS;
- static const char *getS (lua_State *L, void *ud, size_t *size) {
- LoadS *ls = (LoadS *)ud;
- (void)L; /* not used */
- if (ls->size == 0) return NULL;
- *size = ls->size;
- ls->size = 0;
- return ls->s;
- }
- /*
- ** load precompiled chunk
- */
- LClosure *luat_luf_undump(lua_State *L, const char* ptr, size_t len, const char *name) {
- LoadState S;
- LClosure *cl;
- ZIO z;
- LoadS ls;
- ls.s = ptr;
- ls.size = len;
- luaZ_init(L, &z, getS, &ls);
- zgetc(&z);
- S.name = name;
- S.L = L;
- S.Z = &z;
- checkHeader(&S);
- cl = luaF_newLclosure(L, LoadByte(&S));
- setclLvalue(L, L->top, cl);
- luaD_inctop(L);
- cl->p = luaF_newproto(L);
- // LLOGD("sizeupvalues %d", cl->nupvalues);
- luaC_objbarrier(L, cl, cl->p); // add by wendal, refer: https://github.com/lua/lua/commit/f5eb809d3f1da13683cd02184042e67228206205
- size_t s = LoadInt(&S);
- LoadFunction(&S, cl->p, (TString*)s);
- lua_assert(cl->nupvalues == cl->p->sizeupvalues);
- luai_verifycode(L, buff, cl->p);
- luaF_initupvals(L, cl);
- //-----------------
- // from lua_load
- LClosure *f = cl;
- if (f->nupvalues >= 1) { /* does it have an upvalue? */
- /* get global table from registry */
- Table *reg = hvalue(&G(L)->l_registry);
- const TValue *gt = luaH_getint(reg, LUA_RIDX_GLOBALS);
- /* set global table as 1st upvalue of 'f' (may be LUA_ENV) */
- setobj(L, f->upvals[0]->v, gt);
- luaC_upvalbarrier(L, f->upvals[0]);
- }
- //-----------------
- //sizeof(LClosure) + sizeof(Proto) + sizeof(UpVal);
- return cl;
- }
- #ifndef LoadF
- typedef struct LoadF {
- int n; /* number of pre-read characters */
- FILE *f; /* file being read */
- char buff[BUFSIZ]; /* area for reading file */
- } LoadF;
- #endif
- LClosure *luat_luf_undump2(lua_State *L, ZIO *Z, const char *name) {
- LoadState S;
- LClosure *cl;
- S.name = name;
- S.L = L;
- S.Z = Z;
- #ifdef LUAT_USE_FS_VFS
- LLOGD("try mmap");
- char* ptr = (char*)luat_vfs_mmap(((LoadF*)Z->data)->f);
- if (ptr != NULL) {
- LLOGD("found mmap %p", ptr);
- ZIO z;
- LoadS ls;
- ls.s = ptr;
- ls.size = 64*1024;
- luaZ_init(L, &z, getS, &ls);
- zgetc(&z);
- S.Z = &z;
- // LLOGD(">> %02X %02X %02X %02X", S.Z->p[0], S.Z->p[1], S.Z->p[2], S.Z->p[3]);
- // LLOGD(">> %02X %02X %02X %02X", S.Z->p[4], S.Z->p[5], S.Z->p[6], S.Z->p[7]);
- // LLOGD(">> %02X %02X %02X %02X", S.Z->p[8], S.Z->p[9], S.Z->p[10], S.Z->p[11]);
- }
- #endif
- // LLOGD("LClosure %d Proto %d Upvaldesc %d LocVal %d",
- // sizeof(LClosure), sizeof(Proto), sizeof(Upvaldesc), sizeof(LocVar));
- checkHeader(&S);
- cl = luaF_newLclosure(L, LoadByte(&S));
- // 有几个对齐用的字节
- size_t fd_offset = (size_t)S.Z->p;
- if (fd_offset % 0x04 != 0) {
- LLOGD("skip %d 0x00", fd_offset % 0x04);
- for (size_t i = 0; i < (4 - (fd_offset % 0x04)); i++)
- {
- LoadByte(&S);
- }
- }
- //
- setclLvalue(L, L->top, cl);
- luaD_inctop(L);
- cl->p = luaF_newproto(L);
- luaC_objbarrier(L, cl, cl->p); // add by wendal, refer: https://github.com/lua/lua/commit/f5eb809d3f1da13683cd02184042e67228206205
- size_t s = LoadInt(&S);
- LoadFunction(&S, cl->p, (TString*)s);
- lua_assert(cl->nupvalues == cl->p->sizeupvalues);
- luai_verifycode(L, buff, cl->p);
- // dumpHex("& upvalues", &cl->p->upvalues[0], 8);
- // dumpHex("& upvalues[0].name", &cl->p->upvalues[0].name, 8);
- // dumpHex("> upvalues[0].name", cl->p->upvalues[0].name, 8);
- // LLOGD("> getstr(upvalues[0].name) %p", getstr(cl->p->upvalues[0].name));
- // LLOGD("> getstr(upvalues[0].name) %s", getstr(cl->p->upvalues[0].name));
- // dumpHex("head", (char*)0x080E0000, 8);
- //dumpHex("lineinfo", cl->p->lineinfo, 8);
- //LLOGD("lineinfo %d %d", cl->p->lineinfo[0], cl->p->lineinfo[1]);
- return cl;
- }
|