-
Notifications
You must be signed in to change notification settings - Fork 14.5k
[LoongArch] Allow difference across sections #141722
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-backend-loongarch Author: Jinyang He (MQ-mengqing) ChangesFor SecA != SecB but SecB is current section, fallback for pcrel{64,32} relocations. For linker relaxation being disabled and SecA == SecB, return directly for avoid record relocations. In other cases, record relocations which also allows across sections. Full diff: https://github.com/llvm/llvm-project/pull/141722.diff 4 Files Affected:
diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp
index d7569ab0ea597..9566fd0b163da 100644
--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp
+++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp
@@ -447,19 +447,16 @@ bool LoongArchAsmBackend::addReloc(const MCFragment &F, const MCFixup &Fixup,
if (!force) {
const MCSection &SecA = SA.getSection();
const MCSection &SecB = SB.getSection();
+ const MCSection &SecCur = *F.getParent();
- // We need record relocation if SecA != SecB. Usually SecB is same as the
- // section of Fixup, which will be record the relocation as PCRel. If SecB
- // is not same as the section of Fixup, it will report error. Just return
- // false and then this work can be finished by handleFixup.
- if (&SecA != &SecB)
+ // Fallback for PCRel relocations.
+ if ((&SecA != &SecB) && (&SecB == &SecCur))
return Fallback();
- // In SecA == SecB case. If the linker relaxation is enabled, we need
- // record the ADD, SUB relocations. Otherwise the FixedValue has already
- // been calc- ulated out in evaluateFixup, return true and avoid record
- // relocations.
- if (!STI.hasFeature(LoongArch::FeatureRelax))
+ // In SecA == SecB case. If the linker relaxation is disabled, the
+ // FixedValue has already been calculated out in evaluateFixup,
+ // return true and avoid record relocations.
+ if ((&SecA == &SecB) && !STI.hasFeature(LoongArch::FeatureRelax))
return true;
}
diff --git a/llvm/test/MC/LoongArch/Misc/cfi-advance.s b/llvm/test/MC/LoongArch/Misc/cfi-advance.s
index 662c43e6bceaf..faec615c0b6d4 100644
--- a/llvm/test/MC/LoongArch/Misc/cfi-advance.s
+++ b/llvm/test/MC/LoongArch/Misc/cfi-advance.s
@@ -1,6 +1,8 @@
# RUN: llvm-mc --filetype=obj --triple=loongarch64 -mattr=-relax %s -o %t.o
# RUN: llvm-readobj -r %t.o | FileCheck --check-prefix=RELOC %s
# RUN: llvm-dwarfdump --debug-frame %t.o | FileCheck --check-prefix=DWARFDUMP %s
+# RUN: llvm-mc --filetype=obj --triple=loongarch64 -mattr=+relax %s \
+# RUN: | llvm-readobj -r - | FileCheck --check-prefix=RELAX %s
# RELOC: Relocations [
# RELOC-NEXT: .rela.eh_frame {
@@ -12,6 +14,12 @@
# DWARFDUMP-NEXT: DW_CFA_advance_loc: 8
# DWARFDUMP-NEXT: DW_CFA_def_cfa_offset: +8
+# RELAX: Relocations [
+# RELAX: .rela.eh_frame {
+# RELAX-NEXT: 0x1C R_LARCH_32_PCREL .L{{.*}} 0x0
+# RELAX-NEXT: }
+# RELAX-NEXT: ]
+
.text
.globl test
.p2align 2
diff --git a/llvm/test/MC/LoongArch/Relocations/fde-reloc.s b/llvm/test/MC/LoongArch/Relocations/fde-reloc.s
index 990e07c7f00bd..ab911d1853a87 100644
--- a/llvm/test/MC/LoongArch/Relocations/fde-reloc.s
+++ b/llvm/test/MC/LoongArch/Relocations/fde-reloc.s
@@ -1,5 +1,7 @@
-# RUN: llvm-mc --filetype=obj --triple=loongarch64 < %s \
+# RUN: llvm-mc --filetype=obj --triple=loongarch64 --mattr=-relax < %s \
# RUN: | llvm-readobj -r - | FileCheck %s
+# RUN: llvm-mc --filetype=obj --triple=loongarch64 --mattr=+relax < %s \
+# RUN: | llvm-readobj -r - | FileCheck %s --check-prefix=RELAX
## Ensure that the eh_frame records the symbolic difference with
## the R_LARCH_32_PCREL relocation.
@@ -12,3 +14,6 @@ func:
# CHECK: Section (4) .rela.eh_frame {
# CHECK-NEXT: 0x1C R_LARCH_32_PCREL .text 0x0
# CHECK-NEXT: }
+# RELAX: Section ({{.*}}) .rela.eh_frame {
+# RELAX-NEXT: 0x1C R_LARCH_32_PCREL .L{{.*}} 0x0
+# RELAX-NEXT: }
diff --git a/llvm/test/MC/LoongArch/Relocations/sub-expr.s b/llvm/test/MC/LoongArch/Relocations/sub-expr.s
index 0179e1027af8f..b8d24b91ca1a8 100644
--- a/llvm/test/MC/LoongArch/Relocations/sub-expr.s
+++ b/llvm/test/MC/LoongArch/Relocations/sub-expr.s
@@ -1,5 +1,7 @@
-# RUN: llvm-mc --filetype=obj --triple=loongarch64 %s -o %t
-# RUN: llvm-readobj -r %t | FileCheck %s
+# RUN: llvm-mc --filetype=obj --triple=loongarch64 --mattr=-relax %s \
+# RUN: | llvm-readobj -r - | FileCheck %s
+# RUN: llvm-mc --filetype=obj --triple=loongarch64 --mattr=+relax %s \
+# RUN: | llvm-readobj -r - | FileCheck %s --check-prefix=RELAX
## Check that subtraction expressions emit R_LARCH_32_PCREL and R_LARCH_64_PCREL relocations.
@@ -7,13 +9,46 @@
# CHECK: Relocations [
# CHECK-NEXT: Section ({{.*}}) .rela.data {
-# CHECK-NEXT: 0x0 R_LARCH_64_PCREL sx 0x0
-# CHECK-NEXT: 0x8 R_LARCH_64_PCREL sy 0x0
-# CHECK-NEXT: 0x10 R_LARCH_32_PCREL sx 0x0
-# CHECK-NEXT: 0x14 R_LARCH_32_PCREL sy 0x0
+# CHECK-NEXT: 0x0 R_LARCH_64_PCREL sx 0x4
+# CHECK-NEXT: 0x8 R_LARCH_64_PCREL sy 0x4
+# CHECK-NEXT: 0x10 R_LARCH_32_PCREL sx 0x4
+# CHECK-NEXT: 0x14 R_LARCH_32_PCREL sy 0x4
+# CHECK-NEXT: 0x18 R_LARCH_ADD64 sx 0x4
+# CHECK-NEXT: 0x18 R_LARCH_SUB64 sy 0x4
+# CHECK-NEXT: 0x20 R_LARCH_ADD64 sy 0x4
+# CHECK-NEXT: 0x20 R_LARCH_SUB64 sx 0x4
+# CHECK-NEXT: 0x28 R_LARCH_ADD32 sx 0x4
+# CHECK-NEXT: 0x28 R_LARCH_SUB32 sy 0x4
+# CHECK-NEXT: 0x2C R_LARCH_ADD32 sy 0x4
+# CHECK-NEXT: 0x2C R_LARCH_SUB32 sx 0x4
+# CHECK-NEXT: 0x30 R_LARCH_ADD64 .data 0x30
+# CHECK-NEXT: 0x30 R_LARCH_SUB64 sx 0x4
+# CHECK-NEXT: 0x38 R_LARCH_ADD32 .data 0x38
+# CHECK-NEXT: 0x38 R_LARCH_SUB32 sy 0x4
# CHECK-NEXT: }
+# RELAX: Relocations [
+# RELAX-NEXT: Section ({{.*}}) .rela.data {
+# RELAX-NEXT: 0x0 R_LARCH_64_PCREL x 0x0
+# RELAX-NEXT: 0x8 R_LARCH_64_PCREL y 0x0
+# RELAX-NEXT: 0x10 R_LARCH_32_PCREL x 0x0
+# RELAX-NEXT: 0x14 R_LARCH_32_PCREL y 0x0
+# RELAX-NEXT: 0x18 R_LARCH_ADD64 x 0x0
+# RELAX-NEXT: 0x18 R_LARCH_SUB64 y 0x0
+# RELAX-NEXT: 0x20 R_LARCH_ADD64 y 0x0
+# RELAX-NEXT: 0x20 R_LARCH_SUB64 x 0x0
+# RELAX-NEXT: 0x28 R_LARCH_ADD32 x 0x0
+# RELAX-NEXT: 0x28 R_LARCH_SUB32 y 0x0
+# RELAX-NEXT: 0x2C R_LARCH_ADD32 y 0x0
+# RELAX-NEXT: 0x2C R_LARCH_SUB32 x 0x0
+# RELAX-NEXT: 0x30 R_LARCH_ADD64 {{.*}} 0x0
+# RELAX-NEXT: 0x30 R_LARCH_SUB64 x 0x0
+# RELAX-NEXT: 0x38 R_LARCH_ADD32 {{.*}} 0x0
+# RELAX-NEXT: 0x38 R_LARCH_SUB32 y 0x0
+# RELAX-NEXT: }
+
.section sx,"a"
+nop
x:
nop
@@ -22,7 +57,14 @@ nop
.8byte y-.
.4byte x-.
.4byte y-.
+.8byte x-y
+.8byte y-x
+.4byte x-y
+.4byte y-x
+.8byte .-x
+.4byte .-y
.section sy,"a"
+nop
y:
nop
|
@llvm/pr-subscribers-mc Author: Jinyang He (MQ-mengqing) ChangesFor SecA != SecB but SecB is current section, fallback for pcrel{64,32} relocations. For linker relaxation being disabled and SecA == SecB, return directly for avoid record relocations. In other cases, record relocations which also allows across sections. Full diff: https://github.com/llvm/llvm-project/pull/141722.diff 4 Files Affected:
diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp
index d7569ab0ea597..9566fd0b163da 100644
--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp
+++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp
@@ -447,19 +447,16 @@ bool LoongArchAsmBackend::addReloc(const MCFragment &F, const MCFixup &Fixup,
if (!force) {
const MCSection &SecA = SA.getSection();
const MCSection &SecB = SB.getSection();
+ const MCSection &SecCur = *F.getParent();
- // We need record relocation if SecA != SecB. Usually SecB is same as the
- // section of Fixup, which will be record the relocation as PCRel. If SecB
- // is not same as the section of Fixup, it will report error. Just return
- // false and then this work can be finished by handleFixup.
- if (&SecA != &SecB)
+ // Fallback for PCRel relocations.
+ if ((&SecA != &SecB) && (&SecB == &SecCur))
return Fallback();
- // In SecA == SecB case. If the linker relaxation is enabled, we need
- // record the ADD, SUB relocations. Otherwise the FixedValue has already
- // been calc- ulated out in evaluateFixup, return true and avoid record
- // relocations.
- if (!STI.hasFeature(LoongArch::FeatureRelax))
+ // In SecA == SecB case. If the linker relaxation is disabled, the
+ // FixedValue has already been calculated out in evaluateFixup,
+ // return true and avoid record relocations.
+ if ((&SecA == &SecB) && !STI.hasFeature(LoongArch::FeatureRelax))
return true;
}
diff --git a/llvm/test/MC/LoongArch/Misc/cfi-advance.s b/llvm/test/MC/LoongArch/Misc/cfi-advance.s
index 662c43e6bceaf..faec615c0b6d4 100644
--- a/llvm/test/MC/LoongArch/Misc/cfi-advance.s
+++ b/llvm/test/MC/LoongArch/Misc/cfi-advance.s
@@ -1,6 +1,8 @@
# RUN: llvm-mc --filetype=obj --triple=loongarch64 -mattr=-relax %s -o %t.o
# RUN: llvm-readobj -r %t.o | FileCheck --check-prefix=RELOC %s
# RUN: llvm-dwarfdump --debug-frame %t.o | FileCheck --check-prefix=DWARFDUMP %s
+# RUN: llvm-mc --filetype=obj --triple=loongarch64 -mattr=+relax %s \
+# RUN: | llvm-readobj -r - | FileCheck --check-prefix=RELAX %s
# RELOC: Relocations [
# RELOC-NEXT: .rela.eh_frame {
@@ -12,6 +14,12 @@
# DWARFDUMP-NEXT: DW_CFA_advance_loc: 8
# DWARFDUMP-NEXT: DW_CFA_def_cfa_offset: +8
+# RELAX: Relocations [
+# RELAX: .rela.eh_frame {
+# RELAX-NEXT: 0x1C R_LARCH_32_PCREL .L{{.*}} 0x0
+# RELAX-NEXT: }
+# RELAX-NEXT: ]
+
.text
.globl test
.p2align 2
diff --git a/llvm/test/MC/LoongArch/Relocations/fde-reloc.s b/llvm/test/MC/LoongArch/Relocations/fde-reloc.s
index 990e07c7f00bd..ab911d1853a87 100644
--- a/llvm/test/MC/LoongArch/Relocations/fde-reloc.s
+++ b/llvm/test/MC/LoongArch/Relocations/fde-reloc.s
@@ -1,5 +1,7 @@
-# RUN: llvm-mc --filetype=obj --triple=loongarch64 < %s \
+# RUN: llvm-mc --filetype=obj --triple=loongarch64 --mattr=-relax < %s \
# RUN: | llvm-readobj -r - | FileCheck %s
+# RUN: llvm-mc --filetype=obj --triple=loongarch64 --mattr=+relax < %s \
+# RUN: | llvm-readobj -r - | FileCheck %s --check-prefix=RELAX
## Ensure that the eh_frame records the symbolic difference with
## the R_LARCH_32_PCREL relocation.
@@ -12,3 +14,6 @@ func:
# CHECK: Section (4) .rela.eh_frame {
# CHECK-NEXT: 0x1C R_LARCH_32_PCREL .text 0x0
# CHECK-NEXT: }
+# RELAX: Section ({{.*}}) .rela.eh_frame {
+# RELAX-NEXT: 0x1C R_LARCH_32_PCREL .L{{.*}} 0x0
+# RELAX-NEXT: }
diff --git a/llvm/test/MC/LoongArch/Relocations/sub-expr.s b/llvm/test/MC/LoongArch/Relocations/sub-expr.s
index 0179e1027af8f..b8d24b91ca1a8 100644
--- a/llvm/test/MC/LoongArch/Relocations/sub-expr.s
+++ b/llvm/test/MC/LoongArch/Relocations/sub-expr.s
@@ -1,5 +1,7 @@
-# RUN: llvm-mc --filetype=obj --triple=loongarch64 %s -o %t
-# RUN: llvm-readobj -r %t | FileCheck %s
+# RUN: llvm-mc --filetype=obj --triple=loongarch64 --mattr=-relax %s \
+# RUN: | llvm-readobj -r - | FileCheck %s
+# RUN: llvm-mc --filetype=obj --triple=loongarch64 --mattr=+relax %s \
+# RUN: | llvm-readobj -r - | FileCheck %s --check-prefix=RELAX
## Check that subtraction expressions emit R_LARCH_32_PCREL and R_LARCH_64_PCREL relocations.
@@ -7,13 +9,46 @@
# CHECK: Relocations [
# CHECK-NEXT: Section ({{.*}}) .rela.data {
-# CHECK-NEXT: 0x0 R_LARCH_64_PCREL sx 0x0
-# CHECK-NEXT: 0x8 R_LARCH_64_PCREL sy 0x0
-# CHECK-NEXT: 0x10 R_LARCH_32_PCREL sx 0x0
-# CHECK-NEXT: 0x14 R_LARCH_32_PCREL sy 0x0
+# CHECK-NEXT: 0x0 R_LARCH_64_PCREL sx 0x4
+# CHECK-NEXT: 0x8 R_LARCH_64_PCREL sy 0x4
+# CHECK-NEXT: 0x10 R_LARCH_32_PCREL sx 0x4
+# CHECK-NEXT: 0x14 R_LARCH_32_PCREL sy 0x4
+# CHECK-NEXT: 0x18 R_LARCH_ADD64 sx 0x4
+# CHECK-NEXT: 0x18 R_LARCH_SUB64 sy 0x4
+# CHECK-NEXT: 0x20 R_LARCH_ADD64 sy 0x4
+# CHECK-NEXT: 0x20 R_LARCH_SUB64 sx 0x4
+# CHECK-NEXT: 0x28 R_LARCH_ADD32 sx 0x4
+# CHECK-NEXT: 0x28 R_LARCH_SUB32 sy 0x4
+# CHECK-NEXT: 0x2C R_LARCH_ADD32 sy 0x4
+# CHECK-NEXT: 0x2C R_LARCH_SUB32 sx 0x4
+# CHECK-NEXT: 0x30 R_LARCH_ADD64 .data 0x30
+# CHECK-NEXT: 0x30 R_LARCH_SUB64 sx 0x4
+# CHECK-NEXT: 0x38 R_LARCH_ADD32 .data 0x38
+# CHECK-NEXT: 0x38 R_LARCH_SUB32 sy 0x4
# CHECK-NEXT: }
+# RELAX: Relocations [
+# RELAX-NEXT: Section ({{.*}}) .rela.data {
+# RELAX-NEXT: 0x0 R_LARCH_64_PCREL x 0x0
+# RELAX-NEXT: 0x8 R_LARCH_64_PCREL y 0x0
+# RELAX-NEXT: 0x10 R_LARCH_32_PCREL x 0x0
+# RELAX-NEXT: 0x14 R_LARCH_32_PCREL y 0x0
+# RELAX-NEXT: 0x18 R_LARCH_ADD64 x 0x0
+# RELAX-NEXT: 0x18 R_LARCH_SUB64 y 0x0
+# RELAX-NEXT: 0x20 R_LARCH_ADD64 y 0x0
+# RELAX-NEXT: 0x20 R_LARCH_SUB64 x 0x0
+# RELAX-NEXT: 0x28 R_LARCH_ADD32 x 0x0
+# RELAX-NEXT: 0x28 R_LARCH_SUB32 y 0x0
+# RELAX-NEXT: 0x2C R_LARCH_ADD32 y 0x0
+# RELAX-NEXT: 0x2C R_LARCH_SUB32 x 0x0
+# RELAX-NEXT: 0x30 R_LARCH_ADD64 {{.*}} 0x0
+# RELAX-NEXT: 0x30 R_LARCH_SUB64 x 0x0
+# RELAX-NEXT: 0x38 R_LARCH_ADD32 {{.*}} 0x0
+# RELAX-NEXT: 0x38 R_LARCH_SUB32 y 0x0
+# RELAX-NEXT: }
+
.section sx,"a"
+nop
x:
nop
@@ -22,7 +57,14 @@ nop
.8byte y-.
.4byte x-.
.4byte y-.
+.8byte x-y
+.8byte y-x
+.4byte x-y
+.4byte y-x
+.8byte .-x
+.4byte .-y
.section sy,"a"
+nop
y:
nop
|
@@ -447,19 +447,16 @@ bool LoongArchAsmBackend::addReloc(const MCFragment &F, const MCFixup &Fixup, | |||
if (!force) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I forgot why we need check the force
while RISC-V do not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because later it calls SA.getSection() and SB.getSection(). I want to handle the other cases by these section info.
E.g. for case (SecB == SecCur and SecA != SecCur), use Fallback() to emit PCRel.
For llvm/test/MC/LoongArch/Relocations/sub-expr.s
,
LoongArch emits,
0000000000000000 000000010000006d R_LARCH_64_PCREL 0000000000000004 x + 0
0000000000000008 000000020000006d R_LARCH_64_PCREL 0000000000000004 y + 0
0000000000000010 0000000100000063 R_LARCH_32_PCREL 0000000000000004 x + 0
0000000000000014 0000000200000063 R_LARCH_32_PCREL 0000000000000004 y + 0
...
RISCV emits,
0000000000000000 0000000200000024 R_RISCV_ADD64 0000000000000004 x + 0
0000000000000000 0000000300000028 R_RISCV_SUB64 0000000000000000 .L0 + 0
0000000000000008 0000000600000024 R_RISCV_ADD64 0000000000000004 y + 0
0000000000000008 0000000500000028 R_RISCV_SUB64 0000000000000008 .L0 + 0
0000000000000010 0000000200000023 R_RISCV_ADD32 0000000000000004 x + 0
0000000000000010 0000000700000027 R_RISCV_SUB32 0000000000000010 .L0 + 0
0000000000000014 0000000600000023 R_RISCV_ADD32 0000000000000004 y + 0
0000000000000014 0000000800000027 R_RISCV_SUB32 0000000000000014 .L0 + 0
...
// false and then this work can be finished by handleFixup. | ||
if (&SecA != &SecB) | ||
// Fallback for PCRel relocations. | ||
if ((&SecA != &SecB) && (&SecB == &SecCur)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't add parentheses for (a == b) && (c == d)
For SecA != SecB but SecB is current section, fallback for pcrel{64,32} relocations. For linker relaxation being disabled and SecA == SecB, return directly for avoid record relocations. In other cases, record relocations which also allows across sections.
05dd7c3
to
5b0d1a0
Compare
Addressed MaskRay's comment. Fixed test error after commit ab0931b. |
// is not same as the section of Fixup, it will report error. Just return | ||
// false and then this work can be finished by handleFixup. | ||
if (&SecA != &SecB) | ||
// Fallback for PCRel relocations. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems that we fallback because the generic case may generate R_LARCH_32_PCREL, which is better than ADD/SUB relocation pair here? The comment should be clarified.
The code is different from RISCVAsmBackend.cpp. I haven't studied why it's different.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I process the case A-B when B is same section with the current to generate PCRel relocations, by resolve it as A-PC+PC-B
. The A-PC
will be resolved as a PCRel relocation. The PC-B
should be a constant. Then I use a copy of RISCV::isPCRelFixupResolved to evaluate whether PC-B
is a constant.
To handle the case of A - B which B is same section with the current, generate PCRel relocations is better than ADD/SUB relocation pair. We can resolve it as A - PC + PC - B. The A - PC will be resolved as a PCRel relocation, while PC - B will serve as the addend. If the linker relaxation is disabled, it can be done directly since PC - B is constant. Otherwise, we should evaluate whether PC - B is constant. If it can be resolved as PCRel, use Fallback which generates R_LARCH_{32,64}_PCREL relocation later. Refer to RISCV, we add isPCRelFixupResolved to evaluate whether the PC - B is constant.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks.
For SecA != SecB but SecB is current section, fallback for pcrel{64,32} relocations. For linker relaxation being disabled and SecA == SecB, return directly for avoid record relocations. In other cases, record relocations which also allows across sections.
For SecA != SecB but SecB is current section, fallback for pcrel{64,32} relocations. For linker relaxation being disabled and SecA == SecB, return directly for avoid record relocations. In other cases, record relocations which also allows across sections.
For SecA != SecB but SecB is current section, fallback for pcrel{64,32} relocations. For linker relaxation being disabled and SecA == SecB, return directly for avoid record relocations. In other cases, record relocations which also allows across sections.