Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

[ARM64/Unix] #9500

Merged
merged 24 commits into from
Feb 17, 2017
Merged

[ARM64/Unix] #9500

merged 24 commits into from
Feb 17, 2017

Conversation

sdmaclea
Copy link

Patches to support correct ARM64 functional behaviour on Ubuntu 16.04

@janvorli

@@ -46,27 +46,27 @@ LOCAL_LABEL(donestack):

// If FP arguments are supplied in registers (x8 != NULL) then initialize all of them from the pointer
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please fix the comment to refer to r9 instead of r8.

@@ -8,6 +8,7 @@
//

#include "unixasmmacros.inc"
#include "asmconstants.h"

#define CONTEXT_ARM64 0x00400000L
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please move these constants to the asmconstants.h too to match the amd64 version of this file?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure

EMIT_BREAKPOINT
// Save the FP & LR to the stack so that the unwind can work at the instruction after
// loading the FP from the context, but before loading the SP from the context.
stp fp, lr, [sp, -16]!
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A nit - can you please keep the parameter indentation uniform in the function?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure

// loading the FP from the context, but before loading the SP from the context.
stp fp, lr, [sp, -16]!

ldr x19, [x0, #(CONTEXT_X19)]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason for not using ldp here?

C_FUNC(\Name\()_End):
.global C_FUNC(\Name\()_End)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was this change necessary? We have the .global before the label on amd64, so if it was just a cosmetic change, I would prefer reverting it to keep the look consistent with amd64.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At the time I was trying to remove cosmetic difference between amd64 and arm64. I'll take a look.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just confirmed that this currently matches amd64.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am sorry, you're right. I don't know at what I was looking before.

@@ -264,7 +264,7 @@ WRITE_BARRIER_END JIT_CheckedWriteBarrier
//
WRITE_BARRIER_ENTRY JIT_WriteBarrier
dmb ST
str x15, [x14]
str x15, [x14]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A nit - this change breaks the indentation, I guess it was just accidental.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK

PROLOG_SAVE_REG_PAIR x23, x24, #48
PROLOG_SAVE_REG_PAIR x25, x26, #64
PROLOG_SAVE_REG_PAIR x27, x28, #80
NESTED_ENTRY OnHijackTripThread, _TEXT, NoHandler
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The NESTED_ENTRY should not be indented to keep it in line with the other functions in this file. And the same for the NESTED_END.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK

{
pAbortContext->Fp = pContextRecord->Fp;
}
UPDATEREG(Fp);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this will likely break Windows ARM64 that according to the comment don't have Fp in current context pointers pointing to a location of the Fp.
CC: @rahku

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can add a #ifdef FEATURE_PAL around it until it is fixed on Windows.

This appeared to be a required fix for Unix.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess I am actually mistaken. I have read the comment that was there before as "the unwinder doesn't set the context pointer for Fp", which would mean that it is not being set in the unwinder inside of windows that we use. But reading it again, it seems that it actually means that it just requires changes to the MachState that you have made, so it should probably be ok.
@rahku, @gkhanna79 - am I right?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe you are correct. @rahku should comment why MachState didnt support FP earlier, though, before we enable the change for both platforms.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes this looks good. It was a mistake to not add FP in MachState earlier which was fixed but this code was not fixed.

// On PAL, we don't always have the context pointers available due to
// a limitation of an unwinding library. In such case, preserve
// the unwound values.
CalleeSavedRegisters m_Unwound;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not needed for ARM64. The reason we have it for AMD64 is OSX which uses a different libunwind (the one that's part of the LLVM) that doesn't support unw_get_save_loc. See https://github.com/dotnet/coreclr/pull/527/files.

@@ -1778,7 +1778,7 @@ StackWalkAction StackFrameIterator::Filter(void)
pCurrTracker = pCurrTracker->GetPreviousExceptionTracker();
}

if (pCurrTracker != NULL)
if ((pCurrTracker != NULL) && !pCurrTracker->IsEHClauseFilter())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you have a repro for this issue? I would like to see what's going on here and see why we don't hit this problem on amd64.
It looks suspicious based on the comment at line 1743 that I've added when I was implementing the Unix exception handling at the beginning of the opensourcing of .net core.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I was debugging this test

JIT/Methodical/eh/basics/throwinfilter_d/throwinfilter_d.exe

The issue happened in the nested call to IL_Throw.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is not the correct fix, then it should be changed to an assert to detect this unexpected condition.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will look into it first.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have tried to run the test on amd64 with GC stress mode C and this "if" was never entered. Could you please verify that the issue really happened in the JIT/Methodical/eh/basics/throwinfilter_d/throwinfilter_d.exe test?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I saw it with this config

env | grep COMPlus
COMPlus_GCStress=2

Here is the gdb log from my AMD64 run

(gdb) b IL_Throw
Function "IL_Throw" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 1 (IL_Throw) pending.
(gdb) r
Starting program: /home/sdmaclea/tests-2017-01-11/Tests/coreoverlay/corerun /home/sdmaclea/test/JIT/Methodical/eh/basics/throwinfilt
er_d/throwinfilter_d.exe
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[New Thread 0x7ffff45d2700 (LWP 23557)]
[New Thread 0x7ffff3dd1700 (LWP 23558)]
[New Thread 0x7ffff35d0700 (LWP 23559)]
[New Thread 0x7ffff2dcf700 (LWP 23560)]
[New Thread 0x7ffff25ce700 (LWP 23561)]
[New Thread 0x7ffff1da2700 (LWP 23562)]
In try, throwing the first obj

Thread 1 "corerun" hit Breakpoint 1, IL_Throw (obj=0x7fff5c01ada0) at /home/sdmaclea/git/coreclr/src/vm/jithelpers.cpp:5374
(gdb) b stackwalk.cpp:1768
Breakpoint 2 at 0x7ffff5e0aa4d: file /home/sdmaclea/git/coreclr/src/vm/stackwalk.cpp, line 1768.
(gdb) c
Continuing.

Thread 1 "corerun" hit Breakpoint 2, StackFrameIterator::Filter (this=0x7fffffff9680) at /home/sdmaclea/git/coreclr/src/vm/stackwalk
.cpp:1768
(gdb) display pCurrTracker
1: pCurrTracker = (ExceptionTracker *) 0x0
(gdb) cond 2 pCurrTracker
(gdb) c
Continuing.
In filter

Thread 1 "corerun" hit Breakpoint 1, IL_Throw (obj=0x7fff5c01ada0) at /home/sdmaclea/git/coreclr/src/vm/jithelpers.cpp:5374
(gdb) c
Continuing.

Thread 1 "corerun" hit Breakpoint 2, StackFrameIterator::Filter (this=0x7fffffff6ae0) at /home/sdmaclea/git/coreclr/src/vm/stackwalk
.cpp:1768
1: pCurrTracker = (ExceptionTracker *) 0x67ae00
(gdb) print pCurrTracker->IsEHClauseFilter()
$1 = true

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sdmaclea I can repro the GC hole on amd64 too with GCStress 2. Let me get my head around the exact way it happens. It seems it would make sense to remove this commit from this PR and create a separate PR for it so that we can merge in the remainder of the commits without unnecessary delay.

@sdmaclea
Copy link
Author

I believe all clear comments are handled with my latest push

@sdmaclea
Copy link
Author

@janvorli How do I remove this commit from the pull request? Do you want me to append a revert of this commit?

@janvorli
Copy link
Member

@sdmaclea you can use interactive rebase to remove the commit and then force push your changes to origin. But adding a commit that reverts the change would be ok too.

@sdmaclea
Copy link
Author

OK that should be the identical code without the GCStress=2 commit.

Do you want me to upload the other patch as a separate PR?

Copy link
Member

@janvorli janvorli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thank you!

Copy link
Author

@sdmaclea sdmaclea left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@janvorli

This is all whitespace

git diff -w HEAD~1..HEAD

@janvorli
Copy link
Member

@dotnet-bot test Ubuntu x64 Checked Build and Test please

@janvorli
Copy link
Member

@dotnet-bot test Linux ARM Emulator Cross Debug Build please

@janvorli janvorli merged commit 9baa44a into dotnet:master Feb 17, 2017
@sdmaclea
Copy link
Author

@janvorli Thanks

@sdmaclea sdmaclea deleted the PR-ARM64-UNIX branch February 17, 2017 18:53
@janvorli
Copy link
Member

And thank you a lot for all the great work you did on that!

@jashook
Copy link

jashook commented Feb 17, 2017

@dotnet/arm64-contrib It looks like this commit broke the arm64 Windows_NT build.

Is anyone looking into this?

@@ -89,7 +89,11 @@ ASMCONSTANTS_C_ASSERT(MachState__isValid == offsetof(MachState, _isValid))
#define LazyMachState_captureX19_X29 MachState__captureX19_X29
ASMCONSTANTS_C_ASSERT(LazyMachState_captureX19_X29 == offsetof(LazyMachState, captureX19_X29))

#ifdef FEATURE_PAL
#define LazyMachState_captureSp (MachState__isValid+8+12*8) // padding for alignment & m_Unwound
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sdmaclea I have missed this before - since the m_Unwound was removed, this should be different, right?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sdmaclea oops, sorry for the false alarm. I was looking at each commit separately and right after I have written the comment, I have realized that this was removed by another commit.

PKNONVOLATILE_CONTEXT_POINTERS ContextPointers;
} ARM64_UNWIND_PARAMS, *PARM64_UNWIND_PARAMS;

#define UNWIND_PARAMS_SET_TRAP_FRAME(Params, Address, Size)

#define UPDATE_CONTEXT_POINTERS(Params, RegisterNumber, Address)
#define UPDATE_FP_CONTEXT_POINTERS(Params, RegisterNumber, Address)
#define UPDATE_CONTEXT_POINTERS(Params, RegisterNumber, Address) \
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jashook

@jashook @janvorli
There are only a few files touched which I expect to be shared by Windows. Based on the build failures, my guess is it is this change to src/unwinder/arm64/unwinder_arm64.cpp

These lines probably need to be marked with #ifdef FEATURE_PAL

I was surprised to see these failures, but looks like there was no premerge run against Windows arm64. It was run against arm and x86 only.

I'll create a PR if you want and you can see if it fixes WinArm64

@@ -89,11 +89,7 @@ ASMCONSTANTS_C_ASSERT(MachState__isValid == offsetof(MachState, _isValid))
#define LazyMachState_captureX19_X29 MachState__captureX19_X29
ASMCONSTANTS_C_ASSERT(LazyMachState_captureX19_X29 == offsetof(LazyMachState, captureX19_X29))

#ifdef FEATURE_PAL
#define LazyMachState_captureSp (MachState__isValid+8+12*8) // padding for alignment & m_Unwound
#else
#define LazyMachState_captureSp (MachState__isValid+8) // padding for alignment
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@janvorli I thought it was removed here. Did I miss something?

sdmaclea added a commit to sdmaclea/coreclr that referenced this pull request Feb 18, 2017
@janvorli
Copy link
Member

@sdmaclea, @jashook I am sorry, I wanted to run the Win ARM64 test run and then unfortunately forgotten about it.

#define UPDATE_CONTEXT_POINTERS(Params, RegisterNumber, Address) \
do { \
if (ARGUMENT_PRESENT(Params)) { \
PKNONVOLATILE_CONTEXT_POINTERS ContextPointers = (Params)->ContextPointers; \
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume the fix to the build break is to use the type PT_KNONVOLATILE_CONTEXT_POINTERS instead of PKNONVOLATILE_CONTEXT_POINTERS. @janvorli this type is correctly shared between both the windows SDK and the PAL correct?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The original code was a nop. #9663 restores that behavior.

For Unix, the calling code was change to provide the necessary support of copying the pointers. It seems bad to implement for Windows without any testing.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, well, for what it is worth, I have successfully built with PT_KNONVOLATILE_CONTEXT_POINTERS.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think the PT_KNONVOLATILE_CONTEXT_POINTERS vs PKNONVOLATILE_CONTEXT_POINTERS is a problem here. The _ARM64_UNWIND_PARAMS in this file was using PKNONVOLATILE_CONTEXT_POINTERS before this change.
Where can I take a look at the build error?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@janvorli
Copy link
Member

@jashook actually, you are right. And all the PKNONVOLATILE_CONTEXT_POINTERS should be changed to PT_KNONVOLATILE_CONTEXT_POINTERS, since it is currently wrong. This change just uncovered the problem, we were not accessing any members of the struct before and so it was not a problem that the struct actually is a AMD64 version (the build error happens during building cross tools that run on amd64, but target arm64).

@sdmaclea
Copy link
Author

Since I have been natively compiling, I didn't see the issue. Sound like I should also test a cross compiled build to look for other errors...

I am happy to prepare the patch .... I'll even cross build on amd64...

@janvorli
Copy link
Member

@sdmaclea that would be great. Although I am not sure if crossbuild for ARM64 works on AMD64 Linux yet. I used to have some problems with the rootfs creation in the past.

sdmaclea added a commit to sdmaclea/coreclr that referenced this pull request Mar 15, 2017
rahku pushed a commit that referenced this pull request Apr 4, 2017
hadibrais pushed a commit to hadibrais/coreclr that referenced this pull request Apr 7, 2017
jorive pushed a commit to guhuro/coreclr that referenced this pull request May 4, 2017
* [Arm64/Unix] Update arm64 *.S files to match *.asm

* [Arm64/Unix] Fix CONTEXTToNativeContext()

* [Arm64/Unix] ThrowExceptionFromContextInternal

* [Arm64/Unix] Preserve x8 argument register

* [ARM64/Unix] Add CFI directives

Add native unwind info

* [Arm64/Unix] Fix RtlRestoreContext

* [Arm64/Unix] Restore FP from CurrentContextPointers

* [Arm64/Unix] fix pointer math

* [Arm64/Unix] Fix CallDescrWorkerInternal personality

* [Arm64/Unix] More Fp fixups

* [Arm64/Unix] CallEHFunclet machine state

Restore non-volatile machine state in CallEHFunclet

* [Arm64/Unix] CallDescrWorkerInternal

Use empty stack slot to save argument

* [Arm64/Unix] RtlVirtualUnwind update pointers

* [Arm64] LazyMachState fixes

* [Arm64/Unix] disable USE_REDIRECT_FOR_GCSTRESS

When FEATURE_PAL is enableds USE_REDIRECT_FOR_GCSTRESS
is not supported

* [Arm64] ClearRegDisplayArgumentAndScratchRegisters()

* [Arm64] Remove unnecesary copy in TransitionFrame

* [Arm64/Unix] Fix comment per review

* [Arm64/Unix] move constants per review

* [Arm64/Unix] Use ldp per review

Also fix indentation

* [Arm64/Unix] Fix indentation per review

* [Arm64/Unix] Remove m_Unwound per review comments

* [Arm64/Unix] Use PREPARE_EXTERNAL_VAR to access globals

* [Arm64/Unix] Fix more whitespace per earlier review comments
@karelz karelz modified the milestone: 2.0.0 Aug 28, 2017
@xiangzhai
Copy link

:mips-interest

picenka21 pushed a commit to picenka21/runtime that referenced this pull request Feb 18, 2022
* [Arm64/Unix] Update arm64 *.S files to match *.asm

* [Arm64/Unix] Fix CONTEXTToNativeContext()

* [Arm64/Unix] ThrowExceptionFromContextInternal

* [Arm64/Unix] Preserve x8 argument register

* [ARM64/Unix] Add CFI directives

Add native unwind info

* [Arm64/Unix] Fix RtlRestoreContext

* [Arm64/Unix] Restore FP from CurrentContextPointers

* [Arm64/Unix] fix pointer math

* [Arm64/Unix] Fix CallDescrWorkerInternal personality

* [Arm64/Unix] More Fp fixups

* [Arm64/Unix] CallEHFunclet machine state

Restore non-volatile machine state in CallEHFunclet

* [Arm64/Unix] CallDescrWorkerInternal

Use empty stack slot to save argument

* [Arm64/Unix] RtlVirtualUnwind update pointers

* [Arm64] LazyMachState fixes

* [Arm64/Unix] disable USE_REDIRECT_FOR_GCSTRESS

When FEATURE_PAL is enableds USE_REDIRECT_FOR_GCSTRESS
is not supported

* [Arm64] ClearRegDisplayArgumentAndScratchRegisters()

* [Arm64] Remove unnecesary copy in TransitionFrame

* [Arm64/Unix] Fix comment per review

* [Arm64/Unix] move constants per review

* [Arm64/Unix] Use ldp per review

Also fix indentation

* [Arm64/Unix] Fix indentation per review

* [Arm64/Unix] Remove m_Unwound per review comments

* [Arm64/Unix] Use PREPARE_EXTERNAL_VAR to access globals

* [Arm64/Unix] Fix more whitespace per earlier review comments


Commit migrated from dotnet/coreclr@9baa44a
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants