diff --git a/llvm/lib/MC/XCOFFObjectWriter.cpp b/llvm/lib/MC/XCOFFObjectWriter.cpp --- a/llvm/lib/MC/XCOFFObjectWriter.cpp +++ b/llvm/lib/MC/XCOFFObjectWriter.cpp @@ -633,7 +633,38 @@ report_fatal_error("TOCEntryOffset overflows in small code model mode"); FixedValue = TOCEntryOffset; - } + } else if (Type == XCOFF::RelocationType::R_RBR) { + MCSectionXCOFF *ParentSec = cast(Fragment->getParent()); + assert((SymASec->getMappingClass() == XCOFF::XMC_PR && + ParentSec->getMappingClass() == XCOFF::XMC_PR) && + "Only XMC_PR csect may have the R_RBR relocation."); + + // The address of the branch instruction should be the sum of section + // address, fragment offset and Fixup offset. + uint64_t BRInstrAddress = SectionMap[ParentSec]->Address + + Layout.getFragmentOffset(Fragment) + + Fixup.getOffset(); + // The FixedValue should be the difference between SymA csect address and BR + // instr address plus any constant value. + FixedValue = + SectionMap[SymASec]->Address - BRInstrAddress + Target.getConstant(); + } else if (Type == XCOFF::RelocationType::R_RBR) { + MCSectionXCOFF *ParentSec = cast(Fragment->getParent()); + assert((SymASec->getMappingClass() == XCOFF::XMC_PR && + ParentSec->getMappingClass() == XCOFF::XMC_PR) && + "Only XMC_PR csect may have the R_RBR relocation."); + + // The address of the branch instruction should be the sum of section + // address, fragment offset and Fixup offset. + uint64_t BRInstrAddress = SectionMap[ParentSec]->Address + + Layout.getFragmentOffset(Fragment) + + Fixup.getOffset(); + // The FixedValue should be the difference between SymA csect address and BR + // instr address plus any constant value. + FixedValue = + SectionMap[SymASec]->Address - BRInstrAddress + Target.getConstant(); + } else + llvm_unreachable("the relocation type isn't supported yet!"); assert((Fixup.getOffset() <= MaxRawDataSize - Layout.getFragmentOffset(Fragment)) && diff --git a/llvm/test/CodeGen/PowerPC/aix-xcoff-funcsect.ll b/llvm/test/CodeGen/PowerPC/aix-xcoff-funcsect.ll --- a/llvm/test/CodeGen/PowerPC/aix-xcoff-funcsect.ll +++ b/llvm/test/CodeGen/PowerPC/aix-xcoff-funcsect.ll @@ -10,12 +10,16 @@ ; RUN: -filetype=obj -o %t32.o < %s ; RUN: llvm-objdump --syms --reloc --symbol-description %t32.o | \ ; RUN: FileCheck --check-prefix=XCOFF32 %s +; RUN: llvm-objdump -dr --symbol-description %t32.o | \ +; RUN: FileCheck --check-prefix=DIS32 %s ; RUN: llc -verify-machineinstrs -mtriple powerpc64-ibm-aix-xcoff -mcpu=pwr4 \ ; RUN: -mattr=-altivec -function-sections -xcoff-traceback-table=true \ ; RUN: -filetype=obj -o %t64.o < %s ; RUN: llvm-objdump --syms --reloc --symbol-description %t64.o | \ ; RUN: FileCheck --check-prefix=XCOFF64 %s +; RUN: llvm-objdump -dr --symbol-description %t64.o | \ +; RUN: FileCheck --check-prefix=DIS64 %s @alias_foo = alias void (...), bitcast (void ()* @foo to void (...)*) @@ -141,7 +145,6 @@ ; XCOFF32-NEXT: 00000024 R_POS (idx: 15) .static_overalign_foo[PR] ; XCOFF32-NEXT: 00000028 R_POS (idx: 27) TOC[TC0] - ; XCOFF64: SYMBOL TABLE: ; XCOFF64-NEXT: 0000000000000000 df *DEBUG* 0000000000000000 (idx: 0) ; XCOFF64-NEXT: 0000000000000000 *UND* 0000000000000000 (idx: 1) .extern_foo[PR] @@ -176,3 +179,49 @@ ; XCOFF64-NEXT: 0000000000000038 R_POS (idx: 27) TOC[TC0] ; XCOFF64-NEXT: 0000000000000048 R_POS (idx: 15) .static_overalign_foo[PR] ; XCOFF64-NEXT: 0000000000000050 R_POS (idx: 27) TOC[TC0] + +; DIS32: Disassembly of section .text: +; DIS32: 00000000 (idx: 9) .alias_foo: +; DIS32: 00000020 (idx: 11) .hidden_foo[PR]: +; DIS32: 00000040 (idx: 13) .bar[PR]: +; DIS32-NEXT: 40: 7c 08 02 a6 mflr 0 +; DIS32-NEXT: 44: 94 21 ff c0 stwu 1, -64(1) +; DIS32-NEXT: 48: 90 01 00 48 stw 0, 72(1) +; DIS32-NEXT: 4c: 4b ff ff b5 bl 0x0 <.alias_foo> +; DIS32-NEXT: 0000004c: R_RBR (idx: 7) .foo[PR] +; DIS32-NEXT: 50: 60 00 00 00 nop +; DIS32-NEXT: 54: 48 00 00 6d bl 0xc0 <.static_overalign_foo> +; DIS32-NEXT: 00000054: R_RBR (idx: 15) .static_overalign_foo[PR] +; DIS32-NEXT: 58: 60 00 00 00 nop +; DIS32-NEXT: 5c: 4b ff ff a5 bl 0x0 <.alias_foo> +; DIS32-NEXT: 0000005c: R_RBR (idx: 9) .alias_foo +; DIS32-NEXT: 60: 60 00 00 00 nop +; DIS32-NEXT: 64: 4b ff ff 9d bl 0x0 <.alias_foo> +; DIS32-NEXT: 00000064: R_RBR (idx: 1) .extern_foo[PR] +; DIS32-NEXT: 68: 60 00 00 00 nop +; DIS32-NEXT: 6c: 4b ff ff b5 bl 0x20 <.hidden_foo> +; DIS32-NEXT: 0000006c: R_RBR (idx: 11) .hidden_foo[PR] +; DIS32: 000000c0 (idx: 15) .static_overalign_foo[PR]: + +; DIS64: Disassembly of section .text: +; DIS64: 0000000000000000 (idx: 9) .alias_foo: +; DIS64: 0000000000000020 (idx: 11) .hidden_foo[PR]: +; DIS64: 0000000000000040 (idx: 13) .bar[PR]: +; DIS64-NEXT: 40: 7c 08 02 a6 mflr 0 +; DIS64-NEXT: 44: f8 21 ff 91 stdu 1, -112(1) +; DIS64-NEXT: 48: f8 01 00 80 std 0, 128(1) +; DIS64-NEXT: 4c: 4b ff ff b5 bl 0x0 <.alias_foo> +; DIS64-NEXT: 000000000000004c: R_RBR (idx: 7) .foo[PR] +; DIS64-NEXT: 50: 60 00 00 00 nop +; DIS64-NEXT: 54: 48 00 00 6d bl 0xc0 <.static_overalign_foo> +; DIS64-NEXT: 0000000000000054: R_RBR (idx: 15) .static_overalign_foo[PR] +; DIS64-NEXT: 58: 60 00 00 00 nop +; DIS64-NEXT: 5c: 4b ff ff a5 bl 0x0 <.alias_foo> +; DIS64-NEXT: 000000000000005c: R_RBR (idx: 9) .alias_foo +; DIS64-NEXT: 60: 60 00 00 00 nop +; DIS64-NEXT: 64: 4b ff ff 9d bl 0x0 <.alias_foo> +; DIS64-NEXT: 0000000000000064: R_RBR (idx: 1) .extern_foo[PR] +; DIS64-NEXT: 68: 60 00 00 00 nop +; DIS64-NEXT: 6c: 4b ff ff b5 bl 0x20 <.hidden_foo> +; DIS64-NEXT: 000000000000006c: R_RBR (idx: 11) .hidden_foo[PR] +; DIS64: 00000000000000c0 (idx: 15) .static_overalign_foo[PR]: