📄 core-lite.patch
字号:
+ char tmp_variable[BREAK_INSTR_SIZE];+ error = kgdb_get_mem((char *)addr, tmp_variable, BREAK_INSTR_SIZE);+ return error;+}++int __attribute__ ((weak))+ kgdb_arch_set_breakpoint(unsigned long addr, char *saved_instr)+{+ int error = 0;+ if ((error = kgdb_get_mem((char *)addr,+ saved_instr, BREAK_INSTR_SIZE)) < 0)+ return error;++ if ((error = kgdb_set_mem((char *)addr, kgdb_ops->gdb_bpt_instr,+ BREAK_INSTR_SIZE)) < 0)+ return error;+ return 0;+}++int __attribute__ ((weak))+ kgdb_arch_remove_breakpoint(unsigned long addr, char *bundle)+{++ int error = 0;+ if ((error =kgdb_set_mem((char *)addr, (char *)bundle,+ BREAK_INSTR_SIZE)) < 0)+ return error;+ return 0;+}++static int hex(char ch)+{+ if ((ch >= 'a') && (ch <= 'f'))+ return (ch - 'a' + 10);+ if ((ch >= '0') && (ch <= '9'))+ return (ch - '0');+ if ((ch >= 'A') && (ch <= 'F'))+ return (ch - 'A' + 10);+ return (-1);+}++/* scan for the sequence $<data>#<checksum> */+static void get_packet(char *buffer)+{+ unsigned char checksum;+ unsigned char xmitcsum;+ int count;+ char ch;+ if (!kgdb_io_ops.read_char)+ return;+ do {+ /* Spin and wait around for the start character, ignore all+ * other characters */+ while ((ch = (kgdb_io_ops.read_char())) != '$') ;+ kgdb_connected = 1;+ checksum = 0;+ xmitcsum = -1;++ count = 0;++ /* now, read until a # or end of buffer is found */+ while (count < (BUFMAX - 1)) {+ ch = kgdb_io_ops.read_char();+ if (ch == '#')+ break;+ checksum = checksum + ch;+ buffer[count] = ch;+ count = count + 1;+ }+ buffer[count] = 0;++ if (ch == '#') {+ xmitcsum = hex(kgdb_io_ops.read_char()) << 4;+ xmitcsum += hex(kgdb_io_ops.read_char());++ if (checksum != xmitcsum)+ /* failed checksum */+ kgdb_io_ops.write_char('-');+ else+ /* successful transfer */+ kgdb_io_ops.write_char('+');+ if (kgdb_io_ops.flush)+ kgdb_io_ops.flush();+ }+ } while (checksum != xmitcsum);+}++/*+ * Send the packet in buffer.+ * Check for gdb connection if asked for.+ */+static void put_packet(char *buffer)+{+ unsigned char checksum;+ int count;+ char ch;++ if (!kgdb_io_ops.write_char)+ return;+ /* $<packet info>#<checksum>. */+ while (1) {+ kgdb_io_ops.write_char('$');+ checksum = 0;+ count = 0;++ while ((ch = buffer[count])) {+ kgdb_io_ops.write_char(ch);+ checksum += ch;+ count++;+ }++ kgdb_io_ops.write_char('#');+ kgdb_io_ops.write_char(hexchars[checksum >> 4]);+ kgdb_io_ops.write_char(hexchars[checksum % 16]);+ if (kgdb_io_ops.flush)+ kgdb_io_ops.flush();++ /* Now see what we get in reply. */+ ch = kgdb_io_ops.read_char();++ if (ch == 3)+ ch = kgdb_io_ops.read_char();++ /* If we get an ACK, we are done. */+ if (ch == '+')+ return;++ /* If we get the start of another packet, this means+ * that GDB is attempting to reconnect. We will NAK+ * the packet being sent, and stop trying to send this+ * packet. */+ if (ch == '$') {+ kgdb_io_ops.write_char('-');+ if (kgdb_io_ops.flush)+ kgdb_io_ops.flush();+ return;+ }+ }+}++/*+ * convert the memory pointed to by mem into hex, placing result in buf+ * return a pointer to the last char put in buf (null). May return an error.+ */+char *kgdb_mem2hex(char *mem, char *buf, int count)+{+ kgdb_may_fault = 1;+ if ((kgdb_fault_setjmp(kgdb_fault_jmp_regs)) != 0) {+ kgdb_may_fault = 0;+ return ERR_PTR(-EINVAL);+ }+ /* Accessing some registers in a single load instruction is+ * required to avoid bad side effects for some I/O registers.+ */+ if ((count == 2) && (((long)mem & 1) == 0)) {+ unsigned short tmp_s = *(unsigned short *)mem;+ mem += 2;+#ifdef __BIG_ENDIAN+ *buf++ = hexchars[(tmp_s >> 12) & 0xf];+ *buf++ = hexchars[(tmp_s >> 8) & 0xf];+ *buf++ = hexchars[(tmp_s >> 4) & 0xf];+ *buf++ = hexchars[tmp_s & 0xf];+#else+ *buf++ = hexchars[(tmp_s >> 4) & 0xf];+ *buf++ = hexchars[tmp_s & 0xf];+ *buf++ = hexchars[(tmp_s >> 12) & 0xf];+ *buf++ = hexchars[(tmp_s >> 8) & 0xf];+#endif+ } else if ((count == 4) && (((long)mem & 3) == 0)) {+ unsigned long tmp_l = *(unsigned int *)mem;+ mem += 4;+#ifdef __BIG_ENDIAN+ *buf++ = hexchars[(tmp_l >> 28) & 0xf];+ *buf++ = hexchars[(tmp_l >> 24) & 0xf];+ *buf++ = hexchars[(tmp_l >> 20) & 0xf];+ *buf++ = hexchars[(tmp_l >> 16) & 0xf];+ *buf++ = hexchars[(tmp_l >> 12) & 0xf];+ *buf++ = hexchars[(tmp_l >> 8) & 0xf];+ *buf++ = hexchars[(tmp_l >> 4) & 0xf];+ *buf++ = hexchars[tmp_l & 0xf];+#else+ *buf++ = hexchars[(tmp_l >> 4) & 0xf];+ *buf++ = hexchars[tmp_l & 0xf];+ *buf++ = hexchars[(tmp_l >> 12) & 0xf];+ *buf++ = hexchars[(tmp_l >> 8) & 0xf];+ *buf++ = hexchars[(tmp_l >> 20) & 0xf];+ *buf++ = hexchars[(tmp_l >> 16) & 0xf];+ *buf++ = hexchars[(tmp_l >> 28) & 0xf];+ *buf++ = hexchars[(tmp_l >> 24) & 0xf];+#endif+#ifdef CONFIG_64BIT+ } else if ((count == 8) && (((long)mem & 7) == 0)) {+ unsigned long long tmp_ll = *(unsigned long long *)mem;+ mem += 8;+#ifdef __BIG_ENDIAN+ *buf++ = hexchars[(tmp_ll >> 60) & 0xf];+ *buf++ = hexchars[(tmp_ll >> 56) & 0xf];+ *buf++ = hexchars[(tmp_ll >> 52) & 0xf];+ *buf++ = hexchars[(tmp_ll >> 48) & 0xf];+ *buf++ = hexchars[(tmp_ll >> 44) & 0xf];+ *buf++ = hexchars[(tmp_ll >> 40) & 0xf];+ *buf++ = hexchars[(tmp_ll >> 36) & 0xf];+ *buf++ = hexchars[(tmp_ll >> 32) & 0xf];+ *buf++ = hexchars[(tmp_ll >> 28) & 0xf];+ *buf++ = hexchars[(tmp_ll >> 24) & 0xf];+ *buf++ = hexchars[(tmp_ll >> 20) & 0xf];+ *buf++ = hexchars[(tmp_ll >> 16) & 0xf];+ *buf++ = hexchars[(tmp_ll >> 12) & 0xf];+ *buf++ = hexchars[(tmp_ll >> 8) & 0xf];+ *buf++ = hexchars[(tmp_ll >> 4) & 0xf];+ *buf++ = hexchars[tmp_ll & 0xf];+#else+ *buf++ = hexchars[(tmp_ll >> 4) & 0xf];+ *buf++ = hexchars[tmp_ll & 0xf];+ *buf++ = hexchars[(tmp_ll >> 12) & 0xf];+ *buf++ = hexchars[(tmp_ll >> 8) & 0xf];+ *buf++ = hexchars[(tmp_ll >> 20) & 0xf];+ *buf++ = hexchars[(tmp_ll >> 16) & 0xf];+ *buf++ = hexchars[(tmp_ll >> 28) & 0xf];+ *buf++ = hexchars[(tmp_ll >> 24) & 0xf];+ *buf++ = hexchars[(tmp_ll >> 36) & 0xf];+ *buf++ = hexchars[(tmp_ll >> 32) & 0xf];+ *buf++ = hexchars[(tmp_ll >> 44) & 0xf];+ *buf++ = hexchars[(tmp_ll >> 40) & 0xf];+ *buf++ = hexchars[(tmp_ll >> 52) & 0xf];+ *buf++ = hexchars[(tmp_ll >> 48) & 0xf];+ *buf++ = hexchars[(tmp_ll >> 60) & 0xf];+ *buf++ = hexchars[(tmp_ll >> 56) & 0xf];+#endif+#endif+ } else {+ while (count-- > 0) {+ unsigned char ch = *mem++;+ *buf++ = hexchars[ch >> 4];+ *buf++ = hexchars[ch & 0xf];+ }+ }+ kgdb_may_fault = 0;+ *buf = 0;+ return (buf);+}++/*+ * Copy the binary array pointed to by buf into mem. Fix $, #, and+ * 0x7d escaped with 0x7d. Return a pointer to the character after+ * the last byte written.+ */+static char *kgdb_ebin2mem(char *buf, char *mem, int count)+{+ kgdb_may_fault = 1;+ if ((kgdb_fault_setjmp(kgdb_fault_jmp_regs)) != 0) {+ kgdb_may_fault = 0;+ return ERR_PTR(-EINVAL);+ }+ for (; count > 0; count--, buf++) {+ if (*buf == 0x7d)+ *mem++ = *(++buf) ^ 0x20;+ else+ *mem++ = *buf;+ }+ kgdb_may_fault = 0;+ return mem;+}++/*+ * convert the hex array pointed to by buf into binary to be placed in mem+ * return a pointer to the character AFTER the last byte written+ * May return an error.+ */+char *kgdb_hex2mem(char *buf, char *mem, int count)+{+ kgdb_may_fault = 1;+ if ((kgdb_fault_setjmp(kgdb_fault_jmp_regs)) != 0) {+ kgdb_may_fault = 0;+ return ERR_PTR(-EINVAL);+ }+ if ((count == 2) && (((long)mem & 1) == 0)) {+ unsigned short tmp_s = 0;+#ifdef __BIG_ENDIAN+ tmp_s |= hex(*buf++) << 12;+ tmp_s |= hex(*buf++) << 8;+ tmp_s |= hex(*buf++) << 4;+ tmp_s |= hex(*buf++);+#else+ tmp_s |= hex(*buf++) << 4;+ tmp_s |= hex(*buf++);+ tmp_s |= hex(*buf++) << 12;+ tmp_s |= hex(*buf++) << 8;+#endif+ *(unsigned short *)mem = tmp_s;+ mem += 2;+ } else if ((count == 4) && (((long)mem & 3) == 0)) {+ unsigned long tmp_l = 0;+#ifdef __BIG_ENDIAN+ tmp_l |= hex(*buf++) << 28;+ tmp_l |= hex(*buf++) << 24;+ tmp_l |= hex(*buf++) << 20;+ tmp_l |= hex(*buf++) << 16;+ tmp_l |= hex(*buf++) << 12;+ tmp_l |= hex(*buf++) << 8;+ tmp_l |= hex(*buf++) << 4;+ tmp_l |= hex(*buf++);+#else+ tmp_l |= hex(*buf++) << 4;+ tmp_l |= hex(*buf++);+ tmp_l |= hex(*buf++) << 12;+ tmp_l |= hex(*buf++) << 8;+ tmp_l |= hex(*buf++) << 20;+ tmp_l |= hex(*buf++) << 16;+ tmp_l |= hex(*buf++) << 28;+ tmp_l |= hex(*buf++) << 24;+#endif+ *(unsigned long *)mem = tmp_l;+ mem += 4;+ } else {+ int i;+ for (i = 0; i < count; i++) {+ unsigned char ch = hex(*buf++) << 4;+ ch |= hex(*buf++);+ *mem++ = ch;+ }+ }+ kgdb_may_fault = 0;+ return (mem);+}++/*+ * While we find nice hex chars, build a long_val.+ * Return number of chars processed.+ */+int kgdb_hex2long(char **ptr, long *long_val)+{+ int hex_val, num = 0;++ *long_val = 0;++ while (**ptr) {+ hex_val = hex(**ptr);+ if (hex_val >= 0) {+ *long_val = (*long_val << 4) | hex_val;+ num++;+ } else+ break;++ (*ptr)++;+ }++ return (num);+}++/* Write memory due to an 'M' or 'X' packet. */+static char *write_mem_msg(int binary)+{+ char *ptr = &remcom_in_buffer[1];+ unsigned long addr, length;++ if (kgdb_hex2long(&ptr, &addr) > 0 && *(ptr++) == ',' &&+ kgdb_hex2long(&ptr, &length) > 0 && *(ptr++) == ':') {+ if (binary)+ ptr = kgdb_ebin2mem(ptr, (char *)addr, length);+ else+ ptr = kgdb_hex2mem(ptr, (char *)addr, length);+ if (CACHE_FLUSH_IS_SAFE)+ flush_icache_range(addr, addr + length + 1);+ if (IS_ERR(ptr))+ return ptr;+ return NULL;+ }++ return ERR_PTR(-EINVAL);+}++static inline char *pack_hex_byte(char *pkt, int byte)+{+ *pkt++ = hexchars[(byte >> 4) & 0xf];+ *pkt++ = hexchars[(byte & 0xf)];+ return pkt;+}++static inline void error_packet(char *pkt, int error)+{+ error = -error;+ pkt[0] = 'E';+ pkt[1] = hexchars[(error / 10)];+ pkt[2] = hexchars[(error % 10)];+ pkt[3] = '\0';+}++static char *pack_threadid(char *pkt, threadref * id)+{+ char *limit;+ unsigned char *altid;++ altid = (unsigned char *)id;+ limit = pkt + BUF_THREAD_ID_SIZE;+ while (pkt < limit)+ pkt = pack_hex_byte(pkt, *altid++);++ return pkt;+}++void int_to_threadref(threadref * id, int value)+{+ unsigned char *scan;+ int i = 4;++ scan = (unsigned char *)id;+ while (i--)+ *scan++ = 0;+ *scan++ = (value >> 24) & 0xff;+ *scan++ = (value >> 16) & 0xff;+ *scan++ = (value >> 8) & 0xff;+ *scan++ = (value & 0xff);+}++static struct task_struct *getthread(struct pt_regs *regs, int tid)+{+ if (!pidhash_init_done)+ return current;++ if (num_online_cpus() &&+ (tid >= pid_max + num_online_cpus() + kgdb_ops->shadowth))+ return NULL;++ if (kgdb_ops->shadowth && (tid >= pid_max + num_online_cpus()))+ return kgdb_get_shadow_thread(regs, tid - pid_max -+ num_online_cpus());++ if (tid >= pid_max)+ return idle_task(tid - pid_max);++ if (!tid)+ return NULL;++ return find_task_by_pid(tid);+}++#ifdef CONFIG_SMP+static void kgdb_wait(struct pt_regs *regs)+{+ unsigned long flags;+ int processor;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -