@Override
	protected void load(ByteProvider provider, LoadSpec loadSpec, List<Option> options,
			Program program, TaskMonitor monitor, MessageLog log)
			throws IOException, CancelledException {

		OmfFileHeader header = null;
		AbstractOmfRecordFactory factory = new OmfRecordFactory(provider);
		try {
			header = OmfFileHeader.parse(factory, monitor, log);
			header.resolveNames();
			header.sortSegmentDataBlocks();
			OmfFileHeader.doLinking(IMAGE_BASE, header.getSegments(), header.getGroups());
		}
		catch (OmfException e) {
			if (header == null) {
				throw new IOException("OMF File header was corrupted. " + e.getMessage());
			}
			log.appendMsg("File was corrupted - leaving partial program " + provider.getName());
		}

		// We don't use the file bytes to create block because the bytes are manipulated before
		// forming the block.  Creating the FileBytes anyway in case later we want access to all
		// the original bytes.
		FileBytes fileBytes = MemoryBlockUtils.createFileBytes(program, provider, monitor);

		try {
			processSegmentHeaders(factory.getReader(), header, program, monitor, log);
			processPublicSymbols(header, program, monitor, log);
			processExternalSymbols(header, program, monitor, log);
			processRelocations(header, program, monitor, log);
			markupRecords(program, fileBytes, header, log, monitor);
		}
		catch (AddressOverflowException e) {
			throw new IOException(e);
		}
	}
OMF usually stores a string describing the compiler that produced it in a
translator comment.  This routine maps this string to official
"secondary constraint" used by the Ghidra opinion service to pick a
language module for the program 
@param record is the translator comment string
@return the "secondary constraint"
Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/OmfLoader.java