diff --git a/bits/dl_find_object.h b/bits/dl_find_object.h
index b9f796dc2b..908feece08 100644
--- a/bits/dl_find_object.h
+++ b/bits/dl_find_object.h
@@ -30,3 +30,6 @@
 
 /* The ELF segment which contains the exception handling data.  */
 #define DLFO_EH_SEGMENT_TYPE PT_GNU_EH_FRAME
+
+/* The ELF segment which contains the SFrame data.  */
+#define DLFO_SFRAME_SEGMENT_TYPE PT_GNU_SFRAME
diff --git a/dlfcn/dlfcn.h b/dlfcn/dlfcn.h
index 5747962611..411b401c9e 100644
--- a/dlfcn/dlfcn.h
+++ b/dlfcn/dlfcn.h
@@ -217,7 +217,11 @@ struct dl_find_object
   int dlfo_eh_count;		/* Number of exception handling entries.  */
   unsigned int __dlfo_eh_count_pad;
 # endif
-  __extension__ unsigned long long int __dflo_reserved[7];
+  void *dlfo_sframe;		/* SFrame stack trace data of the object.  */
+#if __WORDSIZE == 32
+  unsigned int __dlfo_sframe_pad;
+#endif
+  __extension__ unsigned long long int __dflo_reserved[6];
 };
 
 /* If ADDRESS is found in an object, fill in *RESULT and return 0.
@@ -226,6 +230,7 @@ int _dl_find_object (void *__address, struct dl_find_object *__result) __THROW;
 
 #endif /* __USE_GNU */
 
+#define DLF_SFRAME      (1 << 0)   /* SFrame stack trace data is valid.  */
 
 __END_DECLS
 
diff --git a/elf/dl-find_object.h b/elf/dl-find_object.h
index 0915065be0..54092f9af7 100644
--- a/elf/dl-find_object.h
+++ b/elf/dl-find_object.h
@@ -33,6 +33,7 @@
    transactions).  */
 struct dl_find_object_internal
 {
+  unsigned long long int flags;
   uintptr_t map_start;
   uintptr_t map_end;            /* Set to map_start by dlclose.  */
   struct link_map *map;         /* Set to NULL by dlclose.  */
@@ -43,6 +44,7 @@ struct dl_find_object_internal
 #if DLFO_STRUCT_HAS_EH_COUNT
   int eh_count;
 #endif
+  void *sframe;
 };
 
 /* Create a copy of *SOURCE in *COPY using relaxed MO loads and
@@ -51,6 +53,8 @@ static inline void
 _dl_find_object_internal_copy (const struct dl_find_object_internal *source,
                                struct dl_find_object_internal *copy)
 {
+  atomic_store_relaxed (&copy->flags,
+                        atomic_load_relaxed (&source->flags));
   atomic_store_relaxed (&copy->map_start,
                         atomic_load_relaxed (&source->map_start));
   atomic_store_relaxed (&copy->map_end,
@@ -67,13 +71,15 @@ _dl_find_object_internal_copy (const struct dl_find_object_internal *source,
   atomic_store_relaxed (&copy->eh_count,
                         atomic_load_relaxed (&source->eh_count));
 #endif
+  atomic_store_relaxed (&copy->sframe,
+                        atomic_load_relaxed (&source->sframe));
 }
 
 static inline void
 _dl_find_object_to_external (struct dl_find_object_internal *internal,
                              struct dl_find_object *external)
 {
-  external->dlfo_flags = 0;
+  external->dlfo_flags = internal->flags;
   external->dlfo_map_start = (void *) internal->map_start;
   external->dlfo_map_end = (void *) internal->map_end;
   external->dlfo_link_map = internal->map;
@@ -84,6 +90,7 @@ _dl_find_object_to_external (struct dl_find_object_internal *internal,
 # if DLFO_STRUCT_HAS_EH_COUNT
   external->dlfo_eh_count = internal->eh_count;
 # endif
+  external->dlfo_sframe = internal->sframe;
 }
 
 /* Extract the object location data from a link map and writes it to
@@ -92,6 +99,8 @@ static void __attribute__ ((unused))
 _dl_find_object_from_map (struct link_map *l,
                           struct dl_find_object_internal *result)
 {
+  uint64_t read_seg = 0;
+  atomic_store_relaxed (&result->flags, 0);
   atomic_store_relaxed (&result->map_start, (uintptr_t) l->l_map_start);
   atomic_store_relaxed (&result->map_end, (uintptr_t) l->l_map_end);
   atomic_store_relaxed (&result->map, l);
@@ -100,23 +109,40 @@ _dl_find_object_from_map (struct link_map *l,
   atomic_store_relaxed (&result->eh_dbase, (void *) l->l_info[DT_PLTGOT]);
 #endif
 
+  /* Initialize object's exception handling segment and SFrame segment
+     data.  */
+  atomic_store_relaxed (&result->sframe, NULL);
+  atomic_store_relaxed (&result->eh_frame, NULL);
+#if DLFO_STRUCT_HAS_EH_COUNT
+  atomic_store_relaxed (&result->eh_count, 0);
+#endif
+
   for (const ElfW(Phdr) *ph = l->l_phdr, *ph_end = l->l_phdr + l->l_phnum;
        ph < ph_end; ++ph)
