diff options
author | Rui Ueyama <ruiu@google.com> | 2013-09-13 21:11:00 +0000 |
---|---|---|
committer | Rui Ueyama <ruiu@google.com> | 2013-09-13 21:11:00 +0000 |
commit | a8ce9529c34682ab252b5655ce09a6cd4aabcd81 (patch) | |
tree | 67365777f31b9830d0fe4514105f8c4d0b251d18 | |
parent | 1ea9b9770778a8b425ac375af2710434a39bd6a0 (diff) | |
download | bcm5719-llvm-a8ce9529c34682ab252b5655ce09a6cd4aabcd81.tar.gz bcm5719-llvm-a8ce9529c34682ab252b5655ce09a6cd4aabcd81.zip |
[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
-rw-r--r-- | lld/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp | 14 | ||||
-rw-r--r-- | lld/test/pecoff/Inputs/alignment.obj.yaml | 48 | ||||
-rw-r--r-- | lld/test/pecoff/alignment.test | 6 |
3 files changed, 62 insertions, 6 deletions
diff --git a/lld/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp b/lld/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp index dd5b14de165..beddcf14f84 100644 --- a/lld/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp +++ b/lld/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp @@ -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; diff --git a/lld/test/pecoff/Inputs/alignment.obj.yaml b/lld/test/pecoff/Inputs/alignment.obj.yaml new file mode 100644 index 00000000000..ba6e156eaa0 --- /dev/null +++ b/lld/test/pecoff/Inputs/alignment.obj.yaml @@ -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 +... diff --git a/lld/test/pecoff/alignment.test b/lld/test/pecoff/alignment.test new file mode 100644 index 00000000000..b2e1d002541 --- /dev/null +++ b/lld/test/pecoff/alignment.test @@ -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 |