Java Code Examples for ghidra.util.task.TaskMonitor#setMessage()

The following examples show how to use ghidra.util.task.TaskMonitor#setMessage() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: DyldCacheHeader.java    From ghidra with Apache License 2.0 6 votes vote down vote up
private void parseMappingInfo(MessageLog log, TaskMonitor monitor) throws CancelledException {
	monitor.setMessage("Parsing DYLD mapping info...");
	monitor.initialize(mappingCount);
	try {
		reader.setPointerIndex(mappingOffset);
		for (int i = 0; i < mappingCount; ++i) {
			mappingInfoList.add(new DyldCacheMappingInfo(reader));
			monitor.checkCanceled();
			monitor.incrementProgress(1);
		}
	}
	catch (IOException e) {
		log.appendMsg(DyldCacheHeader.class.getSimpleName(),
			"Failed to parse dyld_cache_mapping_info.");
	}
}
 
Example 2
Source File: ElfProgramBuilder.java    From ghidra with Apache License 2.0 6 votes vote down vote up
/**
 * Adjust GNU read-only segments following relocations (PT_GNU_RELRO).
 */
private void processGNU_readOnly(TaskMonitor monitor) {

	// Set read-only segments
	if (elf.e_shentsize() != 0) {
		return;
	}

	monitor.setMessage("Processing GNU Definitions");
	for (ElfProgramHeader roSegment : elf.getProgramHeaders(
		ElfProgramHeaderConstants.PT_GNU_RELRO)) {
		ElfProgramHeader loadedSegment =
			elf.getProgramLoadHeaderContaining(roSegment.getVirtualAddress());
		if (loadedSegment != null) {
			for (AddressRange blockRange : getResolvedLoadAddresses(loadedSegment)) {
				MemoryBlock block = memory.getBlock(blockRange.getMinAddress());
				if (block != null) {
					log("Setting block " + block.getName() +
						" to read-only based upon PT_GNU_RELRO data");
					block.setWrite(false);
				}
			}
		}
	}
}
 
Example 3
Source File: AnalysisScheduler.java    From ghidra with Apache License 2.0 6 votes vote down vote up
public boolean runAnalyzer(Program program, TaskMonitor monitor, MessageLog log)
		throws CancelledException {
	AddressSetView saveAddSet;
	AddressSetView saveRemoveSet;

	synchronized (this) {
		saveAddSet = getAddedAddressSet();
		saveRemoveSet = getRemovedAddressSet();
		scheduled = false;
	}

	monitor.setMessage(analyzer.getName());
	monitor.setProgress(0);
	boolean result = false;
	if (!saveAddSet.isEmpty()) {
		result |= analyzer.added(program, saveAddSet, monitor, log);
	}

	if (!saveRemoveSet.isEmpty()) {
		result |= analyzer.removed(program, saveRemoveSet, monitor, log);
	}

	return result;
}
 
Example 4
Source File: ClearCmd.java    From ghidra with Apache License 2.0 6 votes vote down vote up
private void clearComments(Program program, AddressSetView clearView, TaskMonitor monitor)
		throws CancelledException {

	monitor.initialize(clearView.getNumAddresses());
	monitor.setMessage("Starting to clear comments...");

	Listing listing = program.getListing();
	AddressRangeIterator iter = clearView.getAddressRanges();
	int progress = 0;
	while (iter.hasNext()) {

		monitor.checkCanceled();
		AddressRange range = iter.next();
		listing.clearComments(range.getMinAddress(), range.getMaxAddress());
		progress += range.getLength();
		monitor.setProgress(progress);
	}
}
 
Example 5
Source File: SymbolDatabaseAdapterV0.java    From ghidra with Apache License 2.0 6 votes vote down vote up
long extractLocalSymbols(DBHandle handle, TaskMonitor monitor) throws IOException,
		CancelledException {

	monitor.setMessage("Extracting Local and Dynamic Symbols...");
	monitor.initialize(symbolTable.getRecordCount());
	int cnt = 0;
	RecordIterator iter = symbolTable.iterator();
	while (iter.hasNext()) {
		monitor.checkCanceled();
		Record rec = iter.next();
		if (rec.getBooleanValue(V0_SYMBOL_LOCAL_COL)) {
			SymbolManager.saveLocalSymbol(handle, rec.getKey(),
				rec.getLongValue(V0_SYMBOL_ADDR_COL), rec.getString(V0_SYMBOL_NAME_COL),
				rec.getBooleanValue(V0_SYMBOL_PRIMARY_COL));
		}
		monitor.setProgress(++cnt);
	}
	return symbolTable.getKey();
}
 
