This is an archive of the discontinued LLVM Phabricator instance.

Fix RuntimeDyldCOFFX86_64 handling of image-relative relocations when there are not loaded sections
ClosedPublic

Authored by AndrewScheidecker on Aug 28 2018, 4:25 AM.

Details

Summary

I'm not sure if this is the correct fix, but it does make it work for my use.

Without this change, I get some message in stderr about "IMAGE_REL_AMD64_ADDR32NB relocation requires anordered section layout", and I have to rely on my old workaround for IMAGE_REL_AMD64_ADDR32NB.

With this change, the IMAGE_REL_AMD64_ADDR32NB relocations seem to work correctly.

If I print the sections that have a load address of 0, sometimes it's a zero-sized .data or .bss, but usually it's debug sections that aren't loaded with ProcessAllSections=false.

Diff Detail

Repository
rL LLVM

Event Timeline

marsupial requested changes to this revision.Sep 9 2018, 9:26 AM

Just maybe add a comment similar to the last line of the summary

This revision now requires changes to proceed.Sep 9 2018, 9:26 AM

Added a comment

marsupial accepted this revision.Sep 9 2018, 8:14 PM

Thanks.

This revision is now accepted and ready to land.Sep 9 2018, 8:14 PM

I don't have commit access; can you commit it?

Hi Andrew,

I am happy to commit on your behalf. Do you have an example of some failing assembly though? I would like to add a test case for your fix.

Cheers,
Lang.

I started to write a test, but it turns out that COFF_x86_64_IMGREL.s actually triggers this problem, since it has empty data sections that aren't loaded. It seems to be an accident that the test passes right now: it expects the F@IMGREL operand to be relocated to section_addr(.text)+0, but that should only be true if the image base is 0. I think for that test to be meaningful, it needs to pass an explicit target-addr-start to llvm-rtdyld, and subtract that address from the section_addr it compares against.

Passing an explicit target-addr-start exposes a similar problem to that fixed by this diff, but in remapSectionsAndSymbols: it adds sections that weren't loaded to the AlreadyAllocated map at address 0, and the other sections are mapped following that, so target-addr-start has no effect. Adding a similar *LoadAddr != 0 check to remapSectionsAndSymbols fixes that.

I also ran into another problem: the target-addr-start argument works on Windows, but not Linux! It turns out that it's a known bug that cl::opt<uint64_t> only works on Windows: https://bugs.llvm.org/show_bug.cgi?id=19665. I changed those command-line options to use cl::opt<unsigned long long>, as is done elsewhere in LLVM to work around the problem.

Hi Andrew,

Sorry for the delay. This looks good to me, and thanks very much for taking the time to write a test case and fix the infrastructure!

If you're able to commit then go for it, otherwise I can commit on your behalf.

Cheers,
Lang.

This looks good to me, and thanks very much for taking the time to write a test case and fix the infrastructure!

You're welcome!

If you're able to commit then go for it, otherwise I can commit on your behalf.

Please commit it on my behalf.

lhames closed this revision.Oct 22 2018, 7:56 PM

Committed in r344995. Thanks again Andrew!