void os_link_runtime() { lispobj head; void *link_target = (void*)(intptr_t)LINKAGE_TABLE_SPACE_START; void *validated_end = link_target; lispobj symbol_name; char *namechars; boolean datap; void* result; int strict /* If in a cold core, fail early and often. */ = (SymbolValue(GC_INHIBIT, 0) & WIDETAG_MASK) == UNBOUND_MARKER_WIDETAG; int n = 0, m = 0; for (head = SymbolValue(REQUIRED_RUNTIME_C_SYMBOLS,0); head!=NIL; head = cdr(head), n++) { lispobj item = car(head); symbol_name = car(item); datap = (NIL!=(cdr(item))); namechars = (void*)(intptr_t)FOTHERPTR(symbol_name,vector).data; result = os_dlsym_default(namechars); odxprint(runtime_link, "linking %s => %p", namechars, result); if (link_target == validated_end) { validated_end += os_vm_page_size; #ifdef LISP_FEATURE_WIN32 os_validate_recommit(link_target,os_vm_page_size); #endif } if (result) { if (datap) arch_write_linkage_table_ref(link_target,result); else arch_write_linkage_table_jmp(link_target,result); } else { m++; if (strict) fprintf(stderr, "undefined foreign symbol in cold init: %s\n", namechars); } link_target = (void*)(((uintptr_t)link_target)+LINKAGE_TABLE_ENTRY_SIZE); } odxprint(runtime_link, "%d total symbols linked, %d undefined", n, m); if (strict && m) /* We could proceed, but rather than run into improperly * displayed internal errors, let's make ourselves heard right * here and now. */ lose("Undefined aliens in cold init."); }
void os_link_runtime() { #ifdef LISP_FEATURE_SB_DYNAMIC_CORE char *link_target = (char*)(intptr_t)LINKAGE_TABLE_SPACE_START; void *validated_end = link_target; lispobj symbol_name; char *namechars; boolean datap; void* result; int j; if (lisp_linkage_table_n_prelinked) return; // Linkage was already performed by coreparse struct vector* symbols = VECTOR(SymbolValue(REQUIRED_FOREIGN_SYMBOLS,0)); lisp_linkage_table_n_prelinked = fixnum_value(symbols->length); for (j = 0 ; j < lisp_linkage_table_n_prelinked ; ++j) { lispobj item = symbols->data[j]; datap = listp(item); symbol_name = datap ? CONS(item)->car : item; namechars = (void*)(intptr_t)(VECTOR(symbol_name)->data); result = os_dlsym_default(namechars); if (link_target == validated_end) { validated_end = (char*)validated_end + os_vm_page_size; #ifdef LISP_FEATURE_WIN32 os_validate_recommit(link_target,os_vm_page_size); #endif } if (result) { arch_write_linkage_table_entry(link_target, result, datap); } else { // startup might or might not work. ymmv printf("Missing required foreign symbol '%s'\n", namechars); } link_target += LINKAGE_TABLE_ENTRY_SIZE; } #endif /* LISP_FEATURE_SB_DYNAMIC_CORE */ #ifdef LISP_FEATURE_X86_64 SetSymbolValue(CPUID_FN1_ECX, (lispobj)make_fixnum(cpuid_fn1_ecx), 0); #endif }
os_vm_address_t inflate_core_bytes(int fd, os_vm_offset_t offset, os_vm_address_t addr, int len) { z_stream stream; unsigned char buf[ZLIB_BUFFER_SIZE]; int ret; # ifdef LISP_FEATURE_WIN32 /* Ensure the memory is committed so zlib doesn't segfault trying to inflate. */ os_validate_recommit(addr, len); # endif if (-1 == lseek(fd, offset, SEEK_SET)) { lose("Unable to lseek() on corefile\n"); } stream.zalloc = NULL; stream.zfree = NULL; stream.opaque = NULL; stream.avail_in = 0; stream.next_in = buf; ret = inflateInit(&stream); if (ret != Z_OK) lose("zlib error %i\n", ret); stream.next_out = (void*)addr; stream.avail_out = len; do { ssize_t count = read(fd, buf, sizeof(buf)); if (count < 0) lose("unable to read core file (errno = %i)\n", errno); stream.next_in = buf; stream.avail_in = count; if (count == 0) break; ret = inflate(&stream, Z_NO_FLUSH); switch (ret) { case Z_STREAM_END: break; case Z_OK: if (stream.avail_out == 0) lose("Runaway gzipped core directory... aborting\n"); if (stream.avail_in > 0) lose("zlib inflate returned without fully" "using up input buffer... aborting\n"); break; default: lose("zlib inflate error: %i\n", ret); break; } } while (ret != Z_STREAM_END); if (stream.avail_out > 0) { if (stream.avail_out >= os_vm_page_size) fprintf(stderr, "Warning: gzipped core directory significantly" "shorter than expected (%lu bytes)", (unsigned long)stream.avail_out); /* Is this needed? */ memset(stream.next_out, 0, stream.avail_out); } inflateEnd(&stream); return addr; }