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 const MCSection *getUnwindInfoSection( 29 StringRef SecName, const MCSectionCOFF *UnwindSec, const MCSymbol *Function, 30 MCContext &Context) { 31 if (Function && Function->isInSection()) { 32 // If Function is in a COMDAT, get or create an unwind info section in that 33 // COMDAT group. 34 const MCSectionCOFF *FunctionSection = 35 cast<MCSectionCOFF>(&Function->getSection()); 36 if (FunctionSection->getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT) { 37 return Context.getAssociativeCOFFSection( 38 UnwindSec, FunctionSection->getCOMDATSymbol()); 39 } 40 41 // If Function is in a section other than .text, create a new .pdata section. 42 // Otherwise use the plain .pdata section. 43 if (const auto *Section = dyn_cast<MCSectionCOFF>(FunctionSection)) { 44 StringRef CodeSecName = Section->getSectionName(); 45 if (CodeSecName == ".text") 46 return UnwindSec; 47 48 if (CodeSecName.startswith(".text$")) 49 CodeSecName = CodeSecName.substr(6); 50 51 return Context.getCOFFSection( 52 (SecName + Twine('$') + CodeSecName).str(), 53 COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | COFF::IMAGE_SCN_MEM_READ, 54 SectionKind::getDataRel()); 55 } 56 } 57 58 return UnwindSec; 59 60 } 61 62 const MCSection *UnwindEmitter::getPDataSection(const MCSymbol *Function, 63 MCContext &Context) { 64 const MCSectionCOFF *PData = 65 cast<MCSectionCOFF>(Context.getObjectFileInfo()->getPDataSection()); 66 return getUnwindInfoSection(".pdata", PData, Function, Context); 67 } 68 69 const MCSection *UnwindEmitter::getXDataSection(const MCSymbol *Function, 70 MCContext &Context) { 71 const MCSectionCOFF *XData = 72 cast<MCSectionCOFF>(Context.getObjectFileInfo()->getXDataSection()); 73 return getUnwindInfoSection(".xdata", XData, Function, Context); 74 } 75 76 } 77 } 78 79