-
Notifications
You must be signed in to change notification settings - Fork 23
Fix Maybe Uninitialised Error and Remove UB #456
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Conversation
|
|
||
| // Check fstatat returned 0 | ||
| EXPECT_EQ(getGeneralRegister<int64_t>(27), 0); | ||
| EXPECT_EQ(getGeneralRegister<int64_t>(21), 0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@FinnWilkinson @jj16791 I think this test was checking the wrong register. Can you double check?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we are wanting to check the newfstatat register, then it sould be 21 yeah. My sme branch has register 21 being checked though so unsure when this happened...
| stateChange.memoryAddressValues.push_back(RegisterValue( | ||
| reinterpret_cast<const uint8_t*>(out.data()), outSize)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reinterpret_casting throughout this function is alarming and requires further investigation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Personally I think RegisterValue should have proper move semantics and you should be able to create a blank register of some size and move it into the vector
|
|
||
| // Write data for this buffer in 128-byte chunks | ||
| auto iSrc = reinterpret_cast<const char*>(buffers[i].data()); | ||
| auto iSrc = reinterpret_cast<const uint8_t*>(buffers[i].data()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure about this one
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comments same as AArch exception handler
| // TODO avoid malloc and copy altogether | ||
| uint8_t* data = (uint8_t*)malloc(size); | ||
| aggrReq->data.getAsVector<char>().copyTo(data, size); | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could have a member buffer but not sure what size?
| reinterpret_cast<uint8_t*>(memData.data()), memData.size() * sizeof(uint64_t)); | ||
| index++; | ||
| memData.clear(); | ||
| } | ||
| } | ||
| // Check if final data needs putting into memoryData_ | ||
| if (memData.size() > 0) { | ||
| memoryData_[index] = RegisterValue((char*)memData.data(), | ||
| memoryData_[index] = RegisterValue(reinterpret_cast<uint8_t*>(memData.data()), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could be dangerous
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reinterpret casts throughout need to be checked for safety
ABenC377
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good. A couple of general questions (more for my own understanding than anything else).
|
|
||
| for (int i = 0; i < I; i++) { | ||
| if (isXtn2 & (i < (I / 2))) { | ||
| assert(isXtn2 && "isXtn2 is false so d is not initialised"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will this assert ever fail? If isXtn2 & anything is true, wont isXtn2 always be true?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is layover from when I was having issues previously. No harm in keeping it but happy to remove. Your call
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think get rid of it, as it doesn't do anything and so might cause momentary confusion for someone reading this bit of code in the future.
| assert(response->data && "unhandled failed read in exception handler"); | ||
| uint8_t bytesRead = response->target.size; | ||
| const uint8_t* data = response->data.getAsVector<uint8_t>(); | ||
| uint8_t* data = (uint8_t*)malloc(bytesRead); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Create a block-scoped std::vector<uint8_t> and copy to that instead of malloc/free
| memcpy(dest, ptr, bytes); | ||
| } | ||
|
|
||
| void copyTo(void* dest, const size_t bytes, const uint64_t offset) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method should be const too?
| stateChange.memoryAddressValues.push_back(RegisterValue( | ||
| reinterpret_cast<const uint8_t*>(out.data()), outSize)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Personally I think RegisterValue should have proper move semantics and you should be able to create a blank register of some size and move it into the vector
| uint8_t bytesRead = response->target.size; | ||
| const uint8_t* data = response->data.getAsVector<uint8_t>(); | ||
| // TODO clean up malloc | ||
| uint8_t* data = (uint8_t*)malloc(bytesRead); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See comment about using scoped vector
| initialStackFrame.push_back(commandLine_.size()); // argc | ||
| for (size_t i = 0; i < commandLine_.size(); i++) { | ||
| char* argvi = commandLine_[i].data(); | ||
| uint8_t* argvi = reinterpret_cast<uint8_t*>(commandLine_[i].data()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use auto on lhs if rhs is reinterpret_cast
| return "+sve,+lse"; | ||
| #elif SIMENG_LLVM_VERSION < 18 | ||
| return "+sve,+lse,+sve2,+sme,+sme-f64"; | ||
| return "+sve,+lse,+sve2,+sme,+sme-f64,+sme-i64"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be part of the PR?
| #include <algorithm> | ||
| #include <cassert> | ||
| #include <cstring> | ||
| #include <iostream> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove extra header
| struct safePointer { | ||
| public: | ||
| explicit safePointer(const uint8_t* ptr) : ptr(ptr) {} | ||
| explicit safePointer() : ptr(nullptr) {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we need a null safePointer? Is it still safe if calling anything on it is UB? also, might want to assert in the ctor above if the build is debug
Fixes #426 among other errors.
Add a safe pointer struct to remove undefined behaviour caused by reinterpret casting in the
RegisterValue. The safe pointer hides the underlying pointer toRegisterValuedata. This enforces immutability and fixes UB by converting unsafereinterpret_casts to safememcpys.