Thanks to visit codestin.com
Credit goes to github.com

Skip to content

OrcV2: also set COFF flag overrides when custom linking layer is used #129533

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

wjakob
Copy link
Contributor

@wjakob wjakob commented Mar 3, 2025

LLJIT's LLJIT::createObjectLinkingLayer() function sets the OverrideObjectFlagsWithResponsibilityFlags and AutoClaimResponsibilityForObjectSymbols flags when compiling on Windows, where the COFF format is internally used

if (S.JTMB->getTargetTriple().isOSBinFormatCOFF()) {
Layer->setOverrideObjectFlagsWithResponsibilityFlags(true);
Layer->setAutoClaimResponsibilityForObjectSymbols(true);
}

However, the implementation fails to do these flag assignments when the user has specified a linking layer.

if (S.CreateObjectLinkingLayer)
return S.CreateObjectLinkingLayer(ES, S.JTMB->getTargetTriple());

For applications that specify a custom linking layer, this makes LLVM unusable when using LLJIT through the C-API bindings on Windows, since setOverrideObjectFlagsWithResponsibilityFlags and setAutoClaimResponsibilityForObjectSymbols don't have C-API bindings and can therefore not be called to set these flags manually. In particular, the LLVMOrcCreateRTDyldObjectLinkingLayerWithMCJITMemoryManagerLikeCallbacks linking layer is affected by this.

This PR fixes the issue by inserting an additional check in the early exit branch to see if COFF is used, and if the created linking layer is/derives from RTDyldObjectLinkingLayer. In that case, those flags should also be set.

cc @lhames @rtabbara @njroussel

Copy link

github-actions bot commented Mar 3, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

@wjakob
Copy link
Contributor Author

wjakob commented Mar 3, 2025

(fixed formatting)

@wjakob
Copy link
Contributor Author

wjakob commented Mar 4, 2025

A related question to @lhames: do you see any way to work around this issue using the C-API and configure OrcV2 so that it correctly sets these flags when using a custom linking layer? Thank you 🙇

Copy link
Contributor

@lhames lhames left a comment

Choose a reason for hiding this comment

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

LGTM. These flags are hacks, but RTDyldObjectLinkingLayer won't be fixed and will be deprecated in the future. This is a good way to avoid them complicating the public API in the mean time.

@lhames
Copy link
Contributor

lhames commented Mar 4, 2025

A related question to @lhames: do you see any way to work around this issue using the C-API and configure OrcV2 so that it correctly sets these flags when using a custom linking layer? Thank you 🙇

If your fix is sufficient for you for now i'd prefer not to expose these flags through the C API as they're workarounds for deficiencies in our current implementation. The eventual hope is to remove them, but I'm busy with other tasks at the moment and don't have time to do this work at the moment.

@wjakob
Copy link
Contributor Author

wjakob commented Mar 4, 2025

Great, thank you. Let's use this version then instead of adding bindings of those methods.

Regarding the workaround: this is making a number of LLVM versions unusable for my project on Windows, so I was just wondering if you see some other way to set those flags that doesn't need changes in LLVM itself. (Maybe by creating a default linking layer and then retroactively applying the customization from the custom link layer) But I'm assuming it's not possible with the C API.

Also: If/when RTDyldObjectLinkingLayer is deprecated, what will happen to C-API functions like LLVMOrcCreateRTDyldObjectLinkingLayerWithSectionMemoryManager or LLVMOrcCreateRTDyldObjectLinkingLayerWithMCJITMemoryManagerLikeCallbacks? Do you plan to adapt these bindings the RTDyldObjectLinkingLayer replacement, or will there be a new set of APIs?

@wjakob
Copy link
Contributor Author

wjakob commented Mar 7, 2025

I adapted the commit to address a merge conflict caused by conflicting changes on master.

Copy link
Contributor

@lhames lhames left a comment

Choose a reason for hiding this comment

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

Otherwise LGTM.

@lhames
Copy link
Contributor

lhames commented Mar 10, 2025

Great, thank you. Let's use this version then instead of adding bindings of those methods.

Regarding the workaround: this is making a number of LLVM versions unusable for my project on Windows, so I was just wondering if you see some other way to set those flags that doesn't need changes in LLVM itself. (Maybe by creating a default linking layer and then retroactively applying the customization from the custom link layer) But I'm assuming it's not possible with the C API.

I think the LLVM change is the right way to go for now.

Also: If/when RTDyldObjectLinkingLayer is deprecated, what will happen to C-API functions like LLVMOrcCreateRTDyldObjectLinkingLayerWithSectionMemoryManager or LLVMOrcCreateRTDyldObjectLinkingLayerWithMCJITMemoryManagerLikeCallbacks? Do you plan to adapt these bindings the RTDyldObjectLinkingLayer replacement, or will there be a new set of APIs?

They will also be deprecated.

