diff --git a/lld/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp b/lld/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp index 66116cdd9918..ace10cb60411 100644 --- a/lld/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp +++ b/lld/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp @@ -320,9 +320,9 @@ class GenericSectionChunk : public SectionChunk { public: virtual void write(uint8_t *fileBuffer); - GenericSectionChunk(StringRef name, + GenericSectionChunk(const PECOFFLinkingContext &ctx, StringRef name, const std::vector &atoms) - : SectionChunk(name, getCharacteristics(name, atoms)) { + : SectionChunk(name, getCharacteristics(ctx, name, atoms)) { for (auto *a : atoms) appendAtom(a); _sectionHeader.VirtualSize = _size; @@ -330,36 +330,13 @@ public: } private: - uint32_t getCharacteristics(StringRef name, + uint32_t getCharacteristics(const PECOFFLinkingContext &ctx, StringRef name, const std::vector &atoms) { - const uint32_t code = llvm::COFF::IMAGE_SCN_CNT_CODE; - const uint32_t execute = llvm::COFF::IMAGE_SCN_MEM_EXECUTE; - const uint32_t read = llvm::COFF::IMAGE_SCN_MEM_READ; - const uint32_t write = llvm::COFF::IMAGE_SCN_MEM_WRITE; - const uint32_t data = llvm::COFF::IMAGE_SCN_CNT_INITIALIZED_DATA; - const uint32_t bss = llvm::COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA; - if (name == ".text") - return code | execute | read; - if (name == ".data") - return data | read | write; - if (name == ".rdata") - return data | read; - if (name == ".bss") - return bss | read | write; - assert(atoms.size() > 0); - switch (atoms[0]->permissions()) { - case DefinedAtom::permR__: - return data | read; - case DefinedAtom::permRW_: - return data | read | write; - case DefinedAtom::permR_X: - return code | execute | read; - case DefinedAtom::permRWX: - return code | execute | read | write; - default: - llvm_unreachable("Unsupported permission"); - } + return ctx.getSectionAttributes(name, getDefaultCharacteristics(name, atoms)); } + + uint32_t getDefaultCharacteristics( + StringRef name, const std::vector &atoms); }; /// A BaseRelocAtom represents a base relocation block in ".reloc" section. @@ -714,6 +691,37 @@ void GenericSectionChunk::write(uint8_t *fileBuffer) { SectionChunk::write(fileBuffer); } +uint32_t GenericSectionChunk::getDefaultCharacteristics( + StringRef name, const std::vector &atoms) { + const uint32_t code = llvm::COFF::IMAGE_SCN_CNT_CODE; + const uint32_t execute = llvm::COFF::IMAGE_SCN_MEM_EXECUTE; + const uint32_t read = llvm::COFF::IMAGE_SCN_MEM_READ; + const uint32_t write = llvm::COFF::IMAGE_SCN_MEM_WRITE; + const uint32_t data = llvm::COFF::IMAGE_SCN_CNT_INITIALIZED_DATA; + const uint32_t bss = llvm::COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA; + if (name == ".text") + return code | execute | read; + if (name == ".data") + return data | read | write; + if (name == ".rdata") + return data | read; + if (name == ".bss") + return bss | read | write; + assert(atoms.size() > 0); + switch (atoms[0]->permissions()) { + case DefinedAtom::permR__: + return data | read; + case DefinedAtom::permRW_: + return data | read | write; + case DefinedAtom::permR_X: + return code | execute | read; + case DefinedAtom::permRWX: + return code | execute | read | write; + default: + llvm_unreachable("Unsupported permission"); + } +} + void SectionHeaderTableChunk::addSection(SectionChunk *chunk) { _sections.push_back(chunk); } @@ -925,7 +933,8 @@ void ExecutableWriter::build(const File &linkedFile) { for (auto i : atoms) { StringRef sectionName = i.first; std::vector &contents = i.second; - auto *section = new GenericSectionChunk(sectionName, contents); + auto *section = new GenericSectionChunk(_PECOFFLinkingContext, sectionName, + contents); addSectionChunk(section, sectionTable); if (!text && sectionName == ".text") diff --git a/lld/test/pecoff/section-attribute.test b/lld/test/pecoff/section-attribute.test new file mode 100644 index 000000000000..a5e71625df99 --- /dev/null +++ b/lld/test/pecoff/section-attribute.test @@ -0,0 +1,45 @@ +# RUN: yaml2obj %p/Inputs/nonstandard-sections.obj.yaml > %t.obj +# RUN: lld -flavor link /out:%t.exe /subsystem:console /force \ +# RUN: /section:.foo,d /section:.bar,rw /section:.text,rwe -- %t.obj +# RUN: llvm-readobj -sections %t.exe | FileCheck %s + +CHECK: Sections [ +CHECK: Section { +CHECK: Number: 1 +CHECK: Name: .bar (2E 62 61 72 00 00 00 00) +CHECK: Characteristics [ (0xC0000040) +CHECK: IMAGE_SCN_CNT_INITIALIZED_DATA (0x40) +CHECK: IMAGE_SCN_MEM_READ (0x40000000) +CHECK: IMAGE_SCN_MEM_WRITE (0x80000000) +CHECK: ] +CHECK: } +CHECK: Section { +CHECK: Number: 2 +CHECK: Name: .data (2E 64 61 74 61 00 00 00) +CHECK: Characteristics [ (0xC0000040) +CHECK: IMAGE_SCN_CNT_INITIALIZED_DATA (0x40) +CHECK: IMAGE_SCN_MEM_READ (0x40000000) +CHECK: IMAGE_SCN_MEM_WRITE (0x80000000) +CHECK: ] +CHECK: } +CHECK: Section { +CHECK: Number: 3 +CHECK: Name: .foo (2E 66 6F 6F 00 00 00 00) +CHECK: Characteristics [ (0xC2000040) +CHECK: IMAGE_SCN_CNT_INITIALIZED_DATA (0x40) +CHECK: IMAGE_SCN_MEM_DISCARDABLE (0x2000000) +CHECK: IMAGE_SCN_MEM_READ (0x40000000) +CHECK: IMAGE_SCN_MEM_WRITE (0x80000000) +CHECK: ] +CHECK: } +CHECK: Section { +CHECK: Number: 4 +CHECK: Name: .text (2E 74 65 78 74 00 00 00) +CHECK: Characteristics [ (0xE0000020) +CHECK: IMAGE_SCN_CNT_CODE (0x20) +CHECK: IMAGE_SCN_MEM_EXECUTE (0x20000000) +CHECK: IMAGE_SCN_MEM_READ (0x40000000) +CHECK: IMAGE_SCN_MEM_WRITE (0x80000000) +CHECK: ] +CHECK: } +CHECK: ]