Exemplo n.º 1
0
void slirp_init(int restricted, const char *special_ip)
{
#if DEBUG
    int   slirp_logmask = 0;
    char  slirp_logfile[512];
    {
        const char*  env = getenv( "ANDROID_SLIRP_LOGMASK" );
        if (env != NULL)
            slirp_logmask = atoi(env);
         else if (VERBOSE_CHECK(slirp))
            slirp_logmask = DEBUG_DEFAULT;
    }

    {
        char*  p   = slirp_logfile;
        char*  end = p + sizeof(slirp_logfile);

        p = bufprint_temp_file( p, end, "slirp.log" );
        if (p >= end) {
            dprint( "cannot create slirp log file in temporary directory" );
            slirp_logmask = 0;
        }
    }
    if (slirp_logmask) {
        dprint( "sending slirp logs with mask %x to %s", slirp_logmask, slirp_logfile );
        debug_init( slirp_logfile, slirp_logmask );
    }
#endif

    link_up = 1;
    slirp_restrict = restricted;

    if_init();
    ip_init();

    
    m_init();

    
    inet_strtoip("127.0.0.1", &loopback_addr_ip);

    if (dns_addr_count == 0) {
        if (slirp_get_system_dns_servers() < 0) {
            dns_addr[0]    = loopback_addr_ip;
            dns_addr_count = 1;
            fprintf (stderr, "Warning: No DNS servers found\n");
        }
    }

    inet_strtoip(CTL_SPECIAL, &special_addr_ip);

    alias_addr_ip = special_addr_ip | CTL_ALIAS;
    getouraddr();
    register_savevm("slirp", 0, 1, slirp_state_save, slirp_state_load, NULL);

    slirp_net_forward_init();
}
void
user_event_key(unsigned code, unsigned down)
{
    if(code == 0) {
        return;
    }
    if (VERBOSE_CHECK(keys))
        printf(">> KEY [0x%03x,%s]\n", (code & 0x1ff), down ? "down" : " up " );

    user_event_keycode((code & 0x1ff) | (down ? 0x200 : 0));
}
Exemplo n.º 3
0
void
android_keycodes_flush(AKeycodeBuffer* keycodes)
{
    if (keycodes->keycode_count > 0) {
        if (VERBOSE_CHECK(keys)) {
            int  nn;
            printf(">> KEY" );
            for (nn = 0; nn < keycodes->keycode_count; nn++) {
                int  code = keycodes->keycodes[nn];
                printf(" [0x%03x,%s]", (code & 0x1ff), (code & 0x200) ? "down" : " up " );
            }
            printf( "\n" );
        }
        user_event_keycodes(keycodes->keycodes, keycodes->keycode_count);
        keycodes->keycode_count = 0;
    }
}
Exemplo n.º 4
0
void nand_add_dev(const char *arg)
{
    uint64_t dev_size = 0;
    const char *next_arg;
    const char *value;
    size_t arg_len, value_len;
    nand_dev *new_devs, *dev;
    char *devname = NULL;
    size_t devname_len = 0;
    char *initfilename = NULL;
    char *rwfilename = NULL;
    int initfd = -1;
    int rwfd = -1;
    int read_only = 0;
    int pad;
    ssize_t read_size;
    uint32_t page_size = 2048;
    uint32_t extra_size = 64;
    uint32_t erase_pages = 64;

    VERBOSE_PRINT(init, "%s: %s", __FUNCTION__, arg);

    while(arg) {
        next_arg = strchr(arg, ',');
        value = strchr(arg, '=');
        if(next_arg != NULL) {
            arg_len = next_arg - arg;
            next_arg++;
            if(value >= next_arg)
                value = NULL;
        }
        else
            arg_len = strlen(arg);
        if(value != NULL) {
            size_t new_arg_len = value - arg;
            value_len = arg_len - new_arg_len - 1;
            arg_len = new_arg_len;
            value++;
        }
        else
            value_len = 0;

        if(devname == NULL) {
            if(value != NULL)
                goto bad_arg_and_value;
            devname_len = arg_len;
            devname = malloc(arg_len+1);
            if(devname == NULL)
                goto out_of_memory;
            memcpy(devname, arg, arg_len);
            devname[arg_len] = 0;
        }
        else if(value == NULL) {
            if(arg_match("readonly", arg, arg_len)) {
                read_only = 1;
            }
            else {
                XLOG("bad arg: %.*s\n", arg_len, arg);
                exit(1);
            }
        }
        else {
            if(arg_match("size", arg, arg_len)) {
                char *ep;
                dev_size = strtoull(value, &ep, 0);
                if(ep != value + value_len)
                    goto bad_arg_and_value;
            }
            else if(arg_match("pagesize", arg, arg_len)) {
                char *ep;
                page_size = strtoul(value, &ep, 0);
                if(ep != value + value_len)
                    goto bad_arg_and_value;
            }
            else if(arg_match("extrasize", arg, arg_len)) {
                char *ep;
                extra_size = strtoul(value, &ep, 0);
                if(ep != value + value_len)
                    goto bad_arg_and_value;
            }
            else if(arg_match("erasepages", arg, arg_len)) {
                char *ep;
                erase_pages = strtoul(value, &ep, 0);
                if(ep != value + value_len)
                    goto bad_arg_and_value;
            }
            else if(arg_match("initfile", arg, arg_len)) {
                initfilename = malloc(value_len + 1);
                if(initfilename == NULL)
                    goto out_of_memory;
                memcpy(initfilename, value, value_len);
                initfilename[value_len] = '\0';
            }
            else if(arg_match("file", arg, arg_len)) {
                rwfilename = malloc(value_len + 1);
                if(rwfilename == NULL)
                    goto out_of_memory;
                memcpy(rwfilename, value, value_len);
                rwfilename[value_len] = '\0';
            }
            else {
                goto bad_arg_and_value;
            }
        }

        arg = next_arg;
    }

    if (rwfilename == NULL) {
        /* we create a temporary file to store everything */
        TempFile*    tmp = tempfile_create();

        if (tmp == NULL) {
            XLOG("could not create temp file for %.*s NAND disk image: %s\n",
                  devname_len, devname, strerror(errno));
            exit(1);
        }
        rwfilename = (char*) tempfile_path(tmp);
        if (VERBOSE_CHECK(init))
            dprint( "mapping '%.*s' NAND image to %s", devname_len, devname, rwfilename);
    }

    if(rwfilename) {
        if (initfilename) {
            /* Overwrite with content of the 'initfilename'. */
            if (read_only) {
                /* Cannot be readonly when initializing the device from another file. */
                XLOG("incompatible read only option is requested while initializing %.*s from %s\n",
                     devname_len, devname, initfilename);
                exit(1);
            }
            rwfd = open(rwfilename, O_BINARY | O_TRUNC | O_RDWR);
        } else {
            rwfd = open(rwfilename, O_BINARY | (read_only ? O_RDONLY : O_RDWR));
        }
        if(rwfd < 0) {
            XLOG("could not open file %s, %s\n", rwfilename, strerror(errno));
            exit(1);
        }
        /* this could be a writable temporary file. use atexit_close_fd to ensure
         * that it is properly cleaned up at exit on Win32
         */
        if (!read_only)
            atexit_close_fd(rwfd);
    }

    if(initfilename) {
        initfd = open(initfilename, O_BINARY | O_RDONLY);
        if(initfd < 0) {
            XLOG("could not open file %s, %s\n", initfilename, strerror(errno));
            exit(1);
        }
        if(dev_size == 0) {
            dev_size = do_lseek(initfd, 0, SEEK_END);
            do_lseek(initfd, 0, SEEK_SET);
        }
    }

    new_devs = realloc(nand_devs, sizeof(nand_devs[0]) * (nand_dev_count + 1));
    if(new_devs == NULL)
        goto out_of_memory;
    nand_devs = new_devs;
    dev = &new_devs[nand_dev_count];

    dev->page_size = page_size;
    dev->extra_size = extra_size;
    dev->erase_size = erase_pages * (page_size + extra_size);
    pad = dev_size % dev->erase_size;
    if (pad != 0) {
        dev_size += (dev->erase_size - pad);
        D("rounding devsize up to a full eraseunit, now %llx\n", dev_size);
    }
    dev->devname = devname;
    dev->devname_len = devname_len;
    dev->max_size = dev_size;
    dev->data = malloc(dev->erase_size);
    if(dev->data == NULL)
        goto out_of_memory;
    dev->flags = read_only ? NAND_DEV_FLAG_READ_ONLY : 0;
#ifdef TARGET_I386
    dev->flags |= NAND_DEV_FLAG_BATCH_CAP;
#endif

    if (initfd >= 0) {
        do {
            read_size = do_read(initfd, dev->data, dev->erase_size);
            if(read_size < 0) {
                XLOG("could not read file %s, %s\n", initfilename, strerror(errno));
                exit(1);
            }
            if(do_write(rwfd, dev->data, read_size) != read_size) {
                XLOG("could not write file %s, %s\n", rwfilename, strerror(errno));
                exit(1);
            }
        } while(read_size == dev->erase_size);
        close(initfd);
    }
    dev->fd = rwfd;

    nand_dev_count++;

    return;

out_of_memory:
    XLOG("out of memory\n");
    exit(1);

bad_arg_and_value:
    XLOG("bad arg: %.*s=%.*s\n", arg_len, arg, value_len, value);
    exit(1);
}
Exemplo n.º 5
0
void
memcheck_guest_alloc(target_ulong guest_address)
{
    MallocDescEx desc;
    MallocDescEx replaced;
    RBTMapResult insert_res;
    ProcDesc* proc;
    ThreadDesc* thread;
    uint32_t indx;

    // Copy allocation descriptor from guest to emulator.
    memcheck_get_malloc_descriptor(&desc.malloc_desc, guest_address);
    desc.flags = 0;
    desc.call_stack = NULL;
    desc.call_stack_count = 0;

    proc = get_process_from_pid(desc.malloc_desc.allocator_pid);
    if (proc == NULL) {
        ME("memcheck: Unable to obtain process for allocation pid=%u",
           desc.malloc_desc.allocator_pid);
        memcheck_fail_alloc(guest_address);
        return;
    }

    if (!procdesc_is_executing(proc)) {
        desc.flags |= MDESC_FLAG_TRANSITION_ENTRY;
    }

    /* Copy thread's calling stack to the allocation descriptor. */
    thread = get_current_thread();
    desc.call_stack_count = thread->call_stack_count;
    if (desc.call_stack_count) {
        desc.call_stack = g_malloc(desc.call_stack_count * sizeof(target_ulong));
        if (desc.call_stack == NULL) {
            ME("memcheck: Unable to allocate %u bytes for the calling stack",
               desc.call_stack_count * sizeof(target_ulong));
            return;
        }
    }

    /* Thread's calling stack is in descending order (i.e. first entry in the
     * thread's stack is the most distant routine from the current one). On the
     * other hand, we keep calling stack entries in allocation descriptor in
     * assending order. */
    for (indx = 0; indx < thread->call_stack_count; indx++) {
        desc.call_stack[indx] =
           thread->call_stack[thread->call_stack_count - 1 - indx].call_address;
    }

    // Save malloc descriptor in the map.
    insert_res = procdesc_add_malloc(proc, &desc, &replaced);
    if (insert_res == RBT_MAP_RESULT_ENTRY_INSERTED) {
        // Invalidate TLB cache for the allocated block.
        if (memcheck_instrument_mmu) {
            invalidate_tlb_cache(desc.malloc_desc.ptr,
                                mallocdesc_get_alloc_end(&desc.malloc_desc));
        }
    } else if (insert_res == RBT_MAP_RESULT_ENTRY_REPLACED) {
        /* We don't expect to have another entry in the map that matches
         * inserting entry. This is an error condition for us, indicating
         * that we somehow lost track of memory allocations. */
        ME("memcheck: Duplicate allocation blocks:");
        if (VERBOSE_CHECK(memcheck)) {
            printf("   New block:\n");
            memcheck_dump_malloc_desc(&desc, 1, 1);
            printf("   Replaced block:\n");
            memcheck_dump_malloc_desc(&replaced, 1, 1);
        }
        if (replaced.call_stack != NULL) {
            g_free(replaced.call_stack);
        }
    } else {
        ME("memcheck: Unable to insert an entry to the allocation map:");
        if (VERBOSE_CHECK(memcheck)) {
            memcheck_dump_malloc_desc(&desc, 1, 1);
        }
        memcheck_fail_alloc(guest_address);
        return;
    }
}
Exemplo n.º 6
0
extern SkinSurface*
skin_surface_create_window(int x,
                           int y,
                           int w,
                           int h,
                           int original_w,
                           int original_h,
                           int is_fullscreen)
{
    static SkinSurface* result = NULL;

    SDL_Window* window = skin_winsys_get_window();
    SDL_Renderer* renderer = globals_get_renderer();

    D("%s: x=%d y=%d w=%d h=%d original_w=%d original_h=%d is_fullscreen=%d",
      __FUNCTION__, x, y, w, h, original_w, original_h, is_fullscreen);

    // Textures do not survive window resize events, so
    globals_foreach_surface(&_skin_surface_destroy_texture, NULL);

    if (!window) {
        // NOTE: Don't use SDL_WINDOW_ALLOW_HIGHDPI here. On OS X, this will
        //       make mouse event coordinates twice smaller than needed
        //       when running on a high-dpi machine (e.g. recent MacBook Pro),
        //       making the UI unusable. Note that this doesn't happen on a
        //       'low-dpi' device such as a MacPro connected to a 30" monitor.
        int window_flags = SDL_WINDOW_OPENGL;
        if (is_fullscreen) {
            window_flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
        }
        window = SDL_CreateWindow("Android emulator",
                                  x, y, w, h,
                                  window_flags);
        if (!window) {
            panic("Could not create SDL2 window: %s\n", SDL_GetError());
        }
        skin_winsys_set_window(window);
    } else {
        if (is_fullscreen) {
            SDL_CHECK(SDL_SetWindowFullscreen(window,
                                              SDL_WINDOW_FULLSCREEN_DESKTOP));
#if DEBUG
#endif
        } else {
            SDL_CHECK(SDL_SetWindowFullscreen(window, 0));
            SDL_SetWindowPosition(window, x, y);
            SDL_SetWindowSize(window, w, h);
        }
    }

    // Generate renderer
    if (!renderer) {
        SDL_CHECK(SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear"));
        renderer = SDL_CreateRenderer(window,
                                    -1,
                                    SDL_RENDERER_ACCELERATED|
                                    SDL_RENDERER_PRESENTVSYNC|
                                    SDL_RENDERER_TARGETTEXTURE);
        if  (!renderer) {
            panic("Could not create renderer: %s\n", SDL_GetError());
        }
        globals_set_renderer(renderer);
    }

    SDL_CHECK(SDL_RenderSetLogicalSize(renderer, original_w, original_h));

    if (DEBUG && VERBOSE_CHECK(surface)) {
        SDL_RendererInfo info;
        SDL_CHECK(SDL_GetRendererInfo(renderer, &info));
        printf("renderer.name = %s\n", info.name);
        printf("renderer.flags = 0x%x\n", info.flags);
        printf("renderer.num_texture_formats = %d\n", info.num_texture_formats);
        int nn;
        for (nn = 0; nn < info.num_texture_formats; ++nn) {
            printf("   0x%x (%s)\n", info.texture_formats[nn],
                   SDL_GetPixelFormatName(info.texture_formats[nn]));
        }
        printf("renderer.max_texture_width = %d\n", info.max_texture_width);
        printf("renderer.max_texture_height = %d\n", info.max_texture_height);
    }

    // Compute scaling parameters.
    {
        int window_x, window_y, window_w, window_h;

        SDL_GetWindowSize(window, &window_w, &window_h);
        SDL_GetWindowPosition(window, &window_x, &window_y);

        D("Window pos=(%d,%d) size=(%d,%d)", window_x, window_y, window_w, window_h);

        double x_scale = window_w * 1.0 / original_w;
        double y_scale = window_h * 1.0 / original_h;
        double scale = (x_scale <= y_scale) ? x_scale : y_scale;

        double effective_x = 0.;
        double effective_y = 0.;

        if (is_fullscreen) {
            effective_x = (window_w - original_w * scale) * 0.5;
            effective_y = (window_h - original_h * scale) * 0.5;
        }

        globals_set_window_scale(scale, effective_x, effective_y);
    }

    SDL_Texture* texture =
            SDL_CreateTexture(renderer,
                              SDL_PIXELFORMAT_ARGB8888,
                              SDL_TEXTUREACCESS_TARGET,
                              original_w,
                              original_h);
    if (!texture) {
        panic("Could not create window texture: %s", SDL_GetError());
    }

    SDL_CHECK(SDL_SetRenderTarget(renderer, texture));
    SDL_CHECK(SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255));
    SDL_CHECK(SDL_RenderClear(renderer));

    SDL_CHECK(SDL_SetRenderTarget(renderer, NULL));
    SDL_CHECK(SDL_SetRenderDrawColor(renderer, 0, 0, 128, 255));
    SDL_CHECK(SDL_RenderClear(renderer));
    SDL_CHECK(SDL_RenderCopy(renderer, texture, NULL, NULL));
    SDL_RenderPresent(renderer);

    if (!result) {
        result = _skin_surface_create(NULL, texture, original_w, original_h);
    } else {
        result->texture = texture;
        result->w = original_w;
        result->h = original_h;
    }
    skin_surface_ref(result);

    // Ensure all textures are regenerated properly.
    globals_foreach_surface(&_skin_surface_reset_texture, renderer);

    return result;
}