Example 6
Source File: CodeManager.java    From ghidra with Apache License 2.0 6 votes vote down vote up
/**
 * Returns the next undefined data whose min address is greater
 * than the specified address.
 *
 * @param addr the address to look after
 *
 * @return Data the undefined data after the specified address,
 *                  or null if a undefined data does not exist
 */
public Data getFirstUndefinedDataAfter(Address addr, TaskMonitor monitor) {
	if (!addr.isMemoryAddress() || addr.equals(addr.getAddressSpace().getMaxAddress())) {
		return null;
	}
	Memory mem = program.getMemory();
	AddressSetView set =
		mem.intersectRange(addr.next(), addr.getAddressSpace().getMaxAddress());

	int i = 0;
	CodeUnitIterator it = getCodeUnits(set, true);
	while (it.hasNext()) {
		CodeUnit cu = it.next();
		if (cu instanceof Data && !((Data) cu).isDefined()) {
			return (Data) cu;
		}
		if (++i % 1000 == 0) {
			monitor.setMessage("Searching address " + cu.getMinAddress());
		}
	}
	return null;
}
 
Example 7
Source File: ElfProgramBuilder.java    From ghidra with Apache License 2.0 5 votes vote down vote up
private void processStringTables(TaskMonitor monitor) throws CancelledException {
		monitor.setMessage("Processing string tables...");

		for (ElfStringTable stringTable : elf.getStringTables()) {

			monitor.checkCanceled();

			Address stringTableAddr = null;

			ElfSectionHeader section = stringTable.getTableSectionHeader();
			if (section != null) {
				stringTableAddr = findLoadAddress(section, 0);
			}
			else {
				stringTableAddr = findLoadAddress(stringTable.getFileOffset(), 1);
			}
			if (stringTableAddr == null) {
//				log("Failed to locate string table at file offset 0x" +
//					Long.toHexString(stringTable.getFileOffset()));
				continue;
			}

			AddressRange rangeConstraint = getMarkupMemoryRangeConstraint(stringTableAddr);
			if (rangeConstraint == null) {
				continue;
			}

			long limit = Math.min(stringTable.getLength(), rangeConstraint.getLength());

			markupStringTable(stringTableAddr, limit, monitor);
		}
	}
 
Example 8
Source File: Img3FileSystem.java    From ghidra with Apache License 2.0 5 votes vote down vote up
@Override
public void open(TaskMonitor monitor) throws IOException {
	monitor.setMessage("Opening IMG3...");

	this.header = new Img3(provider);

	if (!header.getMagic().equals(Img3Constants.IMG3_SIGNATURE)) {
		throw new IOException("Unable to decrypt file: invalid IMG3 file!");
	}

	List<DataTag> tags = header.getTags(DataTag.class);

	monitor.initialize(tags.size());

	for (int i = 0; i < tags.size(); ++i) {
		if (monitor.isCancelled()) {
			break;
		}
		monitor.setProgress(i);

		DataTag dataTag = tags.get(i);
		String filename = getDataTagFilename(dataTag, i, tags.size() > 1);
		GFileImpl dataFile = GFileImpl.fromPathString(this, root, filename, null, false,
			dataTag.getTotalLength());
		dataFileList.add(dataFile);
	}
}
 
Example 9
Source File: AndroidProjectCreator.java    From ghidra with Apache License 2.0 5 votes vote down vote up
private static File copyFile(ResourceFile inputFile, File outputDirectory, String outputName,
		TaskMonitor monitor) throws IOException {

	try (InputStream is = inputFile.getInputStream()) {
		FileUtilities.checkedMkdirs(outputDirectory);
		File destFile = new File(outputDirectory, outputName);

		monitor.setMessage("Copying [" + inputFile.getName() + "] to Eclipse project...");
		FileUtilities.copyStreamToFile(is, destFile, false, monitor);

		return destFile;
	}
}
 
