mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 11:13:28 +01:00
eecdfef0b6
Previously we assumed the section name had the form .text$foo, which is what we used to do for inline functions. If the dollar wasn't present, we'd put unwind data in the .pdata and .xdata sections for the main .text section, which is incorrect. Fixes PR22001. llvm-svn: 224738
78 lines
2.8 KiB
C++
78 lines
2.8 KiB
C++
//===- lib/MC/MCWinEH.cpp - Windows EH implementation ---------------------===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "llvm/ADT/StringRef.h"
|
|
#include "llvm/MC/MCContext.h"
|
|
#include "llvm/MC/MCObjectFileInfo.h"
|
|
#include "llvm/MC/MCSectionCOFF.h"
|
|
#include "llvm/MC/MCSymbol.h"
|
|
#include "llvm/MC/MCWinEH.h"
|
|
#include "llvm/Support/COFF.h"
|
|
|
|
namespace llvm {
|
|
namespace WinEH {
|
|
|
|
/// We can't have one section for all .pdata or .xdata because the Microsoft
|
|
/// linker seems to want all code relocations to refer to the same object file
|
|
/// section. If the code described is comdat, create a new comdat section
|
|
/// associated with that comdat. If the code described is not in the main .text
|
|
/// section, make a new section for it. Otherwise use the main unwind info
|
|
/// section.
|
|
static const MCSection *getUnwindInfoSection(
|
|
StringRef SecName, const MCSectionCOFF *UnwindSec, const MCSymbol *Function,
|
|
MCContext &Context) {
|
|
if (Function && Function->isInSection()) {
|
|
// If Function is in a COMDAT, get or create an unwind info section in that
|
|
// COMDAT group.
|
|
const MCSectionCOFF *FunctionSection =
|
|
cast<MCSectionCOFF>(&Function->getSection());
|
|
if (FunctionSection->getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT) {
|
|
return Context.getAssociativeCOFFSection(
|
|
UnwindSec, FunctionSection->getCOMDATSymbol());
|
|
}
|
|
|
|
// If Function is in a section other than .text, create a new .pdata section.
|
|
// Otherwise use the plain .pdata section.
|
|
if (const auto *Section = dyn_cast<MCSectionCOFF>(FunctionSection)) {
|
|
StringRef CodeSecName = Section->getSectionName();
|
|
if (CodeSecName == ".text")
|
|
return UnwindSec;
|
|
|
|
if (CodeSecName.startswith(".text$"))
|
|
CodeSecName = CodeSecName.substr(6);
|
|
|
|
return Context.getCOFFSection(
|
|
(SecName + Twine('$') + CodeSecName).str(),
|
|
COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | COFF::IMAGE_SCN_MEM_READ,
|
|
SectionKind::getDataRel());
|
|
}
|
|
}
|
|
|
|
return UnwindSec;
|
|
|
|
}
|
|
|
|
const MCSection *UnwindEmitter::getPDataSection(const MCSymbol *Function,
|
|
MCContext &Context) {
|
|
const MCSectionCOFF *PData =
|
|
cast<MCSectionCOFF>(Context.getObjectFileInfo()->getPDataSection());
|
|
return getUnwindInfoSection(".pdata", PData, Function, Context);
|
|
}
|
|
|
|
const MCSection *UnwindEmitter::getXDataSection(const MCSymbol *Function,
|
|
MCContext &Context) {
|
|
const MCSectionCOFF *XData =
|
|
cast<MCSectionCOFF>(Context.getObjectFileInfo()->getXDataSection());
|
|
return getUnwindInfoSection(".xdata", XData, Function, Context);
|
|
}
|
|
|
|
}
|
|
}
|
|
|