예제 #1
0
파일: hwthread.c 프로젝트: artynet/OpenOCD
static int hwthread_thread_packet(struct connection *connection, const char *packet, int packet_size)
{
	struct target *target = get_target_from_connection(connection);

	struct target *curr = NULL;
	int64_t current_threadid;

	if (packet[0] == 'H' && packet[1] == 'g') {
		sscanf(packet, "Hg%16" SCNx64, &current_threadid);

		if (current_threadid > 0) {
			if (hwthread_target_for_threadid(connection, current_threadid, &curr) != ERROR_OK) {
				LOG_ERROR("hwthread: cannot find thread id %"PRId64, current_threadid);
				gdb_put_packet(connection, "E01", 3);
				return ERROR_FAIL;
			}
			target->rtos->current_thread = current_threadid;
		} else
		if (current_threadid == 0 || current_threadid == -1)
			target->rtos->current_thread = threadid_from_target(target);

		target->rtos->current_threadid = current_threadid;

		gdb_put_packet(connection, "OK", 2);
		return ERROR_OK;
	}

	return rtos_thread_packet(connection, packet, packet_size);
}
예제 #2
0
파일: linux.c 프로젝트: Bot007/openOCD
int linux_gdb_T_packet(struct connection *connection,
                       struct target *target, char *packet, int packet_size)
{
    int64_t threadid;
    struct linux_os *linux_os = (struct linux_os *)
                                target->rtos->rtos_specific_params;
    int retval = ERROR_OK;
    sscanf(packet, "T%" SCNx64, &threadid);

    if (linux_os->threads_needs_update == 0) {
        struct threads *temp = linux_os->thread_list;
        struct threads *prev = linux_os->thread_list;

        while (temp != NULL) {
            if (temp->threadid == threadid) {
                if (temp->status != 0) {
                    gdb_put_packet(connection, "OK", 2);
                    return ERROR_OK;
                } else {
                    /* delete item in the list   */
                    linux_os->thread_list =
                        liste_del_task(linux_os->
                                       thread_list, &temp,
                                       prev);
                    linux_os->thread_count--;
                    gdb_put_packet(connection, "E01", 3);
                    return ERROR_OK;
                }
            }

            /*  for deletion  */
            prev = temp;
            temp = temp->next;
        }

        LOG_INFO("gdb requested status on non existing thread");
        gdb_put_packet(connection, "E01", 3);
        return ERROR_OK;

    } else {
        retval = linux_task_update(target, 1);
        struct threads *temp = linux_os->thread_list;

        while (temp != NULL) {
            if (temp->threadid == threadid) {
                if (temp->status == 1) {
                    gdb_put_packet(connection, "OK", 2);
                    return ERROR_OK;
                } else {
                    gdb_put_packet(connection, "E01", 3);
                    return ERROR_OK;
                }
            }

            temp = temp->next;
        }
    }

