diff -Nru gcc-13.2.0-orig/libiberty/lrealpath.c gcc-13.2.0-patched/libiberty/lrealpath.c
--- gcc-13.2.0-orig/libiberty/lrealpath.c	2023-07-27 04:13:08.000000000 -0400
+++ gcc-13.2.0-patched/libiberty/lrealpath.c	2024-04-29 06:35:13.462421957 -0400
@@ -68,135 +68,8 @@
   /* cygwin has realpath, so it won't get here.  */ 
 # if defined (_WIN32)
 #  define WIN32_LEAN_AND_MEAN
-#  include <windows.h> /* for GetFullPathName/GetFinalPathNameByHandle/
-                          CreateFile/CloseHandle */
-#  define WIN32_REPLACE_SLASHES(_ptr, _len) \
-     for (unsigned i = 0; i != (_len); ++i) \
-       if ((_ptr)[i] == '\\') (_ptr)[i] = '/';
-
-#  define WIN32_UNC_PREFIX "//?/UNC/"
-#  define WIN32_UNC_PREFIX_LEN (sizeof(WIN32_UNC_PREFIX)-1)
-#  define WIN32_IS_UNC_PREFIX(ptr) \
-  (0 == memcmp(ptr, WIN32_UNC_PREFIX, WIN32_UNC_PREFIX_LEN))
-
-#  define WIN32_NON_UNC_PREFIX "//?/"
-#  define WIN32_NON_UNC_PREFIX_LEN (sizeof(WIN32_NON_UNC_PREFIX)-1)
-#  define WIN32_IS_NON_UNC_PREFIX(ptr) \
-  (0 == memcmp(ptr, WIN32_NON_UNC_PREFIX, WIN32_NON_UNC_PREFIX_LEN))
-
-/* Get full path name without symlinks resolution.
-   It also converts all forward slashes to back slashes.
-*/
-char* get_full_path_name(const char *filename) {
-  DWORD len;
-  char *buf, *ptr, *res;
-
-  /* determining the required buffer size.
-     from the man: `If the lpBuffer buffer is too small to contain
-     the path, the return value is the size, in TCHARs, of the buffer
-     that is required to hold the path _and_the_terminating_null_character_`
-  */
-  len = GetFullPathName(filename, 0, NULL, NULL);
-
-  if ( len == 0 )
-    return strdup(filename);
-
-  buf = (char *)malloc(len);
-
-  /* no point to check the result again */
-  len = GetFullPathName(filename, len, buf, NULL);
-  buf[len] = 0;
-
-  /* replace slashes */
-  WIN32_REPLACE_SLASHES(buf, len);
-
-  /* calculate offset based on prefix type */
-  len = WIN32_IS_UNC_PREFIX(buf)
-    ? (WIN32_UNC_PREFIX_LEN - 2)
-    : WIN32_IS_NON_UNC_PREFIX(buf)
-      ? WIN32_NON_UNC_PREFIX_LEN
-      : 0
-  ;
-
-  ptr = buf + len;
-  if ( WIN32_IS_UNC_PREFIX(buf) ) {
-    ptr[0] = '/';
-    ptr[1] = '/';
-  }
-
-  res = strdup(ptr);
-
-  free(buf);
-
-  return res;
-}
-
-# if _WIN32_WINNT >= 0x0600
-
-/* Get full path name WITH symlinks resolution.
-   It also converts all forward slashes to back slashes.
-*/
-char* get_final_path_name(HANDLE fh) {
-  DWORD len;
-  char *buf, *ptr, *res;
-
-  /* determining the required buffer size.
-     from the  man: `If the function fails because lpszFilePath is too
-     small to hold the string plus the terminating null character,
-     the return value is the required buffer size, in TCHARs. This
-     value _includes_the_size_of_the_terminating_null_character_`.
-     but in my testcase I have path with 26 chars, the function
-     returns 26 also, ie without the trailing zero-char...
-  */
-  len = GetFinalPathNameByHandle(
-     fh
-    ,NULL
-    ,0
-    ,FILE_NAME_NORMALIZED | VOLUME_NAME_DOS
-  );
-
-  if ( len == 0 )
-    return NULL;
-
-  len += 1; /* for zero-char */
-  buf = (char *)malloc(len);
-
-  /* no point to check the result again */
-  len = GetFinalPathNameByHandle(
-     fh
-    ,buf
-    ,len
-    ,FILE_NAME_NORMALIZED | VOLUME_NAME_DOS
-  );
-  buf[len] = 0;
-
-  /* replace slashes */
-  WIN32_REPLACE_SLASHES(buf, len);
-
-  /* calculate offset based on prefix type */
-  len = WIN32_IS_UNC_PREFIX(buf)
-    ? (WIN32_UNC_PREFIX_LEN - 2)
-    : WIN32_IS_NON_UNC_PREFIX(buf)
-      ? WIN32_NON_UNC_PREFIX_LEN
-      : 0
-  ;
-
-  ptr = buf + len;
-  if ( WIN32_IS_UNC_PREFIX(buf) ) {
-    ptr[0] = '/';
-    ptr[1] = '/';
-  }
-
-  res = strdup(ptr);
-
-  free(buf);
-
-  return res;
-}
-
-# endif // _WIN32_WINNT >= 0x0600
-
-# endif // _WIN32
+#  include <windows.h> /* for GetFullPathName */
+# endif
 #endif
 
 char *
