diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -826,13 +826,14 @@ // * It is easy to check if a give branch was taken. // * It is easy two see how similar two ranks are (see getRankProximity). enum RankFlags { - RF_NOT_ADDR_SET = 1 << 27, - RF_NOT_ALLOC = 1 << 26, - RF_PARTITION = 1 << 18, // Partition number (8 bits) - RF_NOT_PART_EHDR = 1 << 17, - RF_NOT_PART_PHDR = 1 << 16, - RF_NOT_INTERP = 1 << 15, - RF_NOT_NOTE = 1 << 14, + RF_NOT_ADDR_SET = 1 << 28, + RF_NOT_ALLOC = 1 << 27, + RF_PARTITION = 1 << 19, // Partition number (8 bits) + RF_NOT_PART_EHDR = 1 << 18, + RF_NOT_PART_PHDR = 1 << 17, + RF_NOT_INTERP = 1 << 16, + RF_NOT_NOTE = 1 << 15, + RF_LARGE = 1 << 14, RF_WRITE = 1 << 13, RF_EXEC_WRITE = 1 << 12, RF_EXEC = 1 << 11, @@ -939,6 +940,15 @@ // Some architectures have additional ordering restrictions for sections // within the same PT_LOAD. + + if (config->emachine == EM_X86_64) { + // Large sections should always come after non-large sections so that + // smaller relocations between non-large sections are less likely to + // overflow. + if (osec.flags & SHF_X86_64_LARGE) + rank |= RF_LARGE; + } + if (config->emachine == EM_PPC64) { // PPC64 has a number of special SHT_PROGBITS+SHF_ALLOC+SHF_WRITE sections // that we would like to make sure appear is a specific order to maximize diff --git a/lld/test/ELF/section-layout.s b/lld/test/ELF/section-layout.s --- a/lld/test/ELF/section-layout.s +++ b/lld/test/ELF/section-layout.s @@ -18,6 +18,14 @@ .section n,"",@nobits .section m,"" +.section u,"axl",@nobits +.section v,"axl" +.section w,"awl",@nobits +.section x,"awl" +.section y1,"awxl",@nobits +.section y2,"awxl" +.section z1,"al",@nobits +.section z2,"al" .section l,"awx",@nobits .section k,"awx" .section j,"aw",@nobits @@ -50,6 +58,16 @@ // CHECK: Name: j +// Large sections come at the end +// CHECK: Name: z1 +// CHECK: Name: z2 +// CHECK: Name: v +// CHECK: Name: u +// CHECK: Name: y2 +// CHECK: Name: y1 +// CHECK: Name: x +// CHECK: Name: w + // Non allocated sections are in input order. // CHECK: Name: t // CHECK: Name: s