Skip to content

Conversation

@VSadov
Copy link
Member

@VSadov VSadov commented Aug 18, 2022

Fixes:#71507

@ghost
Copy link

ghost commented Aug 18, 2022

I couldn't figure out the best area label to add to this PR. If you have write-permissions please help me learn by adding exactly one area label.

@ghost
Copy link

ghost commented Aug 18, 2022

Tagging subscribers to this area: @vitek-karas, @agocke, @VSadov
See info in area-owners.md if you want to be subscribed.

Issue Details

Fixes:#71507

Author: VSadov
Assignees: VSadov
Labels:

area-AssemblyLoader-coreclr

Milestone: -


#ifdef TARGET_OSX
// We need to allocate executable memory on OSX in order to do relocation of R2R code.
// Converted layout currently uses VirtualAlloc, so it will not work.
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 not sure I understand this comment. Why would allocating executable memory not work on OSX?

Copy link
Member Author

Choose a reason for hiding this comment

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

I think it would work if correct APIs are used. It is probably not as simple as just passing MAP_JIT to VirtualAlloc or just replacing VirtualAlloc with another call.
I want to backport this to 7.0, so I'd like to not do a lot of changes to how we convert layouts, which would carry extra risk to scenarios that are not being fixed.

The goal is to make sure that assemblies can be loaded from byte arrays even if they contain R2R code.
Whether the R2R is actually enabled is of less importance. It is a relatively rare case and a reflection scenario with unclear benefits from R2R.

Linux part was just tweaking the assert, but for OSX enabling R2R needs more changes. I think it is ok to do those changes in 8.0

Copy link
Member

Choose a reason for hiding this comment

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

I agree that the change is fine as is.
Just FYI though, the VirtualAlloc sets MAP_JIT automatically for executable memory allocations. Either it gets memory from the g_executableMemoryAllocator.AllocateMemory or it sets the special flag that results in MAP_JIT addition during memory reservation:

if ((flProtect & 0xff) == PAGE_EXECUTE_READWRITE)
{
flAllocationType |= MEM_RESERVE_EXECUTABLE;
}
pRetVal = ReserveVirtualMemory(pthrCurrent, (LPVOID)StartBoundary, MemSize, flAllocationType);

Copy link
Member Author

Choose a reason for hiding this comment

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

Does it mean that I could just pass PAGE_EXECUTE_READWRITE to VirtualAlloc on OSX?

Copy link
Member

Choose a reason for hiding this comment

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

Yes

Copy link
Member Author

@VSadov VSadov Aug 19, 2022

Choose a reason for hiding this comment

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

I tried going that path (setting PAGE_EXECUTE_READWRITE), but I think I also need to toggle PAL_JitWriteProtect when copying sections and then the change started making me worried about the complexity and possible bugs.

I think I will leave that for after-7.0, we do not have to do this now.

Copy link
Member

Choose a reason for hiding this comment

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

Right (for both)

Copy link
Member Author

Choose a reason for hiding this comment

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

I've logged #74203 to follow up with enabling R2R on OSX

@jkotas
Copy link
Member

jkotas commented Aug 19, 2022

Loading from byte arrays/streams is expected to ignore R2R payload if there is one.

Respecting R2R payload in this scenario has a dubious value (you are giving up perf advantage of memory mapped files) and there are number of problems that would be have to be fixed to make it work end-to-end well (don't forget diagnostic tools).

@VSadov
Copy link
Member Author

VSadov commented Aug 19, 2022

Loading from byte arrays/streams is expected to ignore R2R payload if there is one.

I was not sure about this primarily because it seems to work on Windows and on Linux (modulo an assert) and probably worked in past releases. "work" here is basically "code runs". I do not know what the situation with diagnostics etc.
It does seem to have dubious value, since loading from a byte array is hardly a startup scenario and avoiding JIT is unlikely a big win.

I guess this is enough controversy to just disable R2R in this scenario on all platforms.
I'll add a note to the follow-up issue to revisit later - whether there is any benefit at all.

@VSadov
Copy link
Member Author

VSadov commented Aug 20, 2022

Thanks!!

@VSadov
Copy link
Member Author

VSadov commented Aug 20, 2022

/backport to release/7.0-rc1

@github-actions
Copy link
Contributor

Started backporting to release/7.0-rc1: https://github.com/dotnet/runtime/actions/runs/2893425031

@ghost ghost locked as resolved and limited conversation to collaborators Sep 19, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants