Пример #1
0
int _jit_block_record_label(jit_block_t block)
{
	jit_builder_t builder = block->func->builder;
	jit_label_t num;
	jit_block_t *blocks;
	if(block->label >= builder->max_label_blocks)
	{
		num = builder->max_label_blocks;
		if(num < 64)
		{
			num = 64;
		}
		while(num <= block->label)
		{
			num *= 2;
		}
		blocks = (jit_block_t *)jit_realloc
			(builder->label_blocks, num * sizeof(jit_block_t));
		if(!blocks)
		{
			return 0;
		}
		jit_memzero(blocks + builder->max_label_blocks,
					sizeof(jit_block_t) * (num - builder->max_label_blocks));
		builder->label_blocks = blocks;
		builder->max_label_blocks = num;
	}
	builder->label_blocks[block->label] = block;
	return 1;
}
Пример #2
0
/*
 * Append data to a section.
 */
static int add_to_section
	(jit_section_t section, const void *buf, unsigned int len)
{
	char *data = (char *)jit_realloc(section->data, section->data_len + len);
	if(!data)
	{
		return 0;
	}
	section->data = data;
	jit_memcpy(data + section->data_len, buf, len);
	section->data_len += len;
	return 1;
}
Пример #3
0
/*
 * Add a string to the dynamic string section.
 *
 * TODO: use a hash table to cache previous names.
 */
static Elf_Word add_dyn_string(jit_writeelf_t writeelf, const char *name)
{
	jit_section_t section;
	char *data;
	Elf_Word index;
	unsigned int name_len = jit_strlen(name) + 1;
	section = &(writeelf->sections[writeelf->dynamic_string_section]);
	data = (char *)jit_realloc(section->data, section->data_len + name_len);
	if(!data)
	{
		return 0;
	}
	section->data = data;
	jit_strcpy(data + section->data_len, name);
	index = (Elf_Word)(section->data_len);
	section->data_len += name_len;
	return index;
}
Пример #4
0
jit_insn_t _jit_block_add_insn(jit_block_t block)
{
	jit_builder_t builder = block->func->builder;
	jit_insn_t insn;
	int num;
	jit_insn_t *insns;

	/* Allocate the instruction from the builder's memory pool */
	insn = jit_memory_pool_alloc(&(builder->insn_pool), struct _jit_insn);
	if(!insn)
	{
		return 0;
	}

	/* Make space for the instruction in the function's instruction list */
	if(builder->num_insns >= builder->max_insns)
	{
		num = builder->max_insns * 2;
		if(num < 64)
		{
			num = 64;
		}
		insns = (jit_insn_t *)jit_realloc
			(builder->insns, num * sizeof(jit_insn_t));
		if(!insns)
		{
			return 0;
		}
		builder->insns = insns;
		builder->max_insns = num;
	}
	else
	{
		insns = builder->insns;
	}
	insns[builder->num_insns] = insn;
	block->last_insn = (builder->num_insns)++;

	/* Return the instruction, which is now ready to fill in */
	return insn;
}
Пример #5
0
void
_jit_prolog(jit_state_t *_jit)
{
    jit_int32_t		 offset;

    if (_jitc->function)
	jit_epilog();
    assert(jit_regset_cmp_ui(&_jitc->regarg, 0) == 0);
    jit_regset_set_ui(&_jitc->regsav, 0);
    offset = _jitc->functions.offset;
    if (offset >= _jitc->functions.length) {
	jit_realloc((jit_pointer_t *)&_jitc->functions.ptr,
		    _jitc->functions.length * sizeof(jit_function_t),
		    (_jitc->functions.length + 16) * sizeof(jit_function_t));
	_jitc->functions.length += 16;
    }
    _jitc->function = _jitc->functions.ptr + _jitc->functions.offset++;
    _jitc->function->self.size = stack_framesize;
    _jitc->function->self.argi = _jitc->function->self.argf =
	_jitc->function->self.aoff = _jitc->function->self.alen = 0;
    /* float conversion */
    _jitc->function->self.aoff = -8;
     _jitc->function->self.call = jit_call_default;
    jit_alloc((jit_pointer_t *)&_jitc->function->regoff,
	      _jitc->reglen * sizeof(jit_int32_t));

    _jitc->function->prolog = jit_new_node_no_link(jit_code_prolog);
    jit_link(_jitc->function->prolog);
    _jitc->function->prolog->w.w = offset;
    _jitc->function->epilog = jit_new_node_no_link(jit_code_epilog);
    /*	u:	label value
     *	v:	offset in blocks vector
     *	w:	offset in functions vector
     */
    _jitc->function->epilog->w.w = offset;

    jit_regset_new(&_jitc->function->regset);
}
Пример #6
0
static void
_patch(jit_state_t *_jit, jit_word_t instr, jit_node_t *node)
{
    jit_int32_t		flag;

    assert(node->flag & jit_flag_node);
    if (node->code == jit_code_movi)
	flag = node->v.n->flag;
    else
	flag = node->u.n->flag;
    assert(!(flag & jit_flag_patch));
    if (_jitc->patches.offset >= _jitc->patches.length) {
	jit_realloc((jit_pointer_t *)&_jitc->patches.ptr,
		    _jitc->patches.length * sizeof(jit_patch_t),
		    (_jitc->patches.length + 1024) * sizeof(jit_patch_t));
	memset(_jitc->patches.ptr + _jitc->patches.length, 0,
	       1024 * sizeof(jit_patch_t));
	_jitc->patches.length += 1024;
    }
    _jitc->patches.ptr[_jitc->patches.offset].inst = instr;
    _jitc->patches.ptr[_jitc->patches.offset].node = node;
    ++_jitc->patches.offset;
}
Пример #7
0
/*
 * Get or add a section.
 */
static jit_section_t get_section
	(jit_writeelf_t writeelf, const char *name, jit_int type,
	 Elf_Word flags, Elf_Word entry_size, Elf_Word alignment)
{
	int index;
	jit_section_t section;

	/* Search the section table for an existing section by this name */
	for(index = 0; index < writeelf->num_sections; ++index)
	{
		section = &(writeelf->sections[index]);
		if(!jit_strcmp(get_string(writeelf, section->shdr.sh_name), name))
		{
			return section;
		}
	}

	/* Create a new section and clear it */
	section = (jit_section_t)jit_realloc
		(writeelf->sections,
		 (writeelf->num_sections + 1) * sizeof(struct jit_section));
	if(!section)
	{
		return 0;
	}
	writeelf->sections = section;
	section += writeelf->num_sections;
	jit_memzero(section, sizeof(struct jit_section));

	/* Set the section's name.  If this is the first section created,
	   then it is the string table itself, and we have to add the
	   name to the section itself to start the ball rolling */
	if(writeelf->regular_string_section < 0)
	{
		section->data = (char *)jit_malloc(jit_strlen(name) + 2);
		if(!(section->data))
		{
			return 0;
		}
		section->data_len = jit_strlen(name) + 2;
		section->data[0] = '\0';	/* Empty string is always first */
		jit_strcpy(section->data + 1, name);
		section->shdr.sh_name = 1;
		writeelf->regular_string_section = writeelf->num_sections;
	}
	else
	{
		section->shdr.sh_name = add_string(writeelf, name);
		if(!(section->shdr.sh_name))
		{
			return 0;
		}
	}

	/* Set the other section properties */
	section->shdr.sh_type = (Elf_Word)type;
	section->shdr.sh_flags = flags;
	section->shdr.sh_entsize = entry_size;
	section->shdr.sh_addralign = alignment;

	/* Increase the section count and return */
	++(writeelf->num_sections);
	return section;
}
Пример #8
0
/*
 * Implementation
 */
void
jit_init_debug(const char *progname)
{
#if DISASSEMBLER
    bfd_init();

    if (progname)
	disasm_bfd = bfd_openr(progname, NULL);
    if (disasm_bfd == NULL) {
#if defined(__linux__)
	disasm_bfd = bfd_openr("/proc/self/exe", NULL);
	if (disasm_bfd == NULL)
#endif
	    return;
    }
    bfd_check_format(disasm_bfd, bfd_object);
    bfd_check_format(disasm_bfd, bfd_archive);
    disasm_print = disassembler(disasm_bfd);
    assert(disasm_print);
    INIT_DISASSEMBLE_INFO(disasm_info, disasm_stream, fprintf);
#  if defined(__i386__) || defined(__x86_64__)
    disasm_info.arch = bfd_arch_i386;
#    if defined(__x86_64__)
#      if __WORDSIZE == 32
    disasm_info.mach = bfd_mach_x64_32;
#      else
    disasm_info.mach = bfd_mach_x86_64;
#      endif
#    else
    disasm_info.mach = bfd_mach_i386_i386;
#    endif
#  endif
#  if defined(__powerpc__)
    disasm_info.arch = bfd_arch_powerpc;
    disasm_info.mach = bfd_mach_ppc64;
#    if HAVE_DISASSEMBLE_INIT_FOR_TARGET
    disassemble_init_for_target(&disasm_info);
#    elif HAVE_DISASSEMBLE_INIT_POWERPC
    disassemble_init_powerpc(&disasm_info);
#    endif
#    if defined(__powerpc64__)
    disasm_info.disassembler_options = "64";
#    endif
#    if HAVE_DISASSEMBLE_INIT_FOR_TARGET
    disassemble_init_for_target(&disasm_info);
#    elif HAVE_DISASSEMBLE_INIT_POWERPC
    disassemble_init_powerpc(&disasm_info);
#    endif
#  endif
#  if defined(__sparc__)
    disasm_info.endian = disasm_info.display_endian = BFD_ENDIAN_BIG;
#  endif
#  if defined(__s390__) || defined(__s390x__)
    disasm_info.arch = bfd_arch_s390;
#    if __WORDSIZE == 32
    disasm_info.mach = bfd_mach_s390_31;
#    else
    disasm_info.mach = bfd_mach_s390_64;
#    endif
    disasm_info.endian = disasm_info.display_endian = BFD_ENDIAN_BIG;
    disasm_info.disassembler_options = "zarch";
#  endif
#  if defined(__alpha__)
    disasm_info.arch = bfd_arch_alpha;
    disasm_info.mach = bfd_mach_alpha_ev6;
#  endif
    disasm_info.print_address_func = disasm_print_address;

    if (bfd_get_file_flags(disasm_bfd) & HAS_SYMS) {
	asymbol		**in;
	asymbol		**out;
	asymbol		 *symbol;
	long		  offset;
	long		  sym_count;
	long		  dyn_count;
	long		  sym_storage;
	long		  dyn_storage;

	if ((sym_storage = bfd_get_symtab_upper_bound(disasm_bfd)) >= 0) {

	    if (bfd_get_file_flags(disasm_bfd) & DYNAMIC) {
		dyn_storage = bfd_get_dynamic_symtab_upper_bound(disasm_bfd);
#  if defined(__alpha__)
		/* XXX */
		if (dyn_storage < 0)
		    dyn_storage = 0;
#  else
		assert(dyn_storage >= 0);
#  endif
	    }
	    else
		dyn_storage = 0;

	    jit_alloc((jit_pointer_t *)&disasm_symbols,
		      (sym_storage + dyn_storage) * sizeof(asymbol *));
	    sym_count = bfd_canonicalize_symtab(disasm_bfd, disasm_symbols);
	    assert(sym_count >= 0);
	    if (dyn_storage) {
		dyn_count = bfd_canonicalize_dynamic_symtab(disasm_bfd,
							    disasm_symbols +
							    sym_count);
		assert(dyn_count >= 0);
	    }
	    else
		dyn_count = 0;
	    disasm_num_symbols = sym_count + dyn_count;

	    disasm_num_synthetic = bfd_get_synthetic_symtab(disasm_bfd,
							    sym_count,
							    disasm_symbols,
							    dyn_count,
							    disasm_symbols +
							    sym_count,
							    &disasm_synthetic);
	    if (disasm_num_synthetic > 0) {
		jit_realloc((jit_pointer_t *)&disasm_symbols,
			    (sym_storage + dyn_storage) * sizeof(asymbol *),
			    (sym_storage + dyn_storage + disasm_num_synthetic) *
			    sizeof(asymbol *));
		for (offset = 0; offset < disasm_num_synthetic; offset++)
		    disasm_symbols[disasm_num_symbols++] =
			disasm_synthetic + offset;
	    }

	    /* remove symbols not useful for disassemble */
	    in = out = disasm_symbols;
	    for (offset = 0; offset < disasm_num_symbols; offset++) {
		symbol = *in++;
		if (symbol->name &&
		    symbol->name[0] != '\0' &&
		    !(symbol->flags & (BSF_DEBUGGING | BSF_SECTION_SYM)) &&
		    !bfd_is_und_section(symbol->section) &&
		    !bfd_is_com_section(symbol->section))
		    *out++ = symbol;
	    }
	    disasm_num_symbols = out - disasm_symbols;
	    qsort(disasm_symbols, disasm_num_symbols,
		  sizeof(asymbol *), disasm_compare_symbols);
	}
    }
#endif
}