⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 oops.c

📁 kdb-v4.3-2.4.20-common-1.bz2 键盘的驱动啊 克里斯蒂警方可死了地方军
💻 C
📖 第 1 页 / 共 5 页
字号:
/*    oops.c.    Oops processing for ksymoops.    Copyright 1999 Keith Owens <kaos@ocs.com.au>.    Released under the GNU Public Licence, Version 2. */#include "ksymoops.h"#include <ctype.h>#include <errno.h>#include <malloc.h>#include <memory.h>#include <stdlib.h>#include <string.h>#include <unistd.h>/* Error detected by bfd */static void Oops_bfd_perror(const char *msg){    static char const procname[] = "Oops_bfd_perror";    bfd_error_type err = bfd_get_error();    ERROR("%s %s", msg, bfd_errmsg(err));}/* Open the ksymoops binary so we have an input bfd to copy data from. */static void Oops_open_input_bfd(char **me, bfd **ibfd, const OPTIONS *options){    char **matches, **match;    static char const procname[] = "Oops_open_input_bfd";    *me = find_fullpath(prefix);    if (!*ibfd && !(*ibfd = bfd_openr(*me, NULL))) {	Oops_bfd_perror(*me);	FATAL("%s", "giving up");    }    if (!bfd_check_format_matches(*ibfd, bfd_object, &matches)) {	Oops_bfd_perror(*me);	if (bfd_get_error() == bfd_error_file_ambiguously_recognized) {	    printf("%s Matching formats:", procname);	    match = matches;	    while (*match)		printf(" %s", *match++);	    printf("\n");	    free(matches);	}	FATAL("%s", "giving up");    }}/* If target or architecture is not already set, default to the same as * ksymoops. */static void Oops_set_default_ta(const char *me, const bfd *ibfd,				OPTIONS *options){    static char const procname[] = "Oops_set_default_ta";    const char *bt;    const bfd_arch_info_type *bai;    int t = 0, a = 0;    if (!options->target) {	bt = bfd_get_target(ibfd);	/* Bah, undocumented bfd function */	if (!bt) {	    Oops_bfd_perror(me);	    FATAL("cannot get bfd_target for %s:", me);	}	options->target = bt;	t = 1;    }    if (!options->architecture) {	/* bfd_get_arch_info should really take (const bfd *) */	bai = bfd_get_arch_info((bfd *)ibfd);	if (!bai) {	    Oops_bfd_perror(me);	    FATAL("cannot get bfd_arch_info for %s:", me);	}	options->architecture = bai->printable_name;	a = 1;    }    if (t || a) {	printf("Using defaults from ksymoops");	if (t)	    printf(" -t %s", options->target);	if (a)	    printf(" -a %s", options->architecture);	printf("\n");    }}/* Write the code values to a file using bfd. */static int Oops_write_bfd_data(const bfd *ibfd, bfd *obfd,			       const char *code, int size){    asection *isec, *osec;    asymbol *osym;    /* bfd_get_section_by_name should really take (const bfd *,) */    if (!(isec = bfd_get_section_by_name((bfd *)ibfd, ".text"))) {	Oops_bfd_perror("get_section");	return(0);    }    if (!bfd_set_start_address(obfd, 0)) {	Oops_bfd_perror("set_start_address");	return(0);    }    if (!(osec = bfd_make_section(obfd, ".text"))) {	Oops_bfd_perror("make_section");	return(0);    }    if (!bfd_set_section_flags(obfd, osec,	bfd_get_section_flags(ibfd, isec))) {	Oops_bfd_perror("set_section_flags");	return(0);    }    if (!bfd_set_section_alignment(obfd, osec,	bfd_get_section_alignment(ibfd, isec))) {	Oops_bfd_perror("set_section_alignment");	return(0);    }    osec->output_section = osec;    if (!(osym = bfd_make_empty_symbol(obfd))) {	Oops_bfd_perror("make_empty_symbol");	return(0);    }    osym->name = "_XXX";    osym->section = osec;    osym->flags = BSF_GLOBAL;    osym->value = 0;    if (!bfd_set_symtab(obfd, &osym, 1)) {	Oops_bfd_perror("set_symtab");	return(0);    }    if (!bfd_set_section_size(obfd, osec, size)) {	Oops_bfd_perror("set_section_size");	return(0);    }    if (!bfd_set_section_vma(obfd, osec, 0)) {	Oops_bfd_perror("set_section_vma");	return(0);    }    if (!bfd_set_section_contents(obfd, osec, (PTR) code, 0, size)) {	Oops_bfd_perror("set_section_contents");	return(0);    }    if (!bfd_close(obfd)) {	Oops_bfd_perror("close(obfd)");	return(0);    }    return 1;}/* Write the Oops code to a temporary file with suitable header and trailer. */static char *Oops_code_to_file(const char *code, int size, const bfd *ibfd,			       OPTIONS *options){    char *file, *tmpdir;    int fd;    bfd *obfd;    const bfd_arch_info_type *bai;    static const char temp_suffix[] = "/ksymoops.XXXXXX";    static char const procname[] = "Oops_code_to_file";    /* Security fix, use mkstemp and honour TMPDIR */    if (!(tmpdir = getenv("TMPDIR")) || !*tmpdir) {#ifdef P_tmpdir	tmpdir = P_tmpdir;#else	tmpdir = "/tmp";#endif    }    file = malloc(strlen(tmpdir) + sizeof(temp_suffix));    if (!file)	malloc_error(procname);    strcpy(file, tmpdir);    strcat(file, temp_suffix);    if ((fd = mkstemp(file)) < 0) {	ERROR("Unable to open mkstemp file '%s'\n", file);	perror(prefix);	return(NULL);    }    close(fd);    /* Set the target on the output file */    if (!(obfd = bfd_openw(file, options->target))) {	Oops_bfd_perror(file);	if (bfd_get_error() == bfd_error_wrong_format)	    printf("Sorry, looks like your binutils cannot "		   "handle target %s\n", options->target);	return(NULL);    }    bfd_set_format(obfd, bfd_object);    /* Set the architecture on the output file */    if (!(bai = bfd_scan_arch(options->architecture))) {	Oops_bfd_perror("scan_arch for specified architecture");	if (bfd_get_error() == bfd_error_wrong_format)	    printf("Sorry, looks like your binutils cannot "		"handle the specified architecture\n");	return(NULL);    }    bfd_set_arch_info(obfd, bai);    options->address_bits = bfd_arch_bits_per_address(obfd);    if (!Oops_write_bfd_data(ibfd, obfd, code, size))	return(NULL);    return(file);}/* Run objdump against the binary Oops code */static FILE *Oops_objdump(const char *file, const OPTIONS *options){    char *cmd;    FILE *f;    int cmd_strlen;    static char const objdump_options[] = "-dhf --target=";    static char const procname[] = "Oops_objdump";    /* remember to leave space for spaces */    cmd_strlen = strlen(path_objdump)+1+strlen(objdump_options)+strlen(options->target)+1+strlen(file)+1;    cmd = malloc(cmd_strlen);    if (!cmd)	malloc_error(procname);    strcpy(cmd, path_objdump);    strcat(cmd, " ");    strcat(cmd, objdump_options);    strcat(cmd, options->target);    strcat(cmd, " ");    strcat(cmd, file);    DEBUG(2, "command '%s'", cmd);    f = popen_local(cmd, procname);    free(cmd);    return(f);}/* Forward references. */static const char *Oops_arch_to_eip(const OPTIONS *options);static void Oops_decode_one_add(SYMBOL_SET *ss, const addr_t address,				const char *line1, const char type, const OPTIONS *options);static addr_t Oops_truncate_address(addr_t address, const OPTIONS *options);/* Process one code line from objdump, ignore everything else */static void Oops_decode_one(SYMBOL_SET *ss, const char *line, addr_t eip,			    int adjust, const char type, const OPTIONS *options){    int i;    addr_t address, eip_relative;    char *line2, *map, **string = NULL;    static regex_t     re_Oops_objdump;    static regmatch_t *re_Oops_objdump_pmatch;    static char const procname[] = "Oops_decode_one";    /* objdump output.  Optional whitespace, hex digits, optional     * ' <_XXX+offset>', ':'.  The '+offset' after _XXX is also optional.     * Older binutils output 'xxxxxxxx <_XXX+offset>:', newer versions do     * '00000000 <_XXX>:' first followed by '      xx:' lines.     *     * Just to complicate things even more, objdump recognises jmp, call,     * etc., converts the code to something like this :-     * "   f: e8 32 34 00 00  call   3446 <_XXX+0x3446>"     * Recognise this and append the eip adjusted address, followed by the     * map_address text for that address.     *     * With any luck, objdump will take care of all such references which     * makes this routine architecture insensitive.  No need to test for     * i386 jmp, call or m68k swl etc.     */    RE_COMPILE(&re_Oops_objdump,	    "^ *"	    "([0-9a-fA-F]+)"				/* 1 */	    "( <_XXX[^>]*>)?"				/* 2 */	    ":"	    "("						/* 3 */	    ".* +<_XXX\\+0?x?([0-9a-fA-F]+)> *$"	/* 4 */	    ")?"	    ".*"	    ,	REG_NEWLINE|REG_EXTENDED|REG_ICASE,	&re_Oops_objdump_pmatch);    i = regexec(&re_Oops_objdump, line, re_Oops_objdump.re_nsub+1,	re_Oops_objdump_pmatch, 0);    DEBUG(4, "regexec %d", i);    if (i != 0)	return;    re_strings(&re_Oops_objdump, line, re_Oops_objdump_pmatch, &string);    address = hexstring(string[1]);    if (errno) {	ERROR("Invalid hex value in objdump line, treated as zero - '%s'\n"	    "  objdump line '%s'",	    string[1], line);	perror(prefix);	address = 0;    }    address = Oops_truncate_address(address + eip + adjust, options);    if (string[4]) {	/* EIP relative data to be adjusted. */	eip_relative = hexstring(string[4]);	if (errno) {	    ERROR("Invalid hex value in objdump line, treated as zero - '%s'\n"		  "objdump line '%s'", string[4], line);	    perror(prefix);	    eip_relative = 0;	}	eip_relative = Oops_truncate_address(eip_relative + eip + adjust,		options);	map = map_address(&ss_merged, eip_relative, options);	/* new text is original line, eip_relative in hex, map text */	i = strlen(line)+1+2*sizeof(eip_relative)+1+strlen(map)+1;	line2 = malloc(i);	if (!line2)	    malloc_error(procname);	snprintf(line2, i, "%s %s %s",	    line, format_address(eip_relative, options), map);	Oops_decode_one_add(ss, address, line2, type, options);	free(line2);    }    else	Oops_decode_one_add(ss, address, line, type, options);  /* as is */    re_strings_free(&re_Oops_objdump, &string);}/* Maximum number of code bytes to process.  It needs to be a multiple of 2 for * endianess swapping (-e).  Sparc and alpha dump 36 bytes so use 64. */#define CODE_SIZE 64/* Extract the hex values from the Code: line and convert to binary. * Strange as it seems, this is actually architecture independent, nothing in * this proc cares who created the Code: line. */static int Oops_code_values(const unsigned char* code_text, unsigned char *code,			    int *adjust, const OPTIONS *options){    int byte = 0, byte_prev, len, ret = 1;    U16 u16;    U32 u32;    U64 u64, value;    char **string = NULL;    const char *p;    static regex_t     re_Oops_code_value;    static regmatch_t *re_Oops_code_value_pmatch;    static const char procname[] = "Oops_code_values";    /* Given by re_Oops_code: code_text is a message (e.g. "general protection")     * or one or more hex fields separated by spaces.  Some architectures     * bracket the current instruction with '<' and '>', others use '(' and ')'.     * The first character is nonblank.     */    if (!isxdigit(*code_text)) {	WARNING("%s", "Code looks like message, not hex digits.  "	    "No disassembly attempted.");	return(0);    }    memset(code, '\0', CODE_SIZE);    p = code_text;    *adjust = 0;    /* EIP points to code byte 0 */    /* Code values.  Hex values separated by white space.  On some systems, the     * current instruction is bracketed in '<' and '>' or '(' and ')'.     */    RE_COMPILE(&re_Oops_code_value,	    "^"	    "("				/* 1 */	      "([<(]?)"			/* 2 */	      "([0-9a-fA-F]+)"		/* 3 */	      "[)>]?"	      " *"	    ")"	    "|(Bad .*)"			/* 4 */	    ,	REG_NEWLINE|REG_EXTENDED|REG_ICASE,	&re_Oops_code_value_pmatch);    while (regexec(&re_Oops_code_value, p, re_Oops_code_value.re_nsub+1,	    re_Oops_code_value_pmatch, 0) == 0) {	re_strings(&re_Oops_code_value, p,	    re_Oops_code_value_pmatch, &string);	if (string[4] && *(string[4])) {	    ret = 0;	    break;	/* Bad EIP value, no code bytes */	}	if (byte >= CODE_SIZE)	    break;	value = hexstring(string[3]);	if (errno) {	    ERROR("Invalid hex value in code_value line, treated as zero - "		  "'%s'\ncode_value line '%s'", string[3], code_text);	    perror(prefix);	    value = 0;	}	if (string[2] && *(string[2]))	    *adjust = -byte;    /* this byte is EIP */	/* On some architectures Code: is a stream of bytes, on some it is a	 * stream of shorts, on some it is a stream of ints.  Consistent we're	 * not!	 */	len = strlen(string[3]);	byte_prev = byte;	if (byte+len/2 > CODE_SIZE) {	    WARNING("extra values in Code line, ignored - '%s'", string[3]);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -