[PECOFF] Fix alignment bug.

There was a bug that if a section has an alignment requirement and there are
multiple symbols at offset 0 in the section, only the last atom at offset 0
would be aligned properly. That bug would move only the last symbol to an
alignment boundary, leaving other symbols unaligned, although they should be at
the same location. That caused a mysterious SEGV error of the resultant
executable.

With this patch, we manage all symbols at the same location properly, rather
than keeping the last one.

llvm-svn: 190724
This commit is contained in:
Rui Ueyama 2013-09-13 21:11:00 +00:00
parent 1ea9b97707
commit a8ce9529c3
3 changed files with 62 additions and 6 deletions

View File

@ -478,7 +478,7 @@ private:
COFFDefinedAtom(*this, "", sectionName, Atom::scopeTranslationUnit,
type, perms, _merge[section], data, 0);
atoms.push_back(atom);
_definedAtomLocations[section][0] = atom;
_definedAtomLocations[section][0].push_back(atom);
return error_code::success();
}
@ -491,7 +491,7 @@ private:
COFFDefinedAtom(*this, "", sectionName, Atom::scopeTranslationUnit,
type, perms, _merge[section], data, ++ordinal);
atoms.push_back(atom);
_definedAtomLocations[section][0] = atom;
_definedAtomLocations[section][0].push_back(atom);
}
for (auto si = symbols.begin(), se = symbols.end(); si != se; ++si) {
@ -505,12 +505,12 @@ private:
type, perms, _merge[section], data, ++ordinal);
atoms.push_back(atom);
_symbolAtom[*si] = atom;
_definedAtomLocations[section][(*si)->Value] = atom;
_definedAtomLocations[section][(*si)->Value].push_back(atom);
}
// Finally, set alignment to the first atom so that the section contents
// will be aligned as specified by the object section header.
_definedAtomLocations[section][0]->setAlignment(getAlignment(section));
_definedAtomLocations[section][0][0]->setAlignment(getAlignment(section));
return error_code::success();
}
@ -542,7 +542,8 @@ private:
COFFDefinedFileAtom *&result, uint32_t &offsetInAtom) {
for (auto i : _definedAtomLocations[section]) {
uint32_t atomAddress = i.first;
COFFDefinedAtom *atom = i.second;
std::vector<COFFDefinedAtom *> &atomsAtSameLocation = i.second;
COFFDefinedAtom *atom = atomsAtSameLocation.back();
if (atomAddress <= targetAddress &&
targetAddress < atomAddress + atom->size()) {
result = atom;
@ -697,7 +698,8 @@ private:
// A sorted map to find an atom from a section and an offset within
// the section.
std::map<const coff_section *, std::map<uint32_t, COFFDefinedAtom *> >
std::map<const coff_section *,
std::map<uint32_t, std::vector<COFFDefinedAtom *> > >
_definedAtomLocations;
mutable llvm::BumpPtrAllocator _alloc;

View File

@ -0,0 +1,48 @@
---
header:
Machine: IMAGE_FILE_MACHINE_I386
Characteristics: [ ]
sections:
- Name: .text
Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
Alignment: 256
SectionData: 5589E583EC14C745FC00000000C744240C00000000C744240807000000C744240400000000C7042400000000FF150000000083EC1031C083C4145DC3
Relocations:
- VirtualAddress: 25
SymbolName: .data
Type: IMAGE_REL_I386_DIR32
- VirtualAddress: 33
SymbolName: .data
Type: IMAGE_REL_I386_DIR32
- Name: .text$1
Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
Alignment: 4096
SectionData: 00
- Name: .data
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
Alignment: 4
SectionData: 576F726C64210048656C6C6F2C00
symbols:
- Name: .text
Value: 0
SectionNumber: 1
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_STATIC
NumberOfAuxSymbols: 1
AuxiliaryData: 3C0000000300000000000000010000000000
- Name: .data
Value: 0
SectionNumber: 2
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_STATIC
NumberOfAuxSymbols: 1
AuxiliaryData: 0E0000000000000000000000020000000000
- Name: _start
Value: 0
SectionNumber: 1
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_FUNCTION
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
...

View File

@ -0,0 +1,6 @@
# RUN: yaml2obj %p/Inputs/alignment.obj.yaml > %t.obj
#
# RUN: lld -flavor link /out:%t1 /subsystem:console /force /entry:start \
# RUN: -- %t.obj && llvm-readobj -sections %t1 | FileCheck %s
CHECK: VirtualSize: 0x1001