diff --git a/EfiLib/gnuefi-helper.c b/EfiLib/gnuefi-helper.c
index 8730403..032c7c7 100644
--- a/EfiLib/gnuefi-helper.c
+++ b/EfiLib/gnuefi-helper.c
@@ -109,6 +109,8 @@ UnicodeStrToAsciiStr (
   @return The length of String.
 
 **/
+// prevent duplicate definitions when compiled against gnu-efi 4.x
+#ifndef _GNU_EFI_4_0
 UINTN
 AsciiStrLen (
   IN      CONST CHAR8               *String
@@ -129,6 +131,7 @@ AsciiStrLen (
   }
   return Length;
 }
+#endif
 
 /**
   Determine whether a given device path is valid.
diff --git a/EfiLib/gnuefi-helper.h b/EfiLib/gnuefi-helper.h
index b691155..d3b4112 100644
--- a/EfiLib/gnuefi-helper.h
+++ b/EfiLib/gnuefi-helper.h
@@ -38,10 +38,12 @@ UnicodeStrToAsciiStr (
    OUT      CHAR8               *Destination
 );
 
+#ifndef _GNU_EFI_4_0
 UINTN
 AsciiStrLen (
    IN      CONST CHAR8               *String
 );
+#endif
 
 UINTN
 EFIAPI
diff --git a/EfiLib/legacy.c b/EfiLib/legacy.c
index 4ee6229..3fa470b 100644
--- a/EfiLib/legacy.c
+++ b/EfiLib/legacy.c
@@ -16,11 +16,12 @@
  */
 
 #ifdef __MAKEWITH_GNUEFI
+#define GNU_EFI_USE_REALLOCATEPOOL_ABI 0
 #include "efi.h"
 #include "efilib.h"
 #include "gnuefi-helper.h"
 #define EFI_DEVICE_PATH_PROTOCOL EFI_DEVICE_PATH
-#define EfiReallocatePool ReallocatePool
+#define EfiReallocatePool MyReallocatePool
 #define EfiLibLocateProtocol LibLocateProtocol
 #else
 #include "../include/tiano_includes.h"
diff --git a/filesystems/fsw_efi.h b/filesystems/fsw_efi.h
index bb51073..6182a46 100644
--- a/filesystems/fsw_efi.h
+++ b/filesystems/fsw_efi.h
@@ -42,8 +42,11 @@
 #include "../include/refit_call_wrapper.h"
 
 #ifdef __MAKEWITH_GNUEFI
+// prevent duplicate definitions when compiled against gnu-efi 4.x
+#ifndef _GNU_EFI_4_0
 #define CompareGuid(a, b) CompareGuid(a, b)==0
 #endif
+#endif
 
 #define REFIND_EFI_DISK_IO_PROTOCOL_GUID \
   { \
diff --git a/refind/driver_support.c b/refind/driver_support.c
index cba4132..69ec6f2 100644
--- a/refind/driver_support.c
+++ b/refind/driver_support.c
@@ -99,6 +99,7 @@ EFI_GUID gMyEfiBlockIoProtocolGuid = { 0x964E5B21, 0x6459, 0x11D2, { 0x8E, 0x39,
 EFI_GUID gMyEfiSimpleFileSystemProtocolGuid = { 0x964E5B22, 0x6459, 0x11D2, { 0x8E, 0x39, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B }};
 
 #ifdef __MAKEWITH_GNUEFI
+#define CompareGuid MyCompareGuid
 struct MY_EFI_SIMPLE_FILE_SYSTEM_PROTOCOL;
 struct MY_EFI_FILE_PROTOCOL;
 
@@ -607,3 +608,38 @@ BOOLEAN LoadDrivers(VOID) {
         ConnectAllDriversToAllControllers();
     return (NumFound > 0);
 } /* BOOLEAN LoadDrivers() */
+
+#ifdef __MAKEWITH_GNUEFI
+/* When using GNU-EFI, revert to the old CompareGuid() and RtCompareGuid()
+   functions, because GNU-EFI 4.x changed their definitions in a way that broke
+   rEFInd. Modified from GNU-EFI 3.x functions in lib/guid.c and
+   lib/runtime/efirtlib.c; original copyright Intel & BSD-licensed. */
+INTN
+MyCompareGuid(
+    IN EFI_GUID     *Guid1,
+    IN EFI_GUID     *Guid2
+    )
+{
+    return MyRtCompareGuid (Guid1, Guid2);
+}
+
+INTN
+RUNTIMEFUNCTION
+MyRtCompareGuid (
+    IN EFI_GUID     *Guid1,
+    IN EFI_GUID     *Guid2
+    )
+{
+    INT32       *g1, *g2, r;
+
+    g1 = (INT32 *) Guid1;
+    g2 = (INT32 *) Guid2;
+
+    r  = g1[0] - g2[0];
+    r |= g1[1] - g2[1];
+    r |= g1[2] - g2[2];
+    r |= g1[3] - g2[3];
+
+    return r;
+}
+#endif
diff --git a/refind/driver_support.h b/refind/driver_support.h
index 5869a8c..40eee33 100644
--- a/refind/driver_support.h
+++ b/refind/driver_support.h
@@ -22,6 +22,8 @@
 
 #ifdef __MAKEWITH_GNUEFI
 #include <efi.h>
+INTN MyCompareGuid(IN EFI_GUID *Guid1, IN EFI_GUID *Guid2);
+INTN RUNTIMEFUNCTION MyRtCompareGuid(IN EFI_GUID *Guid1, IN EFI_GUID *Guid2);
 #else
 #include "../include/tiano_includes.h"
 #endif
diff --git a/refind/lib.c b/refind/lib.c
index 7a9f28e..7cd72dd 100644
--- a/refind/lib.c
+++ b/refind/lib.c
@@ -56,6 +56,7 @@
  */
 
 #pragma pack(0)
+#define GNU_EFI_USE_REALLOCATEPOOL_ABI 0
 #include "global.h"
 #include "lib.h"
 #include "icns.h"
@@ -69,7 +70,7 @@
 #include "mystrings.h"
 
 #ifdef __MAKEWITH_GNUEFI
-#define EfiReallocatePool ReallocatePool
+#define EfiReallocatePool MyReallocatePool
 #else
 #define LibLocateHandle gBS->LocateHandleBuffer
 #define DevicePathProtocol gEfiDevicePathProtocolGuid
@@ -1972,3 +1973,34 @@ VOID EraseUint32List(UINT32_LIST **TheList) {
         *TheList = NextItem;
     } // while
 } // EraseUin32List()
+
+#ifdef __MAKEWITH_GNUEFI
+/* When using GNU-EFI, revert to the old ReallocatePool() function, because
+   GNU-EFI 4.x changed its definition in a way that broke rEFInd.
+   Modified from EfiLib/BmLib.c (matches GNU-EFI 3.x); original copyright Intel
+   & BSD-licensed. */
+VOID *
+MyReallocatePool (
+  IN VOID                 *OldPool,
+  IN UINTN                OldSize,
+  IN UINTN                NewSize
+  )
+{
+  VOID  *NewPool;
+
+  NewPool = NULL;
+  if (NewSize != 0) {
+    NewPool = AllocateZeroPool (NewSize);
+  }
+
+  if (OldPool != NULL) {
+    if (NewPool != NULL) {
+      MyCopyMem (NewPool, OldPool, OldSize < NewSize ? OldSize : NewSize);
+    }
+
+    FreePool (OldPool);
+  }
+
+  return NewPool;
+}
+#endif
diff --git a/refind/lib.h b/refind/lib.h
index 73c5c12..0c8f10d 100644
--- a/refind/lib.h
+++ b/refind/lib.h
@@ -48,6 +48,7 @@
 #ifdef __MAKEWITH_GNUEFI
 #include "efi.h"
 #include "efilib.h"
+VOID * MyReallocatePool(IN VOID *OldPool, IN UINTN OldSize, IN UINTN NewSize);
 #define EFI_DEVICE_PATH_PROTOCOL EFI_DEVICE_PATH
 #else
 #include "../include/tiano_includes.h"
