diff options
Diffstat (limited to 'lld/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp')
-rw-r--r-- | lld/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp | 12 |
1 files changed, 11 insertions, 1 deletions
diff --git a/lld/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp b/lld/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp index 77399225f1e..26d1e63f7da 100644 --- a/lld/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp +++ b/lld/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp @@ -92,10 +92,20 @@ DefinedAtom::ContentPermissions getPermissions(const coff_section *section) { DefinedAtom::Alignment getAlignment(const coff_section *section) { if (section->Characteristics & llvm::COFF::IMAGE_SCN_TYPE_NO_PAD) return DefinedAtom::Alignment(0); + // Bit [20:24] contains section alignment information. We need to decrease // the value stored by 1 in order to get the real exponent (e.g, ALIGN_1BYTE // is 0x00100000, but the exponent should be 0) - int powerOf2 = ((section->Characteristics >> 20) & 0xf) - 1; + uint32_t charactersitcis = (section->Characteristics >> 20) & 0xf; + + // If all bits are off, we treat it as if ALIGN_1BYTE was on. The PE/COFF spec + // does not say anything about this case, but CVTRES.EXE does not set any bit + // in characteristics[20:24], and its output is intended to be copied to .rsrc + // section with no padding, so I think doing this is the right thing. + if (charactersitcis == 0) + return DefinedAtom::Alignment(0); + + uint32_t powerOf2 = charactersitcis - 1; return DefinedAtom::Alignment(powerOf2); } |