@@ -255,52 +128,30 @@
   }
 #endif
 
-  /* The MS Windows method */
+  /* The MS Windows method.  If we don't have realpath, we assume we
+     don't have symlinks and just canonicalize to a Windows absolute
+     path.  GetFullPath converts ../ and ./ in relative paths to
+     absolute paths, filling in current drive if one is not given
+     or using the current directory of a specified drive (eg, "E:foo").
+     It also converts all forward slashes to back slashes.  */
 #if defined (_WIN32)
   {
-    char *res;
-
-    /* For Windows Vista and greater */
-#if _WIN32_WINNT >= 0x0600
-
-    /* For some reason the function receives just empty `filename`, but not NULL.
-       What should we do in that case?
-       According to `strdup()` implementation
-         (https://elixir.bootlin.com/glibc/latest/source/string/strdup.c)
-       it will alloc 1 byte even for empty but non NULL string.
-       OK, will use `strdup()` for that case.
-    */
-    if ( 0 == strlen(filename) )
-      return strdup(filename);
-
-    HANDLE fh = CreateFile(
-       filename
-      ,FILE_READ_ATTRIBUTES
-      ,FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE
-      ,NULL
-      ,OPEN_EXISTING
-      ,FILE_FLAG_BACKUP_SEMANTICS
-      ,NULL
-    );
-
-    if ( fh == INVALID_HANDLE_VALUE ) {
-      res = get_full_path_name(filename);
-    } else {
-      res = get_final_path_name(fh);
-      CloseHandle(fh);
-
-      if ( !res )
-        res = get_full_path_name(filename);
-    }
-
-#else
-
-    /* For Windows XP */
-    res = get_full_path_name(filename);
-
-#endif // _WIN32_WINNT >= 0x0600
-
-    return res;
+    char buf[MAX_PATH];
+    char* basename;
+    DWORD len = GetFullPathName (filename, MAX_PATH, buf, &basename);
+    if (len == 0 || len > MAX_PATH - 1)
+      return strdup (filename);
+    else
+      {
+	/* The file system is case-preserving but case-insensitive,
+	   Canonicalize to lowercase, using the codepage associated
+	   with the process locale.  */
+        CharLowerBuff (buf, len);
+        return strdup (buf);
+      }
   }
-#endif // _WIN32
+#endif
+
+  /* This system is a lost cause, just duplicate the filename.  */
+  return strdup (filename);
 }
