diff --git a/.gitignore b/.gitignore index 326fac8fa..a89a8e180 100644 --- a/.gitignore +++ b/.gitignore @@ -14,9 +14,11 @@ config.sub configure install-sh libtool +lightning-*.tar.* ltmain.sh missing stamp-h1 +test-driver check/.deps lib/.deps m4/libtool.m4 diff --git a/ChangeLog b/ChangeLog index 97d8b2642..e73819343 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,25 @@ +2013-01-11 Paulo Andrade + + * lib/jit_note.c: New file implementing a simple string+integer + annotation, that should be used to map filename and line number + to offsets in the generated jit. + + * include/lightning.h, lib/lightning.c: Update for the new + note code. + Add an extra mandatory argument to init_jit, that is used + as argument to bfd_openr. + Change from generic void* to char* the argument to jit_note + and add an extra integer argument, to map to filename and + line number. + + * check/ccall.c, check/lightning.c, include/lightning/jit_private.h, + lib/jit_arm.c, lib/jit_disasm.c, lib/jit_mips.c, lib/jit_ppc.c, + lib/jit_print.c, lib/jit_x86.c: lib/Makefile.am: Update for the + new annotation code. + + * configure.ac, check/Makefile.am: Update to work with latest + automake. + 2013-01-09 Paulo Andrade * include/lightning.h, lib/jit_arm.c, jit_mips-fpu.c, diff --git a/check/Makefile.am b/check/Makefile.am index 8324c36f2..ce78c49fd 100644 --- a/check/Makefile.am +++ b/check/Makefile.am @@ -96,21 +96,72 @@ $(base_TESTS): check.sh TESTS = $(base_TESTS) if test_x86_x87 -x87_TESTS = $(addsuffix .x87, $(base_TESTS)) +#x87_TESTS = $(addsuffix .x87, $(base_TESTS)) +x87_TESTS = \ + 3to2.x87 add.x87 allocai.x87 \ + bp.x87 divi.x87 fib.x87 rpn.x87 \ + ldstr.x87 ldsti.x87 \ + ldstxr.x87 ldstxi.x87 \ + ldstr-c.x87 ldstxr-c.x87 ldstxi-c.x87 \ + cvt.x87 branch.x87 \ + alu_add.x87 alux_add.x87 \ + alu_sub.x87 alux_sub.x87 \ + alu_mul.x87 alu_div.x87 alu_rem.x87 \ + alu_and.x87 alu_or.x87 alu_xor.x87 \ + alu_lsh.x87 alu_rsh.x87 \ + alu_com.x87 alu_neg.x87 \ + fop_abs.x87 fop_sqrt.x87 \ + varargs.x87 stack.x87 \ + clobber.x87 carry.x87 call.x87 \ + float.x87 $(x87_TESTS): check.x87.sh $(LN_S) $(srcdir)/check.x87.sh $@ TESTS += $(x87_TESTS) endif if test_arm_arm -arm_TESTS = $(addsuffix .arm, $(base_TESTS)) +#arm_TESTS = $(addsuffix .arm, $(base_TESTS)) +arm_TESTS = \ + 3to2.arm add.arm allocai.arm \ + bp.arm divi.arm fib.arm rpn.arm \ + ldstr.arm ldsti.arm \ + ldstxr.arm ldstxi.arm \ + ldstr-c.arm ldstxr-c.arm ldstxi-c.arm \ + cvt.arm branch.arm \ + alu_add.arm alux_add.arm \ + alu_sub.arm alux_sub.arm \ + alu_mul.arm alu_div.arm alu_rem.arm \ + alu_and.arm alu_or.arm alu_xor.arm \ + alu_lsh.arm alu_rsh.arm \ + alu_com.arm alu_neg.arm \ + fop_abs.arm fop_sqrt.arm \ + varargs.arm stack.arm \ + clobber.arm carry.arm call.arm \ + float.arm $(arm_TESTS): check.arm.sh $(LN_S) $(srcdir)/check.arm.sh $@ TESTS += $(arm_TESTS) endif if test_arm_swf -swf_TESTS = $(addsuffix .swf, $(base_TESTS)) +#swf_TESTS = $(addsuffix .swf, $(base_TESTS)) +swf_TESTS = \ + 3to2.swf add.swf allocai.swf \ + bp.swf divi.swf fib.swf rpn.swf \ + ldstr.swf ldsti.swf \ + ldstxr.swf ldstxi.swf \ + ldstr-c.swf ldstxr-c.swf ldstxi-c.swf \ + cvt.swf branch.swf \ + alu_add.swf alux_add.swf \ + alu_sub.swf alux_sub.swf \ + alu_mul.swf alu_div.swf alu_rem.swf \ + alu_and.swf alu_or.swf alu_xor.swf \ + alu_lsh.swf alu_rsh.swf \ + alu_com.swf alu_neg.swf \ + fop_abs.swf fop_sqrt.swf \ + varargs.swf stack.swf \ + clobber.swf carry.swf call.swf \ + float.swf $(swf_TESTS): check.swf.sh $(LN_S) $(srcdir)/check.swf.sh $@ TESTS += $(swf_TESTS) @@ -119,7 +170,7 @@ endif TESTS += ccall CLEANFILES = $(TESTS) -TESTS_ENVIRONMENT=$(srcdir)/run-test +#TESTS_ENVIRONMENT=$(srcdir)/run-test; debug: $(check_PROGRAMS) $(LIBTOOL) --mode=execute gdb $(check_PROGRAMS) diff --git a/check/ccall.c b/check/ccall.c index 1ff6b2aeb..201bc2ed7 100644 --- a/check/ccall.c +++ b/check/ccall.c @@ -600,7 +600,7 @@ main(int argc, char *argv[]) jit_node_t *a10,*a11,*a12,*a13,*a14,*a15; jit_node_t *jmp; - init_jit(); + init_jit(argv[0]); _jit = jit_new_state(); jmpi_main = jit_jmpi(); @@ -701,9 +701,10 @@ main(int argc, char *argv[]) #else # define jit_extr_l(u, v) /**/ #endif - + +#define strfy(n) #n #define defi(T, N) \ - n##T##N = jit_note(NULL); \ + n##T##N = jit_note(strfy(n##T##N), 0); \ jit_prolog(); \ arg##N(); \ get##N(,T,JIT_R) \ @@ -711,7 +712,7 @@ main(int argc, char *argv[]) jit_retr(JIT_R0); \ jit_epilog(); #define deff(T, N) \ - n##T##N = jit_note(NULL); \ + n##T##N = jit_note(strfy(n##T##N), 0); \ jit_prolog(); \ arg##N(T); \ get##N(T,T,JIT_F); \ @@ -751,6 +752,7 @@ main(int argc, char *argv[]) #undef def jit_patch(jmpi_main); + jit_note("main", 0); jit_prolog(); #define push0(T) /**/ diff --git a/check/lightning.c b/check/lightning.c index 4c05ba7c8..90bdd7c3d 100644 --- a/check/lightning.c +++ b/check/lightning.c @@ -207,6 +207,7 @@ struct label { char *name; void *value; label_kind_t kind; + int line; }; typedef enum { @@ -501,7 +502,7 @@ static void *xmalloc(size_t size); static void *xrealloc(void *pointer, size_t size); static void *xcalloc(size_t nmemb, size_t size); -static label_t *new_label(label_kind_t kind, char *name, void *value); +static label_t *new_label(label_kind_t kind, char *name, void *value, int line); static patch_t *new_patch(patch_kind_t kind, label_t *label, void *value); static int bcmp_symbols(const void *left, const void *right); static int qcmp_symbols(const void *left, const void *right); @@ -1808,7 +1809,7 @@ get_label(skip_t skip) } if ((label = get_label_by_name(parser.string)) == NULL) label = new_label(label_kind_code_forward, - parser.string, jit_forward()); + parser.string, jit_forward(), 0); return (label); } @@ -2263,7 +2264,7 @@ dynamic(void) value = dlsym(RTLD_DEFAULT, parser.string + 1); if ((string = dlerror())) error("%s", string); - label = new_label(label_kind_dynamic, parser.string, value); + label = new_label(label_kind_dynamic, parser.string, value, 0); } parser.type = type_p; parser.value.p = label->value; @@ -3476,7 +3477,9 @@ parse(void) if ((label = get_label_by_name(parser.string))) { if (label->kind == label_kind_code_forward) { label->kind = label_kind_code; - label->value = jit_label(); + label->line = parser.line; + jit_link(label->value); + jit_note(parser.string, parser.line); } else error("label %s: redefined", parser.string); @@ -3492,7 +3495,8 @@ parse(void) } else error("label not in .code or .data"); - label = new_label(kind, parser.string, value); + label = new_label(kind, parser.string, value, + parser.line); } break; } @@ -3588,7 +3592,7 @@ xcalloc(size_t nmemb, size_t size) } static label_t * -new_label(label_kind_t kind, char *name, void *value) +new_label(label_kind_t kind, char *name, void *value, int line) { label_t *label; @@ -3596,8 +3600,11 @@ new_label(label_kind_t kind, char *name, void *value) label->kind = kind; label->name = strdup(name); label->value = value; + label->line = line; put_hash(labels, (entry_t *)label); label_offset++; + if (label->kind == label_kind_code) + jit_note(name, line); return (label); } @@ -3787,9 +3794,10 @@ main(int argc, char *argv[]) int opt_short; char cmdline[8192]; - init_jit(); - progname = argv[0]; + + init_jit(progname); + for (;;) { if ((opt_short = getopt_long_only(argc, argv, short_options, long_options, &opt_index)) < 0) @@ -3934,8 +3942,6 @@ main(int argc, char *argv[]) parser.line = 1; parser.string = (char *)xmalloc(parser.length = 4096); - labels = new_hash(); - #if defined(__linux__) && (defined(__i386__) || defined(__x86_64__)) /* double precision 0x200 * round nearest 0x000 diff --git a/configure.ac b/configure.ac index 98f0eddfc..9d5e43350 100644 --- a/configure.ac +++ b/configure.ac @@ -19,7 +19,7 @@ AC_CONFIG_SRCDIR([Makefile.am]) AM_INIT_AUTOMAKE([dist-bzip2]) AC_CONFIG_MACRO_DIR(m4) -AM_CONFIG_HEADER(config.h) +AC_CONFIG_HEADER(config.h) AC_PROG_CC AC_PROG_INSTALL @@ -53,10 +53,7 @@ if test "x$DISASSEMBLER" != "xno"; then fi AM_CONDITIONAL(with_disassembler, [test "x$DISASSEMBLER" != "xno"]) if test "x$DISASSEMBLER" != "xno"; then - case "$target_os" in - *linux*) LIGHTNING_CFLAGS="$LIGHTNING_CFLAGS -DDISASSEMBLER=1" ;; - *) ;; - esac + LIGHTNING_CFLAGS="$LIGHTNING_CFLAGS -DDISASSEMBLER=1" fi cpu= diff --git a/include/lightning.h b/include/lightning.h index 821177ebd..41c83fa6b 100644 --- a/include/lightning.h +++ b/include/lightning.h @@ -102,7 +102,7 @@ typedef enum { #define jit_data(u,v) _jit_data(_jit,u,v) jit_code_data, jit_code_save, jit_code_load, -#define jit_note(u) jit_new_node_ww(jit_code_note,0,(jit_word_t)u) +#define jit_note(u, v) _jit_note(_jit, u, v) #define jit_label() _jit_label(_jit) #define jit_forward() _jit_forward(_jit) #define jit_link(u) _jit_link(_jit,u) @@ -732,7 +732,7 @@ typedef enum { /* * Prototypes */ -extern void init_jit(void); +extern void init_jit(char*); extern void finish_jit(void); extern jit_state_t *jit_new_state(void); @@ -740,8 +740,7 @@ extern jit_state_t *jit_new_state(void); #define jit_address(node) _jit_address(_jit, node) extern jit_pointer_t _jit_address(jit_state_t*, jit_node_t*); extern jit_node_t *_jit_data(jit_state_t*, jit_pointer_t, jit_word_t); -extern jit_node_t *_jit_note(jit_state_t*, jit_pointer_t); - +extern jit_node_t *_jit_note(jit_state_t*, char*, int); extern jit_node_t *_jit_label(jit_state_t*); extern jit_node_t *_jit_forward(jit_state_t*); extern void _jit_link(jit_state_t*, jit_node_t*); diff --git a/include/lightning/jit_private.h b/include/lightning/jit_private.h index ca6f97073..5efeee838 100644 --- a/include/lightning/jit_private.h +++ b/include/lightning/jit_private.h @@ -125,6 +125,7 @@ jit_regset_scan1(jit_regset_t, jit_int32_t); * Types */ typedef union jit_data jit_data_t; +typedef struct jit_note jit_note_t; typedef struct jit_block jit_block_t; typedef struct jit_value jit_value_t; typedef struct jit_function jit_function_t; @@ -152,6 +153,13 @@ union jit_data { jit_node_t *n; }; +struct jit_note { + char *name; + jit_int32_t *linenos; + jit_int32_t *offsets; + jit_word_t length; +}; + struct jit_node { jit_node_t *next; jit_code_t code; @@ -269,6 +277,12 @@ struct jit_state { jit_word_t length; } pool; jit_node_t *list; + struct { + jit_note_t *ptr; + jit_node_t *head; /* first note node */ + jit_node_t *tail; /* linked list insertion */ + jit_word_t length; + } note; #if __arm__ # if DISASSEMBLER struct { @@ -378,9 +392,19 @@ _emit_stxi_d(jit_state_t*, jit_word_t, jit_int32_t, jit_int32_t); extern void jit_init_debug(void); extern void jit_finish_debug(void); +extern void jit_init_note(void); +extern void jit_finish_note(void); +#define jit_set_note(u, v, w) _jit_set_note(_jit, u, v, w) +extern void _jit_set_note(jit_state_t*, char*, int, jit_int32_t); +#define jit_get_note(u, v, w) _jit_get_note(_jit, u, v, w) +extern jit_bool_t _jit_get_note(jit_state_t*,jit_uint8_t*,char**,int*); +#define jit_annotate() _jit_annotate(_jit) +extern void _jit_annotate(jit_state_t*); + /* * Externs */ extern jit_register_t _rvs[]; +extern const char *jit_progname; #endif /* _jit_private_h */ diff --git a/lib/Makefile.am b/lib/Makefile.am index 2b2837706..02d58973d 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -18,6 +18,7 @@ liblightning_LTLIBRARIES = liblightning.la liblightningdir = $(libdir) liblightning_la_SOURCES = \ jit_disasm.c \ + jit_note.c \ jit_print.c \ lightning.c diff --git a/lib/jit_arm.c b/lib/jit_arm.c index d3316833a..7b467b12c 100644 --- a/lib/jit_arm.c +++ b/lib/jit_arm.c @@ -1543,6 +1543,7 @@ _jit_emit(jit_state_t *_jit) __clear_cache(_jit->code.ptr, _jit->pc.uc); _jit->done = 1; + jit_annotate(); return (_jit->code.ptr); } diff --git a/lib/jit_disasm.c b/lib/jit_disasm.c index c0a5079b0..602d96b18 100644 --- a/lib/jit_disasm.c +++ b/lib/jit_disasm.c @@ -17,7 +17,9 @@ #include #include -#include +#if DISASSEMBLER +# include +#endif /* * Prototypes @@ -45,6 +47,7 @@ static asymbol **disasm_symbols; static asymbol *disasm_synthetic; static long disasm_num_symbols; static long disasm_num_synthetic; +static jit_state_t *disasm_jit; #define disasm_stream stdout #endif @@ -57,9 +60,7 @@ jit_init_debug(void) #if DISASSEMBLER bfd_init(); - /* FIXME */ - disasm_bfd = bfd_openr("/proc/self/exe", NULL); - + disasm_bfd = bfd_openr(jit_progname, NULL); assert(disasm_bfd); bfd_check_format(disasm_bfd, bfd_object); bfd_check_format(disasm_bfd, bfd_archive); @@ -193,12 +194,27 @@ disasm_compare_symbols(const void *ap, const void *bp) static void disasm_print_address(bfd_vma addr, struct disassemble_info *info) { + char *name; + int line; char buffer[address_buffer_length]; sprintf(buffer, address_buffer_format, (long long)addr); (*info->fprintf_func)(info->stream, "0x%s", buffer); - if (disasm_num_symbols) { +# define _jit disasm_jit +# define jit_pointer_p(u) \ + ((u) >= _jit->code.ptr && (u) < _jit->pc.uc) + if (jit_pointer_p((jit_uint8_t *)(jit_word_t)addr)) { + if (jit_get_note((jit_uint8_t *)(jit_word_t)addr, &name, &line)) { + if (line) + (*info->fprintf_func)(info->stream, " %s:%d", name, line); + else + (*info->fprintf_func)(info->stream, " %s", name); + } + } +# undef jit_pointer_p +# undef _jit + else if (disasm_num_symbols) { long low; long high; long offset; @@ -241,15 +257,17 @@ disasm_print_address(bfd_vma addr, struct disassemble_info *info) static void _disassemble(jit_state_t *_jit, jit_pointer_t code, jit_int32_t length) { - int bytes; + int bytes; + char *name, *old_name; + int line, old_line; #if __arm__ - jit_int32_t offset; - jit_bool_t data_info; - jit_int32_t data_offset; + jit_int32_t offset; + jit_bool_t data_info; + jit_int32_t data_offset; #endif - bfd_vma pc = (jit_uword_t)code; - bfd_vma end = (jit_uword_t)code + length; - char buffer[address_buffer_length]; + bfd_vma pc = (jit_uword_t)code; + bfd_vma end = (jit_uword_t)code + length; + char buffer[address_buffer_length]; #if __arm__ data_info = 1; @@ -258,6 +276,9 @@ _disassemble(jit_state_t *_jit, jit_pointer_t code, jit_int32_t length) disasm_info.buffer = code; disasm_info.buffer_vma = (jit_uword_t)code; disasm_info.buffer_length = length; + old_name = NULL; + old_line = 0; + disasm_jit = _jit; while (pc < end) { #if __arm__ again: @@ -289,6 +310,18 @@ _disassemble(jit_state_t *_jit, jit_pointer_t code, jit_int32_t length) } } #endif + if (jit_get_note((jit_uint8_t *)(jit_word_t)pc, &name, &line) && + (name != old_name || line != old_line)) { + if (line) + (*disasm_info.fprintf_func)(disasm_stream, "# %s:%d\n", + name, line); + else + (*disasm_info.fprintf_func)(disasm_stream, "# %s\n", + name); + old_name = name; + old_line = line; + } + bytes = sprintf(buffer, address_buffer_format, (long long)pc); (*disasm_info.fprintf_func)(disasm_stream, "%*c0x%s\t", 16 - bytes, ' ', buffer); diff --git a/lib/jit_mips.c b/lib/jit_mips.c index cbf4ebd6b..94c4ff3b7 100644 --- a/lib/jit_mips.c +++ b/lib/jit_mips.c @@ -1250,6 +1250,7 @@ _jit_emit(jit_state_t *_jit) _flush_cache((char *)_jit->code.ptr, _jit->pc.uc - _jit->code.ptr, ICACHE); #endif _jit->done = 1; + jit_annotate(); return (_jit->code.ptr); } diff --git a/lib/jit_note.c b/lib/jit_note.c new file mode 100644 index 000000000..648ecac54 --- /dev/null +++ b/lib/jit_note.c @@ -0,0 +1,236 @@ +/* + * Copyright (C) 2013 Free Software Foundation, Inc. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Authors: + * Paulo Cesar Pereira de Andrade + */ + +#include +#include + +/* + * Prototypes + */ +#define new_note(u, v, w, x) _new_note(_jit, u, v, w, x) +static void _new_note(jit_state_t*,jit_int32_t,char*,jit_int32_t,jit_int32_t); +#define note_insert_index(u) _note_insert_index(_jit, u) +static jit_int32_t _note_insert_index(jit_state_t*,jit_int32_t); +#define note_search_index(u) _note_search_index(_jit, u) +static jit_int32_t _note_search_index(jit_state_t*,jit_int32_t); +static jit_int32_t offset_insert_index(jit_note_t*,jit_int32_t); +static jit_int32_t offset_search_index(jit_note_t*,jit_int32_t); + +/* + * Implementation + */ +void +jit_init_note(void) +{ +} + +void +jit_finish_note(void) +{ +} + +void +_jit_set_note(jit_state_t *_jit, + char *name, int lineno, jit_int32_t offset) +{ + jit_note_t *note; + jit_int32_t index; + + index = note_insert_index(offset); + if (index >= _jit->note.length || _jit->note.ptr[index].name != name) + new_note(index, name, lineno, offset); + else { + note = _jit->note.ptr + index; + index = offset_insert_index(note, offset); + if (note->offsets[index] == offset) { + /* common case if no code was generated for several source lines */ + if (note->linenos[index] < lineno) + note->linenos[index] = lineno; + } + else if (note->linenos[index] == lineno) { + /* common case of extending entry */ + if (note->offsets[index] > offset) + note->offsets[index] = offset; + } + else { + /* line or offset changed */ + if ((note->length & 15) == 0) { + note->linenos = realloc(note->linenos, (note->length + 17) * + sizeof(jit_int32_t)); + note->offsets = realloc(note->offsets, (note->length + 17) * + sizeof(jit_int32_t)); + } + if (index < note->length) { + memmove(note->linenos + index + 1, note->linenos + index, + sizeof(jit_int32_t) * (note->length - index)); + memmove(note->offsets + index + 1, note->offsets + index, + sizeof(jit_int32_t) * (note->length - index)); + } + note->linenos[index] = lineno; + note->offsets[index] = offset; + ++note->length; + } + } +} + +jit_bool_t +_jit_get_note(jit_state_t *_jit, jit_uint8_t *code, + char **name, jit_int32_t *lineno) +{ + jit_note_t *note; + jit_int32_t index; + jit_int32_t offset; + + if (code < _jit->code.ptr || code >= _jit->pc.uc) + return (0); + offset = code - _jit->code.ptr; + if ((index = note_search_index(offset)) >= _jit->note.length) + return (0); + if (index == 0 && offset < _jit->note.ptr[0].offsets[0]) + return (0); + note = _jit->note.ptr + index; + if ((index = offset_search_index(note, offset)) >= note->length) + return (0); + + if (name) + *name = note->name; + if (lineno) + *lineno = note->linenos[index]; + + return (1); +} + +static void +_new_note(jit_state_t *_jit, jit_int32_t index, + char *name, jit_int32_t lineno, jit_int32_t offset) +{ + jit_note_t *note; + + if (_jit->note.ptr == NULL) + _jit->note.ptr = malloc(16 * sizeof(jit_note_t)); + else if ((_jit->note.length & 15) == 0) + _jit->note.ptr = realloc(_jit->note.ptr, + (_jit->note.length + 17) * sizeof(jit_note_t)); + + if (index < _jit->note.length) + memmove(_jit->note.ptr + index + 1, _jit->note.ptr + index, + sizeof(jit_note_t) * (_jit->note.length - index)); + note = _jit->note.ptr + index; + ++_jit->note.length; + + note->name = name; + note->length = 1; + note->linenos = malloc(16 * sizeof(jit_int32_t)); + note->linenos[0] = lineno; + note->offsets = malloc(16 * sizeof(jit_int32_t)); + note->offsets[0] = offset; +} + +static jit_int32_t +_note_insert_index(jit_state_t *_jit, jit_int32_t offset) +{ + jit_int32_t bot; + jit_int32_t top; + jit_int32_t index; + jit_note_t *notes; + + bot = 0; + top = _jit->note.length; + if ((notes = _jit->note.ptr) == NULL) + return (0); + for (index = (bot + top) >> 1; bot < top; index = (bot + top) >> 1) { + if (offset < *notes[index].offsets) + top = index; + else + bot = index + 1; + } + + return ((bot + top) >> 1); +} + +static jit_int32_t +_note_search_index(jit_state_t *_jit, jit_int32_t offset) +{ + jit_int32_t bot; + jit_int32_t top; + jit_int32_t index; + jit_note_t *notes; + + bot = 0; + top = _jit->note.length; + if ((notes = _jit->note.ptr) == NULL) + return (0); + for (index = (bot + top) >> 1; bot < top; index = (bot + top) >> 1) { + if (offset < *notes[index].offsets) + top = index; + /* offset should be already verified to be in range */ + else if (index == _jit->note.length - 1 || + (offset >= *notes[index].offsets && + offset < *notes[index + 1].offsets)) + break; + else + bot = index + 1; + } + + return (index); +} + +static jit_int32_t +offset_insert_index(jit_note_t *note, jit_int32_t offset) +{ + jit_int32_t bot; + jit_int32_t top; + jit_int32_t index; + jit_int32_t *offsets; + + bot = 0; + top = note->length; + offsets = note->offsets; + for (index = (bot + top) >> 1; bot < top; index = (bot + top) >> 1) { + if (offset < offsets[index]) + top = index; + else + bot = index + 1; + } + + return ((bot + top) >> 1); +} + +static jit_int32_t +offset_search_index(jit_note_t *note, jit_int32_t offset) +{ + jit_int32_t bot; + jit_int32_t top; + jit_int32_t index; + jit_int32_t *offsets; + + bot = 0; + top = note->length; + offsets = note->offsets; + for (index = (bot + top) >> 1; bot < top; index = (bot + top) >> 1) { + if (offset < offsets[index]) + top = index; + /* offset should be already verified to be in range */ + else if (index == note->length - 1 || + (offset >= offsets[index] && offset < offsets[index + 1])) + break; + else + bot = index + 1; + } + + return (index); +} diff --git a/lib/jit_ppc.c b/lib/jit_ppc.c index c4a507ea1..44b01e5ac 100644 --- a/lib/jit_ppc.c +++ b/lib/jit_ppc.c @@ -1213,6 +1213,7 @@ _jit_emit(jit_state_t *_jit) __clear_cache(_jit->code.ptr, _jit->pc.uc); _jit->done = 1; + jit_annotate(); return (_jit->code.ptr); } diff --git a/lib/jit_print.c b/lib/jit_print.c index 0b3d3bca0..8d5404593 100644 --- a/lib/jit_print.c +++ b/lib/jit_print.c @@ -375,13 +375,15 @@ _jit_print(jit_state_t *_jit) else print_flt(node->w.d); continue; - case jit_code_note: - /* FIXME should be name:line information */ print_chr(' '); - print_ptr(node->v.p); + if (node->v.p) + print_str(node->v.n->u.p); + if (node->v.p && node->w.w) + print_chr(':'); + if (node->w.w) + print_dec(node->w.w); break; - case jit_code_data: case jit_code_label: case jit_code_prolog: case jit_code_epilog: diff --git a/lib/jit_x86.c b/lib/jit_x86.c index fe7aa9863..99063d919 100644 --- a/lib/jit_x86.c +++ b/lib/jit_x86.c @@ -1630,6 +1630,7 @@ _jit_emit(jit_state_t *_jit) patch_at(node, _jit->patches.ptr[offset].inst, word); } _jit->done = 1; + jit_annotate(); return (_jit->code.ptr); } diff --git a/lib/lightning.c b/lib/lightning.c index f61aed34b..62cfea485 100644 --- a/lib/lightning.c +++ b/lib/lightning.c @@ -126,12 +126,18 @@ static void _patch_register(jit_state_t *jit, jit_node_t *node, jit_node_t *link, jit_int32_t regno, jit_int32_t patch); +/* + * Initialization + */ +const char *jit_progname; + /* * Implementation */ void -init_jit(void) +init_jit(char *progname) { + jit_progname = progname; jit_get_cpu(); jit_init_debug(); } @@ -406,6 +412,29 @@ _jit_data(jit_state_t *_jit, jit_pointer_t data, jit_word_t length) return (node); } +jit_node_t * +_jit_note(jit_state_t *_jit, char *name, int line) +{ + jit_node_t *node; + + node = new_node(jit_code_note); + if (name) + node->v.n = jit_data(name, strlen(name)); + else + node->v.p = NULL; + node->w.w = line; + + (void)link_node(node); + if (_jit->note.head == NULL) + _jit->note.head = _jit->note.tail = node; + else { + _jit->note.tail->link = node; + _jit->note.tail = node; + } + + return (node); +} + static void _new_pool(jit_state_t *_jit) { @@ -1113,7 +1142,6 @@ _jit_optimize(jit_state_t *_jit) } } -#if JIT_HASH_CONSTS /* create read only data buffer */ if ((_jit->data.length = (_jit->data.offset + 4095) & -4096)) { jit_uint8_t *ptr; @@ -1132,7 +1160,18 @@ _jit_optimize(jit_state_t *_jit) } } } -#endif +} + +void +_jit_annotate(jit_state_t *_jit) +{ + jit_node_t *node; + + for (node = _jit->note.head; node; node = node->link) { + if (node->v.p) + jit_set_note(node->v.n->u.p, node->w.w, + (jit_uint8_t *)node->u.p - _jit->code.ptr); + } } void