/* main thread entrypoint */ void thread_main() { /* if they want redirections, set up to receive the location */ char *loc = 0; char **locp = ((options & NetReqNoRedirect) != 0 ? &loc : 0); /* set up a memory stream object to hold the reply */ CVmExpandableMemoryStream *reply = new CVmExpandableMemoryStream(0); /* no reply headers yet */ char *reply_hdrs = 0; /* figure the request option flags */ int rflags = 0; if (https) rflags |= OS_HttpClient::OptHTTPS; /* get the length of the custom headers, if we have any */ size_t hdrs_len = (hdrs != 0 ? strlen(hdrs) : 0); /* presume failure */ int status = OS_HttpClient::ErrOther; /* send the request, catching any errors */ err_try { /* send the request */ status = OS_HttpClient::request( rflags, host, port, verb, resource, hdrs, hdrs_len, body, reply, &reply_hdrs, locp, 0); } err_catch (exc) { } /* * if the status is negative, a system-level error occurred, so * there's no reply data - delete and forget the reply stream */ if (status < 0) { delete reply; reply = 0; } err_end; /* * Always post a result event, even on failure, since the event is * the way we transmit the status information back to the caller. * Note that the event object takes ownership of the reply stream, * headers string, and location string, and will free the * underlying memory when the event object is deleted. */ post_result(status, reply, reply_hdrs, loc); }
static int gdb_fileio_end(struct target *target, int result, int fileio_errno, bool ctrl_c) { struct arm *arm = target_to_arm(target); struct gdb_fileio_info *fileio_info = target->fileio_info; /* clear pending status */ arm->semihosting_hit_fileio = false; arm->semihosting_result = result; arm->semihosting_errno = fileio_errno; /* Some fileio results do not match up with what the semihosting * operation expects; for these operations, we munge the results * below: */ switch (arm->semihosting_op) { case 0x05: /* SYS_WRITE */ if (result < 0) arm->semihosting_result = fileio_info->param_3; else arm->semihosting_result = 0; break; case 0x06: /* SYS_READ */ if (result == (int)fileio_info->param_3) arm->semihosting_result = 0; if (result <= 0) arm->semihosting_result = fileio_info->param_3; break; case 0x0a: /* SYS_SEEK */ if (result > 0) arm->semihosting_result = 0; break; } return post_result(target); }
/** * Checks for and processes an ARM semihosting request. This is meant * to be called when the target is stopped due to a debug mode entry. * If the value 0 is returned then there was nothing to process. A non-zero * return value signifies that a request was processed and the target resumed, * or an error was encountered, in which case the caller must return * immediately. * * @param target Pointer to the ARM target to process. This target must * not represent an ARMv6-M or ARMv7-M processor. * @param retval Pointer to a location where the return code will be stored * @return non-zero value if a request was processed or an error encountered */ int arm_semihosting(struct target *target, int *retval) { struct arm *arm = target_to_arm(target); struct armv7a_common *armv7a = target_to_armv7a(target); uint32_t pc, lr, spsr; struct reg *r; if (!arm->is_semihosting) return 0; if (is_arm7_9(target_to_arm7_9(target)) || is_armv7a(armv7a)) { uint32_t vbar = 0x00000000; if (arm->core_mode != ARM_MODE_SVC) return 0; if (is_armv7a(armv7a)) { struct arm_dpm *dpm = armv7a->arm.dpm; *retval = dpm->prepare(dpm); if (*retval == ERROR_OK) { *retval = dpm->instr_read_data_r0(dpm, ARMV4_5_MRC(15, 0, 0, 12, 0, 0), &vbar); dpm->finish(dpm); if (*retval != ERROR_OK) return 1; } else { return 1; } } /* Check for PC == 0x00000008 or 0xffff0008: Supervisor Call vector. */ r = arm->pc; pc = buf_get_u32(r->value, 0, 32); if (pc != (vbar + 0x00000008) && pc != 0xffff0008) return 0; r = arm_reg_current(arm, 14); lr = buf_get_u32(r->value, 0, 32); /* Core-specific code should make sure SPSR is retrieved * when the above checks pass... */ if (!arm->spsr->valid) { LOG_ERROR("SPSR not valid!"); *retval = ERROR_FAIL; return 1; } spsr = buf_get_u32(arm->spsr->value, 0, 32); /* check instruction that triggered this trap */ if (spsr & (1 << 5)) { /* was in Thumb (or ThumbEE) mode */ uint8_t insn_buf[2]; uint16_t insn; *retval = target_read_memory(target, lr-2, 2, 1, insn_buf); if (*retval != ERROR_OK) return 1; insn = target_buffer_get_u16(target, insn_buf); /* SVC 0xab */ if (insn != 0xDFAB) return 0; } else if (spsr & (1 << 24)) { /* was in Jazelle mode */ return 0; } else { /* was in ARM mode */ uint8_t insn_buf[4]; uint32_t insn; *retval = target_read_memory(target, lr-4, 4, 1, insn_buf); if (*retval != ERROR_OK) return 1; insn = target_buffer_get_u32(target, insn_buf); /* SVC 0x123456 */ if (insn != 0xEF123456) return 0; } } else if (is_armv7m(target_to_armv7m(target))) { uint16_t insn; if (target->debug_reason != DBG_REASON_BREAKPOINT) return 0; r = arm->pc; pc = buf_get_u32(r->value, 0, 32); pc &= ~1; *retval = target_read_u16(target, pc, &insn); if (*retval != ERROR_OK) return 1; /* bkpt 0xAB */ if (insn != 0xBEAB) return 0; } else { LOG_ERROR("Unsupported semi-hosting Target"); return 0; } /* Perform semihosting if we are not waiting on a fileio * operation to complete. */ if (!arm->semihosting_hit_fileio) { *retval = do_semihosting(target); if (*retval != ERROR_OK) { LOG_ERROR("Failed semihosting operation"); return 0; } } /* Post result to target if we are not waiting on a fileio * operation to complete: */ if (!arm->semihosting_hit_fileio) { *retval = post_result(target); if (*retval != ERROR_OK) { LOG_ERROR("Failed to post semihosting result"); return 0; } *retval = target_resume(target, 1, 0, 0, 0); if (*retval != ERROR_OK) { LOG_ERROR("Failed to resume target"); return 0; } return 1; } return 0; }