This is an archive of the discontinued LLVM Phabricator instance.

[XCOFF] adjust the Fixedvalue for R_RBR relocations.
ClosedPublic

Authored by Esme on Nov 29 2022, 11:47 PM.

Details

Summary

Currently we get a wrong fixed value for R_RBR relocations when -ffunction-sections enabled. This patch fixes this.

      4c: 4b ff ff f5  	bl 0x40 <.bar>
			0000004c:  R_RBR	.foo
      50: 60 00 00 00  	nop
      54: 4b ff ff ed  	bl 0x40 <.bar>
			00000054:  R_RBR	.static_overalign_foo
      58: 60 00 00 00  	nop
      5c: 4b ff ff e5  	bl 0x40 <.bar>
			0000005c:  R_RBR	.alias_foo
      60: 60 00 00 00  	nop
      64: 4b ff ff dd  	bl 0x40 <.bar>
			00000064:  R_RBR	.extern_foo
      68: 60 00 00 00  	nop
      6c: 4b ff ff d5  	bl 0x40 <.bar>
			0000006c:  R_RBR	.hidden_foo

Diff Detail

Event Timeline

Esme created this revision.Nov 29 2022, 11:47 PM
Herald added a project: Restricted Project. · View Herald TranscriptNov 29 2022, 11:47 PM
Esme requested review of this revision.Nov 29 2022, 11:47 PM
Herald added a project: Restricted Project. · View Herald TranscriptNov 29 2022, 11:47 PM
DiggerLin added inline comments.Dec 2 2022, 8:50 AM
llvm/lib/MC/XCOFFObjectWriter.cpp
646

according to
https://www.ibm.com/docs/en/aix/7.2?topic=formats-xcoff-object-file-format#XCOFF__sua3i125jbau

R_RBR
Specifies (relative) branch relocation. Provides a displacement value between the address of the symbol specified by the r_symndx field and the address of the csect containing the branch instruction to be modified. The instruction can be modified to an absolute branch instruction if the target address is not relocatable.

DiggerLin added inline comments.Dec 2 2022, 1:46 PM
llvm/lib/MC/XCOFFObjectWriter.cpp
646

but the output looks correct. the document is error? or I misunderstand the doc ?

Esme added a comment.Dec 6 2022, 6:17 AM

Hi @DiggerLin, thank you for your review. I'm also confused by the description from the doc, if my understanding is correct, according to the doc, the FixedValue will ignore the value of Fixup.getOffset(), because the address of the csect containing the branch instruction to be modified equals to SectionMap[ParentSec]->Address + Layout.getFragmentOffset(Fragment). This is obviously incorrect. I have tested LNT and bootstrap for this patch under the options of -fintegrated-as -ffunction-sections, and both are clean.

Hi @DiggerLin, thank you for your review. I'm also confused by the description from the doc, if my understanding is correct, according to the doc, the FixedValue will ignore the value of Fixup.getOffset(), because the address of the csect containing the branch instruction to be modified equals to SectionMap[ParentSec]->Address + Layout.getFragmentOffset(Fragment). This is obviously incorrect. I have tested LNT and bootstrap for this patch under the options of -fintegrated-as -ffunction-sections, and both are clean.

Hi @DiggerLin, thank you for your review. I'm also confused by the description from the doc, if my understanding is correct, according to the doc, the FixedValue will ignore the value of Fixup.getOffset(), because the address of the csect containing the branch instruction to be modified equals to SectionMap[ParentSec]->Address + Layout.getFragmentOffset(Fragment). This is obviously incorrect. I have tested LNT and bootstrap for this patch under the options of -fintegrated-as -ffunction-sections, and both are clean.

I agree with you, I asked the problem in our slack channel and wait for confirm, if it is doc error, we should the ask doc to be modified.

DiggerLin added inline comments.Dec 6 2022, 8:16 AM
llvm/test/CodeGen/PowerPC/aix-xcoff-funcsect.ll
13

add --symbol-description here for llvm-objdump

21

add --symbol-description here for llvm-objdump

I also thinks the doc is wrong about the relocation type R_RBR, it should be the diff between the relocatable symbol and the branch instruction, not between the symbol and the csect which contains the branch instruction.

llvm/lib/MC/XCOFFObjectWriter.cpp
637

Is it possible that the XCOFF::RelocationType::R_RBR is generated for a non XMC_PR type symbol? Maybe we should make it as an assertion here for both SymASec and ParentSec?

Esme updated this revision to Diff 481149.Dec 7 2022, 9:32 PM

Addressed comments. Thanks @DiggerLin and @shchenz

stephenpeckham added inline comments.Dec 8 2022, 7:35 AM
llvm/lib/MC/XCOFFObjectWriter.cpp
644–645

// The FixedValue is the difference between the SymA address and BRInstrAddress plus any constant value.

The documentation for R_RBR is easy to misunderstand. The documentation doesn't describe what should be computed for the FixedValue. It describes how the FixedValue should be adjusted at link time. This adjustment is based both on the change to the address of SymA (pre-link vs. post-link) and the change to the address of the branch instruction (or its csect--they're equivalent)

DiggerLin accepted this revision.EditedDec 9 2022, 8:08 AM

LGTM , but wait for several days to see whether other reviewer has comment or not.

This revision is now accepted and ready to land.Dec 9 2022, 8:08 AM
shchenz accepted this revision as: shchenz.Dec 13 2022, 5:33 PM

LGTM too with one nit. Thanks for fixing this.

llvm/lib/MC/XCOFFObjectWriter.cpp
651

For the other else(relocation types), maybe we should add an assertion here to avoid any other unhandled relocation type that may introduce in PPCXCOFFObjectWriter::getRelocTypeAndSignSize() in future. The assertion will help us address the root cause early like the one for XCOFF::RelocationType::R_RBR.

Esme updated this revision to Diff 483059.Dec 14 2022, 6:39 PM
Esme added inline comments.
llvm/lib/MC/XCOFFObjectWriter.cpp
644–645

@stephenpeckham Thank you for your explanation.

651

Good point!

Esme added inline comments.Dec 14 2022, 7:33 PM
llvm/lib/MC/XCOFFObjectWriter.cpp
651

Oh, it's incorrect to add the assertion/unreachable here, because what we are doing in the function is just to adjust the fixedvalue for some particular cases, and the fixedvalue for general cases are already calculated before this function.

shchenz added inline comments.Dec 14 2022, 8:57 PM
llvm/lib/MC/XCOFFObjectWriter.cpp
651

Thanks. My initial thought was like:

else {
  assert(Type == {list all other relocation types in `PPCXCOFFObjectWriter::getRelocTypeAndSignSize()` that we know are OK with current FixedValue handling})
}

But this assertion may report false alarm if we add a new relocation type in PPCXCOFFObjectWriter::getRelocTypeAndSignSize() in future but that relocation type does not need special handling for the FixedValue.

If we know what relocation types need special handling for FixedValue and assert here that all of them are handled or known to be unhandled for now, that would be the most reasonable solution. But I guess it must need non trivial effort to understand each relocation type. So let's just back to previous version for now.

Thanks again for the try.

Esme updated this revision to Diff 483079.Dec 14 2022, 9:27 PM
Esme added inline comments.
llvm/lib/MC/XCOFFObjectWriter.cpp
651

Oh, I see. Thank you for your explanation. I can post another patch for this after I look through other relocation types. And I'll land this patch before that.

This revision was landed with ongoing or failed builds.Dec 14 2022, 10:57 PM
This revision was automatically updated to reflect the committed changes.