Example 10
Source File: ExternalProgramMerger.java    From ghidra with Apache License 2.0 5 votes vote down vote up
public void autoMerge(TaskMonitor monitor) throws CancelledException {
	monitor.setMessage("Auto-merging External Program Names and determining conflicts.");
	if (monitor.isCancelled()) {
		throw new CancelledException();
	}

	if (mergeManager != null) {
		latestResolvedSymbols = (LongLongHashtable) mergeManager
			.getResolveInformation(MergeConstants.RESOLVED_LATEST_SYMBOLS);
		myResolvedSymbols = (LongLongHashtable) mergeManager
			.getResolveInformation(MergeConstants.RESOLVED_MY_SYMBOLS);
		originalResolvedSymbols = (LongLongHashtable) mergeManager
			.getResolveInformation(MergeConstants.RESOLVED_ORIGINAL_SYMBOLS);

		// Populate the reverse maps.
		mapResultsToOriginalLibs();
		mapResultsToLatestLibs();
		mapResultsToMyLibs();
	}

	// Determine the symbol ID group for each external program (Library) to possibly merge.
	List<IDGroup> idGroups = new ArrayList<>();
	idGroups.addAll(getGroupsForOriginalLibs());
	idGroups.addAll(getGroupsForLatestNewLibs());
	idGroups.addAll(getGroupsForMyNewLibs());

	// Process each Library symbol ID group and determine any conflicts.
	int resolveCount = 0;
	int maximum = idGroups.size();
	monitor.initialize(maximum);
	for (IDGroup idGroup : idGroups) {
		int progress = (int) (((float) (resolveCount / maximum)) * 100);
		autoMergeNamedExternalProgram(idGroup, progress);
		monitor.setProgress(++resolveCount);
	}
}
 
Example 11
Source File: DexHeaderFormatAnalyzer.java    From ghidra with Apache License 2.0 5 votes vote down vote up
private void createInitialFragments(Program program, DexHeader header, TaskMonitor monitor)
		throws Exception {
	monitor.setMessage("DEX: creating fragments");

	if (header.getDataSize() > 0) {
		Address start = toAddr(program, header.getDataOffset());
		Address end = start.add(header.getDataSize());
		createFragment(program, "data", start, end);
	}
}
 
Example 12
Source File: OmfArchiveFileSystem.java    From ghidra with Apache License 2.0 5 votes vote down vote up
public void mount(TaskMonitor monitor) throws IOException {
	monitor.setMessage("Opening OMF archive...");
	BinaryReader reader = OmfFileHeader.createReader(provider);
	OmfLibraryRecord libraryRec = OmfLibraryRecord.parse(reader, monitor);
	ArrayList<OmfLibraryRecord.MemberHeader> memberHeaders = libraryRec.getMemberHeaders();
	for (OmfLibraryRecord.MemberHeader member : memberHeaders) {
		String name = member.name;
		monitor.setMessage(name);
		fsih.storeFile(name, fsih.getFileCount(), false, member.size, member);
	}
}
 
Example 13
Source File: ClearCmd.java    From ghidra with Apache License 2.0 5 votes vote down vote up
private void clearReferences(Program program, AddressSetView clearView,
		Set<SourceType> sourceTypesToClear, TaskMonitor monitor) throws CancelledException {

	if (clearView.isEmpty()) {
		return;
	}

	monitor.initialize(clearView.getNumAddresses());
	monitor.setMessage("Clearing references...");

	ReferenceManager refMgr = program.getReferenceManager();
	AddressIterator it = refMgr.getReferenceSourceIterator(clearView, true);
	removeRefs(refMgr, it, sourceTypesToClear, monitor);
}
 
Example 14
Source File: CParserPlugin.java    From ghidra with Apache License 2.0 5 votes vote down vote up
private void parseFile(String filename, TaskMonitor monitor, PreProcessor cpp) {
	monitor.setMessage("PreProcessing " + filename);
	try {
		Msg.info(this, "parse " + filename);
		cpp.parse(filename);
	}
	catch (Throwable e) {
		Msg.error(this, "Parsing file :" + filename);
		Msg.error(this, "Unexpected Exception: " + e.getMessage(), e);
	}
}
 
