Index: include/xray/xray_interface.h
===================================================================
--- include/xray/xray_interface.h
+++ include/xray/xray_interface.h
@@ -15,6 +15,7 @@
 #define XRAY_XRAY_INTERFACE_H
 
 #include <cstdint>
+#include <stddef.h>
 
 extern "C" {
 
@@ -86,6 +87,14 @@
 /// result values.
 extern XRayPatchingStatus __xray_unpatch_function(int32_t FuncId);
 
+/// This function returns the address of the function provided a valid function
+/// id. We return 0 if we encounter any error, even if 0 may be a valid function
+/// address.
+extern uintptr_t __xray_function_address(int32_t FuncId);
+
+/// This function returns the maximum valid function id. Returns 0 if we
+/// encounter errors (when there are no instrumented functions, etc.).
+extern size_t __xray_max_function_id();
 
 }
 
Index: lib/xray/xray_interface.cc
===================================================================
--- lib/xray/xray_interface.cc
+++ lib/xray/xray_interface.cc
@@ -255,7 +255,7 @@
 
   // FuncId must be a positive number, less than the number of functions
   // instrumented.
-  if (FuncId <= 0 || static_cast<size_t>(FuncId) >= InstrMap.Functions) {
+  if (FuncId <= 0 || static_cast<size_t>(FuncId) > InstrMap.Functions) {
     Report("Invalid function id provided: %d\n", FuncId);
     return XRayPatchingStatus::FAILED;
   }
@@ -302,3 +302,15 @@
   return 1;
 }
 int __xray_remove_handler_arg1() { return __xray_set_handler_arg1(nullptr); }
+
+uintptr_t __xray_function_address(int32_t FuncId) XRAY_NEVER_INSTRUMENT {
+  __sanitizer::SpinMutexLock Guard(&XRayInstrMapMutex);
+  if (FuncId <= 0 || static_cast<size_t>(FuncId) > XRayInstrMap.Functions)
+    return 0;
+  return XRayInstrMap.SledsIndex[FuncId - 1].Begin->Address;
+}
+
+size_t __xray_max_function_id() XRAY_NEVER_INSTRUMENT {
+  __sanitizer::SpinMutexLock Guard(&XRayInstrMapMutex);
+  return XRayInstrMap.Functions;
+}
Index: test/xray/TestCases/Linux/func-id-utils.cc
===================================================================
--- /dev/null
+++ test/xray/TestCases/Linux/func-id-utils.cc
@@ -0,0 +1,29 @@
+// Check that we can turn a function id to a function address, and also get the
+// maximum function id for the current binary.
+//
+// RUN: %clangxx_xray -std=c++11 %s -o %t
+// RUN: XRAY_OPTIONS="patch_premain=false xray_naive_log=false" %run %t | FileCheck %s
+
+#include "xray/xray_interface.h"
+#include <cstdio>
+
+[[clang::xray_always_instrument]] void bar() {
+  // do nothing!
+}
+
+[[clang::xray_always_instrument]] void foo() {
+  bar();
+}
+
+[[clang::xray_always_instrument]] int main(int argc, char* argv[]) {
+  printf("max function id: %zu\n", __xray_max_function_id());
+  // CHECK: max function id: [[MAX:.*]]
+
+  printf("addresses:\n");
+  for (auto i = __xray_max_function_id(); i != 0; --i)
+    printf("#%lu -> @%04lx\n", i, __xray_function_address(i));
+
+  // CHECK-LABEL: addresses:
+  // CHECK: #[[MAX]] -> @[[ADDR:.*]]
+  // CHECK-NOT: #0 -> @{{.*}}
+}