private int markupDataSegmentStructs(TaskMonitor monitor)
			throws IOException, CancelledException {

		AddressSet structDataRange = new AddressSet(goBinary.getStringStructRange());
		structDataRange.delete(markupSession.getMarkedupAddresses());

		AddressSet stringDataRange = new AddressSet(goBinary.getStringDataRange());

		long initAddrCount = structDataRange.getNumAddresses();
		monitor.initialize(initAddrCount,
			"Searching for Golang strings & structures in data segments");

		int stringCount = 0;
		int sliceCount = 0;

		int align = goBinary.getPtrSize(); // TODO: hack
		while (alignStartOfSet(structDataRange, align)) {
			monitor.setProgress(initAddrCount - structDataRange.getNumAddresses());
			monitor.checkCancelled();

			Address addr = structDataRange.getMinAddress();
			structDataRange.deleteFromMin(addr);

			Object newObj = tryCreateStruct(stringDataRange, addr);
			if (newObj != null) {
				structDataRange.deleteFromMin(goBinary.getMaxAddressOfStructure(newObj));
				stringCount += newObj instanceof GoString ? 1 : 0;
				sliceCount += newObj instanceof GoSlice ? 1 : 0;
				monitor.setMessage("Searching for Golang strings & slices in data segments: %d+%d"
						.formatted(stringCount, sliceCount));
			}
			else {
				Data data = goBinary.getProgram().getListing().getDataContaining(addr);
				if (data != null) {
					structDataRange.deleteFromMin(data.getMaxAddress());
				}
			}
		}

		return stringCount;
	}
Analyzer that finds Golang strings (and optionally slices) and marks up the found instances.
<p>
The char[] data for Golang strings does not contain null terminators, so the normal logic already
built into Ghidra to find terminated strings doesn't work.
<p>
This implementation looks for data that matches what a Golang string 
struct { char* data, long len } would look like, and follows the pointer to the char[] data 
and creates a fixed-length string at that location using the length info from the struct.
<p>
The string struct is found in a couple of different ways:
<ul>
	<li>References from an instruction (see markupStaticStructRefsInFunction)</li>
 <li>Iterating through data segments and making educated guesses (see markupDataSegmentStructs)</li>
</ul>
Some char[] data is only referenced from Golang string structs that exist temporarily
in registers after being set by an instruction that statically references the char[] data,
and an instruction that statically contains the length. (see tryCreateInlineString) 
<p>
Because slice structures can look like string structs, possible string struct locations are also
examined for slice-ness.  When marking a struct as a slice instead of as a string, the data
pointed to by the slice is not marked up because there is no information about the size of the
elements that the slice points to.
Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/GolangStringAnalyzer.java