Support stripping debug info in Lua 5.1 luac_cross

This commit is contained in:
Johny Mattsson 2021-08-25 13:45:49 +10:00
parent dba57fa0ea
commit cd585ae91c
1 changed files with 37 additions and 14 deletions

View File

@ -181,23 +181,26 @@ static void addTS(lua_State *L, TString *ts) {
* Enumerate all of the Protos in the Proto hiearchy and scan contents to collect
* all referenced strings in a Lua Array at ToS.
*/
static void scanProtoStrings(lua_State *L, const Proto* f) {
static void scanProtoStrings(lua_State *L, const Proto* f, int strip) {
/* Table at L->Top[-1] is used to collect the strings */
int i;
if (f->source)
addTS(L, f->source);
if (f->packedlineinfo)
if (f->packedlineinfo && !strip)
addTS(L, luaS_new(L, cast(const char *, f->packedlineinfo)));
for (i = 0; i < f->sizek; i++) {
if (ttisstring(f->k + i))
addTS(L, rawtsvalue(f->k + i));
}
for (i = 0; i < f->sizeupvalues; i++) addTS(L, f->upvalues[i]);
for (i = 0; i < f->sizelocvars; i++) addTS(L, f->locvars[i].varname);
for (i = 0; i < f->sizep; i++) scanProtoStrings(L, f->p[i]);
if (!strip)
{
for (i = 0; i < f->sizeupvalues; i++) addTS(L, f->upvalues[i]);
for (i = 0; i < f->sizelocvars; i++) addTS(L, f->locvars[i].varname);
}
for (i = 0; i < f->sizep; i++) scanProtoStrings(L, f->p[i], strip);
}
@ -218,7 +221,10 @@ static void createROstrt(lua_State *L, FlashHeader *fh) {
DBG_PRINT("Found: %s\n",getstr(rawtsvalue(L->top-2)));
lua_pop(L, 1); // dump the value
}
fh->nROsize = 2<<luaO_log2(fh->nROuse);
// Ensure at least 30% overprovisioning, to reduce pathological chaining if nROuse is just under a power of 2
fh->nROsize = 2<<luaO_log2((int)((double)fh->nROuse*1.3));
DBG_PRINT("nROsize=%u, nROuse=%u\n",(unsigned)fh->nROsize,(unsigned)fh->nROuse);
FlashAddr *hashTab = flashAlloc(L, fh->nROsize * WORDSIZE);
toFlashAddr(L, fh->pROhash, hashTab);
@ -354,13 +360,23 @@ static void *flashCopy(lua_State* L, int n, const char *fmt, void *src) {
return dest;
}
static void stripdebug (Proto *f) {
// Yes, this is leaking memory. In the cross compiler, that's *host* memory, and we don't care.
// It's more hassle than it's worth to stop it from doing so.
f->packedlineinfo = NULL;
f->locvars = NULL;
f->upvalues = NULL;
f->sizelocvars = 0;
f->sizeupvalues = 0;
}
/* The debug optimised version has a different Proto layout */
#define PROTO_COPY_MASK "AHAAAAAASIIIIIIIAI"
/*
* Do the actual prototype copy.
*/
static void *functionToFlash(lua_State* L, const Proto* orig) {
static void *functionToFlash(lua_State* L, const Proto* orig, int strip) {
Proto f;
int i;
@ -372,36 +388,43 @@ static void *functionToFlash(lua_State* L, const Proto* orig) {
if (f.sizep) { /* clone included Protos */
Proto **p = luaM_newvector(L, f.sizep, Proto *);
for (i=0; i<f.sizep; i++)
p[i] = cast(Proto *, functionToFlash(L, f.p[i]));
p[i] = cast(Proto *, functionToFlash(L, f.p[i], strip));
f.p = cast(Proto **, flashCopy(L, f.sizep, "A", p));
luaM_freearray(L, p, f.sizep, Proto *);
}
f.k = cast(TValue *, flashCopy(L, f.sizek, "V", f.k));
f.code = cast(Instruction *, flashCopy(L, f.sizecode, "I", f.code));
if (strip)
stripdebug(&f);
if (f.packedlineinfo) {
TString *ts=luaS_new(L, cast(const char *,f.packedlineinfo));
f.packedlineinfo = cast(unsigned char *, resolveTString(L, ts)) + sizeof (FlashTS);
}
f.locvars = cast(struct LocVar *, flashCopy(L, f.sizelocvars, "SII", f.locvars));
f.upvalues = cast(TString **, flashCopy(L, f.sizeupvalues, "S", f.upvalues));
if (!strip)
{
f.locvars = cast(struct LocVar *, flashCopy(L, f.sizelocvars, "SII", f.locvars));
f.upvalues = cast(TString **, flashCopy(L, f.sizeupvalues, "S", f.upvalues));
}
return cast(void *, flashCopy(L, 1, PROTO_COPY_MASK, &f));
}
uint dumpToFlashImage (lua_State* L, const Proto *main, lua_Writer w,
void* data, int strip,
lu_int32 address, lu_int32 maxSize) {
// parameter strip is ignored for now
(void)strip;
FlashHeader *fh = cast(FlashHeader *, flashAlloc(L, sizeof(FlashHeader)));
int i, status;
lua_newtable(L);
scanProtoStrings(L, main);
scanProtoStrings(L, main, strip);
createROstrt(L, fh);
toFlashAddr(L, fh->mainProto, functionToFlash(L, main));
toFlashAddr(L, fh->mainProto, functionToFlash(L, main, strip));
fh->flash_sig = FLASH_SIG + (address ? FLASH_SIG_ABSOLUTE : 0);
fh->flash_size = curOffset*WORDSIZE;
printf("Flash image size: %u bytes (%.2fkiB, %.1f%% of available size of %ukiB)\n",
+ (unsigned)fh->flash_size,(double)fh->flash_size/1024.0,(double)fh->flash_size/(double)maxSize*100.0,(unsigned)(maxSize>>10));
if (fh->flash_size>maxSize) {
fatal ("The image is too large for specfied LFS size");
}