1*0a6a1f1dSLionel Sambuc /* $NetBSD: lundump.c,v 1.3 2015/02/02 14:03:05 lneto Exp $ */
211be35a1SLionel Sambuc
311be35a1SLionel Sambuc /*
4*0a6a1f1dSLionel Sambuc ** Id: lundump.c,v 2.41 2014/11/02 19:19:04 roberto Exp
511be35a1SLionel Sambuc ** load precompiled Lua chunks
611be35a1SLionel Sambuc ** See Copyright Notice in lua.h
711be35a1SLionel Sambuc */
811be35a1SLionel Sambuc
911be35a1SLionel Sambuc #define lundump_c
1011be35a1SLionel Sambuc #define LUA_CORE
1111be35a1SLionel Sambuc
12*0a6a1f1dSLionel Sambuc #include "lprefix.h"
13*0a6a1f1dSLionel Sambuc
14*0a6a1f1dSLionel Sambuc
15*0a6a1f1dSLionel Sambuc #ifndef _KERNEL
16*0a6a1f1dSLionel Sambuc #include <string.h>
17*0a6a1f1dSLionel Sambuc #endif
18*0a6a1f1dSLionel Sambuc
1911be35a1SLionel Sambuc #include "lua.h"
2011be35a1SLionel Sambuc
2111be35a1SLionel Sambuc #include "ldebug.h"
2211be35a1SLionel Sambuc #include "ldo.h"
2311be35a1SLionel Sambuc #include "lfunc.h"
2411be35a1SLionel Sambuc #include "lmem.h"
2511be35a1SLionel Sambuc #include "lobject.h"
2611be35a1SLionel Sambuc #include "lstring.h"
2711be35a1SLionel Sambuc #include "lundump.h"
2811be35a1SLionel Sambuc #include "lzio.h"
2911be35a1SLionel Sambuc
30*0a6a1f1dSLionel Sambuc
31*0a6a1f1dSLionel Sambuc #if !defined(luai_verifycode)
32*0a6a1f1dSLionel Sambuc #define luai_verifycode(L,b,f) /* empty */
33*0a6a1f1dSLionel Sambuc #endif
34*0a6a1f1dSLionel Sambuc
35*0a6a1f1dSLionel Sambuc
3611be35a1SLionel Sambuc typedef struct {
3711be35a1SLionel Sambuc lua_State *L;
3811be35a1SLionel Sambuc ZIO *Z;
3911be35a1SLionel Sambuc Mbuffer *b;
4011be35a1SLionel Sambuc const char *name;
4111be35a1SLionel Sambuc } LoadState;
4211be35a1SLionel Sambuc
4311be35a1SLionel Sambuc
error(LoadState * S,const char * why)44*0a6a1f1dSLionel Sambuc static l_noret error(LoadState *S, const char *why) {
45*0a6a1f1dSLionel Sambuc luaO_pushfstring(S->L, "%s: %s precompiled chunk", S->name, why);
4611be35a1SLionel Sambuc luaD_throw(S->L, LUA_ERRSYNTAX);
4711be35a1SLionel Sambuc }
4811be35a1SLionel Sambuc
4911be35a1SLionel Sambuc
50*0a6a1f1dSLionel Sambuc /*
51*0a6a1f1dSLionel Sambuc ** All high-level loads go through LoadVector; you can change it to
52*0a6a1f1dSLionel Sambuc ** adapt to the endianness of the input
53*0a6a1f1dSLionel Sambuc */
54*0a6a1f1dSLionel Sambuc #define LoadVector(S,b,n) LoadBlock(S,b,(n)*sizeof((b)[0]))
55*0a6a1f1dSLionel Sambuc
LoadBlock(LoadState * S,void * b,size_t size)56*0a6a1f1dSLionel Sambuc static void LoadBlock (LoadState *S, void *b, size_t size) {
57*0a6a1f1dSLionel Sambuc if (luaZ_read(S->Z, b, size) != 0)
58*0a6a1f1dSLionel Sambuc error(S, "truncated");
5911be35a1SLionel Sambuc }
6011be35a1SLionel Sambuc
61*0a6a1f1dSLionel Sambuc
62*0a6a1f1dSLionel Sambuc #define LoadVar(S,x) LoadVector(S,&x,1)
63*0a6a1f1dSLionel Sambuc
64*0a6a1f1dSLionel Sambuc
LoadByte(LoadState * S)65*0a6a1f1dSLionel Sambuc static lu_byte LoadByte (LoadState *S) {
66*0a6a1f1dSLionel Sambuc lu_byte x;
6711be35a1SLionel Sambuc LoadVar(S, x);
6811be35a1SLionel Sambuc return x;
6911be35a1SLionel Sambuc }
7011be35a1SLionel Sambuc
71*0a6a1f1dSLionel Sambuc
LoadInt(LoadState * S)72*0a6a1f1dSLionel Sambuc static int LoadInt (LoadState *S) {
7311be35a1SLionel Sambuc int x;
7411be35a1SLionel Sambuc LoadVar(S, x);
7511be35a1SLionel Sambuc return x;
7611be35a1SLionel Sambuc }
7711be35a1SLionel Sambuc
78*0a6a1f1dSLionel Sambuc
LoadNumber(LoadState * S)79*0a6a1f1dSLionel Sambuc static lua_Number LoadNumber (LoadState *S) {
8011be35a1SLionel Sambuc lua_Number x;
8111be35a1SLionel Sambuc LoadVar(S, x);
8211be35a1SLionel Sambuc return x;
8311be35a1SLionel Sambuc }
8411be35a1SLionel Sambuc
85*0a6a1f1dSLionel Sambuc
LoadInteger(LoadState * S)86*0a6a1f1dSLionel Sambuc static lua_Integer LoadInteger (LoadState *S) {
87*0a6a1f1dSLionel Sambuc lua_Integer x;
88*0a6a1f1dSLionel Sambuc LoadVar(S, x);
89*0a6a1f1dSLionel Sambuc return x;
90*0a6a1f1dSLionel Sambuc }
91*0a6a1f1dSLionel Sambuc
92*0a6a1f1dSLionel Sambuc
LoadString(LoadState * S)93*0a6a1f1dSLionel Sambuc static TString *LoadString (LoadState *S) {
94*0a6a1f1dSLionel Sambuc size_t size = LoadByte(S);
95*0a6a1f1dSLionel Sambuc if (size == 0xFF)
9611be35a1SLionel Sambuc LoadVar(S, size);
9711be35a1SLionel Sambuc if (size == 0)
9811be35a1SLionel Sambuc return NULL;
99*0a6a1f1dSLionel Sambuc else {
100*0a6a1f1dSLionel Sambuc char *s = luaZ_openspace(S->L, S->b, --size);
101*0a6a1f1dSLionel Sambuc LoadVector(S, s, size);
102*0a6a1f1dSLionel Sambuc return luaS_newlstr(S->L, s, size);
10311be35a1SLionel Sambuc }
10411be35a1SLionel Sambuc }
10511be35a1SLionel Sambuc
106*0a6a1f1dSLionel Sambuc
LoadCode(LoadState * S,Proto * f)107*0a6a1f1dSLionel Sambuc static void LoadCode (LoadState *S, Proto *f) {
10811be35a1SLionel Sambuc int n = LoadInt(S);
10911be35a1SLionel Sambuc f->code = luaM_newvector(S->L, n, Instruction);
11011be35a1SLionel Sambuc f->sizecode = n;
111*0a6a1f1dSLionel Sambuc LoadVector(S, f->code, n);
11211be35a1SLionel Sambuc }
11311be35a1SLionel Sambuc
11411be35a1SLionel Sambuc
115*0a6a1f1dSLionel Sambuc static void LoadFunction(LoadState *S, Proto *f, TString *psource);
116*0a6a1f1dSLionel Sambuc
117*0a6a1f1dSLionel Sambuc
LoadConstants(LoadState * S,Proto * f)118*0a6a1f1dSLionel Sambuc static void LoadConstants (LoadState *S, Proto *f) {
119*0a6a1f1dSLionel Sambuc int i;
120*0a6a1f1dSLionel Sambuc int n = LoadInt(S);
12111be35a1SLionel Sambuc f->k = luaM_newvector(S->L, n, TValue);
12211be35a1SLionel Sambuc f->sizek = n;
12311be35a1SLionel Sambuc for (i = 0; i < n; i++)
124*0a6a1f1dSLionel Sambuc setnilvalue(&f->k[i]);
125*0a6a1f1dSLionel Sambuc for (i = 0; i < n; i++) {
12611be35a1SLionel Sambuc TValue *o = &f->k[i];
127*0a6a1f1dSLionel Sambuc int t = LoadByte(S);
128*0a6a1f1dSLionel Sambuc switch (t) {
12911be35a1SLionel Sambuc case LUA_TNIL:
13011be35a1SLionel Sambuc setnilvalue(o);
13111be35a1SLionel Sambuc break;
13211be35a1SLionel Sambuc case LUA_TBOOLEAN:
133*0a6a1f1dSLionel Sambuc setbvalue(o, LoadByte(S));
13411be35a1SLionel Sambuc break;
135*0a6a1f1dSLionel Sambuc #ifndef _KERNEL
136*0a6a1f1dSLionel Sambuc case LUA_TNUMFLT:
137*0a6a1f1dSLionel Sambuc setfltvalue(o, LoadNumber(S));
13811be35a1SLionel Sambuc break;
139*0a6a1f1dSLionel Sambuc #endif
140*0a6a1f1dSLionel Sambuc case LUA_TNUMINT:
141*0a6a1f1dSLionel Sambuc setivalue(o, LoadInteger(S));
142*0a6a1f1dSLionel Sambuc break;
143*0a6a1f1dSLionel Sambuc case LUA_TSHRSTR:
144*0a6a1f1dSLionel Sambuc case LUA_TLNGSTR:
14511be35a1SLionel Sambuc setsvalue2n(S->L, o, LoadString(S));
14611be35a1SLionel Sambuc break;
14711be35a1SLionel Sambuc default:
148*0a6a1f1dSLionel Sambuc lua_assert(0);
14911be35a1SLionel Sambuc }
15011be35a1SLionel Sambuc }
15111be35a1SLionel Sambuc }
15211be35a1SLionel Sambuc
153*0a6a1f1dSLionel Sambuc
LoadProtos(LoadState * S,Proto * f)154*0a6a1f1dSLionel Sambuc static void LoadProtos (LoadState *S, Proto *f) {
155*0a6a1f1dSLionel Sambuc int i;
156*0a6a1f1dSLionel Sambuc int n = LoadInt(S);
157*0a6a1f1dSLionel Sambuc f->p = luaM_newvector(S->L, n, Proto *);
158*0a6a1f1dSLionel Sambuc f->sizep = n;
159*0a6a1f1dSLionel Sambuc for (i = 0; i < n; i++)
160*0a6a1f1dSLionel Sambuc f->p[i] = NULL;
161*0a6a1f1dSLionel Sambuc for (i = 0; i < n; i++) {
162*0a6a1f1dSLionel Sambuc f->p[i] = luaF_newproto(S->L);
163*0a6a1f1dSLionel Sambuc LoadFunction(S, f->p[i], f->source);
164*0a6a1f1dSLionel Sambuc }
165*0a6a1f1dSLionel Sambuc }
166*0a6a1f1dSLionel Sambuc
167*0a6a1f1dSLionel Sambuc
LoadUpvalues(LoadState * S,Proto * f)168*0a6a1f1dSLionel Sambuc static void LoadUpvalues (LoadState *S, Proto *f) {
169*0a6a1f1dSLionel Sambuc int i, n;
170*0a6a1f1dSLionel Sambuc n = LoadInt(S);
171*0a6a1f1dSLionel Sambuc f->upvalues = luaM_newvector(S->L, n, Upvaldesc);
172*0a6a1f1dSLionel Sambuc f->sizeupvalues = n;
173*0a6a1f1dSLionel Sambuc for (i = 0; i < n; i++)
174*0a6a1f1dSLionel Sambuc f->upvalues[i].name = NULL;
175*0a6a1f1dSLionel Sambuc for (i = 0; i < n; i++) {
176*0a6a1f1dSLionel Sambuc f->upvalues[i].instack = LoadByte(S);
177*0a6a1f1dSLionel Sambuc f->upvalues[i].idx = LoadByte(S);
178*0a6a1f1dSLionel Sambuc }
179*0a6a1f1dSLionel Sambuc }
180*0a6a1f1dSLionel Sambuc
181*0a6a1f1dSLionel Sambuc
LoadDebug(LoadState * S,Proto * f)182*0a6a1f1dSLionel Sambuc static void LoadDebug (LoadState *S, Proto *f) {
18311be35a1SLionel Sambuc int i, n;
18411be35a1SLionel Sambuc n = LoadInt(S);
18511be35a1SLionel Sambuc f->lineinfo = luaM_newvector(S->L, n, int);
18611be35a1SLionel Sambuc f->sizelineinfo = n;
187*0a6a1f1dSLionel Sambuc LoadVector(S, f->lineinfo, n);
18811be35a1SLionel Sambuc n = LoadInt(S);
18911be35a1SLionel Sambuc f->locvars = luaM_newvector(S->L, n, LocVar);
19011be35a1SLionel Sambuc f->sizelocvars = n;
19111be35a1SLionel Sambuc for (i = 0; i < n; i++)
192*0a6a1f1dSLionel Sambuc f->locvars[i].varname = NULL;
193*0a6a1f1dSLionel Sambuc for (i = 0; i < n; i++) {
19411be35a1SLionel Sambuc f->locvars[i].varname = LoadString(S);
19511be35a1SLionel Sambuc f->locvars[i].startpc = LoadInt(S);
19611be35a1SLionel Sambuc f->locvars[i].endpc = LoadInt(S);
19711be35a1SLionel Sambuc }
19811be35a1SLionel Sambuc n = LoadInt(S);
199*0a6a1f1dSLionel Sambuc for (i = 0; i < n; i++)
200*0a6a1f1dSLionel Sambuc f->upvalues[i].name = LoadString(S);
20111be35a1SLionel Sambuc }
20211be35a1SLionel Sambuc
203*0a6a1f1dSLionel Sambuc
LoadFunction(LoadState * S,Proto * f,TString * psource)204*0a6a1f1dSLionel Sambuc static void LoadFunction (LoadState *S, Proto *f, TString *psource) {
205*0a6a1f1dSLionel Sambuc f->source = LoadString(S);
206*0a6a1f1dSLionel Sambuc if (f->source == NULL) /* no source in dump? */
207*0a6a1f1dSLionel Sambuc f->source = psource; /* reuse parent's source */
20811be35a1SLionel Sambuc f->linedefined = LoadInt(S);
20911be35a1SLionel Sambuc f->lastlinedefined = LoadInt(S);
21011be35a1SLionel Sambuc f->numparams = LoadByte(S);
21111be35a1SLionel Sambuc f->is_vararg = LoadByte(S);
21211be35a1SLionel Sambuc f->maxstacksize = LoadByte(S);
21311be35a1SLionel Sambuc LoadCode(S, f);
21411be35a1SLionel Sambuc LoadConstants(S, f);
215*0a6a1f1dSLionel Sambuc LoadUpvalues(S, f);
216*0a6a1f1dSLionel Sambuc LoadProtos(S, f);
21711be35a1SLionel Sambuc LoadDebug(S, f);
21811be35a1SLionel Sambuc }
21911be35a1SLionel Sambuc
220*0a6a1f1dSLionel Sambuc
checkliteral(LoadState * S,const char * s,const char * msg)221*0a6a1f1dSLionel Sambuc static void checkliteral (LoadState *S, const char *s, const char *msg) {
222*0a6a1f1dSLionel Sambuc char buff[sizeof(LUA_SIGNATURE) + sizeof(LUAC_DATA)]; /* larger than both */
223*0a6a1f1dSLionel Sambuc size_t len = strlen(s);
224*0a6a1f1dSLionel Sambuc LoadVector(S, buff, len);
225*0a6a1f1dSLionel Sambuc if (memcmp(s, buff, len) != 0)
226*0a6a1f1dSLionel Sambuc error(S, msg);
22711be35a1SLionel Sambuc }
22811be35a1SLionel Sambuc
229*0a6a1f1dSLionel Sambuc
fchecksize(LoadState * S,size_t size,const char * tname)230*0a6a1f1dSLionel Sambuc static void fchecksize (LoadState *S, size_t size, const char *tname) {
231*0a6a1f1dSLionel Sambuc if (LoadByte(S) != size)
232*0a6a1f1dSLionel Sambuc error(S, luaO_pushfstring(S->L, "%s size mismatch in", tname));
233*0a6a1f1dSLionel Sambuc }
234*0a6a1f1dSLionel Sambuc
235*0a6a1f1dSLionel Sambuc
236*0a6a1f1dSLionel Sambuc #define checksize(S,t) fchecksize(S,sizeof(t),#t)
237*0a6a1f1dSLionel Sambuc
checkHeader(LoadState * S)238*0a6a1f1dSLionel Sambuc static void checkHeader (LoadState *S) {
239*0a6a1f1dSLionel Sambuc checkliteral(S, LUA_SIGNATURE + 1, "not a"); /* 1st char already checked */
240*0a6a1f1dSLionel Sambuc if (LoadByte(S) != LUAC_VERSION)
241*0a6a1f1dSLionel Sambuc error(S, "version mismatch in");
242*0a6a1f1dSLionel Sambuc if (LoadByte(S) != LUAC_FORMAT)
243*0a6a1f1dSLionel Sambuc error(S, "format mismatch in");
244*0a6a1f1dSLionel Sambuc checkliteral(S, LUAC_DATA, "corrupted");
245*0a6a1f1dSLionel Sambuc checksize(S, int);
246*0a6a1f1dSLionel Sambuc checksize(S, size_t);
247*0a6a1f1dSLionel Sambuc checksize(S, Instruction);
248*0a6a1f1dSLionel Sambuc checksize(S, lua_Integer);
249*0a6a1f1dSLionel Sambuc checksize(S, lua_Number);
250*0a6a1f1dSLionel Sambuc if (LoadInteger(S) != LUAC_INT)
251*0a6a1f1dSLionel Sambuc error(S, "endianness mismatch in");
252*0a6a1f1dSLionel Sambuc if (LoadNumber(S) != LUAC_NUM)
253*0a6a1f1dSLionel Sambuc error(S, "float format mismatch in");
254*0a6a1f1dSLionel Sambuc }
255*0a6a1f1dSLionel Sambuc
256*0a6a1f1dSLionel Sambuc
25711be35a1SLionel Sambuc /*
25811be35a1SLionel Sambuc ** load precompiled chunk
25911be35a1SLionel Sambuc */
luaU_undump(lua_State * L,ZIO * Z,Mbuffer * buff,const char * name)260*0a6a1f1dSLionel Sambuc LClosure *luaU_undump(lua_State *L, ZIO *Z, Mbuffer *buff,
261*0a6a1f1dSLionel Sambuc const char *name) {
26211be35a1SLionel Sambuc LoadState S;
263*0a6a1f1dSLionel Sambuc LClosure *cl;
26411be35a1SLionel Sambuc if (*name == '@' || *name == '=')
26511be35a1SLionel Sambuc S.name = name + 1;
26611be35a1SLionel Sambuc else if (*name == LUA_SIGNATURE[0])
26711be35a1SLionel Sambuc S.name = "binary string";
26811be35a1SLionel Sambuc else
26911be35a1SLionel Sambuc S.name = name;
27011be35a1SLionel Sambuc S.L = L;
27111be35a1SLionel Sambuc S.Z = Z;
27211be35a1SLionel Sambuc S.b = buff;
273*0a6a1f1dSLionel Sambuc checkHeader(&S);
274*0a6a1f1dSLionel Sambuc cl = luaF_newLclosure(L, LoadByte(&S));
275*0a6a1f1dSLionel Sambuc setclLvalue(L, L->top, cl);
276*0a6a1f1dSLionel Sambuc incr_top(L);
277*0a6a1f1dSLionel Sambuc cl->p = luaF_newproto(L);
278*0a6a1f1dSLionel Sambuc LoadFunction(&S, cl->p, NULL);
279*0a6a1f1dSLionel Sambuc lua_assert(cl->nupvalues == cl->p->sizeupvalues);
280*0a6a1f1dSLionel Sambuc luai_verifycode(L, buff, cl->p);
281*0a6a1f1dSLionel Sambuc return cl;
28211be35a1SLionel Sambuc }
28311be35a1SLionel Sambuc
284