diff --git a/src/aix_state_tab_eh.inc b/src/aix_state_tab_eh.inc
new file mode 100644
index 0000000..032a2c8
--- /dev/null
+++ b/src/aix_state_tab_eh.inc
@@ -0,0 +1,681 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//
+//  This file implements the personality and helper functions for the state
+//  table based EH used by IBM legacy compilers xlC and xlclang++ on AIX.
+//
+//===----------------------------------------------------------------------===//
+
+#include <new>
+#include <stdio.h>
+#include <sys/debug.h>
+
+/*
+  The legacy IBM xlC and xlclang++ compilers use the state table for EH
+  instead of the range table. Destructors, or addresses of the possible catch
+  sites or cleanup code are specified in the state table which is a finite
+  state machine (FSM). Each function that has a state table also has an
+  autolocal state variable. The state variable represents the current state
+  of the function for EH and is found through the traceback table of the
+  function during unwinding, which is located at the end of each function.
+  The FSM is an array of state entries. Each state entry has the following
+  fields:
+
+  * offset/address/pointer - the offset used to locate the object, or the
+    address of a global object, or the address of the next state if it is an
+    old conditional state change entry;
+  * dtor/landing pad - address of the destructor function to invoke,
+    or address of the catch block or cleanup code in the user code to branch to;
+  * element count/action flag - the number of elements or the flag for actions;
+  * element size - if the object is an array this is the size of one element
+    of the array;
+  * flags - flags used to control how fields in the entry are interpreted;
+  * next state - the state to execute next after the action for this state is
+    performed. The value of zero indicates the end of the state for this
+    function.
+
+  The following is the description of 'element count/action flag' field.
++-----------------------------------------------------------------------------+
+| value |      description       |                  action                    |
++-------+------------------------+--------------------------------------------+
+| > 1   |   object is an array   | calls __cxa_vec_cleanup to run dtor for    |
+|       |                        | each member of the array                   |
++-------+------------------------+--------------------------------------------+
+| 1, 0  |   object is a scalar   | calls dtor for the object                  |
++-------+------------------------+--------------------------------------------+
+|  -1   |      begin catch       | branches to the handler which performes    |
+|       |                        | catch-match. If there is no catch that     |
+|       |                        | matches the exception it will be rethrown  |
++-------+------------------------+--------------------------------------------+
+|  -2   |       end catch        | ends current catch block and continues     |
+|       |                        | attempting to catch the exception          |
++-------+------------------------+--------------------------------------------+
+|  -3   |   delete the object    | calls the delete function of the object    |
++-------+------------------------+--------------------------------------------+
+|  -4   |      cleanup label     | branches to the user code for cleaning up  |
++-------+------------------------+--------------------------------------------+
+*/
+
+namespace __cxxabiv1 {
+
+extern "C" {
+
+// Macros for debugging the state table parsing.
+#ifdef NDEBUG
+#  define _LIBCXXABI_TRACE_STATETAB(msg, ...)
+#  define _LIBCXXABI_TRACE_STATETAB0(msg)
+#  define _LIBCXXABI_TRACE_STATETAB1(msg)
+#  define _LIBCXXABI_TRACING_STATETAB 0
+#else
+static bool state_tab_dbg() {
+  static bool checked = false;
+  static bool log = false;
+  if (!checked) {
+    log = (getenv("LIBCXXABI_PRINT_STATTAB") != NULL);
+    checked = true;
+  }
+  return log;
+}
+
+#  define _LIBCXXABI_TRACE_STATETAB(msg, ...)                                  \
+     do {                                                                      \
+       if (state_tab_dbg())                                                    \
+         fprintf(stderr, "libcxxabi: " msg, __VA_ARGS__);                      \
+     } while (0)
+#  define _LIBCXXABI_TRACE_STATETAB0(msg)                                      \
+     do {                                                                      \
+       if (state_tab_dbg())                                                    \
+         fprintf(stderr, "libcxxabi: " msg);                                   \
+     } while (0)
+#  define _LIBCXXABI_TRACE_STATETAB1(msg)                                      \
+     do {                                                                      \
+       if (state_tab_dbg())                                                    \
+         fprintf(stderr, msg);                                                 \
+     } while (0)
+
+#  define _LIBCXXABI_TRACING_STATETAB state_tab_dbg()
+#endif // NDEBUG
+
+namespace __state_table_eh {
+
+using destruct_f = void (*)(void*);
+
+// Definition of flags for the state table entry field 'action flag'.
+enum FSMEntryCount : intptr_t { beginCatch = -1, endCatch = -2, deleteObject = -3, cleanupLabel = -4, terminate = -5 };
+
+// Definition of flags for the state table entry field 'flags'.
+enum FSMEntryFlag : int16_t {
+  indirect = 0x100,                  // Object was thrown from a function where
+                                     // the return value optimization was used.
+  oldConditionalStateChange = 0x400, // State table entry is an indirect state
+                                     // change, dereference the address in
+                                     // offset as int for the target state.
+                                     // This is deprecated. This indicates
+                                     // the address is direct. (static local).
+  conditionalStateChange = 0x800,    // State table entry is an indirect state
+                                     // change, dereference the address in
+                                     // offset as int for the target state.
+                                     // The temporary is an automatic. State
+                                     // change is used in cases such as
+                                     // (b?(T1(),foo()):(T2(),foo())),throw 42;
+                                     // which causes a conditional state change
+                                     // so that we know if T1 or T2 need to be
+                                     // destroyed.
+  thisFlag = 0x01,                   // The address of the object for the
+                                     // cleanup action is based on the
+                                     // StateVariable::thisValue.
+  vBaseFlag = 0x02,                  // The object is of a virtual base class.
+  globalObj = 0x04                   // FSMEntry::address is the address of
+                                     // a global object.
+};
+
+namespace {
+// The finite state machine to be walked.
+struct FSMEntry {
+  union {
+    // Offset of the object within its stack frame or containing object.
+    intptr_t offset;
+    // Address of a global object.
+    intptr_t address;
+    // Address of the next state if it is an old conditional state change entry.
+    intptr_t nextStatePtr;
+  };
+  union {
+    // Address of the destructor function.
+    void (*destructor)(void*, size_t);
+    // The address of the catch block or cleanup code.
+    void* landingPad;
+  };
+  union {
+    // The flag for actions (when the value is negative).
+    FSMEntryCount actionFlag;
+    // The element count (when the value is positive or zero).
+    size_t elementCount;
+  };
+  size_t elemSize;
+  FSMEntryFlag flags;
+  uint16_t nextState;
+};
+
+struct FSM {
+  uint32_t magic; // Magic number of the state table.
+  int32_t numberOfStates;
+  FSMEntry table[1]; // Actually table[numberOfStates].
+};
+
+// The state variable on the stack.
+struct StateVariable {
+  int32_t state;
+  struct FSM* table;
+  intptr_t thisValue;
+  int32_t ignoreVBasePtrs;
+};
+} // namespace
+
+// State table magic number
+enum FSMMagic : uint32_t {
+  number = 0xbeefdead,  // State table generated by xlC compiler.
+  number2 = 0xbeeedead, // State table generated by early version xlC compiler.
+  number3 = 0x1cedbeef  // State table generated by xlclang++ compiler.
+};
+
+constexpr uint32_t REG_EXCP_OBJ = 14; // Register to pass the address of the exception
+                                      // object from the personality to xlclang++
+                                      // compiled code.
+
+constexpr size_t dtorArgument = 0x02; // Flag to destructor indicating to free
+                                      // virtual bases, don't delete object.
+
+static void invoke_destructor(FSMEntry* fsmEntry, void* addr) {
+  _LIBCXXABI_TRACE_STATETAB("Destruct object=%p, fsmEntry=%p\n", addr, reinterpret_cast<void*>(fsmEntry));
+  try {
+    if (fsmEntry->elementCount == 1) {
+      _LIBCXXABI_TRACE_STATETAB0("calling scalar destructor\n");
+      (*fsmEntry->destructor)(addr, dtorArgument);
+      _LIBCXXABI_TRACE_STATETAB0("returned from scalar destructor\n");
+    } else {
+      _LIBCXXABI_TRACE_STATETAB0("calling vector destructor\n");
+      __cxa_vec_cleanup(addr, reinterpret_cast<size_t>(fsmEntry->elementCount), fsmEntry->elemSize,
+                        reinterpret_cast<destruct_f>(fsmEntry->destructor));
+      _LIBCXXABI_TRACE_STATETAB0("returned from vector destructor\n");
+    }
+  } catch (...) {
+    _LIBCXXABI_TRACE_STATETAB0("Uncaught exception in destructor, terminating\n");
+    std::terminate();
+  }
+}
+
+static void invoke_delete(FSMEntry* fsmEntry, void* addr) {
+  char* objectAddress = *reinterpret_cast<char**>(addr);
+
+  _LIBCXXABI_TRACE_STATETAB("Delete object=%p, fsmEntry=%p\n", reinterpret_cast<void*>(objectAddress),
+                            reinterpret_cast<void*>(fsmEntry));
+  try {
+    _LIBCXXABI_TRACE_STATETAB0("..calling delete()\n");
+    // 'destructor' holds a function pointer to delete().
+    (*fsmEntry->destructor)(objectAddress, fsmEntry->elemSize);
+    _LIBCXXABI_TRACE_STATETAB0("..returned from delete()\n");
+  } catch (...) {
+    _LIBCXXABI_TRACE_STATETAB0("Uncaught exception in delete(), terminating\n");
+    std::terminate();
+  }
+}
+
+// Get the frame address of the current function from its traceback table
+// which is at the end of each function.
+static uintptr_t get_frame_addr(_Unwind_Context* context) {
+  int framePointerReg = 1; // default frame pointer == SP.
+  uint32_t* p = reinterpret_cast<uint32_t*>(_Unwind_GetIP(context));
+
+  // Keep looking forward until a word of 0 is found. The traceback
+  // table starts at the following word.
+  while (*p)
+    ++p;
+  tbtable* TBTable = reinterpret_cast<tbtable*>(p + 1);
+
+  p = reinterpret_cast<uint32_t*>(&TBTable->tb_ext);
+
+  // Skip field parminfo if it exists.
+  if (TBTable->tb.fixedparms || TBTable->tb.floatparms)
+    ++p;
+
+  // Skip field tb_offset if it exists.
+  if (TBTable->tb.has_tboff)
+    ++p;
+
+  // Skip field hand_mask if it exists.
+  if (TBTable->tb.int_hndl)
+    ++p;
+
+  // Skip fields ctl_info and ctl_info_disp if they exist.
+  if (TBTable->tb.has_ctl)
+    p += 1 + *p;
+
+  // Skip fields name_len and name if exist.
+  if (TBTable->tb.name_present) {
+    const uint16_t name_len = *reinterpret_cast<uint16_t*>(p);
+    p = reinterpret_cast<uint32_t*>(reinterpret_cast<char*>(p) + name_len + sizeof(uint16_t));
+  }
+
+  if (TBTable->tb.uses_alloca)
+    framePointerReg = *reinterpret_cast<char*>(p);
+
+  return _Unwind_GetGR(context, framePointerReg);
+}
+
+// Calculate the object address from the FSM entry.
+static void* compute_addr_from_table(FSMEntry* fsmEntry, StateVariable* const state, _Unwind_Context* context) {
+  void* addr;
+  if (fsmEntry->flags & FSMEntryFlag::globalObj) {
+    addr = reinterpret_cast<void*>(fsmEntry->address);
+    _LIBCXXABI_TRACE_STATETAB("Address calculation (global obj) addr=fsmEntry->address=%p\n", addr);
+  } else if (fsmEntry->flags & FSMEntryFlag::thisFlag) {
+    addr = reinterpret_cast<void*>(state->thisValue + fsmEntry->offset);
+    _LIBCXXABI_TRACE_STATETAB("Address calculation (this obj) fsmEntry->offset=%ld : "
+                              "state->thisValue=%ld addr=(fsmEntry->offset+state->thisValue)=%p\n",
+                              fsmEntry->offset, state->thisValue, addr);
+  } else if (fsmEntry->flags & FSMEntryFlag::indirect) {
+    addr = reinterpret_cast<void*>(
+        *reinterpret_cast<char**>(get_frame_addr(context) + static_cast<uintptr_t>(fsmEntry->offset)));
+    _LIBCXXABI_TRACE_STATETAB("Address calculation (indirect obj) addr=%p, fsmEntry->offset=%ld \n",
+                              addr, fsmEntry->offset);
+  } else {
+    addr = reinterpret_cast<void*>(get_frame_addr(context) + static_cast<uintptr_t>(fsmEntry->offset));
+    _LIBCXXABI_TRACE_STATETAB("Address calculation. (local obj) addr=fsmEntry->offset=%p\n",
+                              addr);
+  }
+  return addr;
+}
+
+static void scan_state_tab(scan_results& results, _Unwind_Action actions, bool native_exception,
+                           _Unwind_Exception* unwind_exception, _Unwind_Context* context) {
+  // Initialize results to found nothing but an error.
+  results.ttypeIndex = 0;
+  results.actionRecord = 0;
+  results.languageSpecificData = 0;
+  results.landingPad = 0;
+  results.adjustedPtr = 0;
+  results.reason = _URC_FATAL_PHASE1_ERROR;
+
+  // Check for consistent actions.
+  if (actions & _UA_SEARCH_PHASE) {
+    // Do Phase 1
+    if (actions & (_UA_CLEANUP_PHASE | _UA_HANDLER_FRAME | _UA_FORCE_UNWIND)) {
+      // None of these flags should be set during Phase 1.
+      //   Client error
+      results.reason = _URC_FATAL_PHASE1_ERROR;
+      return;
+    }
+  } else if (actions & _UA_CLEANUP_PHASE) {
+    if ((actions & _UA_HANDLER_FRAME) && (actions & _UA_FORCE_UNWIND)) {
+      // _UA_HANDLER_FRAME should only be set if phase 1 found a handler.
+      // If _UA_FORCE_UNWIND is set, phase 1 shouldn't have happened.
+      //    Client error
+      results.reason = _URC_FATAL_PHASE2_ERROR;
+      return;
+    }
+  } else {
+    // Neither _UA_SEARCH_PHASE nor _UA_CLEANUP_PHASE is set.
+    //   Client error
+    results.reason = _URC_FATAL_PHASE1_ERROR;
+    return;
+  }
+
+  if (_LIBCXXABI_TRACING_STATETAB) {
+    _LIBCXXABI_TRACE_STATETAB1("\n");
+    _LIBCXXABI_TRACE_STATETAB("%s: actions=%d (", __func__, actions);
+
+    if (_UA_SEARCH_PHASE & actions)
+      _LIBCXXABI_TRACE_STATETAB1("_UA_SEARCH_PHASE ");
+    if (_UA_CLEANUP_PHASE & actions)
+      _LIBCXXABI_TRACE_STATETAB1("_UA_CLEANUP_PHASE ");
+    if (_UA_HANDLER_FRAME & actions)
+      _LIBCXXABI_TRACE_STATETAB1("_UA_HANDLER_FRAME ");
+    if (_UA_FORCE_UNWIND & actions)
+      _LIBCXXABI_TRACE_STATETAB1("_UA_FORCE_UNWIND ");
+    _LIBCXXABI_TRACE_STATETAB1(")\n");
+    _LIBCXXABI_TRACE_STATETAB("       unwind_exception=%p context=%p\n", reinterpret_cast<void*>(unwind_exception),
+                              reinterpret_cast<void*>(context));
+  }
+
+  // Start scan by getting state table address.
+  StateVariable* const state = reinterpret_cast<StateVariable* const>(_Unwind_GetLanguageSpecificData(context));
+  if (state->state <= 0) {
+    // The state is not correct - give up on this routine.
+    _LIBCXXABI_TRACE_STATETAB("state=%d and is <= 0), continue unwinding\n", state->state);
+    results.reason = _URC_CONTINUE_UNWIND;
+    return;
+  }
+  // Parse the state table.
+  FSM* const fsm = state->table;
+  FSMEntry* currFSMEntry;
+
+  if (fsm->magic != FSMMagic::number && fsm->magic != FSMMagic::number2 && fsm->magic != FSMMagic::number3) {
+    // Something is wrong with the state table we found.
+    if (_UA_SEARCH_PHASE & actions) {
+      _LIBCXXABI_TRACE_STATETAB0("Invalid FSM table, return _URC_FATAL_PHASE1_ERROR\n");
+      results.reason = _URC_FATAL_PHASE1_ERROR;
+    } else if (_UA_CLEANUP_PHASE & actions) {
+      _LIBCXXABI_TRACE_STATETAB0("Invalid FSM table, return _URC_FATAL_PHASE2_ERROR\n");
+      results.reason = _URC_FATAL_PHASE2_ERROR;
+    } else {
+      // We should never get here.
+      _LIBCXXABI_TRACE_STATETAB0("Invalid FSM table + RT Internal error, return _URC_FATAL_PHASE2_ERROR\n");
+      results.reason = _URC_FATAL_PHASE2_ERROR;
+    }
+    return;
+  }
+
+  if (_LIBCXXABI_TRACING_STATETAB) {
+    // Print the state table for debugging purposes.
+    _LIBCXXABI_TRACE_STATETAB("state->state=%d, state->ignoreVBasePtrs=%d\n", state->state, state->ignoreVBasePtrs);
+    _LIBCXXABI_TRACE_STATETAB("fsm->magic=%#x, fsm->numberOfStates=%d\n", fsm->magic, fsm->numberOfStates);
+    // Print out the FSM table.
+    _LIBCXXABI_TRACE_STATETAB0("FSM table:\n");
+    _LIBCXXABI_TRACE_STATETAB("%12s %10s %8s  %10s %7s %7s %7s %7s\n", "Entry Addr", "state", "Offset", "DTR/lpad",
+                              "count", "el_size", "flags", "next");
+    for (int i = 0; i < fsm->numberOfStates; i++) {
+      currFSMEntry = &fsm->table[i];
+      _LIBCXXABI_TRACE_STATETAB("%12p (%8d) %8ld  %10p %7ld "
+                                "%7ld %#7x %7d\n",
+                                reinterpret_cast<void*>(&currFSMEntry), i + 1, currFSMEntry->offset,
+                                reinterpret_cast<void*>(currFSMEntry->destructor),
+                                currFSMEntry->elementCount, currFSMEntry->elemSize, currFSMEntry->flags,
+                                currFSMEntry->nextState);
+    }
+  }
+
+  if (_UA_SEARCH_PHASE & actions) {
+    // Start walking the state table. Use a local copy of state->state so when
+    // we return from search phase we don't change the state number.
+    int currState = state->state;
+
+    while (currState > 0) {
+      currFSMEntry = &fsm->table[currState - 1];
+      _LIBCXXABI_TRACE_STATETAB("Processing state=%d, flags=0x%hx\n", currState, currFSMEntry->flags);
+
+      if (currFSMEntry->actionFlag == FSMEntryCount::beginCatch) {
+        // Found a catch handler.
+        if (fsm->magic == FSMMagic::number) {
+          _LIBCXXABI_TRACE_STATETAB0("Found a xlC catch handler, return _URC_FATAL_PHASE1_ERROR\n");
+          // xlC catch handlers cannot be entered because they use a
+          // proprietary EH runtime that is not interoperable.
+          results.reason = _URC_FATAL_PHASE1_ERROR;
+          return;
+        }
+        // xlclang++ compiled frames use CXA-abi EH calls and any catch
+        // block will include a catch(...) block so it is safe to assume that
+        // the handler is found without checking the catch match. The
+        // catch(...) block will rethrow the exception if there isn't a
+        // match.
+        _LIBCXXABI_TRACE_STATETAB0("Found a catch handler, return _URC_HANDLER_FOUND\n");
+        results.reason = _URC_HANDLER_FOUND;
+        return;
+      }
+      if (currFSMEntry->actionFlag == FSMEntryCount::terminate) {
+        _LIBCXXABI_TRACE_STATETAB0("Found the terminate state, return _URC_HANDLER_FOUND\n");
+        results.reason = _URC_HANDLER_FOUND;
+        return;
+      }
+      if (currFSMEntry->flags & FSMEntryFlag::oldConditionalStateChange) {
+        // Deprecated conditional expression.
+        currState = *reinterpret_cast<int*>(currFSMEntry->nextStatePtr);
+        _LIBCXXABI_TRACE_STATETAB("Flag: FSMEntryFlag::oldConditionalStateChange, dereference "
+                                  "currFSMEntry->nextStatePtr(%ld), set state=%d\n",
+                                  currFSMEntry->nextStatePtr, currState);
+        continue; // We are done this iteration of the loop, since
+                  // we changed a state.
+      }
+      if (currFSMEntry->flags & FSMEntryFlag::conditionalStateChange) {
+        void* addr = compute_addr_from_table(currFSMEntry, state, context);
+        currState = *reinterpret_cast<int*>(addr);
+        _LIBCXXABI_TRACE_STATETAB("Flag: FSMEntryFlag::conditionalStateChange, dereference "
+                                  "addr(%p), set state=%d\n", addr, currState);
+        continue; // We are done this iteration of the loop, since we
+                  // changed the state.
+      }
+      // Go to the next state.
+      currState = currFSMEntry->nextState;
+    }
+    _LIBCXXABI_TRACE_STATETAB0("No catch handler found, return _URC_CONTINUE_UNWIND\n");
+    results.reason = _URC_CONTINUE_UNWIND;
+    return;
+  }
+  if (_UA_CLEANUP_PHASE & actions) {
+    // Start walking the state table.
+    while (state->state > 0) {
+      currFSMEntry = &fsm->table[state->state - 1];
+
+      if (currFSMEntry->actionFlag == FSMEntryCount::terminate) {
+        _LIBCXXABI_TRACE_STATETAB0("Reached terminate state. Call terminate.\n");
+        std::terminate();
+      }
+      // Perform action according to the currFSMEntry->actionFlag,
+      // except when flag is FSMEntryFlag::conditionalStateChange or
+      // FSMEntryFlag::oldConditionalStateChange.
+      _LIBCXXABI_TRACE_STATETAB("Processing state=%d, flags=0x%hx\n", state->state, currFSMEntry->flags);
+      if (currFSMEntry->flags & FSMEntryFlag::oldConditionalStateChange) {
+        state->state = *reinterpret_cast<int*>(currFSMEntry->nextStatePtr);
+        _LIBCXXABI_TRACE_STATETAB("Flag: FSMEntryFlag::oldConditionalStateChange, dereference "
+                                  "currFSMEntry->nextStatePtr(%ld), set state=%d\n",
+                                  currFSMEntry->nextStatePtr, state->state);
+        continue; // We are done with this iteration of the loop, since we changed a state.
+      }
+      if (currFSMEntry->flags & FSMEntryFlag::conditionalStateChange) {
+        // A conditional state table entry holds the address of a local
+        // that holds the next state.
+        void* addr = compute_addr_from_table(currFSMEntry, state, context);
+        state->state = *reinterpret_cast<int*>(addr);
+        _LIBCXXABI_TRACE_STATETAB("Flag: FSMEntryFlag::conditionalStateChange, dereference "
+                                  "addr(%p), set state=%d\n", addr, state->state);
+        continue; // We are done with this iteration of the loop, since we changed a state.
+      }
+      if (currFSMEntry->actionFlag == FSMEntryCount::beginCatch || currFSMEntry->actionFlag == FSMEntryCount::endCatch ||
+          currFSMEntry->actionFlag == FSMEntryCount::cleanupLabel) {
+
+        _LIBCXXABI_TRACE_STATETAB(
+            "FSMEntryCount::%s: handler %p/%p, return _URC_HANDLER_FOUND\n",
+            (currFSMEntry->actionFlag == FSMEntryCount::beginCatch
+                 ? "beginCatch"
+                 : (currFSMEntry->actionFlag == FSMEntryCount::endCatch ? "endCatch" : "cleanupLabel")),
+            currFSMEntry->landingPad, *reinterpret_cast<void**>(currFSMEntry->landingPad));
+
+        state->state = currFSMEntry->nextState;
+        results.landingPad = reinterpret_cast<uintptr_t>(*reinterpret_cast<void**>(currFSMEntry->landingPad));
+        results.reason = _URC_HANDLER_FOUND;
+        return;
+      }
+      if (currFSMEntry->elementCount > 0) {
+        if (currFSMEntry->flags & FSMEntryFlag::vBaseFlag && state->ignoreVBasePtrs) {
+          _LIBCXXABI_TRACE_STATETAB0("Ignoring virtual base dtor.\n");
+        } else {
+          // We need to invoke the virtual base destructor. This must be
+          // a frame from the legacy xlC compiler as the xlclang++ compiler
+          // generates inline cleanup code rather than specifying
+          // the destructor via the state table.
+          void* addr = compute_addr_from_table(currFSMEntry, state, context);
+
+          // An extra indirect to get to the object according to the object
+          // model used by the xlC compiler.
+          addr = reinterpret_cast<void*>(*reinterpret_cast<char**>(addr));
+          _LIBCXXABI_TRACE_STATETAB("Invoke dtor for object=%p\n", addr);
+          invoke_destructor(currFSMEntry, addr);
+        }
+      } else if (currFSMEntry->actionFlag == FSMEntryCount::deleteObject) {
+        void* addr = compute_addr_from_table(currFSMEntry, state, context);
+        if (currFSMEntry->flags & FSMEntryFlag::vBaseFlag) {
+          // We need to invoke the virtual base delete function. This must be
+          // a frame from the legacy xlC compiler as the xlclang++ compiler
+          // generates inline cleanup code rather than specifying
+          // the delete function via the state table.
+
+          // An extra indirect to get to the object according to the object
+          // model used by the xlC compiler.
+          addr = reinterpret_cast<void*>(*reinterpret_cast<char**>(addr));
+        }
+        _LIBCXXABI_TRACE_STATETAB("Delete object at %p\n", addr);
+        invoke_delete(currFSMEntry, addr);
+      } else {
+        _LIBCXXABI_TRACE_STATETAB("Unknown entry in FSM (count=%ld), ignored\n",
+                                  currFSMEntry->elementCount);
+      } // End of action switching.
+
+      // Go to next state.
+      state->state = currFSMEntry->nextState;
+    }
+    _LIBCXXABI_TRACE_STATETAB0("No catch handler, return _URC_CONTINUE_UNWIND\n");
+    results.reason = _URC_CONTINUE_UNWIND;
+    return;
+  }
+  _LIBCXXABI_TRACE_STATETAB0("No state table entry for this exception, call_terminate()\n");
+  // It is possible that no state table entry specify how to handle
+  // this exception. By spec, terminate it immediately.
+  call_terminate(native_exception, unwind_exception);
+}
+
+// Personality routine for EH using the state table.
+_Unwind_Reason_Code __xlcxx_personality_v0(int version, _Unwind_Action actions, uint64_t exceptionClass,
+                                           _Unwind_Exception* unwind_exception, _Unwind_Context* context) {
+  if (version != 1 || unwind_exception == 0 || context == 0)
+    return _URC_FATAL_PHASE1_ERROR;
+
+  bool native_exception = (exceptionClass & get_vendor_and_language) == (kOurExceptionClass & get_vendor_and_language);
+  scan_results results;
+  scan_state_tab(results, actions, native_exception, unwind_exception, context);
+  if (actions & _UA_SEARCH_PHASE) {
+    // Phase 1 search:  All we're looking for in phase 1 is a handler that
+    //   halts unwinding
+    return results.reason;
+  }
+  if (actions & _UA_CLEANUP_PHASE) {
+    // Phase 2 cleanup:
+    if (results.reason == _URC_HANDLER_FOUND) {
+      // Jump to the handler.
+      _Unwind_SetGR(context, REG_EXCP_OBJ, reinterpret_cast<uintptr_t>(unwind_exception));
+      _Unwind_SetIP(context, results.landingPad);
+      return _URC_INSTALL_CONTEXT;
+    }
+    // Did not find a handler. Return the results of the scan. Normally
+    // _URC_CONTINUE_UNWIND, but could have been _URC_FATAL_PHASE2_ERROR.
+    return results.reason;
+  }
+  // We were called improperly: neither a phase 1 or phase 2 search.
+  return _URC_FATAL_PHASE1_ERROR;
+}
+} // namespace __state_table_eh
+
+// The following are EH helper functions for xlclang++ compiled code.
+
+// __xlc_catch_matchv2
+// Check whether the thrown object matches the catch handler's exception
+// declaration. If there is a match, the function returns true with adjusted
+// address of the thrown object. Otherwise, returns false.
+bool __xlc_catch_matchv2(_Unwind_Exception* exceptionObject, std::type_info* catchTypeInfo, void*& obj) {
+  _LIBCXXABI_TRACE_STATETAB("Entering %s, exceptionObject=%p\n", __func__, reinterpret_cast<void*>(exceptionObject));
+
+  if (!__isOurExceptionClass(exceptionObject)) {
+    _LIBCXXABI_TRACE_STATETAB0("No match, not a C++ exception\n");
+    return false;
+  }
+
+  __cxa_exception* exceptionHeader = 0;
+
+  if (__getExceptionClass(exceptionObject) == kOurDependentExceptionClass) {
+    // Walk to the __cxa_dependent_exception primary exception for the
+    // exception object and its type_info.
+    __cxa_dependent_exception* dependentExceptionHeader =
+        reinterpret_cast<__cxa_dependent_exception*>(exceptionObject + 1) - 1;
+    exceptionHeader = reinterpret_cast<__cxa_exception*>(dependentExceptionHeader->primaryException) - 1;
+    _LIBCXXABI_TRACE_STATETAB("exceptionObject 0x%p is a dependent, primary 0x%p\n",
+                              reinterpret_cast<void*>(exceptionObject),
+                              reinterpret_cast<void*>(&exceptionHeader->unwindHeader));
+    exceptionObject = &exceptionHeader->unwindHeader;
+  } else {
+    _LIBCXXABI_TRACE_STATETAB("exceptionObject %p is NOT a dependent\n", reinterpret_cast<void*>(exceptionObject));
+    exceptionHeader = reinterpret_cast<__cxa_exception*>(exceptionObject + 1) - 1;
+  }
+
+  void* thrownObject = reinterpret_cast<void*>(exceptionObject + 1);
+  std::type_info* throwTypeInfo = exceptionHeader->exceptionType;
+
+  // Get the type info for the thrown type and this catch clause and
+  // see if the catch caluse can catch that type.
+
+  __cxxabiv1::__shim_type_info* catchType = reinterpret_cast<__cxxabiv1::__shim_type_info*>(catchTypeInfo);
+  __cxxabiv1::__shim_type_info* throwType = reinterpret_cast<__cxxabiv1::__shim_type_info*>(throwTypeInfo);
+  _LIBCXXABI_TRACE_STATETAB("UnwindException=%p, thrownObject=%p, throwTypeInfo=%p(%s), catchTypeInfo=%p(%s)\n",
+                            reinterpret_cast<void*>(exceptionObject), thrownObject, reinterpret_cast<void*>(throwType),
+                            throwType->name(), reinterpret_cast<void*>(catchType), catchType->name());
+  if (catchType->can_catch(throwType, thrownObject)) {
+    exceptionHeader->adjustedPtr = thrownObject;
+    obj = thrownObject;
+    _LIBCXXABI_TRACE_STATETAB("Match found for thrownObject=%p\n", thrownObject);
+    return true;
+  }
+  _LIBCXXABI_TRACE_STATETAB0("No match\n");
+  return false;
+}
+
+// __xlc_throw_badexception
+// This function is for xlclang++. It allocates and throws a bad_exception.
+// During unwinding for this bad_exception, the previous exception which is
+// not matching the throw spec will be cleaned up. Thus having the same
+// effect as replace the top most exception (which is bad) with a bad_exception.
+void __xlc_throw_badexception() {
+  _LIBCXXABI_TRACE_STATETAB("Entering function: %s\n\n", __func__);
+  void* newexception = new (__cxa_allocate_exception(sizeof(std::bad_exception))) std::bad_exception;
+  __cxa_throw(newexception, const_cast<std::type_info*>(&typeid(std::bad_exception)), 0);
+}
+
+// __xlc_exception_handle
+// This function is for xlclang++. It returns the address of the exception
+// object set in gpr14 by the personality routine for xlclang++ compiled code.
+uintptr_t __xlc_exception_handle() {
+  uintptr_t exceptionObject;
+  asm("mr %0, 14" : "=r"(exceptionObject));
+  return exceptionObject;
+}
+
+// xlclang++ may generate calls to __Deleted_Virtual.
+void __Deleted_Virtual() { abort(); }
+
+// __catchThrownException is called during AIX library initialization and
+// termination to handle exceptions.  An implementation is also provided in
+// libC.a(shrcore.o).  This implementation is provided for applications that
+// link with -lc++ (the xlclang++ or ibm-clang++ link default.)
+int __catchThrownException(void (*cdfunc)(void),   // function which may fail
+                           void (*cleanup)(void*), // cleanup function
+                           void* cleanuparg,       // parameter to cleanup function
+                           int action) {           // control exception throwing and termination
+  enum Action : int { None = 0, Rethrow = 1, Terminate = 2 };
+  if (!cdfunc)
+    return 0;
+  if (action == Action::Rethrow && !cleanup) {
+    // No cleanup and rethrow is effectively no-op.
+    // Avoid the catch handler when possible to allow exceptions generated
+    // from xlC binaries to flow through.
+    (*cdfunc)();
+    return 0;
+  }
+  try {
+    (*cdfunc)();
+  } catch (...) {
+    if (action == Action::Terminate)
+      std::terminate();
+    if (cleanup)
+      (*cleanup)(cleanuparg);
+    if (action == Action::Rethrow)
+      throw;
+    assert(action == Action::None);
+    return -1; // FAILED
+  }
+  return 0;
+}
+
+}  // extern "C"
+
+}  // __cxxabiv1
diff --git a/src/cxa_personality.cpp b/src/cxa_personality.cpp
index b7ff4c2..f58d4de 100644
--- a/src/cxa_personality.cpp
+++ b/src/cxa_personality.cpp
@@ -1305,3 +1305,9 @@
 }  // extern "C"
 
 }  // __cxxabiv1
+
+#if defined(_AIX)
+// Include implementation of the personality and helper functions for the
+// state table based EH used by IBM legacy compilers xlC and xlclang++ on AIX.
+#  include "aix_state_tab_eh.inc"
+#endif
