Skip to content

Commit

Permalink
Merge remote-tracking branch
Browse files Browse the repository at this point in the history
'origin/GP-1778_ghidravore_address_range_map_iterator--SQUASHED'
  • Loading branch information
ghidra1 committed May 3, 2022
2 parents 47ad16a + 0b65bf2 commit c064355
Show file tree
Hide file tree
Showing 16 changed files with 2,100 additions and 693 deletions.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http:https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.program.database.map;

import java.io.IOException;

import ghidra.program.database.ProgramDB;
import ghidra.program.model.lang.*;

public class AddressRangeMap32BitTest extends AbstractAddressRangeMapTest {

protected ProgramDB createProgram() throws IOException {
LanguageService service = getLanguageService();
Language language = service.getLanguage(new LanguageID("sparc:BE:32:default"));
return new ProgramDB("test", language, language.getDefaultCompilerSpec(), this);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http:https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.program.database.map;

import java.io.IOException;

import org.junit.Test;

import ghidra.program.database.ProgramDB;
import ghidra.program.model.lang.*;

public class AddressRangeMap64BitTest extends AbstractAddressRangeMapTest {

protected ProgramDB createProgram() throws IOException {
LanguageService service = getLanguageService();
Language language = service.getLanguage(new LanguageID("sparc:BE:64:default"));
return new ProgramDB("test", language, language.getDefaultCompilerSpec(), this);
}

@Test
public void testGetValue64BitSpecific() {
map.paintRange(addr(0), spaceMax, ONE);

checkValueNoCache(ONE, addr(0x0));
checkValueNoCache(ONE, addr(0x0));

// now check addresses that are in different address bases that don't exist yet
// addresses that differ in the upper 32bits are in different address basesI
checkValueNoCache(ONE, addr(0xA0000000000000L));
checkValueNoCache(ONE, addr(0xB0000000000000L));

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import ghidra.program.model.listing.ProgramContext;
import ghidra.program.model.mem.Memory;
import ghidra.test.AbstractGhidraHeadedIntegrationTest;
import ghidra.util.task.TaskMonitor;
import ghidra.util.task.TaskMonitorAdapter;

/**
Expand Down Expand Up @@ -78,7 +79,7 @@ public void testAll() {
int id = program.startTransaction("Test");
try {

Address start = getAddress(0);
Address start = addr(0);
try {
mem.createInitializedBlock("first", start, 100, (byte) 0,
TaskMonitorAdapter.DUMMY_MONITOR, false);
Expand All @@ -91,7 +92,7 @@ public void testAll() {
boolean didSomething = false;

Address startAddress = start;
Address endAddress = getAddress(0x30);
Address endAddress = addr(0x30);

// stick a value into each one!
BigInteger value = BigInteger.valueOf(255);
Expand Down Expand Up @@ -157,8 +158,38 @@ public void testAll() {
}
}

private Address getAddress(long offset) {
return space.getAddress(offset);
@Test
public void testImageBaseChange() throws Exception {
int id = program.startTransaction("Test");
Address start = addr(0x10);
Address end = addr(0x20);

mem.createInitializedBlock("first", addr(0), 0x100, (byte) 0, TaskMonitor.DUMMY, false);

ProgramContext programContext = program.getProgramContext();

Register register = programContext.getRegisters().get(0);
BigInteger value = BigInteger.valueOf(0x11);

programContext.setValue(register, addr(0x10), addr(0x20), value);
assertNull(programContext.getValue(register, start.subtract(1), true));
assertEquals(value, programContext.getValue(register, start, true));
assertEquals(value, programContext.getValue(register, end, true));
assertNull(programContext.getValue(register, end.add(1), true));

long imageOffset = 0x5;
Address imageBase = addr(imageOffset);
program.setImageBase(imageBase, true);

assertNull(programContext.getValue(register, start.add(imageOffset - 1), true));
assertEquals(value, programContext.getValue(register, start.add(imageOffset), true));
assertEquals(value, programContext.getValue(register, end.add(imageOffset), true));
assertNull(programContext.getValue(register, end.add(imageOffset + 1), true));

program.endTransaction(id, false);
}

private Address addr(long offset) {
return space.getAddress(offset);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,6 @@ public class ProgramDB extends DomainObjectAdapterDB implements Program, ChangeM
private int languageMinorVersion;
private LanguageTranslator languageUpgradeTranslator;

private Address storedImageBase; // current image base maintained by addrMap
private boolean imageBaseOverride = false;
private boolean recordChanges;

Expand Down Expand Up @@ -1119,7 +1118,7 @@ private void refreshName() throws IOException {

private void refreshImageBase() throws IOException {
long baseOffset = getStoredBaseImageOffset();
storedImageBase = addressFactory.getDefaultAddressSpace().getAddress(baseOffset);
Address storedImageBase = addressFactory.getDefaultAddressSpace().getAddress(baseOffset);
if (!imageBaseOverride) {
Address currentImageBase = getImageBase();
if (!currentImageBase.equals(storedImageBase)) {
Expand Down Expand Up @@ -1268,7 +1267,6 @@ public void setImageBase(Address base, boolean commit)
if (commit) {
try {
dataMap.put(IMAGE_OFFSET, Long.toHexString(base.getOffset()));
storedImageBase = base;
imageBaseOverride = false;

setChanged(ChangeManager.DOCR_IMAGE_BASE_CHANGED, oldBase, base);
Expand Down Expand Up @@ -1736,9 +1734,7 @@ protected void clearCache(boolean all) {
refreshName();
overlaySpaceAdapter.updateOverlaySpaces(addressFactory);
addrMap.invalidateCache();
if (!imageBaseOverride) {
refreshImageBase();
}
refreshImageBase();
for (int i = 0; i < NUM_MANAGERS; i++) {
managers[i].invalidateCache(all);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,19 @@ public interface AddressMap {
* never be generated. The returned key ranges will correspond
* to those key ranges which have previously been created within
* the specified address range and may represent a much smaller subset
* of addresses within the specified range.
* @param start minimum address of range
* of addresses within the specified range.
* NOTE: if the create parameter is true, the given range must not extend in the upper 32 bits
* by more than 1 segment. For example, range(0x0000000000000000 - 0x0000000100000000)
* is acceptable, but the range (0x0000000000000000 - 0x0000000200000000) is not because the
* upper 32 bits differ by 2.
* @param start the start address of the range
* @param end maximum address of range
* @param create true if a new keys may be generated, otherwise returned
* key-ranges will be limited to those already defined.
* key-ranges will be limited to those already defined. And if true, the range will be limited
* to a size of 2^32 so that at most it creates two new address bases
* @return "sorted" list of KeyRange objects
* @throws UnsupportedOperationException if the given range is so large that the upper 32 bit
* segments differ by more than 1.
*/
public List<KeyRange> getKeyRanges(Address start, Address end, boolean create);

Expand Down Expand Up @@ -136,7 +143,8 @@ public interface AddressMap {
* key-ranges will be limited to those already defined.
* @return "sorted" list of KeyRange objects
*/
public List<KeyRange> getKeyRanges(Address start, Address end, boolean absolute, boolean create);
public List<KeyRange> getKeyRanges(Address start, Address end, boolean absolute,
boolean create);

/**
* Generates a properly ordered list of database key ranges for a
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
*/
package ghidra.program.database.map;

import static generic.util.UnsignedDataUtils.*;

import java.io.IOException;
import java.util.*;

Expand Down Expand Up @@ -811,15 +813,16 @@ private void getKeyRangesForAddressSet(AddressSetView set, boolean absolute, boo
/**
* Create all memory base segments within the specified range.
* NOTE: minAddress and maxAddress must have the same address space!
* @param minAddress
* @param maxAddress
* @param minAddress start address of the range
* @param maxAddress last address of the range
* @param absolute if the address are absolute and not relative
*/
private void createBaseSegments(Address minAddress, Address maxAddress) {
private void createBaseSegments(Address minAddress, Address maxAddress, boolean absolute) {

long minBase;
long maxBase;

if (isInDefaultAddressSpace(minAddress)) {
if (!absolute && isInDefaultAddressSpace(minAddress)) {
minBase = getNormalizedOffset(minAddress) & BASE_MASK;
maxBase = getNormalizedOffset(maxAddress) & BASE_MASK;
}
Expand All @@ -828,25 +831,35 @@ private void createBaseSegments(Address minAddress, Address maxAddress) {
maxBase = maxAddress.getOffset() & BASE_MASK;
}

for (long base = minBase; base <= maxBase; base += (MAX_OFFSET + 1)) {
long numBases = (maxBase >>> 32) - (minBase >>> 32);

if (numBases > 2) {
throw new UnsupportedOperationException("Can't create address bases for a range that" +
"extends across more than two upper 32 bit segments!");
}

for (long base = minBase; unsignedLessThanOrEqual(base, maxBase); base +=
(MAX_OFFSET + 1)) {
getBaseAddressIndex(minAddress.getNewAddress(base), false, INDEX_CREATE);
}
}

/**
* Add simple key ranges where the address range lies within a single base segment for a single space.
* NOTE: start and end addresses must have the same address space!
* @param keyRangeList
* @param start
* @param end
* @param absolute
* @param create
* @param keyRangeList the list to store key ranges into
* @param start the start address
* @param end the end address
* @param absolute true if the address are to be encoded as absolute (not relative to the
* image base
* @param create if true, this method will add new address bases that are required to
* store addresses in that database that have that address base
*/
private void addKeyRanges(List<KeyRange> keyRangeList, Address start, Address end,
boolean absolute, boolean create) {
if (start.isMemoryAddress()) {
if (create) {
createBaseSegments(start, end);
createBaseSegments(start, end, absolute);
}
Address normalizedStart = absolute ? start : getShiftedAddr(start);
Address normalizedEnd = absolute ? end : getShiftedAddr(end);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@
*/
package ghidra.program.database.register;

import java.util.*;

import ghidra.program.model.address.*;
import ghidra.util.exception.CancelledException;
import ghidra.util.task.TaskMonitor;

import java.util.*;

/**
* Associates objects with address ranges.
*/
Expand Down Expand Up @@ -170,7 +170,8 @@ private AddressValueRange<T> adjustPreviousRangeForOverlap(Address start, Addres
T object, AddressValueRange<T> newRange, int pos) {

AddressValueRange<T> previousRange = ranges.get(pos);
if ((start.previous() == null) || (previousRange.getEnd().compareTo(start.previous()) < 0)) {
if ((start.previous() == null) ||
(previousRange.getEnd().compareTo(start.previous()) < 0)) {
return newRange; // no overlap
}

Expand Down Expand Up @@ -469,6 +470,10 @@ public AddressRange getAddressRangeContaining(Address addr) {
}
return new AddressRangeImpl(min, max);
}

public void clearCache() {
lastRange = null;
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,4 +209,9 @@ public void checkWritableState() {
}
}

@Override
public void invalidate() {
rangeMap.invalidate();
}

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
/* ###
* IP: GHIDRA
* REVIEWED: YES
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -143,4 +142,9 @@ public void setLanguage(LanguageTranslator translator, Register mapReg, TaskMoni
}
rangeMap = newRangeMap;
}

@Override
public void invalidate() {
rangeMap.clearCache();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ public void initializeDefaultValues(Language lang, CompilerSpec compilerSpec) {
@Override
public void invalidateCache(boolean all) throws IOException {
this.invalidateReadCache();
invalidateRegisterStores();
}

@Override
Expand Down Expand Up @@ -525,4 +526,12 @@ public RegisterValue getNonDefaultValue(Register register, Address address) {
}
}

private void invalidateRegisterStores() {
for (RegisterValueStore store : registerValueMap.values()) {
store.invalidate();
}
for (RegisterValueStore store : defaultRegisterValueMap.values()) {
store.invalidate();
}
}
}
Loading

0 comments on commit c064355

Please sign in to comment.