private void generateCallGraph() {
		FunctionManager mgr = program.getFunctionManager();
		for (FunctionNode node : addrToNode.values()) {								//Addresses are associated to nodes.
			if (node != null) {
				List<Address> callAddresses = node.releaseCallAddresses();
				for (Address addr : callAddresses) {
					FunctionNode kid;
					for (;;) {
						kid = addrToNode.get(addr);							//These nodes are the vertices in the call graph.
						if (kid != null) {
							break;
						}
						Function f = mgr.getFunctionAt(addr);	// If addr does not link to a node, it is most likely a thunk
						if (f == null) {
							break;
						}
						if (!f.isThunk()) {
							break;
						}
						addr = f.getThunkedFunction(false).getEntryPoint();	// Replace with address of thunked function
					}
					if (kid != null) {
						node.getChildren().add(kid);
						kid.getParents().add(node);
					}
				}
			}
		}
		return;
	}
Generate program call-graph in terms of FunctionNodes
Uses the call address attached to each raw FunctionNode
Once the xrefs are built, the original call address arrays are released
Ghidra/Features/VersionTrackingBSim/src/main/java/ghidra/feature/vt/api/FunctionNodeContainer.java