    return retval;
}
예제 #3
0
int rtos_get_gdb_reg_list(struct connection *connection)
{
	struct target *target = get_target_from_connection(connection);
	int64_t current_threadid = target->rtos->current_threadid;
	if ((target->rtos != NULL) && (current_threadid != -1) &&
			(current_threadid != 0) &&
			((current_threadid != target->rtos->current_thread) ||
			(target->smp))) {	/* in smp several current thread are possible */
		char *hex_reg_list;

		LOG_DEBUG("RTOS: getting register list for thread 0x%" PRIx64
				  ", target->rtos->current_thread=0x%" PRIx64 "\r\n",
										current_threadid,
										target->rtos->current_thread);

		target->rtos->type->get_thread_reg_list(target->rtos,
			current_threadid,
			&hex_reg_list);

		if (hex_reg_list != NULL) {
			gdb_put_packet(connection, hex_reg_list, strlen(hex_reg_list));
			free(hex_reg_list);
			return ERROR_OK;
		}
	}
	return ERROR_FAIL;
}
예제 #4
0
파일: smp.c 프로젝트: Xplorer001/openocd
/* packet j :smp status request */
int gdb_read_smp_packet(struct connection *connection,
		char *packet, int packet_size)
{
	struct target *target = get_target_from_connection(connection);
	uint32_t len = sizeof(int32_t);
	uint8_t *buffer;
	char *hex_buffer;
	int retval = ERROR_OK;
	if (target->smp)
	{
		if (strstr(packet, "jc"))
		{
			hex_buffer = malloc(len * 2 + 1);
			buffer = (uint8_t *)&target->gdb_service->core[0];
			uint32_t i;
			for (i = 0; i < 4; i++)
			{
				uint8_t t = buffer[i];
				hex_buffer[2 * i] = DIGITS[(t >> 4) & 0xf];
				hex_buffer[2 * i + 1] = DIGITS[t & 0xf];
			}

			retval = gdb_put_packet(connection, hex_buffer, len * 2);

			free(hex_buffer);
		}
	}
예제 #5
0
파일: linux.c 프로젝트: Bot007/openOCD
int linux_gdb_thread_update(struct target *target,
                            struct connection *connection, char *packet,
                            int packet_size)
{
    int found = 0;
    struct linux_os *linux_os = (struct linux_os *)
                                target->rtos->rtos_specific_params;
    struct threads *temp = linux_os->thread_list;

    while (temp != NULL) {
        if (temp->threadid == linux_os->preupdtate_threadid_count + 1) {
            /*LOG_INFO("FOUND");*/
            found = 1;
            break;
        } else
            temp = temp->next;
    }

    if (found == 1) {
        /*LOG_INFO("INTO GDB THREAD UPDATE FOUNDING START TASK");*/
        char *out_strr = (char *)calloc(1, 350 * sizeof(int64_t));
        char *tmp_strr = out_strr;
        tmp_strr += sprintf(tmp_strr, "m");
        /*LOG_INFO("CHAR MALLOC & M DONE");*/
        tmp_strr += sprintf(tmp_strr, "%016" PRIx64, temp->threadid);

        temp = temp->next;

        while (temp != NULL) {
            /*LOG_INFO("INTO GDB THREAD UPDATE WHILE");*/
            tmp_strr += sprintf(tmp_strr, ",");
            tmp_strr +=
                sprintf(tmp_strr, "%016" PRIx64, temp->threadid);
            temp = temp->next;
        }

        /*tmp_str[0] = 0;*/
        gdb_put_packet(connection, out_strr, strlen(out_strr));
        linux_os->preupdtate_threadid_count =
            linux_os->threadid_count - 1;
        free(out_strr);
    } else
        gdb_put_packet(connection, "l", 1);

    return ERROR_OK;
}
예제 #6
0
파일: smp.c 프로젝트: EmuxEvans/openocd
/* packet j :smp status request */
int gdb_read_smp_packet(struct connection *connection,
		char const *packet, int packet_size)
{
	struct target *target = get_target_from_connection(connection);
	int retval = ERROR_OK;
	if (target->smp) {
		if (strncmp(packet, "jc", 2) == 0) {
			const uint32_t len = sizeof(target->gdb_service->core[0]);
			char hex_buffer[len * 2 + 1];
			char buffer[len];
			buf_set_u32(buffer, 0, len * 8, target->gdb_service->core[0]);
			int pkt_len = hexify(hex_buffer, buffer, sizeof(buffer), sizeof(hex_buffer));

			retval = gdb_put_packet(connection, hex_buffer, pkt_len);
		}
	} else
		retval = gdb_put_packet(connection, "E01", 3);
	return retval;
}
예제 #7
0
파일: smp.c 프로젝트: EmuxEvans/openocd
/* J :  smp set request */
int gdb_write_smp_packet(struct connection *connection,
		char const *packet, int packet_size)
{
	struct target *target = get_target_from_connection(connection);
	char *separator;
	int coreid = 0;
	int retval = ERROR_OK;

	/* skip command character */
	if (target->smp) {
		if (strncmp(packet, "Jc", 2) == 0) {
			packet += 2;
			coreid = strtoul(packet, &separator, 16);
			target->gdb_service->core[1] = coreid;
			retval = gdb_put_packet(connection, "OK", 2);
		}
	} else
		retval = gdb_put_packet(connection, "E01", 3);

	return retval;
}
예제 #8
0
/* packet j :smp status request */
int gdb_read_smp_packet(struct connection *connection,
		char *packet, int packet_size)
{
	struct target *target = get_target_from_connection(connection);
	uint32_t len = sizeof(int32_t);
	uint8_t *buffer;
	char *hex_buffer;
	int retval = ERROR_OK;
	if (target->smp) {
		if (strncmp(packet, "jc", 2) == 0) {
			hex_buffer = malloc(len * 2 + 1);
			buffer = (uint8_t *)&target->gdb_service->core[0];
			int pkt_len = hexify(hex_buffer, (char *)buffer, len, len * 2 + 1);

			retval = gdb_put_packet(connection, hex_buffer, pkt_len);
			free(hex_buffer);
		}
	} else
		retval = gdb_put_packet(connection, "E01", 3);
	return retval;
}
예제 #9
0
파일: linux.c 프로젝트: Bot007/openOCD
int linux_thread_extra_info(struct target *target,
                            struct connection *connection, char *packet,
                            int packet_size)
{
    int64_t threadid = 0;
    struct linux_os *linux_os = (struct linux_os *)
                                target->rtos->rtos_specific_params;
    sscanf(packet, "qThreadExtraInfo,%" SCNx64, &threadid);
    /*LOG_INFO("lookup extra info for thread %" SCNx64, threadid);*/
    struct threads *temp = linux_os->thread_list;

    while (temp != NULL) {
        if (temp->threadid == threadid) {
            char *pid = " PID: ";
            char *pid_current = "*PID: ";
            char *name = "NAME: ";
            int str_size = strlen(pid) + strlen(name);
            char *tmp_str = (char *)calloc(1, str_size + 50);
            char *tmp_str_ptr = tmp_str;

            /*  discriminate cuurent task */
            if (temp->status == 3)
                tmp_str_ptr += sprintf(tmp_str_ptr, "%s",
                                       pid_current);
            else
                tmp_str_ptr += sprintf(tmp_str_ptr, "%s", pid);

            tmp_str_ptr +=
                sprintf(tmp_str_ptr, "%d", (int)temp->pid);
            tmp_str_ptr += sprintf(tmp_str_ptr, "%s", " | ");
            sprintf(tmp_str_ptr, "%s", name);
            sprintf(tmp_str_ptr, "%s", temp->name);
            char *hex_str =
                (char *)calloc(1, strlen(tmp_str) * 2 + 1);
            str_to_hex(hex_str, tmp_str);
            gdb_put_packet(connection, hex_str, strlen(hex_str));
            free(hex_str);
            free(tmp_str);
            return ERROR_OK;
        }

        temp = temp->next;
    }

    LOG_INFO("thread not found");
    return ERROR_OK;
}
예제 #10
0
파일: rtos.c 프로젝트: Xplorer001/openocd
int rtos_get_gdb_reg_list(struct connection *connection, struct reg **reg_list[], int *reg_list_size)
{
	struct target *target = get_target_from_connection(connection);

	if ( ( target->rtos != NULL ) &&
		 ( current_threadid != -1 ) &&
		 ( current_threadid != 0 ) &&
		 ( current_threadid != target->rtos->current_thread ) )
	{
		char * hex_reg_list;
		target->rtos->type->get_thread_reg_list( target->rtos, current_threadid, &hex_reg_list );

		if ( hex_reg_list != NULL )
		{
			gdb_put_packet(connection, hex_reg_list, strlen(hex_reg_list));
			free(hex_reg_list);
			return ERROR_OK;
		}
	}
	return ERROR_FAIL;
}
예제 #11
0
int rtos_thread_packet(struct connection *connection, char const *packet, int packet_size)
{
	struct target *target = get_target_from_connection(connection);

	if (strncmp(packet, "qThreadExtraInfo,", 17) == 0) {
		if ((target->rtos != NULL) && (target->rtos->thread_details != NULL) &&
				(target->rtos->thread_count != 0)) {
			threadid_t threadid = 0;
			int found = -1;
			sscanf(packet, "qThreadExtraInfo,%" SCNx64, &threadid);

			if ((target->rtos != NULL) && (target->rtos->thread_details != NULL)) {
				int thread_num;
				for (thread_num = 0; thread_num < target->rtos->thread_count; thread_num++) {
					if (target->rtos->thread_details[thread_num].threadid == threadid) {
						if (target->rtos->thread_details[thread_num].exists)
							found = thread_num;
					}
				}
			}
			if (found == -1) {
				gdb_put_packet(connection, "E01", 3);	/* thread not found */
				return ERROR_OK;
			}

			struct thread_detail *detail = &target->rtos->thread_details[found];

			int str_size = 0;
			if (detail->display_str != NULL)
				str_size += strlen(detail->display_str);
			if (detail->thread_name_str != NULL)
				str_size += strlen(detail->thread_name_str);
			if (detail->extra_info_str != NULL)
				str_size += strlen(detail->extra_info_str);

			char *tmp_str = calloc(str_size + 7, sizeof(char));
			char *tmp_str_ptr = tmp_str;

			if (detail->display_str != NULL)
				tmp_str_ptr += sprintf(tmp_str_ptr, "%s", detail->display_str);
			if (detail->thread_name_str != NULL) {
				if (tmp_str_ptr != tmp_str)
					tmp_str_ptr += sprintf(tmp_str_ptr, " : ");
				tmp_str_ptr += sprintf(tmp_str_ptr, "%s", detail->thread_name_str);
			}
			if (detail->extra_info_str != NULL) {
				if (tmp_str_ptr != tmp_str)
					tmp_str_ptr += sprintf(tmp_str_ptr, " : ");
				tmp_str_ptr +=
					sprintf(tmp_str_ptr, " : %s", detail->extra_info_str);
			}

			assert(strlen(tmp_str) ==
				(size_t) (tmp_str_ptr - tmp_str));

			char *hex_str = malloc(strlen(tmp_str) * 2 + 1);
			int pkt_len = hexify(hex_str, tmp_str, 0, strlen(tmp_str) * 2 + 1);

			gdb_put_packet(connection, hex_str, pkt_len);
			free(hex_str);
			free(tmp_str);
			return ERROR_OK;

		}
		gdb_put_packet(connection, "", 0);
		return ERROR_OK;
	} else if (strncmp(packet, "qSymbol", 7) == 0) {
		if (rtos_qsymbol(connection, packet, packet_size) == 1) {
			target->rtos_auto_detect = false;
			target->rtos->type->create(target);
			target->rtos->type->update_threads(target->rtos);
		}
		return ERROR_OK;
	} else if (strncmp(packet, "qfThreadInfo", 12) == 0) {
		int i;
		if (target->rtos != NULL) {
			if (target->rtos->thread_count == 0) {
				gdb_put_packet(connection, "l", 1);
			} else {
				/*thread id are 16 char +1 for ',' */
				char *out_str = malloc(17 * target->rtos->thread_count + 1);
				char *tmp_str = out_str;
				for (i = 0; i < target->rtos->thread_count; i++) {
					tmp_str += sprintf(tmp_str, "%c%016" PRIx64, i == 0 ? 'm' : ',',
										target->rtos->thread_details[i].threadid);
				}
				gdb_put_packet(connection, out_str, strlen(out_str));
				free(out_str);
			}
		} else
			gdb_put_packet(connection, "l", 1);

		return ERROR_OK;
	} else if (strncmp(packet, "qsThreadInfo", 12) == 0) {
		gdb_put_packet(connection, "l", 1);
		return ERROR_OK;
	} else if (strncmp(packet, "qAttached", 9) == 0) {
		gdb_put_packet(connection, "1", 1);
		return ERROR_OK;
	} else if (strncmp(packet, "qOffsets", 8) == 0) {
		char offsets[] = "Text=0;Data=0;Bss=0";
		gdb_put_packet(connection, offsets, sizeof(offsets)-1);
		return ERROR_OK;
	} else if (strncmp(packet, "qCRC:", 5) == 0) {
		/* make sure we check this before "qC" packet below
		 * otherwise it gets incorrectly handled */
		return GDB_THREAD_PACKET_NOT_CONSUMED;
	} else if (strncmp(packet, "qC", 2) == 0) {
		if (target->rtos != NULL) {
			char buffer[19];
			int size;
			size = snprintf(buffer, 19, "QC%016" PRIx64, target->rtos->current_thread);
			gdb_put_packet(connection, buffer, size);
		} else
			gdb_put_packet(connection, "QC0", 3);
		return ERROR_OK;
	} else if (packet[0] == 'T') {	/* Is thread alive? */
		threadid_t threadid;
		int found = -1;
		sscanf(packet, "T%" SCNx64, &threadid);
		if ((target->rtos != NULL) && (target->rtos->thread_details != NULL)) {
			int thread_num;
			for (thread_num = 0; thread_num < target->rtos->thread_count; thread_num++) {
				if (target->rtos->thread_details[thread_num].threadid == threadid) {
					if (target->rtos->thread_details[thread_num].exists)
						found = thread_num;
				}
			}
		}
		if (found != -1)
			gdb_put_packet(connection, "OK", 2);	/* thread alive */
		else
			gdb_put_packet(connection, "E01", 3);	/* thread not found */
		return ERROR_OK;
	} else if (packet[0] == 'H') {	/* Set current thread ( 'c' for step and continue, 'g' for
					 * all other operations ) */
		if ((packet[1] == 'g') && (target->rtos != NULL)) {
			sscanf(packet, "Hg%16" SCNx64, &target->rtos->current_threadid);
			LOG_DEBUG("RTOS: GDB requested to set current thread to 0x%" PRIx64 "\r\n",
										target->rtos->current_threadid);
		}
		gdb_put_packet(connection, "OK", 2);
		return ERROR_OK;
	}

	return GDB_THREAD_PACKET_NOT_CONSUMED;
}
예제 #12
0
/* rtos_qsymbol() processes and replies to all qSymbol packets from GDB.
 *
 * GDB sends a qSymbol:: packet (empty address, empty name) to notify
 * that it can now answer qSymbol::hexcodedname queries, to look up symbols.
 *
 * If the qSymbol packet has no address that means GDB did not find the
 * symbol, in which case auto-detect will move on to try the next RTOS.
 *
 * rtos_qsymbol() then calls the next_symbol() helper function, which
 * iterates over symbol names for the current RTOS until it finds the
 * symbol in the received GDB packet, and then returns the next entry
 * in the list of symbols.
 *
 * If GDB replied about the last symbol for the RTOS and the RTOS was
 * specified explicitly, then no further symbol lookup is done. When
 * auto-detecting, the RTOS driver _detect() function must return success.
 *
 * rtos_qsymbol() returns 1 if an RTOS has been detected, or 0 otherwise.
 */
int rtos_qsymbol(struct connection *connection, char const *packet, int packet_size)
{
	int rtos_detected = 0;
	uint64_t addr = 0;
	size_t reply_len;
	char reply[GDB_BUFFER_SIZE], cur_sym[GDB_BUFFER_SIZE / 2] = "";
	symbol_table_elem_t *next_sym = NULL;
	struct target *target = get_target_from_connection(connection);
	struct rtos *os = target->rtos;

	reply_len = sprintf(reply, "OK");

	if (!os)
		goto done;

	/* Decode any symbol name in the packet*/
	int len = unhexify(cur_sym, strchr(packet + 8, ':') + 1, strlen(strchr(packet + 8, ':') + 1));
	cur_sym[len] = 0;

	if ((strcmp(packet, "qSymbol::") != 0) &&               /* GDB is not offering symbol lookup for the first time */
	    (!sscanf(packet, "qSymbol:%" SCNx64 ":", &addr)) && /* GDB did not find an address for a symbol */
	    is_symbol_mandatory(os, cur_sym)) {					/* the symbol is mandatory for this RTOS */

		/* GDB could not find an address for the previous symbol */
		if (!target->rtos_auto_detect) {
			LOG_WARNING("RTOS %s not detected. (GDB could not find symbol \'%s\')", os->type->name, cur_sym);
			goto done;
		} else {
			/* Autodetecting RTOS - try next RTOS */
			if (!rtos_try_next(target)) {
				LOG_WARNING("No RTOS could be auto-detected!");
				goto done;
			}

			/* Next RTOS selected - invalidate current symbol */
			cur_sym[0] = '\x00';
		}
	}
	next_sym = next_symbol(os, cur_sym, addr);

	if (!next_sym->symbol_name) {
		/* No more symbols need looking up */

		if (!target->rtos_auto_detect) {
			rtos_detected = 1;
			goto done;
		}

		if (os->type->detect_rtos(target)) {
			LOG_INFO("Auto-detected RTOS: %s", os->type->name);
			rtos_detected = 1;
			goto done;
		} else {
			LOG_WARNING("No RTOS could be auto-detected!");
			goto done;
		}
	}

	if (8 + (strlen(next_sym->symbol_name) * 2) + 1 > sizeof(reply)) {
		LOG_ERROR("ERROR: RTOS symbol '%s' name is too long for GDB!", next_sym->symbol_name);
		goto done;
	}

	reply_len = snprintf(reply, sizeof(reply), "qSymbol:");
	reply_len += hexify(reply + reply_len, next_sym->symbol_name, 0, sizeof(reply) - reply_len);

done:
	gdb_put_packet(connection, reply, reply_len);
	return rtos_detected;
}
예제 #13
0
파일: linux.c 프로젝트: Bot007/openOCD
static int linux_task_update(struct target *target, int context)
{
    struct linux_os *linux_os = (struct linux_os *)
                                target->rtos->rtos_specific_params;
    struct threads *thread_list = linux_os->thread_list;
    int retval;
    int loop = 0;
    linux_os->thread_count = 0;

    /*thread_list = thread_list->next; skip init_task*/
    while (thread_list != NULL) {
        thread_list->status = 0;	/*setting all tasks to dead state*/

        if (thread_list->context) {
            free(thread_list->context);
            thread_list->context = NULL;
        }

        thread_list = thread_list->next;
    }

    int found = 0;

    if (linux_os->init_task_addr == 0xdeadbeef) {
        LOG_INFO("no init symbol\n");
        return ERROR_FAIL;
    }
    int64_t start = timeval_ms();
    struct threads *t = calloc(1, sizeof(struct threads));
    uint32_t previous = 0xdeadbeef;
    t->base_addr = linux_os->init_task_addr;
    retval = get_current(target, 0);
    /*check that all current threads have been identified  */
    linux_identify_current_threads(target);

    while (((t->base_addr != linux_os->init_task_addr) &&
            (t->base_addr != previous)) || (loop == 0)) {
        /*  for avoiding any permanent loop for any reason possibly due to
         *  target */
        loop++;
        previous = t->base_addr;
        /*  read only pid */
#ifdef PID_CHECK
        retval = fill_task_pid(target, t);
#endif

        if (retval != ERROR_OK) {
            free(t);
            return ERROR_FAIL;
        }

        thread_list = linux_os->thread_list;

        while (thread_list != NULL) {
#ifdef PID_CHECK
            if (t->pid == thread_list->pid) {
#else
            if (t->base_addr == thread_list->base_addr) {
#endif
                if (!thread_list->status) {
#ifdef PID_CHECK
                    if (t->base_addr != thread_list->base_addr)
                        LOG_INFO("thread base_addr has changed !!");
#endif
                    /*  this is not a current thread  */
                    thread_list->base_addr = t->base_addr;
                    thread_list->status = 1;

                    /*  we don 't update this field any more */

                    /*thread_list->state = t->state;
                    thread_list->oncpu = t->oncpu;
                    thread_list->asid = t->asid;
                    */
                    if (context)
                        thread_list->context =
                            cpu_context_read(target,
                                             thread_list->
                                             base_addr,
                                             &thread_list->
                                             thread_info_addr);
                } else {
                    /*  it is a current thread no need to read context */
                }

                linux_os->thread_count++;
                found = 1;
                break;
            } else {
                found = 0;
                thread_list = thread_list->next;
            }
        }

        if (found == 0) {
            uint32_t base_addr;
            fill_task(target, t);
            get_name(target, t);
            retval = insert_into_threadlist(target, t);
            t->thread_info_addr = 0xdeadbeef;

            if (context)
                t->context =
                    cpu_context_read(target, t->base_addr,
                                     &t->thread_info_addr);

            base_addr = next_task(target, t);
            t = calloc(1, sizeof(struct threads));
            t->base_addr = base_addr;
            linux_os->thread_count++;
        } else
            t->base_addr = next_task(target, t);
    }

    LOG_INFO("update thread done %" PRId64 ", mean%" PRId64 "\n",
             (timeval_ms() - start), (timeval_ms() - start) / loop);
    free(t);
    linux_os->threads_needs_update = 0;
    return ERROR_OK;
}

int linux_gdb_thread_packet(struct target *target,
                            struct connection *connection, char *packet,
                            int packet_size)
{
    int retval;
    struct linux_os *linux_os =
        (struct linux_os *)target->rtos->rtos_specific_params;

    if (linux_os->init_task_addr == 0xdeadbeef) {
        /* it has not been initialized */
        LOG_INFO("received thread request without init task address");
        gdb_put_packet(connection, "l", 1);
        return ERROR_OK;
    }

    retval = linux_get_tasks(target, 1);

    if (retval != ERROR_OK)
        return ERROR_TARGET_FAILURE;

    char *out_str = (char *)calloc(1, 350 * sizeof(int64_t));
    char *tmp_str = out_str;
    tmp_str += sprintf(tmp_str, "m");
    struct threads *temp = linux_os->thread_list;
    tmp_str += sprintf(tmp_str, "%016" PRIx64, temp->threadid);
    temp = temp->next;

    while (temp != NULL) {
        tmp_str += sprintf(tmp_str, ",");
        tmp_str += sprintf(tmp_str, "%016" PRIx64, temp->threadid);
        temp = temp->next;
    }

    gdb_put_packet(connection, out_str, strlen(out_str));
    return ERROR_OK;
}
예제 #14
0
파일: linux.c 프로젝트: Bot007/openOCD
static int linux_thread_packet(struct connection *connection, char *packet,
                               int packet_size)
{
    int retval = ERROR_OK;
    struct current_thread *ct;
    struct target *target = get_target_from_connection(connection);
    struct linux_os *linux_os = (struct linux_os *)
                                target->rtos->rtos_specific_params;

    switch (packet[0]) {
    case 'T':		/* Is thread alive?*/

        linux_gdb_T_packet(connection, target, packet, packet_size);
        break;
    case 'H':		/* Set current thread */
        /*  ( 'c' for step and continue, 'g' for all other operations )*/
        /*LOG_INFO(" H packet received '%s'", packet);*/
        linux_gdb_h_packet(connection, target, packet, packet_size);
        break;
    case 'q':

        if (strncmp(packet, "qSymbol", 7) == 0) {
            if (rtos_qsymbol(connection, packet, packet_size) == 1) {
                linux_compute_virt2phys(target,
                                        target->rtos->
                                        symbols[INIT_TASK].
                                        address);
            }

            break;
        } else if (strncmp(packet, "qfThreadInfo", 12) == 0) {
            if (linux_os->thread_list == NULL) {
                retval = linux_gdb_thread_packet(target,
                                                 connection,
                                                 packet,
                                                 packet_size);
                break;
            } else {
                retval = linux_gdb_thread_update(target,
                                                 connection,
                                                 packet,
                                                 packet_size);
                break;
            }
        } else if (strncmp(packet, "qsThreadInfo", 12) == 0) {
            gdb_put_packet(connection, "l", 1);
            break;
        } else if (strncmp(packet, "qThreadExtraInfo,", 17) == 0) {
            linux_thread_extra_info(target, connection, packet,
                                    packet_size);
            break;
        } else {
            retval = GDB_THREAD_PACKET_NOT_CONSUMED;
            break;
        }

    case 'Q':
        /* previously response was : thread not found
         * gdb_put_packet(connection, "E01", 3); */
        retval = GDB_THREAD_PACKET_NOT_CONSUMED;
        break;
    case 'c':
    case 's': {
        if (linux_os->threads_lookup == 1) {
            ct = linux_os->current_threads;

            while ((ct != NULL) && (ct->core_id) != target->coreid)
                ct = ct->next;

            if ((ct != NULL) && (ct->threadid == -1)) {
                ct = linux_os->current_threads;

                while ((ct != NULL) && (ct->threadid == -1))
                    ct = ct->next;
            }

            if ((ct != NULL) && (ct->threadid !=
                                 target->rtos->
                                 current_threadid)
                    && (target->rtos->current_threadid != -1))
                LOG_WARNING("WARNING! current GDB thread do not match" \
                            "current thread running." \
                            "Switch thread in GDB to threadid %d",
                            (int)ct->threadid);

            LOG_INFO("threads_needs_update = 1");
            linux_os->threads_needs_update = 1;
        }
    }

        /* if a packet handler returned an error, exit input loop */
    if (retval != ERROR_OK)
        return retval;
    }

    return retval;
}
예제 #15
0
파일: linux.c 프로젝트: Bot007/openOCD
int linux_gdb_h_packet(struct connection *connection,
                       struct target *target, char *packet, int packet_size)
{
    struct linux_os *linux_os = (struct linux_os *)
                                target->rtos->rtos_specific_params;
    struct current_thread *ct = linux_os->current_threads;

    /* select to display the current thread of the selected target */
    while ((ct != NULL) && (ct->core_id != target->coreid))
        ct = ct->next;

    int64_t current_gdb_thread_rq;

    if (linux_os->threads_lookup == 1) {
        if ((ct != NULL) && (ct->threadid == -1)) {
            ct = linux_os->current_threads;

            while ((ct != NULL) && (ct->threadid == -1))
                ct = ct->next;
        }

        if (ct == NULL) {
            /*  no current thread can be identified
             *  any way with smp  */
            LOG_INFO("no current thread identified");
            /* attempt to display the name of the 2 threads identified with
             * get_current */
            struct threads t;
            ct = linux_os->current_threads;

            while ((ct != NULL) && (ct->threadid == -1)) {
                t.base_addr = ct->TS;
                get_name(target, &t);
                LOG_INFO("name of unidentified thread %s",
                         t.name);
                ct = ct->next;
            }

            gdb_put_packet(connection, "OK", 2);
            return ERROR_OK;
        }

        if (packet[1] == 'g') {
            sscanf(packet, "Hg%16" SCNx64, &current_gdb_thread_rq);

            if (current_gdb_thread_rq == 0) {
                target->rtos->current_threadid = ct->threadid;
                gdb_put_packet(connection, "OK", 2);
            } else {
                target->rtos->current_threadid =
                    current_gdb_thread_rq;
                gdb_put_packet(connection, "OK", 2);
            }
        } else if (packet[1] == 'c') {
            sscanf(packet, "Hc%16" SCNx64, &current_gdb_thread_rq);

            if ((current_gdb_thread_rq == 0) ||
                    (current_gdb_thread_rq == ct->threadid)) {
                target->rtos->current_threadid = ct->threadid;
                gdb_put_packet(connection, "OK", 2);
            } else
                gdb_put_packet(connection, "E01", 3);
        }
    } else
        gdb_put_packet(connection, "OK", 2);

    return ERROR_OK;
}
예제 #16
0
/*
 * This function does all command procesing for interfacing to gdb.
 */
void gdb_stub_handler(int exception_vector)
{
  int    sigval;
  int    addr, length;
  char * ptr;

#ifdef GDB_REMOTE_UDP
  gdb_udp_poll_start();
#endif /* GDB_REMOTE_UDP */
  
  if(remote_debug) 
	  GDB_PRINTF("vector=%d, ps=0x%x, pc=0x%x\n", exception_vector, gdb_registers[PS], gdb_registers[PC]);

  /* reply to host that an exception has occurred */
  sigval = compute_signal(exception_vector);
  remcomOutBuffer[0] = 'S';
  remcomOutBuffer[1] =  hexchars[sigval >> 4];
  remcomOutBuffer[2] =  hexchars[sigval % 16];
  remcomOutBuffer[3] = 0;

  if(remote_debug)
	  GDB_PRINTF("GDB send packet: %s\n", remcomOutBuffer);
  gdb_put_packet(remcomOutBuffer);

  while (1) {
    remcomOutBuffer[0] = 0;
    gdb_get_packet(remcomInBuffer);
	if(remote_debug)
		GDB_PRINTF("GDB reveive packet: %s\n", remcomInBuffer);
    switch (remcomInBuffer[0]) {
      case '?' :   remcomOutBuffer[0] = 'S';
                   remcomOutBuffer[1] =  hexchars[sigval >> 4];
                   remcomOutBuffer[2] =  hexchars[sigval % 16];
                   remcomOutBuffer[3] = 0;
                 break;
      case 'd' : remote_debug = !(remote_debug);  /* toggle debug flag */
                 break;
      case 'g' : /* return the value of the CPU registers */
                mem2hex((char*) gdb_registers, remcomOutBuffer, NUMREGBYTES, 0);
                break;
      case 'G' : /* set the value of the CPU registers - return OK */
                hex2mem(&remcomInBuffer[1], (char*) gdb_registers, NUMREGBYTES, 0);
                gdb_strcpy(remcomOutBuffer,"OK");
                break;

      /* mAA..AA,LLLL  Read LLLL bytes at address AA..AA */
      case 'm' :
		    /* TRY TO READ %x,%x.  IF SUCCEED, SET PTR = 0 */
				ptr = &remcomInBuffer[1];
				if (hex2int(&ptr,&addr))
					if (*(ptr++) == ',')
						if (hex2int(&ptr,&length))
						{
							ptr = 0;
							mem_err = 0;
                            mem2hex((char*) addr, remcomOutBuffer, length, 1);

							if (mem_err) {
								gdb_strcpy (remcomOutBuffer, "E03");
								if(remote_debug)
									GDB_PRINTF("memory fault");
							}
                        }

				if (ptr)
				{
				  gdb_strcpy(remcomOutBuffer,"E01");
				  if(remote_debug)
					  GDB_PRINTF("malformed read memory command: %s",remcomInBuffer);
				}
	          break;

      /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
      case 'M' :
		    /* TRY TO READ '%x,%x:'.  IF SUCCEED, SET PTR = 0 */
			ptr = &remcomInBuffer[1];
			if (hex2int(&ptr,&addr))
				if (*(ptr++) == ',')
					if (hex2int(&ptr,&length))
						if (*(ptr++) == ':')
						{
							mem_err = 0;
							hex2mem(ptr, (char*) addr, length, 1);

							if (mem_err) {
							gdb_strcpy (remcomOutBuffer, "E03");
							if(remote_debug)
								GDB_PRINTF("memory fault");
							} else {
								gdb_strcpy(remcomOutBuffer,"OK");
							}

							ptr = 0;
						}
            if (ptr)
            {
		      gdb_strcpy(remcomOutBuffer,"E02");
		      if(remote_debug)
				  GDB_PRINTF("malformed write memory command: %s",remcomInBuffer);
		    }
            break;

      /* cAA..AA    Continue at address AA..AA(optional) */
      /* sAA..AA   Step one instruction from AA..AA(optional) */
      case 'c' :
      case 's' :
		/* try to read optional parameter, pc unchanged if no parm */
		ptr = &remcomInBuffer[1];
		if (hex2int(&ptr,&addr))
			gdb_registers[PC] = addr;


		/* set the trace bit if we're stepping */
		if (remcomInBuffer[0] == 's') 
			gdb_registers[PS] |= 0x100;
		else
			gdb_registers[PS] &= 0xfffffeff;

#ifdef GDB_REMOTE_UDP
  		gdb_udp_poll_stop();
#endif /* GDB_REMOTE_UDP */
		return;
//		break;

	  /* kill the program */
	  case 'k' :  /* do nothing */
		break;

	  /* Z<type-1x>,<address-x>,<length-x>    Add breakpoint */
	  case 'Z' :
		if(hex(remcomInBuffer[1]) != 0)
		{
			/* We support only software break points so far */
			break;
		}

		ptr = &remcomInBuffer[2];
		if (*(ptr++) == ',')
			if (hex2int(&ptr,&addr))
			{
				if (*(ptr++) == ',')
				{
					if (hex2int(&ptr,&length))
					{
						if(length != 1)
						{
							gdb_strcpy(remcomOutBuffer,"E02");
							if(remote_debug)
								GDB_PRINTF("Breakpoint address length isn't equal to 1.");
							break;
						}
						ptr = 0;
					}
				}
			}

		if (ptr)
		{
		  gdb_strcpy(remcomOutBuffer,"E01");
		  if(remote_debug)
			  GDB_PRINTF("malformed add breakpoint command: %s",remcomInBuffer);
		}
		else
		{
			struct zbreak *z;

			/* check whether this break point already set */
			z = zbreak_list_find(addr);
			if(z)
			{
				/* Repeated packet */
				gdb_strcpy(remcomOutBuffer,"OK");
				break;
			}
			
			/* get an free zbreak */
			mem_err = 0;
			z = zbreak_new(addr);
			if(z == NULL)
			{
				gdb_strcpy(remcomOutBuffer,"E03");
				if(remote_debug)
				  GDB_PRINTF("new zbreak failed.\n");
				break;
			}
			if (mem_err) {
				gdb_strcpy (remcomOutBuffer, "E03");
				if(remote_debug)
					GDB_PRINTF("memory fault");
				break;
			}
			gdb_strcpy(remcomOutBuffer, "OK");
		}
		break;

	  /* z<type-1x>,<address-x>,<length-x>    Remove breakpoint */
	  /* zz    Remove all breakpoints */
	  case 'z' : 
		if(hex(remcomInBuffer[1]) == 'z')
		{
			/* remove all breakpoints */
			while(valid_zbreak_list.next != &valid_zbreak_list)
			{
				zbreak_free(valid_zbreak_list.next);
			}
			gdb_strcpy(remcomOutBuffer, "OK");
			break;
		}

		if(hex(remcomInBuffer[1]) != 0)
		{
			/* We support only software break points so far */
			break;
		}

		ptr = &remcomInBuffer[2];
		if (*(ptr++) == ',')
			if (hex2int(&ptr,&addr))
			{
				if (*(ptr++) == ',')
				{
					if (hex2int(&ptr,&length))
					{
						if(length != 1)
						{
							gdb_strcpy(remcomOutBuffer,"E02");
							if(remote_debug)
								GDB_PRINTF("Breakpoint address length isn't equal to 1.");
							break;
						}
						ptr = 0;
					}
				}
			}

		if (ptr)
		{
		  gdb_strcpy(remcomOutBuffer,"E01");
		  if(remote_debug)
			  GDB_PRINTF("malformed remove breakpoint command: %s",remcomInBuffer);
		}
		else
		{
			struct zbreak *z;

			z = zbreak_list_find(addr);
			if(z == NULL)
			{
				gdb_strcpy(remcomOutBuffer,"E03");
				if(remote_debug)
				  GDB_PRINTF("Breakpoint no found.\n");
				break;
			}

			/* free zbreak */
			zbreak_free(z);

			gdb_strcpy(remcomOutBuffer,"OK");
		}
		break;
      } /* switch */

    /* reply to the request */
	if(remote_debug)
		GDB_PRINTF("GDB send packet: %s\n", remcomOutBuffer);
    gdb_put_packet(remcomOutBuffer);
    }
}
예제 #17
0
파일: rtos.c 프로젝트: Xplorer001/openocd
int gdb_thread_packet(struct connection *connection, char *packet, int packet_size)
{
	struct target *target = get_target_from_connection(connection);

	if (strstr(packet, "qThreadExtraInfo,"))
	{
		if ((target->rtos != NULL) && (target->rtos->thread_details != NULL) && (target->rtos->thread_count != 0))
		{
			threadid_t threadid = 0;
			int found = -1;
			sscanf(packet, "qThreadExtraInfo,%" SCNx64, &threadid );

			if ((target->rtos != NULL) && (target->rtos->thread_details
					!= NULL)) {
				int thread_num;
				for (thread_num = 0; thread_num
						< target->rtos->thread_count; thread_num++) {
					if (target->rtos->thread_details[thread_num].threadid
							== threadid) {
						if (target->rtos->thread_details[thread_num].exists) {
							found = thread_num;
						}
					}
				}
			}
			if (found == -1) {
				gdb_put_packet(connection, "E01", 3); // thread not found
				return ERROR_OK;
			}

			struct thread_detail* detail = &target->rtos->thread_details[found];

			int str_size = 0;
			if ( detail->display_str != NULL )
			{
				str_size += strlen(detail->display_str);
			}
			if ( detail->thread_name_str != NULL )
			{
				str_size += strlen(detail->thread_name_str);
			}
			if ( detail->extra_info_str != NULL )
			{
				str_size += strlen(detail->extra_info_str);
			}

			char * tmp_str = (char*) malloc( str_size + 7 );
			char*  tmp_str_ptr = tmp_str;

			if ( detail->display_str != NULL )
			{
				tmp_str_ptr += sprintf( tmp_str_ptr, "%s", detail->display_str );
			}
			if ( detail->thread_name_str != NULL )
			{
				if ( tmp_str_ptr != tmp_str )
				{
					tmp_str_ptr += sprintf( tmp_str_ptr, " : " );
				}
				tmp_str_ptr += sprintf( tmp_str_ptr, "%s", detail->thread_name_str );
			}
			if ( detail->extra_info_str != NULL )
			{
				if ( tmp_str_ptr != tmp_str )
				{
					tmp_str_ptr += sprintf( tmp_str_ptr, " : " );
				}
				tmp_str_ptr += sprintf( tmp_str_ptr, " : %s", detail->extra_info_str );
			}

			assert(strlen(tmp_str) ==
				(size_t) (tmp_str_ptr - tmp_str));

			char * hex_str = (char*) malloc( strlen(tmp_str)*2 +1 );
			str_to_hex( hex_str, tmp_str );

			gdb_put_packet(connection, hex_str, strlen(hex_str));
			free(hex_str);
			free(tmp_str);
			return ERROR_OK;

		}
		gdb_put_packet(connection, "", 0);
		return ERROR_OK;
	}
	else if (strstr(packet, "qSymbol"))
	{
		if ( target->rtos != NULL )
		{
			int next_symbol_num = -1;
			if (target->rtos->symbols == NULL)
			{
				target->rtos->type->get_symbol_list_to_lookup( &target->rtos->symbols );
			}
			if (0 == strcmp( "qSymbol::", packet ) )
			{
				// first query -
				next_symbol_num = 0;
			}
			else
			{
				int64_t value = 0;
				char * hex_name_str = malloc( strlen(packet));
				char * name_str;
				int symbol_num;

				char* found = strstr( packet, "qSymbol::" );
				if (0 == found )
				{
					sscanf(packet, "qSymbol:%" SCNx64 ":%s", &value, hex_name_str);
				}
				else
				{
					// No value returned by GDB - symbol was not found
					sscanf(packet, "qSymbol::%s", hex_name_str);
				}
				name_str = (char*) malloc( 1+ strlen(hex_name_str) / 2 );

				hex_to_str( name_str, hex_name_str );


				symbol_num = 0;
				while ( ( target->rtos->symbols[ symbol_num ].symbol_name != NULL ) && ( 0 != strcmp( target->rtos->symbols[ symbol_num ].symbol_name, name_str ) ) )
				{
					symbol_num++;
				}


				if ( target->rtos->symbols[ symbol_num ].symbol_name == NULL )
				{
					LOG_OUTPUT("ERROR: unknown symbol\r\n");
					gdb_put_packet(connection, "OK", 2);
					return ERROR_OK;
				}

				target->rtos->symbols[ symbol_num ].address = value;

				next_symbol_num = symbol_num+1;
				free( hex_name_str );
				free( name_str );

			}

			int symbols_done = 0;
			if ( target->rtos->symbols[ next_symbol_num ].symbol_name == NULL )
			{
				if ( ( target->rtos_auto_detect == false ) ||
					 ( 1 == target->rtos->type->detect_rtos( target ) ) )
				{
					// Found correct RTOS or not autodetecting
					if ( target->rtos_auto_detect == true )
					{
						LOG_OUTPUT( "Auto-detected RTOS: %s\r\n",target->rtos->type->name );
					}
					symbols_done = 1;
				}
				else
				{
					// Auto detecting RTOS and currently not found
					if( 1 != rtos_try_next( target ) )
					{
						// No more RTOS's to try
						symbols_done = 1;
					}
					else
					{
						next_symbol_num = 0;
						target->rtos->type->get_symbol_list_to_lookup( &target->rtos->symbols );
					}

				}
			}


			if ( symbols_done == 1 )
			{
				target->rtos_auto_detect = false;
				target->rtos->type->create( target );
				target->rtos->type->update_threads(target->rtos);
				// No more symbols needed
				gdb_put_packet(connection, "OK", 2);
				return ERROR_OK;

			}
			else
			{
				char* symname = target->rtos->symbols[ next_symbol_num ].symbol_name;
				char qsymstr[] = "qSymbol:";
				char * opstring = (char*)malloc(sizeof(qsymstr)+strlen(symname)*2+1);
				char * posptr = opstring;
				posptr += sprintf( posptr, "%s", qsymstr );
				str_to_hex( posptr, symname );
				gdb_put_packet(connection, opstring, strlen(opstring));
				free(opstring);
				return ERROR_OK;
			}

		}
		gdb_put_packet(connection, "OK", 2);
		return ERROR_OK;
	}
	else if (strstr(packet, "qfThreadInfo"))
	{
		int i;
		if ( ( target->rtos != NULL ) && ( target->rtos->thread_count != 0 ) )
		{

			char* out_str = (char*) malloc(17 * target->rtos->thread_count + 5);
			char* tmp_str = out_str;
			tmp_str += sprintf(tmp_str, "m");
			for (i = 0; i < target->rtos->thread_count; i++) {
				if (i != 0) {
					tmp_str += sprintf(tmp_str, ",");
				}
				tmp_str += sprintf(tmp_str, "%016" PRIx64,
						target->rtos->thread_details[i].threadid);
			}
			tmp_str[0] = 0;
			gdb_put_packet(connection, out_str, strlen(out_str));
		}
		else
		{
			gdb_put_packet(connection, "", 0);
		}

		return ERROR_OK;
	}
	else if (strstr(packet, "qsThreadInfo"))
	{
		gdb_put_packet(connection, "l", 1);
		return ERROR_OK;
	}
	else if (strstr(packet, "qAttached"))
	{
		gdb_put_packet(connection, "1", 1);
		return ERROR_OK;
	}
	else if (strstr(packet, "qOffsets"))
	{
		char offsets[] = "Text=0;Data=0;Bss=0";
		gdb_put_packet(connection, offsets, sizeof(offsets)-1);
		return ERROR_OK;
	}
	else if (strstr(packet, "qC"))
	{
		if( target->rtos!=NULL )
		{
			char buffer[15];
			int size;
			size = snprintf(buffer, 15, "QC%08X", (int)target->rtos->current_thread);
			gdb_put_packet(connection, buffer, size);
		}
		else
		{
			gdb_put_packet(connection, "QC0", 3);
		}
		return ERROR_OK;
	}
	else if ( packet[0] == 'T' ) // Is thread alive?
	{
		threadid_t threadid;
		int found = -1;
		sscanf(packet, "T%" SCNx64, &threadid);
		if ((target->rtos != NULL) && (target->rtos->thread_details
				!= NULL)) {
			int thread_num;
			for (thread_num = 0; thread_num
					< target->rtos->thread_count; thread_num++) {
				if (target->rtos->thread_details[thread_num].threadid
						== threadid) {
					if (target->rtos->thread_details[thread_num].exists) {
						found = thread_num;
					}
				}
			}
		}
		if (found != -1) {
			gdb_put_packet(connection, "OK", 2); // thread alive
		} else {
			gdb_put_packet(connection, "E01", 3); // thread not found
		}
		return ERROR_OK;
	}
	else if ( packet[0] == 'H') // Set current thread ( 'c' for step and continue, 'g' for all other operations )
	{
		if (packet[1] == 'g')
		{
			sscanf(packet, "Hg%16" SCNx64, &current_threadid);
		}
		gdb_put_packet(connection, "OK", 2);
		return ERROR_OK;
	}

	return GDB_THREAD_PACKET_NOT_CONSUMED;
}