K Jelesnianski via llvm-dev
2018-Sep-22 18:24 UTC
[llvm-dev] Quick question: How to BuildMI mov64mi32 arbitrary MMB address to memory
Dear All, I am working on a x86 backend machineFunction pass, where I am trying to save the hard coded address of an arbitrary machine basic block to memory in ASM. I know the assembly needed for this but am lost at how to construct the BuildMI(). Note that these machine basic blocks are not entry's to a function. but in the middle of the function. so using addGlobalAddress or addExternalSymbol are no use to me and am trying to avoid having to make a separate jump table section. Is a jump table section with symbols associated with these new basic blocks the only option? In x86 assembly this would look something like: MOVQ 0x40044540, 0x8(%rsp) # Store address of trampoline basic block to stack The BuildMI looks like: BuildMI(MBB, MBIt, DL, TII->get(X86::MOV64mi32)) .addImm(0x1) // Scale .addReg(X86::RSP) // Base .addImm(0x8) // Disp .addMBB(my_target_mbb); // Source So far I have looked into the BuildMI API of LLVM and the only one that looks relevant is addMBB. While my LLVM pass compiles, my linker complains (and note that I am compiling with -fPIC): 1) /usr/bin/ld: /tmp/foo-d523b6.o: Unknown temporary symbol or 2) /usr/bin/ld: /tmp/foo-d523b6.o: relocation R_X86_64_32S against `.text' can not be used when making a shared object; recompile with -fPIC /usr/bin/ld: final link failed: Nonrepresentable section on output Any suggestions? Much appreciated for taking a look! Sincerely, K Jelesnianski -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180922/f830f042/attachment.html>
Tim Northover via llvm-dev
2018-Sep-22 18:46 UTC
[llvm-dev] Quick question: How to BuildMI mov64mi32 arbitrary MMB address to memory
Hi, On Sat, 22 Sep 2018 at 19:25, K Jelesnianski via llvm-dev <llvm-dev at lists.llvm.org> wrote:> /usr/bin/ld: /tmp/foo-d523b6.o: relocation R_X86_64_32S against `.text' can not be used when making a shared object; recompile with -fPIC > /usr/bin/ld: final link failed: Nonrepresentable section on outputThe issue is that you're presumably building in position-independent mode (PIC). Shared libraries are almost always built like this, and a lot of executables these days to aid ASLR. Anyway, because of that you can't directly reference the absolute address of a basic block from the .text section because that's supposed to be read-only and so couldn't be fixed up by ld-linux or dyld. The solution is to instead calculate the address of the block relative to %rip, which can't be stored in the same instruction (it'd have two addressing-mode operands, which no x86 instruction does). So instead it'd be a lea/mov pair (and you'll need a scratch register). To get the exact form, it's useful to compile a simple .ll file: define void @foo(i8** %addr) { br label %next next: store i8* blockaddress(@foo, %next), i8** %addr ret void } $ bin/llc -relocation-model=pic simple.ll -o - [...] leaq .Ltmp0(%rip), %rax movq %rax, (%rdi) You seem to be reasonably OK with BuildMI so I'm not going to try and translate that to C++. And yes, addMBB is the one you want for that operand.> The BuildMI looks like: > > BuildMI(MBB, MBIt, DL, TII->get(X86::MOV64mi32)) > .addImm(0x1) // Scale > .addReg(X86::RSP) // Base > .addImm(0x8) // Disp > .addMBB(my_target_mbb); // SourceThis looks like some operands might be wrong to me. Aren't the x86 addressing-mode operands [base, scale, index,disp, segment]? Cheers. Tim.
K Jelesnianski via llvm-dev
2018-Sep-22 21:20 UTC
[llvm-dev] Quick question: How to BuildMI mov64mi32 arbitrary MMB address to memory
Dear Mr. Northover, Thank you for the quick reply. You are correct about the address-mode operands :) . I guess an important detail left out was that the basic block (call it A) that wants to calculate the address of the target stationary trampoline basic block (call it B) will be moved around in memory during run-time. Our earlier solution, before the feature was implemented to move around (A) is exactly as you explained using the following with a scratch reg: $ bin/llc -relocation-model=pic simple.ll -o -> [...] > leaq .Ltmp0(%rip), %rax > movq %rax, (%rdi) >We now run into the problem that with this feature enabled, if we try to perform LEA backwards to the trampoline, after A has been moved the %rip relative offset that was put in by LLVM is no longer valid. Also if we perform LEA forwards to the target address in A that trampoline B is supposed to trampoline us too, that address will also be invalidated once A has been moved. Thus calculating forwards is most likely impossible. This leaves calculating LEA backwards to the trampoline BB (B) since we know that the trampoline BB will remain stationary throughout execution. That is why I would "like" to somehow store (B)'s address. I am looking for a work around to accommodate this feature. I have never attempted to make my own section/symbols using LLVM, but I assume this is the route I should take? Pairing each trampoline BB to a symbol should make it visible and this MOVQ instruction I want possible? With that approach, my questions are: Do I need to make these symbols for the trampoline BBs as an IR opt pass, can I get away with it using a MachineModule Pass to add the trampolines per module (file) (so far I have only created BasicBlock, MachineBasicBlock, and MachineFunction passes)?? Do I need to make a separate custom section for these trampolines symbols, or can I just add them to the .text section? Thanks again for your reply. Sincerely, K Jelesnianski -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180922/bc574791/attachment.html>