// FIXME: make this as intelligent as stack_trace. bool within_function(conf_object_t *cpu, int eip, int func, int func_end) { if (eip >= func && eip < func_end) return true; eip = READ_STACK(cpu, 0); if (eip >= func && eip < func_end) return true; int stop_ebp = 0; int ebp = GET_CPU_ATTR(cpu, ebp); int rabbit = ebp; int frame_count = 0; while (ebp != stop_ebp && (unsigned)ebp < USER_MEM_START && frame_count++ < 1024) { /* Test eip against given range. */ eip = READ_MEMORY(cpu, ebp + WORD_SIZE); if (eip >= func && eip < func_end) return true; /* Advance ebp and rabbit. Rabbit must go first to set stop_ebp * accurately. */ // XXX XXX XXX Actually fix the cycle detection - read from // rabbit not ebp; and get rid of the frame counter. // Fix this same bug in stack trace function below. if (rabbit != stop_ebp) rabbit = READ_MEMORY(cpu, ebp); if (rabbit == ebp) stop_ebp = ebp; if (rabbit != stop_ebp) rabbit = READ_MEMORY(cpu, ebp); if (rabbit == ebp) stop_ebp = ebp; ebp = READ_MEMORY(cpu, ebp); } return false; }
/****************************************************************************** \brief Read CRC of stored data from persist memory \ \param[out] crcStation - pointer to CRC service structure ******************************************************************************/ void pdsReadCrc(PDS_ServiceCrc_t *crcStation) { MEMORY_DESCRIPTOR descriptor; if (NULL == crcStation) return; descriptor.address = csPersistentMemorySize; descriptor.length = 1; while (descriptor.address < USER_BASE_EEPROM_ADDRESS) { descriptor.data = &(crcStation->crc); pdsWaitMemoryFree(); if (EEPROM_ERROR == READ_MEMORY(&descriptor, NULL)) { crcStation->eepromState = PDS_EEPROM_ERROR; return; } pdsWaitMemoryFree(); if (0xFF != crcStation->crc) { crcStation->position = descriptor.address; crcStation->eepromState = PDS_SUCCESS; return; } descriptor.address++; } crcStation->position = csPersistentMemorySize; crcStation->eepromState = PDS_SUCCESS; }
/****************************************************************************** \brief Calculate CRC of persistent data stored in persist memory \ \param[out] crcStation - pointer to CRC service structure ******************************************************************************/ void pdsCalculateCrc(PDS_ServiceCrc_t *crcStation) { uint8_t tdata = 0; MEMORY_DESCRIPTOR descriptor; if (NULL == crcStation) return; crcStation->crc = 0; descriptor.address = SYSTEM_BASE_EEPROM_ADDRESS; descriptor.length = 1; while (descriptor.address < csPersistentMemorySize) { descriptor.data = &tdata; pdsWaitMemoryFree(); if (EEPROM_ERROR == READ_MEMORY(&descriptor, NULL)) { crcStation->eepromState = PDS_EEPROM_ERROR; return; } pdsWaitMemoryFree(); crcStation->crc += tdata; descriptor.address++; } crcStation->eepromState = PDS_SUCCESS; }
bool kern_ready_for_timer_interrupt(cpu_t *cpu) { #ifdef PREEMPT_ENABLE_FLAG #ifndef PREEMPT_ENABLE_VALUE STATIC_ASSERT(false && "preempt flag but not value defined"); return false; #else return READ_MEMORY(cpu, (unsigned int)PREEMPT_ENABLE_FLAG) == PREEMPT_ENABLE_VALUE; #endif #else /* no preempt enable flag. assume the scheduler protects itself by * disabling interrupts wholesale. */ return true; #endif }
/* Caller has to free the return value. */ char *stack_trace(conf_object_t *cpu, int eip, int tid) { char *buf = MM_XMALLOC(MAX_TRACE_LEN, char); int pos = 0, old_pos; int stack_offset = 0; /* Counts by 1 - READ_STACK already multiplies */ ADD_STR(buf, pos, MAX_TRACE_LEN, "TID%d at 0x%.8x in ", tid, eip); ADD_FRAME(buf, pos, MAX_TRACE_LEN, eip); int stop_ebp = 0; int ebp = GET_CPU_ATTR(cpu, ebp); int rabbit = ebp; int frame_count = 0; while (ebp != 0 && (unsigned)ebp < USER_MEM_START && frame_count++ < 1024) { bool extra_frame; do { int eip_offset; bool iret_block = false; extra_frame = false; /* at the beginning or end of a function, there is no * frame, but a return address is still on the stack. */ if (function_eip_offset(eip, &eip_offset)) { if (eip_offset == 0) { extra_frame = true; } else if (eip_offset == 1 && READ_BYTE(cpu, eip - 1) == OPCODE_PUSH_EBP) { stack_offset++; extra_frame = true; } } if (!extra_frame) { int opcode = READ_BYTE(cpu, eip); if (opcode == OPCODE_RET) { extra_frame = true; } else if (opcode == OPCODE_IRET) { iret_block = true; extra_frame = true; } } if (extra_frame) { eip = READ_STACK(cpu, stack_offset); ADD_STR(buf, pos, MAX_TRACE_LEN, "%s0x%.8x in ", STACK_TRACE_SEPARATOR, eip); ADD_FRAME(buf, pos, MAX_TRACE_LEN, eip); if (iret_block) stack_offset += IRET_BLOCK_WORDS; else stack_offset++;; } } while (extra_frame); /* pushed return address behind the base pointer */ eip = READ_MEMORY(cpu, ebp + WORD_SIZE); stack_offset = ebp + 2; ADD_STR(buf, pos, MAX_TRACE_LEN, "%s0x%.8x in ", STACK_TRACE_SEPARATOR, eip); old_pos = pos; ADD_FRAME(buf, pos, MAX_TRACE_LEN, eip); /* special-case termination condition */ if (pos - old_pos >= strlen(ENTRY_POINT) && strncmp(buf + old_pos, ENTRY_POINT, strlen(ENTRY_POINT)) == 0) { break; } if (rabbit != stop_ebp) rabbit = READ_MEMORY(cpu, ebp); if (rabbit == ebp) stop_ebp = ebp; if (rabbit != stop_ebp) rabbit = READ_MEMORY(cpu, ebp); if (rabbit == ebp) stop_ebp = ebp; ebp = READ_MEMORY(cpu, ebp); } char *buf2 = MM_XSTRDUP(buf); /* truncate to save space */ MM_FREE(buf); return buf2; }
bool kern_ready_for_timer_interrupt(conf_object_t *cpu) { int x = READ_MEMORY(cpu, GUEST_SCHEDULER_LOCK); return x == 0; }