[lld] r202550 - [PECOFF] Sort SEH table entries according to its value.
Rui Ueyama
ruiu at google.com
Fri Feb 28 14:17:54 PST 2014
Author: ruiu
Date: Fri Feb 28 16:17:53 2014
New Revision: 202550
URL: http://llvm.org/viewvc/llvm-project?rev=202550&view=rev
Log:
[PECOFF] Sort SEH table entries according to its value.
It looks like the contents of the table need to be sorted according to its
value, so that the runtime can find the entry by binary search. I'm not 100%
sure if we really have to do that, but at least I can say it's safe to do
because the contents of .sxdata is just a list of exception handlers' RVAs.
Modified:
lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp
lld/trunk/test/pecoff/Inputs/seh.obj.yaml
lld/trunk/test/pecoff/seh.test
Modified: lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp?rev=202550&r1=202549&r2=202550&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp Fri Feb 28 16:17:53 2014
@@ -836,6 +836,8 @@ public:
private:
void applyAllRelocations(uint8_t *bufferStart);
void printAllAtomAddresses() const;
+ void reorderSEHTableEntries(uint8_t *bufferStart);
+
void addChunk(Chunk *chunk);
void addSectionChunk(SectionChunk *chunk, SectionHeaderTableChunk *table);
void setImageSizeOnDisk();
@@ -1020,6 +1022,7 @@ error_code PECOFFWriter::writeFile(const
for (std::unique_ptr<Chunk> &chunk : _chunks)
chunk->write(buffer->getBufferStart() + chunk->fileOffset());
applyAllRelocations(buffer->getBufferStart());
+ reorderSEHTableEntries(buffer->getBufferStart());
DEBUG(printAllAtomAddresses());
if (_ctx.isDll())
@@ -1066,6 +1069,24 @@ void PECOFFWriter::printAllAtomAddresses
chunk->printAtomAddresses(_ctx.getBaseAddress());
}
+/// It seems that the entries in .sxdata must be sorted. This function is called
+/// after a COFF file image is created in memory and before it is written to
+/// disk. It is safe to reorder entries at this stage because the contents of
+/// the entries are RVAs and there's no reference to a .sxdata entry other than
+/// to the beginning of the section.
+void PECOFFWriter::reorderSEHTableEntries(uint8_t *bufferStart) {
+ for (std::unique_ptr<Chunk> &chunk : _chunks) {
+ if (SectionChunk *section = dyn_cast<SectionChunk>(chunk.get())) {
+ if (section->getSectionName() == ".sxdata") {
+ int numEntries = section->size() / sizeof(ulittle32_t);
+ ulittle32_t *begin = reinterpret_cast<ulittle32_t *>(bufferStart + section->fileOffset());
+ ulittle32_t *end = begin + numEntries;
+ std::sort(begin, end);
+ }
+ }
+ }
+}
+
void PECOFFWriter::addChunk(Chunk *chunk) {
_chunks.push_back(std::unique_ptr<Chunk>(chunk));
}
Modified: lld/trunk/test/pecoff/Inputs/seh.obj.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/Inputs/seh.obj.yaml?rev=202550&r1=202549&r2=202550&view=diff
==============================================================================
--- lld/trunk/test/pecoff/Inputs/seh.obj.yaml (original)
+++ lld/trunk/test/pecoff/Inputs/seh.obj.yaml Fri Feb 28 16:17:53 2014
@@ -114,7 +114,7 @@ sections:
- Name: .sxdata
Characteristics: [ IMAGE_SCN_LNK_INFO ]
Alignment: 4
- SectionData: 1B000000
+ SectionData: 1B0000001A000000
symbols:
- Name: '@comp.id'
Value: 14766605
Modified: lld/trunk/test/pecoff/seh.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/seh.test?rev=202550&r1=202549&r2=202550&view=diff
==============================================================================
--- lld/trunk/test/pecoff/seh.test (original)
+++ lld/trunk/test/pecoff/seh.test Fri Feb 28 16:17:53 2014
@@ -21,8 +21,8 @@ CHECK: Process Heap Flags: 0
CHECK: CSD Version: 0
CHECK: Security Cookie: 0
CHECK: SEH Table: 4210688
-CHECK: SEH Count: 1
-CHECK: SEH Table: 0x{{[0-9a-f]+}}
+CHECK: SEH Count: 2
+CHECK: SEH Table: 0x{{[0-9a-f]+}} 0x{{[0-9a-f]+}}
# RUN: lld -flavor link /out:%t.exe /subsystem:console /force /nodefaultlib \
# RUN: /safeseh:no -- %t.obj
More information about the llvm-commits
mailing list