mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-03 01:39:21 +02:00
GP-5989 Fix ForceUnionAction "Could not recover p-code op"
This commit is contained in:
parent
8802befa22
commit
72344ce13e
1 changed files with 36 additions and 32 deletions
|
@ -4,9 +4,9 @@
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -128,28 +128,28 @@ public class ForceUnionAction extends AbstractDecompilerAction {
|
||||||
int opcode = accessOp.getOpcode();
|
int opcode = accessOp.getOpcode();
|
||||||
if (opcode == PcodeOp.PTRSUB) {
|
if (opcode == PcodeOp.PTRSUB) {
|
||||||
parentDt = typeIsUnionRelated(accessOp.getInput(0));
|
parentDt = typeIsUnionRelated(accessOp.getInput(0));
|
||||||
if (parentDt == null) {
|
if (parentDt != null) {
|
||||||
accessOp = null;
|
accessVn = accessOp.getInput(0);
|
||||||
return;
|
accessSlot = 0;
|
||||||
}
|
if (accessOp.getInput(1).getOffset() == 0) { // Artificial op
|
||||||
accessVn = accessOp.getInput(0);
|
do {
|
||||||
accessSlot = 0;
|
Varnode tmpVn = accessOp.getOutput();
|
||||||
if (accessOp.getInput(1).getOffset() == 0) { // Artificial op
|
PcodeOp tmpOp = tmpVn.getLoneDescend();
|
||||||
do {
|
if (tmpOp == null) {
|
||||||
Varnode tmpVn = accessOp.getOutput();
|
break;
|
||||||
PcodeOp tmpOp = tmpVn.getLoneDescend();
|
}
|
||||||
if (tmpOp == null) {
|
accessOp = tmpOp;
|
||||||
break;
|
accessVn = tmpVn;
|
||||||
|
accessSlot = accessOp.getSlot(accessVn);
|
||||||
}
|
}
|
||||||
accessOp = tmpOp;
|
while (accessOp.getOpcode() == PcodeOp.PTRSUB &&
|
||||||
accessVn = tmpVn;
|
accessOp.getInput(1).getOffset() == 0);
|
||||||
accessSlot = accessOp.getSlot(accessVn);
|
|
||||||
}
|
}
|
||||||
while (accessOp.getOpcode() == PcodeOp.PTRSUB &&
|
return;
|
||||||
accessOp.getInput(1).getOffset() == 0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
parentDt = null;
|
||||||
for (accessSlot = 0; accessSlot < accessOp.getNumInputs(); ++accessSlot) {
|
for (accessSlot = 0; accessSlot < accessOp.getNumInputs(); ++accessSlot) {
|
||||||
accessVn = accessOp.getInput(accessSlot);
|
accessVn = accessOp.getInput(accessSlot);
|
||||||
parentDt = typeIsUnionRelated(accessVn);
|
parentDt = typeIsUnionRelated(accessVn);
|
||||||
|
@ -157,22 +157,26 @@ public class ForceUnionAction extends AbstractDecompilerAction {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (accessSlot >= accessOp.getNumInputs()) {
|
if (parentDt != null) {
|
||||||
accessSlot = -1;
|
if (opcode == PcodeOp.SUBPIECE && accessSlot == 0 &&
|
||||||
accessVn = accessOp.getOutput();
|
!(parentDt instanceof Pointer)) {
|
||||||
parentDt = typeIsUnionRelated(accessVn);
|
// SUBPIECE acts directly as resolution operator
|
||||||
if (parentDt == null) {
|
// Choose field based on output varnode, even though it isn't the union data-type
|
||||||
accessOp = null;
|
accessSlot = -1;
|
||||||
return; // Give up, could not find type associated with field
|
accessVn = accessOp.getOutput();
|
||||||
}
|
}
|
||||||
}
|
return;
|
||||||
if (opcode == PcodeOp.SUBPIECE && accessSlot == 0 && !(parentDt instanceof Pointer)) {
|
|
||||||
// SUBPIECE acts directly as resolution operator
|
|
||||||
// Choose field based on output varnode, even though it isn't the union data-type
|
|
||||||
accessSlot = -1;
|
|
||||||
accessVn = accessOp.getOutput();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
accessSlot = -1;
|
||||||
|
accessVn = accessOp.getOutput();
|
||||||
|
if (accessVn != null) {
|
||||||
|
parentDt = typeIsUnionRelated(accessVn);
|
||||||
|
if (parentDt != null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
accessOp = null; // Give up, could not find type associated with field
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue