static void modeset_destroy_fb(int fd, struct modeset_buf *buf) { if (buf->map) { munmap(buf->map, buf->size); } if (buf->fb) { drmModeRmFB(fd, buf->fb); } if (buf->handle) { struct drm_mode_destroy_dumb dreq = { .handle = buf->handle, }; drmIoctl(fd, DRM_IOCTL_MODE_DESTROY_DUMB, &dreq); } } static int modeset_create_fb(struct vo *vo, int fd, struct modeset_buf *buf) { int ret = 0; buf->handle = 0; // create dumb buffer struct drm_mode_create_dumb creq = { .width = buf->width, .height = buf->height, .bpp = 32, }; ret = drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &creq); if (ret < 0) { MP_ERR(vo, "Cannot create dumb buffer: %s\n", mp_strerror(errno)); ret = -errno; goto end; } buf->stride = creq.pitch; buf->size = creq.size; buf->handle = creq.handle; // create framebuffer object for the dumb-buffer ret = drmModeAddFB(fd, buf->width, buf->height, 24, 32, buf->stride, buf->handle, &buf->fb); if (ret) { MP_ERR(vo, "Cannot create framebuffer: %s\n", mp_strerror(errno)); ret = -errno; goto end; } // prepare buffer for memory mapping struct drm_mode_map_dumb mreq = { .handle = buf->handle, }; ret = drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &mreq); if (ret) { MP_ERR(vo, "Cannot map dumb buffer: %s\n", mp_strerror(errno)); ret = -errno; goto end; } // perform actual memory mapping buf->map = mmap(0, buf->size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, mreq.offset); if (buf->map == MAP_FAILED) { MP_ERR(vo, "Cannot map dumb buffer: %s\n", mp_strerror(errno)); ret = -errno; goto end; } memset(buf->map, 0, buf->size); end: if (ret == 0) { return 0; } modeset_destroy_fb(fd, buf); return ret; } static int modeset_find_crtc(struct vo *vo, int fd, drmModeRes *res, drmModeConnector *conn, struct modeset_dev *dev) { for (unsigned int i = 0; i < conn->count_encoders; ++i) { drmModeEncoder *enc = drmModeGetEncoder(fd, conn->encoders[i]); if (!enc) { MP_WARN(vo, "Cannot retrieve encoder %u:%u: %s\n", i, conn->encoders[i], mp_strerror(errno)); continue; } // iterate all global CRTCs for (unsigned int j = 0; j < res->count_crtcs; ++j) { // check whether this CRTC works with the encoder if (!(enc->possible_crtcs & (1 << j))) continue; dev->enc = enc; dev->crtc = enc->crtc_id; return 0; } drmModeFreeEncoder(enc); } MP_ERR(vo, "Connector %u has no suitable CRTC\n", conn->connector_id); return -ENOENT; } static bool is_connector_valid(struct vo *vo, int conn_id, drmModeConnector *conn, bool silent) { if (!conn) { if (!silent) { MP_ERR(vo, "Cannot get connector %d: %s\n", conn_id, mp_strerror(errno)); } return false; } if (conn->connection != DRM_MODE_CONNECTED) { if (!silent) { MP_ERR(vo, "Connector %d is disconnected\n", conn_id); } return false; } if (conn->count_modes == 0) { if (!silent) { MP_ERR(vo, "Connector %d has no valid modes\n", conn_id); } return false; } return true; } static int modeset_prepare_dev(struct vo *vo, int fd, int conn_id, struct modeset_dev **out) { struct modeset_dev *dev = NULL; drmModeConnector *conn = NULL; int ret = 0; *out = NULL; drmModeRes *res = drmModeGetResources(fd); if (!res) { MP_ERR(vo, "Cannot retrieve DRM resources: %s\n", mp_strerror(errno)); ret = -errno; goto end; } if (conn_id == -1) { // get the first connected connector for (int i = 0; i < res->count_connectors; i++) { conn = drmModeGetConnector(fd, res->connectors[i]); if (is_connector_valid(vo, i, conn, true)) { conn_id = i; break; } if (conn) { drmModeFreeConnector(conn); conn = NULL; } } if (conn_id == -1) { MP_ERR(vo, "No connected connectors found\n"); ret = -ENODEV; goto end; } } if (conn_id < 0 || conn_id >= res->count_connectors) { MP_ERR(vo, "Bad connector ID. Max valid connector ID = %u\n", res->count_connectors); ret = -ENODEV; goto end; } conn = drmModeGetConnector(fd, res->connectors[conn_id]); if (!is_connector_valid(vo, conn_id, conn, false)) { ret = -ENODEV; goto end; } dev = talloc_zero(vo->priv, struct modeset_dev); dev->conn = conn->connector_id; dev->front_buf = 0; dev->mode = conn->modes[0]; dev->bufs[0].width = conn->modes[0].hdisplay; dev->bufs[0].height = conn->modes[0].vdisplay; dev->bufs[1].width = conn->modes[0].hdisplay; dev->bufs[1].height = conn->modes[0].vdisplay; MP_INFO(vo, "Connector using mode %ux%u\n", dev->bufs[0].width, dev->bufs[0].height); ret = modeset_find_crtc(vo, fd, res, conn, dev); if (ret) { MP_ERR(vo, "Connector %d has no valid CRTC\n", conn_id); goto end; } for (unsigned int i = 0; i < BUF_COUNT; i++) { ret = modeset_create_fb(vo, fd, &dev->bufs[i]); if (ret) { MP_ERR(vo, "Cannot create framebuffer for connector %d\n", conn_id); for (unsigned int j = 0; j < i; j++) { modeset_destroy_fb(fd, &dev->bufs[j]); } goto end; } } end: if (conn) { drmModeFreeConnector(conn); conn = NULL; } if (res) { drmModeFreeResources(res); res = NULL; } if (ret == 0) { *out = dev; } else { talloc_free(dev); } return ret; } static void modeset_page_flipped(int fd, unsigned int frame, unsigned int sec, unsigned int usec, void *data) { struct priv *p = data; p->pflip_happening = false; } static int setup_vo_crtc(struct vo *vo) { struct priv *p = vo->priv; if (p->active) return 0; p->old_crtc = drmModeGetCrtc(p->fd, p->dev->crtc); int ret = drmModeSetCrtc(p->fd, p->dev->crtc, p->dev->bufs[p->dev->front_buf + BUF_COUNT - 1].fb, 0, 0, &p->dev->conn, 1, &p->dev->mode); p->active = true; return ret; } static void release_vo_crtc(struct vo *vo) { struct priv *p = vo->priv; if (!p->active) return; p->active = false; // wait for current page flip while (p->pflip_happening) { int ret = drmHandleEvent(p->fd, &p->ev); if (ret) { MP_ERR(vo, "drmHandleEvent failed: %i\n", ret); break; } } if (p->old_crtc) { drmModeSetCrtc(p->fd, p->old_crtc->crtc_id, p->old_crtc->buffer_id, p->old_crtc->x, p->old_crtc->y, &p->dev->conn, 1, &p->dev->mode); drmModeFreeCrtc(p->old_crtc); p->old_crtc = NULL; } } static void release_vt(void *data) { struct vo *vo = data; release_vo_crtc(vo); if (USE_MASTER) { //this function enables support for switching to x, weston etc. //however, for whatever reason, it can be called only by root users. //until things change, this is commented. struct priv *p = vo->priv; if (drmDropMaster(p->fd)) { MP_WARN(vo, "Failed to drop DRM master: %s\n", mp_strerror(errno)); } } } static void acquire_vt(void *data) { struct vo *vo = data; if (USE_MASTER) { struct priv *p = vo->priv; if (drmSetMaster(p->fd)) { MP_WARN(vo, "Failed to acquire DRM master: %s\n", mp_strerror(errno)); } } setup_vo_crtc(vo); } static int wait_events(struct vo *vo, int64_t until_time_us) { struct priv *p = vo->priv; int64_t wait_us = until_time_us - mp_time_us(); int timeout_ms = MPCLAMP((wait_us + 500) / 1000, 0, 10000); vt_switcher_poll(&p->vt_switcher, timeout_ms); return 0; } static void wakeup(struct vo *vo) { struct priv *p = vo->priv; vt_switcher_interrupt_poll(&p->vt_switcher); } static int reconfig(struct vo *vo, struct mp_image_params *params, int flags) { struct priv *p = vo->priv; vo->dwidth = p->device_w; vo->dheight = p->device_h; vo_get_src_dst_rects(vo, &p->src, &p->dst, &p->osd); int32_t w = p->dst.x1 - p->dst.x0; int32_t h = p->dst.y1 - p->dst.y0; // p->osd contains the parameters assuming OSD rendering in window // coordinates, but OSD can only be rendered in the intersection // between window and video rectangle (i.e. not into panscan borders). p->osd.w = w; p->osd.h = h; p->osd.mt = MPMIN(0, p->osd.mt); p->osd.mb = MPMIN(0, p->osd.mb); p->osd.mr = MPMIN(0, p->osd.mr); p->osd.ml = MPMIN(0, p->osd.ml); p->x = (p->device_w - w) >> 1; p->y = (p->device_h - h) >> 1; mp_sws_set_from_cmdline(p->sws, vo->opts->sws_opts); p->sws->src = *params; p->sws->dst = (struct mp_image_params) { .imgfmt = IMGFMT_BGR0, .w = w, .h = h, .d_w = w, .d_h = h, }; talloc_free(p->cur_frame); p->cur_frame = mp_image_alloc(IMGFMT_BGR0, p->device_w, p->device_h); mp_image_params_guess_csp(&p->sws->dst); mp_image_set_params(p->cur_frame, &p->sws->dst); struct modeset_buf *buf = p->dev->bufs; memset(buf[0].map, 0, buf[0].size); memset(buf[1].map, 0, buf[1].size); if (mp_sws_reinit(p->sws) < 0) return -1; vo->want_redraw = true; return 0; } static void draw_image(struct vo *vo, mp_image_t *mpi) { struct priv *p = vo->priv; if (p->active) { struct mp_image src = *mpi; struct mp_rect src_rc = p->src; src_rc.x0 = MP_ALIGN_DOWN(src_rc.x0, mpi->fmt.align_x); src_rc.y0 = MP_ALIGN_DOWN(src_rc.y0, mpi->fmt.align_y); mp_image_crop_rc(&src, src_rc); mp_sws_scale(p->sws, p->cur_frame, &src); osd_draw_on_image(vo->osd, p->osd, src.pts, 0, p->cur_frame); struct modeset_buf *front_buf = &p->dev->bufs[p->dev->front_buf]; int32_t shift = (p->device_w * p->y + p->x) * 4; memcpy_pic(front_buf->map + shift, p->cur_frame->planes[0], (p->dst.x1 - p->dst.x0) * 4, p->dst.y1 - p->dst.y0, p->device_w * 4, p->cur_frame->stride[0]); } if (mpi != p->last_input) { talloc_free(p->last_input); p->last_input = mpi; } } static void flip_page(struct vo *vo) { struct priv *p = vo->priv; if (!p->active || p->pflip_happening) return; int ret = drmModePageFlip(p->fd, p->dev->crtc, p->dev->bufs[p->dev->front_buf].fb, DRM_MODE_PAGE_FLIP_EVENT, p); if (ret) { MP_WARN(vo, "Cannot flip page for connector\n"); } else { p->dev->front_buf++; p->dev->front_buf %= BUF_COUNT; p->pflip_happening = true; } // poll page flip finish event const int timeout_ms = 3000; struct pollfd fds[1] = { { .events = POLLIN, .fd = p->fd }, }; poll(fds, 1, timeout_ms); if (fds[0].revents & POLLIN) { ret = drmHandleEvent(p->fd, &p->ev); if (ret != 0) { MP_ERR(vo, "drmHandleEvent failed: %i\n", ret); return; } } } static void uninit(struct vo *vo) { struct priv *p = vo->priv; if (p->dev) { release_vo_crtc(vo); modeset_destroy_fb(p->fd, &p->dev->bufs[1]); modeset_destroy_fb(p->fd, &p->dev->bufs[0]); drmModeFreeEncoder(p->dev->enc); } vt_switcher_destroy(&p->vt_switcher); talloc_free(p->last_input); talloc_free(p->cur_frame); talloc_free(p->dev); close(p->fd); } static int preinit(struct vo *vo) { struct priv *p = vo->priv; p->sws = mp_sws_alloc(vo); p->fd = -1; p->ev.version = DRM_EVENT_CONTEXT_VERSION; p->ev.page_flip_handler = modeset_page_flipped; if (vt_switcher_init(&p->vt_switcher, vo->log)) goto err; vt_switcher_acquire(&p->vt_switcher, acquire_vt, vo); vt_switcher_release(&p->vt_switcher, release_vt, vo); if (modeset_open(vo, &p->fd, p->device_path)) goto err; if (modeset_prepare_dev(vo, p->fd, p->connector_id, &p->dev)) goto err; assert(p->dev); p->device_w = p->dev->bufs[0].width; p->device_h = p->dev->bufs[0].height; if (setup_vo_crtc(vo)) { MP_ERR(vo, "Cannot set CRTC for connector %u: %s\n", p->connector_id, mp_strerror(errno)); goto err; } return 0; err: uninit(vo); return -1; } static int query_format(struct vo *vo, int format) { return sws_isSupportedInput(imgfmt2pixfmt(format)); } static int control(struct vo *vo, uint32_t request, void *data) { struct priv *p = vo->priv; switch (request) { case VOCTRL_SCREENSHOT_WIN: *(struct mp_image**)data = mp_image_new_copy(p->cur_frame); return VO_TRUE; case VOCTRL_REDRAW_FRAME: draw_image(vo, p->last_input); return VO_TRUE; case VOCTRL_GET_PANSCAN: return VO_TRUE; case VOCTRL_SET_PANSCAN: if (vo->config_ok) reconfig(vo, vo->params, 0); return VO_TRUE; } return VO_NOTIMPL; } #define OPT_BASE_STRUCT struct priv const struct vo_driver video_out_drm = { .name = "drm", .description = "Direct Rendering Manager", .preinit = preinit, .query_format = query_format, .reconfig = reconfig, .control = control, .draw_image = draw_image, .flip_page = flip_page, .uninit = uninit, .wait_events = wait_events, .wakeup = wakeup, .priv_size = sizeof(struct priv), .options = (const struct m_option[]) { OPT_STRING("devpath", device_path, 0), OPT_INT("connector", connector_id, 0), {0}, }, .priv_defaults = &(const struct priv) {
static struct ibv_context *mthca_alloc_context(struct ibv_device *ibdev, int cmd_fd) { struct mthca_context *context; struct ibv_get_context cmd; struct mthca_alloc_ucontext_resp resp; int i; context = calloc(1, sizeof *context); if (!context) return NULL; context->ibv_ctx.cmd_fd = cmd_fd; if (ibv_cmd_get_context(&context->ibv_ctx, &cmd, sizeof cmd, &resp.ibv_resp, sizeof resp)) goto err_free; context->num_qps = resp.qp_tab_size; context->qp_table_shift = ffs(context->num_qps) - 1 - MTHCA_QP_TABLE_BITS; context->qp_table_mask = (1 << context->qp_table_shift) - 1; /* * Need to set ibv_ctx.device because mthca_is_memfree() will * look at it to figure out the HCA type. */ context->ibv_ctx.device = ibdev; if (mthca_is_memfree(&context->ibv_ctx)) { context->db_tab = mthca_alloc_db_tab(resp.uarc_size); if (!context->db_tab) goto err_free; } else context->db_tab = NULL; pthread_mutex_init(&context->qp_table_mutex, NULL); for (i = 0; i < MTHCA_QP_TABLE_SIZE; ++i) context->qp_table[i].refcnt = 0; context->uar = mmap(NULL, to_mdev(ibdev)->page_size, PROT_WRITE, MAP_SHARED, cmd_fd, 0); if (context->uar == MAP_FAILED) goto err_db_tab; pthread_spin_init(&context->uar_lock, PTHREAD_PROCESS_PRIVATE); context->pd = mthca_alloc_pd(&context->ibv_ctx); if (!context->pd) goto err_unmap; context->pd->context = &context->ibv_ctx; context->ibv_ctx.ops = mthca_ctx_ops; if (mthca_is_memfree(&context->ibv_ctx)) { context->ibv_ctx.ops.req_notify_cq = mthca_arbel_arm_cq; context->ibv_ctx.ops.cq_event = mthca_arbel_cq_event; context->ibv_ctx.ops.post_send = mthca_arbel_post_send; context->ibv_ctx.ops.post_recv = mthca_arbel_post_recv; context->ibv_ctx.ops.post_srq_recv = mthca_arbel_post_srq_recv; } else { context->ibv_ctx.ops.req_notify_cq = mthca_tavor_arm_cq; context->ibv_ctx.ops.cq_event = NULL; context->ibv_ctx.ops.post_send = mthca_tavor_post_send; context->ibv_ctx.ops.post_recv = mthca_tavor_post_recv; context->ibv_ctx.ops.post_srq_recv = mthca_tavor_post_srq_recv; } return &context->ibv_ctx; err_unmap: munmap(context->uar, to_mdev(ibdev)->page_size); err_db_tab: mthca_free_db_tab(context->db_tab); err_free: free(context); return NULL; }
int pageinout_test(int test_runs, unsigned long long file_size) { int fd; char tmpname[] = "pageinoutXXXXXX"; unsigned char *vec; int i; long long j; volatile char *buf; int ret = -1; int rc; struct timeval begin_time, end_time, elapsed_time, total_time_in, total_time_out; long pagesize = sysconf(_SC_PAGE_SIZE); timerclear(&total_time_in); timerclear(&total_time_out); fd = create_tmp_file(tmpname, file_size); if (fd < 0) { return -1; } vec = alloc_mincore_vec(file_size); if (vec == NULL) { goto err_alloc; } buf = mmap(NULL, file_size, PROT_READ, MAP_PRIVATE, fd, 0); if (buf == ((void *)-1)) { fprintf(stderr, "Failed to mmap file: %s\n", strerror(errno)); goto err_mmap; } if (!check_caching((void *)buf, vec, file_size, false)) { goto err; } for (i = 0; i < test_runs; i++) { gettimeofday(&begin_time, NULL); //Read backwards to prevent mmap prefetching for (j = ((file_size - 1) & ~(pagesize - 1)); j >= 0; j -= pagesize) { buf[j]; } gettimeofday(&end_time, NULL); timersub(&end_time, &begin_time, &elapsed_time); timeradd(&total_time_in, &elapsed_time, &total_time_in); if (!check_caching((void *)buf, vec, file_size, true)) { goto err; } gettimeofday(&begin_time, NULL); rc = madvise((void *)buf, file_size, MADV_DONTNEED) || posix_fadvise(fd, 0, file_size, POSIX_FADV_DONTNEED); gettimeofday(&end_time, NULL); if (rc) { fprintf(stderr, "posix_fadvise/madvise DONTNEED failed\n"); goto err; } timersub(&end_time, &begin_time, &elapsed_time); timeradd(&total_time_out, &elapsed_time, &total_time_out); if (!check_caching((void *)buf, vec, file_size, false)) { goto err; } } printf("page-in: %llu MB/s\n", (file_size * test_runs * USEC_PER_SEC) / (1024 * 1024 * (total_time_in.tv_sec * USEC_PER_SEC + total_time_in.tv_usec))); printf("page-out (clean): %llu MB/s\n", (file_size * test_runs * USEC_PER_SEC) / (1024 * 1024 * (total_time_out.tv_sec * USEC_PER_SEC + total_time_out.tv_usec))); ret = 0; err: munmap((void *)buf, file_size); err_mmap: free(vec); err_alloc: close(fd); return ret; }
/* }}} */ static XC_SHM_INIT(xc_mmap_init) /* {{{ */ { #ifdef ZEND_WIN32 # define TMP_PATH "XCache" #else # define TMP_PATH "/tmp/XCache" int fd = -1; #endif xc_shm_t *shm = NULL; int ro_ok; volatile void *romem; char tmpname[sizeof(TMP_PATH) - 1 + 4 * 10 + 100] = { 0 }; const char *errstr = NULL; const char *path = (const char *) arg1; static int instanceId = 0; CHECK(shm = calloc(1, sizeof(xc_shm_t)), "shm OOM"); shm->size = size; if (path == NULL || !path[0]) { snprintf(tmpname, sizeof(tmpname) - 1, "%s.%d.%d.%d", TMP_PATH, (int) getuid(), (int) getpid(), ++instanceId); path = tmpname; } #ifdef ZEND_WIN32 else { snprintf(tmpname, sizeof(tmpname) - 1, "%s.%d.%d.%d", path, (int) getuid(), (int) getpid(), ++instanceId); path = tmpname; } #endif shm->name = strdup(path); #ifndef ZEND_WIN32 # define XCACHE_MMAP_PERMISSION (S_IRUSR | S_IWUSR) fd = open(shm->name, O_RDWR, XCACHE_MMAP_PERMISSION); if (fd == -1) { /* do not create file in /dev */ if (strncmp(shm->name, "/dev", 4) == 0) { perror(shm->name); errstr = "Cannot open file set by xcache.mmap_path, check the xcache.size/var_size against system limitation"; goto err; } fd = open(shm->name, O_CREAT | O_RDWR, XCACHE_MMAP_PERMISSION); shm->newfile = 1; if (fd == -1) { perror(shm->name); errstr = "Cannot open or create file set by xcache.mmap_path, check the path permission or check xcache.size/var_size against system limitation"; goto err; } } if (ftruncate(fd, size) != 0 && errno != EINVAL) { perror(shm->name); errstr = "Failed to ftruncate the file"; goto err; } #endif #ifdef ZEND_WIN32 shm->hmap = XCacheCreateFileMapping(size, PAGE_READWRITE, shm->name); shm->ptr = (LPSTR) MapViewOfFile(shm->hmap, FILE_MAP_WRITE, 0, 0, 0); #else shm->ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); #endif if (shm->ptr == XCACHE_MAP_FAILED) { perror(shm->name); errstr = "Failed creating file mapping"; shm->ptr = NULL; goto err; } /* {{{ readonly protection, mmap it readonly and check if ptr_ro works */ if (readonly_protection) { ro_ok = 0; #ifdef ZEND_WIN32 shm->hmap_ro = XCacheCreateFileMapping(size, PAGE_READONLY, shm->name); shm->ptr_ro = (LPSTR) MapViewOfFile(shm->hmap_ro, FILE_MAP_READ, 0, 0, 0); #else shm->ptr_ro = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0); #endif if (shm->ptr_ro == XCACHE_MAP_FAILED) { shm->ptr_ro = NULL; } romem = shm->ptr_ro; do { if (romem == NULL || romem == shm->ptr) { break; } *(char *)shm->ptr = 1; if (*(char *)romem != 1) { break; } *(char *)shm->ptr = 2; if (*(char *)romem != 2) { break; } ro_ok = 1; } while (0); if (ro_ok) { shm->diff = PTR_SUB(shm->ptr_ro, (char *) shm->ptr); /* no overlap */ assert((xc_shmsize_t) abs(shm->diff) >= size); } else { if (shm->ptr_ro) { munmap(shm->ptr_ro, size); } #ifdef ZEND_WIN32 if (shm->hmap_ro) { CloseHandle(shm->hmap_ro); } #endif shm->ptr_ro = NULL; shm->diff = 0; } } /* }}} */ #ifndef ZEND_WIN32 close(fd); # ifndef __CYGWIN__ if (shm->newfile) { unlink(shm->name); } # endif #endif return shm; err: #ifndef ZEND_WIN32 if (fd != -1) { close(fd); } #endif if (shm) { xc_mmap_destroy(shm); } if (errstr) { fprintf(stderr, "%s\n", errstr); zend_error(E_ERROR, "%s", errstr); } return NULL; }
int tap_ctl_stats_fwrite(pid_t pid, int minor, FILE *stream) { tapdisk_message_t message; int sfd = -1, prot, flags, err; size_t len, bufsz; char *buf = MAP_FAILED; prot = PROT_READ|PROT_WRITE; flags = MAP_ANONYMOUS|MAP_PRIVATE; bufsz = sysconf(_SC_PAGE_SIZE); buf = mmap(NULL, bufsz, prot, flags, -1, 0); if (buf == MAP_FAILED) { buf = NULL; err = -ENOMEM; goto out; } sfd = _tap_ctl_stats_connect_and_send(pid, minor); if (sfd < 0) { err = sfd; goto out; } err = tap_ctl_read_message(sfd, &message, NULL); if (err) goto out; len = message.u.info.length; err = len; if (len < 0) goto out; while (len) { fd_set rfds; size_t in, out; int n; FD_ZERO(&rfds); FD_SET(sfd, &rfds); n = select(sfd + 1, &rfds, NULL, NULL, NULL); err = n; if (n < 0) goto out; in = read(sfd, buf, bufsz); err = in; if (in <= 0) goto out; len -= in; out = fwrite(buf, in, 1, stream); if (out != in) { err = -errno; goto out; } } out: if (sfd >= 0) close(sfd); if (buf != MAP_FAILED) munmap(buf, bufsz); return err; }
int main(int argc, const char** argv) { if (argc < 7 or argc > 10) { usageAndExit(argv[0]); } unsigned alignment = 1; if (argc > 7) { alignment = atoi(argv[7]); } bool writable = false; bool executable = false; for (int i = 8; i < argc; ++i) { if (strcmp("writable", argv[i]) == 0) { writable = true; } else if (strcmp("executable", argv[i]) == 0) { executable = true; } else { usageAndExit(argv[0]); } } uint8_t* data = 0; unsigned size; int fd = open(argv[1], O_RDONLY); if (fd != -1) { struct stat s; int r = fstat(fd, &s); if (r != -1) { #ifdef WIN32 HANDLE fm; HANDLE h = (HANDLE) _get_osfhandle (fd); fm = CreateFileMapping( h, NULL, PAGE_READONLY, 0, 0, NULL); data = static_cast<uint8_t*>(MapViewOfFile( fm, FILE_MAP_READ, 0, 0, s.st_size)); CloseHandle(fm); #else data = static_cast<uint8_t*> (mmap(0, s.st_size, PROT_READ, MAP_PRIVATE, fd, 0)); #endif size = s.st_size; } close(fd); } bool success = false; if (data) { FileOutputStream out(argv[2]); if (out.isValid()) { success = writeObject (data, size, &out, argv[3], argv[4], argv[5], argv[6], alignment, writable, executable); } else { fprintf(stderr, "unable to open %s\n", argv[2]); } #ifdef WIN32 UnmapViewOfFile(data); #else munmap(data, size); #endif } else { perror(argv[0]); } return (success ? 0 : -1); }
void upx_main( struct Extent xi, f_expand *const f_decompress, int junk, f_unfilter *const f_unf, char *envp[], char *argv[], int argc ) { // file descriptor int fdo; // decompression buffer unsigned char *buf; char *tmpname; struct p_info header; // temporary file name char tmpname_buf[20]; (void)junk; // // ----- Step 0: set /proc/self using /proc/<pid> ----- // //personality(PER_LINUX); // // ----- Step 1: prepare input file ----- // // Read header. { register char *__d0, *__d1; __asm__ __volatile__( "movsl; movsl; movsl" : "=&D" (__d0), "=&S" (__d1) : "0" (&header), "1" (xi.buf) : "memory"); xi.buf = __d1; xi.size -= sizeof(header); } // Paranoia. Make sure this is actually our expected executable // by checking the random program id. (The id is both stored // in the header and patched into this stub.) if (header.p_progid != UPX3) goto error1; // // ----- Step 2: prepare temporary output file ----- // tmpname = tmpname_buf; SET4(tmpname + 0, '/', 't', 'm', 'p'); SET4(tmpname + 4, '/', 'u', 'p', 'x'); // Compute name of temporary output file in tmpname[]. // Protect against Denial-of-Service attacks. { char *p = tmpname_buf + sizeof(tmpname_buf) - 1; // Compute the last 4 characters (20 bits) from getpid(). uint32_t r = ascii5(p, (uint32_t)getpid(), 4); *p = '\0'; p -= 4; // Provide 4 random bytes from our program id. r ^= header.p_progid; // Mix in 4 runtime random bytes. // Don't consume precious bytes from /dev/urandom. { #if 1 struct timeval tv; gettimeofday(&tv, 0); r ^= (uint32_t) tv.tv_sec; r ^= ((uint32_t) tv.tv_usec) << 12; // shift into high-bits #else // using adjtimex() may cause portability problems struct timex tx; adjtimex(&tx); r ^= (uint32_t) tx.time.tv_sec; r ^= ((uint32_t) tx.time.tv_usec) << 12; // shift into high-bits r ^= (uint32_t) tx.errcnt; #endif } // Compute 7 more characters from the 32 random bits. ascii5(p, r, 7); } // Just in case, remove the file. { int err = unlink(tmpname); if (err != -ENOENT && err != 0) goto error1; } // Create the temporary output file. #if (USE_MMAP_FO) fdo = open(tmpname, O_RDWR | O_CREAT | O_EXCL, 0700); #else fdo = open(tmpname, O_WRONLY | O_CREAT | O_EXCL, 0700); #endif #if 0 // Save some bytes of code - the ftruncate() below will fail anyway. if (fdo < 0) goto error; #endif // Set expected uncompressed file size. if (ftruncate(fdo, header.p_filesize) != 0) goto error; // // ----- Step 3: setup memory ----- // #if (USE_MMAP_FO) // FIXME: packer could set length buf = (unsigned char *)mmap(0, header.p_filesize, PROT_READ | PROT_WRITE, MAP_SHARED, fdo, 0); if ((unsigned long) buf >= (unsigned long) -4095) goto error; // Decompressor can overrun the output by 3 bytes. // Defend against SIGSEGV by using a scratch page. // FIXME: packer could set address delta mmap(buf + (PAGE_MASK & (header.p_filesize + ~PAGE_MASK)), -PAGE_MASK, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0 ); #else // Temporary decompression buffer. // FIXME: packer could set length buf = mmap(0, (header.p_blocksize + OVERHEAD + ~PAGE_MASK) & PAGE_MASK, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0 ); if ((unsigned long) buf >= (unsigned long) -4095) goto error; #endif // // ----- Step 4: decompress blocks ----- // for (;;) { struct b_info h; // Read and check block sizes. { register char *__d0, *__d1; __asm__ __volatile__( "movsl; movsl; movsl" : "=&D" (__d0), "=&S" (__d1) : "0" (&h), "1" (xi.buf) : "memory"); xi.buf = __d1; xi.size -= sizeof(h); } if (h.sz_unc == 0) // uncompressed size 0 -> EOF { if (h.sz_cpr != UPX_MAGIC_LE32) // h.sz_cpr must be h->magic goto error; if (header.p_filesize != 0) // all bytes must be written goto error; break; } // Note: if sz_unc == sz_cpr then the block was not // compressible and is stored in its uncompressed form. if (h.sz_cpr > h.sz_unc || h.sz_cpr > header.p_blocksize) goto error; // Now we have: // assert(h.sz_cpr <= h.sz_unc); // assert(h.sz_unc > 0 && h.sz_unc <= blocksize); // assert(h.sz_cpr > 0 && h.sz_cpr <= blocksize); if (h.sz_cpr < h.sz_unc) { // Decompress block. nrv_uint out_len = h.sz_unc; // EOF for lzma int i = (*f_decompress)((unsigned char *)xi.buf, h.sz_cpr, buf, &out_len, *(int *)(void *)&h.b_method); if (i != 0 || out_len != (nrv_uint)h.sz_unc) goto error; // Right now, unfilter is combined with decompression. // (*f_unfilter)(buf, out_len, cto8); (void)f_unf; } else { // Incompressible block #if (USE_MMAP_FO) //memcpy(buf, xi.buf, h.sz_unc); register unsigned long int __d0, __d1, __d2; __asm__ __volatile__( "rep; movsb" : "=&c" (__d0), "=&D" (__d1), "=&S" (__d2) : "0" (h.sz_unc), "1" (buf), "2" (xi.buf) : "memory"); #endif } #if (USE_MMAP_FO) // unmap part of the output munmap(buf, h.sz_unc); buf += h.sz_unc; #else // write output file if (xwrite(fdo, buf, h.sz_unc) != 0) goto error; #endif header.p_filesize -= h.sz_unc; xi.buf += h.sz_cpr; xi.size -= h.sz_cpr; if (xi.size < 0) { // error exit is here in the middle to keep the jumps short. error: (void) unlink(tmpname); error1: // Note: the kernel will close all open files and // unmap any allocated memory. for (;;) (void) exit(127); } } // // ----- Step 5: release resources ----- // #if !(USE_MMAP_FO) // Free our temporary decompression buffer. munmap(buf, malloc_args.ma_length); #endif if (close(fdo) != 0) goto error; // // ----- Step 6: try to start program via /proc/self/fd/X ----- // // Many thanks to Andi Kleen <*****@*****.**> and // Jamie Lokier <*****@*****.**> for this nice idea. if (0 > go_self(tmpname, argv, envp)) goto error; // // ----- Step 7: start program in /tmp ----- // // Fork off a subprocess to clean up. // We have to do this double-fork trick to keep a zombie from // hanging around if the spawned original program doesn't check for // subprocesses (as well as to prevent the real program from getting // confused about this subprocess it shouldn't have). // Thanks to Adam Ierymenko <*****@*****.**> for this solution. if (fork() == 0) { if (fork() == 0) { // Sleep 3 seconds, then remove the temp file. struct timespec ts; ts.tv_sec = UPX4; ts.tv_nsec = 0; nanosleep(&ts, 0); unlink(tmpname); } exit(0); } // Wait for the first fork()'d process to die. waitpid(-1, (int *)0, 0); // Execute the original program. (void)argc; execve(tmpname, (char const *const *)argv, (char const *const *)envp); // // ----- Step 8: error exit ----- // // If we return from execve() there was an error. Give up. goto error; }
/* ::1 localhost6 alias1 alias2 # internet protocol, pseudo protocol number */ struct hostent* gethostent_r(char* buf, int len) { char *dest; struct hostent* pe=(struct hostent*)buf; char* last; char* max=buf+len; int aliasidx; if (!hostmap) { int hostfd=open(_PATH_HOSTS,O_RDONLY); if (hostfd<0) return 0; hostlen=lseek(hostfd,0,SEEK_END); hostmap=mmap(0,hostlen,PROT_READ|PROT_WRITE,MAP_PRIVATE,hostfd,0); if ((long)hostmap==(-1)) { close(hostfd); hostmap=0; goto error; } close(hostfd); cur=hostmap; } last=hostmap+hostlen; again: if ((size_t)len<sizeof(struct hostent)+11*sizeof(char*)) goto nospace; dest=buf+sizeof(struct hostent); pe->h_name=0; pe->h_aliases=(char**)dest; pe->h_aliases[0]=0; dest+=10*sizeof(char*); pe->h_addr_list=(char**)dest; dest+=2*sizeof(char**); if (cur>=last) return 0; if (*cur=='#' || *cur=='\n') goto parseerror; /* first, the ip number */ pe->h_name=cur; while (cur<last && !isspace(*cur)) cur++; if (cur>=last) return 0; if (*cur=='\n') goto parseerror; { char save=*cur; *cur=0; pe->h_addr_list[0]=dest; pe->h_addr_list[1]=0; if (max-dest<16) goto nospace; if (inet_pton(AF_INET6,pe->h_name,dest)>0) { pe->h_addrtype=AF_INET6; pe->h_length=16; dest+=16; } else if (inet_pton(AF_INET,pe->h_name,dest)>0) { pe->h_addrtype=AF_INET; pe->h_length=4; dest+=4; } else { *cur=save; goto parseerror; } *cur=save; } ++cur; /* now the aliases */ for (aliasidx=0;aliasidx<9;++aliasidx) { while (cur<last && isblank(*cur)) ++cur; pe->h_aliases[aliasidx]=cur; while (cur<last && !isspace(*cur)) ++cur; { char *from=pe->h_aliases[aliasidx]; int l=cur-from; if (max-dest<l+2) goto nospace; pe->h_aliases[aliasidx]=dest; memmove(dest,from,(size_t)(cur-from)); dest+=l; *dest=0; ++dest; } if (*cur=='\n') { ++cur; ++aliasidx; break; } if (cur>=last || !isblank(*cur)) break; cur++; } pe->h_aliases[aliasidx]=0; pe->h_name=pe->h_aliases[0]; pe->h_aliases++; return pe; parseerror: while (cur<last && *cur!='\n') cur++; cur++; goto again; nospace: errno=ERANGE; goto __error; error: errno=ENOMEM; __error: if (hostmap!=(char*)-1) munmap(hostmap,hostlen); hostmap=(char*)-1; return 0; }
DISPATCH_NOINLINE static void _dispatch_alloc_try_create_heap(dispatch_heap_t *heap_ptr) { #if HAVE_MACH kern_return_t kr; mach_vm_size_t vm_size = MAGAZINES_PER_HEAP * BYTES_PER_MAGAZINE; mach_vm_offset_t vm_mask = ~MAGAZINE_MASK; mach_vm_address_t vm_addr = vm_page_size; while (slowpath(kr = mach_vm_map(mach_task_self(), &vm_addr, vm_size, vm_mask, VM_FLAGS_ANYWHERE | VM_MAKE_TAG(VM_MEMORY_LIBDISPATCH), MEMORY_OBJECT_NULL, 0, FALSE, VM_PROT_DEFAULT, VM_PROT_ALL, VM_INHERIT_DEFAULT))) { if (kr != KERN_NO_SPACE) { (void)dispatch_assume_zero(kr); DISPATCH_CLIENT_CRASH("Could not allocate heap"); } _dispatch_temporary_resource_shortage(); vm_addr = vm_page_size; } uintptr_t aligned_region = (uintptr_t)vm_addr; #else // HAVE_MACH const size_t region_sz = (1 + MAGAZINES_PER_HEAP) * BYTES_PER_MAGAZINE; void *region_p; while (!dispatch_assume((region_p = mmap(NULL, region_sz, PROT_READ|PROT_WRITE, MAP_ANON | MAP_PRIVATE, VM_MAKE_TAG(VM_MEMORY_LIBDISPATCH), 0)) != MAP_FAILED)) { _dispatch_temporary_resource_shortage(); } uintptr_t region = (uintptr_t)region_p; uintptr_t region_end = region + region_sz; uintptr_t aligned_region, aligned_region_end; uintptr_t bottom_slop_len, top_slop_len; // Realign if needed; find the slop at top/bottom to unmap if ((region & ~(MAGAZINE_MASK)) == 0) { bottom_slop_len = 0; aligned_region = region; aligned_region_end = region_end - BYTES_PER_MAGAZINE; top_slop_len = BYTES_PER_MAGAZINE; } else { aligned_region = (region & MAGAZINE_MASK) + BYTES_PER_MAGAZINE; aligned_region_end = aligned_region + (MAGAZINES_PER_HEAP * BYTES_PER_MAGAZINE); bottom_slop_len = aligned_region - region; top_slop_len = BYTES_PER_MAGAZINE - bottom_slop_len; } #if DISPATCH_DEBUG // Double-check our math. dispatch_assert(aligned_region % DISPATCH_ALLOCATOR_PAGE_SIZE == 0); dispatch_assert(aligned_region % vm_kernel_page_size == 0); dispatch_assert(aligned_region_end % DISPATCH_ALLOCATOR_PAGE_SIZE == 0); dispatch_assert(aligned_region_end % vm_kernel_page_size == 0); dispatch_assert(aligned_region_end > aligned_region); dispatch_assert(top_slop_len % DISPATCH_ALLOCATOR_PAGE_SIZE == 0); dispatch_assert(bottom_slop_len % DISPATCH_ALLOCATOR_PAGE_SIZE == 0); dispatch_assert(aligned_region_end + top_slop_len == region_end); dispatch_assert(region + bottom_slop_len == aligned_region); dispatch_assert(region_sz == bottom_slop_len + top_slop_len + MAGAZINES_PER_HEAP * BYTES_PER_MAGAZINE); if (bottom_slop_len) { (void)dispatch_assume_zero(mprotect((void *)region, bottom_slop_len, PROT_NONE)); } if (top_slop_len) { (void)dispatch_assume_zero(mprotect((void *)aligned_region_end, top_slop_len, PROT_NONE)); } #else if (bottom_slop_len) { (void)dispatch_assume_zero(munmap((void *)region, bottom_slop_len)); } if (top_slop_len) { (void)dispatch_assume_zero(munmap((void *)aligned_region_end, top_slop_len)); } #endif // DISPATCH_DEBUG #endif // HAVE_MACH if (!dispatch_atomic_cmpxchg(heap_ptr, NULL, (void *)aligned_region, relaxed)) { // If we lost the race to link in the new region, unmap the whole thing. #if DISPATCH_DEBUG (void)dispatch_assume_zero(mprotect((void *)aligned_region, MAGAZINES_PER_HEAP * BYTES_PER_MAGAZINE, PROT_NONE)); #else (void)dispatch_assume_zero(munmap((void *)aligned_region, MAGAZINES_PER_HEAP * BYTES_PER_MAGAZINE)); #endif } }
int main(int argc, char *argv[]) { unsigned char c; int i, j; int64_t l; int fdSerial; int fdFile; int64_t *ram; int64_t len; uint8_t *byt_buf; uint8_t *buf; char *ptr; struct stat statbuf; // allocate arrays ram = calloc(MAX_MEM, sizeof(int64_t)); if (ram==NULL) { printf("error with allocation\n"); exit(-1); } buf = calloc(10000, sizeof(char)); if (buf == NULL) { fprintf(stderr, "Could not allocate memory\n"); exit(-1); } byt_buf = calloc(MAX_MEM, sizeof(int64_t)); if (byt_buf==NULL) { printf("error with allocation\n"); exit(-1); } // process arguments if (argc<3) { fprintf(stderr, "usage: down [-e] [-c] [-usb] file port\n"); exit(-1); } for (i=1; i<argc-2; i++) { if (strcmp(argv[i], "-e") == 0) echo = 1; else if (strcmp(argv[i], "-usb") == 0) usb = 1; else if (strcmp(argv[i], "-c") == 0) cont = 1; } // open word file and map it into memory fdFile = open(argv[argc-2], O_RDONLY); if (fdFile < 0) { perror("Error opening file"); exit(-1); } if (fstat(fdFile, &statbuf)) { perror("Error stat'ing file"); exit(-1); } ptr = mmap(0, statbuf.st_size, PROT_READ, MAP_PRIVATE, fdFile, 0); if (ptr == MAP_FAILED) { perror("Error mapping file"); exit(-1); } // now parse the text data and build the mem array parse_text(ram, &len, ptr, statbuf.st_size); if (ram[0] != len) { fprintf(stderr, "JOP header says length = %ld, parsed length = %ld\n", (long int)ram[0], (long int)len); fprintf(stderr, "Maybe a bad JOP file?"); exit(-1); } fprintf(stdout, "Parsed JOP file ok.\n"); munmap(ptr, statbuf.st_size); close(fdFile); for (i=0; i<len; ++i) { l = ram[i]; for (j=0; j<4; ++j) { byt_buf[i*4+j] = l>>((3-j)*8); } } // // write external RAM // // open serial port fdSerial = serial_open(argv[argc-1]); printf("* %ld words of Java bytecode (%ld KB)\n", (long int)ram[1]-1, (long int)(ram[1]-1)/256); printf("* %ld words external RAM (%ld KB)\n", (long int)len, (long int)len/256); fprintf(stdout, "\nTransmitting data via serial...\n"); if (usb) { ssize_t count = 0; ssize_t max = len * 4; while (count < max) { print_progress(count/4, max/4); count += write(fdSerial, byt_buf + count, (max - count > 128) ? 128 : max-count); } fprintf(stderr, "\nDone.\n"); } else { for (j=0; j<len; ++j) { if (j % 128 == 0) print_progress(j, len); write32_check(fdSerial, ram[j]); } fprintf(stderr, "\nDone.\n"); } // // read serial output of Jop // for (j=0; j<strlen(exitString)+1; ++j) { buf[j] = 0; } if (echo) { long rdCnt; for (;;) { read(fdSerial, &c, 1); printf("%c", c); fflush(stdout); for (j=0; j<strlen(exitString)-1; ++j) { buf[j] = buf[j+1]; } buf[strlen(exitString)-1] = c; if (strcmp(buf, exitString)==0) { break; } //printf("'%c' %d\n", c, c); fflush(stdout); } } /* */ close(fdSerial); return 0; }
void endhostent(void) { if (hostmap!=(char*)-1) munmap(hostmap,hostlen); hostmap=0; }
int main(int argc, char **argv) { int i; int files = 0; xmlRelaxNGPtr schema = NULL; for (i = 1; i < argc ; i++) { #ifdef LIBXML_DEBUG_ENABLED if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug"))) debug++; else #endif #ifdef HAVE_SYS_MMAN_H if ((!strcmp(argv[i], "-memory")) || (!strcmp(argv[i], "--memory"))) { memory++; } else #endif if ((!strcmp(argv[i], "-noout")) || (!strcmp(argv[i], "--noout"))) { noout++; } else if ((!strcmp(argv[i], "-tree")) || (!strcmp(argv[i], "--tree"))) { tree++; } } xmlLineNumbersDefault(1); xmlSubstituteEntitiesDefault(1); for (i = 1; i < argc ; i++) { if (argv[i][0] != '-') { if (schema == NULL) { xmlRelaxNGParserCtxtPtr ctxt; #ifdef HAVE_SYS_MMAN_H if (memory) { int fd; struct stat info; const char *base; if (stat(argv[i], &info) < 0) break; if ((fd = open(argv[i], O_RDONLY)) < 0) break; base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ; if (base == (void *) MAP_FAILED) break; ctxt = xmlRelaxNGNewMemParserCtxt((char *)base,info.st_size); xmlRelaxNGSetParserErrors(ctxt, (xmlRelaxNGValidityErrorFunc) fprintf, (xmlRelaxNGValidityWarningFunc) fprintf, stderr); schema = xmlRelaxNGParse(ctxt); xmlRelaxNGFreeParserCtxt(ctxt); munmap((char *) base, info.st_size); } else #endif { ctxt = xmlRelaxNGNewParserCtxt(argv[i]); xmlRelaxNGSetParserErrors(ctxt, (xmlRelaxNGValidityErrorFunc) fprintf, (xmlRelaxNGValidityWarningFunc) fprintf, stderr); schema = xmlRelaxNGParse(ctxt); xmlRelaxNGFreeParserCtxt(ctxt); } if (schema == NULL) { printf("Relax-NG schema %s failed to compile\n", argv[i]); files = -1; break; } #ifdef LIBXML_OUTPUT_ENABLED #ifdef LIBXML_DEBUG_ENABLED if (debug) xmlRelaxNGDump(stdout, schema); #endif if (tree) xmlRelaxNGDumpTree(stdout, schema); #endif } else { xmlDocPtr doc; doc = xmlReadFile(argv[i],NULL,0); if (doc == NULL) { fprintf(stderr, "Could not parse %s\n", argv[i]); } else { xmlRelaxNGValidCtxtPtr ctxt; int ret; ctxt = xmlRelaxNGNewValidCtxt(schema); xmlRelaxNGSetValidErrors(ctxt, (xmlRelaxNGValidityErrorFunc) fprintf, (xmlRelaxNGValidityWarningFunc) fprintf, stderr); ret = xmlRelaxNGValidateDoc(ctxt, doc); if (ret == 0) { printf("%s validates\n", argv[i]); } else if (ret > 0) { printf("%s fails to validate\n", argv[i]); } else { printf("%s validation generated an internal error\n", argv[i]); } xmlRelaxNGFreeValidCtxt(ctxt); xmlFreeDoc(doc); } } files ++; } } if (schema != NULL) xmlRelaxNGFree(schema); if (files == 0) { printf("Usage : %s [--debug] [--noout] schemas XMLfiles ...\n", argv[0]); printf("\tParse the HTML files and output the result of the parsing\n"); #ifdef LIBXML_DEBUG_ENABLED printf("\t--debug : dump a debug tree of the in-memory document\n"); #endif printf("\t--noout : do not print the result\n"); printf("\t--tree : print the intermediate Relax-NG document tree\n"); #ifdef HAVE_SYS_MMAN_H printf("\t--memory : test the schemas in memory parsing\n"); #endif } xmlRelaxNGCleanupTypes(); xmlCleanupParser(); xmlMemoryDump(); return(0); }
int __fdnlist_aout(int fd, struct nlist *list) { struct nlist *p, *s; char *strtab; off_t stroff, symoff; int nent; size_t strsize, symsize, cc; struct nlist nbuf[1024]; struct exec exec; struct stat st; char *scoreboard, *scored; _DIAGASSERT(fd != -1); _DIAGASSERT(list != NULL); if (pread(fd, &exec, sizeof(exec), (off_t)0) != sizeof(exec) || N_BADMAG(exec) || fstat(fd, &st) < 0) return (-1); symoff = N_SYMOFF(exec); symsize = (size_t)exec.a_syms; stroff = symoff + symsize; /* Check for files too large to mmap. */ if ((uintmax_t)(st.st_size - stroff) > (uintmax_t)SIZE_T_MAX) { errno = EFBIG; return (-1); } /* * Map string table into our address space. This gives us * an easy way to randomly access all the strings, without * making the memory allocation permanent as with malloc/free * (i.e., munmap will return it to the system). */ strsize = (size_t)(st.st_size - stroff); strtab = mmap(NULL, strsize, PROT_READ, MAP_PRIVATE|MAP_FILE, fd, stroff); if (strtab == (char *)-1) return (-1); /* * clean out any left-over information for all valid entries. * Type and value defined to be 0 if not found; historical * versions cleared other and desc as well. Also figure out * the largest string length so don't read any more of the * string table than we have to. * * XXX clearing anything other than n_type and n_value violates * the semantics given in the man page. */ nent = 0; for (p = list; !ISLAST(p); ++p) { p->n_type = 0; p->n_other = 0; p->n_desc = 0; p->n_value = 0; ++nent; } if (lseek(fd, symoff, SEEK_SET) == -1) return (-1); #if defined(__SSP__) || defined(__SSP_ALL__) scoreboard = malloc((size_t)nent); #else scoreboard = alloca((size_t)nent); #endif if (scoreboard == NULL) return (-1); (void)memset(scoreboard, 0, (size_t)nent); while (symsize > 0) { cc = MIN(symsize, sizeof(nbuf)); if (read(fd, nbuf, cc) != (ssize_t) cc) break; symsize -= cc; for (s = nbuf; cc > 0; ++s, cc -= sizeof(*s)) { long soff = s->n_un.n_strx; if (soff == 0 || (s->n_type & N_STAB) != 0) continue; for (p = list, scored = scoreboard; !ISLAST(p); p++, scored++) if (*scored == 0 && !strcmp(&strtab[(size_t)soff], p->n_un.n_name)) { p->n_value = s->n_value; p->n_type = s->n_type; p->n_desc = s->n_desc; p->n_other = s->n_other; *scored = 1; if (--nent <= 0) break; } } } munmap(strtab, strsize); #if defined(__SSP__) || defined(__SSP_ALL__) free(scoreboard); #endif return (nent); }
void hfree(void *ptr, size_t size) { munmap(ptr, size); }
static int create_sysv_file(struct shmget_msg *msg, size_t size, struct shmid_ds *shmseg) { char filename[FILENAME_MAX]; int fd; void *addr; int nsems; struct semid_pool *sems; struct msqid_pool *msgq; key_t key = msg->key; int i; errno = 0; switch(msg->type) { case SHMGET: sprintf(filename, "%s/%s_%ld", DIRPATH, SHM_NAME, key); break; case SEMGET: sprintf(filename, "%s/%s_%ld", DIRPATH, SEM_NAME, key); break; case MSGGET: sprintf(filename, "%s/%s_%ld", DIRPATH, MSG_NAME, key); break; case UNDOGET: sprintf(filename, "%s/%s_%ld", DIRPATH, UNDO_NAME, key); break; default: return (-EINVAL); } fd = open(filename, O_RDWR | O_CREAT, 0666); if (fd < 0) { sysvd_print_err("create sysv file: open\n"); goto out; } ftruncate(fd, size); switch(msg->type) { case SEMGET: /* Map the semaphore to initialize it. */ addr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); //TODO modify 0 for more sems on a page if (!addr) { sysvd_print_err("create sysv file: mmap"); goto error; } /* There is no need for any lock because all clients * that try to access this segment are blocked until * it becames ~SHMSEG_REMOVED. */ sems = (struct semid_pool*)addr; nsems = (msg->size - sizeof(struct semid_pool)) / sizeof(struct sem); sysvd_print("alocate %d sems\n", nsems); /* Init lock. */ #ifdef SYSV_RWLOCK sysv_rwlock_init(&sems->rwlock); #else sysv_mutex_init(&sems->mutex); #endif /* Credentials are kept in shmid_ds structure. */ sems->ds.sem_perm.seq = shmseg->shm_perm.seq; sems->ds.sem_nsems = nsems; sems->ds.sem_otime = 0; //sems->ds.sem_ctime = time(NULL); //semtot += nsems; sems->gen = 0; /* Initialize each sem. */ memset(sems->ds.sem_base, 0, nsems + sizeof(struct sem)); #ifdef SYSV_SEMS int l; for (l=0; l < nsems; l++) sysv_mutex_init(&sems->ds.sem_base[l].sem_mutex); #endif munmap(addr, size); break; case MSGGET: /* Map the message queue to initialize it. */ addr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (!addr) { sysvd_print_err("create sysv file: mmap"); goto error; } /* There is no need for any lock because all clients * that try to access this segment are blocked until * it becames ~SHMSEG_REMOVED. */ msgq = (struct msqid_pool*)addr; //TODO /*sysvd_print("Attention!!! : %ld %ld %ld %ld\n", sizeof(struct msqid_pool), sizeof(msgq->msghdrs), sizeof(msgq->msgmaps), sizeof(msgq->msgpool));*/ /* Init lock. */ #ifdef SYSV_RWLOCK sysv_rwlock_init(&msgq->rwlock); #else sysv_mutex_init(&msgq->mutex); #endif /* In kernel implementation, this was done globally. */ for (i = 0; i < msginfo.msgseg; i++) { if (i > 0) msgq->msgmaps[i-1].next = i; msgq->msgmaps[i].next = -1; /* implies entry is available */ } msgq->free_msgmaps = 0; msgq->nfree_msgmaps = msginfo.msgseg; for (i = 0; i < msginfo.msgtql; i++) { msgq->msghdrs[i].msg_type = 0; if (i > 0) msgq->msghdrs[i-1].msg_next = i; msgq->msghdrs[i].msg_next = -1; } msgq->free_msghdrs = 0; /* Credentials are kept in shmid_ds structure. */ msgq->ds.msg_perm.seq = shmseg->shm_perm.seq; msgq->ds.first.msg_first_index = -1; msgq->ds.last.msg_last_index = -1; msgq->ds.msg_cbytes = 0; msgq->ds.msg_qnum = 0; msgq->ds.msg_qbytes = msginfo.msgmnb; msgq->ds.msg_lspid = 0; msgq->ds.msg_lrpid = 0; msgq->ds.msg_stime = 0; msgq->ds.msg_rtime = 0; munmap(addr, size); break; default: break; } unlink(filename); out: return (fd); error: close(fd); return (-1); }
/* * Find and reserve a free memory area of size 'size'. The search * starts at 'start'. * It must be called with mmap_lock() held. * Return -1 if error. */ abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size, abi_ulong align) { void *ptr, *prev; abi_ulong addr; int wrapped, repeat; align = MAX(align, qemu_host_page_size); /* If 'start' == 0, then a default start address is used. */ if (start == 0) { start = mmap_next_start; } else { start &= qemu_host_page_mask; } start = ROUND_UP(start, align); size = HOST_PAGE_ALIGN(size); if (reserved_va) { return mmap_find_vma_reserved(start, size, align); } addr = start; wrapped = repeat = 0; prev = 0; for (;; prev = ptr) { /* * Reserve needed memory area to avoid a race. * It should be discarded using: * - mmap() with MAP_FIXED flag * - mremap() with MREMAP_FIXED flag * - shmat() with SHM_REMAP flag */ ptr = mmap(g2h(addr), size, PROT_NONE, MAP_ANONYMOUS|MAP_PRIVATE|MAP_NORESERVE, -1, 0); /* ENOMEM, if host address space has no memory */ if (ptr == MAP_FAILED) { return (abi_ulong)-1; } /* Count the number of sequential returns of the same address. This is used to modify the search algorithm below. */ repeat = (ptr == prev ? repeat + 1 : 0); if (h2g_valid(ptr + size - 1)) { addr = h2g(ptr); if ((addr & (align - 1)) == 0) { /* Success. */ if (start == mmap_next_start && addr >= TASK_UNMAPPED_BASE) { mmap_next_start = addr + size; } return addr; } /* The address is not properly aligned for the target. */ switch (repeat) { case 0: /* Assume the result that the kernel gave us is the first with enough free space, so start again at the next higher target page. */ addr = ROUND_UP(addr, align); break; case 1: /* Sometimes the kernel decides to perform the allocation at the top end of memory instead. */ addr &= -align; break; case 2: /* Start over at low memory. */ addr = 0; break; default: /* Fail. This unaligned block must the last. */ addr = -1; break; } } else { /* Since the result the kernel gave didn't fit, start again at low memory. If any repetition, fail. */ addr = (repeat ? -1 : 0); } /* Unmap and try again. */ munmap(ptr, size); /* ENOMEM if we checked the whole of the target address space. */ if (addr == (abi_ulong)-1) { return (abi_ulong)-1; } else if (addr == 0) { if (wrapped) { return (abi_ulong)-1; } wrapped = 1; /* Don't actually use 0 when wrapping, instead indicate that we'd truly like an allocation in low memory. */ addr = (mmap_min_addr > TARGET_PAGE_SIZE ? TARGET_PAGE_ALIGN(mmap_min_addr) : TARGET_PAGE_SIZE); } else if (wrapped && addr >= start) { return (abi_ulong)-1; } } }
static void unmapreg(void **pmem){ if (*pmem == MAP_FAILED) return; munmap(*pmem, 4096); *pmem = MAP_FAILED; }
/* NOTE: all the constants are the HOST ones */ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, int flags, int fd, abi_ulong offset) { abi_ulong ret, end, real_start, real_end, retaddr, host_offset, host_len; mmap_lock(); #ifdef DEBUG_MMAP { printf("mmap: start=0x" TARGET_ABI_FMT_lx " len=0x" TARGET_ABI_FMT_lx " prot=%c%c%c flags=", start, len, prot & PROT_READ ? 'r' : '-', prot & PROT_WRITE ? 'w' : '-', prot & PROT_EXEC ? 'x' : '-'); if (flags & MAP_FIXED) printf("MAP_FIXED "); if (flags & MAP_ANONYMOUS) printf("MAP_ANON "); switch(flags & MAP_TYPE) { case MAP_PRIVATE: printf("MAP_PRIVATE "); break; case MAP_SHARED: printf("MAP_SHARED "); break; default: printf("[MAP_TYPE=0x%x] ", flags & MAP_TYPE); break; } printf("fd=%d offset=" TARGET_ABI_FMT_lx "\n", fd, offset); } #endif if (!len) { errno = EINVAL; goto fail; } /* Also check for overflows... */ len = TARGET_PAGE_ALIGN(len); if (!len) { errno = ENOMEM; goto fail; } if (offset & ~TARGET_PAGE_MASK) { errno = EINVAL; goto fail; } real_start = start & qemu_host_page_mask; host_offset = offset & qemu_host_page_mask; /* If the user is asking for the kernel to find a location, do that before we truncate the length for mapping files below. */ if (!(flags & MAP_FIXED)) { host_len = len + offset - host_offset; host_len = HOST_PAGE_ALIGN(host_len); start = mmap_find_vma(real_start, host_len, TARGET_PAGE_SIZE); if (start == (abi_ulong)-1) { errno = ENOMEM; goto fail; } } /* When mapping files into a memory area larger than the file, accesses to pages beyond the file size will cause a SIGBUS. For example, if mmaping a file of 100 bytes on a host with 4K pages emulating a target with 8K pages, the target expects to be able to access the first 8K. But the host will trap us on any access beyond 4K. When emulating a target with a larger page-size than the hosts, we may need to truncate file maps at EOF and add extra anonymous pages up to the targets page boundary. */ if ((qemu_real_host_page_size < qemu_host_page_size) && !(flags & MAP_ANONYMOUS)) { struct stat sb; if (fstat (fd, &sb) == -1) goto fail; /* Are we trying to create a map beyond EOF?. */ if (offset + len > sb.st_size) { /* If so, truncate the file map at eof aligned with the hosts real pagesize. Additional anonymous maps will be created beyond EOF. */ len = REAL_HOST_PAGE_ALIGN(sb.st_size - offset); } } if (!(flags & MAP_FIXED)) { unsigned long host_start; void *p; host_len = len + offset - host_offset; host_len = HOST_PAGE_ALIGN(host_len); /* Note: we prefer to control the mapping address. It is especially important if qemu_host_page_size > qemu_real_host_page_size */ p = mmap(g2h(start), host_len, prot, flags | MAP_FIXED | MAP_ANONYMOUS, -1, 0); if (p == MAP_FAILED) goto fail; /* update start so that it points to the file position at 'offset' */ host_start = (unsigned long)p; if (!(flags & MAP_ANONYMOUS)) { p = mmap(g2h(start), len, prot, flags | MAP_FIXED, fd, host_offset); if (p == MAP_FAILED) { munmap(g2h(start), host_len); goto fail; } host_start += offset - host_offset; } start = h2g(host_start); } else { if (start & ~TARGET_PAGE_MASK) { errno = EINVAL; goto fail; } end = start + len; real_end = HOST_PAGE_ALIGN(end); /* * Test if requested memory area fits target address space * It can fail only on 64-bit host with 32-bit target. * On any other target/host host mmap() handles this error correctly. */ if (!guest_range_valid(start, len)) { errno = ENOMEM; goto fail; } /* worst case: we cannot map the file because the offset is not aligned, so we read it */ if (!(flags & MAP_ANONYMOUS) && (offset & ~qemu_host_page_mask) != (start & ~qemu_host_page_mask)) { /* msync() won't work here, so we return an error if write is possible while it is a shared mapping */ if ((flags & MAP_TYPE) == MAP_SHARED && (prot & PROT_WRITE)) { errno = EINVAL; goto fail; } retaddr = target_mmap(start, len, prot | PROT_WRITE, MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); if (retaddr == -1) goto fail; if (pread(fd, g2h(start), len, offset) == -1) goto fail; if (!(prot & PROT_WRITE)) { ret = target_mprotect(start, len, prot); assert(ret == 0); } goto the_end; } /* handle the start of the mapping */ if (start > real_start) { if (real_end == real_start + qemu_host_page_size) { /* one single host page */ ret = mmap_frag(real_start, start, end, prot, flags, fd, offset); if (ret == -1) goto fail; goto the_end1; } ret = mmap_frag(real_start, start, real_start + qemu_host_page_size, prot, flags, fd, offset); if (ret == -1) goto fail; real_start += qemu_host_page_size; } /* handle the end of the mapping */ if (end < real_end) { ret = mmap_frag(real_end - qemu_host_page_size, real_end - qemu_host_page_size, end, prot, flags, fd, offset + real_end - qemu_host_page_size - start); if (ret == -1) goto fail; real_end -= qemu_host_page_size; } /* map the middle (easier) */ if (real_start < real_end) { void *p; unsigned long offset1; if (flags & MAP_ANONYMOUS) offset1 = 0; else offset1 = offset + real_start - start; p = mmap(g2h(real_start), real_end - real_start, prot, flags, fd, offset1); if (p == MAP_FAILED) goto fail; } } the_end1: page_set_flags(start, start + len, prot | PAGE_VALID); the_end: #ifdef DEBUG_MMAP printf("ret=0x" TARGET_ABI_FMT_lx "\n", start); page_dump(stdout); printf("\n"); #endif tb_invalidate_phys_range(start, start + len); mmap_unlock(); return start; fail: mmap_unlock(); return -1; }
int FileMapping::unmap ( void* anAddress, kl_size_t aNumberOfBytes ) { if ( munmap ( anAddress, aNumberOfBytes ) ) return -1; return 0; }
int target_munmap(abi_ulong start, abi_ulong len) { abi_ulong end, real_start, real_end, addr; int prot, ret; #ifdef DEBUG_MMAP printf("munmap: start=0x" TARGET_ABI_FMT_lx " len=0x" TARGET_ABI_FMT_lx "\n", start, len); #endif if (start & ~TARGET_PAGE_MASK) return -TARGET_EINVAL; len = TARGET_PAGE_ALIGN(len); if (len == 0 || !guest_range_valid(start, len)) { return -TARGET_EINVAL; } mmap_lock(); end = start + len; real_start = start & qemu_host_page_mask; real_end = HOST_PAGE_ALIGN(end); if (start > real_start) { /* handle host page containing start */ prot = 0; for(addr = real_start; addr < start; addr += TARGET_PAGE_SIZE) { prot |= page_get_flags(addr); } if (real_end == real_start + qemu_host_page_size) { for(addr = end; addr < real_end; addr += TARGET_PAGE_SIZE) { prot |= page_get_flags(addr); } end = real_end; } if (prot != 0) real_start += qemu_host_page_size; } if (end < real_end) { prot = 0; for(addr = end; addr < real_end; addr += TARGET_PAGE_SIZE) { prot |= page_get_flags(addr); } if (prot != 0) real_end -= qemu_host_page_size; } ret = 0; /* unmap what we can */ if (real_start < real_end) { if (reserved_va) { mmap_reserve(real_start, real_end - real_start); } else { ret = munmap(g2h(real_start), real_end - real_start); } } if (ret == 0) { page_set_flags(start, start + len, 0); tb_invalidate_phys_range(start, start + len); } mmap_unlock(); return ret; }
void free(void *ptr) { struct free_arena_header *ah; if (!ptr) return; ah = (struct free_arena_header *) ((struct arena_header *)ptr - 1); #ifdef DEBUG_MALLOC assert(ah->a.type == ARENA_TYPE_USED); #endif /* Merge into adjacent free blocks */ ah = __free_block(ah); /* See if it makes sense to return memory to the system */ #if _KLIBC_MALLOC_USES_SBRK if (ah->a.size >= _KLIBC_MALLOC_CHUNK_SIZE && (char *)ah + ah->a.size == __current_brk) { remove_from_chains(ah); brk(ah); } #else { size_t page_size = getpagesize(); size_t page_mask = page_size - 1; size_t head_portion = -(size_t)ah & page_mask; size_t tail_portion = ((size_t)ah + ah->a.size) & page_mask; size_t adj_size; /* Careful here... an individual chunk of memory must have a minimum size if it exists at all, so if either the head or the tail is below the minimum, then extend that chunk by a page. */ if (head_portion && head_portion < 2*sizeof(struct arena_header)) head_portion += page_size; if (tail_portion && tail_portion < 2*sizeof(struct arena_header)) tail_portion += page_size; adj_size = ah->a.size - head_portion - tail_portion; /* Worth it? This is written the way it is to guard against overflows... */ if (ah->a.size >= head_portion+tail_portion+ _KLIBC_MALLOC_CHUNK_SIZE) { struct free_arena_header *tah, *tan, *tap; if (tail_portion) { /* Make a new header, and insert into chains immediately after the current block */ tah = (struct free_arena_header *) ((char *)ah + head_portion + adj_size); tah->a.type = ARENA_TYPE_FREE; tah->a.size = tail_portion; tah->a.next = tan = ah->a.next; tan->a.prev = tah; tah->a.prev = ah; ah->a.next = tah; tah->prev_free = tap = ah->prev_free; tap->next_free = tah; tah->next_free = ah; ah->prev_free = tah; } if (head_portion) ah->a.size = head_portion; else remove_from_chains(ah); munmap((char *)ah + head_portion, adj_size); } } #endif }
int main (int argc, char **argv) { int tv,index,i,j,cmct=CMCT,cmc=CMC,trnspi=TRANSP,trnsp=0,found,loop=1,first=1,x0,x1,x2,x3,x4,x5,x6,x7; int xdir=1, ydir=1; double xstep=1, ystep=1; double csx, cex, csy, cey; time_t atim; struct tm *ltim; char *aptr,*rptr; char dstr[2]= {0,0}; printf("SSaver Version %s\n",CL_VERSION); ReadConf(); for(i=1; i<argc; i++) { aptr=argv[i]; if((rptr=strchr(aptr,'='))!=NULL) { rptr++; if(strstr(aptr,"DATE=")!=NULL) { if(sscanf(rptr,"%d",&j)==1) { sdat=j; } } if(strstr(aptr,"BIG=")!=NULL) { if(sscanf(rptr,"%d",&j)==1) { big=(j)?1:0; } } if(strstr(aptr,"SEC=")!=NULL) { if(sscanf(rptr,"%d",&j)==1) { secs=j; } } if(strstr(aptr,"SLOW=")!=NULL) { if(sscanf(rptr,"%d",&j)==1) { if(!j) { j=1; } slow=j; } } if(strstr(aptr,"FCOL=")!=NULL) { if(sscanf(rptr,"%d",&j)==1) { fcol=j; } } if(strstr(aptr,"BCOL=")!=NULL) { if(sscanf(rptr,"%d",&j)==1) { bcol=j; } } } } if((sx=Read_Neutrino_Cfg("screen_StartX"))<0) sx=80; if((ex=Read_Neutrino_Cfg("screen_EndX"))<0) ex=620; if((sy=Read_Neutrino_Cfg("screen_StartY"))<0) sy=80; if((ey=Read_Neutrino_Cfg("screen_EndY"))<0) ey=505; if(!slow) { slow=1; } if(slow>10) { slow=10; } xpos=ex/2; ypos=ey/2; for(index=CMCST; index<=CMH; index++) { sprintf(tstr,"menu_%s_alpha",menucoltxt[index-1]); if((tv=Read_Neutrino_Cfg(tstr))>=0) tr[index-1]=(tv<<8); sprintf(tstr,"menu_%s_blue",menucoltxt[index-1]); if((tv=Read_Neutrino_Cfg(tstr))>=0) bl[index-1]=(tv+(tv<<8)); sprintf(tstr,"menu_%s_green",menucoltxt[index-1]); if((tv=Read_Neutrino_Cfg(tstr))>=0) gn[index-1]=(tv+(tv<<8)); sprintf(tstr,"menu_%s_red",menucoltxt[index-1]); if((tv=Read_Neutrino_Cfg(tstr))>=0) rd[index-1]=(tv+(tv<<8)); } fb = open(FB_DEVICE, O_RDWR); if(ioctl(fb, FBIOGET_FSCREENINFO, &fix_screeninfo) == -1) { printf("Clock <FBIOGET_FSCREENINFO failed>\n"); return -1; } if(ioctl(fb, FBIOGET_VSCREENINFO, &var_screeninfo) == -1) { printf("Clock <FBIOGET_VSCREENINFO failed>\n"); return -1; } if(ioctl(fb, FBIOGETCMAP, &colormap) == -1) { printf("Clock <FBIOGETCMAP failed>\n"); return -1; } if(!(lfb = (unsigned char*)mmap(0, fix_screeninfo.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, fb, 0))) { printf("Clock <mapping of Framebuffer failed>\n"); return -1; } //init fontlibrary if((error = FT_Init_FreeType(&library))) { printf("Clock <FT_Init_FreeType failed with Errorcode 0x%.2X>", error); munmap(lfb, fix_screeninfo.smem_len); return -1; } if((error = FTC_Manager_New(library, 1, 2, 0, &MyFaceRequester, NULL, &manager))) { printf("Clock <FTC_Manager_New failed with Errorcode 0x%.2X>\n", error); FT_Done_FreeType(library); munmap(lfb, fix_screeninfo.smem_len); return -1; } if((error = FTC_SBitCache_New(manager, &cache))) { printf("Clock <FTC_SBitCache_New failed with Errorcode 0x%.2X>\n", error); FTC_Manager_Done(manager); FT_Done_FreeType(library); munmap(lfb, fix_screeninfo.smem_len); return -1; } if((error = FTC_Manager_LookupFace(manager, FONT, &face))) { printf("Clock <FTC_Manager_LookupFace failed with Errorcode 0x%.2X>\n", error); FTC_Manager_Done(manager); FT_Done_FreeType(library); munmap(lfb, fix_screeninfo.smem_len); return -1; } use_kerning = FT_HAS_KERNING(face); desc.face_id = FONT; desc.flags = FT_LOAD_MONOCHROME; if(!(lbb = malloc(var_screeninfo.xres*var_screeninfo.yres))) { printf("Clock <allocating of Backbuffer failed>\n"); FTC_Manager_Done(manager); FT_Done_FreeType(library); munmap(lfb, fix_screeninfo.smem_len); return -1; } memset(lbb, 0, var_screeninfo.xres*var_screeninfo.yres); startx = sx; starty = sy; xstep/=(double)slow; ystep/=(double)slow; InitRC(); while(loop) { usleep(15000L); ioctl(fb, FBIOGETCMAP, &colormap); found=0; trnsp=0; for(i=colormap.start; i<colormap.len && found!=7; i++) { if(!colormap.red[i] && !colormap.green[i] && !colormap.blue[i] && !colormap.transp[i]) { cmc=i; found|=1; } if(colormap.red[i]>=0xF000 && colormap.green[i]>=0xF000 && colormap.blue[i]>=0xF000 && !colormap.transp[i]) { cmct=i; found|=2; } if(colormap.transp[i]>trnsp) { trnspi=i; trnsp=colormap.transp[i]; found|=4; } } if(first) { first=0; memset(lbb, (bcol==0)?trnspi:((bcol==1)?cmc:cmct), var_screeninfo.xres*var_screeninfo.yres); memset(lfb, (bcol==0)?trnspi:((bcol==1)?cmc:cmct), var_screeninfo.xres*var_screeninfo.yres); } if(big) { x0=3; x1=14; x2=26; x3=BIG; x4=30; x5=60; } else { x0=7; x1=12; x2=18; x3=MED; x4=18; x5=40; } x6=0; x7=0; time(&atim); ltim=localtime(&atim); if(secs) { sprintf(tstr,"%02d:%02d:%02d",ltim->tm_hour,ltim->tm_min,ltim->tm_sec); } else { sprintf(tstr," %02d%c%02d",ltim->tm_hour,(ltim->tm_sec & 1)?':':' ',ltim->tm_min); if(!sdat) { x6=3; x7=36+4*big; } } xpos+=xstep*(double)xdir; ypos+=ystep*(double)ydir; csx=xpos+x7; csy=ypos; cex=xpos+x7+100+20*big; cey=ypos+x2+2*(1+big)+sdat*x4; if(csx<0 || (sx+cex)>=ex) { xdir*=-1; xpos+=xstep*(double)xdir; csx=xpos+x7; cex=xpos+x7+100+20*big; xstep=rand()&3; if(!xstep) { xstep=1; } xstep/=(double)slow; } if(csy<0 || (sy+cey)>=ey) { ydir*=-1; ypos+=ystep*(double)ydir; csy=ypos; cey=ypos+x2+2*(1+big)+sdat*x4; ystep=rand()&3; if(!ystep || (ystep==3 && ydir==1)) { ystep=1; } ystep/=(double)slow; } for(i=x6; i<strlen(tstr); i++) { *dstr=tstr[i]; RenderString(dstr, xpos-x0+(i*x1), ypos+x2, 30, CENTER, x3, (fcol==0)?trnspi:((fcol==2)?cmct:cmc)); } if(sdat) { sprintf(tstr,"%02d.%02d.%02d",ltim->tm_mday,ltim->tm_mon+1,ltim->tm_year-100); for(i=0; i<strlen(tstr); i++) { *dstr=tstr[i]; RenderString(dstr, xpos-x0+(i*x1), ypos+x5-2-2*big, 30, CENTER, x3, (fcol==0)?trnspi:((fcol==2)?cmct:cmc)); } } for(i=0; i<=((sdat)?40:20)*(1+big); i++) { j=(starty+ypos+i)*var_screeninfo.xres+xpos+startx; if((j+100+20*big)<var_screeninfo.xres*var_screeninfo.yres) { memcpy(lfb+j, lbb+j, 100+20*big); } } RenderBox(csx, csy, cex, cey, FILL, (bcol==0)?trnspi:((bcol==1)?cmc:cmct)); if(++loop>10) { if(RCKeyPressed()||ExistFile("/tmp/.ssaver_kill")) { loop=0; } } } cmct=0; cmc=0; for(i=colormap.start; i<colormap.len; i++) { if(colormap.transp[i]>cmct) { cmc=i; cmct=colormap.transp[i]; } } memset(lfb, cmc, var_screeninfo.xres*var_screeninfo.yres); FTC_Manager_Done(manager); FT_Done_FreeType(library); free(lbb); munmap(lfb, fix_screeninfo.smem_len); close(fb); CloseRC(); remove("/tmp/.ssaver_kill"); return 0; }
int ctrl_cleanup() { munmap(ctrlMem, AM335X_CTRL_SIZE); close(mem_fd); }
void coopth_done(void) { int i, tt, itd, it; struct coopth_thrdata_t *thdata = NULL; it = _coopth_is_in_thread_nowarn(); itd = it; // assert(!it || is_detached()); if (it) { thdata = co_get_data(co_current(co_handle)); assert(thdata); /* unfortunately the shutdown can run from signal handler - * in this case we can be in a joinable thread interrupted * by signal, and there is no way to leave that thread. */ if (!is_detached()) itd = 0; } /* there is no safe way to delete joinable threads without joining, * so print error only if there are also detached threads left */ if (threads_total > threads_joinable + itd) error("Coopth: not all detached threads properly shut down\n"); again: tt = threads_total; for (i = 0; i < threads_active; i++) { int tid = active_tids[i]; struct coopth_t *thr = &coopthreads[tid]; struct coopth_per_thread_t *pth = current_thr(thr); /* dont cancel own thread */ if (thdata && *thdata->tid == tid) continue; if (!pth->data.attached) { error("\ttid=%i state=%i name=\"%s\" off=%#x\n", tid, pth->st.state, thr->name, thr->off); do_cancel(thr, pth); assert(threads_total == tt - 1); /* retry the loop as the array changed */ goto again; } else { g_printf("\ttid=%i state=%i name=%s off=%#x\n", tid, pth->st.state, thr->name, thr->off); } } /* at this point all detached threads should be killed, * except perhaps current one */ assert(threads_total == threads_joinable + itd); for (i = 0; i < coopth_num; i++) { struct coopth_t *thr = &coopthreads[i]; int j; /* dont free own thread */ if (thdata && *thdata->tid == i) continue; for (j = thr->cur_thr; j < thr->max_thr; j++) { struct coopth_per_thread_t *pth = &thr->pth[j]; munmap(pth->stack, pth->stk_size); } } if (!threads_total) co_thread_cleanup(co_handle); else g_printf("coopth: leaked %i threads\n", threads_total); }
/* ------------------------------------------------------------ */ int main() { list_audio_devices(alcGetString(NULL, ALC_DEVICE_SPECIFIER)); /* BBBIOlib init*/ iolib_init(); iolib_setdir(8,11, BBBIO_DIR_IN); /* Button */ iolib_setdir(8,12, BBBIO_DIR_OUT); /* LED */ // sys_info.capability = SYS_CAPABILITY_VIDEO_Tx | SYS_CAPABILITY_VIDEO_Rx | SYS_CAPABILITY_AUDIO_Tx | SYS_CAPABILITY_AUDIO_Rx; // sys_info.capability = SYS_CAPABILITY_VIDEO_Tx | SYS_CAPABILITY_AUDIO_Tx; sys_info.capability =SYS_CAPABILITY_AUDIO_Rx | SYS_CAPABILITY_VIDEO_Rx; // sys_info.capability = SYS_CAPABILITY_VIDEO_Tx; sys_info.status = SYS_STATUS_INIT; sys_info.cam.width = 320; sys_info.cam.height = 240; // sys_info.cam.pixel_fmt = V4L2_PIX_FMT_YUV420; sys_info.cam.pixel_fmt = V4L2_PIX_FMT_YUYV; /* alloc RGB565 buffer for frame buffer data store */ RGB565_buffer = (unsigned char *)malloc(sys_info.cam.width * sys_info.cam.height *2); /* step Codec register */ avcodec_register_all(); av_register_all(); video_encoder_init(sys_info.cam.width, sys_info.cam.height, sys_info.cam.pixel_fmt); video_decoder_init(sys_info.cam.width, sys_info.cam.height, sys_info.cam.pixel_fmt); printf("Codec init finish\n"); /* step Frame buffer initial*/ if(FB_init() == 0) { fprintf(stderr, "Frame Buffer init error\n"); } FB_clear(var_info.xres, var_info.yres); sys_set_status(SYS_STATUS_IDLE); /* Create Video thread */ if(sys_info.capability & SYS_CAPABILITY_VIDEO_Rx) pthread_create(&Video_Rx_thread, NULL, Video_Rx_loop, NULL); if(sys_info.capability & SYS_CAPABILITY_VIDEO_Tx) pthread_create(&Video_Tx_thread, NULL, Video_Tx_loop, NULL); /* Create Audio thread*/ if(sys_info.capability & SYS_CAPABILITY_AUDIO_Rx) pthread_create(&Audio_Rx_thread, NULL, Audio_Rx_loop, NULL); if(sys_info.capability & SYS_CAPABILITY_AUDIO_Tx) pthread_create(&Audio_Tx_thread, NULL, Audio_Tx_loop, NULL); /* Signale SIGINT */ signal(SIGINT, SIGINT_release); /* Main loop */ while(sys_get_status() != SYS_STATUS_RELEASE) { /* Button on */ if (is_high(8,11)) { sys_set_status(SYS_STATUS_WORK); pin_high(8, 12); /* LED on*/ } else { // FB_clear(var_info.xres, var_info.yres); // sys_set_status(SYS_STATUS_IDLE); sys_set_status(SYS_STATUS_WORK); pin_low(8, 12); /* LED off */ } //usleep(100000); sleep(1); } pin_low(8, 12); /* LED off */ /* ******************************************************* * Main thread for SIP server communication and HW process * * * *******************************************************/ /* release */ if(sys_info.capability & SYS_CAPABILITY_VIDEO_Tx) pthread_join(Video_Tx_thread,NULL); if(sys_info.capability & SYS_CAPABILITY_VIDEO_Rx) pthread_join(Video_Rx_thread,NULL); if(sys_info.capability & SYS_CAPABILITY_AUDIO_Tx) pthread_join(Audio_Tx_thread,NULL); if(sys_info.capability & SYS_CAPABILITY_AUDIO_Rx) pthread_join(Audio_Rx_thread,NULL); munmap(FB_ptr, FB_scerrn_size); close(FB); free(RGB565_buffer); video_encoder_release(); video_decoder_release(); printf("finish\n"); return 0; }
/* * _prop_object_internalize_map_file -- * Map a file for the purpose of internalizing it. */ struct _prop_object_internalize_mapped_file * _prop_object_internalize_map_file(const char *fname) { struct stat sb; struct _prop_object_internalize_mapped_file *mf; size_t pgsize = (size_t)sysconf(_SC_PAGESIZE); size_t pgmask = pgsize - 1; bool need_guard = false; int fd; mf = _PROP_MALLOC(sizeof(*mf), M_TEMP); if (mf == NULL) return (NULL); fd = open(fname, O_RDONLY, 0400); if (fd == -1) { _PROP_FREE(mf, M_TEMP); return (NULL); } if (fstat(fd, &sb) == -1) { (void) close(fd); _PROP_FREE(mf, M_TEMP); return (NULL); } mf->poimf_mapsize = ((size_t)sb.st_size + pgmask) & ~pgmask; if (mf->poimf_mapsize < (size_t)sb.st_size) { (void) close(fd); _PROP_FREE(mf, M_TEMP); return (NULL); } /* * If the file length is an integral number of pages, then we * need to map a guard page at the end in order to provide the * necessary NUL-termination of the buffer. */ if ((sb.st_size & pgmask) == 0) need_guard = true; mf->poimf_xml = mmap(NULL, need_guard ? mf->poimf_mapsize + pgsize : mf->poimf_mapsize, PROT_READ, MAP_FILE|MAP_SHARED, fd, (off_t)0); (void) close(fd); if (mf->poimf_xml == MAP_FAILED) { _PROP_FREE(mf, M_TEMP); return (NULL); } (void) madvise(mf->poimf_xml, mf->poimf_mapsize, MADV_SEQUENTIAL); if (need_guard) { if (mmap(mf->poimf_xml + mf->poimf_mapsize, pgsize, PROT_READ, MAP_ANON|MAP_PRIVATE|MAP_FIXED, -1, (off_t)0) == MAP_FAILED) { (void) munmap(mf->poimf_xml, mf->poimf_mapsize); _PROP_FREE(mf, M_TEMP); return (NULL); } mf->poimf_mapsize += pgsize; } return (mf); }
int main(int argc, char** argv) { int i; int child_ret; pid_t pid; const char* smem_name = "/SHARE"; /* name of the shared memory area */ int smem_fd; /* shared memory file descriptor */ size_t smem_size = 1024; /* size in bytes */ int* smem_ptr; /* Create the shared memory area and get a file descriptor to it */ smem_fd = shm_open(smem_name, O_CREAT | O_RDWR, 0666); /* set the size as you normally would with a file via ftruncate */ ftruncate(smem_fd, smem_size); /* map the file (i.e. shared memory) into memory */ smem_ptr = mmap(0, smem_size, PROT_WRITE | PROT_READ, MAP_SHARED, smem_fd, 0); /* write some data into shared memory */ for (i=0; i<10; i++) { smem_ptr[i] = i; } /* Fork a child process */ pid = fork(); if (pid < 0) { fprintf(stderr, "error -- fork() failed\n"); exit(1); } if (pid == 0) { /* only the CHILD executes this */ for (i=0; i<10; i++) { /* read values from shared memory and display */ printf("child -- smem_ptr[%i]: %i\n", i, smem_ptr[i]); /* also increment each value by 5 */ smem_ptr[i] += 5; } exit(0); } wait(&child_ret); /* have the parent read and display the contents of shared memory */ printf("---------------------\n"); for (i=0; i<10; i++) { /* read values from shared memory and display */ printf("parent -- smem_ptr[%i]: %i\n", i, smem_ptr[i]); } /* tear down shared memory region */ munmap(smem_ptr, smem_size); close(smem_fd); shm_unlink(smem_name); }
static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry, unsigned int *flags, struct ebt_entry_match **match) { struct ebt_among_info *info = (struct ebt_among_info *) (*match)->data; struct ebt_mac_wormhash *wh; struct ebt_entry_match *h; int new_size; long flen; int fd; switch (c) { case AMONG_DST_F: case AMONG_SRC_F: case AMONG_DST: case AMONG_SRC: if (c == AMONG_DST || c == AMONG_DST_F) { ebt_check_option2(flags, OPT_DST); } else { ebt_check_option2(flags, OPT_SRC); } if (ebt_check_inverse2(optarg)) { if (c == AMONG_DST || c == AMONG_DST_F) info->bitmask |= EBT_AMONG_DST_NEG; else info->bitmask |= EBT_AMONG_SRC_NEG; } if (c == AMONG_DST_F || c == AMONG_SRC_F) { struct stat stats; if ((fd = open(optarg, O_RDONLY)) == -1) ebt_print_error("Couldn't open file '%s'", optarg); fstat(fd, &stats); flen = stats.st_size; /* use mmap because the file will probably be big */ optarg = mmap(0, flen, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0); if (optarg == MAP_FAILED) ebt_print_error("Couldn't map file to memory"); if (optarg[flen-1] != '\n') ebt_print_error("File should end with a newline"); if (strchr(optarg, '\n') != optarg+flen-1) ebt_print_error("File should only contain one line"); optarg[flen-1] = '\0'; if (ebt_errormsg[0] != '\0') { munmap(argv, flen); close(fd); exit(-1); } } wh = create_wormhash(optarg); if (ebt_errormsg[0] != '\0') break; new_size = old_size+ebt_mac_wormhash_size(wh); h = malloc(sizeof(struct ebt_entry_match)+EBT_ALIGN(new_size)); if (!h) ebt_print_memory(); memcpy(h, *match, old_size+sizeof(struct ebt_entry_match)); memcpy((char *)h+old_size+sizeof(struct ebt_entry_match), wh, ebt_mac_wormhash_size(wh)); h->match_size = EBT_ALIGN(new_size); info = (struct ebt_among_info *) h->data; if (c == AMONG_DST) { info->wh_dst_ofs = old_size; } else { info->wh_src_ofs = old_size; } old_size = new_size; free(*match); *match = h; free(wh); if (c == AMONG_DST_F || c == AMONG_SRC_F) { munmap(argv, flen); close(fd); } break; default: return 0; } return 1; }
static void destroyMarkStack(GcMarkStack *stack) { munmap((char *)stack->limit, (uintptr_t)stack->base - (uintptr_t)stack->limit); memset(stack, 0, sizeof(*stack)); }
extern "C" ssize_t read(int fd, void *buf, size_t count) { ssize_t ret; if (!eminfo || eminfo->currently_detached()) { if (!shim_read) { shim_read = (ssize_t (*)(int, void *, size_t))dlsym (RTLD_NEXT, "read"); } return ((shim_read)(fd, buf, count)); } if (!is_regular[fd]) { struct pollfd pfd; pfd.fd = fd; pfd.events = POLLIN; ((shim_poll)(&pfd, 1, 0)); if (pfd.revents & POLLIN) { // if it won't block return ((shim_read)(fd, buf, count)); } } else { /* Use mmap and mincore to find out if the page is in memory, if YES, then just do the read if NO, then use the thread-pool to fake asynch IO */ off_t off = lseek(fd, 0, SEEK_CUR); void *addr = mmap(0, count, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, off); int len = (count+page_size-1) / page_size; unsigned char *vec = new unsigned char[len]; //int rt = -- unused #ifdef LINUX mincore((char*)addr, count, (unsigned char*)vec); #else mincore((char*)addr, count, (char*)vec); #endif munmap(addr, count); bool in_memory = true; for (int i=0; i< len; i++) { if (vec[i] == 0) { in_memory = false; break; } } delete [] vec; if (in_memory) { return ((shim_read)(fd, buf, count)); } } int mgr_awake = eminfo->wake_another_thread(); oflux::WaitingToRunRAII wtr_raii(eminfo->thread()); SHIM_CALL("read"); { oflux::UnlockRunTime urt(eminfo); ret = ((shim_read)(fd, buf, count)); } SHIM_WAIT("read"); if (mgr_awake == 0) { wtr_raii.state_wtr(); eminfo->wait_to_run(); } SHIM_RETURN("read"); return ret; }