Fix bound checking dlcose problem
The main problem is that an application called dlclose and then had a bound checking problem. The list of dll's in tccrun was not updated an caused a crash. Also fixed some minor other things. tccdbg.c: - Allow filenames like ../file.c - Rewrite DWARF_ABBREV_MEMBER_BF/DWARF_ABBREV_MEMBER a bit tccelf.c: - Add call to __bt_exit. This solves problem when dlclose is called tccrun.c: - Rewrite rt_printline_dwarf a litlle to use opcode_length correctly - Do not stop at DW_LNE_end_sequence - Fix DW_LNE_set_address again. Works now in *bsd. lib/bt-exe.c lib/bt-dll.c: - Add __bt_exit/__bound_exit_dll lib/bcheck.c: - Add __bound_exit_dll
This commit is contained in:
		
							parent
							
								
									4c82b00342
								
							
						
					
					
						commit
						aaec564a82
					
				
					 6 changed files with 192 additions and 149 deletions
				
			
		
							
								
								
									
										20
									
								
								lib/bcheck.c
									
										
									
									
									
								
							
							
						
						
									
										20
									
								
								lib/bcheck.c
									
										
									
									
									
								
							|  | @ -270,6 +270,7 @@ DLL_EXPORT void FASTCALL __bound_local_delete(void *p1); | |||
| void __bound_init(size_t *, int); | ||||
| void __bound_main_arg(int argc, char **argv, char **envp); | ||||
| void __bound_exit(void); | ||||
| void __bound_exit_dll(size_t *); | ||||
| #if !defined(_WIN32) | ||||
| void *__bound_mmap (void *start, size_t size, int prot, int flags, int fd, | ||||
|                     off_t offset); | ||||
|  | @ -1255,6 +1256,25 @@ void __attribute__((destructor)) __bound_exit(void) | |||
|     } | ||||
| } | ||||
| 
 | ||||
| void __bound_exit_dll(size_t *p) | ||||
| { | ||||
|     dprintf(stderr, "%s, %s()\n", __FILE__, __FUNCTION__); | ||||
| 
 | ||||
|     if (p) { | ||||
| 	while (p[0] != 0) { | ||||
| 	    tree = splay_delete(p[0], tree); | ||||
| #if BOUND_DEBUG | ||||
|             if (print_calls) { | ||||
|                 dprintf(stderr, "%s, %s(): remove static var %p 0x%lx\n", | ||||
|                         __FILE__, __FUNCTION__, | ||||
|                         (void *) p[0], (unsigned long) p[1]); | ||||
|             } | ||||
| #endif | ||||
| 	    p += 2; | ||||
| 	} | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #if HAVE_PTHREAD_CREATE | ||||
| typedef struct { | ||||
|     void *(*start_routine) (void *); | ||||
|  |  | |||
|  | @ -6,6 +6,8 @@ | |||
| 
 | ||||
| #define REDIR_ALL \ | ||||
|   REDIR(__bt_init) \ | ||||
|   REDIR(__bt_exit) \ | ||||
|   REDIR(__bound_exit_dll) \ | ||||
|   REDIR(tcc_backtrace) \ | ||||
|   \ | ||||
|   REDIR(__bound_ptr_add) \ | ||||
|  |  | |||
							
								
								
									
										18
									
								
								lib/bt-exe.c
									
										
									
									
									
								
							
							
						
						
									
										18
									
								
								lib/bt-exe.c
									
										
									
									
									
								
							|  | @ -30,11 +30,27 @@ void __bt_init(rt_context *p, int num_callers) | |||
|         __rt_error = _rt_error; | ||||
|         set_exception_handler(); | ||||
|     } else { | ||||
| 	p->num_callers = -1; | ||||
|         p->next = rc->next, rc->next = p; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| __declspec(dllexport) | ||||
| void __bt_exit(rt_context *p) | ||||
| { | ||||
|     __attribute__((weak)) void __bound_exit_dll(void*); | ||||
|     struct rt_context *rc = &g_rtctxt; | ||||
| 
 | ||||
|     if (__bound_exit_dll && p->bounds_start) | ||||
| 	__bound_exit_dll(p->bounds_start); | ||||
|     while (rc) { | ||||
|         if (rc->next == p) { | ||||
| 	    rc->next = rc->next->next; | ||||
| 	    break; | ||||
| 	} | ||||
| 	rc = rc->next; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| /* copy a string and truncate it. */ | ||||
| ST_FUNC char *pstrcpy(char *buf, size_t buf_size, const char *s) | ||||
| { | ||||
|  |  | |||
							
								
								
									
										66
									
								
								tccdbg.c
									
										
									
									
									
								
							
							
						
						
									
										66
									
								
								tccdbg.c
									
										
									
									
									
								
							|  | @ -541,7 +541,7 @@ static void dwarf_file(TCCState *s1) | |||
| 
 | ||||
|     filename = strrchr(file->filename, '/'); | ||||
|     if (filename == NULL) { | ||||
|         for (i = 1; i < dwarf_line.filename_size; i++) | ||||
|         for (i = 0; i < dwarf_line.filename_size; i++) | ||||
|             if (dwarf_line.filename_table[i].dir_entry == 0 && | ||||
| 		strcmp(dwarf_line.filename_table[i].name, | ||||
| 		file->filename) == 0) { | ||||
|  | @ -685,6 +685,7 @@ ST_FUNC void tcc_debug_start(TCCState *s1) | |||
|         if (s1->dwarf) { | ||||
|             int start_abbrev; | ||||
|             unsigned char *ptr; | ||||
| 	    char *undo; | ||||
| 
 | ||||
|             /* dwarf_abbrev */ | ||||
|             start_abbrev = dwarf_abbrev_section->data_offset; | ||||
|  | @ -775,18 +776,32 @@ ST_FUNC void tcc_debug_start(TCCState *s1) | |||
|             dwarf_data1(dwarf_line_section, DWARF_OPCODE_BASE); | ||||
|             ptr = section_ptr_add(dwarf_line_section, sizeof(dwarf_line_opcodes)); | ||||
|             memcpy(ptr, dwarf_line_opcodes, sizeof(dwarf_line_opcodes)); | ||||
|             dwarf_line.dir_size = 1; | ||||
|             dwarf_line.dir_table = (char **) tcc_malloc(sizeof (char *)); | ||||
| 	    undo = strrchr(filename, '/'); | ||||
| 	    if (undo) | ||||
| 		*undo = 0; | ||||
|             dwarf_line.dir_size = 1 + (undo != NULL); | ||||
|             dwarf_line.dir_table = (char **) tcc_malloc(sizeof (char *) * | ||||
| 							dwarf_line.dir_size); | ||||
|             dwarf_line.dir_table[0] = tcc_strdup(buf); | ||||
|             /* line state machine starts with file 1 instead of 0 */ | ||||
| 	    if (undo) | ||||
|                 dwarf_line.dir_table[1] = tcc_strdup(filename); | ||||
|             dwarf_line.filename_size = 2; | ||||
|             dwarf_line.filename_table = | ||||
|     	        (struct dwarf_filename_struct *) | ||||
|     	        tcc_malloc(2*sizeof (struct dwarf_filename_struct)); | ||||
|             dwarf_line.filename_table[0].dir_entry = 0; | ||||
|             dwarf_line.filename_table[0].name = tcc_strdup(filename); | ||||
|             dwarf_line.filename_table[1].dir_entry = 0; | ||||
|             dwarf_line.filename_table[1].name = tcc_strdup(filename); | ||||
| 	    if (undo) { | ||||
|                 dwarf_line.filename_table[0].name = tcc_strdup(filename); | ||||
|                 dwarf_line.filename_table[1].dir_entry = 1; | ||||
|                 dwarf_line.filename_table[1].name = tcc_strdup(undo + 1); | ||||
| 		*undo = '/'; | ||||
|                 dwarf_line.filename_table[0].name = tcc_strdup(filename); | ||||
| 	    } | ||||
| 	    else { | ||||
|                 dwarf_line.filename_table[0].name = tcc_strdup(filename); | ||||
|                 dwarf_line.filename_table[1].dir_entry = 0; | ||||
|                 dwarf_line.filename_table[1].name = tcc_strdup(filename); | ||||
| 	    } | ||||
|             dwarf_line.line_size = dwarf_line.line_max_size = 0; | ||||
|             dwarf_line.line_data = NULL; | ||||
|             dwarf_line.cur_file = 1; | ||||
|  | @ -1020,7 +1035,8 @@ ST_FUNC void tcc_debug_bincl(TCCState *s1) | |||
| 	} | ||||
|         if (strcmp(filename, "<command line>")) { | ||||
| 	    for (j = 0; j < dwarf_line.filename_size; j++) | ||||
| 	        if (strcmp (dwarf_line.filename_table[j].name, filename) == 0) | ||||
| 	        if (dwarf_line.filename_table[j].dir_entry == i && | ||||
| 		    strcmp (dwarf_line.filename_table[j].name, filename) == 0) | ||||
| 		    break; | ||||
| 	    if (j == dwarf_line.filename_size) { | ||||
| 	        dwarf_line.filename_table = | ||||
|  | @ -1428,32 +1444,25 @@ static int tcc_get_dwarf_info(TCCState *s1, Sym *s) | |||
| 	    i = 0; | ||||
|             while (e->next) { | ||||
|                 e = e->next; | ||||
| 	        dwarf_data1(dwarf_info_section, | ||||
| 			    e->type.t & VT_BITFIELD ? DWARF_ABBREV_MEMBER_BF | ||||
| 						    : DWARF_ABBREV_MEMBER); | ||||
| 		dwarf_strp(dwarf_info_section, | ||||
| 			   (e->v & ~SYM_FIELD) >= SYM_FIRST_ANOM | ||||
| 			   ? "" : get_tok_str(e->v & ~SYM_FIELD, NULL)); | ||||
| 		dwarf_uleb128(dwarf_info_section, dwarf_line.cur_file); | ||||
| 		dwarf_uleb128(dwarf_info_section, file->line_num); | ||||
| 		pos_type[i++] = dwarf_info_section->data_offset; | ||||
| 		dwarf_data4(dwarf_info_section, 0); | ||||
|                 if (e->type.t & VT_BITFIELD) { | ||||
|                     int pos = e->c * 8 + BIT_POS(e->type.t); | ||||
|                     int size = BIT_SIZE(e->type.t); | ||||
| 
 | ||||
| 	            dwarf_data1(dwarf_info_section, DWARF_ABBREV_MEMBER_BF); | ||||
| 		    dwarf_strp(dwarf_info_section, | ||||
| 			       (e->v & ~SYM_FIELD) >= SYM_FIRST_ANOM | ||||
| 			       ? "" : get_tok_str(e->v & ~SYM_FIELD, NULL)); | ||||
| 		    dwarf_uleb128(dwarf_info_section, dwarf_line.cur_file); | ||||
| 		    dwarf_uleb128(dwarf_info_section, file->line_num); | ||||
| 		    pos_type[i++] = dwarf_info_section->data_offset; | ||||
| 		    dwarf_data4(dwarf_info_section, 0); | ||||
| 		    dwarf_uleb128(dwarf_info_section, size); | ||||
| 		    dwarf_uleb128(dwarf_info_section, pos); | ||||
| 		} | ||||
| 		else { | ||||
| 	            dwarf_data1(dwarf_info_section, DWARF_ABBREV_MEMBER); | ||||
| 		    dwarf_strp(dwarf_info_section, | ||||
| 			       (e->v & ~SYM_FIELD) >= SYM_FIRST_ANOM | ||||
| 			       ? "" : get_tok_str(e->v & ~SYM_FIELD, NULL)); | ||||
| 		    dwarf_uleb128(dwarf_info_section, dwarf_line.cur_file); | ||||
| 		    dwarf_uleb128(dwarf_info_section, file->line_num); | ||||
| 		    pos_type[i++] = dwarf_info_section->data_offset; | ||||
| 		    dwarf_data4(dwarf_info_section, 0); | ||||
| 		else | ||||
| 		    dwarf_uleb128(dwarf_info_section, e->c); | ||||
| 		} | ||||
| 	    } | ||||
| 	    dwarf_data1(dwarf_info_section, 0); | ||||
| 	    write32le(dwarf_info_section->data + pos_sib, | ||||
|  | @ -1785,12 +1794,13 @@ ST_FUNC void tcc_debug_funcstart(TCCState *s1, Sym *sym) | |||
|         dwarf_info.func = sym; | ||||
|         dwarf_info.line = file->line_num; | ||||
| 	if (s1->do_backtrace) { | ||||
| 	    int i; | ||||
| 	    int i, len; | ||||
| 
 | ||||
| 	    dwarf_line_op(s1, 0); // extended
 | ||||
| 	    dwarf_uleb128_op(s1, strlen(funcname) + 2); | ||||
| 	    dwarf_line_op(s1, DW_LNE_hi_user - 1); | ||||
| 	    for (i = 0; i < strlen(funcname) + 1; i++) | ||||
| 	    len = strlen(funcname) + 1; | ||||
| 	    for (i = 0; i < len; i++) | ||||
| 		dwarf_line_op(s1, funcname[i]); | ||||
| 	} | ||||
|     } | ||||
|  |  | |||
							
								
								
									
										9
									
								
								tccelf.c
									
										
									
									
									
								
							
							
						
						
									
										9
									
								
								tccelf.c
									
										
									
									
									
								
							|  | @ -1389,15 +1389,14 @@ ST_FUNC void tcc_add_btstub(TCCState *s1) | |||
|             put_ptr(s1, dwarf_line_str_section, 0); | ||||
| 	else | ||||
|             put_ptr(s1, dwarf_str_section, 0); | ||||
| 	put_ptr(s1, text_section, 0); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         put_ptr(s1, stab_section, 0); | ||||
|         put_ptr(s1, stab_section, -1); | ||||
|         put_ptr(s1, stab_section->link, 0); | ||||
|         section_ptr_add(s, PTR_SIZE); | ||||
|     } | ||||
|     *(addr_t *)section_ptr_add(s, PTR_SIZE) = s1->dwarf; | ||||
|     /* skip esym_start/esym_end/elf_str (not loaded) */ | ||||
|     section_ptr_add(s, 3 * PTR_SIZE); | ||||
|     /* prog_base : local nameless symbol with offset 0 at SHN_ABS */ | ||||
|  | @ -1412,7 +1411,7 @@ ST_FUNC void tcc_add_btstub(TCCState *s1) | |||
|     section_ptr_add(s, n); | ||||
|     cstr_new(&cstr); | ||||
|     cstr_printf(&cstr, | ||||
|         "extern void __bt_init(),__bt_init_dll();" | ||||
|         "extern void __bt_init(),__bt_exit(),__bt_init_dll();" | ||||
|         "static void *__rt_info[];" | ||||
|         "__attribute__((constructor)) static void __bt_init_rt(){"); | ||||
| #ifdef TCC_TARGET_PE | ||||
|  | @ -1425,6 +1424,10 @@ ST_FUNC void tcc_add_btstub(TCCState *s1) | |||
| #endif | ||||
|     cstr_printf(&cstr, "__bt_init(__rt_info,%d);}", | ||||
|         s1->output_type == TCC_OUTPUT_DLL ? 0 : s1->rt_num_callers + 1); | ||||
|     /* In case dlcose is called by application */ | ||||
|     cstr_printf(&cstr, | ||||
|         "__attribute__((destructor)) static void __bt_exit_rt(){" | ||||
|         "__bt_exit(__rt_info);}"); | ||||
|     tcc_compile_string_no_debug(s1, cstr.data); | ||||
|     cstr_free(&cstr); | ||||
|     set_local_sym(s1, &"___rt_info"[!s1->leading_underscore], s, o); | ||||
|  |  | |||
							
								
								
									
										226
									
								
								tccrun.c
									
										
									
									
									
								
							
							
						
						
									
										226
									
								
								tccrun.c
									
										
									
									
									
								
							|  | @ -34,9 +34,9 @@ typedef struct rt_context | |||
| 	}; | ||||
| 	struct { | ||||
|     	    unsigned char *dwarf_line, *dwarf_line_end, *dwarf_line_str; | ||||
| 	    addr_t dwarf_text; | ||||
| 	}; | ||||
|     }; | ||||
|     addr_t dwarf; | ||||
|     ElfW(Sym) *esym_start, *esym_end; | ||||
|     char *elf_str; | ||||
|     addr_t prog_base; | ||||
|  | @ -182,15 +182,14 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv) | |||
| 	    rc->dwarf_line_end = dwarf_line_section->data + dwarf_line_section->data_offset; | ||||
| 	    if (dwarf_line_str_section) | ||||
| 		rc->dwarf_line_str = dwarf_line_str_section->data; | ||||
|             rc->dwarf_text = text_section->sh_addr; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
|             rc->stab_sym = (Stab_Sym *)stab_section->data; | ||||
|             rc->stab_sym_end = (Stab_Sym *)(stab_section->data + stab_section->data_offset); | ||||
|             rc->stab_str = (char *)stab_section->link->data; | ||||
| 	    rc->dwarf_text = 0; | ||||
| 	} | ||||
|         rc->dwarf = s1->dwarf; | ||||
|         rc->esym_start = (ElfW(Sym) *)(symtab_section->data); | ||||
|         rc->esym_end = (ElfW(Sym) *)(symtab_section->data + symtab_section->data_offset); | ||||
|         rc->elf_str = (char *)symtab_section->link->data; | ||||
|  | @ -666,7 +665,9 @@ static addr_t rt_printline_dwarf (rt_context *rc, addr_t wanted_pc, | |||
|     unsigned char *ln; | ||||
|     unsigned char *cp; | ||||
|     unsigned char *end; | ||||
|     unsigned int size; | ||||
|     unsigned char *opcode_length; | ||||
|     unsigned long long size; | ||||
|     unsigned int length; | ||||
|     unsigned char version; | ||||
|     unsigned int min_insn_length; | ||||
|     unsigned int max_ops_per_insn; | ||||
|  | @ -678,7 +679,7 @@ static addr_t rt_printline_dwarf (rt_context *rc, addr_t wanted_pc, | |||
|     unsigned int i; | ||||
|     unsigned int j; | ||||
|     unsigned int len; | ||||
|     unsigned int value; | ||||
|     unsigned long long value; | ||||
|     struct { | ||||
| 	unsigned int type; | ||||
| 	unsigned int form; | ||||
|  | @ -695,13 +696,11 @@ static addr_t rt_printline_dwarf (rt_context *rc, addr_t wanted_pc, | |||
|     addr_t last_pc; | ||||
|     addr_t pc; | ||||
|     addr_t func_addr; | ||||
|     addr_t offset_dll; | ||||
|     int line; | ||||
|     char *filename; | ||||
|     char *function; | ||||
| 
 | ||||
| next: | ||||
|     offset_dll = 0; | ||||
|     ln = rc->dwarf_line; | ||||
|     while (ln < rc->dwarf_line_end) { | ||||
| 	dir_size = 0; | ||||
|  | @ -712,13 +711,18 @@ next: | |||
|         line = 1; | ||||
|         filename = NULL; | ||||
|         function = NULL; | ||||
| 	length = 4; | ||||
| 	size = dwarf_read_4(ln, rc->dwarf_line_end); | ||||
| 	if (size == 0xffffffffu) // dwarf 64
 | ||||
| 	    length = 8, size = dwarf_read_8(ln, rc->dwarf_line_end); | ||||
| 	end = ln + size; | ||||
| 	if (end < ln || end > rc->dwarf_line_end) | ||||
| 	    break; | ||||
| 	version = dwarf_read_2(ln, end); | ||||
| 	if (version >= 5) | ||||
| 	    ln += 6; // address size, segment selector, prologue Length
 | ||||
| 	    ln += length + 2; // address size, segment selector, prologue Length
 | ||||
| 	else | ||||
| 	    ln += 4; // prologue Length
 | ||||
| 	    ln += length; // prologue Length
 | ||||
| 	min_insn_length = dwarf_read_1(ln, end); | ||||
| 	if (version >= 4) | ||||
| 	    max_ops_per_insn = dwarf_read_1(ln, end); | ||||
|  | @ -729,8 +733,9 @@ next: | |||
| 	line_base |= line_base >= 0x80 ? ~0xff : 0; | ||||
| 	line_range = dwarf_read_1(ln, end); | ||||
| 	opcode_base = dwarf_read_1(ln, end); | ||||
| 	opcode_length = ln; | ||||
| 	ln += opcode_base - 1; | ||||
| 	opindex = 0; | ||||
| 	ln += 12; | ||||
| 	if (version >= 5) { | ||||
| 	    col = dwarf_read_1(ln, end); | ||||
| 	    for (i = 0; i < col; i++) { | ||||
|  | @ -744,11 +749,13 @@ next: | |||
| 		        if (entry_format[j].form != DW_FORM_line_strp) | ||||
| 			    goto next_line; | ||||
| #if 0 | ||||
| 		        value = dwarf_read_4(ln, end); | ||||
| 		        value = length == 4 ? dwarf_read_4(ln, end) | ||||
| 					    : dwarf_read_8(ln, end); | ||||
| 		        if (i < DIR_TABLE_SIZE) | ||||
| 		            dirs[i] = (char *)rc->dwarf_line_str + value; | ||||
| #else | ||||
| 			dwarf_read_4(ln, end); | ||||
| 			length == 4 ? dwarf_read_4(ln, end) | ||||
| 				    : dwarf_read_8(ln, end); | ||||
| #endif | ||||
| 		    } | ||||
| 		    else  | ||||
|  | @ -766,7 +773,8 @@ next: | |||
| 		    if (entry_format[j].type == DW_LNCT_path) { | ||||
| 			if (entry_format[j].form != DW_FORM_line_strp) | ||||
| 			    goto next_line; | ||||
| 			value = dwarf_read_4(ln, end); | ||||
| 			value = length == 4 ? dwarf_read_4(ln, end) | ||||
| 					    : dwarf_read_8(ln, end); | ||||
| 		        if (i < FILE_TABLE_SIZE) | ||||
| 		            filename_table[i].name = | ||||
| 				(char *)rc->dwarf_line_str + value; | ||||
|  | @ -813,108 +821,8 @@ next: | |||
| 	    filename = filename_table[0].name; | ||||
| 	while (ln < end) { | ||||
| 	    last_pc = pc; | ||||
| 	    switch (dwarf_read_1(ln, end)) { | ||||
| 	    case 0: | ||||
| 		len = dwarf_read_uleb128(&ln, end); | ||||
| 		cp = ln; | ||||
| 		ln += len; | ||||
| 		if (len == 0) | ||||
| 		    goto next_line; | ||||
| 		switch (dwarf_read_1(cp, end)) { | ||||
| 		case DW_LNE_end_sequence: | ||||
| 		    goto next_line; | ||||
| 		case DW_LNE_set_address: | ||||
| #if PTR_SIZE == 4 | ||||
| 		    pc = dwarf_read_4(cp, end); | ||||
| #else | ||||
| 		    pc = dwarf_read_8(cp, end); | ||||
| #endif | ||||
| 		    if (rc->num_callers < 0) { | ||||
| 			/* dll */ | ||||
| 			if (!offset_dll) | ||||
| 			    offset_dll = pc; | ||||
| 		        pc = rc->dwarf_text + (pc - offset_dll); | ||||
| 		    } | ||||
| 		    opindex = 0; | ||||
| 		    break; | ||||
| 		case DW_LNE_define_file: /* deprecated */ | ||||
| 		    if (++filename_size < FILE_TABLE_SIZE) { | ||||
| 		        filename_table[filename_size - 1].name = (char *)ln - 1; | ||||
| 		        while (dwarf_read_1(ln, end)) {} | ||||
| 		        filename_table[filename_size - 1].dir_entry = | ||||
| 		            dwarf_read_uleb128(&ln, end); | ||||
| 		    } | ||||
| 		    else { | ||||
| 		        while (dwarf_read_1(ln, end)) {} | ||||
| 		        dwarf_read_uleb128(&ln, end); | ||||
| 		    } | ||||
| 		    dwarf_read_uleb128(&ln, end); // time
 | ||||
| 		    dwarf_read_uleb128(&ln, end); // size
 | ||||
| 		    break; | ||||
| 		case DW_LNE_hi_user - 1: | ||||
| 		    function = (char *)cp; | ||||
| 		    func_addr = pc; | ||||
| 		    break; | ||||
| 		default: | ||||
| 		    break; | ||||
| 		} | ||||
| 		break; | ||||
| 	    case DW_LNS_copy: | ||||
| 		break; | ||||
| 	    case DW_LNS_advance_pc: | ||||
| 		if (max_ops_per_insn == 1) | ||||
| 		    pc += dwarf_read_uleb128(&ln, end) * min_insn_length; | ||||
| 		else { | ||||
| 		    unsigned long long off = dwarf_read_uleb128(&ln, end); | ||||
| 
 | ||||
| 		    pc += (opindex + off) / max_ops_per_insn * | ||||
| 			  min_insn_length; | ||||
| 		    opindex = (opindex + off) % max_ops_per_insn; | ||||
| 		} | ||||
| 		i = 0; | ||||
| 		goto check_pc; | ||||
| 	    case DW_LNS_advance_line: | ||||
| 		line += dwarf_read_sleb128(&ln, end); | ||||
| 		break; | ||||
| 	    case DW_LNS_set_file: | ||||
| 		i = dwarf_read_uleb128(&ln, end); | ||||
| 		if (i < FILE_TABLE_SIZE && i < filename_size) | ||||
| 		    filename = filename_table[i].name; | ||||
| 		break; | ||||
| 	    case DW_LNS_set_column: | ||||
| 		dwarf_read_uleb128(&ln, end); | ||||
| 		break; | ||||
| 	    case DW_LNS_negate_stmt: | ||||
| 		break; | ||||
| 	    case DW_LNS_set_basic_block: | ||||
| 		break; | ||||
| 	    case DW_LNS_const_add_pc: | ||||
| 		if (max_ops_per_insn ==  1) | ||||
| 		    pc += ((255 - opcode_base) / line_range) * min_insn_length; | ||||
| 		else { | ||||
| 		    unsigned int off = (255 - opcode_base) / line_range; | ||||
| 
 | ||||
| 		    pc += ((opindex + off) / max_ops_per_insn) * | ||||
| 			  min_insn_length; | ||||
| 		    opindex = (opindex + off) % max_ops_per_insn; | ||||
| 		} | ||||
| 		i = 0; | ||||
| 		goto check_pc; | ||||
| 	    case DW_LNS_fixed_advance_pc: | ||||
| 		i = dwarf_read_2(ln, end); | ||||
| 		pc += i; | ||||
| 		opindex = 0; | ||||
| 		i = 0; | ||||
| 		goto check_pc; | ||||
| 	    case DW_LNS_set_prologue_end: | ||||
| 		break; | ||||
| 	    case DW_LNS_set_epilogue_begin: | ||||
| 		break; | ||||
| 	    case DW_LNS_set_isa: | ||||
| 		dwarf_read_uleb128(&ln, end); | ||||
| 		break; | ||||
| 	    default: | ||||
| 		i = ln[-1]; | ||||
| 	    i = dwarf_read_1(ln, end); | ||||
| 	    if (i >= opcode_base) { | ||||
| 	        if (max_ops_per_insn == 1) | ||||
| 		    pc += ((i - opcode_base) / line_range) * min_insn_length; | ||||
| 		else { | ||||
|  | @ -928,7 +836,91 @@ check_pc: | |||
| 		if (pc >= wanted_pc && wanted_pc >= last_pc) | ||||
| 		    goto found; | ||||
| 		line += i; | ||||
| 		break; | ||||
| 	    } | ||||
| 	    else { | ||||
| 	        switch (i) { | ||||
| 	        case 0: | ||||
| 		    len = dwarf_read_uleb128(&ln, end); | ||||
| 		    cp = ln; | ||||
| 		    ln += len; | ||||
| 		    if (len == 0) | ||||
| 		        goto next_line; | ||||
| 		    switch (dwarf_read_1(cp, end)) { | ||||
| 		    case DW_LNE_end_sequence: | ||||
| 		        break; | ||||
| 		    case DW_LNE_set_address: | ||||
| #if PTR_SIZE == 4 | ||||
| 		        pc = dwarf_read_4(cp, end); | ||||
| #else | ||||
| 		        pc = dwarf_read_8(cp, end); | ||||
| #endif | ||||
| 		        opindex = 0; | ||||
| 		        break; | ||||
| 		    case DW_LNE_define_file: /* deprecated */ | ||||
| 		        if (++filename_size < FILE_TABLE_SIZE) { | ||||
| 		            filename_table[filename_size - 1].name = (char *)ln - 1; | ||||
| 		            while (dwarf_read_1(ln, end)) {} | ||||
| 		            filename_table[filename_size - 1].dir_entry = | ||||
| 		                dwarf_read_uleb128(&ln, end); | ||||
| 		        } | ||||
| 		        else { | ||||
| 		            while (dwarf_read_1(ln, end)) {} | ||||
| 		            dwarf_read_uleb128(&ln, end); | ||||
| 		        } | ||||
| 		        dwarf_read_uleb128(&ln, end); // time
 | ||||
| 		        dwarf_read_uleb128(&ln, end); // size
 | ||||
| 		        break; | ||||
| 		    case DW_LNE_hi_user - 1: | ||||
| 		        function = (char *)cp; | ||||
| 		        func_addr = pc; | ||||
| 		        break; | ||||
| 		    default: | ||||
| 		        break; | ||||
| 		    } | ||||
| 		    break; | ||||
| 	        case DW_LNS_advance_pc: | ||||
| 		    if (max_ops_per_insn == 1) | ||||
| 		        pc += dwarf_read_uleb128(&ln, end) * min_insn_length; | ||||
| 		    else { | ||||
| 		        unsigned long long off = dwarf_read_uleb128(&ln, end); | ||||
| 
 | ||||
| 		        pc += (opindex + off) / max_ops_per_insn * | ||||
| 			      min_insn_length; | ||||
| 		        opindex = (opindex + off) % max_ops_per_insn; | ||||
| 		    } | ||||
| 		    i = 0; | ||||
| 		    goto check_pc; | ||||
| 	        case DW_LNS_advance_line: | ||||
| 		    line += dwarf_read_sleb128(&ln, end); | ||||
| 		    break; | ||||
| 	        case DW_LNS_set_file: | ||||
| 		    i = dwarf_read_uleb128(&ln, end); | ||||
| 		    if (i < FILE_TABLE_SIZE && i < filename_size) | ||||
| 		        filename = filename_table[i].name; | ||||
| 		    break; | ||||
| 	        case DW_LNS_const_add_pc: | ||||
| 		    if (max_ops_per_insn ==  1) | ||||
| 		        pc += ((255 - opcode_base) / line_range) * min_insn_length; | ||||
| 		    else { | ||||
| 		        unsigned int off = (255 - opcode_base) / line_range; | ||||
| 
 | ||||
| 		        pc += ((opindex + off) / max_ops_per_insn) * | ||||
| 			      min_insn_length; | ||||
| 		        opindex = (opindex + off) % max_ops_per_insn; | ||||
| 		    } | ||||
| 		    i = 0; | ||||
| 		    goto check_pc; | ||||
| 	        case DW_LNS_fixed_advance_pc: | ||||
| 		    i = dwarf_read_2(ln, end); | ||||
| 		    pc += i; | ||||
| 		    opindex = 0; | ||||
| 		    i = 0; | ||||
| 		    goto check_pc; | ||||
| 	        default: | ||||
| 		    for (j = 0; j < opcode_length[i - 1]; j++) | ||||
|                         dwarf_read_uleb128 (&ln, end); | ||||
| 		    break; | ||||
| 		} | ||||
| 	    } | ||||
| 	} | ||||
| next_line: | ||||
|  | @ -988,7 +980,7 @@ static int _rt_error(void *fp, void *ip, const char *fmt, va_list ap) | |||
|         ret = rt_get_caller_pc(&pc, rc, i); | ||||
|         a = "%s"; | ||||
|         if (ret != -1) { | ||||
| 	    if ((addr_t)rc->dwarf_text) | ||||
| 	    if (rc->dwarf) | ||||
|                 pc = rt_printline_dwarf(rc, pc, level ? "by" : "at", skip); | ||||
| 	    else | ||||
|                 pc = rt_printline(rc, pc, level ? "by" : "at", skip); | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue