Skip to content

Commit f9bfc9e

Browse files
committed
basic sanity checks before attempting restore a new module from a cache file
1 parent 78962ae commit f9bfc9e

File tree

1 file changed

+75
-6
lines changed

1 file changed

+75
-6
lines changed

src/dump.c

Lines changed: 75 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ static jl_array_t *datatype_list=NULL; // (only used in MODE_SYSTEM_IMAGE)
113113
#define read_uint8(s) ((uint8_t)ios_getc(s))
114114
#define write_int8(s, n) write_uint8(s, n)
115115
#define read_int8(s) read_uint8(s)
116+
116117
static void write_int32(ios_t *s, int32_t i)
117118
{
118119
write_uint8(s, i & 0xff);
@@ -130,6 +131,19 @@ static int32_t read_int32(ios_t *s)
130131
return b0 | (b1<<8) | (b2<<16) | (b3<<24);
131132
}
132133

134+
static void write_uint64(ios_t *s, uint64_t i)
135+
{
136+
write_int32(s, i & 0xffffffff);
137+
write_int32(s, (i>>32) & 0xffffffff);
138+
}
139+
140+
static uint64_t read_uint64(ios_t *s)
141+
{
142+
uint64_t b0 = (uint32_t)read_int32(s);
143+
uint64_t b1 = (uint32_t)read_int32(s);
144+
return b0 | (b1<<32);
145+
}
146+
133147
static void write_uint16(ios_t *s, uint16_t i)
134148
{
135149
write_uint8(s, i & 0xff);
@@ -486,8 +500,7 @@ static void jl_serialize_module(ios_t *s, jl_module_t *m)
486500
}
487501
}
488502
jl_serialize_value(s, m->constant_table);
489-
write_int32(s, (uint32_t)m->uuid);
490-
write_int32(s, (uint32_t)(m->uuid>>32));
503+
write_uint64(s, m->uuid);
491504
}
492505

493506
static int is_ast_node(jl_value_t *v)
@@ -823,6 +836,32 @@ void jl_serialize_lambdas_from_mod(ios_t *s, jl_module_t *m)
823836
}
824837
}
825838

839+
void jl_serialize_mod_list(ios_t *s)
840+
{
841+
jl_module_t *m = jl_main_module;
842+
size_t i;
843+
void **table = m->bindings.table;
844+
for(i=1; i < m->bindings.size; i+=2) {
845+
if (table[i] != HT_NOTFOUND) {
846+
jl_binding_t *b = (jl_binding_t*)table[i];
847+
if (b->owner == m &&
848+
b->value &&
849+
b->value != (jl_value_t*)jl_current_module &&
850+
jl_is_module(b->value)) {
851+
jl_module_t *child = (jl_module_t*)b->value;
852+
if (child->name == b->name) {
853+
// this is the original/primary binding for the submodule
854+
size_t l = strlen(child->name->name);
855+
write_int32(s, l);
856+
ios_write(s, child->name->name, l);
857+
write_uint64(s, child->uuid);
858+
}
859+
}
860+
}
861+
}
862+
write_int32(s, 0);
863+
}
864+
826865
// --- deserialize ---
827866

828867
static jl_fptr_t jl_deserialize_fptr(ios_t *s)
@@ -1165,8 +1204,7 @@ static jl_value_t *jl_deserialize_value_(ios_t *s, jl_value_t *vtag, jl_value_t
11651204
i++;
11661205
}
11671206
m->constant_table = (jl_array_t*)jl_deserialize_value(s, (jl_value_t**)&m->constant_table);
1168-
m->uuid = read_int32(s);
1169-
m->uuid |= ((uint64_t)read_int32(s))<<32;
1207+
m->uuid = read_uint64(s);
11701208
return (jl_value_t*)m;
11711209
}
11721210
else if (vtag == (jl_value_t*)SmallInt64_tag) {
@@ -1305,6 +1343,32 @@ void jl_deserialize_lambdas_from_mod(ios_t *s)
13051343
}
13061344
}
13071345

1346+
int jl_deserialize_verify_mod_list(ios_t *s)
1347+
{
1348+
while (1) {
1349+
size_t len = read_int32(s);
1350+
if (len == 0)
1351+
return 1;
1352+
char *name = (char*)alloca(len+1);
1353+
ios_read(s, name, len);
1354+
name[len] = '\0';
1355+
uint64_t uuid = read_uint64(s);
1356+
jl_module_t *m = (jl_module_t*)jl_get_global(jl_main_module, jl_symbol(name));
1357+
if (!m) {
1358+
JL_PRINTF(JL_STDERR, "Module %s must be loaded first\n", name);
1359+
return 0;
1360+
}
1361+
if (!jl_is_module(m)) {
1362+
ios_close(s);
1363+
jl_errorf("typeassert: expected %s::Module", name);
1364+
}
1365+
if (m->uuid != uuid) {
1366+
JL_PRINTF(JL_STDERR, "Module %s uuid did not match cache file\n", name);
1367+
return 0;
1368+
}
1369+
}
1370+
}
1371+
13081372
// --- entry points ---
13091373

13101374
extern jl_array_t *jl_module_init_order;
@@ -1554,6 +1618,9 @@ int jl_save_new_module(char *fname, jl_module_t *mod)
15541618
JL_PRINTF(JL_STDERR, "Cannot open cache file \"%s\" for writing.\n", fname);
15551619
return 1;
15561620
}
1621+
jl_module_t *lastmod = jl_current_module;
1622+
jl_current_module = mod;
1623+
jl_serialize_mod_list(&f);
15571624
htable_new(&backref_table, 5000);
15581625
ptrhash_put(&backref_table, jl_main_module, (void*)(uintptr_t)0);
15591626

@@ -1562,8 +1629,6 @@ int jl_save_new_module(char *fname, jl_module_t *mod)
15621629
jl_gc_ephemeral_on();
15631630
DUMP_MODES last_mode = mode;
15641631
mode = MODE_MODULE;
1565-
jl_module_t *lastmod = jl_current_module;
1566-
jl_current_module = mod;
15671632
jl_serialize_value(&f, mod->parent);
15681633
jl_serialize_value(&f, mod->name);
15691634
jl_serialize_value(&f, mod);
@@ -1598,6 +1663,10 @@ jl_module_t *jl_restore_new_module(char *fname)
15981663
ios_close(&f);
15991664
return NULL;
16001665
}
1666+
if (!jl_deserialize_verify_mod_list(&f)) {
1667+
ios_close(&f);
1668+
return NULL;
1669+
}
16011670
arraylist_new(&backref_list, 4000);
16021671
arraylist_push(&backref_list, jl_main_module);
16031672
arraylist_new(&flagref_list, 0);

0 commit comments

Comments
 (0)