cross-section differences in MC generation

I'm working on Position-independent code for 32-bit PowerPC, but
running into a problem. At the beginning of each function, there's a
pre-word that's the difference between the PICBase (.L1$pb) and the
GOT. This works fine when generating assembly output, but it fails
when generating ELF output, with the error "Cannot represent a
difference across sections" (line 847, lib/MC/ELFObjectWriter.cpp).

Roman Divacky suggested I try something with 'let EncoderMethod = ...'
similar to how the TOC entries are done for ppc64. However, I'm not
sure if that would work, given that the TOC on ppc64 is handled
differently from the GOT on ppc32, and I'm not sure how to represent
that if it could work.

Any ideas on how a cross-section diff and relocation could be
represented for this?

Thanks,
Justin

I'm working on Position-independent code for 32-bit PowerPC, but
running into a problem. At the beginning of each function, there's a
pre-word that's the difference between the PICBase (.L1$pb) and the
GOT. This works fine when generating assembly output, but it fails
when generating ELF output, with the error "Cannot represent a
difference across sections" (line 847, lib/MC/ELFObjectWriter.cpp).

Roman Divacky suggested I try something with 'let EncoderMethod = ...'
similar to how the TOC entries are done for ppc64. However, I'm not
sure if that would work, given that the TOC on ppc64 is handled
differently from the GOT on ppc32, and I'm not sure how to represent
that if it could work.

Any ideas on how a cross-section diff and relocation could be
represented for this?

Can you post the generated assembly that works with gas but fails with llvm-mc?

Attached. You can also find it at
http://people.freebsd.org/~jhibbits/hello_llvm.s .

- Justin

hello_llvm.s (1.58 KB)

This reduces to

.section .foo
.L1:
.L2 = .L1
.section .bar
.long .L1-.L2

Which is fairly silly :frowning:

I think this is the some root issue as pr20119. I will add the
testcase to that PR.

Cheers,
Rafael

I think that's incorrect. It should to:

.section .foo
.L1:
.L2 = .L1
.section .bar
.long .L3-.L2
.L3:

Because .L3 and .L2 are in different sections.

- Justin

I think this is fixed with r212101.

No error now, thanks! It generates the relocation, but puts a 0 in the
pre-word, which GNU as doesn't (puts the difference 0x8000 - delta of
preword and PIC Base label). I think that's a red herring, though,
because 'readelf -a' shows in both cases the relocations having a
starting value of 0, but I could be wrong (don't know quite enough).
I'll add some tests, and send a patch for review.

- Justin