ir_visitor_status
ir_explog_to_explog2_visitor::visit_leave(ir_expression *ir)
{
   if (ir->operation == ir_unop_exp) {
      void *mem_ctx = talloc_parent(ir);
      ir_constant *log2_e = new(mem_ctx) ir_constant(log2f(M_E));

      ir->operation = ir_unop_exp2;
      ir->operands[0] = new(mem_ctx) ir_expression(ir_binop_mul,
						   ir->operands[0]->type,
						   ir->operands[0],
						   log2_e);
      this->progress = true;
   }

   if (ir->operation == ir_unop_log) {
      void *mem_ctx = talloc_parent(ir);

      ir->operation = ir_binop_mul;
      ir->operands[0] = new(mem_ctx) ir_expression(ir_unop_log2,
						   ir->operands[0]->type,
						   ir->operands[0],
						   NULL);
      ir->operands[1] = new(mem_ctx) ir_constant(1.0f / log2f(M_E));
      this->progress = true;
   }

   return visit_continue;
}
Exemple #2
0
/** Generate a talloc memory report for a context and print to stderr/stdout
 *
 * @param ctx to generate a report for, may be NULL in which case the root context is used.
 */
int fr_log_talloc_report(TALLOC_CTX *ctx)
{
#define TALLOC_REPORT_MAX_DEPTH 20

	FILE *log;
	int fd;

	fd = dup(fr_fault_log_fd);
	if (fd < 0) {
		fr_strerror_printf("Couldn't write memory report, failed to dup log fd: %s", fr_syserror(errno));
		return -1;
	}
	log = fdopen(fd, "w");
	if (!log) {
		close(fd);
		fr_strerror_printf("Couldn't write memory report, fdopen failed: %s", fr_syserror(errno));
		return -1;
	}

	if (!ctx) {
		fprintf(log, "Current state of talloced memory:\n");
		talloc_report_full(talloc_null_ctx, log);
	} else {
		int i;

		fprintf(log, "Talloc chunk lineage:\n");
		fprintf(log, "%p (%s)", ctx, talloc_get_name(ctx));

		i = 0;
		while ((i < TALLOC_REPORT_MAX_DEPTH) && (ctx = talloc_parent(ctx))) {
			fprintf(log, " < %p (%s)", ctx, talloc_get_name(ctx));
			i++;
		}
		fprintf(log, "\n");

		i = 0;
		do {
			fprintf(log, "Talloc context level %i:\n", i++);
			talloc_report_full(ctx, log);
		} while ((ctx = talloc_parent(ctx)) &&
			 (i < TALLOC_REPORT_MAX_DEPTH) &&
			 (talloc_parent(ctx) != talloc_autofree_ctx) &&	/* Stop before we hit the autofree ctx */
			 (talloc_parent(ctx) != talloc_null_ctx));  	/* Stop before we hit NULL ctx */
	}

	fclose(log);

	return 0;
}
Exemple #3
0
void log_talloc_report(TALLOC_CTX *ctx)
{
	FILE *fd;
	char const *null_ctx = NULL;
	int i = 0;

	if (ctx) {
		null_ctx = talloc_get_name(NULL);
	}

	fd = fdopen(default_log.fd, "w");
	if (!fd) {
		ERROR("Couldn't write memory report, fdopen failed: %s", fr_syserror(errno));

		return;
	}

	if (!ctx) {
		talloc_report_full(NULL, fd);
	} else {
		do {
			INFO("Context level %i", i++);

			talloc_report_full(ctx, fd);
		} while ((ctx = talloc_parent(ctx)) && (talloc_get_name(ctx) != null_ctx));  /* Stop before we hit NULL ctx */
	}

	fclose(fd);
}
Exemple #4
0
static void mangle_append_sub(char **s, char *m)
{
    void *p = talloc_parent(*s);
    assert(p);
    // Kill prefix, for not making type names not ridiculous long.
    if (strncmp(m, MANGLE_PREFIX, strlen(MANGLE_PREFIX)) == 0)
        m = m + strlen(MANGLE_PREFIX);
    *s = talloc_asprintf_append_buffer(*s, "%zd_%s_", strlen(m), m);
}
Exemple #5
0
static int cli_trans_state_ptr_destructor(struct cli_trans_state **ptr)
{
	struct cli_trans_state *state = *ptr;
	void *parent = talloc_parent(state);

	talloc_set_destructor(state, NULL);

	talloc_reparent(state, parent, state->req);
	talloc_free(state);
	return 0;
}
Exemple #6
0
cbuf* cbuf_swapptr(cbuf* b, char** ptr, size_t len)
{
    void* p = talloc_parent(*ptr);
    SWAP(b->buf, *ptr, char*);
    talloc_steal(b, b->buf);
    talloc_steal(p, *ptr);
    b->size = talloc_get_size(b->buf);
    b->pos  = (len == -1) ? strlen(b->buf) : len;

    assert(b->pos <= b->size);
    return b;
}
Exemple #7
0
int main(int argc, char *argv[])
{
	char **split, *str;
	void *ctx;

	plan_tests(16);
	split = strsplit(NULL, "hello  world", " ");
	ok1(talloc_array_length(split) == 4);
	ok1(!strcmp(split[0], "hello"));
	ok1(!strcmp(split[1], ""));
	ok1(!strcmp(split[2], "world"));
	ok1(split[3] == NULL);
	talloc_free(split);

	split = strsplit(NULL, "hello  world", "o ");
	ok1(talloc_array_length(split) == 6);
	ok1(!strcmp(split[0], "hell"));
	ok1(!strcmp(split[1], ""));
	ok1(!strcmp(split[2], ""));
	ok1(!strcmp(split[3], "w"));
	ok1(!strcmp(split[4], "rld"));
	ok1(split[5] == NULL);

	ctx = split;
	split = strsplit(ctx, "hello  world", "o ");
	ok1(talloc_parent(split) == ctx);
	talloc_free(ctx);

	str = strjoin(NULL, (char **)substrings, ", ");
	ok1(!strcmp(str, "far, bar, baz, b, ba, z, ar, "));
	ctx = str;
	str = strjoin(ctx, (char **)substrings, "");
	ok1(!strcmp(str, "farbarbazbbazar"));
	ok1(talloc_parent(str) == ctx);
	talloc_free(ctx);

	return exit_status();
}				
Exemple #8
0
   void generate(unsigned i, ir_rvalue* condition, exec_list *list) const
   {
      /* Just clone the rest of the deref chain when trying to get at the
       * underlying variable.
       */
      void *mem_ctx = talloc_parent(base_ir);
      ir_rvalue *element =
	 new(mem_ctx) ir_dereference_array(this->array->clone(mem_ctx, NULL),
					   new(mem_ctx) ir_constant(i));
      ir_rvalue *variable = new(mem_ctx) ir_dereference_variable(this->var);

      ir_assignment *assignment = (is_write)
	 ? new(mem_ctx) ir_assignment(element, variable, condition)
	 : new(mem_ctx) ir_assignment(variable, element, condition);

      list->push_tail(assignment);
   }
Exemple #9
0
void dsdb_make_schema_global(struct ldb_context *ldb)
{
	struct dsdb_schema *schema = dsdb_get_schema(ldb);
	if (!schema) {
		return;
	}

	if (global_schema) {
		talloc_unlink(talloc_autofree_context(), global_schema);
	}

	/* we want the schema to be around permanently */
	talloc_reparent(talloc_parent(schema), talloc_autofree_context(), schema);

	global_schema = schema;

	dsdb_set_global_schema(ldb);
}
Exemple #10
0
NTSTATUS cli_trans_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
			uint16_t *recv_flags2,
			uint16_t **setup, uint8_t min_setup,
			uint8_t *num_setup,
			uint8_t **param, uint32_t min_param,
			uint32_t *num_param,
			uint8_t **data, uint32_t min_data,
			uint32_t *num_data)
{
	NTSTATUS status;
	void *parent = talloc_parent(req);
	struct cli_trans_state *state =
		talloc_get_type(parent,
		struct cli_trans_state);
	bool map_dos_errors = true;

	status = smb1cli_trans_recv(req, mem_ctx, recv_flags2,
				    setup, min_setup, num_setup,
				    param, min_param, num_param,
				    data, min_data, num_data);

	if (state) {
		map_dos_errors = state->cli->map_dos_errors;
		state->cli->raw_status = status;
		talloc_free(state->ptr);
		state = NULL;
	}

	if (NT_STATUS_IS_DOS(status) && map_dos_errors) {
		uint8_t eclass = NT_STATUS_DOS_CLASS(status);
		uint16_t ecode = NT_STATUS_DOS_CODE(status);
		/*
		 * TODO: is it really a good idea to do a mapping here?
		 *
		 * The old cli_pull_error() also does it, so I do not change
		 * the behavior yet.
		 */
		status = dos_to_ntstatus(eclass, ecode);
	}

	return status;
}
Exemple #11
0
cbuf* cbuf_copy(const cbuf* b)
{
    cbuf* s = talloc(talloc_parent(b), cbuf);
    if (s == NULL) {
        return NULL;
    }

    s->buf = (char *)talloc_memdup(s, b->buf, b->size); /* only up to pos? */

    /* XXX shallow did not work, because realloc */
    /* fails with multiple references */
    /* s->buf = talloc_reference(s, b->buf); */

    if (s->buf == NULL) {
        cbuf_delete(s);
        return NULL;
    }
    s->size = b->size;
    s->pos  = b->pos;
    return s;
}
Exemple #12
0
ir_rvalue *
ir_vec_index_to_swizzle_visitor::convert_vec_index_to_swizzle(ir_rvalue *ir)
{
   ir_dereference_array *deref = ir->as_dereference_array();
   ir_constant *ir_constant;

   if (!deref)
      return ir;

   if (deref->array->type->is_matrix() || deref->array->type->is_array())
      return ir;

   assert(deref->array_index->type->base_type == GLSL_TYPE_INT);
   ir_constant = deref->array_index->constant_expression_value();
   if (!ir_constant)
      return ir;

   void *ctx = talloc_parent(ir);
   this->progress = true;
   return new(ctx) ir_swizzle(deref->array,
			      ir_constant->value.i[0], 0, 0, 0, 1);
}
Exemple #13
0
/*
  perform the receive side of a async dcerpc request
*/
NTSTATUS dcerpc_request_recv(struct rpc_request *req,
			     TALLOC_CTX *mem_ctx,
			     DATA_BLOB *stub_data)
{
	NTSTATUS status;

	while (req->state != RPC_REQUEST_DONE) {
		struct tevent_context *ctx = dcerpc_event_context(req->p);
		if (event_loop_once(ctx) != 0) {
			return NT_STATUS_CONNECTION_DISCONNECTED;
		}
	}
	*stub_data = req->payload;
	status = req->status;
	if (stub_data->data) {
		stub_data->data = talloc_steal(mem_ctx, stub_data->data);
	}
	if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
		req->p->last_fault_code = req->fault_code;
	}
	talloc_unlink(talloc_parent(req), req);
	return status;
}
Exemple #14
0
int talloc_free(void *ptr)
{
	return talloc_unlink(talloc_parent(ptr), ptr);
}
Exemple #15
0
void *_talloc_steal(const void *new_ctx, const void *ptr)
{
	return talloc_reparent(talloc_parent(ptr), new_ctx, ptr);
}
ir_visitor_status
loop_unroll_visitor::visit_leave(ir_loop *ir)
{
   loop_variable_state *const ls = this->state->get(ir);
   int iterations;

   /* If we've entered a loop that hasn't been analyzed, something really,
    * really bad has happened.
    */
   if (ls == NULL) {
      assert(ls != NULL);
      return visit_continue;
   }

   iterations = ls->max_iterations;

   /* Don't try to unroll loops where the number of iterations is not known
    * at compile-time.
    */
   if (iterations < 0)
      return visit_continue;

   /* Don't try to unroll loops that have zillions of iterations either.
    */
   if (iterations > max_iterations)
      return visit_continue;

   if (ls->num_loop_jumps > 1)
      return visit_continue;
   else if (ls->num_loop_jumps) {
      /* recognize loops in the form produced by ir_lower_jumps */
      ir_instruction *last_ir =
	 ((ir_instruction*)ir->body_instructions.get_tail());

      assert(last_ir != NULL);

      ir_if *last_if = last_ir->as_if();
      if (last_if) {
	 bool continue_from_then_branch;

	 /* Determine which if-statement branch, if any, ends with a break.
	  * The branch that did *not* have the break will get a temporary
	  * continue inserted in each iteration of the loop unroll.
	  *
	  * Note that since ls->num_loop_jumps is <= 1, it is impossible for
	  * both branches to end with a break.
	  */
	 ir_instruction *last =
	    (ir_instruction *) last_if->then_instructions.get_tail();

	 if (last && last->ir_type == ir_type_loop_jump
	     && ((ir_loop_jump*) last)->is_break()) {
	    continue_from_then_branch = false;
	 } else {
	    last = (ir_instruction *) last_if->then_instructions.get_tail();

	    if (last && last->ir_type == ir_type_loop_jump
		&& ((ir_loop_jump*) last)->is_break())
	       continue_from_then_branch = true;
	    else
	       /* Bail out if neither if-statement branch ends with a break.
		*/
	       return visit_continue;
	 }

	 /* Remove the break from the if-statement.
	  */
	 last->remove();

         void *const mem_ctx = talloc_parent(ir);
         ir_instruction *ir_to_replace = ir;

         for (int i = 0; i < iterations; i++) {
            exec_list copy_list;

            copy_list.make_empty();
            clone_ir_list(mem_ctx, &copy_list, &ir->body_instructions);

            last_if = ((ir_instruction*)copy_list.get_tail())->as_if();
            assert(last_if);

            ir_to_replace->insert_before(&copy_list);
            ir_to_replace->remove();

            /* placeholder that will be removed in the next iteration */
            ir_to_replace =
	       new(mem_ctx) ir_loop_jump(ir_loop_jump::jump_continue);

            exec_list *const list = (continue_from_then_branch)
	       ? &last_if->then_instructions : &last_if->else_instructions;

            list->push_tail(ir_to_replace);
         }

         ir_to_replace->remove();

         this->progress = true;
         return visit_continue;
      } else if (last_ir->ir_type == ir_type_loop_jump
		 && ((ir_loop_jump *)last_ir)->is_break()) {
	 /* If the only loop-jump is a break at the end of the loop, the loop
	  * will execute exactly once.  Remove the break, set the iteration
	  * count, and fall through to the normal unroller.
	  */
         last_ir->remove();
	 iterations = 1;

	 this->progress = true;
      } else
         return visit_continue;
   }

   void *const mem_ctx = talloc_parent(ir);

   for (int i = 0; i < iterations; i++) {
      exec_list copy_list;

      copy_list.make_empty();
      clone_ir_list(mem_ctx, &copy_list, &ir->body_instructions);

      ir->insert_before(&copy_list);
   }

   /* The loop has been replaced by the unrolled copies.  Remove the original
    * loop from the IR sequence.
    */
   ir->remove();

   this->progress = true;
   return visit_continue;
}
Exemple #17
0
/** Registers signal handlers to execute panic_action on fatal signal
 *
 * May be called multiple time to change the panic_action/program.
 *
 * @param cmd to execute on fault. If present %p will be substituted
 *        for the parent PID before the command is executed, and %e
 *        will be substituted for the currently running program.
 * @param program Name of program currently executing (argv[0]).
 * @return 0 on success -1 on failure.
 */
int fr_fault_setup(char const *cmd, char const *program)
{
	static bool setup = false;

	char *out = panic_action;
	size_t left = sizeof(panic_action);

	char const *p = cmd;
	char const *q;

	if (cmd) {
		size_t ret;

		/* Substitute %e for the current program */
		while ((q = strstr(p, "%e"))) {
			out += ret = snprintf(out, left, "%.*s%s", (int) (q - p), p, program ? program : "");
			if (left <= ret) {
			oob:
				fr_strerror_printf("Panic action too long");
				return -1;
			}
			left -= ret;
			p = q + 2;
		}
		if (strlen(p) >= left) goto oob;
		strlcpy(out, p, left);
	} else {
		*panic_action = '\0';
	}

	/*
	 *	Check for administrator sanity.
	 */
	if (fr_fault_check_permissions() < 0) return -1;

	/* Unsure what the side effects of changing the signal handler mid execution might be */
	if (!setup) {
		char *env;
		fr_debug_state_t debug_state;

		/*
		 *  Installing signal handlers interferes with some debugging
		 *  operations.  Give the developer control over whether the
		 *  signal handlers are installed or not.
		 */
		env = getenv("DEBUG");
		if (!env || (strcmp(env, "no") == 0)) {
			debug_state = DEBUG_STATE_NOT_ATTACHED;
		} else if (!strcmp(env, "auto") || !strcmp(env, "yes")) {
			/*
			 *  Figure out if we were started under a debugger
			 */
			if (fr_debug_state < 0) fr_debug_state = fr_get_debug_state();
			debug_state = fr_debug_state;
		} else {
			debug_state = DEBUG_STATE_ATTACHED;
		}

		talloc_set_log_fn(_fr_talloc_log);

		/*
		 *  These signals can't be properly dealt with in the debugger
		 *  if we set our own signal handlers.
		 */
		switch (debug_state) {
		default:
#ifndef NDEBUG
			FR_FAULT_LOG("Debugger check failed: %s", fr_strerror());
			FR_FAULT_LOG("Signal processing in debuggers may not work as expected");
#endif
			/* FALL-THROUGH */

		case DEBUG_STATE_NOT_ATTACHED:
#ifdef SIGABRT
			if (fr_set_signal(SIGABRT, fr_fault) < 0) return -1;

			/*
			 *  Use this instead of abort so we get a
			 *  full backtrace with broken versions of LLDB
			 */
			talloc_set_abort_fn(_fr_talloc_fault);
#endif
#ifdef SIGILL
			if (fr_set_signal(SIGILL, fr_fault) < 0) return -1;
#endif
#ifdef SIGFPE
			if (fr_set_signal(SIGFPE, fr_fault) < 0) return -1;
#endif
#ifdef SIGSEGV
			if (fr_set_signal(SIGSEGV, fr_fault) < 0) return -1;
#endif
			break;

		case DEBUG_STATE_ATTACHED:
			break;
		}

		/*
		 *  Needed for memory reports
		 */
		{
			TALLOC_CTX *tmp;
			bool *marker;

			tmp = talloc(NULL, bool);
			talloc_null_ctx = talloc_parent(tmp);
			talloc_free(tmp);

			/*
			 *  Disable null tracking on exit, else valgrind complains
			 */
			talloc_autofree_ctx = talloc_autofree_context();
			marker = talloc(talloc_autofree_ctx, bool);
			talloc_set_destructor(marker, _fr_disable_null_tracking);
		}

#if defined(HAVE_MALLOPT) && !defined(NDEBUG)
		/*
		 *  If were using glibc malloc > 2.4 this scribbles over
		 *  uninitialised and freed memory, to make memory issues easier
		 *  to track down.
		 */
		if (!getenv("TALLOC_FREE_FILL")) mallopt(M_PERTURB, 0x42);
		mallopt(M_CHECK_ACTION, 3);
#endif

#if defined(HAVE_EXECINFO) && defined(__GNUC__) && !defined(NDEBUG)
	       /*
		*  We need to pre-load lgcc_s, else we can get into a deadlock
		*  in fr_fault, as backtrace() attempts to dlopen it.
		*
		*  Apparently there's a performance impact of loading lgcc_s,
		*  so only do it if this is a debug build.
		*
		*  See: https://sourceware.org/bugzilla/show_bug.cgi?id=16159
		*/
		{
			void *stack[10];

			backtrace(stack, 10);
		}
#endif
	}