Page MenuHomePhabricator

[compiler-rt] Add support for ARM EHABI to gcc_personality_v0.
ClosedPublic

Authored by timonvo on Dec 26 2015, 7:18 AM.

Details

Reviewers
compnerd
logan
Summary

Until now the only exception APIs supported by gcc_personality_v0
are DWARF EH and SJLJ. This adds support for ARM EHABI as well.

This is achieved by
a) changing the function signature on ARM EHABI,
b) unwinding the stack before returning _URC_CONTINUE_UNWIND.

See "Exception Handling ABI for the ARM® Architecture" for details
(http://infocenter.arm.com/help/topic/com.arm.doc.ihi0038b/IHI0038B_ehabi.pdf).

Diff Detail

Event Timeline

timonvo updated this revision to Diff 43644.Dec 26 2015, 7:18 AM
timonvo retitled this revision from to Add support for ARM EHABI exceptions to gcc_personality_v0..
timonvo updated this object.
timonvo changed the visibility from "Public (No Login Required)" to "timonvo (Timon Van Overveldt)".
timonvo changed the edit policy from "All Users" to "timonvo (Timon Van Overveldt)".
timonvo updated this object.Dec 26 2015, 7:21 AM
timonvo retitled this revision from Add support for ARM EHABI exceptions to gcc_personality_v0. to [compiler-rt] Add support for ARM EHABI exceptions to gcc_personality_v0..Dec 26 2015, 7:27 AM
timonvo retitled this revision from [compiler-rt] Add support for ARM EHABI exceptions to gcc_personality_v0. to [compiler-rt] Add support for ARM EHABI to gcc_personality_v0..Dec 26 2015, 7:33 AM
timonvo updated this object.
timonvo added a reviewer: logan.
timonvo changed the visibility from "timonvo (Timon Van Overveldt)" to "Public (No Login Required)".
timonvo changed the edit policy from "timonvo (Timon Van Overveldt)" to "All Users".
timonvo added a subscriber: llvm-commits.
logan added inline comments.Dec 26 2015, 9:38 PM
compiler-rt/trunk/lib/builtins/gcc_personality_v0.c
141 ↗(On Diff #43644)

I would suggest to use continueUnwind as the function name. This name is more consistent with libc++abi counterpart.

143 ↗(On Diff #43644)

Just be picky: Change the position of asterisk to:

struct _Unwind_Context* context
144 ↗(On Diff #43644)

I think you should declare the function prototype before using __gnu_unwind_frame().

171 ↗(On Diff #43644)

Just be picky: Change the position of asterisk to:

struct _Unwind_Context* context
182 ↗(On Diff #43644)

_US_ACTION_MASK is missing from <clang>/lib/Headers/unwind.h. You have to add it in another independent commit beforehand. Otherwise, this commit will break self-bootstrap build.

I don't understand how this works or is correct. The personality does NOT support EHABI. What is the intent for changing this? We shouldn't be generating references to this personality in EHABI AFAIK.

asl added a subscriber: asl.Dec 27 2015, 10:19 AM

I don't understand how this works or is correct. The personality does NOT support EHABI. What is the intent for changing this? We shouldn't be generating references to this personality in EHABI AFAIK.

Thanks for the quick reply. First off, let me be clear that I'm no expert on personality routines, nor the ARM EHABI spec, so if I the following does not make any sense please do tell me.

I'm trying to make Rust (https://github.com/rust-lang/rust) support producing fully statically linked ARM binaries by linking against MUSL libc (and without linking libgcc) on ARM. Because Rust's exception/unwinding semantics conveniently match C's, it leverages C's personality routine instead of building its own (see https://github.com/timonvo/rust/blob/64b90f81c3ec2cf5564ed8456d836516491b9d01/src/libstd/sys/common/unwind/gcc.rs#L58). For dynamically linked binaries it relies on libgcc's personality routine implementation, but in order to avoid libgcc with MUSL libc, I want to use the personality routine defined by compiler-rt instead. That' where the reference to this PR on ARM EHABI would come from.

As you correctly stated, I believe the personality routine definitely does not support ARM EHABI in its current state. I do believe however, that my changes should make it correctly support it. I've read the ARM EHABI spec, as well as looked at GCC's implementation of the C personality routine on ARM EHABI. AFAICT, the main difference between an ARM EHABI PR and a regular Dwarf-based PR is that ARM EHABI expects the PR to unwind the stack before continuing. In fact, I believe most differences lie in the actual unwinding layer, and that those are all already handled in libunwind's EHABI implementation.

I believe that the format of the language-specific data is still the same for both types of exceptions, and hence, the remainder of the code in the personality routine can be preserved/reused. Because LLVM's libunwind already stores all the information it needs in the context variable, we don't even have to preserve or store somewhere the "exceptionObject" like GCC's personality routine does (https://github.com/gcc-mirror/gcc/blob/d353bf189d2bbaf4059f402ee4d2a5ea074c349f/libgcc/unwind-c.c#L141). That link also shows GCC's implementation, and I believe it supports my interpretation of things.

However LLVM just does not want to add support for EHABI in this personality routine because it itself would not normally emit references to it, then perhaps I'll have to land these changes downstream in Rust's copy. I was hoping to avoid that though.

@logan: I plan to address your comments soon. Thanks for the swift reply!

P.S.: I believe that https://github.com/rust-lang/compiler-rt/commit/b6087e82ba1384c4af3adf2dc68e92316f0d4caf also indicates that the current implementation is broken for SJLJ-based exceptions.

There seems to be a couple of items of confusion here (at least to me).

SjLj EH isn't part of this routine (that personality is __gcc_personality_sj0 and is pretty different in behavior).

Yes, you are correct that most of the details of unwinding on ARM will be taken care of by the unwinder. Also, neighter LLVM nor GCC would produce references to this personality routine, so it seems odd to support this.

Why is it unsafe to use the well defined personality routines for ARM and rust? They are required for unwinding to work on ARM. The index and unwind tables have to be generated specifically for use with them, so the code generation is already aware of the existence.

AIUI, LSDA here is not relevant as that is handled by the language dependent portion. If that is similar so be it, I don't think that should have any bearings on the right approach here.

Simply registering a different personality routine based on the function should give you the correct behavior if I'm not mistaken (remember that the table encoding matters and you switch between one of the three personalities!).

Finally, I think that if you generate the personality references correctly on the rust side, you won't need the __gcc_personality_v0 unless there is C code trying to handle exceptions.

logan edited edge metadata.Dec 28 2015, 4:31 PM

Also, neighter LLVM nor GCC would produce references to this personality routine, so it seems odd to support this.

No. Both GCC and LLVM do generate references to __gcc_personality_v0 with __attribute__((cleanup(func))) when the command line option -fexceptions is given. For example,

#include <stdio.h>

extern void may_throw();

void my_cleanup(int *p) {
  printf("%d\n", *p);
}

void test() {
  int a __attribute__((cleanup(my_cleanup))) = 10;
  may_throw();
}

Why is it unsafe to use the well defined personality routines for ARM and rust? They are required for unwinding to work on ARM. The index and unwind tables have to be generated specifically for use with them, so the code generation is already aware of the existence.

Which well-defined personality routines are you referring to? Are you referring to the C++ one, i.e. __gxx_personality_v0()? I guess that they don't need the complexity of the complete C++ personality.

Finally, I think that if you generate the personality references correctly on the rust side, you won't need the __gcc_personality_v0 unless there is C code trying to handle exceptions.

I am not familiar with the Rust compiler. However, I believe they are leveraging LLVM code generators to translate landingpad instructions to exception handlers, LSDA, etc. In the other words, they are not generating LSDA by themselves. Besides, LLVM will only generate either Dwarf or SJLJ LSDA, so IMO it is OK to reuse __gcc_personality_v0 if Rust compiler (or ABI) does not have extra requirements on the personality function.

BTW, I don't think there is any problem to fix the personality for C language.

emaste added a subscriber: emaste.Dec 28 2015, 7:59 PM

I didn't mean to imply the C++ personality. The reconfiguration of the C personality makes things harder IMO. Now you need to rebuild the library if something changes and control that. If you absolutely must use this approach, why not introduce a new routine that dispatches as you want (just to be clear this would be different from the language specific personality)? The entire thing with the personalities is that they handle things one way only and you switch the one that is used.

SjLj EH isn't part of this routine (that personality is __gcc_personality_sj0 and is pretty different in behavior).

Right, but compiler-rt's gcc_personality_v0.c *does* use the function name __gcc_personality_sj0 instead, if that type of unwinding is requested, see line 147 (https://github.com/llvm-mirror/compiler-rt/blob/master/lib/builtins/gcc_personality_v0.c#L147). However, besides changing the function name, it uses the exact same implementation for SJLJ based exceptions. This seems wrong, and this seems to be what that Rust patch I linked to addresses.

Finally, I think that if you generate the personality references correctly on the rust side, you won't need the __gcc_personality_v0 unless there is C code trying to handle exceptions.

I am not familiar with the Rust compiler. However, I believe they are leveraging LLVM code generators to translate landingpad instructions to exception handlers, LSDA, etc. In the other words, they are not generating LSDA by themselves. Besides, LLVM will only generate either Dwarf or SJLJ LSDA, so IMO it is OK to reuse __gcc_personality_v0 if Rust compiler (or ABI) does not have extra requirements on the personality function.

Right. I believe that's exactly what's happening. I'm not very familiar with Rust's code generation details though.

BTW, I don't think there is any problem to fix the personality for C language.

Right. Do you mean that, since GCC/Clang *will* generate references to __gcc_personality_v0 if the cleanup attribute is used, this personality should indeed be fixed to support ARM EHABI, regardless of whether Rust needs it? I do think that's the case, because I can't see how this personality routine would ever work for C code generated for ARM EHABI. Just the difference in function signature will lead to corrupt memory accesses if this isn't fixed.

I didn't mean to imply the C++ personality. The reconfiguration of the C personality makes things harder IMO. Now you need to rebuild the library if something changes and control that. If you absolutely must use this approach, why not introduce a new routine that dispatches as you want (just to be clear this would be different from the language specific personality)?

Are you suggesting having a single PR for C that dispatches to the ARM EHABI PR, the Dwarf PR, the SJLJ PR, depending on which macros are defined? You could do that, but since there's no single function signature that's common between all 3 of those PRs, you'd still end up with a bunch of #ifdefs. Using #ifdefs to switch out whole function implementations rather than using #ifdefs within the function body may make the code a littel cleaner though. Or, if you meant something else, could you elaborate further?

Either way if my understanding is correct that this personality routine would *also* be used by C anyway if the cleanup attribute is used, then we have to support unwinding in C for ARM EHABI somehow, right? I guess another option would be for Clang to be changed to output references to an EHABI specific routine instead, but we can't really change GCC's behavior, so I believe that would go against Clang's binary compatibility with GCC.

The entire thing with the personalities is that they handle things one way only and you switch the one that is used.

I think it's correct to assume that if one compilation unit uses one style of exceptions (e.g. ARM EHABI), then the whole binary must use that style throughout, right? Hence, every reference to the C PR should be expecting it to be handling the same style of exceptions. Therefore the invariant that PR's "handle things one way only" will be satisfied, within the scope of that binary at least.

Perhaps the fact that GCC does implement multiple versions of this routine depending on the target arch, just like this CL is trying to, is telling that this is the best way to go?

logan added a comment.Dec 29 2015, 8:11 AM

I didn't mean to imply the C++ personality. The reconfiguration of the C personality makes things harder IMO. Now you need to rebuild the library if something changes and control that. If you absolutely must use this approach, why not introduce a new routine that dispatches as you want (just to be clear this would be different from the language specific personality)? The entire thing with the personalities is that they handle things one way only and you switch the one that is used.

I feel the discussion is diverged. That's the reason why I can't get your points. If I comprehend the thread correctly, two topics are mentioned:

  1. The compiler-rt implementation of __gcc_personality_v0() is not following ARM EHABI convention.
  1. Rather the compiler or run-time for Rust programming language should define their own personality function or not.

However, IMO, the second topic is irrelevant to this patch. Although this issue is reported by the Rust community, it reveals a general problem in compiler-rt for C programming language. Defining a Rust-specific personality won't fix the C programming language side.

Thus, I would like to focus on the first topic. My arguments are based on these two questions:

1. When will clang or gcc generate references to __gcc_personality_v0()?

The answer to this question is simple and easy to verify. Simply write a program with __attribute__((cleanup(function))) and compile the program with gcc -fexceptions:

$ cat > test.c <<__EOF__
#include <stdio.h>

extern void may_throw();

void my_cleanup(int *p) {
  printf("%d\n", *p);
}

void test() {
  int a __attribute__((cleanup(my_cleanup))) = 10;
  may_throw();
}
__EOF__

Compile the program with -fexceptions:

$ gcc -fexceptions test.c -S

Check the output:

$ grep __gcc_personality_v0 test.s
	.cfi_personality 0x3,__gcc_personality_v0
	.globl	__gcc_personality_v0

2. Is __gcc_personality_v0() working on ARM? If it is not working, how do we fix it?

I don't have time to give it a trail these days. But I would speculate it won't work on ARM platform. Its function signature and its behavior are not conforming to the ARM EHABI specification, which most unwinders assume.

To get this work, we have to have a slightly different implementation of __gcc_personality_v0() for ARM platform. That's the reason why we need those #ifdefs. I won't call these as reconfiguration, since this is the correct way to define a personality on normal ARM platform.

In detail, to fix __gcc_personality_v0() for ARM, we have to:

  1. Change the function signature.
  1. Unwind the virtual frame before returning _URC_CONTINUE_UNWIND.

And this patch is exactly addressing these issues.

I agree that there are multiple points of discussion here. Focusing solely on __gcc_personality_v0 is probably prudent.

I don't think that anyone has shown that the current implementation does not work on ARM. I recall using the current implementation during testing on ARMv7. I may be mistaken, so we should double check that.

The reason that I'm unhappy about changing the signature here is because this is not a generic routine, it is a language specific implementation. The change actually breaks ABI.

The reason that you are able to generate references in your example is due to the C specific exception handling. It is similar to using C++ with exceptions and seeing references to __gxx_personality_v0.

AFAIR, EHABI has no bearing on the language specific handling which is why it doesn't matter if this routine doesn't match its signature.

I agree that there are multiple points of discussion here. Focusing solely on __gcc_personality_v0 is probably prudent.

I don't think that anyone has shown that the current implementation does not work on ARM. I recall using the current implementation during testing on ARMv7. I may be mistaken, so we should double check that.

I have actually verified that with my work on Rust. However, I'm working on providing a minimal reproducible example with plain C to show this is broken.

The reason that I'm unhappy about changing the signature here is because this is not a generic routine, it is a language specific implementation.

Which, depending on the type of exceptions being targeted, *must* have a different signature (Dwarf, SJLJ, EHABI). Note that it is *not* the C spec which defines what the function signature of the C PR must look like. It is the chosen language-independent exception ABI that defines that (see below for more details).

The change actually breaks ABI.

Yes, this breaks ABI with previous versions. But I'm arguing that previous versions' ABI was broken on ARM EHABI.

The reason that you are able to generate references in your example is due to the C specific exception handling. It is similar to using C++ with exceptions and seeing references to __gxx_personality_v0.

AFAIR, EHABI has no bearing on the language specific handling which is why it doesn't matter if this routine doesn't match its signature.

Well, while the ARM EHABI spec does leave room for language-specific handling of exceptions, it does actually specify a) how personality routines are called, b) those personality routines' signatures (regardless of target language).

From the ARM EHABI doc, Sec 6.1:

The language-independent unwinding library described in §7 calls the personality routine to unwind a single stack
frame. The arguments passed to the personality routine contain pointers to the function being unwound and its
exception-handling table entry (see §7.2).

The language-independent unwinding library would be LLVM's libunwind in this case.

The personality routine calls back to the language-independent unwinding library for various services, and calls a
language-semantics library to maintain the particular language semantics.

This allows the PR to implement its language-specific functionality.

Conceptually, an exception-handling table entry begins with the address of the personality routine:

/* See §7.2 for details of the various _Unwind types */
typedef _Unwind_Reason_Code (*PersonalityRoutine)(_Unwind_State,
         _Unwind_Control_Block *,
         _Unwind_Context *);

This is the prescribed function signature that *all* PRs must have, since all PRs across all langauges will be called by the same language-independent library. Note that LLVM's libunwind, if built for ARM EHABI, already expects the above signature today for all PRs it will call: https://github.com/llvm-mirror/libunwind/blob/master/src/Unwind-EHABI.cpp#L514

Anyway, stay tuned for an example showing the current routine is broken on EHABI.

Please take a look at https://github.com/timonvo/compiler-rt/tree/arm-personality-routine-llvm-w-test. It contains both this patch as well as a test_pr.sh script for running the already existing personality routine tests on ARM (the one under test/builtins/Unit). You can compare the branch against the master compiler-rt branch here: https://github.com/llvm-mirror/compiler-rt/compare/master...timonvo:arm-personality-routine-llvm-w-test.

Note that this test relies on qemu-arm, as well as a functional arm-linux-gnueabi-{gcc,g++} toolchain. That means it uses GCC, not Clang, but that shouldn't matter. It uses LLVM's libunwind library, and obviously it tests compiler-rt's personality routine implementatin, not GCC's, and that's what matters.

When you revert the ARM EHABI patch, the test fails with a SIGSEGV (due to the mismatching function signatures). The stack trace for the segfault is;

(gdb) bt
#0  0x00015a64 in unw_get_proc_info (cursor=0x1, info=0xf6ffeac4) at libunwind/src/libunwind.cpp:242
#1  0x00012d2c in _Unwind_GetLanguageSpecificData (context=0x1) at libunwind/src/Unwind-EHABI.cpp:762
#2  0x0001120c in __gcc_personality_v0 (version=0, actions=196408, exceptionClass=300943912463320, exceptionObject=0xbc, context=0x1) at gcc_personality_v0.c:163
#3  0x00012434 in unwind_phase1 (uc=0xf6fff270, exception_object=0x2ff38) at libunwind/src/Unwind-EHABI.cpp:514
#4  0x00012b88 in _Unwind_RaiseException (exception_object=0x2ff38) at libunwind/src/Unwind-EHABI.cpp:715

But that really doesn't matter much. The segfault is caused by the incompatible function signature causing corrupt memory accesses further down the stack.

However, when you do apply the patch, the test does succeed. Does that make it clear why this patch is needed?

logan added a comment.Jan 4 2016, 7:12 AM

Sorry for the late reply. I spent sometime to setup the testing environment.

I don't think that anyone has shown that the current implementation does not work on ARM. I recall using the current implementation during testing on ARMv7. I may be mistaken, so we should double check that.

From my independent experiment, I can confirm the crash as well. I have created a bug report and uploaded the test case to:
http://llvm.org/PR26012

I guess __attribute__((cleanup())) was not tested earlier.

The reason that I'm unhappy about changing the signature here is because this is not a generic routine, it is a language specific implementation. The change actually breaks ABI.

The reason that you are able to generate references in your example is due to the C specific exception handling. It is similar to using C++ with exceptions and seeing references to __gxx_personality_v0.

AFAIR, EHABI has no bearing on the language specific handling which is why it doesn't matter if this routine doesn't match its signature.

Although ARM EHABI does not specify the detail of other personality functions. However, it does specify the interface and the protocol between the personality function and the unwinder. Otherwise, the unwinder won't be able to communicate with the personality function.

IMO, @timonvo gave a good summary in D15781#318066 which I wish to write down before seeing his reply.

logan added a comment.Jan 4 2016, 7:18 AM

Hi @timonvo,

I have tested your patch. It can't be compiled with clang because several types and defines are missing from <clang>/lib/Headers/unwind.h. Thus, submitting this patch will break all self-bootstrapping build.

Please add following symbols to <clang>/lib/Headers/unwind.h in an independent commit beforehand:

--- a/lib/Headers/unwind.h
+++ b/lib/Headers/unwind.h
@@ -79,6 +79,7 @@ struct _Unwind_Context;
 struct _Unwind_Exception;
 typedef enum {
   _URC_NO_REASON = 0,
+  _URC_OK = 0,
   _URC_FOREIGN_EXCEPTION_CAUGHT = 1,
 
   _URC_FATAL_PHASE2_ERROR = 2,
@@ -88,7 +89,8 @@ typedef enum {
   _URC_END_OF_STACK = 5,
   _URC_HANDLER_FOUND = 6,
   _URC_INSTALL_CONTEXT = 7,
-  _URC_CONTINUE_UNWIND = 8
+  _URC_CONTINUE_UNWIND = 8,
+  _URC_FAILURE = 9
 } _Unwind_Reason_Code;
 
 typedef enum {
@@ -150,6 +152,13 @@ typedef enum {
   _UVRSR_FAILED = 2
 } _Unwind_VRS_Result;
 
+typedef uint32_t _Unwind_State;
+#define _US_VIRTUAL_UNWIND_FRAME  ((_Unwind_State)0)
+#define _US_UNWIND_FRAME_STARTING ((_Unwind_State)1)
+#define _US_UNWIND_FRAME_RESUME   ((_Unwind_State)2)
+#define _US_ACTION_MASK           ((_Unwind_State)3)
+#define _US_FORCE_UNWIND          ((_Unwind_State)8)
+
 _Unwind_VRS_Result _Unwind_VRS_Get(struct _Unwind_Context *__context,

Thanks Logan. I'll format patch and send it out for review tonight.

timonvo updated this revision to Diff 43962.Jan 4 2016, 9:58 PM
timonvo edited edge metadata.

Updated the diff to address logan's comments.

Note that I've also got another review out (http://reviews.llvm.org/D15883) to add the various constants this patch needs to clang's unwind.h header, as logan asked.

timonvo marked 4 inline comments as done.Feb 15 2016, 1:17 PM

Could someone please take a look at this patch as well as http://reviews.llvm.org/D15883? Thanks!

compnerd added inline comments.Feb 15 2016, 2:33 PM
lib/builtins/gcc_personality_v0.c
148

The braces are unnecessary. Did you run this through clang-format?

185

Shouldn't this be:

if ((state & _US_ACTION_MASK) != _US_UNWIND_FRAME_STARTING)
197

I think we should move the USING_ARM_EABI check into the continueUnwind and have it do the right thing so we can avoid the check here and below.

timonvo updated this revision to Diff 48023.Feb 15 2016, 3:28 PM

Addressed compnerd's latest comments.

timonvo marked 3 inline comments as done.Feb 15 2016, 3:35 PM
timonvo added inline comments.
lib/builtins/gcc_personality_v0.c
148

I did run it through clang-format now (although I used an IndentWidth of 4 rather than the 2 LLVM style prescribes, because the rest of this file is already formatted that way).

185

I believe what I have is correct. In short _US_VIRTUAL_UNWIND_FRAME is the equivalent of _UA_SEARCH_PHASE on other architectures. GCC's implementation has similar logic as well.

This is discussed in http://infocenter.arm.com/help/topic/com.arm.doc.ihi0038b/IHI0038B_ehabi.pdf, Sec 7.3. During Phase 1, the unwinder '... calls the PR, passing state
_US_VIRTUAL_UNWIND_FRAME, the UCB pointer, and an _Unwind_Context pointer for VRS access.' It's only during Phase 2 that the unwinder calls the PR with _US_UNWIND_FRAME_STARTING. During that phase we have to make sure that we call the landing pad if it exists, hence we can't bail early anymore here.

timonvo marked 4 inline comments as done.Feb 15 2016, 3:47 PM
logan added inline comments.Feb 28 2016, 7:34 AM
lib/builtins/gcc_personality_v0.c
185

@timonvo: What will happen if _US_UNWIND_FRAME_RESUME is passed to this personality function? I think it should not search for landing pads and install the context. Am I wrong? Thanks.

timonvo updated this revision to Diff 49706.Mar 2 2016, 9:23 PM

Only search for landing pads during _US_UNWIND_FRAME_STARTING.

This ensures we don't search for them again during _US_UNWIND_FRAME_RESUME, as
@logan and @compnerd highlighted.

timonvo added inline comments.Mar 2 2016, 9:25 PM
lib/builtins/gcc_personality_v0.c
185

You (and @compnerd earlier) were right, what I had did not take into account the _US_UNWIND_FRAME_RESUME step of phase2. I've updated the code, now it should continue on the next frame during every step *except* _US_UNWIND_FRAME_STARTING.

logan accepted this revision.Mar 6 2016, 3:05 PM
logan edited edge metadata.

Look good to me.

p.s. I will wait for 3 days before committing this for you so that other people can get their chances to add their comments.

This revision is now accepted and ready to land.Mar 6 2016, 3:05 PM
logan added a comment.Mar 6 2016, 3:06 PM

Note: I have tested this change on Debian Jessie (armhf). It works without problems.

Thanks for the review Logan! I look forward to seeing this get committed.

compnerd accepted this revision.Mar 7 2016, 9:08 PM
compnerd added a reviewer: compnerd.

Thanks for sticking with this through all the discussion.

logan added a comment.Mar 9 2016, 5:29 AM

Committed as rL263010.

Thanks for your hard work.

(p.s. This is expected to break some ARM self-bootstrapping build bots if they are compiling with old clang and unwind.h. I will contact the build bot owner to figure out the resolution.)

logan closed this revision.Mar 14 2016, 6:01 AM