2011-03-06 02:43:15 +08:00
|
|
|
//===-- CodeGen/AsmPrinter/ARMException.cpp - ARM EHABI Exception Impl ----===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// This file contains support for writing DWARF exception info into asm files.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "DwarfException.h"
|
2012-12-04 00:50:05 +08:00
|
|
|
#include "llvm/ADT/SmallString.h"
|
|
|
|
#include "llvm/ADT/StringExtras.h"
|
|
|
|
#include "llvm/ADT/Twine.h"
|
2011-03-06 02:43:15 +08:00
|
|
|
#include "llvm/CodeGen/AsmPrinter.h"
|
|
|
|
#include "llvm/CodeGen/MachineFrameInfo.h"
|
|
|
|
#include "llvm/CodeGen/MachineFunction.h"
|
2012-12-04 00:50:05 +08:00
|
|
|
#include "llvm/CodeGen/MachineModuleInfo.h"
|
2013-01-02 19:36:10 +08:00
|
|
|
#include "llvm/IR/DataLayout.h"
|
2014-01-08 05:19:40 +08:00
|
|
|
#include "llvm/IR/Mangler.h"
|
2013-01-02 19:36:10 +08:00
|
|
|
#include "llvm/IR/Module.h"
|
2011-03-06 02:43:15 +08:00
|
|
|
#include "llvm/MC/MCAsmInfo.h"
|
|
|
|
#include "llvm/MC/MCContext.h"
|
|
|
|
#include "llvm/MC/MCExpr.h"
|
|
|
|
#include "llvm/MC/MCSection.h"
|
|
|
|
#include "llvm/MC/MCStreamer.h"
|
|
|
|
#include "llvm/MC/MCSymbol.h"
|
2012-12-04 00:50:05 +08:00
|
|
|
#include "llvm/Support/CommandLine.h"
|
|
|
|
#include "llvm/Support/Dwarf.h"
|
|
|
|
#include "llvm/Support/FormattedStream.h"
|
2011-03-06 02:43:15 +08:00
|
|
|
#include "llvm/Target/TargetFrameLowering.h"
|
|
|
|
#include "llvm/Target/TargetOptions.h"
|
|
|
|
#include "llvm/Target/TargetRegisterInfo.h"
|
|
|
|
using namespace llvm;
|
|
|
|
|
|
|
|
ARMException::ARMException(AsmPrinter *A)
|
2014-06-11 09:19:03 +08:00
|
|
|
: EHStreamer(A), shouldEmitCFI(false) {}
|
2011-03-06 02:43:15 +08:00
|
|
|
|
|
|
|
ARMException::~ARMException() {}
|
|
|
|
|
2013-10-08 21:08:17 +08:00
|
|
|
ARMTargetStreamer &ARMException::getTargetStreamer() {
|
2014-01-14 09:21:46 +08:00
|
|
|
MCTargetStreamer &TS = *Asm->OutStreamer.getTargetStreamer();
|
2013-10-08 21:08:17 +08:00
|
|
|
return static_cast<ARMTargetStreamer &>(TS);
|
|
|
|
}
|
|
|
|
|
2014-02-15 01:19:07 +08:00
|
|
|
/// endModule - Emit all exception information that should come after the
|
|
|
|
/// content.
|
2013-11-26 21:34:55 +08:00
|
|
|
void ARMException::endModule() {
|
2014-02-15 01:19:07 +08:00
|
|
|
if (shouldEmitCFI)
|
|
|
|
Asm->OutStreamer.EmitCFISections(false, true);
|
2011-03-06 02:43:15 +08:00
|
|
|
}
|
|
|
|
|
2013-11-26 21:34:55 +08:00
|
|
|
/// beginFunction - Gather pre-function exception information. Assumes it's
|
2011-03-06 02:43:15 +08:00
|
|
|
/// being emitted immediately after the function entry point.
|
2013-11-26 21:34:55 +08:00
|
|
|
void ARMException::beginFunction(const MachineFunction *MF) {
|
2014-05-01 06:43:13 +08:00
|
|
|
if (Asm->MAI->getExceptionHandlingType() == ExceptionHandling::ARM)
|
|
|
|
getTargetStreamer().emitFnStart();
|
2014-05-15 00:38:30 +08:00
|
|
|
Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_func_begin",
|
|
|
|
Asm->getFunctionNumber()));
|
2014-02-15 01:19:07 +08:00
|
|
|
// See if we need call frame info.
|
|
|
|
AsmPrinter::CFIMoveType MoveType = Asm->needsCFIMoves();
|
|
|
|
assert(MoveType != AsmPrinter::CFI_M_EH &&
|
|
|
|
"non-EH CFI not yet supported in prologue with EHABI lowering");
|
|
|
|
if (MoveType == AsmPrinter::CFI_M_Debug) {
|
|
|
|
shouldEmitCFI = true;
|
Emit .eh_frame with relocations to functions, rather than sections
When LLVM emits DWARF call frame information, it currently creates a local,
section-relative symbol in the code section, which is pointed to by a
relocation on the .eh_frame section. However, for C++ we emit some functions in
section groups, and the SysV ABI has some rules to make it easier to remove
these sections
(http://www.sco.com/developers/gabi/latest/ch4.sheader.html#section_group_rules):
A symbol table entry with STB_LOCAL binding that is defined relative to one
of a group's sections, and that is contained in a symbol table section that is
not part of the group, must be discarded if the group members are discarded.
References to this symbol table entry from outside the group are not allowed.
This means that we need to use the function symbol for the relocation, not a
temporary symbol.
There was a comment in the code claiming that the local symbol was used to
avoid creating a relocation, but a relocation must be created anyway as the
code and CFI are in different sections.
llvm-svn: 221150
2014-11-03 20:02:51 +08:00
|
|
|
Asm->OutStreamer.EmitCFIStartProc(false, Asm->CurrentFnSym);
|
2014-02-15 01:19:07 +08:00
|
|
|
}
|
2011-03-06 02:43:15 +08:00
|
|
|
}
|
|
|
|
|
2013-11-26 21:34:55 +08:00
|
|
|
/// endFunction - Gather and emit post-function exception information.
|
2011-03-06 02:43:15 +08:00
|
|
|
///
|
2013-12-03 23:10:23 +08:00
|
|
|
void ARMException::endFunction(const MachineFunction *) {
|
2014-02-15 01:19:07 +08:00
|
|
|
if (shouldEmitCFI)
|
|
|
|
Asm->OutStreamer.EmitCFIEndProc();
|
|
|
|
|
2014-05-15 00:38:30 +08:00
|
|
|
// Map all labels and get rid of any dead landing pads.
|
|
|
|
MMI->TidyLandingPads();
|
|
|
|
|
2013-10-08 21:08:17 +08:00
|
|
|
ARMTargetStreamer &ATS = getTargetStreamer();
|
2014-05-15 00:38:30 +08:00
|
|
|
if (!Asm->MF->getFunction()->needsUnwindTableEntry() &&
|
|
|
|
MMI->getLandingPads().empty())
|
2013-10-08 21:08:17 +08:00
|
|
|
ATS.emitCantUnwind();
|
2011-03-06 02:43:15 +08:00
|
|
|
else {
|
|
|
|
Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_func_end",
|
|
|
|
Asm->getFunctionNumber()));
|
2014-01-29 19:50:56 +08:00
|
|
|
if (!MMI->getLandingPads().empty()) {
|
|
|
|
// Emit references to personality.
|
|
|
|
if (const Function * Personality =
|
|
|
|
MMI->getPersonalities()[MMI->getPersonalityIndex()]) {
|
|
|
|
MCSymbol *PerSym = Asm->getSymbol(Personality);
|
|
|
|
Asm->OutStreamer.EmitSymbolAttribute(PerSym, MCSA_Global);
|
|
|
|
ATS.emitPersonality(PerSym);
|
|
|
|
}
|
2012-11-15 03:13:30 +08:00
|
|
|
|
2014-01-29 19:50:56 +08:00
|
|
|
// Emit .handlerdata directive.
|
|
|
|
ATS.emitHandlerData();
|
2011-03-06 02:43:15 +08:00
|
|
|
|
2014-01-29 19:50:56 +08:00
|
|
|
// Emit actual exception table
|
2014-06-11 09:19:03 +08:00
|
|
|
emitExceptionTable();
|
2012-01-24 21:05:33 +08:00
|
|
|
}
|
2011-03-06 02:43:15 +08:00
|
|
|
}
|
|
|
|
|
2014-05-01 06:43:13 +08:00
|
|
|
if (Asm->MAI->getExceptionHandlingType() == ExceptionHandling::ARM)
|
|
|
|
ATS.emitFnEnd();
|
2011-03-06 02:43:15 +08:00
|
|
|
}
|
2012-11-20 05:06:26 +08:00
|
|
|
|
2014-06-11 09:19:03 +08:00
|
|
|
void ARMException::emitTypeInfos(unsigned TTypeEncoding) {
|
2012-11-20 05:06:26 +08:00
|
|
|
const std::vector<const GlobalVariable *> &TypeInfos = MMI->getTypeInfos();
|
|
|
|
const std::vector<unsigned> &FilterIds = MMI->getFilterIds();
|
|
|
|
|
|
|
|
bool VerboseAsm = Asm->OutStreamer.isVerboseAsm();
|
|
|
|
|
|
|
|
int Entry = 0;
|
|
|
|
// Emit the Catch TypeInfos.
|
|
|
|
if (VerboseAsm && !TypeInfos.empty()) {
|
|
|
|
Asm->OutStreamer.AddComment(">> Catch TypeInfos <<");
|
|
|
|
Asm->OutStreamer.AddBlankLine();
|
|
|
|
Entry = TypeInfos.size();
|
|
|
|
}
|
|
|
|
|
|
|
|
for (std::vector<const GlobalVariable *>::const_reverse_iterator
|
|
|
|
I = TypeInfos.rbegin(), E = TypeInfos.rend(); I != E; ++I) {
|
|
|
|
const GlobalVariable *GV = *I;
|
|
|
|
if (VerboseAsm)
|
|
|
|
Asm->OutStreamer.AddComment("TypeInfo " + Twine(Entry--));
|
2012-11-20 05:17:20 +08:00
|
|
|
Asm->EmitTTypeReference(GV, TTypeEncoding);
|
2012-11-20 05:06:26 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Emit the Exception Specifications.
|
|
|
|
if (VerboseAsm && !FilterIds.empty()) {
|
|
|
|
Asm->OutStreamer.AddComment(">> Filter TypeInfos <<");
|
|
|
|
Asm->OutStreamer.AddBlankLine();
|
|
|
|
Entry = 0;
|
|
|
|
}
|
|
|
|
for (std::vector<unsigned>::const_iterator
|
|
|
|
I = FilterIds.begin(), E = FilterIds.end(); I < E; ++I) {
|
|
|
|
unsigned TypeID = *I;
|
|
|
|
if (VerboseAsm) {
|
|
|
|
--Entry;
|
|
|
|
if (TypeID != 0)
|
|
|
|
Asm->OutStreamer.AddComment("FilterInfo " + Twine(Entry));
|
|
|
|
}
|
|
|
|
|
2014-04-24 14:44:33 +08:00
|
|
|
Asm->EmitTTypeReference((TypeID == 0 ? nullptr : TypeInfos[TypeID - 1]),
|
2012-11-20 05:17:20 +08:00
|
|
|
TTypeEncoding);
|
2012-11-20 05:06:26 +08:00
|
|
|
}
|
|
|
|
}
|