Beispiel #1
0
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;
}
Beispiel #2
0
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;
}
Beispiel #3
0
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;
}
Beispiel #4
0
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;
}
Beispiel #5
0
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;
}
Beispiel #6
0
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;
}
Beispiel #7
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;
}
Beispiel #8
0
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;
}
Beispiel #9
0
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);
}
Beispiel #10
0
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;
    }
Beispiel #11
0
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);
}
Beispiel #12
0
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;
}
Beispiel #13
0
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;
}
Beispiel #14
0
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;
}
Beispiel #15
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);
}
Beispiel #16
0
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;
}
Beispiel #17
0
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;
}
Beispiel #18
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);
}
Beispiel #19
0
  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;
  }
Beispiel #20
0
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;
}
Beispiel #21
0
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;
}
Beispiel #22
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;
}
Beispiel #23
0
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;
}
Beispiel #24
0
  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;
}
Beispiel #26
0
/*
 * 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);
}
Beispiel #27
0
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;
}