mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-05-23 13:16:48 +08:00
GP-0: Moving addExternalBlock() to a more appropriate class
This commit is contained in:
@@ -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);
|
||||
|
||||
+2
-2
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user