LLVM API Documentation
00001 //===- lib/MC/MCWinEH.cpp - Windows EH implementation ---------------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 00010 #include "llvm/ADT/StringRef.h" 00011 #include "llvm/MC/MCContext.h" 00012 #include "llvm/MC/MCObjectFileInfo.h" 00013 #include "llvm/MC/MCSectionCOFF.h" 00014 #include "llvm/MC/MCSymbol.h" 00015 #include "llvm/MC/MCWinEH.h" 00016 #include "llvm/Support/COFF.h" 00017 00018 namespace llvm { 00019 namespace WinEH { 00020 static StringRef getSectionSuffix(const MCSymbol *Function) { 00021 if (!Function || !Function->isInSection()) 00022 return ""; 00023 00024 const MCSection *FunctionSection = &Function->getSection(); 00025 if (const auto Section = dyn_cast<MCSectionCOFF>(FunctionSection)) { 00026 StringRef Name = Section->getSectionName(); 00027 size_t Dollar = Name.find('$'); 00028 size_t Dot = Name.find('.', 1); 00029 00030 if (Dollar == StringRef::npos && Dot == StringRef::npos) 00031 return ""; 00032 if (Dot == StringRef::npos) 00033 return Name.substr(Dollar); 00034 if (Dollar == StringRef::npos || Dot < Dollar) 00035 return Name.substr(Dot); 00036 00037 return Name.substr(Dollar); 00038 } 00039 00040 return ""; 00041 } 00042 00043 static const MCSection *getUnwindInfoSection( 00044 StringRef SecName, const MCSectionCOFF *UnwindSec, const MCSymbol *Function, 00045 MCContext &Context) { 00046 // If Function is in a COMDAT, get or create an unwind info section in that 00047 // COMDAT group. 00048 if (Function && Function->isInSection()) { 00049 const MCSectionCOFF *FunctionSection = 00050 cast<MCSectionCOFF>(&Function->getSection()); 00051 if (FunctionSection->getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT) { 00052 return Context.getAssociativeCOFFSection( 00053 UnwindSec, FunctionSection->getCOMDATSymbol()); 00054 } 00055 } 00056 00057 // If Function is in a section other than .text, create a new .pdata section. 00058 // Otherwise use the plain .pdata section. 00059 StringRef Suffix = getSectionSuffix(Function); 00060 if (Suffix.empty()) 00061 return UnwindSec; 00062 return Context.getCOFFSection((SecName + Suffix).str(), 00063 COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 00064 COFF::IMAGE_SCN_MEM_READ, 00065 SectionKind::getDataRel()); 00066 } 00067 00068 const MCSection *UnwindEmitter::getPDataSection(const MCSymbol *Function, 00069 MCContext &Context) { 00070 const MCSectionCOFF *PData = 00071 cast<MCSectionCOFF>(Context.getObjectFileInfo()->getPDataSection()); 00072 return getUnwindInfoSection(".pdata", PData, Function, Context); 00073 } 00074 00075 const MCSection *UnwindEmitter::getXDataSection(const MCSymbol *Function, 00076 MCContext &Context) { 00077 const MCSectionCOFF *XData = 00078 cast<MCSectionCOFF>(Context.getObjectFileInfo()->getXDataSection()); 00079 return getUnwindInfoSection(".xdata", XData, Function, Context); 00080 } 00081 00082 } 00083 } 00084