Skip to content

Commit df71243

Browse files
committed
MC: Evaluate .org during fragment relaxation
Similar to 742ecfc for MCFillFragment, ensure `.org` directives with expressions are re-evaluated during fragment relaxation, as their sizes may change. Continue iteration to prevent stale, incorrect sizes. While I knew MCOrgFragment likely needed to be re-evaluated at all, I did not have a motivation to add it;-) This fixes the root cause of ClangBuiltLinux/linux#2116 (writeSectionData assertion failure when building the Linux kernel for arm64) The issue cannot be reliably replicated. The specific test case would not replicate if any of the following condition was not satisfied: * .org was not re-evaluated. Fixed by this commit. * clang -cc1as has a redundant `initSections` call, leading to a redundant initial FT_Align fragment. llvm-mc -filetype=obj, lacking the redundant `initSections`, doesn't replicate. * faa931b decreased sizeof(MCFragment). * f1aa605 added more fragments
1 parent c9684e5 commit df71243

File tree

4 files changed

+16
-2
lines changed

4 files changed

+16
-2
lines changed

llvm/include/llvm/MC/MCAssembler.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ class MCAssembler {
120120
bool relaxCVInlineLineTable(MCCVInlineLineTableFragment &DF);
121121
bool relaxCVDefRange(MCCVDefRangeFragment &DF);
122122
bool relaxFill(MCFillFragment &F);
123+
bool relaxOrg(MCOrgFragment &F);
123124

124125
public:
125126
/// Construct a new assembler instance.

llvm/include/llvm/MC/MCSection.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -383,13 +383,16 @@ class MCOrgFragment : public MCFragment {
383383
/// Source location of the directive that this fragment was created for.
384384
SMLoc Loc;
385385

386+
uint64_t Size = 0;
387+
386388
public:
387389
MCOrgFragment(const MCExpr &Offset, int8_t Value, SMLoc Loc)
388390
: MCFragment(FT_Org), Value(Value), Offset(&Offset), Loc(Loc) {}
389391

390392
const MCExpr &getOffset() const { return *Offset; }
391-
392393
uint8_t getValue() const { return Value; }
394+
uint64_t getSize() const { return Size; }
395+
void setSize(uint64_t Value) { Size = Value; }
393396

394397
SMLoc getLoc() const { return Loc; }
395398

llvm/lib/MC/MCAssembler.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -945,6 +945,14 @@ bool MCAssembler::relaxFill(MCFillFragment &F) {
945945
return true;
946946
}
947947

948+
bool MCAssembler::relaxOrg(MCOrgFragment &F) {
949+
uint64_t Size = computeFragmentSize(F);
950+
if (F.getSize() == Size)
951+
return false;
952+
F.setSize(Size);
953+
return true;
954+
}
955+
948956
bool MCAssembler::relaxFragment(MCFragment &F) {
949957
switch(F.getKind()) {
950958
default:
@@ -966,6 +974,8 @@ bool MCAssembler::relaxFragment(MCFragment &F) {
966974
return relaxCVDefRange(cast<MCCVDefRangeFragment>(F));
967975
case MCFragment::FT_Fill:
968976
return relaxFill(cast<MCFillFragment>(F));
977+
case MCFragment::FT_Org:
978+
return relaxOrg(static_cast<MCOrgFragment &>(F));
969979
}
970980
}
971981

llvm/test/MC/ELF/mc-dump.s

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
# CHECK-NEXT:5 LEB Size:0+1 [15] Value:.Ltmp0-_start Signed:0
3131
# CHECK:]
3232

33-
# CHECK: 2 assembler - Number of fixup evaluations for relaxation
33+
# CHECK: 3 assembler - Number of fixup evaluations for relaxation
3434
# CHECK: 8 assembler - Number of fixups
3535

3636
# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t -debug-only=mc-dump -save-temp-labels -g 2>&1 | FileCheck %s --check-prefix=CHECK2

0 commit comments

Comments
 (0)