LLVM API Documentation

MCWinEH.cpp
Go to the documentation of this file.
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