diff --git a/lld/COFF/Writer.cpp b/lld/COFF/Writer.cpp --- a/lld/COFF/Writer.cpp +++ b/lld/COFF/Writer.cpp @@ -928,8 +928,14 @@ // Move DISCARDABLE (or non-memory-mapped) sections to the end of file // because the loader cannot handle holes. Stripping can remove other // discardable ones than .reloc, which is first of them (created early). - if (s->header.Characteristics & IMAGE_SCN_MEM_DISCARDABLE) + if (s->header.Characteristics & IMAGE_SCN_MEM_DISCARDABLE) { + // Move discardable sections named .debug_ to the end, after other + // discardable sections. Stripping only removes the sections named + // .debug_* - thus try to avoid leaving holes after stripping. + if (s->name.startswith(".debug_")) + return 3; return 2; + } // .rsrc should come at the end of the non-discardable sections because its // size may change by the Win32 UpdateResources() function, causing // subsequent sections to move (see https://crbug.com/827082). diff --git a/lld/test/COFF/sort-debug.test b/lld/test/COFF/sort-debug.test --- a/lld/test/COFF/sort-debug.test +++ b/lld/test/COFF/sort-debug.test @@ -10,6 +10,7 @@ # CHECK: Name: .text # CHECK: Name: .reloc +# CHECK: Name: .rmeta # CHECK: Name: .debug_abbrev # CHECK: Name: .debug_info # CHECK: Name: .debug_line @@ -18,6 +19,7 @@ # NODEBUG: Name: .text # NODEBUG: Name: .reloc +# NODEBUG: Name: .rmeta # NODEBUG-NOT: Name: .debug_abbrev # NODEBUG-NOT: Name: .debug_info # NODEBUG-NOT: Name: .debug_line @@ -183,6 +185,10 @@ - VirtualAddress: 43 SymbolName: .text Type: IMAGE_REL_I386_DIR32 + - Name: .rmeta + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] + Alignment: 1 + SectionData: 00112233 symbols: - Name: .text Value: 0