GP-6540 - Added a tool option to display addresses in upper case

This commit is contained in:
dragonmacher
2026-04-01 17:28:44 -04:00
parent a62a1b3cc9
commit 374584411b
6 changed files with 55 additions and 62 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.
@@ -135,28 +135,26 @@ public class AddressFieldFactory extends FieldFactory {
private String getAddressString(CodeUnit cu) { private String getAddressString(CodeUnit cu) {
Address addr = cu.getMinAddress(); Address addr = cu.getMinAddress();
AddressSpace space = addr.getAddressSpace(); AddressSpace space = addr.getAddressSpace();
String text; int minDigits = padZeros ? 16 : minHexDigits;
String addrText = addr.toString(false, minDigits);
if (displayUpperCase) {
addrText = addrText.toUpperCase();
}
if (displayBlockName) { if (displayBlockName) {
text = addr.toString(false, padZeros ? 16 : minHexDigits);
MemoryBlock block = cu.getProgram().getMemory().getBlock(addr); MemoryBlock block = cu.getProgram().getMemory().getBlock(addr);
if (block != null) { if (block != null) {
if (displayUpperCase) { return block.getName() + ":" + addrText;
text = text.toUpperCase();
}
return block.getName() + ":" + text;
} }
} }
text = addr.toString(space.showSpaceName(), padZeros ? 16 : minHexDigits);
if (displayUpperCase) { String spaceText = "";
int colonIdx = text.lastIndexOf(':'); if (space.showSpaceName()) {
if (colonIdx >= 0) { // this will be the space name followed by one or two colons
text = text.substring(0, colonIdx + 1) + text.substring(colonIdx + 1).toUpperCase(); spaceText = space.toString();
}
else {
text = text.toUpperCase();
}
} }
return text;
return spaceText + addrText;
} }
@Override @Override
@@ -195,8 +193,7 @@ public class AddressFieldFactory extends FieldFactory {
} }
else if (loc instanceof AddressFieldLocation) { else if (loc instanceof AddressFieldLocation) {
if (hasSamePath(lf, loc)) { if (hasSamePath(lf, loc)) {
return new FieldLocation(index, fieldNum, 0, return new FieldLocation(index, fieldNum, 0, loc.getCharOffset());
((AddressFieldLocation) loc).getCharOffset());
} }
} }
return null; return null;
@@ -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.
@@ -142,7 +142,7 @@ public class AddressFieldOptionsPropertyEditor extends PropertyEditorSupport
} }
addressFieldOptionsWrappedOption = (AddressFieldOptionsWrappedOption) value; addressFieldOptionsWrappedOption = (AddressFieldOptionsWrappedOption) value;
setLocalValues(addressFieldOptionsWrappedOption); setValuesFromOption(addressFieldOptionsWrappedOption);
firePropertyChange(); firePropertyChange();
} }
@@ -150,29 +150,30 @@ public class AddressFieldOptionsPropertyEditor extends PropertyEditorSupport
return minDigitsField.getIntValue(); return minDigitsField.getIntValue();
} }
private void setLocalValues(AddressFieldOptionsWrappedOption addressPaddingOption) { private void setValuesFromOption(AddressFieldOptionsWrappedOption option) {
if (addressPaddingOption.showBlockName() != showBlocknameCheckbox.isSelected()) { if (option.showBlockName() != showBlocknameCheckbox.isSelected()) {
showBlocknameCheckbox.setSelected(addressPaddingOption.showBlockName()); showBlocknameCheckbox.setSelected(option.showBlockName());
} }
boolean rightJust = justificationCombobox.getSelectedItem().equals("Right"); boolean rightJust = justificationCombobox.getSelectedItem().equals("Right");
if (addressPaddingOption.rightJustify() != rightJust) { if (option.rightJustify() != rightJust) {
justificationCombobox.setSelectedIndex(addressPaddingOption.rightJustify() ? 1 : 0); justificationCombobox.setSelectedIndex(option.rightJustify() ? 1 : 0);
} }
if (addressPaddingOption.padWithZeros() != padCheckBox.isSelected()) { if (option.padWithZeros() != padCheckBox.isSelected()) {
padCheckBox.setSelected(addressPaddingOption.padWithZeros()); padCheckBox.setSelected(option.padWithZeros());
} }
if (!Integer.toString(addressPaddingOption.getMinimumHexDigits()).equals( if (!Integer.toString(option.getMinimumHexDigits())
minDigitsField.getText())) { .equals(
minDigitsField.setValue(addressPaddingOption.getMinimumHexDigits()); minDigitsField.getText())) {
minDigitsField.setValue(option.getMinimumHexDigits());
} }
boolean enabled = !padCheckBox.isSelected(); boolean enabled = !padCheckBox.isSelected();
minDigitsField.setEnabled(enabled); minDigitsField.setEnabled(enabled);
if (addressPaddingOption.displayUpperCase() != upperCaseCheckbox.isSelected()) { if (option.displayUpperCase() != upperCaseCheckbox.isSelected()) {
upperCaseCheckbox.setSelected(addressPaddingOption.displayUpperCase()); upperCaseCheckbox.setSelected(option.displayUpperCase());
} }
} }
private AddressFieldOptionsWrappedOption cloneAddressPadValues() { private AddressFieldOptionsWrappedOption createOptionFromValues() {
AddressFieldOptionsWrappedOption newOption = new AddressFieldOptionsWrappedOption(); AddressFieldOptionsWrappedOption newOption = new AddressFieldOptionsWrappedOption();
newOption.setPadWithZeros(padCheckBox.isSelected()); newOption.setPadWithZeros(padCheckBox.isSelected());
newOption.setMinimumHexDigits(getMinNumberOfDigits()); newOption.setMinimumHexDigits(getMinNumberOfDigits());
@@ -194,7 +195,7 @@ public class AddressFieldOptionsPropertyEditor extends PropertyEditorSupport
@Override @Override
public Object getValue() { public Object getValue() {
return cloneAddressPadValues(); return createOptionFromValues();
} }
@Override @Override
@@ -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.
@@ -148,7 +148,7 @@ public abstract class OverlayAddressSpace extends AbstractAddressSpace {
} }
/** /**
* If the given address is outside the overlay block, then the address is tranlated to an * If the given address is outside the overlay block, then the address is translated to an
* address in the base space with the same offset, otherwise (if the address exists in the * address in the base space with the same offset, otherwise (if the address exists in the
* overlay block), it is returned * overlay block), it is returned
* *
@@ -161,7 +161,7 @@ public abstract class OverlayAddressSpace extends AbstractAddressSpace {
} }
/** /**
* Tranlated an overlay-space address (addr, which may exceed the bounds of the overlay space) * Translated an overlay-space address (addr, which may exceed the bounds of the overlay space)
* to an address in the base space with the same offset. If forceTranslation is false and addr * to an address in the base space with the same offset. If forceTranslation is false and addr
* is contained within the overlay-space the original addr is returned. * is contained within the overlay-space the original addr is returned.
* *
@@ -221,8 +221,8 @@ public abstract class OverlayAddressSpace extends AbstractAddressSpace {
} }
/** /**
* Compare this overlay to the spacified overlay. * Compare this overlay to the specified overlay.
* @param overlay other overlay to be checked for eqauality * @param overlay other overlay to be checked for equality
* @return see {@link Comparable#compareTo(Object)} * @return see {@link Comparable#compareTo(Object)}
*/ */
int compareOverlay(OverlayAddressSpace overlay) { int compareOverlay(OverlayAddressSpace overlay) {
@@ -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.
@@ -15,7 +15,6 @@
*/ */
package ghidra.program.model.address; package ghidra.program.model.address;
/** /**
* Address class for dealing with (intel) segmented addresses. The class itself is agnostic * Address class for dealing with (intel) segmented addresses. The class itself is agnostic
* about the mapping from segmented encoding to flat address offset, it uses the * about the mapping from segmented encoding to flat address offset, it uses the
@@ -88,7 +87,7 @@ public class SegmentedAddress extends GenericAddress {
/** /**
* Returns a new address that is equivalent to this address using * Returns a new address that is equivalent to this address using
* the given segment number. * the given segment number.
* @param seg the seqment value to normalize to. * @param seg the segment value to normalize to.
* @return the new address * @return the new address
*/ */
public SegmentedAddress normalize(int seg) { public SegmentedAddress normalize(int seg) {
@@ -135,17 +134,11 @@ public class SegmentedAddress extends GenericAddress {
return zeros.substring(0, 4 - str.length()) + str; return zeros.substring(0, 4 - str.length()) + str;
} }
/**
* @see ghidra.program.model.address.Address#toString(String)
*/
@Override @Override
public String toString(String prefix) { public String toString(String prefix) {
return prefix + getString(segment) + SEPARATOR_CHAR + getString(getSegmentOffset()); return prefix + getString(segment) + SEPARATOR_CHAR + getString(getSegmentOffset());
} }
/**
* @see ghidra.program.model.address.Address#getPhysicalAddress()
*/
@Override @Override
public Address getPhysicalAddress() { public Address getPhysicalAddress() {
return this; // A segmented address is already a physical address. return this; // A segmented address is already a physical address.
@@ -155,7 +148,7 @@ public class SegmentedAddress extends GenericAddress {
public String toString(boolean showAddressSpace, int minNumDigits) { public String toString(boolean showAddressSpace, int minNumDigits) {
String addr = getString(segment) + SEPARATOR_CHAR + getString(getSegmentOffset()); String addr = getString(segment) + SEPARATOR_CHAR + getString(getSegmentOffset());
if (showAddressSpace) { if (showAddressSpace) {
addr = addrSpace.getName() + SEPARATOR_CHAR + addr; addr = addrSpace + addr;
} }
return addr; return addr;
} }
@@ -33,7 +33,7 @@ public interface MemoryBlock extends Serializable, Comparable<MemoryBlock> {
* A special purpose EXTERNAL block may be created by certain program loaders * A special purpose EXTERNAL block may be created by certain program loaders
* (e.g., Elf) to act as a stand-in for unknown external symbol locations when * (e.g., Elf) to act as a stand-in for unknown external symbol locations when
* relocation support is required using a valid memory address. While the * relocation support is required using a valid memory address. While the
* EXTERNAL block is created out of neccessity for relocation processing it * EXTERNAL block is created out of necessity for relocation processing it
* introduces a number of limitations when used to carry data symbols * introduces a number of limitations when used to carry data symbols
* where pointer math and offset-references may occur. * where pointer math and offset-references may occur.
* <p> * <p>
@@ -65,6 +65,7 @@ public interface MemoryBlock extends Serializable, Comparable<MemoryBlock> {
/** /**
* Get memory data in the form of an InputStream. Null is returned for thos memory blocks which * Get memory data in the form of an InputStream. Null is returned for thos memory blocks which
* have no data. * have no data.
* @return the input stream
*/ */
public InputStream getData(); public InputStream getData();
@@ -72,6 +73,7 @@ public interface MemoryBlock extends Serializable, Comparable<MemoryBlock> {
* Return whether addr is contained in this block. * Return whether addr is contained in this block.
* *
* @param addr address * @param addr address
* @return true if contained
*/ */
public boolean contains(Address addr); public boolean contains(Address addr);
@@ -303,8 +305,8 @@ public interface MemoryBlock extends Serializable, Comparable<MemoryBlock> {
public int putBytes(Address addr, byte[] b) throws MemoryAccessException; public int putBytes(Address addr, byte[] b) throws MemoryAccessException;
/** /**
* Tries to put len bytes from the specified byte array to this block. All the bytes may not be * Tries to put {@code len} bytes from the specified byte array to this block. All the bytes may
* written if the requested length is beyond the end of the block. * not be written if the requested length is beyond the end of the block.
* *
* @param addr the address of where to put the bytes. * @param addr the address of where to put the bytes.
* @param b the byte array containing the bytes to write. * @param b the byte array containing the bytes to write.
@@ -328,7 +330,7 @@ public interface MemoryBlock extends Serializable, Comparable<MemoryBlock> {
/** /**
* Return whether this block has been initialized. * Return whether this block has been initialized.
* <p> * <p>
* WARNING: A mapped memory block may have a mix of intialized, uninitialized, and undefined * WARNING: A mapped memory block may have a mix of initialized, uninitialized, and undefined
* regions. The value returned by this method for a mapped memory block is always false * regions. The value returned by this method for a mapped memory block is always false
* even if some regions are initialized. * even if some regions are initialized.
* @return true if block is fully initialized and not a memory-mapped-block, else false * @return true if block is fully initialized and not a memory-mapped-block, else false
@@ -347,10 +349,10 @@ public interface MemoryBlock extends Serializable, Comparable<MemoryBlock> {
* (see {@link MemoryBlock#EXTERNAL_BLOCK_NAME}). Checks for individual addresses may be done * (see {@link MemoryBlock#EXTERNAL_BLOCK_NAME}). Checks for individual addresses may be done
* using {@link Memory#isExternalBlockAddress(Address)}. * using {@link Memory#isExternalBlockAddress(Address)}.
* <p> * <p>
* Note that EXTERNAL blocks always resides within a memory space and never within the artifial * Note that EXTERNAL blocks always resides within a memory space and never within the
* {@link AddressSpace#EXTERNAL_SPACE} which is not a memory space. This can be a source of confusion. * artificial {@link AddressSpace#EXTERNAL_SPACE} which is not a memory space. This can be a
* An EXTERNAL memory block exists to facilitate relocation processing for some external * source of confusion. An EXTERNAL memory block exists to facilitate relocation processing for
* symbols which require a real memory address. * some external symbols which require a real memory address.
* *
* @return true if this is a reserved EXTERNAL memory block * @return true if this is a reserved EXTERNAL memory block
*/ */