There is no C API replacement for these yet. We'll need to implement new APIs for this.

What customizations are you using? Do you need to control layout, or just find out where particular sections / symbols are?

@wjakob
Copy link
Contributor Author

wjakob commented Mar 10, 2025

What customizations are you using? Do you need to control layout, or just find out where particular sections / symbols are?

I need to control the layout. I am using LLVMOrcCreateRTDyldObjectLinkingLayerWithMCJITMemoryManagerLikeCallbacks to place generated code into a flat buffer that can contains everything (code, data). The program only uses %rip-relative accesses. An application can later map this data into memory and run it without using any of the LLVM infrastructure.

These are entirely self-contained computational kernels that don't use any external functionality (e.g. from libc).

@wjakob
Copy link
Contributor Author

wjakob commented Mar 10, 2025

@lhames: I incorporated the feedback but left in the COFF check, which was missing in your snippet (which I assume was unintentional).

@lhames
Copy link
Contributor

lhames commented Mar 10, 2025

What customizations are you using? Do you need to control layout, or just find out where particular sections / symbols are?

I need to control the layout. I am using LLVMOrcCreateRTDyldObjectLinkingLayerWithMCJITMemoryManagerLikeCallbacks to place generated code into a flat buffer that can contains everything (code, data). The program only uses %rip-relative accesses. An application can later map this data into memory and run it without using any of the LLVM infrastructure.

These are entirely self-contained computational kernels that don't use any external functionality (e.g. from libc).

This will be interesting. The JITLink and JITLinkMemoryManager APIs are much more complex than RuntimeDyld. I don't think we can expose the raw C API for this.

Do you actually need to control where the JIT'd memory lives, or just its layout? I'm wondering if we could get by with a "SectionMerger" plugin that merges all blocks into a single section with RWX permissions, plus maybe a custom section-based memory manager if you need to control where it goes?

@lhames
Copy link
Contributor

lhames commented Mar 10, 2025

Alternatively we could expose an API that allows you to merge simple LinkGraphs directly into a flat buffer, then we expose the existing SectCreate utility that allows you to add buffers directly to the JIT with a given set of permissions and associated symbols. (This wouldn't let you control its final load address though)

@wjakob
Copy link
Contributor Author

wjakob commented Mar 10, 2025

Do you actually need to control where the JIT'd memory lives, or just its layout? I'm wondering if we could get by with a "SectionMerger" plugin that merges all blocks into a single section with RWX permissions, plus maybe a custom section-based memory manager if you need to control where it goes?

I don't need control over the absolute address, just having a single section will be enough. A SectionMerger plugin, if accessible through the C API, would be perfect (and likely much simpler than the current workaround with the memory manager).

@wjakob
Copy link
Contributor Author

wjakob commented Mar 10, 2025

The other option honestly sounds fine as well :). The main requirement is that there is a way to pack code+data into a single section (no matter its absolute address), via the C API.

@lhames
Copy link
Contributor

lhames commented Mar 10, 2025

Looks like this is causing crashes in MLIR. Unfortunately I don't have access to a Windows machine to debug these.

@lhames
Copy link
Contributor

lhames commented Mar 10, 2025

I've asked the #mlir channel on Discord if they're able to reproduce. If you have a debug build handy you might be able to take a look too? The logs show an unhandled Expected value, so I suspect we have two problems: an error plumbing issue, and then whatever issue is raising the error.

This reverts commit eecf6af.
@wjakob
Copy link
Contributor Author

wjakob commented Mar 11, 2025

@lhames Is it possible that removing the if statement from before was the cause of this regression? I reverted that last commit so that the MLIR team can check.

@wjakob
Copy link
Contributor Author

wjakob commented Apr 11, 2025

Dear @lhames,

I was wondering what I could do to get this unblocked. Current LLVM builds crash with my project when used on Windows because of this issue. Does this current commit still crash in the MLIR test suite after I reverted the latest change?

@lhames
Copy link
Contributor

lhames commented Apr 29, 2025

Hi Wenzel,

Sorry for the late reply — I’ve been out on vacation since early April. I’m back next Monday and should be able to look into this later in the week.

Thanks for your patience!

@wjakob
Copy link
Contributor Author

wjakob commented May 3, 2025

Thank you @lhames, please let me know if I can help with anything.

This specific fix aside, I am also wondering if we discuss (perhaps in a separate issue) a way to link into a flat buffer that has better long-term stability as the currently broken API is also on the way out. (You mentioned the following two potential paths that sound like they would work)

I'm wondering if we could get by with a "SectionMerger" plugin that merges all blocks into a single section with RWX permissions

Alternatively we could expose an API that allows you to merge simple LinkGraphs directly into a flat buffer, then we expose the existing SectCreate utility that allows you to add buffers directly to the JIT with a given set of permissions and associated symbols. (This wouldn't let you control its final load address though)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants