GP-0: Moving addExternalBlock() to a more appropriate class

This commit is contained in:
Ryan Kurtz
2026-01-16 05:47:36 -05:00
parent e31df74ca4
commit 91a47135cb
7 changed files with 67 additions and 89 deletions
@@ -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);
@@ -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) {
@@ -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.
* <p>
@@ -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();
@@ -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);
@@ -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);
}
}
@@ -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) {