Esempio n. 1
0
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
}
Esempio n. 2
0
static void
process_directory(int fd, lispobj *ptr, int count, os_vm_offset_t file_offset)
{
    extern void immobile_space_coreparse(uword_t,uword_t);
    struct ndir_entry *entry;
    int compressed;

    FSHOW((stderr, "/process_directory(..), count=%d\n", count));

    for (entry = (struct ndir_entry *) ptr; --count>= 0; ++entry) {

        compressed = 0;
        sword_t id = entry->identifier;
        if (id <= (MAX_CORE_SPACE_ID | DEFLATED_CORE_SPACE_ID_FLAG)) {
            if (id & DEFLATED_CORE_SPACE_ID_FLAG)
                compressed = 1;
            id &= ~(DEFLATED_CORE_SPACE_ID_FLAG);
        }
        sword_t offset = os_vm_page_size * (1 + entry->data_page);
        os_vm_address_t addr =
            (os_vm_address_t) (os_vm_page_size * entry->address);
        lispobj *free_pointer = (lispobj *) addr + entry->nwords;
        uword_t len = os_vm_page_size * entry->page_count;
        if (len != 0) {
            os_vm_address_t real_addr;
            FSHOW((stderr, "/mapping %ld(0x%lx) bytes at 0x%lx\n",
                   len, len, (uword_t)addr));
            if (compressed) {
#ifdef LISP_FEATURE_SB_CORE_COMPRESSION
                real_addr = inflate_core_bytes(fd, offset + file_offset, addr, len);
#else
                lose("This runtime was not built with zlib-compressed core support... aborting\n");
#endif
            } else {
#ifdef LISP_FEATURE_HPUX
                real_addr = copy_core_bytes(fd, offset + file_offset, addr, len);
#else
                real_addr = os_map(fd, offset + file_offset, addr, len);
#endif
            }
            if (real_addr != addr) {
                lose("file mapped in wrong place! "
                     "(0x%08x != 0x%08lx)\n",
                     real_addr,
                     addr);
            }
        }

#ifdef MADV_MERGEABLE
        if ((merge_core_pages == 1)
            || ((merge_core_pages == -1) && compressed)) {
                madvise(addr, len, MADV_MERGEABLE);
        }
#endif
        FSHOW((stderr, "/space id = %ld, free pointer = %p\n",
               id, (uword_t)free_pointer));

        switch (id) {
        case DYNAMIC_CORE_SPACE_ID:
            if (len > dynamic_space_size) {
                fprintf(stderr,
                        "dynamic space too small for core: %luKiB required, %luKiB available.\n",
                        (unsigned long)len >> 10,
                        (unsigned long)dynamic_space_size >> 10);
                exit(1);
            }
#ifdef LISP_FEATURE_GENCGC
            if (addr != (os_vm_address_t)DYNAMIC_SPACE_START) {
                fprintf(stderr, "in core: %p; in runtime: %p \n",
                        (void*)addr, (void*)DYNAMIC_SPACE_START);
                lose("core/runtime address mismatch: DYNAMIC_SPACE_START\n");
            }
#else
            if ((addr != (os_vm_address_t)DYNAMIC_0_SPACE_START) &&
                (addr != (os_vm_address_t)DYNAMIC_1_SPACE_START)) {
                fprintf(stderr, "in core: %p; in runtime: %p or %p\n",
                        (void*)addr,
                        (void*)DYNAMIC_0_SPACE_START,
                        (void*)DYNAMIC_1_SPACE_START);
                lose("warning: core/runtime address mismatch: DYNAMIC_SPACE_START\n");
            }
#endif
#if defined(ALLOCATION_POINTER)
            SetSymbolValue(ALLOCATION_POINTER, (lispobj)free_pointer,0);
#else
            dynamic_space_free_pointer = free_pointer;
#endif
            /* For stop-and-copy GC, this will be whatever the GC was
             * using at the time. With GENCGC, this will always be
             * space 0. (We checked above that for GENCGC,
             * addr==DYNAMIC_SPACE_START.) */
            current_dynamic_space = (lispobj *)addr;
            break;
        case STATIC_CORE_SPACE_ID:
            if (addr != (os_vm_address_t)STATIC_SPACE_START) {
                fprintf(stderr, "in core: %p - in runtime: %p\n",
                        (void*)addr, (void*)STATIC_SPACE_START);
                lose("core/runtime address mismatch: STATIC_SPACE_START\n");
            }
            break;
        case READ_ONLY_CORE_SPACE_ID:
            if (addr != (os_vm_address_t)READ_ONLY_SPACE_START) {
                fprintf(stderr, "in core: %p - in runtime: %p\n",
                        (void*)addr, (void*)READ_ONLY_SPACE_START);
                lose("core/runtime address mismatch: READ_ONLY_SPACE_START\n");
            }
            break;
#ifdef LISP_FEATURE_IMMOBILE_SPACE
         // Immobile space is subdivided into fixed-size and variable-size.
         // There is no margin between the two, though for efficiency
         // they are written separately to eliminate waste in the core file.
        case IMMOBILE_FIXEDOBJ_CORE_SPACE_ID:
            if (addr != (os_vm_address_t)IMMOBILE_SPACE_START) {
                fprintf(stderr, "in core: %p - in runtime: %p\n",
                        (void*)addr, (void*)IMMOBILE_SPACE_START);
                lose("core/runtime address mismatch: IMMOBILE_SPACE_START\n");
            }
            immobile_space_coreparse(IMMOBILE_SPACE_START, len);
            break;
        case IMMOBILE_VARYOBJ_CORE_SPACE_ID:
            if (addr != (os_vm_address_t)IMMOBILE_VARYOBJ_SUBSPACE_START) {
                fprintf(stderr, "in core: %p - in runtime: %p\n",
                        (void*)addr, (void*)IMMOBILE_VARYOBJ_SUBSPACE_START);
                lose("core/runtime address mismatch: IMMOBILE_VARYOBJ_SUBSPACE_START\n");
            }
            immobile_space_coreparse(IMMOBILE_VARYOBJ_SUBSPACE_START, len);
            break;
#endif
        default:
            lose("unknown space ID %ld addr %p\n", id, addr);
        }
    }
Esempio n. 3
0
boolean
save_to_filehandle(FILE *file, char *filename, lispobj init_function,
                   boolean make_executable,
                   boolean save_runtime_options,
                   int core_compression_level)
{
    struct thread *th;
    os_vm_offset_t core_start_pos;

#ifdef LISP_FEATURE_X86_64
    untune_asm_routines_for_microarch();
#endif

    /* Smash the enclosing state. (Once we do this, there's no good
     * way to go back, which is a sufficient reason that this ends up
     * being SAVE-LISP-AND-DIE instead of SAVE-LISP-AND-GO-ON). */
    printf("[undoing binding stack and other enclosing state... ");
    fflush(stdout);
    for_each_thread(th) {       /* XXX really? */
        unbind_to_here((lispobj *)th->binding_stack_start,th);
        SetSymbolValue(CURRENT_CATCH_BLOCK, 0,th);
        SetSymbolValue(CURRENT_UNWIND_PROTECT_BLOCK, 0,th);
    }
    printf("done]\n");
    fflush(stdout);

    /* (Now we can actually start copying ourselves into the output file.) */

    printf("[saving current Lisp image into %s:\n", filename);
    fflush(stdout);

    core_start_pos = ftell(file);
    write_lispobj(CORE_MAGIC, file);

    write_lispobj(BUILD_ID_CORE_ENTRY_TYPE_CODE, file);
    write_lispobj(/* (We're writing the word count of the entry here, and the 2
          * term is one word for the leading BUILD_ID_CORE_ENTRY_TYPE_CODE
          * word and one word where we store the count itself.) */
         2 + strlen((const char *)build_id),
         file);
    {
        unsigned char *p;
        for (p = (unsigned char *)build_id; *p; ++p)
            write_lispobj(*p, file);
    }

    write_lispobj(NEW_DIRECTORY_CORE_ENTRY_TYPE_CODE, file);
    write_lispobj(/* (word count = N spaces described by 5 words each, plus the
          * entry type code, plus this count itself) */
         (5*N_SPACES_TO_SAVE)+2, file);
    output_space(file,
                 READ_ONLY_CORE_SPACE_ID,
                 (lispobj *)READ_ONLY_SPACE_START,
                 (lispobj *)SymbolValue(READ_ONLY_SPACE_FREE_POINTER,0),
                 core_start_pos,
                 core_compression_level);
    output_space(file,
                 STATIC_CORE_SPACE_ID,
                 (lispobj *)STATIC_SPACE_START,
                 (lispobj *)SymbolValue(STATIC_SPACE_FREE_POINTER,0),
                 core_start_pos,
                 core_compression_level);
#ifdef LISP_FEATURE_GENCGC
    /* Flush the current_region, updating the tables. */
    gc_alloc_update_all_page_tables(1);
    update_dynamic_space_free_pointer();
#endif
#ifdef LISP_FEATURE_IMMOBILE_SPACE
    prepare_immobile_space_for_save();
    output_space(file,
                 IMMOBILE_FIXEDOBJ_CORE_SPACE_ID,
                 (lispobj *)IMMOBILE_SPACE_START,
                 (lispobj *)SymbolValue(IMMOBILE_FIXEDOBJ_FREE_POINTER,0),
                 core_start_pos,
                 core_compression_level);
    output_space(file,
                 IMMOBILE_VARYOBJ_CORE_SPACE_ID,
                 (lispobj *)IMMOBILE_VARYOBJ_SUBSPACE_START,
                 (lispobj *)SymbolValue(IMMOBILE_SPACE_FREE_POINTER,0),
                 core_start_pos,
                 core_compression_level);
#endif
#ifdef reg_ALLOC
#ifdef LISP_FEATURE_GENCGC
    output_space(file,
                 DYNAMIC_CORE_SPACE_ID,
                 (lispobj *)DYNAMIC_SPACE_START,
                 dynamic_space_free_pointer,
                 core_start_pos,
                 core_compression_level);
#else
    output_space(file,
                 DYNAMIC_CORE_SPACE_ID,
                 (lispobj *)current_dynamic_space,
                 dynamic_space_free_pointer,
                 core_start_pos,
                 core_compression_level);
#endif
#else
    output_space(file,
                 DYNAMIC_CORE_SPACE_ID,
                 (lispobj *)DYNAMIC_SPACE_START,
                 (lispobj *)SymbolValue(ALLOCATION_POINTER,0),
                 core_start_pos,
                 core_compression_level);
#endif

    write_lispobj(INITIAL_FUN_CORE_ENTRY_TYPE_CODE, file);
    write_lispobj(3, file);
    write_lispobj(init_function, file);

#ifdef LISP_FEATURE_GENCGC
    {
        size_t size = (last_free_page*sizeof(sword_t)+os_vm_page_size-1)
            &~(os_vm_page_size-1);
        uword_t *data = calloc(size, 1);
        if (data) {
            uword_t word;
            sword_t offset;
            page_index_t i;
            for (i = 0; i < last_free_page; i++) {
                /* Thanks to alignment requirements, the two low bits
                 * are always zero, so we can use them to store the
                 * allocation type -- region is always closed, so only
                 * the two low bits of allocation flags matter. */
                word = page_table[i].scan_start_offset;
                gc_assert((word & 0x03) == 0);
                data[i] = word | (0x03 & page_table[i].allocated);
            }
            write_lispobj(PAGE_TABLE_CORE_ENTRY_TYPE_CODE, file);
            write_lispobj(4, file);
            write_lispobj(size, file);
            offset = write_bytes(file, (char *)data, size, core_start_pos);
            write_lispobj(offset, file);
        }
    }
#endif

    write_lispobj(END_CORE_ENTRY_TYPE_CODE, file);

    /* Write a trailing header, ignored when parsing the core normally.
     * This is used to locate the start of the core when the runtime is
     * prepended to it. */
    fseek(file, 0, SEEK_END);

    /* If NULL runtime options are passed to write_runtime_options,
     * command-line processing is performed as normal in the SBCL
     * executable. Otherwise, the saved runtime options are used and
     * all command-line arguments are available to Lisp in
     * SB-EXT:*POSIX-ARGV*. */
    write_runtime_options(file,
                          (save_runtime_options ? runtime_options : NULL));

    if (1 != fwrite(&core_start_pos, sizeof(os_vm_offset_t), 1, file)) {
        perror("Error writing core starting position to file");
        fclose(file);
    } else {
        write_lispobj(CORE_MAGIC, file);
        fclose(file);
    }

#ifndef LISP_FEATURE_WIN32
    if (make_executable)
        chmod (filename, 0755);
#endif

    printf("done]\n");
    exit(0);
}
Esempio n. 4
0
void
arch_set_pseudo_atomic_interrupted(os_context_t * context)
{
    SetSymbolValue(PSEUDO_ATOMIC_INTERRUPTED, make_fixnum(1));
}
Esempio n. 5
0
boolean
save_to_filehandle(FILE *file, char *filename, lispobj init_function,
                   boolean make_executable,
                   boolean save_runtime_options)
{
    struct thread *th;
    os_vm_offset_t core_start_pos;

    /* Smash the enclosing state. (Once we do this, there's no good
     * way to go back, which is a sufficient reason that this ends up
     * being SAVE-LISP-AND-DIE instead of SAVE-LISP-AND-GO-ON). */
    printf("[undoing binding stack and other enclosing state... ");
    fflush(stdout);
    for_each_thread(th) {       /* XXX really? */
        unbind_to_here((lispobj *)th->binding_stack_start,th);
        SetSymbolValue(CURRENT_CATCH_BLOCK, 0,th);
        SetSymbolValue(CURRENT_UNWIND_PROTECT_BLOCK, 0,th);
    }
    printf("done]\n");
    fflush(stdout);

    /* (Now we can actually start copying ourselves into the output file.) */

    printf("[saving current Lisp image into %s:\n", filename);
    fflush(stdout);

    core_start_pos = ftell(file);
    write_lispobj(CORE_MAGIC, file);

    write_lispobj(VERSION_CORE_ENTRY_TYPE_CODE, file);
    write_lispobj(3, file);
    write_lispobj(SBCL_CORE_VERSION_INTEGER, file);

    write_lispobj(BUILD_ID_CORE_ENTRY_TYPE_CODE, file);
    write_lispobj(/* (We're writing the word count of the entry here, and the 2
          * term is one word for the leading BUILD_ID_CORE_ENTRY_TYPE_CODE
          * word and one word where we store the count itself.) */
         2 + strlen((const char *)build_id),
         file);
    {
        unsigned char *p;
        for (p = (unsigned char *)build_id; *p; ++p)
            write_lispobj(*p, file);
    }

    write_lispobj(NEW_DIRECTORY_CORE_ENTRY_TYPE_CODE, file);
    write_lispobj(/* (word count = 3 spaces described by 5 words each, plus the
          * entry type code, plus this count itself) */
         (5*3)+2, file);
    output_space(file,
                 READ_ONLY_CORE_SPACE_ID,
                 (lispobj *)READ_ONLY_SPACE_START,
                 (lispobj *)SymbolValue(READ_ONLY_SPACE_FREE_POINTER,0),
                 core_start_pos);
    output_space(file,
                 STATIC_CORE_SPACE_ID,
                 (lispobj *)STATIC_SPACE_START,
                 (lispobj *)SymbolValue(STATIC_SPACE_FREE_POINTER,0),
                 core_start_pos);
#ifdef LISP_FEATURE_GENCGC
    /* Flush the current_region, updating the tables. */
    gc_alloc_update_all_page_tables();
    update_dynamic_space_free_pointer();
#endif
#ifdef reg_ALLOC
#ifdef LISP_FEATURE_GENCGC
    output_space(file,
                 DYNAMIC_CORE_SPACE_ID,
                 (lispobj *)DYNAMIC_SPACE_START,
                 dynamic_space_free_pointer,
                 core_start_pos);
#else
    output_space(file,
                 DYNAMIC_CORE_SPACE_ID,
                 (lispobj *)current_dynamic_space,
                 dynamic_space_free_pointer,
                 core_start_pos);
#endif
#else
    output_space(file,
                 DYNAMIC_CORE_SPACE_ID,
                 (lispobj *)DYNAMIC_SPACE_START,
                 (lispobj *)SymbolValue(ALLOCATION_POINTER,0),
                 core_start_pos);
#endif

    write_lispobj(INITIAL_FUN_CORE_ENTRY_TYPE_CODE, file);
    write_lispobj(3, file);
    write_lispobj(init_function, file);

#ifdef LISP_FEATURE_GENCGC
    {
        size_t size = (last_free_page*sizeof(long)+os_vm_page_size-1)
            &~(os_vm_page_size-1);
        unsigned long *data = calloc(size, 1);
        if (data) {
            long offset;
            int i;
            for (i = 0; i < last_free_page; i++) {
                data[i] = page_table[i].region_start_offset;
            }
            write_lispobj(PAGE_TABLE_CORE_ENTRY_TYPE_CODE, file);
            write_lispobj(4, file);
            write_lispobj(size, file);
            offset = write_bytes(file, (char *) data, size, core_start_pos);
            write_lispobj(offset, file);
        }
    }
#endif

#if defined(LISP_FEATURE_SB_THREAD) && defined(LISP_FEATURE_SB_LUTEX)
    if(n_lutexes > 0) {
        long offset;
        printf("writing %ld lutexes to the core...\n", n_lutexes);
        write_lispobj(LUTEX_TABLE_CORE_ENTRY_TYPE_CODE, file);
        /* word count of the entry */
        write_lispobj(4, file);
        /* indicate how many lutexes we saved */
        write_lispobj(n_lutexes, file);
        /* save the lutexes */
        offset = write_bytes(file, (char *) lutex_addresses,
                             n_lutexes * sizeof(*lutex_addresses),
                             core_start_pos);

        write_lispobj(offset, file);
    }
#endif

    write_lispobj(END_CORE_ENTRY_TYPE_CODE, file);

    /* Write a trailing header, ignored when parsing the core normally.
     * This is used to locate the start of the core when the runtime is
     * prepended to it. */
    fseek(file, 0, SEEK_END);

    /* If NULL runtime options are passed to write_runtime_options,
     * command-line processing is performed as normal in the SBCL
     * executable. Otherwise, the saved runtime options are used and
     * all command-line arguments are available to Lisp in
     * SB-EXT:*POSIX-ARGV*. */
    write_runtime_options(file,
                          (save_runtime_options ? runtime_options : NULL));

    if (1 != fwrite(&core_start_pos, sizeof(os_vm_offset_t), 1, file)) {
        perror("Error writing core starting position to file");
        fclose(file);
    } else {
        write_lispobj(CORE_MAGIC, file);
        fclose(file);
    }

#ifndef LISP_FEATURE_WIN32
    if (make_executable)
        chmod (filename, 0755);
#endif

    printf("done]\n");
    exit(0);
}
Esempio n. 6
0
boolean
save_executable(char *filename, lispobj init_function)
{
    char *dir_name;

#if defined WANT_CGC
    volatile lispobj *func_ptr = &init_function;
    char sbuf[128];

    strcpy(sbuf, filename);
    filename = sbuf;
    /* Get rid of remnant stuff. This is a MUST so that
     * the memory manager can get started correctly when
     * we restart after this save. Purify is going to
     * maybe move the args so we need to consider them volatile,
     * especially if the gcc optimizer is working!!
     */
    purify(NIL, NIL);

    init_function = *func_ptr;
    /* Set dynamic space pointer to base value so we don't write out
     * MBs of just cleared heap.
     */
    if(SymbolValue(X86_CGC_ACTIVE_P) != NIL)
        SetSymbolValue(ALLOCATION_POINTER, DYNAMIC_0_SPACE_START);
#endif
    dir_name = dirname(strdup(filename));

    printf("[Undoing binding stack... ");
    fflush(stdout);
    unbind_to_here((lispobj *)BINDING_STACK_START);
    SetSymbolValue(CURRENT_CATCH_BLOCK, 0);
    SetSymbolValue(CURRENT_UNWIND_PROTECT_BLOCK, 0);
    SetSymbolValue(EVAL_STACK_TOP, 0);
    printf("done]\n");
#if defined WANT_CGC && defined X86_CGC_ACTIVE_P
    SetSymbolValue(X86_CGC_ACTIVE_P, T);
#endif
    printf("[Saving current lisp image as executable into \"%s\":\n", filename);

    printf("\t[Writing core objects\n");
    fflush(stdout);
    write_space_object(dir_name, READ_ONLY_SPACE_ID, (os_vm_address_t)read_only_space,
                       (os_vm_address_t)SymbolValue(READ_ONLY_SPACE_FREE_POINTER));
    write_space_object(dir_name, STATIC_SPACE_ID, (os_vm_address_t)static_space,
                       (os_vm_address_t)SymbolValue(STATIC_SPACE_FREE_POINTER));
#ifdef GENCGC
    /* Flush the current_region updating the tables. */
#ifdef DEBUG_BAD_HEAP
    fprintf(stderr, "before ALLOC_POINTER = %p\n", (lispobj *) SymbolValue(ALLOCATION_POINTER));
    dump_region(&boxed_region);
#endif
    gc_alloc_update_page_tables(0,&boxed_region);
    gc_alloc_update_page_tables(1,&unboxed_region);
#ifdef DEBUG_BAD_HEAP
    fprintf(stderr, "boxed_region after update\n");
    dump_region(&boxed_region);

    print_ptr((lispobj*) 0x2805a184);
#endif
#ifdef DEBUG_BAD_HEAP
    /*
     * For some reason x86 has a heap corruption problem.  I (rtoy)
     * have not been able to figure out how that occurs, but what is
     * happening is that when a core is loaded, there is some static
     * object pointing to an object that is on a free page.  In normal
     * usage, at startup there should be 4 objects in static space
     * pointing to a free page, because these are newly allocated
     * objects created by the C runtime.  However, there is an
     * additional object.
     *
     * I do not know what this object should be or how it got there,
     * but it will often cause CMUCL to fail to save a new core file.
     *
     * Disabling this call to update_dynamic_space_free_pointer is a
     * work around.  What is happening is that u_d_s_f_p is resetting
     * ALLOCATION_POINTER, but that weird object is in the current
     * region, but after resetting the pointer, that object isn't
     * saved to the core file.  By not resetting the pointer, the
     * object (or at least enough of it) gets saved in the core file
     * that we don't have problems when reloading.
     *
     * Note that on sparc and ppc, u_d_s_f_p doesn't actually do
     * anything because the call to reset ALLOCATION_POINTER is a nop
     * on sparc and ppc.  And sparc and ppc dont' have the heap
     * corruption issue.  That's not conclusive evidence, though.
     *
     * This needs more work and investigation.
     */
    update_dynamic_space_free_pointer();
#endif

#ifdef DEBUG_BAD_HEAP    
    fprintf(stderr, "after ALLOC_POINTER = %p\n", (lispobj *) SymbolValue(ALLOCATION_POINTER));
#endif    
#endif

#ifdef reg_ALLOC
    write_space_object(dir_name, DYNAMIC_SPACE_ID, (os_vm_address_t)current_dynamic_space,
                       (os_vm_address_t)current_dynamic_space_free_pointer);
#else
    write_space_object(dir_name, DYNAMIC_SPACE_ID, (os_vm_address_t)current_dynamic_space,
                       (os_vm_address_t)SymbolValue(ALLOCATION_POINTER));
#endif

    printf("\tdone]\n");
    fflush(stdout);
    
    printf("Linking executable...\n");
    fflush(stdout);
    obj_run_linker(init_function, filename);
    printf("done.\n");
    exit(0);
}
Esempio n. 7
0
void arch_clear_pseudo_atomic_interrupted(os_context_t *context)
{
    SetSymbolValue(PSEUDO_ATOMIC_INTERRUPTED,NIL,0);
}
Esempio n. 8
0
void arch_set_pseudo_atomic_interrupted(os_context_t *context)
{
    /* 0x000f0001 is the syscall number for BREAK_POINT. */
    SetSymbolValue(PSEUDO_ATOMIC_INTERRUPTED,MAKE_FIXNUM(0x000f0001),0);
}