blob: f0c354feb61ce0482f7299c4b96c009dabef1242 [file] [log] [blame]
Saleem Abdulrasool64a8cc72014-08-07 02:59:41 +00001//===- 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/MCSymbol.h"
15#include "llvm/MC/MCWinEH.h"
16#include "llvm/Support/COFF.h"
17
18namespace llvm {
19namespace WinEH {
Reid Kleckner7c4059e2014-09-04 17:42:03 +000020static StringRef getSectionSuffix(const MCSymbol *Function) {
Saleem Abdulrasool64a8cc72014-08-07 02:59:41 +000021 if (!Function || !Function->isInSection())
22 return "";
23
24 const MCSection *FunctionSection = &Function->getSection();
25 if (const auto Section = dyn_cast<MCSectionCOFF>(FunctionSection)) {
26 StringRef Name = Section->getSectionName();
27 size_t Dollar = Name.find('$');
28 size_t Dot = Name.find('.', 1);
29
30 if (Dollar == StringRef::npos && Dot == StringRef::npos)
31 return "";
32 if (Dot == StringRef::npos)
33 return Name.substr(Dollar);
34 if (Dollar == StringRef::npos || Dot < Dollar)
35 return Name.substr(Dot);
36
37 return Name.substr(Dollar);
38 }
39
40 return "";
41}
Reid Kleckner7c4059e2014-09-04 17:42:03 +000042
43static const MCSection *getUnwindInfoSection(
44 StringRef SecName, const MCSectionCOFF *UnwindSec, const MCSymbol *Function,
45 MCContext &Context) {
46 // If Function is in a COMDAT, get or create an unwind info section in that
47 // COMDAT group.
48 if (Function && Function->isInSection()) {
49 const MCSectionCOFF *FunctionSection =
50 cast<MCSectionCOFF>(&Function->getSection());
51 if (FunctionSection->getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT) {
52 return Context.getAssociativeCOFFSection(
53 UnwindSec, FunctionSection->getCOMDATSymbol());
54 }
55 }
56
57 // If Function is in a section other than .text, create a new .pdata section.
58 // Otherwise use the plain .pdata section.
59 StringRef Suffix = getSectionSuffix(Function);
60 if (Suffix.empty())
61 return UnwindSec;
62 return Context.getCOFFSection((SecName + Suffix).str(),
63 COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
64 COFF::IMAGE_SCN_MEM_READ,
65 SectionKind::getDataRel());
66}
67
68const MCSection *UnwindEmitter::getPDataSection(const MCSymbol *Function,
69 MCContext &Context) {
70 const MCSectionCOFF *PData =
71 cast<MCSectionCOFF>(Context.getObjectFileInfo()->getPDataSection());
72 return getUnwindInfoSection(".pdata", PData, Function, Context);
73}
74
75const MCSection *UnwindEmitter::getXDataSection(const MCSymbol *Function,
76 MCContext &Context) {
77 const MCSectionCOFF *XData =
78 cast<MCSectionCOFF>(Context.getObjectFileInfo()->getXDataSection());
79 return getUnwindInfoSection(".xdata", XData, Function, Context);
80}
81
Saleem Abdulrasool64a8cc72014-08-07 02:59:41 +000082}
83}
84