@@ -653,15 +653,17 @@ enum RankFlags {
653
653
RF_NOT_ADDR_SET = 1 << 27 ,
654
654
RF_NOT_ALLOC = 1 << 26 ,
655
655
RF_PARTITION = 1 << 18 , // Partition number (8 bits)
656
+ RF_LARGE_EXEC_WRITE = 1 << 16 ,
656
657
RF_LARGE_ALT = 1 << 15 ,
657
658
RF_WRITE = 1 << 14 ,
658
659
RF_EXEC_WRITE = 1 << 13 ,
659
660
RF_EXEC = 1 << 12 ,
660
661
RF_RODATA = 1 << 11 ,
661
- RF_LARGE = 1 << 10 ,
662
- RF_NOT_RELRO = 1 << 9 ,
663
- RF_NOT_TLS = 1 << 8 ,
664
- RF_BSS = 1 << 7 ,
662
+ RF_LARGE_EXEC = 1 << 10 ,
663
+ RF_LARGE = 1 << 9 ,
664
+ RF_NOT_RELRO = 1 << 8 ,
665
+ RF_NOT_TLS = 1 << 7 ,
666
+ RF_BSS = 1 << 6 ,
665
667
};
666
668
667
669
unsigned elf::getSectionRank (Ctx &ctx, OutputSection &osec) {
@@ -691,14 +693,15 @@ unsigned elf::getSectionRank(Ctx &ctx, OutputSection &osec) {
691
693
// places.
692
694
bool isExec = osec.flags & SHF_EXECINSTR;
693
695
bool isWrite = osec.flags & SHF_WRITE;
696
+ bool isLarge = osec.flags & SHF_X86_64_LARGE && ctx.arg .emachine == EM_X86_64;
694
697
695
698
if (!isWrite && !isExec) {
696
699
// Among PROGBITS sections, place .lrodata further from .text.
697
700
// For -z lrodata-after-bss, place .lrodata after .lbss like GNU ld. This
698
701
// layout has one extra PT_LOAD, but alleviates relocation overflow
699
702
// pressure for absolute relocations referencing small data from -fno-pic
700
703
// relocatable files.
701
- if (osec. flags & SHF_X86_64_LARGE && ctx. arg . emachine == EM_X86_64 )
704
+ if (isLarge )
702
705
rank |= ctx.arg .zLrodataAfterBss ? RF_LARGE_ALT : 0 ;
703
706
else
704
707
rank |= ctx.arg .zLrodataAfterBss ? 0 : RF_LARGE;
@@ -722,7 +725,16 @@ unsigned elf::getSectionRank(Ctx &ctx, OutputSection &osec) {
722
725
else
723
726
rank |= RF_RODATA;
724
727
} else if (isExec) {
725
- rank |= isWrite ? RF_EXEC_WRITE : RF_EXEC;
728
+ // Place readonly .ltext before .lrodata and writable .ltext after .lbss to
729
+ // keep writable and readonly segments separate.
730
+ if (isLarge) {
731
+ if (isWrite)
732
+ rank |= RF_LARGE_EXEC_WRITE;
733
+ else
734
+ rank |= RF_LARGE_EXEC;
735
+ } else {
736
+ rank |= isWrite ? RF_EXEC_WRITE : RF_EXEC;
737
+ }
726
738
} else {
727
739
rank |= RF_WRITE;
728
740
// The TLS initialization block needs to be a single contiguous block. Place
@@ -737,7 +749,7 @@ unsigned elf::getSectionRank(Ctx &ctx, OutputSection &osec) {
737
749
// alleviates relocation overflow pressure.
738
750
// For -z lrodata-after-bss, place .lbss/.lrodata/.ldata after .bss.
739
751
// .bss/.lbss being adjacent reuses the NOBITS size optimization.
740
- if (osec. flags & SHF_X86_64_LARGE && ctx. arg . emachine == EM_X86_64 ) {
752
+ if (isLarge ) {
741
753
rank |= ctx.arg .zLrodataAfterBss
742
754
? (osec.type == SHT_NOBITS ? 1 : RF_LARGE_ALT)
743
755
: RF_LARGE;
0 commit comments