cpu: fix exec tracing memory corruption bug
Accessing traceData (to call setAddress() and/or setData()) after initiating a timing translation was causing crashes, since a failed translation could delete the traceData object before returning. It turns out that there was never a need to access traceData after initiating the translation, as the traced data was always available earlier; this ordering was merely historical. Furthermore, traceData->setAddress() and traceData->setData() were being called both from the CPU model and the ISA definition, often redundantly. This patch standardizes all setAddress and setData calls for memory instructions to be in the CPU models and not in the ISA definition. It also moves those calls above the translation calls to eliminate the crashes.
This commit is contained in:
@@ -275,7 +275,6 @@ def template StoreExecute {{
|
||||
if (fault == NoFault) {
|
||||
fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
|
||||
memAccessFlags, NULL);
|
||||
if (traceData) { traceData->setData(Mem); }
|
||||
}
|
||||
|
||||
if (fault == NoFault) {
|
||||
@@ -310,7 +309,6 @@ def template StoreCondExecute {{
|
||||
if (fault == NoFault) {
|
||||
fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
|
||||
memAccessFlags, &write_result);
|
||||
if (traceData) { traceData->setData(Mem); }
|
||||
}
|
||||
|
||||
if (fault == NoFault) {
|
||||
@@ -344,7 +342,6 @@ def template StoreInitiateAcc {{
|
||||
if (fault == NoFault) {
|
||||
fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
|
||||
memAccessFlags, NULL);
|
||||
if (traceData) { traceData->setData(Mem); }
|
||||
}
|
||||
|
||||
return fault;
|
||||
@@ -478,9 +475,6 @@ def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
|
||||
mem_flags = makeList(mem_flags)
|
||||
inst_flags = makeList(inst_flags)
|
||||
|
||||
# add hook to get effective addresses into execution trace output.
|
||||
ea_code += '\nif (traceData) { traceData->setAddr(EA); }\n'
|
||||
|
||||
# Some CPU models execute the memory operation as an atomic unit,
|
||||
# while others want to separate them into an effective address
|
||||
# computation and a memory access operation. As a result, we need
|
||||
|
||||
@@ -172,7 +172,6 @@ def template StoreExecute {{
|
||||
if (fault == NoFault) {
|
||||
fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
|
||||
memAccessFlags, NULL);
|
||||
if (traceData) { traceData->setData(Mem); }
|
||||
}
|
||||
|
||||
if (fault == NoFault) {
|
||||
@@ -204,7 +203,6 @@ def template StoreInitiateAcc {{
|
||||
if (fault == NoFault) {
|
||||
fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
|
||||
memAccessFlags, NULL);
|
||||
if (traceData) { traceData->setData(Mem); }
|
||||
}
|
||||
|
||||
// Need to write back any potential address register update
|
||||
|
||||
@@ -305,7 +305,6 @@ def template StoreExecute {{
|
||||
if (fault == NoFault) {
|
||||
fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
|
||||
memAccessFlags, NULL);
|
||||
if (traceData) { traceData->setData(Mem); }
|
||||
}
|
||||
|
||||
if (fault == NoFault) {
|
||||
@@ -342,7 +341,6 @@ def template StoreFPExecute {{
|
||||
if (fault == NoFault) {
|
||||
fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
|
||||
memAccessFlags, NULL);
|
||||
if (traceData) { traceData->setData(Mem); }
|
||||
}
|
||||
|
||||
if (fault == NoFault) {
|
||||
@@ -377,7 +375,6 @@ def template StoreCondExecute {{
|
||||
if (fault == NoFault) {
|
||||
fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
|
||||
memAccessFlags, &write_result);
|
||||
if (traceData) { traceData->setData(Mem); }
|
||||
}
|
||||
|
||||
if (fault == NoFault) {
|
||||
@@ -411,7 +408,6 @@ def template StoreInitiateAcc {{
|
||||
if (fault == NoFault) {
|
||||
fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
|
||||
memAccessFlags, NULL);
|
||||
if (traceData) { traceData->setData(Mem); }
|
||||
}
|
||||
|
||||
return fault;
|
||||
@@ -435,8 +431,6 @@ def template StoreCompleteAcc {{
|
||||
|
||||
if (fault == NoFault) {
|
||||
%(op_wb)s;
|
||||
|
||||
if (traceData) { traceData->setData(getMemData(xc, pkt)); }
|
||||
}
|
||||
|
||||
return fault;
|
||||
@@ -459,8 +453,6 @@ def template StoreCompleteAcc {{
|
||||
|
||||
if (fault == NoFault) {
|
||||
%(op_wb)s;
|
||||
|
||||
if (traceData) { traceData->setData(getMemData(xc, pkt)); }
|
||||
}
|
||||
|
||||
return fault;
|
||||
|
||||
@@ -38,9 +38,6 @@ def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
|
||||
mem_flags = makeList(mem_flags)
|
||||
inst_flags = makeList(inst_flags)
|
||||
|
||||
# add hook to get effective addresses into execution trace output.
|
||||
ea_code += '\nif (traceData) { traceData->setAddr(EA); }\n'
|
||||
|
||||
# Some CPU models execute the memory operation as an atomic unit,
|
||||
# while others want to separate them into an effective address
|
||||
# computation and a memory access operation. As a result, we need
|
||||
|
||||
@@ -166,7 +166,6 @@ def template StoreExecute {{
|
||||
if (fault == NoFault) {
|
||||
fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
|
||||
memAccessFlags, NULL);
|
||||
if (traceData) { traceData->setData(Mem); }
|
||||
}
|
||||
|
||||
if (fault == NoFault) {
|
||||
@@ -196,7 +195,6 @@ def template StoreInitiateAcc {{
|
||||
if (fault == NoFault) {
|
||||
fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
|
||||
memAccessFlags, NULL);
|
||||
if (traceData) { traceData->setData(Mem); }
|
||||
}
|
||||
|
||||
// Need to write back any potential address register update
|
||||
|
||||
@@ -97,9 +97,6 @@ def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
|
||||
mem_flags = makeList(mem_flags)
|
||||
inst_flags = makeList(inst_flags)
|
||||
|
||||
# add hook to get effective addresses into execution trace output.
|
||||
ea_code += '\nif (traceData) { traceData->setAddr(EA); }\n'
|
||||
|
||||
# Generate InstObjParams for the memory access.
|
||||
iop = InstObjParams(name, Name, base_class,
|
||||
{'ea_code': ea_code,
|
||||
|
||||
Reference in New Issue
Block a user