Skip to content

Commit

Permalink
[XCOFF] FixupOffsetInCsect should be 0 for R_REF relocation.
Browse files Browse the repository at this point in the history
Summary: The FixupOffsetInCsect should be 0 for R_REF relocation since it specifies a nonrelocating reference. Otherwise liker would try to relocate the symbol through its address and an error like following occurred.
```
ld: 0711-547 SEVERE ERROR: Object /tmp/1-2a7ea1.o cannot be processed.
	RLD address 0x65 for section 2 (.data) is
	not contained in the section.
```

Reviewed By: shchenz

Differential Revision: https://reviews.llvm.org/D152777
  • Loading branch information
EsmeYi committed Jun 15, 2023
1 parent 03d9250 commit 028a261
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 17 deletions.
25 changes: 13 additions & 12 deletions llvm/lib/MC/XCOFFObjectWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -618,6 +618,12 @@ void XCOFFObjectWriter::recordRelocation(MCAssembler &Asm,
assert(SectionMap.contains(SymASec) &&
"Expected containing csect to exist in map.");

assert((Fixup.getOffset() <=
MaxRawDataSize - Layout.getFragmentOffset(Fragment)) &&
"Fragment offset + fixup offset is overflowed.");
uint32_t FixupOffsetInCsect =
Layout.getFragmentOffset(Fragment) + Fixup.getOffset();

const uint32_t Index = getIndex(SymA, SymASec);
if (Type == XCOFF::RelocationType::R_POS ||
Type == XCOFF::RelocationType::R_TLS)
Expand Down Expand Up @@ -656,23 +662,18 @@ void XCOFFObjectWriter::recordRelocation(MCAssembler &Asm,

// 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();
uint64_t BRInstrAddress =
SectionMap[ParentSec]->Address + FixupOffsetInCsect;
// 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_REF)
// The FixedValue should always be 0 since it specifies a nonrelocating
// reference.
} else if (Type == XCOFF::RelocationType::R_REF) {
// The FixedValue and FixupOffsetInCsect should always be 0 since it
// specifies a nonrelocating reference.
FixedValue = 0;

assert((Fixup.getOffset() <=
MaxRawDataSize - Layout.getFragmentOffset(Fragment)) &&
"Fragment offset + fixup offset is overflowed.");
uint32_t FixupOffsetInCsect =
Layout.getFragmentOffset(Fragment) + Fixup.getOffset();
FixupOffsetInCsect = 0;
}

XCOFFRelocation Reloc = {Index, FixupOffsetInCsect, SignAndSize, Type};
MCSectionXCOFF *RelocationSec = cast<MCSectionXCOFF>(Fragment->getParent());
Expand Down
10 changes: 5 additions & 5 deletions llvm/test/CodeGen/PowerPC/pgo-ref-directive.ll
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ entry:
; NOVNDS-NEXT: .ref __llvm_prf_names[RO]
; NOVNDS-NOT: .ref __llvm_prf_vnds

; NOVNDS-OBJ: 00000008 R_REF __llvm_prf_data
; NOVNDS-OBJ: 00000008 R_REF __llvm_prf_names
; NOVNDS-OBJ: 00000000 R_REF __llvm_prf_data
; NOVNDS-OBJ: 00000000 R_REF __llvm_prf_names
; NOVNDS-OBJ-NOT: R_REF __llvm_prf_vnds

;--- with-vnds.ll
Expand Down Expand Up @@ -115,8 +115,8 @@ entry:

; WITHVNDS-OBJ: RELOCATION RECORDS FOR [.data]:
; WITHVNDS-OBJ-NEXT: OFFSET TYPE VALUE
; WITHVNDS-OBJ-NEXT: 00000008 R_REF __llvm_prf_data
; WITHVNDS-OBJ-NEXT: 00000008 R_REF __llvm_prf_names
; WITHVNDS-OBJ-NEXT: 00000008 R_REF __llvm_prf_vnds
; WITHVNDS-OBJ-NEXT: 00000000 R_REF __llvm_prf_data
; WITHVNDS-OBJ-NEXT: 00000000 R_REF __llvm_prf_names
; WITHVNDS-OBJ-NEXT: 00000000 R_REF __llvm_prf_vnds
; WITHVNDS-OBJ-NEXT: 00000100 R_POS .main
; WITHVNDS-OBJ-NEXT: 00000104 R_POS TOC

0 comments on commit 028a261

Please sign in to comment.