Exemplo n.º 1
0
int resolve_label_ref(argument *arg) {
	if (Mode == mode_label_undef) {
		if (symbol_exists(labels, (char *) Index)) {
			char *msg;
			char *label;

			Mode = mode_constant;
			label = (char *) Index;
			Value = symbol_value(labels, label);
			Index = 0;

			msg = validate_argument(arg);

			if (msg) {
				eprintf("Resolving Label \"%s\": %s\n", label, msg);
				return 1;
			}

			return 0;
		} else {
			if (unresolved_labels) {
				set_symbol(
					unresolved_labels,
					(char *) Index,
					symbol_value(unresolved_labels, (char *) Index) + 1
				);
			}
			return 1;
		}
	}

	return 0;
}
Exemplo n.º 2
0
/*
 *  Versions of disk_dump that support it contain the "dump_level" symbol.
 *  Version 1 and later compressed kdump dumpfiles contain the dump level
 *  in an additional field of the sub_header_kdump structure.
 */
static int 
get_dump_level(void)
{
	int dump_level;

	if (DISKDUMP_VALID()) {
		if (symbol_exists("dump_level") &&
		    readmem(symbol_value("dump_level"), KVADDR, &dump_level,
		    sizeof(dump_level), "dump_level", QUIET|RETURN_ON_ERROR))
                 	return dump_level;
	} else if (KDUMP_CMPRS_VALID()) {
		if (dd->header->header_version >= 1)
			return dd->sub_header_kdump->dump_level;
	}

	return -1;
}
Exemplo n.º 3
0
void
gdb_session_init(void)
{
	struct gnu_request *req;
	int debug_data_pulled_in;

        if (!have_partial_symbols() && !have_full_symbols())
		no_debugging_data(FATAL);

	/*
	 *  Restore the SIGINT and SIGPIPE handlers, which got temporarily
	 *  re-assigned by gdb.  The SIGINT call also initializes GDB's
         *  SIGINT sigaction.
	 */
	SIGACTION(SIGINT, restart, &pc->sigaction, &pc->gdb_sigaction);
	SIGACTION(SIGPIPE, SIG_IGN, &pc->sigaction, NULL);

	if (!(pc->flags & DROP_CORE)) 
		SIGACTION(SIGSEGV, restart, &pc->sigaction, NULL);

	/*
	 *  Set up pointers to gdb variables.
	 */
#if defined(GDB_5_3) || defined(GDB_6_0) || defined(GDB_6_1)
	gdb_output_format = &output_format;
	gdb_print_max = &print_max;
	gdb_prettyprint_structs = &prettyprint_structs;
	gdb_prettyprint_arrays = &prettyprint_arrays;
	gdb_repeat_count_threshold = &repeat_count_threshold;
	gdb_stop_print_at_null = &stop_print_at_null;
	gdb_output_radix = &output_radix;
#else
	gdb_output_format = (int *) 
		gdb_user_print_option_address("output_format");
	gdb_print_max = (unsigned int *)
		gdb_user_print_option_address("print_max");
	gdb_prettyprint_structs = (int *)
		gdb_user_print_option_address("prettyprint_structs");
	gdb_prettyprint_arrays = (int *)
		gdb_user_print_option_address("prettyprint_arrays");
	gdb_repeat_count_threshold = (int *)
		gdb_user_print_option_address("repeat_count_threshold");
	gdb_stop_print_at_null = (int *)
		gdb_user_print_option_address("stop_print_at_null");
	gdb_output_radix = (unsigned int *)
		gdb_user_print_option_address("output_radix");
#endif
	/*
         *  If the output radix is set via the --hex or --dec command line
	 *  option, then pc->output_radix will be non-zero; otherwise use 
	 *  the gdb default.  
	 */
	if (pc->output_radix) {  
		*gdb_output_radix = pc->output_radix;
		*gdb_output_format = (*gdb_output_radix == 10) ? 0 : 'x';
	}

	switch (*gdb_output_radix)
	{
	case 10:
	case 16:
		pc->output_radix = *gdb_output_radix;
		break;
	default:
		pc->output_radix = *gdb_output_radix = 10;
		*gdb_output_format = 0;
	}
		
	*gdb_prettyprint_structs = 1;
	*gdb_repeat_count_threshold = 0x7fffffff;
	*gdb_print_max = 256;
#ifdef GDB_5_3
	gdb_disassemble_from_exec = 0;
#endif

	pc->flags |= GDB_INIT;   /* set here so gdb_interface will work */

        req = (struct gnu_request *)GETBUF(sizeof(struct gnu_request));
        req->buf = GETBUF(BUFSIZE);

	/*
	 *  Make sure the namelist has symbolic data.  Later versions of
	 *  gcc may require that debug data be pulled in by printing a 
	 *  static kernel data structure.
  	 */
	debug_data_pulled_in = FALSE;
retry:
	BZERO(req->buf, BUFSIZE);
        req->command = GNU_GET_DATATYPE;
	req->name = XEN_HYPER_MODE() ? "page_info" : "task_struct";
        req->flags = GNU_RETURN_ON_ERROR;
        gdb_interface(req);

        if (req->flags & GNU_COMMAND_FAILED) {
		if (XEN_HYPER_MODE())
			no_debugging_data(WARNING);  /* just bail out */

		if (!debug_data_pulled_in) {
			if (CRASHDEBUG(1))
				error(INFO, 
           "gdb_session_init: pulling in debug data by accessing init_mm.mmap %s\n",
					symbol_exists("sysfs_mount") ?
					"and syfs_mount" : "");
			debug_data_pulled_in = TRUE;
			req->command = GNU_PASS_THROUGH;
			req->flags = GNU_RETURN_ON_ERROR|GNU_NO_READMEM;
			req->name = NULL;
			if (symbol_exists("sysfs_mount"))
				sprintf(req->buf, "print sysfs_mount, init_mm.mmap");
			else
				sprintf(req->buf, "print init_mm.mmap");
			gdb_interface(req);
        		if (!(req->flags & GNU_COMMAND_FAILED)) 
				goto retry;
		}
		no_debugging_data(WARNING);
	}

	if (pc->flags & KERNEL_DEBUG_QUERY) {
		fprintf(fp, "\n%s: %s: contains debugging data\n\n",
			pc->program_name, pc->namelist);
		if (REMOTE())
			remote_exit();
		clean_exit(0);
	}

	/*
	 *  Set up any pre-ordained gdb settings here that can't be
	 *  accessed directly.
	 */

	req->command = GNU_PASS_THROUGH;
	req->name = NULL, req->flags = 0;
	sprintf(req->buf, "set height 0");
	gdb_interface(req);

	req->command = GNU_PASS_THROUGH;
	req->name = NULL, req->flags = 0;
	sprintf(req->buf, "set width 0");
	gdb_interface(req);

       /*
        *  Patch gdb's symbol values with the correct values from either
        *  the System.map or non-debug vmlinux, whichever is in effect.
        */
	if ((pc->flags & SYSMAP) || (kt->flags & (RELOC_SET|RELOC_FORCE)) || 
	    (pc->namelist_debug && !pc->debuginfo_file)) {
		req->command = GNU_PATCH_SYMBOL_VALUES;
        	req->flags = GNU_RETURN_ON_ERROR;
		gdb_interface(req);
        	if (req->flags & GNU_COMMAND_FAILED)
			error(FATAL, "patching of gdb symbol values failed\n");
	} else if (!(pc->flags & SILENT))
		fprintf(fp, "\n");


	FREEBUF(req->buf);
	FREEBUF(req);
}
Exemplo n.º 4
0
/*
 *  Initialize the unwind table(s) in the best-case order:
 *
 *   1. Use the in-memory kernel and module unwind tables.
 *   2. Use the in-memory kernel-only .eh_frame data. (possible?)
 *   3. Use the kernel-only .eh_frame data from the vmlinux file.
 */ 
void 
init_unwind_table(void)
{
	ulong unwind_table_size;
	void *unwind_table;

	kt->flags &= ~DWARF_UNWIND;

	if (gather_in_memory_unwind_tables()) {
                if (CRASHDEBUG(1))
                        fprintf(fp, "init_unwind_table: DWARF_UNWIND_MEMORY (%d tables)\n",
				unwind_tables_cnt);

                kt->flags |= DWARF_UNWIND_MEMORY;
		if (unwind_tables_cnt > 1)
                	kt->flags |= DWARF_UNWIND_MODULES;
                if (!(kt->flags & NO_DWARF_UNWIND))
                        kt->flags |= DWARF_UNWIND;

		return;
	}

	if (symbol_exists("__start_unwind") &&
	    symbol_exists("__end_unwind")) {
		unwind_table_size = symbol_value("__end_unwind") - 
			symbol_value("__start_unwind");

		if (!(unwind_table = malloc(unwind_table_size))) {
			error(WARNING, "cannot malloc unwind table space\n");
			goto try_eh_frame;
		}

		if (!readmem(symbol_value("__start_unwind"), KVADDR, unwind_table,
            	    unwind_table_size, "unwind table", RETURN_ON_ERROR)) {
			error(WARNING, "cannot read unwind table data\n");
			free(unwind_table);
			goto try_eh_frame;
		}

		kt->flags |= DWARF_UNWIND_MEMORY;
		if (!(kt->flags & NO_DWARF_UNWIND))
			kt->flags |= DWARF_UNWIND;

		default_unwind_table.size = unwind_table_size;
		default_unwind_table.address = unwind_table;

		if (CRASHDEBUG(1)) 
			fprintf(fp, "init_unwind_table: DWARF_UNWIND_MEMORY\n");

		return;
	}

try_eh_frame:

	if (st->dwarf_eh_frame_size || st->dwarf_debug_frame_size) {
		int fd;
		int is_ehframe = (!st->dwarf_debug_frame_size &&
				   st->dwarf_eh_frame_size);

		unwind_table_size = is_ehframe ? st->dwarf_eh_frame_size :
						 st->dwarf_debug_frame_size;

		if (!(unwind_table = malloc(unwind_table_size))) {
			error(WARNING, "cannot malloc unwind table space\n");
			return;
		}

		if ((fd = open(pc->namelist, O_RDONLY)) < 0) {
			error(WARNING, "cannot open %s for %s data\n",
				pc->namelist, is_ehframe ? ".eh_frame" : ".debug_frame");
			free(unwind_table);
			return;
		}

		if (is_ehframe)
			lseek(fd, st->dwarf_eh_frame_file_offset, SEEK_SET);
		else
			lseek(fd, st->dwarf_debug_frame_file_offset, SEEK_SET);

		if (read(fd, unwind_table, unwind_table_size) !=
		    unwind_table_size) {
			if (CRASHDEBUG(1))
				error(WARNING, "cannot read %s data from %s\n",
			        	is_ehframe ? ".eh_frame" : ".debug_frame", pc->namelist);
			free(unwind_table);
			return;
		}

		close(fd);

		default_unwind_table.size = unwind_table_size;
		default_unwind_table.address = unwind_table;

		kt->flags |= DWARF_UNWIND_EH_FRAME;
		if (!(kt->flags & NO_DWARF_UNWIND))
			kt->flags |= DWARF_UNWIND;

		if (CRASHDEBUG(1)) 
			fprintf(fp, "init_unwind_table: DWARF_UNWIND_EH_FRAME\n");

		return;
	}
}