From 46304e03ecb09ae31f535a0974ef4df165eb947f Mon Sep 17 00:00:00 2001 From: Martin Storsjo Date: Thu, 16 Nov 2017 12:06:42 +0000 Subject: [PATCH] [COFF] Don't write long section names for sections that will be mapped at runtime Sections that will be mapped at runtime will only have the short section name available, since the string table it points into isn't mapped. Therefore prefer truncating those names over writing a long name that is unavailable at runtime. This allows libunwind to find the .eh_frame section at runtime even if the module was built with debug info enabled. Differential Revision: https://reviews.llvm.org/D40025 llvm-svn: 318391 --- lld/COFF/Writer.cpp | 10 +++++++++- lld/test/COFF/long-section-name.test | 19 ++++++++++++++++++- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/lld/COFF/Writer.cpp b/lld/COFF/Writer.cpp index 126a497a4ed7..008d2146e384 100644 --- a/lld/COFF/Writer.cpp +++ b/lld/COFF/Writer.cpp @@ -211,7 +211,8 @@ void OutputSection::writeHeaderTo(uint8_t *Buf) { // If name is too long, write offset into the string table as a name. sprintf(Hdr->Name, "/%d", StringTableOff); } else { - assert(!Config->Debug || Name.size() <= COFF::NameSize); + assert(!Config->Debug || Name.size() <= COFF::NameSize || + (Hdr->Characteristics & IMAGE_SCN_MEM_DISCARDABLE) == 0); strncpy(Hdr->Name, Name.data(), std::min(Name.size(), (size_t)COFF::NameSize)); } @@ -541,6 +542,13 @@ void Writer::createSymbolAndStringTable() { StringRef Name = Sec->getName(); if (Name.size() <= COFF::NameSize) continue; + // If a section isn't discardable (i.e. will be mapped at runtime), + // prefer a truncated section name over a long section name in + // the string table that is unavailable at runtime. This is different from + // what link.exe does, but finding ".eh_fram" instead of "/4" is useful + // to libunwind. + if ((Sec->getPermissions() & IMAGE_SCN_MEM_DISCARDABLE) == 0) + continue; Sec->setStringTableOff(addEntryToStringTable(Name)); } diff --git a/lld/test/COFF/long-section-name.test b/lld/test/COFF/long-section-name.test index 1de329db0296..158cc828e0e0 100644 --- a/lld/test/COFF/long-section-name.test +++ b/lld/test/COFF/long-section-name.test @@ -2,6 +2,7 @@ # RUN: lld-link /debug /out:%t.exe /entry:main %t.obj # RUN: llvm-readobj -sections %t.exe | FileCheck %s +# CHECK: Name: .eh_fram ( # CHECK: Name: .data_long_section_name # CHECK: Name: .text_long_section_name @@ -11,10 +12,14 @@ header: Characteristics: [ ] sections: - Name: .text_long_section_name - Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] + Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_DISCARDABLE ] Alignment: 4 SectionData: B82A000000C3 - Name: .data_long_section_name + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE, IMAGE_SCN_MEM_DISCARDABLE ] + Alignment: 4 + SectionData: "00" + - Name: .eh_frame Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] Alignment: 4 SectionData: "00" @@ -49,6 +54,18 @@ symbols: NumberOfLinenumbers: 0 CheckSum: 0 Number: 0 + - Name: .eh_frame + Value: 0 + SectionNumber: 3 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 0 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 0 + Number: 0 - Name: main Value: 0 SectionNumber: 1