private int updateExecutable(DescriptionManager manage, ExecutableRecord erec,
			List<FunctionDescription> badfunc, boolean checkExeCategories)
			throws LSHException, SQLException {
		int val;		// The return value
		beginTransaction(true);
		boolean commit = false;
		try {
			ExecutableRow row = exeTable.queryMd5ExeMatch(erec.getMd5());
			if (row == null) {
				return -1; // Indicate that we couldn't find the executable
			}
			ExecutableRecord erec_db = makeExecutableRecordTemp(row);
			DescriptionManager dbmanage = new DescriptionManager();
			erec_db = dbmanage.transferExecutable(erec_db);
			if (checkExeCategories) {
				final List<CategoryRecord> catvec =
					exeCategoryTable.queryExecutableCategories(erec_db.getRowId().getLong(), 100); // Make sure categories are filled in before diff

				dbmanage.setExeCategories(erec_db, catvec);
			}
			ExecutableRecord.Update exe_update = new ExecutableRecord.Update();
			boolean has_exe_update = erec.diffForUpdate(exe_update, erec_db);

			// Load all the functions in the database under this executable
			List<FunctionDescription> funclist = new ArrayList<FunctionDescription>();
			queryAllFunc(funclist, erec_db, dbmanage, 0);

			// Create a map from address to executables
			Map<Long, FunctionDescription> addrmap =
				FunctionDescription.createAddressToFunctionMap(funclist.iterator());

			// Match new functions to old functions via the address
			List<FunctionDescription.Update> updatelist;
			updatelist =
				FunctionDescription.generateUpdates(manage.listFunctions(erec), addrmap, badfunc);

			if (!has_exe_update && updatelist.isEmpty()) {
				return 0; // All updates are in place already
			}

			// Do the actual database updates
			if (has_exe_update) {
				exeTable.updateExecutable(exe_update);
			}
			for (FunctionDescription.Update updateRec : updatelist) {
				updateFunction(updateRec);
			}
			commit = true;
			val = has_exe_update ? 1 : 0;
			val += 2 * updatelist.size();
		}
		finally {
			endTransaction(commit);
		}
		return val;
	}
Update metadata for the executable -erec- and all its functions (in
manage)

@param manage
           is the collection of functions to update
@param erec
           is the root executable
@param badfunc
           collects references to functions with update info that could
           not be identified
@param checkExeCategories if true, update any found executable categories
@return -1 if the executable could not be found, otherwise return 2*# of
        update functions + 1 if the executable metadata is also updated
@throws LSHException if there is a problem transferring the executable to a new container
@throws SQLException if there is a problem executing various queries
Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/client/AbstractSQLFunctionDatabase.java