1 //===- lib/MC/MCWinEH.cpp - Windows EH implementation ---------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "llvm/ADT/StringRef.h" 11 #include "llvm/MC/MCContext.h" 12 #include "llvm/MC/MCObjectFileInfo.h" 13 #include "llvm/MC/MCSectionCOFF.h" 14 #include "llvm/MC/MCStreamer.h" 15 #include "llvm/MC/MCSymbol.h" 16 #include "llvm/MC/MCWinEH.h" 17 #include "llvm/Support/COFF.h" 18 19 namespace llvm { 20 namespace WinEH { 21 22 /// We can't have one section for all .pdata or .xdata because the Microsoft 23 /// linker seems to want all code relocations to refer to the same object file 24 /// section. If the code described is comdat, create a new comdat section 25 /// associated with that comdat. If the code described is not in the main .text 26 /// section, make a new section for it. Otherwise use the main unwind info 27 /// section. 28 static MCSection *getUnwindInfoSection(StringRef SecName, 29 MCSectionCOFF *UnwindSec, 30 const MCSymbol *Function, 31 MCContext &Context) { 32 if (Function && Function->isInSection()) { 33 // If Function is in a COMDAT, get or create an unwind info section in that 34 // COMDAT group. 35 const MCSectionCOFF *FunctionSection = 36 cast<MCSectionCOFF>(&Function->getSection()); 37 if (FunctionSection->getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT) { 38 return Context.getAssociativeCOFFSection( 39 UnwindSec, FunctionSection->getCOMDATSymbol()); 40 } 41 42 // If Function is in a section other than .text, create a new .pdata section. 43 // Otherwise use the plain .pdata section. 44 if (const auto *Section = dyn_cast<MCSectionCOFF>(FunctionSection)) { 45 StringRef CodeSecName = Section->getSectionName(); 46 if (CodeSecName == ".text") 47 return UnwindSec; 48 49 if (CodeSecName.startswith(".text$")) 50 CodeSecName = CodeSecName.substr(6); 51 52 return Context.getCOFFSection((SecName + Twine('$') + CodeSecName).str(), 53 COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 54 COFF::IMAGE_SCN_MEM_READ, 55 SectionKind::getData()); 56 } 57 } 58 59 return UnwindSec; 60 61 } 62 63 MCSection *UnwindEmitter::getPDataSection(const MCSymbol *Function, 64 MCContext &Context) { 65 MCSectionCOFF *PData = 66 cast<MCSectionCOFF>(Context.getObjectFileInfo()->getPDataSection()); 67 return getUnwindInfoSection(".pdata", PData, Function, Context); 68 } 69 70 MCSection *UnwindEmitter::getXDataSection(const MCSymbol *Function, 71 MCContext &Context) { 72 MCSectionCOFF *XData = 73 cast<MCSectionCOFF>(Context.getObjectFileInfo()->getXDataSection()); 74 return getUnwindInfoSection(".xdata", XData, Function, Context); 75 } 76 77 } 78 } 79 80