[llvm] r204059 - ARM IAS: support .thumb_set

Saleem Abdulrasool compnerd at compnerd.org
Mon Mar 17 21:30:27 PDT 2014


On Mon, Mar 17, 2014 at 11:52 AM, Jim Grosbach <grosbach at apple.com> wrote:

>
> 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.


At the very least GNU AS does mark the labels correctly.  I may try to take
a stab at getting the labels marked correctly in thumb sections.


> >
> > 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
>
>


-- 
Saleem Abdulrasool
compnerd (at) compnerd (dot) org
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140317/bb514f1e/attachment.html>


More information about the llvm-commits mailing list