if (sec.sh_type == SHT_REL || sec.sh_type == SHT_RELA)
this->sections[i] = createInputSection(sec);
- if (!(sec.sh_flags & SHF_LINK_ORDER))
+ // A SHF_LINK_ORDER section with sh_link=0 is handled as if it did not have
+ // the flag.
+ if (!(sec.sh_flags & SHF_LINK_ORDER) || !sec.sh_link)
continue;
- // .ARM.exidx sections have a reverse dependency on the InputSection they
- // have a SHF_LINK_ORDER dependency, this is identified by the sh_link.
InputSectionBase *linkSec = nullptr;
if (sec.sh_link < this->sections.size())
linkSec = this->sections[sec.sh_link];
if (!linkSec)
fatal(toString(this) + ": invalid sh_link index: " + Twine(sec.sh_link));
+ // A SHF_LINK_ORDER section is discarded if its linked-to section is
+ // discarded.
InputSection *isec = cast<InputSection>(this->sections[i]);
linkSec->dependentSections.push_back(isec);
if (!isa<InputSection>(linkSec))
static bool compareByFilePosition(InputSection *a, InputSection *b) {
InputSection *la = a->getLinkOrderDep();
InputSection *lb = b->getLinkOrderDep();
+ // SHF_LINK_ORDER sections with non-zero sh_link are ordered before others.
+ if (!la || !lb)
+ return la && !lb;
OutputSection *aOut = la->getParent();
OutputSection *bOut = lb->getParent();
sections.push_back(isec);
InputSection *link = isec->getLinkOrderDep();
- if (!link->getParent())
+ if (link && !link->getParent())
error(toString(isec) + ": sh_link points to discarded section " +
toString(link));
}
--- /dev/null
+## Test that we allow SHF_LINK_ORDER sections with sh_link=0.
+## SHF_LINK_ORDER sections with sh_link!=0 are ordered before others.
+# RUN: llvm-mc -filetype=obj %s -o %t.o
+# RUN: ld.lld %t.o -o %t
+# RUN: llvm-readelf -S -x .linkorder %t | FileCheck %s
+
+# CHECK: [Nr] Name {{.*}} Size ES Flg Lk Inf
+# CHECK-NEXT: [ 0] {{.*}}
+# CHECK-NEXT: [ 1] .linkorder {{.*}} 000004 00 AL 3 0
+# CHECK-NEXT: [ 2] .ignore {{.*}}
+# CHECK-NEXT: [ 3] .text {{.*}}
+
+# CHECK: Hex dump of section '.linkorder':
+# CHECK-NEXT: [[#%x,ADDR:]] 01020003
+
+## TODO Allow non-contiguous SHF_LINK_ORDER sections in an output section.
+# RUN: llvm-mc --filetype=obj --defsym EXTRA=1 %s -o %t.o
+# RUN: not ld.lld %t.o -o /dev/null
+
+.section .text,"ax",@progbits,unique,0
+.Ltext0:
+.section .text,"ax",@progbits,unique,1
+.Ltext1:
+.section .linkorder,"ao",@progbits,0,unique,0
+ .byte 0
+.section .linkorder,"ao",@progbits,.Ltext0
+ .byte 1
+.section .linkorder,"ao",@progbits,.Ltext1
+ .byte 2
+
+.ifdef EXTRA
+.section .linkorder,"a",@progbits
+ .byte 4
+.else
+.section .ignore,"ao",@progbits,.Ltext1
+.endif
+
+.section .linkorder,"ao",@progbits,0,unique,3
+ .byte 3