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_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 | ||||
|   | ||||
| @@ -193,8 +193,13 @@ uint64_t ELFObjectWriter::SymbolValue(MCSymbolData &Data, | ||||
|   if (!Symbol.isInSection()) | ||||
|     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 0; | ||||
| } | ||||
|   | ||||
| @@ -323,7 +323,8 @@ void MCAsmStreamer::EmitThumbFunc(MCSymbol *Func) { | ||||
|   // This needs to emit to a temporary string to get properly quoted | ||||
|   // MCSymbols when they have spaces in them. | ||||
|   OS << "\t.thumb_func"; | ||||
|   if (Func) | ||||
|   // Only Mach-O hasSubsectionsViaSymbols() | ||||
|   if (MAI.hasSubsectionsViaSymbols()) | ||||
|     OS << '\t' << *Func; | ||||
|   EmitEOL(); | ||||
| } | ||||
|   | ||||
| @@ -57,13 +57,13 @@ void MCELF::SetVisibility(MCSymbolData &SD, unsigned Visibility) { | ||||
|   assert(Visibility == ELF::STV_DEFAULT || Visibility == ELF::STV_INTERNAL || | ||||
|          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)); | ||||
| } | ||||
|  | ||||
| unsigned MCELF::GetVisibility(MCSymbolData &SD) { | ||||
|   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 || | ||||
|          Visibility == ELF::STV_HIDDEN || Visibility == ELF::STV_PROTECTED); | ||||
|   return Visibility; | ||||
|   | ||||
| @@ -66,6 +66,11 @@ void MCELFStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) { | ||||
|  | ||||
| void MCELFStreamer::EmitThumbFunc(MCSymbol *Func) { | ||||
|   // 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) { | ||||
|   | ||||
| @@ -274,7 +274,7 @@ void ARMAsmPrinter::EmitDwarfRegOp(const MachineLocation &MLoc) const { | ||||
| void ARMAsmPrinter::EmitFunctionEntryLabel() { | ||||
|   if (AFI->isThumbFunction()) { | ||||
|     OutStreamer.EmitAssemblerFlag(MCAF_Code16); | ||||
|     OutStreamer.EmitThumbFunc(Subtarget->isTargetDarwin()? CurrentFnSym : 0); | ||||
|     OutStreamer.EmitThumbFunc(CurrentFnSym); | ||||
|   } | ||||
|  | ||||
|   OutStreamer.EmitLabel(CurrentFnSym); | ||||
|   | ||||
| @@ -15,6 +15,7 @@ | ||||
| #include "llvm/MC/MCParser/MCAsmLexer.h" | ||||
| #include "llvm/MC/MCParser/MCAsmParser.h" | ||||
| #include "llvm/MC/MCParser/MCParsedAsmOperand.h" | ||||
| #include "llvm/MC/MCAsmInfo.h" | ||||
| #include "llvm/MC/MCContext.h" | ||||
| #include "llvm/MC/MCStreamer.h" | ||||
| #include "llvm/MC/MCExpr.h" | ||||
| @@ -2099,15 +2100,29 @@ bool ARMAsmParser::ParseDirectiveThumb(SMLoc L) { | ||||
| /// ParseDirectiveThumbFunc | ||||
| ///  ::= .thumbfunc symbol_name | ||||
| 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(); | ||||
|     if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String)) | ||||
|       return Error(L, "unexpected token in .thumb_func directive"); | ||||
|   StringRef Name = Tok.getString(); | ||||
|     Name = Tok.getString(); | ||||
|     Parser.Lex(); // Consume the identifier token. | ||||
|   } | ||||
|  | ||||
|   if (getLexer().isNot(AsmToken::EndOfStatement)) | ||||
|     return Error(L, "unexpected token in directive"); | ||||
|   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. | ||||
|   MCSymbol *Func = getParser().getContext().GetOrCreateSymbol(Name); | ||||
|   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