mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-11-01 00:17:01 +00:00
sets bit 0 of the function address of thumb function in .symtab
("T is 1 if the target symbol S has type STT_FUNC and the
symbol addresses a Thumb instruction ;it is 0 otherwise."
from "ELF for the ARM Architecture" 4.7.1.2)
Patch by Koan-Sin Tan!
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@131406 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -49,7 +49,8 @@ namespace llvm {
|
|||||||
ELF_STV_Hidden = (ELF::STV_HIDDEN << ELF_STV_Shift),
|
ELF_STV_Hidden = (ELF::STV_HIDDEN << ELF_STV_Shift),
|
||||||
ELF_STV_Protected = (ELF::STV_PROTECTED << ELF_STV_Shift),
|
ELF_STV_Protected = (ELF::STV_PROTECTED << ELF_STV_Shift),
|
||||||
|
|
||||||
ELF_Other_Weakref = (1 << ELF_Other_Shift)
|
ELF_Other_Weakref = (1 << ELF_Other_Shift),
|
||||||
|
ELF_Other_ThumbFunc = (2 << ELF_Other_Shift)
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace llvm
|
} // end namespace llvm
|
||||||
|
|||||||
@@ -193,8 +193,13 @@ uint64_t ELFObjectWriter::SymbolValue(MCSymbolData &Data,
|
|||||||
if (!Symbol.isInSection())
|
if (!Symbol.isInSection())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (Data.getFragment())
|
|
||||||
|
if (Data.getFragment()) {
|
||||||
|
if (Data.getFlags() & ELF_Other_ThumbFunc)
|
||||||
|
return Layout.getSymbolOffset(&Data)+1;
|
||||||
|
else
|
||||||
return Layout.getSymbolOffset(&Data);
|
return Layout.getSymbolOffset(&Data);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -323,7 +323,8 @@ void MCAsmStreamer::EmitThumbFunc(MCSymbol *Func) {
|
|||||||
// This needs to emit to a temporary string to get properly quoted
|
// This needs to emit to a temporary string to get properly quoted
|
||||||
// MCSymbols when they have spaces in them.
|
// MCSymbols when they have spaces in them.
|
||||||
OS << "\t.thumb_func";
|
OS << "\t.thumb_func";
|
||||||
if (Func)
|
// Only Mach-O hasSubsectionsViaSymbols()
|
||||||
|
if (MAI.hasSubsectionsViaSymbols())
|
||||||
OS << '\t' << *Func;
|
OS << '\t' << *Func;
|
||||||
EmitEOL();
|
EmitEOL();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,13 +57,13 @@ void MCELF::SetVisibility(MCSymbolData &SD, unsigned Visibility) {
|
|||||||
assert(Visibility == ELF::STV_DEFAULT || Visibility == ELF::STV_INTERNAL ||
|
assert(Visibility == ELF::STV_DEFAULT || Visibility == ELF::STV_INTERNAL ||
|
||||||
Visibility == ELF::STV_HIDDEN || Visibility == ELF::STV_PROTECTED);
|
Visibility == ELF::STV_HIDDEN || Visibility == ELF::STV_PROTECTED);
|
||||||
|
|
||||||
uint32_t OtherFlags = SD.getFlags() & ~(0xf << ELF_STV_Shift);
|
uint32_t OtherFlags = SD.getFlags() & ~(0x3 << ELF_STV_Shift);
|
||||||
SD.setFlags(OtherFlags | (Visibility << ELF_STV_Shift));
|
SD.setFlags(OtherFlags | (Visibility << ELF_STV_Shift));
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned MCELF::GetVisibility(MCSymbolData &SD) {
|
unsigned MCELF::GetVisibility(MCSymbolData &SD) {
|
||||||
unsigned Visibility =
|
unsigned Visibility =
|
||||||
(SD.getFlags() & (0xf << ELF_STV_Shift)) >> ELF_STV_Shift;
|
(SD.getFlags() & (0x3 << ELF_STV_Shift)) >> ELF_STV_Shift;
|
||||||
assert(Visibility == ELF::STV_DEFAULT || Visibility == ELF::STV_INTERNAL ||
|
assert(Visibility == ELF::STV_DEFAULT || Visibility == ELF::STV_INTERNAL ||
|
||||||
Visibility == ELF::STV_HIDDEN || Visibility == ELF::STV_PROTECTED);
|
Visibility == ELF::STV_HIDDEN || Visibility == ELF::STV_PROTECTED);
|
||||||
return Visibility;
|
return Visibility;
|
||||||
|
|||||||
@@ -66,6 +66,11 @@ void MCELFStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
|
|||||||
|
|
||||||
void MCELFStreamer::EmitThumbFunc(MCSymbol *Func) {
|
void MCELFStreamer::EmitThumbFunc(MCSymbol *Func) {
|
||||||
// FIXME: Anything needed here to flag the function as thumb?
|
// FIXME: Anything needed here to flag the function as thumb?
|
||||||
|
|
||||||
|
getAssembler().setIsThumbFunc(Func);
|
||||||
|
|
||||||
|
MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Func);
|
||||||
|
SD.setFlags(SD.getFlags() | ELF_Other_ThumbFunc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MCELFStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
|
void MCELFStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
|
||||||
|
|||||||
@@ -274,7 +274,7 @@ void ARMAsmPrinter::EmitDwarfRegOp(const MachineLocation &MLoc) const {
|
|||||||
void ARMAsmPrinter::EmitFunctionEntryLabel() {
|
void ARMAsmPrinter::EmitFunctionEntryLabel() {
|
||||||
if (AFI->isThumbFunction()) {
|
if (AFI->isThumbFunction()) {
|
||||||
OutStreamer.EmitAssemblerFlag(MCAF_Code16);
|
OutStreamer.EmitAssemblerFlag(MCAF_Code16);
|
||||||
OutStreamer.EmitThumbFunc(Subtarget->isTargetDarwin()? CurrentFnSym : 0);
|
OutStreamer.EmitThumbFunc(CurrentFnSym);
|
||||||
}
|
}
|
||||||
|
|
||||||
OutStreamer.EmitLabel(CurrentFnSym);
|
OutStreamer.EmitLabel(CurrentFnSym);
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
#include "llvm/MC/MCParser/MCAsmLexer.h"
|
#include "llvm/MC/MCParser/MCAsmLexer.h"
|
||||||
#include "llvm/MC/MCParser/MCAsmParser.h"
|
#include "llvm/MC/MCParser/MCAsmParser.h"
|
||||||
#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
|
#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
|
||||||
|
#include "llvm/MC/MCAsmInfo.h"
|
||||||
#include "llvm/MC/MCContext.h"
|
#include "llvm/MC/MCContext.h"
|
||||||
#include "llvm/MC/MCStreamer.h"
|
#include "llvm/MC/MCStreamer.h"
|
||||||
#include "llvm/MC/MCExpr.h"
|
#include "llvm/MC/MCExpr.h"
|
||||||
@@ -2099,15 +2100,29 @@ bool ARMAsmParser::ParseDirectiveThumb(SMLoc L) {
|
|||||||
/// ParseDirectiveThumbFunc
|
/// ParseDirectiveThumbFunc
|
||||||
/// ::= .thumbfunc symbol_name
|
/// ::= .thumbfunc symbol_name
|
||||||
bool ARMAsmParser::ParseDirectiveThumbFunc(SMLoc L) {
|
bool ARMAsmParser::ParseDirectiveThumbFunc(SMLoc L) {
|
||||||
|
const MCAsmInfo &MAI = getParser().getStreamer().getContext().getAsmInfo();
|
||||||
|
bool isMachO = MAI.hasSubsectionsViaSymbols();
|
||||||
|
StringRef Name;
|
||||||
|
|
||||||
|
// Darwin asm has function name after .thumb_func direction
|
||||||
|
// ELF doesn't
|
||||||
|
if (isMachO) {
|
||||||
const AsmToken &Tok = Parser.getTok();
|
const AsmToken &Tok = Parser.getTok();
|
||||||
if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String))
|
if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String))
|
||||||
return Error(L, "unexpected token in .thumb_func directive");
|
return Error(L, "unexpected token in .thumb_func directive");
|
||||||
StringRef Name = Tok.getString();
|
Name = Tok.getString();
|
||||||
Parser.Lex(); // Consume the identifier token.
|
Parser.Lex(); // Consume the identifier token.
|
||||||
|
}
|
||||||
|
|
||||||
if (getLexer().isNot(AsmToken::EndOfStatement))
|
if (getLexer().isNot(AsmToken::EndOfStatement))
|
||||||
return Error(L, "unexpected token in directive");
|
return Error(L, "unexpected token in directive");
|
||||||
Parser.Lex();
|
Parser.Lex();
|
||||||
|
|
||||||
|
// FIXME: assuming function name will be the line following .thumb_func
|
||||||
|
if (!isMachO) {
|
||||||
|
Name = Parser.getTok().getString();
|
||||||
|
}
|
||||||
|
|
||||||
// Mark symbol as a thumb symbol.
|
// Mark symbol as a thumb symbol.
|
||||||
MCSymbol *Func = getParser().getContext().GetOrCreateSymbol(Name);
|
MCSymbol *Func = getParser().getContext().GetOrCreateSymbol(Name);
|
||||||
getParser().getStreamer().EmitThumbFunc(Func);
|
getParser().getStreamer().EmitThumbFunc(Func);
|
||||||
|
|||||||
20
test/MC/ELF/elf-thumbfunc.s
Normal file
20
test/MC/ELF/elf-thumbfunc.s
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
@@ test st_value bit 0 of thumb function
|
||||||
|
@ RUN: llvm-mc %s -triple=thumbv7-linux-gnueabi -filetype=obj -o - | \
|
||||||
|
@ RUN: elf-dump | FileCheck %s
|
||||||
|
.syntax unified
|
||||||
|
.text
|
||||||
|
.globl foo
|
||||||
|
.align 2
|
||||||
|
.type foo,%function
|
||||||
|
.code 16
|
||||||
|
.thumb_func
|
||||||
|
foo:
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
@@ make sure foo is thumb function: bit 0 = 1 (st_value)
|
||||||
|
@CHECK: Symbol 0x00000004
|
||||||
|
@CHECK-NEXT: 'st_name', 0x00000001
|
||||||
|
@CHECK-NEXT: 'st_value', 0x00000001
|
||||||
|
@CHECK-NEXT: 'st_size', 0x00000000
|
||||||
|
@CHECK-NEXT: 'st_bind', 0x00000001
|
||||||
|
@CHECK-NEXT: 'st_type', 0x00000002
|
||||||
Reference in New Issue
Block a user