Example 15
Source File: ISO9660Analyzer.java    From ghidra with Apache License 2.0 4 votes vote down vote up
@Override
public boolean added(Program program, AddressSetView set, TaskMonitor monitor, MessageLog log)
		throws CancelledException {

	ByteProvider provider = new MemoryByteProvider(program.getMemory(),
		program.getAddressFactory().getDefaultAddressSpace());
	BinaryReader reader = new BinaryReader(provider, true);
	try {

		Offset signatureOffset = checkSignatures(program);
		setPointerOffset(signatureOffset, reader);

		monitor.setMessage("Processing ISO9660 Header");

		//Get the full header (contains all volume descriptors)
		ISO9660Header isoHeader = new ISO9660Header(reader);

		//Get the list of volumes from the header
		List<ISO9660BaseVolume> volumes = isoHeader.getVolumeDescriptorSet();

		//Set the overall plate comment at the top of this file
		setPlateComment(program, toAddress(program, 0), isoHeader.toString());

		//Create a new module for the volume descriptor fragments
		ProgramModule descriptorModule =
			program.getListing().getDefaultRootModule().createModule("Volume Descriptors");

		//For each volume, set the volumes plate comment and data at the address it exists
		setDescriptorData(program, volumes, descriptorModule);

		processPathTables(isoHeader, reader, program);

		//Create an alignment over the null characters from start to the first volume
		int offset = getOffsetValue(signatureOffset);
		program.getListing().createData(toAddress(program, 0), new AlignmentDataType(),
			offset - 1);

		ISO9660VolumeDescriptor pvd = isoHeader.getPrimaryVolumeDescriptor();
		ISO9660Directory entryDir = isoHeader.getPrimaryDirectory();

		int logicalBlockSize = pvd.getLogicalBlockSizeLE();

		List<ISO9660Directory> dirList =
			createDirectoryList(reader, entryDir, logicalBlockSize);

		createDirectories(reader, program, dirList, logicalBlockSize);

	}
	catch (Exception e) {
		log.appendException(e);
		return false;
	}
	return true;

}
 
Example 16
Source File: MemoryMapDBAdapter.java    From ghidra with Apache License 2.0 4 votes vote down vote up
static MemoryMapDBAdapter upgrade(DBHandle handle, MemoryMapDBAdapter oldAdapter,
		MemoryMapDB memMap, TaskMonitor monitor) throws VersionException, IOException {

	try {
		monitor.setMessage("Upgrading Memory Blocks...");
		List<MemoryBlockDB> blocks = oldAdapter.getMemoryBlocks();
		oldAdapter.deleteTable(handle);

		monitor.initialize(blocks.size() * 2);

		MemoryMapDBAdapter newAdapter =
			new MemoryMapDBAdapterV3(handle, memMap, Memory.GBYTE, true);
		for (MemoryBlockDB block : blocks) {
			MemoryBlock newBlock = null;
			if (block.isInitialized()) {
				DBBuffer buf = block.getBuffer();
				newBlock = newAdapter.createInitializedBlock(block.getName(), block.getStart(),
					buf, block.getPermissions());
			}
			else {
				Address mappedAddress = null;

				if (block.isMapped()) {
					MemoryBlockSourceInfo info = block.getSourceInfos().get(0);
					mappedAddress = info.getMappedRange().get().getMinAddress();
				}
				newBlock =
					newAdapter.createBlock(block.getType(), block.getName(), block.getStart(),
						block.getSize(), mappedAddress, false, block.getPermissions(), 0);
			}
			newBlock.setComment(block.getComment());
			newBlock.setSourceName(block.getSourceName());
		}
		newAdapter.refreshMemory();
		return newAdapter;
	}
	catch (AddressOverflowException e) {
		// This should not occur
		throw new AssertException(e);
	}
}
 
Example 17
Source File: ASTGraphTask.java    From ghidra with Apache License 2.0 4 votes vote down vote up
@Override
public void run(TaskMonitor monitor) {

	// get a new graph
	AttributedGraph graph = new AttributedGraph();

	try {
		monitor.setMessage("Computing Graph...");
		if (graphType == GraphType.DATA_FLOW_GRAPH) {
			createDataFlowGraph(graph, monitor);
		}
		else {
			createControlFlowGraph(graph, monitor);
		}
		GraphDisplay display = graphService.getDefaultGraphDisplay(!newGraph, monitor);
		ASTGraphDisplayListener displayListener =
			new ASTGraphDisplayListener(tool, display, hfunction, graphType);
		display.setGraphDisplayListener(displayListener);

		monitor.setMessage("Obtaining handle to graph provider...");
		if (monitor.isCancelled()) {
			return;
		}
		monitor.setCancelEnabled(false);

		monitor.setMessage("Rendering Graph...");
		display.defineVertexAttribute(CODE_ATTRIBUTE);
		display.defineVertexAttribute(SYMBOLS_ATTRIBUTE);

		display.setVertexLabel(CODE_ATTRIBUTE, GraphDisplay.ALIGN_LEFT, 12, true,
			graphType == GraphType.CONTROL_FLOW_GRAPH ? (codeLimitPerBlock + 1) : 1);

		String description =
			graphType == GraphType.DATA_FLOW_GRAPH ? "AST Data Flow" : "AST Control Flow";
		display.setGraph(graph, description, false, monitor);
		// set the graph location
		if (location != null) {
			display.setLocation(displayListener.getVertexIdForAddress(location));
		}

	}
	catch (GraphException e) {
		Msg.showError(this, null, "Graph Error", e.getMessage());
	}
	catch (CancelledException e1) {
		return;
	}

}
 
