diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h @@ -32,81 +32,16 @@ class RISCVTargetELFStreamer : public RISCVTargetStreamer { private: - enum class AttributeType { Hidden, Numeric, Text, NumericAndText }; - - struct AttributeItem { - AttributeType Type; - unsigned Tag; - unsigned IntValue; - std::string StringValue; - }; - StringRef CurrentVendor; - SmallVector Contents; MCSection *AttributeSection = nullptr; const MCSubtargetInfo &STI; - AttributeItem *getAttributeItem(unsigned Attribute) { - for (size_t i = 0; i < Contents.size(); ++i) - if (Contents[i].Tag == Attribute) - return &Contents[i]; - return nullptr; - } - - void setAttributeItem(unsigned Attribute, unsigned Value, - bool OverwriteExisting) { - // Look for existing attribute item. - if (AttributeItem *Item = getAttributeItem(Attribute)) { - if (!OverwriteExisting) - return; - Item->Type = AttributeType::Numeric; - Item->IntValue = Value; - return; - } - - // Create new attribute item. - Contents.push_back({AttributeType::Numeric, Attribute, Value, ""}); - } - - void setAttributeItem(unsigned Attribute, StringRef Value, - bool OverwriteExisting) { - // Look for existing attribute item. - if (AttributeItem *Item = getAttributeItem(Attribute)) { - if (!OverwriteExisting) - return; - Item->Type = AttributeType::Text; - Item->StringValue = std::string(Value); - return; - } - - // Create new attribute item. - Contents.push_back({AttributeType::Text, Attribute, 0, std::string(Value)}); - } - - void setAttributeItems(unsigned Attribute, unsigned IntValue, - StringRef StringValue, bool OverwriteExisting) { - // Look for existing attribute item. - if (AttributeItem *Item = getAttributeItem(Attribute)) { - if (!OverwriteExisting) - return; - Item->Type = AttributeType::NumericAndText; - Item->IntValue = IntValue; - Item->StringValue = std::string(StringValue); - return; - } - - // Create new attribute item. - Contents.push_back({AttributeType::NumericAndText, Attribute, IntValue, - std::string(StringValue)}); - } - void emitAttribute(unsigned Attribute, unsigned Value) override; void emitTextAttribute(unsigned Attribute, StringRef String) override; void emitIntTextAttribute(unsigned Attribute, unsigned IntValue, StringRef StringValue) override; void finishAttributeSection() override; - size_t calculateContentSize() const; void reset() override; diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp @@ -53,98 +53,28 @@ void RISCVTargetELFStreamer::emitDirectiveOptionNoRelax() {} void RISCVTargetELFStreamer::emitAttribute(unsigned Attribute, unsigned Value) { - setAttributeItem(Attribute, Value, /*OverwriteExisting=*/true); + getStreamer().setAttributeItem(Attribute, Value, /*OverwriteExisting=*/true); } void RISCVTargetELFStreamer::emitTextAttribute(unsigned Attribute, StringRef String) { - setAttributeItem(Attribute, String, /*OverwriteExisting=*/true); + getStreamer().setAttributeItem(Attribute, String, /*OverwriteExisting=*/true); } void RISCVTargetELFStreamer::emitIntTextAttribute(unsigned Attribute, unsigned IntValue, StringRef StringValue) { - setAttributeItems(Attribute, IntValue, StringValue, - /*OverwriteExisting=*/true); + getStreamer().setAttributeItems(Attribute, IntValue, StringValue, + /*OverwriteExisting=*/true); } void RISCVTargetELFStreamer::finishAttributeSection() { - if (Contents.empty()) + RISCVELFStreamer &S = getStreamer(); + if (S.Contents.empty()) return; - if (AttributeSection) { - Streamer.switchSection(AttributeSection); - } else { - MCAssembler &MCA = getStreamer().getAssembler(); - AttributeSection = MCA.getContext().getELFSection( - ".riscv.attributes", ELF::SHT_RISCV_ATTRIBUTES, 0); - Streamer.switchSection(AttributeSection); - - Streamer.emitInt8(ELFAttrs::Format_Version); - } - - // Vendor size + Vendor name + '\0' - const size_t VendorHeaderSize = 4 + CurrentVendor.size() + 1; - - // Tag + Tag Size - const size_t TagHeaderSize = 1 + 4; - - const size_t ContentsSize = calculateContentSize(); - - Streamer.emitInt32(VendorHeaderSize + TagHeaderSize + ContentsSize); - Streamer.emitBytes(CurrentVendor); - Streamer.emitInt8(0); // '\0' - - Streamer.emitInt8(ELFAttrs::File); - Streamer.emitInt32(TagHeaderSize + ContentsSize); - - // Size should have been accounted for already, now - // emit each field as its type (ULEB or String). - for (AttributeItem item : Contents) { - Streamer.emitULEB128IntValue(item.Tag); - switch (item.Type) { - default: - llvm_unreachable("Invalid attribute type"); - case AttributeType::Numeric: - Streamer.emitULEB128IntValue(item.IntValue); - break; - case AttributeType::Text: - Streamer.emitBytes(item.StringValue); - Streamer.emitInt8(0); // '\0' - break; - case AttributeType::NumericAndText: - Streamer.emitULEB128IntValue(item.IntValue); - Streamer.emitBytes(item.StringValue); - Streamer.emitInt8(0); // '\0' - break; - } - } - - Contents.clear(); -} - -size_t RISCVTargetELFStreamer::calculateContentSize() const { - size_t Result = 0; - for (AttributeItem item : Contents) { - switch (item.Type) { - case AttributeType::Hidden: - break; - case AttributeType::Numeric: - Result += getULEB128Size(item.Tag); - Result += getULEB128Size(item.IntValue); - break; - case AttributeType::Text: - Result += getULEB128Size(item.Tag); - Result += item.StringValue.size() + 1; // string + '\0' - break; - case AttributeType::NumericAndText: - Result += getULEB128Size(item.Tag); - Result += getULEB128Size(item.IntValue); - Result += item.StringValue.size() + 1; // string + '\0'; - break; - } - } - return Result; + S.emitAttributesSection(CurrentVendor, ".riscv.attributes", + ELF::SHT_RISCV_ATTRIBUTES, AttributeSection); } void RISCVTargetELFStreamer::finish() { @@ -184,7 +114,6 @@ void RISCVTargetELFStreamer::reset() { AttributeSection = nullptr; - Contents.clear(); } void RISCVTargetELFStreamer::emitDirectiveVariantCC(MCSymbol &Symbol) {