StringRef StringValue;
static bool LessTag(const AttributeItem &LHS, const AttributeItem &RHS) {
- return (LHS.Tag < RHS.Tag);
+ // The conformance tag must be emitted first when serialised
+ // into an object file. Specifically, the addenda to the ARM ABI
+ // states that (2.3.7.4):
+ //
+ // "To simplify recognition by consumers in the common case of
+ // claiming conformity for the whole file, this tag should be
+ // emitted first in a file-scope sub-subsection of the first
+ // public subsection of the attributes section."
+ //
+ // So it is special-cased in this comparison predicate when the
+ // attributes are sorted in finishAttributeSection().
+ return (RHS.Tag != ARMBuildAttrs::conformance) &&
+ ((LHS.Tag == ARMBuildAttrs::conformance) || (LHS.Tag < RHS.Tag));
}
};
/// necessary.
void EmitValueImpl(const MCExpr *Value, unsigned Size,
const SMLoc &Loc) override {
+ if (const MCSymbolRefExpr *SRE = dyn_cast_or_null<MCSymbolRefExpr>(Value))
+ if (SRE->getKind() == MCSymbolRefExpr::VK_ARM_SBREL && !(Size == 4))
+ getContext().FatalError(Loc, "relocated expression must be 32-bit");
+
EmitDataMappingSymbol();
MCELFStreamer::EmitValueImpl(Value, Size);
}
/* OverwriteExisting= */ false);
break;
+ // FPV5_D16 is identical to FP_ARMV8 except for the number of D registers, so
+ // uses the FP_ARMV8_D16 build attribute.
+ case ARM::FPV5_D16:
+ setAttributeItem(ARMBuildAttrs::FP_arch,
+ ARMBuildAttrs::AllowFPARMv8B,
+ /* OverwriteExisting= */ false);
+ break;
+
case ARM::NEON:
setAttributeItem(ARMBuildAttrs::FP_arch,
ARMBuildAttrs::AllowFPv3A,
if (AttributeSection) {
Streamer.SwitchSection(AttributeSection);
} else {
- AttributeSection =
- Streamer.getContext().getELFSection(".ARM.attributes",
- ELF::SHT_ARM_ATTRIBUTES,
- 0,
- SectionKind::getMetadata());
+ AttributeSection = Streamer.getContext().getELFSection(
+ ".ARM.attributes", ELF::SHT_ARM_ATTRIBUTES, 0);
Streamer.SwitchSection(AttributeSection);
// Format version
Streamer.EmitULEB128IntValue(item.IntValue);
break;
case AttributeItem::TextAttribute:
- Streamer.EmitBytes(item.StringValue.upper());
+ Streamer.EmitBytes(item.StringValue);
Streamer.EmitIntValue(0, 1); // '\0'
break;
case AttributeItem::NumericAndTextAttributes:
Streamer.EmitULEB128IntValue(item.IntValue);
- Streamer.EmitBytes(item.StringValue.upper());
+ Streamer.EmitBytes(item.StringValue);
Streamer.EmitIntValue(0, 1); // '\0'
break;
}
return;
const MCSymbolData &SD = Streamer.getOrCreateSymbolData(Symbol);
- if (MCELF::GetType(SD) & (ELF::STT_FUNC << ELF_STT_Shift))
+ unsigned Type = MCELF::GetType(SD);
+ if (Type == ELF_STT_Func || Type == ELF_STT_GnuIFunc)
Streamer.EmitThumbFunc(Symbol);
}
// Get .ARM.extab or .ARM.exidx section
const MCSectionELF *EHSection = nullptr;
if (const MCSymbol *Group = FnSection.getGroup()) {
- EHSection = getContext().getELFSection(
- EHSecName, Type, Flags | ELF::SHF_GROUP, Kind,
- FnSection.getEntrySize(), Group->getName());
+ EHSection =
+ getContext().getELFSection(EHSecName, Type, Flags | ELF::SHF_GROUP,
+ FnSection.getEntrySize(), Group->getName());
} else {
- EHSection = getContext().getELFSection(EHSecName, Type, Flags, Kind);
+ EHSection = getContext().getELFSection(EHSecName, Type, Flags);
}
assert(EHSection && "Failed to get the required EH section");
// the second word of exception index table entry. The size of the unwind
// opcodes should always be 4 bytes.
assert(PersonalityIndex == ARM::EHABI::AEABI_UNWIND_CPP_PR0 &&
- "Compact model must use __aeabi_cpp_unwind_pr0 as personality");
+ "Compact model must use __aeabi_unwind_cpp_pr0 as personality");
assert(Opcodes.size() == 4u &&
- "Unwind opcode size for __aeabi_cpp_unwind_pr0 must be equal to 4");
- EmitBytes(StringRef(reinterpret_cast<const char*>(Opcodes.data()),
- Opcodes.size()));
+ "Unwind opcode size for __aeabi_unwind_cpp_pr0 must be equal to 4");
+ uint64_t Intval = Opcodes[0] |
+ Opcodes[1] << 8 |
+ Opcodes[2] << 16 |
+ Opcodes[3] << 24;
+ EmitIntValue(Intval, Opcodes.size());
}
// Switch to the section containing FnStart
const MCSymbolRefExpr *PersonalityRef = MCSymbolRefExpr::Create(
PersonalitySym, MCSymbolRefExpr::VK_ARM_NONE, getContext());
- AddValueSymbols(PersonalityRef);
+ visitUsedExpr(*PersonalityRef);
MCDataFragment *DF = getOrCreateDataFragment();
DF->getFixups().push_back(MCFixup::Create(DF->getContents().size(),
PersonalityRef,
}
// Emit unwind opcodes
- EmitBytes(StringRef(reinterpret_cast<const char *>(Opcodes.data()),
- Opcodes.size()));
+ assert((Opcodes.size() % 4) == 0 &&
+ "Unwind opcode size for __aeabi_cpp_unwind_pr0 must be multiple of 4");
+ for (unsigned I = 0; I != Opcodes.size(); I += 4) {
+ uint64_t Intval = Opcodes[I] |
+ Opcodes[I + 1] << 8 |
+ Opcodes[I + 2] << 16 |
+ Opcodes[I + 3] << 24;
+ EmitIntValue(Intval, 4);
+ }
// According to ARM EHABI section 9.2, if the __aeabi_unwind_cpp_pr1() or
// __aeabi_unwind_cpp_pr2() is used, then the handler data must be emitted
return S;
}
- MCELFStreamer* createARMELFStreamer(MCContext &Context, MCAsmBackend &TAB,
- raw_ostream &OS, MCCodeEmitter *Emitter,
- bool RelaxAll, bool NoExecStack,
- bool IsThumb) {
+MCTargetStreamer *createARMNullTargetStreamer(MCStreamer &S) {
+ return new ARMTargetStreamer(S);
+}
+
+MCELFStreamer *createARMELFStreamer(MCContext &Context, MCAsmBackend &TAB,
+ raw_ostream &OS, MCCodeEmitter *Emitter,
+ bool RelaxAll, bool IsThumb) {
ARMELFStreamer *S = new ARMELFStreamer(Context, TAB, OS, Emitter, IsThumb);
new ARMTargetELFStreamer(*S);
// FIXME: This should eventually end up somewhere else where more
if (RelaxAll)
S->getAssembler().setRelaxAll(true);
- if (NoExecStack)
- S->getAssembler().setNoExecStack(true);
return S;
}