private void processPublicSymbols(OmfFileHeader header, Program program, TaskMonitor monitor,
			MessageLog log) {
		SymbolTable symbolTable = program.getSymbolTable();

		List<OmfSymbolRecord> symbols = header.getPublicSymbols();
		List<OmfSegmentHeader> segments = header.getSegments();
		List<OmfGroupRecord> groups = header.getGroups();
		Language language = program.getLanguage();

		monitor.setMessage("Creating Public Symbols");

		for (OmfSymbolRecord symbolrec : symbols) {
			if (monitor.isCancelled()) {
				break;
			}
			Address addrBase = null;
			boolean tagFunction = false;
			if (symbolrec.getSegmentIndex() != 0) {
				// TODO: What does it mean if both the segment and group index are non-zero?
				//     Is the segment index group relative?
				//     For now we assume if a segment index is present, we don't need the group index
				OmfSegmentHeader baseSegment = segments.get(symbolrec.getSegmentIndex() - 1);
				addrBase = baseSegment.getAddress(language);
				tagFunction = baseSegment.isCode();
			}
			else if (symbolrec.getGroupIndex() != 0) {
				OmfGroupRecord baseGroup = groups.get(symbolrec.getGroupIndex() - 1);
				addrBase = baseGroup.getAddress(language);
			}
			else { // Absolute address
					// The base frame is ignored by most linkers
				addrBase = language.getDefaultSpace().getAddress(0);
			}

			int numSymbols = symbolrec.numSymbols();
			for (int i = 0; i < numSymbols; ++i) {
				OmfSymbol symbol = symbolrec.getSymbol(i);
				try {
					Address address = addrBase.add(symbol.getOffset());
					symbol.setAddress(address);

					createSymbol(symbol, address, symbolTable, log);
					if (tagFunction) {
						// Create a dummy function so that EntryPointAnalyzer will disassemble it
						try {
							program.getFunctionManager()
									.createFunction(symbol.getName(), address,
										new AddressSet(address), SourceType.IMPORTED);
						}
						catch (OverlappingFunctionException e) {
							log.appendMsg("Function already exists at address " + address + ": " +
								e.getMessage());
						}
						catch (InvalidInputException e) {
							log.appendMsg("Unable to create function with invalid name " +
								symbol.getName() + ": " + e.getMessage());
						}
					}
				}
				catch (AddressOutOfBoundsException e) {
					log.appendMsg(
						"Unable to create symbol " + symbol.getName() + ": " + e.getMessage());
				}
			}
		}
	}
Process any public symbol records and produce corresponding Ghidra symbols
@param header is the file header for the program
@param program is the Program
@param monitor is checked for cancellations
@param log receives any error messages
Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/OmfLoader.java