control_flow: Correct block breaking algorithm.
This commit is contained in:
parent
dc4a93594c
commit
e7c6045a03
|
@ -75,19 +75,17 @@ struct CFGRebuildState {
|
||||||
|
|
||||||
enum class BlockCollision : u32 { None, Found, Inside };
|
enum class BlockCollision : u32 { None, Found, Inside };
|
||||||
|
|
||||||
std::pair<BlockCollision, std::vector<BlockInfo>::iterator> TryGetBlock(CFGRebuildState& state,
|
std::pair<BlockCollision, u32> TryGetBlock(CFGRebuildState& state, u32 address) {
|
||||||
u32 address) {
|
const auto& blocks = state.block_info;
|
||||||
auto it = state.block_info.begin();
|
for (u32 index = 0; index < blocks.size(); index++) {
|
||||||
while (it != state.block_info.end()) {
|
if (blocks[index].start == address) {
|
||||||
if (it->start == address) {
|
return {BlockCollision::Found, index};
|
||||||
return {BlockCollision::Found, it};
|
|
||||||
}
|
}
|
||||||
if (it->IsInside(address)) {
|
if (blocks[index].IsInside(address)) {
|
||||||
return {BlockCollision::Inside, it};
|
return {BlockCollision::Inside, index};
|
||||||
}
|
}
|
||||||
it++;
|
|
||||||
}
|
}
|
||||||
return {BlockCollision::None, it};
|
return {BlockCollision::None, -1};
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ParseInfo {
|
struct ParseInfo {
|
||||||
|
@ -318,24 +316,26 @@ bool TryInspectAddress(CFGRebuildState& state) {
|
||||||
if (state.inspect_queries.empty()) {
|
if (state.inspect_queries.empty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const u32 address = state.inspect_queries.front();
|
const u32 address = state.inspect_queries.front();
|
||||||
state.inspect_queries.pop_front();
|
state.inspect_queries.pop_front();
|
||||||
const auto search_result = TryGetBlock(state, address);
|
const auto [result, block_index] = TryGetBlock(state, address);
|
||||||
switch (search_result.first) {
|
switch (result) {
|
||||||
case BlockCollision::Found: {
|
case BlockCollision::Found: {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case BlockCollision::Inside: {
|
case BlockCollision::Inside: {
|
||||||
// This case is the tricky one:
|
// This case is the tricky one:
|
||||||
// We need to Split the block in 2 sepparate blocks
|
// We need to Split the block in 2 sepparate blocks
|
||||||
const auto it = search_result.second;
|
const u32 end = state.block_info[block_index].end;
|
||||||
BlockInfo& block_info = CreateBlockInfo(state, address, it->end);
|
BlockInfo& new_block = CreateBlockInfo(state, address, end);
|
||||||
it->end = address - 1;
|
BlockInfo& current_block = state.block_info[block_index];
|
||||||
block_info.branch = it->branch;
|
current_block.end = address - 1;
|
||||||
|
new_block.branch = current_block.branch;
|
||||||
BlockBranchInfo forward_branch{};
|
BlockBranchInfo forward_branch{};
|
||||||
forward_branch.address = address;
|
forward_branch.address = address;
|
||||||
forward_branch.ignore = true;
|
forward_branch.ignore = true;
|
||||||
it->branch = forward_branch;
|
current_block.branch = forward_branch;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|
Reference in New Issue