mirror of
https://git.h3cjp.net/H3cJP/citra.git
synced 2024-11-23 20:13:02 +00:00
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 };
|
||||
|
||||
std::pair<BlockCollision, std::vector<BlockInfo>::iterator> TryGetBlock(CFGRebuildState& state,
|
||||
u32 address) {
|
||||
auto it = state.block_info.begin();
|
||||
while (it != state.block_info.end()) {
|
||||
if (it->start == address) {
|
||||
return {BlockCollision::Found, it};
|
||||
std::pair<BlockCollision, u32> TryGetBlock(CFGRebuildState& state, u32 address) {
|
||||
const auto& blocks = state.block_info;
|
||||
for (u32 index = 0; index < blocks.size(); index++) {
|
||||
if (blocks[index].start == address) {
|
||||
return {BlockCollision::Found, index};
|
||||
}
|
||||
if (it->IsInside(address)) {
|
||||
return {BlockCollision::Inside, it};
|
||||
if (blocks[index].IsInside(address)) {
|
||||
return {BlockCollision::Inside, index};
|
||||
}
|
||||
it++;
|
||||
}
|
||||
return {BlockCollision::None, it};
|
||||
return {BlockCollision::None, -1};
|
||||
}
|
||||
|
||||
struct ParseInfo {
|
||||
|
@ -318,24 +316,26 @@ bool TryInspectAddress(CFGRebuildState& state) {
|
|||
if (state.inspect_queries.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const u32 address = state.inspect_queries.front();
|
||||
state.inspect_queries.pop_front();
|
||||
const auto search_result = TryGetBlock(state, address);
|
||||
switch (search_result.first) {
|
||||
const auto [result, block_index] = TryGetBlock(state, address);
|
||||
switch (result) {
|
||||
case BlockCollision::Found: {
|
||||
return true;
|
||||
}
|
||||
case BlockCollision::Inside: {
|
||||
// This case is the tricky one:
|
||||
// We need to Split the block in 2 sepparate blocks
|
||||
const auto it = search_result.second;
|
||||
BlockInfo& block_info = CreateBlockInfo(state, address, it->end);
|
||||
it->end = address - 1;
|
||||
block_info.branch = it->branch;
|
||||
const u32 end = state.block_info[block_index].end;
|
||||
BlockInfo& new_block = CreateBlockInfo(state, address, end);
|
||||
BlockInfo& current_block = state.block_info[block_index];
|
||||
current_block.end = address - 1;
|
||||
new_block.branch = current_block.branch;
|
||||
BlockBranchInfo forward_branch{};
|
||||
forward_branch.address = address;
|
||||
forward_branch.ignore = true;
|
||||
it->branch = forward_branch;
|
||||
current_block.branch = forward_branch;
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
|
|
Loading…
Reference in a new issue