private boolean readStorage(DIEAggregate diea, DWARFLocation location) {

		if (location == null) {
			return false;
		}

		lexicalOffset = location.getOffset(dfunc.address.getOffset());

		DWARFProgram prog = diea.getProgram();
		DWARFImportSummary importSummary = prog.getImportSummary();

		try {
			DWARFExpressionEvaluator exprEvaluator =
				new DWARFExpressionEvaluator(diea.getCompilationUnit());
			exprEvaluator.setFrameBase(dfunc.frameBase);

			DWARFExpression expr = exprEvaluator.readExpr(location.getExpr());

			exprEvaluator.evaluate(expr);
			long res = exprEvaluator.pop();

			// check expression eval result.  Use early return for errors, leaving storage unset.
			// Success return is at bottom of if/else chain of checks.

			if (exprEvaluator.isDwarfStackValue()) {
				// result is a value (not a location) left on the expr stack, which is not supported 
				importSummary.varDWARFExpressionValue++;
				return false;
			}

			if (exprEvaluator.useUnknownRegister()) {
				// This is a deref of a register (excluding the stack pointer)
				// If the offset of the deref was 0, we can cheese it into a ghidra register location
				// by changing the datatype to a pointer-to-original-datatype, otherwise
				// its not usable in ghidra

				if (!exprEvaluator.isRegisterLocation()) {
					importSummary.varDynamicRegisterError++;
					return false;
				}

				if (exprEvaluator.getLastRegister() != null) {
					type = prog.getDwarfDTM().getPtrTo(type);
					setRegisterStorage(List.of(exprEvaluator.getLastRegister()));
				}
			}
			else if (exprEvaluator.isStackRelative()) {
				if (exprEvaluator.isDeref()) {
					type = prog.getDwarfDTM().getPtrTo(type);
				}
				setStackStorage(res);
			}
			else if (exprEvaluator.isRegisterLocation()) {
				// The DWARF expression evaluated to a simple register.  If we have a mapping
				// for it in the "processor.dwarf" register mapping file, try to create
				// a variable, otherwise log the unknown register for later logging.
				Register reg = exprEvaluator.getLastRegister();
				if (reg == null) {
					// The DWARF register did not have a mapping to a Ghidra register, so
					// log it to be displayed in an error summary at end of import phase.
					importSummary.unknownRegistersEncountered
							.add(exprEvaluator.getRawLastRegister());
					return false;
				}
				if ((type.getLength() > reg.getMinimumByteSize())) {
					importSummary.varFitError++;
					program.logWarningAt(dfunc.address, dfunc.name.getName(),
						"%s %s [%s, size=%d] can not fit into specified register %s, size=%d"
								.formatted(getVarTypeName(diea), name.getName(), type.getName(),
									type.getLength(), reg.getName(), reg.getMinimumByteSize()));
					return false;
				}
				setRegisterStorage(List.of(reg));
			}
			else if (exprEvaluator.getRawLastRegister() == -1 && res != 0) {
				// static global variable location
				setRamStorage(res);
			}
			else {
				Msg.error(this,
					"%s location error for function %s@%s, %s: %s, DWARF DIE: %s, unsupported location information."
							.formatted(getVarTypeName(diea), dfunc.name.getName(), dfunc.address,
								name.getName(),
								DWARFExpression.exprToString(location.getExpr(), diea),
								diea.getHexOffset()));
				return false;
			}

			return true;
		}
		catch (DWARFExpressionException | UnsupportedOperationException
				| IndexOutOfBoundsException ex) {
			importSummary.exprReadError++;
			return false;
		}
	}
If this is a static/global variable, stored at a ram address, return it's
ram address.

@return address of where this variable is stored, null if not ram address
Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/dwarf/DWARFVariable.java