diff options
| author | Saleem Abdulrasool <compnerd@compnerd.org> | 2014-03-22 19:26:18 +0000 |
|---|---|---|
| committer | Saleem Abdulrasool <compnerd@compnerd.org> | 2014-03-22 19:26:18 +0000 |
| commit | 44419fc3cdc126898caa87824287dd6065942a2e (patch) | |
| tree | b411b3bb1084b3210f49e67082db3e51e79b2537 /llvm/lib/Target/ARM | |
| parent | 55805eb562abe19a6bbea29c8f416377cc742963 (diff) | |
| download | bcm5719-llvm-44419fc3cdc126898caa87824287dd6065942a2e.tar.gz bcm5719-llvm-44419fc3cdc126898caa87824287dd6065942a2e.zip | |
ARM IAS: properly handle function entries in .thumb
When a label is parsed, check if there is type information available for the
label. If so, check if the symbol is a function. If the symbol is a function
and we are in thumb mode and no explicit thumb_func has been emitted, adjust the
symbol data to indicate that the function definition is a thumb function.
The application of this inferencing is improved value handling in the object
file (the required thumb bit is set on symbols which are thumb functions). It
also helps improve compatibility with binutils.
The one complication that arises from this handling is the MCAsmStreamer. The
default implementation of getOrCreateSymbolData in MCStreamer does not support
tracking the symbol data. In order to support the semantics of thumb functions,
track symbol data in assembly streamer. Although O(n) in number of labels in
the TU, this is already done in various other streamers and as such the memory
overhead is not a practical concern in this scenario.
llvm-svn: 204544
Diffstat (limited to 'llvm/lib/Target/ARM')
| -rw-r--r-- | llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index ccb1c641efe..1a153522796 100644 --- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -25,7 +25,9 @@ #include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCDisassembler.h" +#include "llvm/MC/MCELF.h" #include "llvm/MC/MCELFStreamer.h" +#include "llvm/MC/MCELFSymbolFlags.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInst.h" #include "llvm/MC/MCInstrDesc.h" @@ -8085,6 +8087,7 @@ bool ARMAsmParser::parseDirectiveThumb(SMLoc L) { if (!isThumb()) SwitchMode(); + getParser().getStreamer().EmitAssemblerFlag(MCAF_Code16); return false; } @@ -8105,6 +8108,7 @@ bool ARMAsmParser::parseDirectiveARM(SMLoc L) { if (isThumb()) SwitchMode(); + getParser().getStreamer().EmitAssemblerFlag(MCAF_Code32); return false; } @@ -8113,6 +8117,32 @@ void ARMAsmParser::onLabelParsed(MCSymbol *Symbol) { if (NextSymbolIsThumb) { getParser().getStreamer().EmitThumbFunc(Symbol); NextSymbolIsThumb = false; + return; + } + + if (!isThumb()) + return; + + const MCObjectFileInfo::Environment Format = + getContext().getObjectFileInfo()->getObjectFileType(); + switch (Format) { + case MCObjectFileInfo::IsCOFF: { + const MCSymbolData &SD = + getParser().getStreamer().getOrCreateSymbolData(Symbol); + char Type = COFF::IMAGE_SYM_DTYPE_FUNCTION << COFF::SCT_COMPLEX_TYPE_SHIFT; + if (SD.getFlags() & (Type << COFF::SF_TypeShift)) + getParser().getStreamer().EmitThumbFunc(Symbol); + break; + } + case MCObjectFileInfo::IsELF: { + const MCSymbolData &SD = + getParser().getStreamer().getOrCreateSymbolData(Symbol); + if (MCELF::GetType(SD) & (ELF::STT_FUNC << ELF_STT_Shift)) + getParser().getStreamer().EmitThumbFunc(Symbol); + break; + } + case MCObjectFileInfo::IsMachO: + break; } } |

