summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorKai Nacke <kai.nacke@redstar.de>2013-09-15 17:46:46 +0000
committerKai Nacke <kai.nacke@redstar.de>2013-09-15 17:46:46 +0000
commit74adc8a457ecd9089adbba574ee3f24d74a6e370 (patch)
tree77a8ae231c773ee9fccd2c59a48cccdec9d5b392 /llvm/lib
parent31025a63250998cc1f11aa0d54a3cf0ad7783120 (diff)
downloadbcm5719-llvm-74adc8a457ecd9089adbba574ee3f24d74a6e370.tar.gz
bcm5719-llvm-74adc8a457ecd9089adbba574ee3f24d74a6e370.zip
Generate IMAGE_REL_AMD64_ADDR32NB relocations for SEH
data structures. The Win64 EH data structures must be of type IMAGE_REL_AMD64_ADDR32NB instead of IMAGE_REL_AMD64_ADDR32. This is easiely achieved by adding the VK_COFF_IMGREL32 modifier to the symbol reference. Change also references to start and end of the SEH range of a function as offsets to start of the function. Reviewed by Jim Grosbach, Charles Davis and Nico Rieck. llvm-svn: 190766
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/MC/MCWin64EH.cpp26
1 files changed, 21 insertions, 5 deletions
diff --git a/llvm/lib/MC/MCWin64EH.cpp b/llvm/lib/MC/MCWin64EH.cpp
index 8db1fa2a93c..c3d568b454c 100644
--- a/llvm/lib/MC/MCWin64EH.cpp
+++ b/llvm/lib/MC/MCWin64EH.cpp
@@ -128,14 +128,29 @@ static void EmitUnwindCode(MCStreamer &streamer, MCSymbol *begin,
}
}
+static void EmitSymbolRefWithOfs(MCStreamer &streamer,
+ const MCSymbol *Base,
+ const MCSymbol *Other) {
+ MCContext &Context = streamer.getContext();
+ const MCSymbolRefExpr *BaseRef = MCSymbolRefExpr::Create(Base, Context);
+ const MCSymbolRefExpr *OtherRef = MCSymbolRefExpr::Create(Other, Context);
+ const MCExpr *Ofs = MCBinaryExpr::CreateSub(OtherRef, BaseRef, Context);
+ const MCSymbolRefExpr *BaseRefRel = MCSymbolRefExpr::Create(Base,
+ MCSymbolRefExpr::VK_COFF_IMGREL32,
+ Context);
+ streamer.EmitValue(MCBinaryExpr::CreateAdd(BaseRefRel, Ofs, Context), 4);
+}
+
static void EmitRuntimeFunction(MCStreamer &streamer,
const MCWin64EHUnwindInfo *info) {
MCContext &context = streamer.getContext();
streamer.EmitValueToAlignment(4);
- streamer.EmitValue(MCSymbolRefExpr::Create(info->Begin, context), 4);
- streamer.EmitValue(MCSymbolRefExpr::Create(info->End, context), 4);
- streamer.EmitValue(MCSymbolRefExpr::Create(info->Symbol, context), 4);
+ EmitSymbolRefWithOfs(streamer, info->Function, info->Begin);
+ EmitSymbolRefWithOfs(streamer, info->Function, info->End);
+ streamer.EmitValue(MCSymbolRefExpr::Create(info->Symbol,
+ MCSymbolRefExpr::VK_COFF_IMGREL32,
+ context), 4);
}
static void EmitUnwindInfo(MCStreamer &streamer, MCWin64EHUnwindInfo *info) {
@@ -188,8 +203,9 @@ static void EmitUnwindInfo(MCStreamer &streamer, MCWin64EHUnwindInfo *info) {
EmitRuntimeFunction(streamer, info->ChainedParent);
else if (flags &
((Win64EH::UNW_TerminateHandler|Win64EH::UNW_ExceptionHandler) << 3))
- streamer.EmitValue(MCSymbolRefExpr::Create(info->ExceptionHandler, context),
- 4);
+ streamer.EmitValue(MCSymbolRefExpr::Create(info->ExceptionHandler,
+ MCSymbolRefExpr::VK_COFF_IMGREL32,
+ context), 4);
else if (numCodes < 2) {
// The minimum size of an UNWIND_INFO struct is 8 bytes. If we're not
// a chained unwind info, if there is no handler, and if there are fewer
OpenPOWER on IntegriCloud