Example 18
Source File: LocalManagedBufferFile.java    From ghidra with Apache License 2.0 4 votes vote down vote up
/**
 * Create a new buffer file version (used for check-in) 
 * @param destFile must be an versioned file representing an earlier version
 * of srcFile.
 * @param fileComment a comment for the new version.
 * @param monitor the current monitor.
 * @throws CancelledException if the operation is canceled.
 * @throws IOException if the file is in an unexpected state.
 */
public void createNewVersion(ManagedBufferFile destFile, String fileComment,
		TaskMonitor monitor) throws CancelledException, IOException {

	if (monitor != null) {
		monitor.checkCanceled();
		monitor.setMessage("Opening versioned file for update...");
		monitor.setProgress(0);
	}
	ManagedBufferFile outFile = destFile.getSaveFile();
	if (outFile == null) {
		throw new IOException("File update not permitted");
	}

	boolean success = false;
	BufferFile newChangeFile = null;
	BufferFile changeDataFile = null;
	try {
		if (monitor != null) {
			monitor.checkCanceled();
			monitor.setMessage("Creating new file version...");
		}
		outFile.setVersionComment(fileComment);

		changeDataFile = getNextChangeDataFile(true);
		if (changeDataFile == null) {
			throw new IOException("Unexpected state for check-in file");
		}

		BufferFile nextChangeDataFile = getNextChangeDataFile(false);
		if (nextChangeDataFile != null) {
			nextChangeDataFile.dispose();
			throw new IOException("Unexpected state for check-in file");
		}

		// Create new version
		ChangeMap newChangeMap = new ChangeMap(getForwardModMapData());
		copyFile(this, outFile, newChangeMap, monitor);

		// Copy change data
		newChangeFile = destFile.getSaveChangeDataFile();
		copyFile(changeDataFile, newChangeFile, null, monitor);

		newChangeFile.close(); // commit and close newChangeFile
		newChangeFile = null;  // null indicates closed state

		success = true;
	}
	finally {
		if (changeDataFile != null) {
			changeDataFile.dispose();
		}
		if (newChangeFile != null) {
			newChangeFile.dispose();
		}
		try {
			destFile.saveCompleted(success);
		}
		finally {
			outFile.dispose();
		}
	}
}
 
