public static DWARFFunction read(DIEAggregate diea)
			throws IOException, DWARFExpressionException {
		if (diea.isDanglingDeclaration()) {
			return null;
		}
		DWARFRangeList bodyRanges = getFuncBodyRanges(diea);
		if (bodyRanges.isEmpty()) {
			return null;
		}

		DWARFProgram prog = diea.getProgram();
		DWARFDataTypeManager dwarfDTM = prog.getDwarfDTM();

		DWARFFunction dfunc = new DWARFFunction(diea, prog.getName(diea), bodyRanges);

		dfunc.namespace = dfunc.name.getParentNamespace(prog.getGhidraProgram());
		dfunc.sourceInfo = DWARFSourceInfo.create(diea);

		// Check if the function is an external function
		dfunc.isExternal = diea.getBool(DW_AT_external, false);
		dfunc.noReturn = diea.getBool(DW_AT_noreturn, false);

		// Retrieve the frame base if it exists
		DWARFLocationList frameBaseLocs = diea.getLocationList(DW_AT_frame_base);
		if (!frameBaseLocs.isEmpty()) {
			DWARFLocation frameLoc = frameBaseLocs.getLocationContaining(dfunc.getEntryPc());
			// get the framebase register, find where the frame is finally setup.
			if (frameLoc != null) {
				dfunc.frameBase = frameLoc.evaluate(diea.getCompilationUnit()).pop();
			}
		}

		dfunc.retval =
			DWARFVariable.fromDataType(dfunc, dwarfDTM.getDataTypeForVariable(diea.getTypeRef()));

		int paramOrdinal = 0;
		for (DIEAggregate paramDIEA : diea.getFunctionParamList()) {
			DWARFVariable param = DWARFVariable.readParameter(paramDIEA, dfunc, paramOrdinal++);
			dfunc.params.add(param);
		}
		dfunc.varArg = !diea.getChildren(DW_TAG_unspecified_parameters).isEmpty();

		return dfunc;
	}
Create a function instance from the information found in the specified DIEA.

@param diea DW_TAG_subprogram {@link DIEAggregate}
@return new {@link DWARFFunction}, or null if invalid DWARF information 
@throws IOException if error accessing attribute values
@throws DWARFExpressionException if error accessing attribute values
Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/dwarf/DWARFFunction.java