void obs_output_end_data_capture(obs_output_t *output) { bool encoded, has_video, has_audio, has_service; encoded_callback_t encoded_callback; if (!output) return; if (!output->active) return; convert_flags(output, 0, &encoded, &has_video, &has_audio, &has_service); if (encoded) { encoded_callback = (has_video && has_audio) ? interleave_packets : default_encoded_callback; if (has_video) obs_encoder_stop(output->video_encoder, encoded_callback, output); if (has_audio) stop_audio_encoders(output, encoded_callback); } else { if (has_video) video_output_disconnect(output->video, default_raw_video_callback, output); if (has_audio) audio_output_disconnect(output->audio, output->mixer_idx, default_raw_audio_callback, output); } if (has_service) obs_service_deactivate(output->service, false); output->active = false; }
bool obs_output_initialize_encoders(obs_output_t *output, uint32_t flags) { bool encoded, has_video, has_audio, has_service; size_t num_mixes = num_audio_mixes(output); if (!output) return false; if (output->active) return false; convert_flags(output, flags, &encoded, &has_video, &has_audio, &has_service); if (!encoded) return false; if (has_service && !obs_service_initialize(output->service, output)) return false; if (has_video && !obs_encoder_initialize(output->video_encoder)) return false; if (has_audio && !initialize_audio_encoders(output, num_mixes)) return false; if (has_video && has_audio) { if (!pair_encoders(output, num_mixes)) { return false; } } return true; }
bool obs_output_begin_data_capture(obs_output_t output, uint32_t flags) { bool encoded, has_video, has_audio, has_service; if (!output) return false; if (output->active) return false; convert_flags(output, flags, &encoded, &has_video, &has_audio, &has_service); if (!can_begin_data_capture(output, encoded, has_video, has_audio, has_service)) return false; hook_data_capture(output, encoded, has_video, has_audio); if (has_service) obs_service_activate(output->service); output->active = true; if (output->reconnecting) { signal_reconnect_success(output); output->reconnecting = false; } else { signal_start(output); } return true; }
static newtComponent nmt_newt_listbox_build_component (NmtNewtComponent *component, gboolean sensitive) { NmtNewtListboxPrivate *priv = NMT_NEWT_LISTBOX_GET_PRIVATE (component); newtComponent co; int i, active; if (priv->active == -1) update_active_internal (NMT_NEWT_LISTBOX (component), 0); active = priv->active; co = newtListbox (-1, -1, priv->height, convert_flags (priv->flags)); newtComponentAddCallback (co, selection_changed_callback, component); for (i = 0; i < priv->entries->len; i++) { newtListboxAppendEntry (co, priv->entries->pdata[i], GUINT_TO_POINTER (i)); if (active == -1 && priv->keys->pdata[i] == priv->active_key) active = i; } if (active != -1) newtListboxSetCurrent (co, active); return co; }
bool obs_output_initialize_encoders(obs_output_t output, uint32_t flags) { bool encoded, has_video, has_audio, has_service; if (!output) return false; if (output->active) return false; convert_flags(output, flags, &encoded, &has_video, &has_audio, &has_service); if (!encoded) return false; if (has_service && !obs_service_initialize(output->service, output)) return false; if (has_video && !obs_encoder_initialize(output->video_encoder)) return false; if (has_audio && !obs_encoder_initialize(output->audio_encoder)) return false; if (has_video && has_audio && !output->audio_encoder->active && !output->video_encoder->active) { output->audio_encoder->wait_for_video = true; output->video_encoder->paired_encoder = output->audio_encoder; output->audio_encoder->paired_encoder = output->video_encoder; } return true; }
int impl_fuse_context::do_create_file(LPCWSTR FileName, DWORD Disposition, DWORD share_mode, DWORD Flags, PDOKAN_FILE_INFO DokanFileInfo) { std::string fname=unixify(wchar_to_utf8_cstr(FileName)); //Create file? if (Disposition!=CREATE_NEW && Disposition!=CREATE_ALWAYS && Disposition!=OPEN_ALWAYS) return -ENOENT; //No, we're trying to open an existing file! if (!ops_.create) { //Use mknod+open. if (!ops_.mknod || !ops_.open) return -EINVAL; CHECKED(ops_.mknod(fname.c_str(),filemask_,0)); return do_open_file(FileName, share_mode, Flags, DokanFileInfo); } std::auto_ptr<impl_file_handle> file; CHECKED(file_locks.get_file(fname,false,Flags,share_mode,file)); fuse_file_info finfo={0}; finfo.flags=O_CREAT | O_EXCL | convert_flags(Flags); //TODO: these flags should be OK for new files? CHECKED(ops_.create(fname.c_str(),filemask_,&finfo)); DokanFileInfo->Context=reinterpret_cast<ULONG64>(file.release()); return 0; }
int link_open(link_transport_mdriver_t * driver, const char * path, int flags, ...){ link_op_t op; link_reply_t reply; link_mode_t mode; int err; va_list ap; if ( flags & LINK_O_CREAT ){ va_start(ap, flags); mode = va_arg(ap, link_mode_t); va_end(ap); } else { mode = 0; } if( driver == 0 ){ return posix_open(path, convert_flags(flags) | POSIX_OPEN_FLAGS, mode); } link_debug(LINK_DEBUG_MESSAGE, "open %s 0%o 0x%X using %p", path, mode, flags, driver->dev.handle); op.open.cmd = LINK_CMD_OPEN; op.open.path_size = strlen(path) + 1; op.open.flags = flags; op.open.mode = mode; link_debug(LINK_DEBUG_MESSAGE, "Write open op (%p)", driver->dev.handle); err = link_transport_masterwrite(driver, &op, sizeof(link_open_t)); if ( err < 0 ){ link_error("failed to write open op with handle %p", driver->dev.handle); return link_handle_err(driver, err); } //Send the path on the bulk out endpoint link_debug(LINK_DEBUG_MESSAGE, "Write open path (%d bytes)", op.open.path_size); err = link_transport_masterwrite(driver, path, op.open.path_size); if ( err < 0 ){ link_error("failed to write path"); return link_handle_err(driver, err); } //read the reply to see if the file opened correctly err = link_transport_masterread(driver, &reply, sizeof(reply)); if ( err < 0 ){ link_error("failed to read the reply"); return link_handle_err(driver, err); } if ( reply.err < 0 ){ link_errno = reply.err_number; link_debug(LINK_DEBUG_WARNING, "Failed to ioctl file (%d)", link_errno); } else { link_debug(LINK_DEBUG_MESSAGE, "Opened fildes: %d", reply.err); } return reply.err; }
w_rc_t sdisk_unix_t::open(const char *name, int flags, int mode) { if (_fd != FD_NONE) return RC(stBADFD); /* XXX in use */ _fd = ::os_open(name, convert_flags(flags), mode); CHECK_ERRNO(_fd); return RCOK; }
struct result *unix_waitpid(array flags, int pid_req) { int pid, status; pid = waitpid(pid_req, &status, convert_flags(flags, wait_flag_table)); if (pid == -1) unix_error(__FILE__,__LINE__,"waitpid"); return alloc_process_status(pid, status); }
w_rc_t sdisk_unix_t::open(const char *name, int flags, int mode) { if (_fd != FD_NONE) return RC(stBADFD); /* XXX in use */ _fd = ::os_open(name, convert_flags(flags), mode); if (_fd == -1) { w_rc_t rc = RC(fcOS); RC_APPEND_MSG(rc, << "Offending file: " << name << " mode " << mode); return rc; }
bool obs_output_can_begin_data_capture(obs_output_t output, uint32_t flags) { bool encoded, has_video, has_audio, has_service; if (!output) return false; if (output->active) return false; convert_flags(output, flags, &encoded, &has_video, &has_audio, &has_service); return can_begin_data_capture(output, encoded, has_video, has_audio, has_service); }
int cl_db_open(const char *name,int flags) { int err = -1; int fd; int handle; int mode = 0; if(!name) goto out; /*Check if already open*/ if(cl_db_inuse(name)) { output("Database %s already in use",name); goto out; } mode = convert_flags(flags); fd = open(name,mode,0644); if(fd < 0 ) { if((flags & CLDB_APPEND) && !(flags & CLDB_CREAT)) { flags |= CLDB_CREAT | CLDB_TRUNC; mode |= O_CREAT | O_TRUNC; fd = open(name,mode,0644); } if(fd < 0 ) { output("Error in opening file %s with flags:%d",name,flags); goto out; } } handle = cl_db_handle_get(); if(handle < 0 ) { output("CL DB instances reached maximum limit of %d",MAX_CL_DB_INSTANCES); goto out; } strncpy(cl_db_instances[handle].name,name,sizeof(cl_db_instances[handle].name)-1); cl_db_instances[handle].fd = fd; cl_db_cache_init(handle); if(!(flags & CLDB_CREAT)) { if(cl_db_read_db(handle) < 0) { output("Error in reading the database:%s",name); close(fd); cl_db_handle_free(handle); goto out; } } else { cl_db_init(handle); } err = handle; out: return err; }
void obs_output_end_data_capture(obs_output_t *output) { bool encoded, has_video, has_audio, has_service; encoded_callback_t encoded_callback; if (!obs_output_valid(output, "obs_output_end_data_capture")) return; if (output->delay_active) { output->delay_capturing = false; return; } if (!output->active) return; convert_flags(output, 0, &encoded, &has_video, &has_audio, &has_service); if (encoded) { if (output->active_delay_ns) encoded_callback = process_delay; else encoded_callback = (has_video && has_audio) ? interleave_packets : default_encoded_callback; if (has_video) obs_encoder_stop(output->video_encoder, encoded_callback, output); if (has_audio) stop_audio_encoders(output, encoded_callback); } else { if (has_video) video_output_disconnect(output->video, default_raw_video_callback, output); if (has_audio) audio_output_disconnect(output->audio, output->mixer_idx, default_raw_audio_callback, output); } if (has_service) obs_service_deactivate(output->service, false); if (output->active_delay_ns) obs_output_cleanup_delay(output); do_output_signal(output, "deactivate"); output->active = false; }
int impl_fuse_context::do_open_file(LPCWSTR FileName, DWORD Flags, PDOKAN_FILE_INFO DokanFileInfo) { if (!ops_.open) return -EINVAL; std::string fname=unixify(wchar_to_utf8_cstr(FileName)); CHECKED(check_and_resolve(&fname)); fuse_file_info finfo={0}; //if ((ShareMode & FILE_SHARE_READ) || (ShareMode & FILE_SHARE_DELETE)) //TODO: add sharing support? finfo.flags=convert_flags(Flags); CHECKED(ops_.open(fname.c_str(),&finfo)); DokanFileInfo->Context=reinterpret_cast<ULONG64>(new impl_file_handle(fname,false,&finfo)); return 0; }
bool obs_output_can_begin_data_capture(const obs_output_t *output, uint32_t flags) { bool encoded, has_video, has_audio, has_service; if (!obs_output_valid(output, "obs_output_can_begin_data_capture")) return false; if (output->delay_active) return true; if (output->active) return false; convert_flags(output, flags, &encoded, &has_video, &has_audio, &has_service); return can_begin_data_capture(output, encoded, has_video, has_audio, has_service); }
static void *end_data_capture_thread(void *data) { bool encoded, has_video, has_audio, has_service; encoded_callback_t encoded_callback; obs_output_t *output = data; convert_flags(output, 0, &encoded, &has_video, &has_audio, &has_service); if (encoded) { if (output->active_delay_ns) encoded_callback = process_delay; else encoded_callback = (has_video && has_audio) ? interleave_packets : default_encoded_callback; if (has_video) obs_encoder_stop(output->video_encoder, encoded_callback, output); if (has_audio) stop_audio_encoders(output, encoded_callback); } else { if (has_video) video_output_disconnect(output->video, default_raw_video_callback, output); if (has_audio) audio_output_disconnect(output->audio, output->mixer_idx, default_raw_audio_callback, output); } if (has_service) obs_service_deactivate(output->service, false); if (output->active_delay_ns) obs_output_cleanup_delay(output); do_output_signal(output, "deactivate"); os_atomic_set_bool(&output->active, false); os_event_signal(output->stopping_event); os_atomic_set_bool(&output->end_data_capture_thread_active, false); return NULL; }
int impl_fuse_context::do_open_file(LPCWSTR FileName, DWORD share_mode, DWORD Flags, PDOKAN_FILE_INFO DokanFileInfo) { if (!ops_.open) return -EINVAL; std::string fname=unixify(wchar_to_utf8_cstr(FileName)); CHECKED(check_and_resolve(&fname)); std::auto_ptr<impl_file_handle> file; CHECKED(file_locks.get_file(fname,false,Flags,share_mode,file)); fuse_file_info finfo={0}; finfo.flags=convert_flags(Flags); CHECKED(ops_.open(fname.c_str(),&finfo)); file->set_finfo(finfo); DokanFileInfo->Context=reinterpret_cast<ULONG64>(file.release()); return 0; }
bool obs_output_can_begin_data_capture(const obs_output_t *output, uint32_t flags) { bool encoded, has_video, has_audio, has_service; if (!obs_output_valid(output, "obs_output_can_begin_data_capture")) return false; if (delay_active(output)) return true; if (active(output)) return false; if (data_capture_ending(output)) pthread_join(output->end_data_capture_thread, NULL); convert_flags(output, flags, &encoded, &has_video, &has_audio, &has_service); return can_begin_data_capture(output, encoded, has_video, has_audio, has_service); }
static gint cb_mouse_motion (GtkWidget * ww, GdkEventMotion * ee) { int mx, my; GdkModifierType modifier; gdk_window_get_pointer(ww->window, &mx, &my, &modifier); int flags (convert_flags (ee->state, -1) | MOUSE_DRAG); if (dbgos) { *dbgos << __func__ << " " << mx << " -> " << c2vx (mx) << " " << my << " -> " << c2vy (my) << " " << (gdk_flags_t) ee->state << " -> " << (mouse_flags_t) flags << "\n"; } mouse_cb (c2vx (mx), c2vy (my), flags); gtk_widget_queue_draw (canvas); return TRUE; }
bool obs_output_begin_data_capture(obs_output_t *output, uint32_t flags) { bool encoded, has_video, has_audio, has_service; if (!obs_output_valid(output, "obs_output_begin_data_capture")) return false; if (delay_active(output)) return begin_delayed_capture(output); if (active(output)) return false; output->total_frames = 0; convert_flags(output, flags, &encoded, &has_video, &has_audio, &has_service); if (!can_begin_data_capture(output, encoded, has_video, has_audio, has_service)) return false; os_atomic_set_bool(&output->data_active, true); hook_data_capture(output, encoded, has_video, has_audio); if (has_service) obs_service_activate(output->service); do_output_signal(output, "activate"); os_atomic_set_bool(&output->active, true); if (reconnecting(output)) { signal_reconnect_success(output); os_atomic_set_bool(&output->reconnecting, false); } else if (delay_active(output)) { do_output_signal(output, "starting"); } else { signal_start(output); } return true; }
int impl_fuse_context::do_create_file(LPCWSTR FileName, DWORD Disposition, DWORD share_mode, DWORD Flags, PDOKAN_FILE_INFO DokanFileInfo) // Kernel mappsings: // Disposition = CreateDisposition // Flags = DesiredAccess // share_mode = ShareAccess { std::string fname = unixify(wchar_to_utf8_cstr(FileName)); // Create file? if (Disposition != FILE_CREATE && Disposition != FILE_SUPERSEDE && Disposition != FILE_OPEN_IF && Disposition != FILE_OVERWRITE_IF) { SetLastError(ERROR_FILE_NOT_FOUND); return -ENOENT; // No, we're trying to open an existing file! } if (!ops_.create) { // Use mknod+open. if (!ops_.mknod || !ops_.open) return -EINVAL; CHECKED(ops_.mknod(fname.c_str(), filemask_, 0)); return do_open_file(FileName, share_mode, Flags, DokanFileInfo); } std::unique_ptr<impl_file_handle> file; CHECKED(file_locks.get_file(fname, false, Flags, share_mode, file)); fuse_file_info finfo = {0}; finfo.flags = O_CREAT | O_EXCL | convert_flags(Flags); // TODO: these flags should be OK for new files? CHECKED(ops_.create(fname.c_str(), filemask_, &finfo)); file->set_finfo(finfo); DokanFileInfo->Context = reinterpret_cast<ULONG64>(file.release()); return 0; }
void obs_output_end_data_capture(obs_output_t output) { bool encoded, has_video, has_audio, has_service; void (*encoded_callback)(void *data, struct encoder_packet *packet); void *param; if (!output) return; if (!output->active) return; convert_flags(output, 0, &encoded, &has_video, &has_audio, &has_service); if (encoded) { encoded_callback = (has_video && has_audio) ? interleave_packets : output->info.encoded_packet; param = (has_video && has_audio) ? output : output->context.data; if (has_video) obs_encoder_stop(output->video_encoder, encoded_callback, param); if (has_audio) obs_encoder_stop(output->audio_encoder, encoded_callback, param); } else { if (has_video) video_output_disconnect(output->video, output->info.raw_video, output->context.data); if (has_audio) audio_output_disconnect(output->audio, output->info.raw_audio, output->context.data); } if (has_service) obs_service_deactivate(output->service, false); output->active = false; }
static newtComponent nmt_newt_entry_build_component (NmtNewtComponent *component, gboolean sensitive) { NmtNewtEntryPrivate *priv = NMT_NEWT_ENTRY_GET_PRIVATE (component); newtComponent co; char *text_lc; int flags; flags = convert_flags (priv->flags); if (!sensitive) flags |= NEWT_FLAG_DISABLED; text_lc = priv->text ? nmt_newt_locale_from_utf8 (priv->text) : NULL; co = newtEntry (-1, -1, text_lc, priv->width, NULL, flags); g_free (text_lc); if (priv->last_cursor_pos != -1) newtEntrySetCursorPosition (co, priv->last_cursor_pos); newtEntrySetFilter (co, entry_filter, component); return co; }
static gint cb_mouse_click (GtkWidget * ww, GdkEventButton * bb, gpointer data) { int flags (convert_flags (bb->state, bb->button)); if (bb->type == GDK_BUTTON_PRESS) { flags |= MOUSE_PRESS; } else { flags |= MOUSE_RELEASE; } if (dbgos) { *dbgos << __func__ << " " << bb->x << " -> " << c2vx (bb->x) << " " << bb->y << " -> " << c2vy (bb->y) << " " << (gdk_flags_t) bb->state << " -> " << (mouse_flags_t) flags << "\n"; } mouse_cb (c2vx (bb->x), c2vy (bb->y), flags); gtk_widget_queue_draw (canvas); return TRUE; }
/* * Map a shared object into memory. The "fd" argument is a file descriptor, * which must be open on the object and positioned at its beginning. * The "path" argument is a pathname that is used only for error messages. * * The return value is a pointer to a newly-allocated Obj_Entry structure * for the shared object. Returns NULL on failure. */ Obj_Entry * map_object(const char *path, char *buf, ssize_t size) { Obj_Entry *obj; Elf_Ehdr *hdr; int i; Elf_Phdr *phdr; Elf_Phdr *phlimit; Elf_Phdr **segs; int nsegs; Elf_Phdr *phdyn; Elf_Phdr *phinterp; Elf_Phdr *phtls; caddr_t mapbase; size_t mapsize; Elf_Off base_offset; Elf_Addr base_vaddr; Elf_Addr base_vlimit; caddr_t base_addr; Elf_Off data_offset; Elf_Addr data_vaddr; Elf_Addr data_vlimit; caddr_t data_addr; int data_prot; int data_flags; Elf_Addr clear_vaddr; caddr_t clear_addr; caddr_t clear_page; Elf_Addr phdr_vaddr; size_t nclear, phsize; Elf_Addr bss_vaddr; Elf_Addr bss_vlimit; caddr_t bss_addr; hdr = get_elf_header(path, buf, size); if (hdr == NULL) return (NULL); /* * Scan the program header entries, and save key information. * * We expect that the loadable segments are ordered by load address. */ phdr = (Elf_Phdr *) ((char *)hdr + hdr->e_phoff); phsize = hdr->e_phnum * sizeof (phdr[0]); phlimit = phdr + hdr->e_phnum; nsegs = -1; phdyn = phinterp = phtls = NULL; phdr_vaddr = 0; segs = alloca(sizeof(segs[0]) * hdr->e_phnum); while (phdr < phlimit) { switch (phdr->p_type) { case PT_INTERP: phinterp = phdr; break; case PT_LOAD: segs[++nsegs] = phdr; if ((segs[nsegs]->p_align & (PAGE_SIZE - 1)) != 0) { _rtld_error("%s: PT_LOAD segment %d not page-aligned", path, nsegs); return NULL; } break; case PT_PHDR: phdr_vaddr = phdr->p_vaddr; phsize = phdr->p_memsz; break; case PT_DYNAMIC: phdyn = phdr; break; case PT_TLS: phtls = phdr; break; } ++phdr; } if (phdyn == NULL) { _rtld_error("%s: object is not dynamically-linked", path); return NULL; } if (nsegs < 0) { _rtld_error("%s: too few PT_LOAD segments", path); return NULL; } /* * Map the entire address space of the object, to stake out our * contiguous region, and to establish the base address for relocation. */ base_offset = trunc_page(segs[0]->p_offset); base_vaddr = trunc_page(segs[0]->p_vaddr); base_vlimit = round_page(segs[nsegs]->p_vaddr + segs[nsegs]->p_memsz); mapsize = base_vlimit - base_vaddr; base_addr = hdr->e_type == ET_EXEC ? (caddr_t) base_vaddr : NULL; mapbase = mmap(base_addr, mapsize, PROT_NONE, MAP_ANON | MAP_PRIVATE | MAP_NOCORE, -1, 0); if (mapbase == (caddr_t) -1) { _rtld_error("%s: mmap of entire address space failed: %s", path, strerror(errno)); return NULL; } if (base_addr != NULL && mapbase != base_addr) { _rtld_error("%s: mmap returned wrong address: wanted %p, got %p", path, base_addr, mapbase); munmap(mapbase, mapsize); return NULL; } for (i = 0; i <= nsegs; i++) { size_t data_vsize; /* Overlay the segment onto the proper region. */ data_offset = trunc_page(segs[i]->p_offset); data_vaddr = trunc_page(segs[i]->p_vaddr); data_vlimit = round_page(segs[i]->p_vaddr + segs[i]->p_filesz); data_addr = mapbase + (data_vaddr - base_vaddr); data_prot = convert_prot(segs[i]->p_flags) | PROT_WRITE; data_vsize = data_vlimit - data_vaddr; data_flags = convert_flags(segs[i]->p_flags) | \ MAP_FIXED | MAP_ANON | MAP_PRIVATE; if (mmap(data_addr, data_vsize, data_prot, data_flags, -1, data_offset) == (caddr_t) -1) { _rtld_error("%s: mmap of data failed: %s", path, strerror(errno)); return NULL; } bcopy(buf + data_offset, data_addr, MIN(data_vsize, (size - data_offset))); /* Do BSS setup */ if (segs[i]->p_filesz != segs[i]->p_memsz) { /* Clear any BSS in the last page of the segment. */ clear_vaddr = segs[i]->p_vaddr + segs[i]->p_filesz; clear_addr = mapbase + (clear_vaddr - base_vaddr); clear_page = mapbase + (trunc_page(clear_vaddr) - base_vaddr); if ((nclear = data_vlimit - clear_vaddr) > 0) { /* Make sure the end of the segment is writable */ if ((data_prot & PROT_WRITE) == 0 && -1 == mprotect(clear_page, PAGE_SIZE, data_prot|PROT_WRITE)) { _rtld_error("%s: mprotect failed: %s", path, strerror(errno)); return NULL; } memset(clear_addr, 0, nclear); /* Reset the data protection back */ if ((data_prot & PROT_WRITE) == 0) mprotect(clear_page, PAGE_SIZE, data_prot); } /* Overlay the BSS segment onto the proper region. */ bss_vaddr = data_vlimit; bss_vlimit = round_page(segs[i]->p_vaddr + segs[i]->p_memsz); bss_addr = mapbase + (bss_vaddr - base_vaddr); if (bss_vlimit > bss_vaddr) { /* There is something to do */ if (mprotect(bss_addr, bss_vlimit - bss_vaddr, data_prot) == -1) { _rtld_error("%s: mprotect of bss failed: %s", path, strerror(errno)); return NULL; } } } if (phdr_vaddr == 0 && data_offset <= hdr->e_phoff && (data_vlimit - data_vaddr + data_offset) >= (hdr->e_phoff + hdr->e_phnum * sizeof (Elf_Phdr))) { phdr_vaddr = data_vaddr + hdr->e_phoff - data_offset; } } obj = obj_new(); obj->mapbase = mapbase; obj->mapsize = mapsize; obj->textsize = round_page(segs[0]->p_vaddr + segs[0]->p_memsz) - base_vaddr; obj->vaddrbase = base_vaddr; obj->relocbase = mapbase - base_vaddr; obj->dynamic = (const Elf_Dyn *) (obj->relocbase + phdyn->p_vaddr); if (hdr->e_entry != 0) obj->entry = (caddr_t) (obj->relocbase + hdr->e_entry); if (phdr_vaddr != 0) { obj->phdr = (const Elf_Phdr *) (obj->relocbase + phdr_vaddr); } else { obj->phdr = malloc(phsize); if (obj->phdr == NULL) { obj_free(obj); _rtld_error("%s: cannot allocate program header", path); return NULL; } memcpy((char *)obj->phdr, (char *)hdr + hdr->e_phoff, phsize); obj->phdr_alloc = true; } obj->phsize = phsize; if (phinterp != NULL) obj->interp = (const char *) (obj->relocbase + phinterp->p_vaddr); if (phtls != NULL) { tls_dtv_generation++; obj->tlsindex = ++tls_max_index; obj->tlssize = phtls->p_memsz; obj->tlsalign = phtls->p_align; obj->tlsinitsize = phtls->p_filesz; obj->tlsinit = mapbase + phtls->p_vaddr; } return obj; }
/* * Map a shared object into memory. The "fd" argument is a file descriptor, * which must be open on the object and positioned at its beginning. * The "path" argument is a pathname that is used only for error messages. * * The return value is a pointer to a newly-allocated Obj_Entry structure * for the shared object. Returns NULL on failure. */ Obj_Entry * map_object(int fd, const char *path, const struct stat *sb) { Obj_Entry *obj; Elf_Ehdr *hdr; int i; Elf_Phdr *phdr; Elf_Phdr *phlimit; Elf_Phdr **segs; int nsegs; Elf_Phdr *phdyn; Elf_Phdr *phinterp; Elf_Phdr *phtls; caddr_t mapbase; caddr_t shlib_base; size_t mapsize; Elf_Addr base_vaddr; Elf_Addr base_vlimit; caddr_t base_addr; Elf_Off data_offset; Elf_Addr data_vaddr; Elf_Addr data_vlimit; caddr_t data_addr; int data_prot; int data_flags; Elf_Addr clear_vaddr; caddr_t clear_addr; caddr_t clear_page; Elf_Addr phdr_vaddr; size_t nclear, phsize; Elf_Addr bss_vaddr; Elf_Addr bss_vlimit; caddr_t bss_addr; Elf_Word stack_flags; Elf_Addr relro_page; size_t relro_size; Elf_Addr note_start; Elf_Addr note_end; hdr = get_elf_header(fd, path); if (hdr == NULL) return (NULL); if (__ld_sharedlib_base) { shlib_base = (void *)(intptr_t)strtoul(__ld_sharedlib_base, NULL, 0); } else { shlib_base = NULL; } /* * Scan the program header entries, and save key information. * * We expect that the loadable segments are ordered by load address. */ phdr = (Elf_Phdr *) ((char *)hdr + hdr->e_phoff); phsize = hdr->e_phnum * sizeof (phdr[0]); phlimit = phdr + hdr->e_phnum; nsegs = -1; phdyn = phinterp = phtls = NULL; phdr_vaddr = 0; relro_page = 0; relro_size = 0; note_start = 0; note_end = 0; segs = alloca(sizeof(segs[0]) * hdr->e_phnum); stack_flags = RTLD_DEFAULT_STACK_PF_EXEC | PF_R | PF_W; while (phdr < phlimit) { switch (phdr->p_type) { case PT_INTERP: phinterp = phdr; break; case PT_LOAD: segs[++nsegs] = phdr; if ((segs[nsegs]->p_align & (PAGE_SIZE - 1)) != 0) { _rtld_error("%s: PT_LOAD segment %d not page-aligned", path, nsegs); goto error; } break; case PT_PHDR: phdr_vaddr = phdr->p_vaddr; phsize = phdr->p_memsz; break; case PT_DYNAMIC: phdyn = phdr; break; case PT_TLS: phtls = phdr; break; case PT_GNU_STACK: stack_flags = phdr->p_flags; break; case PT_GNU_RELRO: relro_page = phdr->p_vaddr; relro_size = phdr->p_memsz; break; case PT_NOTE: if (phdr->p_offset > PAGE_SIZE || phdr->p_offset + phdr->p_filesz > PAGE_SIZE) break; note_start = (Elf_Addr)(char *)hdr + phdr->p_offset; note_end = note_start + phdr->p_filesz; break; } ++phdr; } if (phdyn == NULL) { _rtld_error("%s: object is not dynamically-linked", path); goto error; } if (nsegs < 0) { _rtld_error("%s: too few PT_LOAD segments", path); goto error; } /* * Map the entire address space of the object, to stake out our * contiguous region, and to establish the base address for relocation. */ base_vaddr = trunc_page(segs[0]->p_vaddr); base_vlimit = round_page(segs[nsegs]->p_vaddr + segs[nsegs]->p_memsz); mapsize = base_vlimit - base_vaddr; base_addr = (caddr_t) base_vaddr; if (base_addr == NULL && shlib_base) { size_t limit = 1024 * 256 * 1024; size_t offset; for (offset = 0; offset < limit; offset += 256 * 1024) { mapbase = mmap(shlib_base + offset, mapsize, PROT_NONE, MAP_ANON | MAP_PRIVATE | MAP_NOCORE | MAP_TRYFIXED, -1, 0); if (mapbase != MAP_FAILED) break; } } else { mapbase = mmap(base_addr, mapsize, PROT_NONE, MAP_ANON | MAP_PRIVATE | MAP_NOCORE, -1, 0); } if (mapbase == (caddr_t) -1) { _rtld_error("%s: mmap of entire address space failed: %s", path, rtld_strerror(errno)); goto error; } if (base_addr != NULL && mapbase != base_addr) { _rtld_error("%s: mmap returned wrong address: wanted %p, got %p", path, base_addr, mapbase); goto error1; } for (i = 0; i <= nsegs; i++) { /* Overlay the segment onto the proper region. */ data_offset = trunc_page(segs[i]->p_offset); data_vaddr = trunc_page(segs[i]->p_vaddr); data_vlimit = round_page(segs[i]->p_vaddr + segs[i]->p_filesz); data_addr = mapbase + (data_vaddr - base_vaddr); data_prot = convert_prot(segs[i]->p_flags); data_flags = convert_flags(segs[i]->p_flags) | MAP_FIXED; if (mmap(data_addr, data_vlimit - data_vaddr, data_prot, data_flags, fd, data_offset) == (caddr_t) -1) { _rtld_error("%s: mmap of data failed: %s", path, rtld_strerror(errno)); goto error1; } /* Do BSS setup */ if (segs[i]->p_filesz != segs[i]->p_memsz) { /* Clear any BSS in the last page of the segment. */ clear_vaddr = segs[i]->p_vaddr + segs[i]->p_filesz; clear_addr = mapbase + (clear_vaddr - base_vaddr); clear_page = mapbase + (trunc_page(clear_vaddr) - base_vaddr); if ((nclear = data_vlimit - clear_vaddr) > 0) { /* Make sure the end of the segment is writable */ if ((data_prot & PROT_WRITE) == 0 && -1 == mprotect(clear_page, PAGE_SIZE, data_prot|PROT_WRITE)) { _rtld_error("%s: mprotect failed: %s", path, rtld_strerror(errno)); goto error1; } memset(clear_addr, 0, nclear); /* * reset the data protection back, enable the segment to be * coredumped since we modified it. */ if ((data_prot & PROT_WRITE) == 0) { madvise(clear_page, PAGE_SIZE, MADV_CORE); mprotect(clear_page, PAGE_SIZE, data_prot); } } /* Overlay the BSS segment onto the proper region. */ bss_vaddr = data_vlimit; bss_vlimit = round_page(segs[i]->p_vaddr + segs[i]->p_memsz); bss_addr = mapbase + (bss_vaddr - base_vaddr); if (bss_vlimit > bss_vaddr) { /* There is something to do */ if (mmap(bss_addr, bss_vlimit - bss_vaddr, data_prot, data_flags | MAP_ANON, -1, 0) == (caddr_t)-1) { _rtld_error("%s: mmap of bss failed: %s", path, rtld_strerror(errno)); goto error1; } } } if (phdr_vaddr == 0 && data_offset <= hdr->e_phoff && (data_vlimit - data_vaddr + data_offset) >= (hdr->e_phoff + hdr->e_phnum * sizeof (Elf_Phdr))) { phdr_vaddr = data_vaddr + hdr->e_phoff - data_offset; } } obj = obj_new(); if (sb != NULL) { obj->dev = sb->st_dev; obj->ino = sb->st_ino; } obj->mapbase = mapbase; obj->mapsize = mapsize; obj->textsize = round_page(segs[0]->p_vaddr + segs[0]->p_memsz) - base_vaddr; obj->vaddrbase = base_vaddr; obj->relocbase = mapbase - base_vaddr; obj->dynamic = (const Elf_Dyn *) (obj->relocbase + phdyn->p_vaddr); if (hdr->e_entry != 0) obj->entry = (caddr_t) (obj->relocbase + hdr->e_entry); if (phdr_vaddr != 0) { obj->phdr = (const Elf_Phdr *) (obj->relocbase + phdr_vaddr); } else { obj->phdr = malloc(phsize); if (obj->phdr == NULL) { obj_free(obj); _rtld_error("%s: cannot allocate program header", path); goto error1; } memcpy((char *)obj->phdr, (char *)hdr + hdr->e_phoff, phsize); obj->phdr_alloc = true; } obj->phsize = phsize; if (phinterp != NULL) obj->interp = (const char *) (obj->relocbase + phinterp->p_vaddr); if (phtls != NULL) { tls_dtv_generation++; obj->tlsindex = ++tls_max_index; obj->tlssize = phtls->p_memsz; obj->tlsalign = phtls->p_align; obj->tlsinitsize = phtls->p_filesz; obj->tlsinit = mapbase + phtls->p_vaddr; } obj->stack_flags = stack_flags; if (relro_size) { obj->relro_page = obj->relocbase + trunc_page(relro_page); obj->relro_size = round_page(relro_size); } if (note_start < note_end) digest_notes(obj, note_start, note_end); munmap(hdr, PAGE_SIZE); return (obj); error1: munmap(mapbase, mapsize); error: munmap(hdr, PAGE_SIZE); return (NULL); }
int main (void) { char *linebuf = NULL; size_t linebuflen = 0; int ntests = 0; int nfailed = 0; char *escinput = NULL; size_t escinputlen = 0; char *escpattern = NULL; size_t escpatternlen = 0; int nr = 0; mtrace (); /* Read lines from stdin with the following format: locale input-string match-string flags result where `result' is either 0 or 1. If the first character of a string is '"' we read until the next '"' and handled escaped '"'. */ while (! feof (stdin)) { ssize_t n = getline (&linebuf, &linebuflen, stdin); char *cp; const char *locale; const char *input; const char *pattern; const char *result_str; int result; const char *flags; int flags_val; int fnmres; char numbuf[24]; if (n == -1) break; if (n == 0) /* Maybe an empty line. */ continue; /* Skip over all leading white spaces. */ cp = linebuf; locale = next_input (&cp, 1, 0); if (locale == NULL) continue; input = next_input (&cp, 0, 0); if (input == NULL) continue; pattern = next_input (&cp, 0, 0); if (pattern == NULL) continue; result_str = next_input (&cp, 0, 0); if (result_str == NULL) continue; if (strcmp (result_str, "0") == 0) result = 0; else if (strcasecmp (result_str, "NOMATCH") == 0) result = FNM_NOMATCH; else { char *endp; result = strtol (result_str, &endp, 0); if (*endp != '\0') continue; } flags = next_input (&cp, 0, 1); if (flags == NULL) /* We allow the flags missing. */ flags = ""; /* Convert the text describing the flags in a numeric value. */ flags_val = convert_flags (flags); if (flags_val == -1) /* Something went wrong. */ continue; /* Now run the actual test. */ ++ntests; if (setlocale (LC_COLLATE, locale) == NULL || setlocale (LC_CTYPE, locale) == NULL) { puts ("*** Cannot set locale"); ++nfailed; continue; } fnmres = fnmatch (pattern, input, flags_val); printf ("%3d: fnmatch (\"%s\", \"%s\", %s) = %s%c", ++nr, escape (pattern, &escpatternlen, &escpattern), escape (input, &escinputlen, &escinput), flag_output (flags_val), (fnmres == 0 ? "0" : (fnmres == FNM_NOMATCH ? "FNM_NOMATCH" : (sprintf (numbuf, "%d", fnmres), numbuf))), (fnmres != 0) != (result != 0) ? ' ' : '\n'); if ((fnmres != 0) != (result != 0)) { printf ("(FAIL, expected %s) ***\n", result == 0 ? "0" : (result == FNM_NOMATCH ? "FNM_NOMATCH" : (sprintf (numbuf, "%d", result), numbuf))); ++nfailed; } } printf ("=====================\n%3d tests, %3d failed\n", ntests, nfailed); free (escpattern); free (escinput); free (linebuf); return nfailed != 0; }