mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-10-31 08:16:47 +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()) |  | ||||||
|     return Layout.getSymbolOffset(&Data); |   if (Data.getFragment()) { | ||||||
|  |     if (Data.getFlags() & ELF_Other_ThumbFunc) | ||||||
|  |       return Layout.getSymbolOffset(&Data)+1; | ||||||
|  |     else | ||||||
|  |       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 AsmToken &Tok = Parser.getTok(); |   const MCAsmInfo &MAI = getParser().getStreamer().getContext().getAsmInfo(); | ||||||
|   if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String)) |   bool isMachO = MAI.hasSubsectionsViaSymbols(); | ||||||
|     return Error(L, "unexpected token in .thumb_func directive"); |   StringRef Name; | ||||||
|   StringRef Name = Tok.getString(); |  | ||||||
|   Parser.Lex(); // Consume the identifier token. |   // Darwin asm has function name after .thumb_func direction | ||||||
|  |   // ELF doesn't | ||||||
|  |   if (isMachO) { | ||||||
|  |     const AsmToken &Tok = Parser.getTok(); | ||||||
|  |     if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String)) | ||||||
|  |       return Error(L, "unexpected token in .thumb_func directive"); | ||||||
|  |     Name = Tok.getString(); | ||||||
|  |     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