[llvm] r204059 - ARM IAS: support .thumb_set

Jim Grosbach grosbach at apple.com
Mon Mar 17 11:52:13 PDT 2014


On Mar 17, 2014, at 10:13 AM, Saleem Abdulrasool <compnerd at compnerd.org> wrote:

> Author: compnerd
> Date: Mon Mar 17 12:13:54 2014
> New Revision: 204059
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=204059&view=rev
> Log:
> ARM IAS: support .thumb_set
> 
> This performs the equivalent of a .set directive in that it creates a symbol
> which is an alias for another symbol or value which may possibly be yet
> undefined.  This directive also has the added property in that it marks the
> aliased symbol as being a thumb function entry point, in the same way that the
> .thumb_func directive does.
> 
> The current implementation fails one test due to an unrelated issue.  Functions
> within .thumb sections are not marked as thumb_func.  The result is that
> the aliasee function is not valued correctly.

FWIW, that’s mainly because the assembler has no idea which symbols are function symbols and which aren’t in most circumstances. It’s also consistent with other assemblers. That said, it’s possible we can, and perhaps should, come up with good heuristics for inferring the value and not always needing .thumb_func.

> 
> Added:
>    llvm/trunk/test/MC/ARM/thumb_set-diagnostics.s
>    llvm/trunk/test/MC/ARM/thumb_set.s
> Modified:
>    llvm/trunk/lib/MC/ELFObjectWriter.cpp
>    llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
> 
> Modified: llvm/trunk/lib/MC/ELFObjectWriter.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/ELFObjectWriter.cpp?rev=204059&r1=204058&r2=204059&view=diff
> ==============================================================================
> --- llvm/trunk/lib/MC/ELFObjectWriter.cpp (original)
> +++ llvm/trunk/lib/MC/ELFObjectWriter.cpp Mon Mar 17 12:13:54 2014
> @@ -470,6 +470,7 @@ uint64_t ELFObjectWriter::SymbolValue(MC
>     return Data->getCommonAlignment();
> 
>   const MCSymbol *Symbol = &Data->getSymbol();
> +  const bool IsThumbFunc = OrigData.getFlags() & ELF_Other_ThumbFunc;
> 
>   uint64_t Res = 0;
>   if (Symbol->isVariable()) {
> @@ -479,7 +480,10 @@ uint64_t ELFObjectWriter::SymbolValue(MC
>       return 0;
>     if (Value.getSymB())
>       return 0;
> +
>     Res = Value.getConstant();
> +    if (IsThumbFunc)
> +      Res |= 1;
> 
>     const MCSymbolRefExpr *A = Value.getSymA();
>     if (!A)
> @@ -496,8 +500,8 @@ uint64_t ELFObjectWriter::SymbolValue(MC
>     return 0;
> 
>   Res += Layout.getSymbolOffset(Data);
> -  if (Data->getFlags() & ELF_Other_ThumbFunc)
> -    ++Res;
> +  if (IsThumbFunc || Data->getFlags() & ELF_Other_ThumbFunc)
> +    Res |= 1;
> 
>   return Res;
> }
> @@ -590,6 +594,8 @@ void ELFObjectWriter::WriteSymbol(MCData
>   // Binding and Type share the same byte as upper and lower nibbles
>   uint8_t Binding = MCELF::GetBinding(OrigData);
>   uint8_t Type = mergeTypeForSet(MCELF::GetType(OrigData), MCELF::GetType(Data));
> +  if (OrigData.getFlags() & ELF_Other_ThumbFunc)
> +    Type = ELF::STT_FUNC;
>   uint8_t Info = (Binding << ELF_STB_Shift) | (Type << ELF_STT_Shift);
> 
>   // Other and Visibility share the same byte with Visibility using the lower
> 
> Modified: llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp?rev=204059&r1=204058&r2=204059&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp (original)
> +++ llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp Mon Mar 17 12:13:54 2014
> @@ -30,6 +30,7 @@
> #include "llvm/MC/MCInst.h"
> #include "llvm/MC/MCInstrDesc.h"
> #include "llvm/MC/MCInstrInfo.h"
> +#include "llvm/MC/MCObjectFileInfo.h"
> #include "llvm/MC/MCParser/MCAsmLexer.h"
> #include "llvm/MC/MCParser/MCAsmParser.h"
> #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
> @@ -41,6 +42,7 @@
> #include "llvm/MC/MCTargetAsmParser.h"
> #include "llvm/Support/ARMBuildAttributes.h"
> #include "llvm/Support/ARMEHABI.h"
> +#include "llvm/Support/COFF.h"
> #include "llvm/Support/Debug.h"
> #include "llvm/Support/ELF.h"
> #include "llvm/Support/MathExtras.h"
> @@ -229,6 +231,7 @@ class ARMAsmParser : public MCTargetAsmP
>   bool parseDirectiveObjectArch(SMLoc L);
>   bool parseDirectiveArchExtension(SMLoc L);
>   bool parseDirectiveAlign(SMLoc L);
> +  bool parseDirectiveThumbSet(SMLoc L);
> 
>   StringRef splitMnemonic(StringRef Mnemonic, unsigned &PredicationCode,
>                           bool &CarrySetting, unsigned &ProcessorIMod,
> @@ -8030,6 +8033,8 @@ bool ARMAsmParser::ParseDirective(AsmTok
>     return parseDirectiveArchExtension(DirectiveID.getLoc());
>   else if (IDVal == ".align")
>     return parseDirectiveAlign(DirectiveID.getLoc());
> +  else if (IDVal == ".thumb_set")
> +    return parseDirectiveThumbSet(DirectiveID.getLoc());
>   return true;
> }
> 
> @@ -9085,6 +9090,71 @@ bool ARMAsmParser::parseDirectiveAlign(S
> 
>   return false;
> }
> +
> +/// parseDirectiveThumbSet
> +///  ::= .thumb_set name, value
> +bool ARMAsmParser::parseDirectiveThumbSet(SMLoc L) {
> +  StringRef Name;
> +  if (Parser.parseIdentifier(Name)) {
> +    TokError("expected identifier after '.thumb_set'");
> +    Parser.eatToEndOfStatement();
> +    return false;
> +  }
> +
> +  if (getLexer().isNot(AsmToken::Comma)) {
> +    TokError("expected comma after name '" + Name + "'");
> +    Parser.eatToEndOfStatement();
> +    return false;
> +  }
> +  Lex();
> +
> +  const MCExpr *Value;
> +  if (Parser.parseExpression(Value)) {
> +    TokError("missing expression");
> +    Parser.eatToEndOfStatement();
> +    return false;
> +  }
> +
> +  if (getLexer().isNot(AsmToken::EndOfStatement)) {
> +    TokError("unexpected token");
> +    Parser.eatToEndOfStatement();
> +    return false;
> +  }
> +  Lex();
> +
> +  MCSymbol *Alias = getContext().GetOrCreateSymbol(Name);
> +  if (const MCSymbolRefExpr *SRE = dyn_cast<MCSymbolRefExpr>(Value)) {
> +    MCSymbol *Sym = getContext().LookupSymbol(SRE->getSymbol().getName());
> +    if (!Sym->isDefined()) {
> +      getStreamer().EmitSymbolAttribute(Sym, MCSA_Global);
> +      getStreamer().EmitAssignment(Alias, Value);
> +      return false;
> +    }
> +
> +    const MCObjectFileInfo::Environment Format =
> +      getContext().getObjectFileInfo()->getObjectFileType();
> +    switch (Format) {
> +    case MCObjectFileInfo::IsCOFF: {
> +      char Type = COFF::IMAGE_SYM_DTYPE_FUNCTION << COFF::SCT_COMPLEX_TYPE_SHIFT;
> +      getStreamer().EmitCOFFSymbolType(Type);
> +      // .set values are always local in COFF
> +      getStreamer().EmitSymbolAttribute(Alias, MCSA_Local);
> +      break;
> +    }
> +    case MCObjectFileInfo::IsELF:
> +      getStreamer().EmitSymbolAttribute(Alias, MCSA_ELF_TypeFunction);
> +      break;
> +    case MCObjectFileInfo::IsMachO:
> +      break;
> +    }
> +  }
> +
> +  // FIXME: set the function as being a thumb function via the assembler
> +  getStreamer().EmitThumbFunc(Alias);
> +  getStreamer().EmitAssignment(Alias, Value);
> +
> +  return false;
> +}
> 
> /// Force static initialization.
> extern "C" void LLVMInitializeARMAsmParser() {
> 
> Added: llvm/trunk/test/MC/ARM/thumb_set-diagnostics.s
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/thumb_set-diagnostics.s?rev=204059&view=auto
> ==============================================================================
> --- llvm/trunk/test/MC/ARM/thumb_set-diagnostics.s (added)
> +++ llvm/trunk/test/MC/ARM/thumb_set-diagnostics.s Mon Mar 17 12:13:54 2014
> @@ -0,0 +1,43 @@
> +@ RUN: not llvm-mc -triple armv7-eabi -o /dev/null 2>&1 %s | FileCheck %s
> +
> +	.syntax unified
> +
> +	.thumb
> +
> +	.thumb_set
> +
> +@ CHECK: error: expected identifier after '.thumb_set'
> +@ CHECK: 	.thumb_set
> +@ CHECL:                  ^
> +
> +	.thumb_set ., 0x0b5e55ed
> +
> +@ CHECK: error: expected identifier after '.thumb_set'
> +@ CHECK: 	.thumb_set ., 0x0b5e55ed
> +@ CHECK:                   ^
> +
> +	.thumb_set labelled, 0x1abe11ed
> +	.thumb_set invalid, :lower16:labelled
> +
> +@ CHECK: error: unknown token in expression
> +@ CHECK: 	.thumb_set invalid, :lower16:labelled
> +@ CHECK:                            ^
> +
> +	.thumb_set missing_comma
> +
> +@ CHECK: error: expected comma after name 'missing_comma'
> +@ CHECK: 	.thumb_set missing_comma
> +@ CHECK:                                ^
> +
> +	.thumb_set missing_expression,
> +
> +@ CHECK: error: missing expression
> +@ CHECK: 	.thumb_set missing_expression,
> +@ CHECK:                                      ^
> +
> +	.thumb_set trailer_trash, 0x11fe1e55,
> +
> +@ CHECK: error: unexpected token
> +@ CHECK: 	.thumb_set trailer_trash, 0x11fe1e55,
> +@ CHECK:                                            ^
> +
> 
> Added: llvm/trunk/test/MC/ARM/thumb_set.s
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/thumb_set.s?rev=204059&view=auto
> ==============================================================================
> --- llvm/trunk/test/MC/ARM/thumb_set.s (added)
> +++ llvm/trunk/test/MC/ARM/thumb_set.s Mon Mar 17 12:13:54 2014
> @@ -0,0 +1,140 @@
> +@ RUN: llvm-mc -triple armv7-eabi -filetype obj -o - %s | llvm-readobj -t \
> +@ RUN:   | FileCheck %s
> +
> +	.syntax unified
> +
> +	.arm
> +
> +	.type arm_func,%function
> +arm_func:
> +	nop
> +
> +	.thumb_set alias_arm_func, arm_func
> +
> +	.thumb
> +
> +	.type thumb_func,%function
> +	.thumb_func
> +thumb_func:
> +	nop
> +
> +	.thumb_set alias_thumb_func, thumb_func
> +
> +	.thumb_set seedless, 0x5eed1e55
> +	.thumb_set eggsalad, seedless + 0x87788358
> +	.thumb_set faceless, ~eggsalad + 0xe133c002
> +
> +	.thumb_set alias_undefined_data, badblood
> +
> +	.data
> +
> +	.type badblood,%object
> +badblood:
> +	.long 0xbadb100d
> +
> +	.type bedazzle,%object
> +bedazzle:
> +	.long 0xbeda221e
> +
> +	.text
> +	.thumb
> +
> +	.thumb_set alias_defined_data, bedazzle
> +
> +	.type alpha,%function
> +alpha:
> +	nop
> +
> +        .type beta,%function
> +beta:
> +	bkpt
> +
> +	.thumb_set beta, alpha
> +
> +	.thumb_set alias_undefined, undefined
> +
> +@ CHECK: Symbol {
> +@ CHECK:   Name: alias_arm_func
> +@ CHECK:   Value: 0x1
> +@ CHECK:   Type: Function
> +@ CHECK: }
> +
> +@ CHECK: Symbol {
> +@ CHECK:   Name: alias_defined_data
> +@ CHECK:   Value: 0x5
> +@ CHECK:   Type: Function
> +@ CHECK: }
> +
> +@ CHECK: Symbol {
> +@ CHECK:   Name: alias_thumb_func
> +@ CHECK:   Value: 0x5
> +@ CHECK:   Type: Function
> +@ CHECK: }
> +
> +@ CHECK: Symbol {
> +@ CHECK:   Name: alias_undefined_data
> +@ CHECK:   Value: 0x0
> +@ CHECK:   Type: Object
> +@ CHECK: }
> +
> +@ CHECK: Symbol {
> +@ CHECK:   Name: alpha
> +@ CHECK:   Value: 0x6
> +@ XFAIL-CHECK:   Value: 0x7
> +@ CHECK:   Type: Function
> +@ CHECK: }
> +
> +@ CHECK: Symbol {
> +@ CHECK:   Name: arm_func
> +@ CHECK:   Value: 0x0
> +@ CHECK:   Type: Function
> +@ CHECK: }
> +
> +@ CHECK: Symbol {
> +@ CHECK:   Name: bedazzle
> +@ CHECK:   Value: 0x4
> +@ CHECK:   Type: Object
> +@ CHECK: }
> +
> +@ CHECK: Symbol {
> +@ CHECK:   Name: beta
> +@ CHECK:   Value: 0x7
> +@ CHECK:   Type: Function
> +@ CHECK: }
> +
> +@ CHECK: Symbol {
> +@ CHECK:   Name: eggsalad
> +@ CHECK:   Value: 0xE665A1AD
> +@ CHECK:   Type: Function
> +@ CHECK: }
> +
> +@ CHECK: Symbol {
> +@ CHECK:   Name: faceless
> +@ CHECK:   Value: 0xFACE1E55
> +@ CHECK:   Type: Function
> +@ CHECK: }
> +
> +@ CHECK: Symbol {
> +@ CHECK:   Name: seedless
> +@ CHECK:   Value: 0x5EED1E55
> +@ CHECK:   Type: Function
> +@ CHECK: }
> +
> +@ CHECK: Symbol {
> +@ CHECK:   Name: thumb_func
> +@ CHECK:   Value: 0x5
> +@ CHECK:   Type: Function
> +@ CHECK: }
> +
> +@ CHECK: Symbol {
> +@ CHECK:   Name: badblood
> +@ CHECK:   Value: 0x0
> +@ CHECK:   Type: Object
> +@ CHECK: }
> +
> +@ CHECK: Symbol {
> +@ CHECK:   Name: undefined
> +@ CHECK:   Value: 0x0
> +@ CHECK:   Type: None
> +@ CHECK: }
> +
> 
> 
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits





More information about the llvm-commits mailing list