Index: llvm/test/tools/llvm-objcopy/COFF/set-flags-on-setion-added.test =================================================================== --- /dev/null +++ llvm/test/tools/llvm-objcopy/COFF/set-flags-on-setion-added.test @@ -0,0 +1,32 @@ +# RUN: yaml2obj %s -o %t + +## Test that llvm-objcopy can add sections and set its flags in the same +## call. +# RUN: echo DEADBEEF > %t.sec +# RUN: llvm-objcopy --set-section-flags=.test.section1=code --add-section=.test.section1=%t.sec --set-section-flags=.test.section2=data --add-section=.test.section2=%t.sec %t %t1 +# RUN: llvm-readobj --sections --section-data %t1 | FileCheck %s --check-prefixes=CHECK-ADD + +# CHECK-ADD: Name: .test.section1 +# CHECK-ADD-NEXT: VirtualSize: 0x9 +# CHECK-ADD-NEXT: VirtualAddress: 0x0 +# CHECK-ADD-NEXT: RawDataSize: 9 +# CHECK-ADD: IMAGE_SCN_CNT_CODE (0x20) +# CHECK-ADD-NEXT: IMAGE_SCN_MEM_EXECUTE (0x20000000) +# CHECK-ADD-NEXT: IMAGE_SCN_MEM_READ (0x40000000) +# CHECK-ADD-NEXT: IMAGE_SCN_MEM_WRITE (0x80000000) + +# CHECK-ADD: Name: .test.section2 +# CHECK-ADD-NEXT: VirtualSize: 0x9 +# CHECK-ADD-NEXT: VirtualAddress: 0x9 +# CHECK-ADD-NEXT: RawDataSize: 9 +# CHECK-ADD: IMAGE_SCN_CNT_INITIALIZED_DATA (0x40) +# CHECK-ADD-NEXT: IMAGE_SCN_MEM_READ (0x40000000) +# CHECK-ADD-NEXT: IMAGE_SCN_MEM_WRITE (0x80000000) + +--- !COFF +header: + Machine: IMAGE_FILE_MACHINE_AMD64 + Characteristics: [ ] +sections: +symbols: +... Index: llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp =================================================================== --- llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp +++ llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp @@ -94,7 +94,7 @@ return Error::success(); } -static void setSectionFlags(Section &Sec, SectionFlag AllFlags) { +static uint32_t flagsToCharacteristics(SectionFlag AllFlags, uint32_t OldChar) { // Need to preserve alignment flags. const uint32_t PreserveMask = IMAGE_SCN_ALIGN_1BYTES | IMAGE_SCN_ALIGN_2BYTES | IMAGE_SCN_ALIGN_4BYTES | @@ -107,8 +107,7 @@ // Setup new section characteristics based on the flags provided in command // line. - uint32_t NewCharacteristics = - (Sec.Header.Characteristics & PreserveMask) | IMAGE_SCN_MEM_READ; + uint32_t NewCharacteristics = (OldChar & PreserveMask) | IMAGE_SCN_MEM_READ; if ((AllFlags & SectionFlag::SecAlloc) && !(AllFlags & SectionFlag::SecLoad)) NewCharacteristics |= IMAGE_SCN_CNT_UNINITIALIZED_DATA; @@ -128,7 +127,7 @@ if (AllFlags & SectionFlag::SecExclude) NewCharacteristics |= IMAGE_SCN_LNK_REMOVE; - Sec.Header.Characteristics = NewCharacteristics; + return NewCharacteristics; } static Error handleArgs(const CommonConfig &Config, Object &Obj) { @@ -226,7 +225,8 @@ for (Section &Sec : Obj.getMutableSections()) { const auto It = Config.SetSectionFlags.find(Sec.Name); if (It != Config.SetSectionFlags.end()) - setSectionFlags(Sec, It->second.NewFlags); + Sec.Header.Characteristics = flagsToCharacteristics( + It->second.NewFlags, Sec.Header.Characteristics); } for (const auto &Flag : Config.AddSection) { @@ -238,11 +238,18 @@ return createFileError(FileName, errorCodeToError(BufOrErr.getError())); auto Buf = std::move(*BufOrErr); + uint32_t Characteristics; + const auto It = Config.SetSectionFlags.find(SecName); + if (It != Config.SetSectionFlags.end()) + Characteristics = flagsToCharacteristics(It->second.NewFlags, 0); + else + Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_1BYTES; + addSection( Obj, SecName, makeArrayRef(reinterpret_cast(Buf->getBufferStart()), Buf->getBufferSize()), - IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_1BYTES); + Characteristics); } if (!Config.AddGnuDebugLink.empty())