Skip to content

Commit 7c89389

Browse files
committed
Merge remote-tracking branch 'origin/GP-1-dragonmacher-enum-signedness-fix' into patch
2 parents daabec6 + b3fbdd3 commit 7c89389

File tree

4 files changed

+52
-15
lines changed

4 files changed

+52
-15
lines changed

Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/EnumDB.java

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,13 +112,17 @@ private EnumSignedState computeSignedness() {
112112
long minValue = valueMap.firstKey();
113113
long maxValue = valueMap.lastKey();
114114

115-
if (minValue < 0) {
116-
return SIGNED;
117-
}
118115
if (maxValue > getMaxPossibleValue(length, true)) {
116+
if (minValue < 0) {
117+
return INVALID;
118+
}
119119
return UNSIGNED;
120120
}
121121

122+
if (minValue < 0) {
123+
return SIGNED;
124+
}
125+
122126
return NONE; // we have no negatives and no large unsigned values
123127
}
124128

@@ -874,6 +878,19 @@ public boolean isSigned() {
874878
}
875879
}
876880

881+
@Override
882+
public EnumSignedState getSignedState() {
883+
lock.acquire();
884+
try {
885+
checkIsValid();
886+
initializeIfNeeded();
887+
return signedState;
888+
}
889+
finally {
890+
lock.release();
891+
}
892+
}
893+
877894
@Override
878895
public int getMinimumPossibleLength() {
879896
lock.acquire();

Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/data/EnumSignedState.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,14 @@
1818
/**
1919
* Keeps track of the signed state of an enum datatype. Enum are fundamentally either signed or
2020
* unsigned, but sometimes you can't tell based on the values they contain. Once a negative value
21-
* is added, then the enum becomes locked as signed, preventing high unsigned values from being
22-
* added. Once a high value unsigned value is added, then it becomes locked as unsigned value. If
23-
* neither a negative value or high unsigned value has been added, then the enum is not locked as
24-
* either signed or unsigned.
21+
* is added, then the enum becomes locked as signed, preventing high unsigned values (those values
22+
* that are too big for signed value of the enum size) from being added. Once a high value unsigned
23+
* value is added, then it becomes locked as unsigned value. If neither a negative value or high
24+
* unsigned value has been added, then the enum is not locked as either signed or unsigned.
2525
*/
2626
public enum EnumSignedState {
2727
SIGNED, // Enum contains at least 1 negative value, preventing high unsigned values
2828
UNSIGNED, // Enum contains at least 1 high unsigned value, preventing negative values
29-
NONE // Enum contains neither a negative or a high unsigned value, so can go either way
29+
NONE, // Enum contains neither a negative or a high unsigned value, so can go either way
30+
INVALID // Enum contains both negative and high unsigned values; can happen with old types
3031
}

Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/Enum.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import java.util.NoSuchElementException;
2020

2121
import ghidra.docking.settings.Settings;
22+
import ghidra.program.database.data.EnumSignedState;
2223

2324
public interface Enum extends DataType {
2425

@@ -133,6 +134,12 @@ public interface Enum extends DataType {
133134
*/
134135
public boolean isSigned();
135136

137+
/**
138+
* Returns the signed state.
139+
* @return the signed state.
140+
*/
141+
public EnumSignedState getSignedState();
142+
136143
/**
137144
* Returns the maximum value that this enum can represent based on its size and signedness.
138145
* @return the maximum value that this enum can represent based on its size and signedness.

Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/EnumDataType.java

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,11 @@ public void add(String valueName, long value) {
148148

149149
@Override
150150
public void add(String valueName, long value, String comment) {
151+
doAdd(valueName, value, comment);
152+
signedState = computeSignedness();
153+
}
154+
155+
private void doAdd(String valueName, long value, String comment) {
151156
bitGroups = null;
152157
checkValue(value);
153158
if (nameMap.containsKey(valueName)) {
@@ -161,8 +166,6 @@ public void add(String valueName, long value, String comment) {
161166
if (!StringUtils.isBlank(comment)) {
162167
commentMap.put(valueName, comment);
163168
}
164-
signedState = computeSignedness();
165-
166169
}
167170

168171
private EnumSignedState computeSignedness() {
@@ -172,13 +175,17 @@ private EnumSignedState computeSignedness() {
172175
long minValue = valueMap.firstKey();
173176
long maxValue = valueMap.lastKey();
174177

175-
if (minValue < 0) {
176-
return SIGNED;
177-
}
178178
if (maxValue > getMaxPossibleValue(length, true)) {
179+
if (minValue < 0) {
180+
return INVALID;
181+
}
179182
return UNSIGNED;
180183
}
181184

185+
if (minValue < 0) {
186+
return SIGNED;
187+
}
188+
182189
return NONE; // we have no negatives and no large unsigned values
183190
}
184191

@@ -277,6 +284,11 @@ public boolean isSigned() {
277284
return signedState == SIGNED;
278285
}
279286

287+
@Override
288+
public EnumSignedState getSignedState() {
289+
return signedState;
290+
}
291+
280292
@Override
281293
public long getMinPossibleValue() {
282294
return getMinPossibleValue(length, signedState != UNSIGNED);
@@ -503,10 +515,10 @@ public void replaceWith(DataType dataType) {
503515
commentMap = new HashMap<>();
504516
setLength(enumm.getLength());
505517
String[] names = enumm.getNames();
518+
signedState = enumm.getSignedState();
506519
for (String valueName : names) {
507-
add(valueName, enumm.getValue(valueName), enumm.getComment(valueName));
520+
doAdd(valueName, enumm.getValue(valueName), enumm.getComment(valueName));
508521
}
509-
computeSignedness();
510522
}
511523

512524
@Override

0 commit comments

Comments
 (0)