//===----------------------------------------------------------------------===//
#include "llvm/MC/MCWin64EH.h"
-#include "llvm/MC/MCStreamer.h"
+#include "llvm/ADT/Twine.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
-#include "llvm/Target/TargetAsmInfo.h"
+#include "llvm/MC/MCObjectFileInfo.h"
+#include "llvm/MC/MCSectionCOFF.h"
+#include "llvm/MC/MCStreamer.h"
+#include "llvm/MC/MCSymbol.h"
namespace llvm {
}
}
+StringRef MCWin64EHUnwindEmitter::GetSectionSuffix(const MCSymbol *func) {
+ if (!func || !func->isInSection()) return "";
+ const MCSection *section = &func->getSection();
+ const MCSectionCOFF *COFFSection;
+ if ((COFFSection = dyn_cast<MCSectionCOFF>(section))) {
+ StringRef name = COFFSection->getSectionName();
+ size_t dollar = name.find('$');
+ size_t dot = name.find('.', 1);
+ if (dollar == StringRef::npos && dot == StringRef::npos)
+ return "";
+ if (dot == StringRef::npos)
+ return name.substr(dollar);
+ if (dollar == StringRef::npos || dot < dollar)
+ return name.substr(dot);
+ return name.substr(dollar);
+ }
+ return "";
+}
+
+static const MCSection *getWin64EHTableSection(StringRef suffix,
+ MCContext &context) {
+ if (suffix == "")
+ return context.getObjectFileInfo()->getXDataSection();
+
+ return context.getCOFFSection((".xdata"+suffix).str(),
+ COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
+ COFF::IMAGE_SCN_MEM_READ,
+ SectionKind::getDataRel());
+}
+
+static const MCSection *getWin64EHFuncTableSection(StringRef suffix,
+ MCContext &context) {
+ if (suffix == "")
+ return context.getObjectFileInfo()->getPDataSection();
+ return context.getCOFFSection((".pdata"+suffix).str(),
+ COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
+ COFF::IMAGE_SCN_MEM_READ,
+ SectionKind::getDataRel());
+}
+
void MCWin64EHUnwindEmitter::EmitUnwindInfo(MCStreamer &streamer,
MCWin64EHUnwindInfo *info) {
// Switch sections (the static function above is meant to be called from
// here and from Emit().
MCContext &context = streamer.getContext();
- const TargetAsmInfo &asmInfo = context.getTargetAsmInfo();
- const MCSection *xdataSect = asmInfo.getWin64EHTableSection();
+ const MCSection *xdataSect =
+ getWin64EHTableSection(GetSectionSuffix(info->Function), context);
streamer.SwitchSection(xdataSect);
llvm::EmitUnwindInfo(streamer, info);
void MCWin64EHUnwindEmitter::Emit(MCStreamer &streamer) {
MCContext &context = streamer.getContext();
// Emit the unwind info structs first.
- const TargetAsmInfo &asmInfo = context.getTargetAsmInfo();
- const MCSection *xdataSect = asmInfo.getWin64EHTableSection();
- streamer.SwitchSection(xdataSect);
- for (unsigned i = 0; i < streamer.getNumW64UnwindInfos(); ++i)
- llvm::EmitUnwindInfo(streamer, &streamer.getW64UnwindInfo(i));
+ for (unsigned i = 0; i < streamer.getNumW64UnwindInfos(); ++i) {
+ MCWin64EHUnwindInfo &info = streamer.getW64UnwindInfo(i);
+ const MCSection *xdataSect =
+ getWin64EHTableSection(GetSectionSuffix(info.Function), context);
+ streamer.SwitchSection(xdataSect);
+ llvm::EmitUnwindInfo(streamer, &info);
+ }
// Now emit RUNTIME_FUNCTION entries.
- const MCSection *pdataSect = asmInfo.getWin64EHFuncTableSection();
- streamer.SwitchSection(pdataSect);
- for (unsigned i = 0; i < streamer.getNumW64UnwindInfos(); ++i)
- EmitRuntimeFunction(streamer, &streamer.getW64UnwindInfo(i));
+ for (unsigned i = 0; i < streamer.getNumW64UnwindInfos(); ++i) {
+ MCWin64EHUnwindInfo &info = streamer.getW64UnwindInfo(i);
+ const MCSection *pdataSect =
+ getWin64EHFuncTableSection(GetSectionSuffix(info.Function), context);
+ streamer.SwitchSection(pdataSect);
+ EmitRuntimeFunction(streamer, &info);
+ }
}
} // End of namespace llvm