Example 19
Source File: CoffLoader.java    From ghidra with Apache License 2.0 4 votes vote down vote up
private void processSectionHeaders(ByteProvider provider, CoffFileHeader header,
		Program program, FileBytes fileBytes, TaskMonitor monitor, MessageLog log,
		Map<CoffSectionHeader, Address> map, boolean performFakeLinking)
		throws AddressOverflowException, IOException {

	monitor.setMessage("Process sections...");

	final Language language = program.getLanguage();

	List<CoffSectionHeader> sections = header.getSections();

	if (performFakeLinking) {
		possiblyRelocateSections(program, header, map);
	}

	int sectionNumber = 0;
	for (CoffSectionHeader section : sections) {
		++sectionNumber;
		if (monitor.isCancelled()) {
			break;
		}

		MemoryBlock block = null;

		final int sectionSize = section.getSize(language);

		Address sectionAddr = section.getPhysicalAddress(language);

		if (sectionSize == 0 || section.getFlags() == 0) {
			log.appendMsg("Empty Section, Created Symbol: " + section.getName());
			// don't create a block, but record the section to get at the address!
			block = program.getMemory().getBlock(sectionAddr);
			try {
				program.getSymbolTable().createLabel(sectionAddr, section.getName(),
					SourceType.IMPORTED);
				// TODO: sectionSize somewhere for case where flags==0 ?
			}
			catch (InvalidInputException e) {
				// unexpected
			}
		}
		else if (!section.isAllocated()) {
			block = createInitializedBlock(provider, program, fileBytes, monitor, log, language,
				sectionNumber, section, sectionSize, sectionAddr, true);
			if (block != null) {
				log.appendMsg("Created Overlay Block: " + section + " @ " + sectionAddr);
			}
		}
		else if (section.isUninitializedData()) {
			block = MemoryBlockUtils.createUninitializedBlock(program, false, section.getName(),
				sectionAddr, sectionSize,
				"PhysAddr:0x" + Integer.toHexString(section.getPhysicalAddress()) + " " +
					"Size:0x" + Integer.toHexString(sectionSize) + " " + "Flags:0x" +
					Integer.toHexString(section.getFlags()),
				null/*source*/, section.isReadable(), section.isWritable(),
				section.isExecutable(), log);
			if (block != null) {
				log.appendMsg("Created Uninitialized Block: " + section + " @ " + sectionAddr);
			}
		}
		else {
			block = createInitializedBlock(provider, program, fileBytes, monitor, log, language,
				sectionNumber, section, sectionSize, sectionAddr, false);
			if (block != null) {
				log.appendMsg("Created Initialized Block: " + section + " @ " + sectionAddr);
			}
		}

		if (block != null) {
			sectionAddr = block.getStart();
		}
		map.put(section, sectionAddr);
	}
}
 
Example 20
Source File: ProgramMerge.java    From ghidra with Apache License 2.0 4 votes vote down vote up
/**
 * <CODE>mergeCommentType</CODE> merges/replaces comments of the indicated
 * type wherever they occur in the specified address set.
 * It merges them from program2 into program1.
 * This merges eol, pre, post, repeatable, and plate comments.
 *
 * @param originAddressSet the addresses to be merged.
 * The addresses in this set should be derived from the origin program.
 * @param type the comment type. PLATE, PRE, EOL, REPEATABLE, POST
 * @param setting how to merge. IGNORE, REPLACE, MERGE
 * @param monitor the task monitor for notifying the user of this merge's progress.
 * @throws CancelledException if user cancels via the monitor.
 */
public void mergeCommentType(AddressSetView originAddressSet, int type, int setting,
		TaskMonitor monitor) throws CancelledException {
	if ((setting != ProgramMergeFilter.REPLACE) && (setting != ProgramMergeFilter.MERGE)) {
		return;
	}

	String typeStr = "Unknown";
	int cuCommentType;
	switch (type) {
		case ProgramMergeFilter.PLATE_COMMENTS:
			typeStr = "Plate";
			cuCommentType = CodeUnit.PLATE_COMMENT;
			break;
		case ProgramMergeFilter.PRE_COMMENTS:
			typeStr = "Pre";
			cuCommentType = CodeUnit.PRE_COMMENT;
			break;
		case ProgramMergeFilter.EOL_COMMENTS:
			typeStr = "EOL";
			cuCommentType = CodeUnit.EOL_COMMENT;
			break;
		case ProgramMergeFilter.REPEATABLE_COMMENTS:
			typeStr = "Repeatable";
			cuCommentType = CodeUnit.REPEATABLE_COMMENT;
			break;
		case ProgramMergeFilter.POST_COMMENTS:
			typeStr = "Post";
			cuCommentType = CodeUnit.POST_COMMENT;
			break;
		default:
			throw new AssertException("Unrecognized comment type: " + type);
	}

	monitor.setMessage("Applying " + typeStr + " comments...");
	if (originAddressSet.isEmpty()) {
		return;
	}

	monitor.checkCanceled();

	boolean both = (setting == ProgramMergeFilter.MERGE) ? true : false;
	String prefix = both ? "Merging" : "Replacing";
	AddressIterator addrIter = originAddressSet.getAddresses(true);
	for (long count = 0; addrIter.hasNext(); count++) {
		monitor.checkCanceled();
		Address originAddress = addrIter.next();
		if (count == PROGRESS_COUNTER_GRANULARITY) {
			monitor.setMessage(
				prefix + " " + typeStr + " comments...   " + originAddress.toString(true));
			count = 0;
		}
		// Determine where to get the Comments from.
		if (both) {
			mergeComments(cuCommentType, originAddress);
		}
		else {
			replaceComment(cuCommentType, originAddress);
		}
	}
}