llvm.org GIT mirror llvm / 1c5f439
Centralize the handling of the thumb bit. This patch centralizes the handling of the thumb bit around MCStreamer::isThumbFunc and makes isThumbFunc handle aliases. This fixes a corner case, but the main advantage is having just one way to check if a MCSymbol is thumb or not. This should still be refactored to be ARM only, but at least now it is just one predicate that has to be refactored instead of 3 (isThumbFunc, ELF_Other_ThumbFunc, and SF_ThumbFunc). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@207522 91177308-0d34-0410-b5e6-96231b3b80d8 Rafael Espindola 6 years ago
9 changed file(s) with 59 addition(s) and 29 deletion(s). Raw diff Collapse all Expand all
901901 // here. Maybe when the relocation stuff moves to target specific,
902902 // this can go with it? The streamer would need some target specific
903903 // refactoring too.
904 SmallPtrSet ThumbFuncs;
904 mutable SmallPtrSet ThumbFuncs;
905905
906906 /// \brief The bundle alignment size currently set in the assembler.
907907 ///
994994 const MCAsmLayout &Layout) const;
995995
996996 /// Check whether a given symbol has been flagged with .thumb_func.
997 bool isThumbFunc(const MCSymbol *Func) const {
998 return ThumbFuncs.count(Func);
999 }
997 bool isThumbFunc(const MCSymbol *Func) const;
1000998
1001999 /// Flag a function symbol as the target of a .thumb_func directive.
10021000 void setIsThumbFunc(const MCSymbol *Func) { ThumbFuncs.insert(Func); }
2323 ELF_STT_Shift = 0, // Shift value for STT_* flags.
2424 ELF_STB_Shift = 4, // Shift value for STB_* flags.
2525 ELF_STV_Shift = 8, // Shift value for STV_* flags.
26 ELF_STO_Shift = 10, // Shift value for STO_* flags.
27 ELF_Other_Shift = 16 // Shift value for llvm local flags,
28 // not part of the final object file
26 ELF_STO_Shift = 10 // Shift value for STO_* flags.
2927 };
3028
3129 enum ELFSymbolFlags {
4846 ELF_STV_Default = (ELF::STV_DEFAULT << ELF_STV_Shift),
4947 ELF_STV_Internal = (ELF::STV_INTERNAL << ELF_STV_Shift),
5048 ELF_STV_Hidden = (ELF::STV_HIDDEN << ELF_STV_Shift),
51 ELF_STV_Protected = (ELF::STV_PROTECTED << ELF_STV_Shift),
52
53 ELF_Other_ThumbFunc = (1 << ELF_Other_Shift)
49 ELF_STV_Protected = (ELF::STV_PROTECTED << ELF_STV_Shift)
5450 };
5551
5652 } // end namespace llvm
214214 const MCAsmLayout &Layout,
215215 SectionIndexMapTy &SectionIndexMap);
216216
217 bool shouldRelocateWithSymbol(const MCSymbolRefExpr *RefA,
217 bool shouldRelocateWithSymbol(const MCAssembler &Asm,
218 const MCSymbolRefExpr *RefA,
218219 const MCSymbolData *SD, uint64_t C,
219220 unsigned Type) const;
220221
485486
486487 uint64_t ELFObjectWriter::SymbolValue(MCSymbolData &OrigData,
487488 const MCAsmLayout &Layout) {
489 const MCSymbol &OrigSymbol = OrigData.getSymbol();
488490 MCSymbolData *Data = &OrigData;
489491 if (Data->isCommon() && Data->isExternal())
490492 return Data->getCommonAlignment();
511513 }
512514 }
513515
514 if ((Data && Data->getFlags() & ELF_Other_ThumbFunc) ||
515 OrigData.getFlags() & ELF_Other_ThumbFunc)
516 const MCAssembler &Asm = Layout.getAssembler();
517 if (Asm.isThumbFunc(&OrigSymbol))
516518 Res |= 1;
517519
518520 if (!Symbol || !Symbol->isInSection())
640642 BaseSD = &Layout.getAssembler().getSymbolData(*Base);
641643 Type = mergeTypeForSet(Type, MCELF::GetType(*BaseSD));
642644 }
643 if (OrigData.getFlags() & ELF_Other_ThumbFunc)
644 Type = ELF::STT_FUNC;
645645 uint8_t Info = (Binding << ELF_STB_Shift) | (Type << ELF_STT_Shift);
646646
647647 // Other and Visibility share the same byte with Visibility using the lower
736736 // It is always valid to create a relocation with a symbol. It is preferable
737737 // to use a relocation with a section if that is possible. Using the section
738738 // allows us to omit some local symbols from the symbol table.
739 bool ELFObjectWriter::shouldRelocateWithSymbol(const MCSymbolRefExpr *RefA,
739 bool ELFObjectWriter::shouldRelocateWithSymbol(const MCAssembler &Asm,
740 const MCSymbolRefExpr *RefA,
740741 const MCSymbolData *SD,
741742 uint64_t C,
742743 unsigned Type) const {
824825 // bit. With a symbol that is done by just having the symbol have that bit
825826 // set, so we would lose the bit if we relocated with the section.
826827 // FIXME: We could use the section but add the bit to the relocation value.
827 if (SD->getFlags() & ELF_Other_ThumbFunc)
828 if (Asm.isThumbFunc(&Sym))
828829 return true;
829830
830831 if (TargetObjectWriter->needsRelocateWithSymbol(Type))
886887 const MCSymbolData *SymAD = SymA ? &Asm.getSymbolData(*SymA) : nullptr;
887888
888889 unsigned Type = GetRelocType(Target, Fixup, IsPCRel);
889 bool RelocateWithSymbol = shouldRelocateWithSymbol(RefA, SymAD, C, Type);
890 bool RelocateWithSymbol = shouldRelocateWithSymbol(Asm, RefA, SymAD, C, Type);
890891 if (!RelocateWithSymbol && SymA && !SymA->isUndefined())
891892 C += Layout.getSymbolOffset(SymAD);
892893
320320 getEmitter().reset();
321321 getWriter().reset();
322322 getLOHContainer().reset();
323 }
324
325 bool MCAssembler::isThumbFunc(const MCSymbol *Symbol) const {
326 if (ThumbFuncs.count(Symbol))
327 return true;
328
329 if (!Symbol->isVariable())
330 return false;
331
332 // FIXME: It looks like gas support some cases of the form "foo + 2". It
333 // is not clear if that is a bug or a feature.
334 const MCExpr *Expr = Symbol->getVariableValue();
335 const MCSymbolRefExpr *Ref = dyn_cast(Expr);
336 if (!Ref)
337 return false;
338
339 if (Ref->getKind() != MCSymbolRefExpr::VK_None)
340 return false;
341
342 const MCSymbol &Sym = Ref->getSymbol();
343 if (!isThumbFunc(&Sym))
344 return false;
345
346 ThumbFuncs.insert(Symbol); // Cache it.
347 return true;
323348 }
324349
325350 bool MCAssembler::isSymbolLinkerVisible(const MCSymbol &Symbol) const {
236236 // Remember that the function is a thumb function. Fixup and relocation
237237 // values will need adjusted.
238238 getAssembler().setIsThumbFunc(Symbol);
239
240 // Mark the thumb bit on the symbol.
241 MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
242 SD.setFlags(SD.getFlags() | SF_ThumbFunc);
243239 }
244240
245241 bool MCMachOStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
349349 Flags = (Flags & 0xF0FF) | (Log2Size << 8);
350350 }
351351 }
352
353 if (Layout.getAssembler().isThumbFunc(&Symbol))
354 Flags |= SF_ThumbFunc;
352355
353356 // struct nlist (12 bytes)
354357
608608 }
609609
610610 void EmitThumbFunc(MCSymbol *Func) override {
611 // FIXME: Anything needed here to flag the function as thumb?
612
613611 getAssembler().setIsThumbFunc(Func);
614
615 MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Func);
616 SD.setFlags(SD.getFlags() | ELF_Other_ThumbFunc);
612 EmitSymbolAttribute(Func, MCSA_ELF_TypeFunction);
617613 }
618614
619615 // Helper functions for ARM exception handling directives
205205 // The thumb bit shouldn't be set in the 'other-half' bit of the
206206 // relocation, but it will be set in FixedValue if the base symbol
207207 // is a thumb function. Clear it out here.
208 if (A_SD->getFlags() & SF_ThumbFunc)
208 if (Asm.isThumbFunc(A))
209209 FixedValue &= 0xfffffffe;
210210 break;
211211 case ARM::fixup_t2_movt_hi16:
212 if (A_SD->getFlags() & SF_ThumbFunc)
212 if (Asm.isThumbFunc(A))
213213 FixedValue &= 0xfffffffe;
214214 MovtBit = 1;
215215 // Fallthrough
1212 nop
1313
1414 .thumb_set alias_arm_func, arm_func
15
16 alias_arm_func2 = alias_arm_func
17 alias_arm_func3 = alias_arm_func2
1518
1619 @ ASM: .thumb_set alias_arm_func, arm_func
1720
5962
6063 @ CHECK: Symbol {
6164 @ CHECK: Name: alias_arm_func
65 @ CHECK: Value: 0x1
66 @ CHECK: Type: Function
67 @ CHECK: }
68
69 @ CHECK: Symbol {
70 @ CHECK: Name: alias_arm_func2
71 @ CHECK: Value: 0x1
72 @ CHECK: Type: Function
73 @ CHECK: }
74
75 @ CHECK: Symbol {
76 @ CHECK: Name: alias_arm_func3
6277 @ CHECK: Value: 0x1
6378 @ CHECK: Type: Function
6479 @ CHECK: }