diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/MemoryBlockUtils.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/MemoryBlockUtils.java index 2506204254..8d0f0c0ad0 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/MemoryBlockUtils.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/MemoryBlockUtils.java @@ -4,9 +4,9 @@ * 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://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. @@ -355,6 +355,64 @@ public class MemoryBlockUtils { } } + /** + * Gets the next available {@link Address} in the {@link Program} + * + * @param program The {@link Program} + * @return The next available {@link Address} in the {@link Program} + */ + public static Address getNextAvailableAddress(Program program) { + Address maxAddress = null; + for (MemoryBlock block : program.getMemory().getBlocks()) { + if (block.isOverlay()) { + continue; + } + if (maxAddress == null || block.getEnd().compareTo(maxAddress) > 0) { + maxAddress = block.getEnd(); + } + } + if (maxAddress == null) { + return program.getAddressFactory().getDefaultAddressSpace().getAddress(0x1000); + } + long maxAddr = maxAddress.getOffset(); + long remainder = maxAddr % 0x1000; + return maxAddress.getNewAddress(maxAddr + 0x1000 - remainder); + } + + /** + * Adds the {@link MemoryBlock#EXTERNAL_BLOCK_NAME EXTERNAL block} to memory at the + * {@link #getNextAvailableAddress(Program) next available address}, or adds to an + * existing one + * + * @param program The {@link Program} + * @param size The desired size of the new EXTERNAL block + * @param log The {@link MessageLog} + * @return The {@link Address} of the new (or new piece) of EXTERNAL block + * @throws Exception if there was an issue creating or adding to the EXTERNAL block + */ + public static Address addExternalBlock(Program program, long size, MessageLog log) + throws Exception { + Memory mem = program.getMemory(); + MemoryBlock externalBlock = mem.getBlock(MemoryBlock.EXTERNAL_BLOCK_NAME); + Address ret; + if (externalBlock != null) { + ret = externalBlock.getEnd().add(1); + MemoryBlock newBlock = + mem.createBlock(externalBlock, MemoryBlock.EXTERNAL_BLOCK_NAME, ret, size); + mem.join(externalBlock, newBlock); + } + else { + ret = getNextAvailableAddress(program); + externalBlock = + mem.createUninitializedBlock(MemoryBlock.EXTERNAL_BLOCK_NAME, ret, size, false); + externalBlock.setWrite(true); + externalBlock.setArtificial(true); + externalBlock.setComment( + "NOTE: This block is artificial and is used to make relocations work correctly"); + } + return ret; + } + private static void setBlockAttributes(MemoryBlock block, String comment, String source, boolean r, boolean w, boolean x) { block.setComment(comment); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/chained/DyldChainedFixups.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/chained/DyldChainedFixups.java index 685d816a6b..e10438c036 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/chained/DyldChainedFixups.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/chained/DyldChainedFixups.java @@ -19,12 +19,12 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; +import ghidra.app.util.MemoryBlockUtils; import ghidra.app.util.bin.BinaryReader; import ghidra.app.util.bin.format.macho.dyld.DyldChainedPtr; import ghidra.app.util.bin.format.macho.dyld.DyldChainedPtr.DyldChainType; import ghidra.app.util.bin.format.macho.dyld.DyldFixup; import ghidra.app.util.importer.MessageLog; -import ghidra.app.util.opinion.AbstractProgramLoader; import ghidra.app.util.opinion.MachoProgramBuilder; import ghidra.program.model.address.Address; import ghidra.program.model.listing.*; @@ -153,7 +153,7 @@ public class DyldChainedFixups { .mapToLong(DyldFixup::size) .sum(); if (externalSize > 0) { - extAddr = AbstractProgramLoader.addExternalBlock(program, externalSize, log); + extAddr = MemoryBlockUtils.addExternalBlock(program, externalSize, log); } } catch (Exception e) { diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/AbstractProgramLoader.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/AbstractProgramLoader.java index 0a3429487b..0d27a656ee 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/AbstractProgramLoader.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/AbstractProgramLoader.java @@ -421,39 +421,6 @@ public abstract class AbstractProgramLoader implements Loader { } } - /** - * Adds the {@link MemoryBlock#EXTERNAL_BLOCK_NAME EXERNAL block} to memory, or adds to an - * existing one - * - * @param program The {@link Program} - * @param size The desired size of the new EXTERNAL block - * @param log The {@link MessageLog} - * @return The {@link Address} of the new (or new piece) of EXTERNAL block - * @throws Exception if there was an issue creating or adding to the EXTERNAL block - */ - public static Address addExternalBlock(Program program, long size, MessageLog log) - throws Exception { - Memory mem = program.getMemory(); - MemoryBlock externalBlock = mem.getBlock(MemoryBlock.EXTERNAL_BLOCK_NAME); - Address ret; - if (externalBlock != null) { - ret = externalBlock.getEnd().add(1); - MemoryBlock newBlock = - mem.createBlock(externalBlock, MemoryBlock.EXTERNAL_BLOCK_NAME, ret, size); - mem.join(externalBlock, newBlock); - } - else { - ret = MachoProgramUtils.getNextAvailableAddress(program); - externalBlock = - mem.createUninitializedBlock(MemoryBlock.EXTERNAL_BLOCK_NAME, ret, size, false); - externalBlock.setWrite(true); - externalBlock.setArtificial(true); - externalBlock.setComment( - "NOTE: This block is artificial and is used to make relocations work correctly"); - } - return ret; - } - /** * Gets the {@link Loader}'s language service. *

diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/MachoLoader.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/MachoLoader.java index c0c235403f..64d0e82715 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/MachoLoader.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/MachoLoader.java @@ -639,8 +639,8 @@ public class MachoLoader extends AbstractLibrarySupportLoader { .map(lib.getSymbolTable()::getPrimarySymbol) .filter(Objects::nonNull) .toList(); - Address addr = AbstractProgramLoader.addExternalBlock(program, - reexportedSymbols.size() * 8, log); + Address addr = + MemoryBlockUtils.addExternalBlock(program, reexportedSymbols.size() * 8, log); monitor.initialize(reexportedSymbols.size(), "Reexporting symbols..."); for (Symbol symbol : reexportedSymbols) { monitor.increment(); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/MachoProgramBuilder.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/MachoProgramBuilder.java index 9cf7c808c0..06fb8e573f 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/MachoProgramBuilder.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/MachoProgramBuilder.java @@ -732,7 +732,7 @@ public class MachoProgramBuilder { return; } try { - Address addr = AbstractProgramLoader.addExternalBlock(program, + Address addr = MemoryBlockUtils.addExternalBlock(program, undefinedSymbols.size() * machoHeader.getAddressSize(), log); monitor.initialize(undefinedSymbols.size(), "Processing undefined symbols..."); for (NList symbol : undefinedSymbols) { @@ -780,7 +780,7 @@ public class MachoProgramBuilder { if (absoluteSymbols.size() == 0) { return; } - Address start = MachoProgramUtils.getNextAvailableAddress(program); + Address start = MemoryBlockUtils.getNextAvailableAddress(program); try { memory.createUninitializedBlock("ABSOLUTE", start, absoluteSymbols.size() * machoHeader.getAddressSize(), false); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/MachoProgramUtils.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/MachoProgramUtils.java deleted file mode 100644 index 6ab579c7cc..0000000000 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/MachoProgramUtils.java +++ /dev/null @@ -1,47 +0,0 @@ -/* ### - * 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://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.app.util.opinion; - -import ghidra.program.model.address.Address; -import ghidra.program.model.listing.Program; -import ghidra.program.model.mem.MemoryBlock; - -public class MachoProgramUtils { - - /** - * Gets the next available {@link Address} in the {@link Program} - * - * @param program The {@link Program} - * @return The next available {@link Address} in the {@link Program} - */ - public static Address getNextAvailableAddress(Program program) { - Address maxAddress = null; - for (MemoryBlock block : program.getMemory().getBlocks()) { - if (block.isOverlay()) { - continue; - } - if (maxAddress == null || block.getEnd().compareTo(maxAddress) > 0) { - maxAddress = block.getEnd(); - } - } - if (maxAddress == null) { - return program.getAddressFactory().getDefaultAddressSpace().getAddress(0x1000); - } - long maxAddr = maxAddress.getOffset(); - long remainder = maxAddr % 0x1000; - return maxAddress.getNewAddress(maxAddr + 0x1000 - remainder); - } -} diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/PeLoader.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/PeLoader.java index 0e956f782b..462324e651 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/PeLoader.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/PeLoader.java @@ -553,7 +553,7 @@ public class PeLoader extends AbstractPeDebugLoader { long forwardedCount = Arrays.stream(exports).filter(ExportInfo::isForwarded).count(); if (forwardedCount > 0) { try { - extAddr = AbstractProgramLoader.addExternalBlock(program, + extAddr = MemoryBlockUtils.addExternalBlock(program, forwardedCount * program.getDefaultPointerSize(), log); } catch (Exception e) {