-    if (ph->p_type == DLFO_EH_SEGMENT_TYPE)
+    switch (ph->p_type)
       {
+      case DLFO_EH_SEGMENT_TYPE:
         atomic_store_relaxed (&result->eh_frame,
                               (void *) (ph->p_vaddr + l->l_addr));
 #if DLFO_STRUCT_HAS_EH_COUNT
         atomic_store_relaxed (&result->eh_count, ph->p_memsz / 8);
 #endif
-        return;
-      }
+        read_seg |= 1;
+        break;
 
-  /* Object has no exception handling segment.  */
-  atomic_store_relaxed (&result->eh_frame, NULL);
-#if DLFO_STRUCT_HAS_EH_COUNT
-  atomic_store_relaxed (&result->eh_count, 0);
-#endif
+      case DLFO_SFRAME_SEGMENT_TYPE:
+        atomic_store_relaxed (&result->sframe,
+                              (void *) (ph->p_vaddr + l->l_addr));
+        atomic_store_relaxed (&result->flags,
+			      atomic_load_relaxed (&result->flags)
+			      | DLF_SFRAME);
+        read_seg |= 2;
+        /* Fall through.  */
+      default:
+        if (read_seg == 3)
+          return;
+        break;
+      }
 }
 
 /* Called by the dynamic linker to set up the data structures for the
diff --git a/manual/dynlink.texi b/manual/dynlink.texi
index 1500a53de6..865a8dcdf7 100644
--- a/manual/dynlink.texi
+++ b/manual/dynlink.texi
@@ -442,7 +442,7 @@ result data to the caller.
 
 @table @code
 @item unsigned long long int dlfo_flags
-Currently unused and always 0.
+Bit zero signals if SFrame stack data is valid.
 
 @item void *dlfo_map_start
 The start address of the inspected mapping.  This information comes from
@@ -459,6 +459,10 @@ This member contains a pointer to the link map of the object.
 This member contains a pointer to the exception handling data of the
 object.  See @code{DLFO_EH_SEGMENT_TYPE} below.
 
+@item void *dlfo_sframe
+This member contains a pointer to the SFrame stack trace data of the
+object.  See @code{DLFO_SFRAME_SEGMENT_TYPE} below.
+
 @end table
 
 This structure is a GNU extension.
@@ -496,6 +500,25 @@ macro expands to the program header type for the unwinding data.
 This macro is a GNU extension.
 @end deftypevr
 
+@deftypevr Macro int DLFO_SFRAME_SEGMENT_TYPE
+@standards{GNU, dlfcn.h}
+On targets using SFrame stack tracer, this macro expands to
+@code{PT_GNU_SFRAME}.  This indicates that @code{dlfo_sframe} in
+@code{struct dl_find_object} points to the @code{PT_GNU_SFRAME}
+segment of the object.
+
+This macro is a GNU extension.
+@end deftypevr
+
+@deftypevr Macro int DLFO_STRUCT_HAS_SFRAME
+@standards{GNU, dlfcn.h}
+On most targets, this macro is defined as @code{0}.  If it is defined to
+@code{1}, @code{struct dl_find_object} contains an additional member
+@code{dlfo_sframe}.
+
+This macro is a GNU extension.
+@end deftypevr
+
 @deftypefun {int} _dl_find_object (void *@var{address}, struct dl_find_object *@var{result})
 @standards{GNU, dlfcn.h}
 @safety{@mtsafe{}@assafe{}@acsafe{}}
