diff --git a/llvm/include/llvm/Support/MSP430AttributeParser.h b/llvm/include/llvm/Support/MSP430AttributeParser.h new file mode 100644 --- /dev/null +++ b/llvm/include/llvm/Support/MSP430AttributeParser.h @@ -0,0 +1,44 @@ +//===-- MSP430AttributeParser.h - MSP430 Attribute Parser -------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// This file contains support routines for parsing MSP430 ELF build attributes. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_MSP430ATTRIBUTEPARSER_H +#define LLVM_SUPPORT_MSP430ATTRIBUTEPARSER_H + +#include "llvm/Support/ELFAttributeParser.h" +#include "llvm/Support/MSP430Attributes.h" + +namespace llvm { +class MSP430AttributeParser : public ELFAttributeParser { + struct DisplayHandler { + MSP430Attrs::AttrType Attribute; + Error (MSP430AttributeParser::*Routine)(MSP430Attrs::AttrType); + }; + static const std::array DisplayRoutines; + + Error parseISA(MSP430Attrs::AttrType Tag); + Error parseCodeModel(MSP430Attrs::AttrType Tag); + Error parseDataModel(MSP430Attrs::AttrType Tag); + Error parseEnumSize(MSP430Attrs::AttrType Tag); + + Error handler(uint64_t Tag, bool &Handled) override; + +public: + MSP430AttributeParser(ScopedPrinter *SW) + : ELFAttributeParser(SW, MSP430Attrs::getMSP430AttributeTags(), + "mspabi") {} + MSP430AttributeParser() + : ELFAttributeParser(MSP430Attrs::getMSP430AttributeTags(), "mspabi") {} +}; +} // namespace llvm + +#endif diff --git a/llvm/include/llvm/Support/MSP430Attributes.h b/llvm/include/llvm/Support/MSP430Attributes.h new file mode 100644 --- /dev/null +++ b/llvm/include/llvm/Support/MSP430Attributes.h @@ -0,0 +1,44 @@ +//===-- MSP430Attributes.h - MSP430 Attributes ------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===-----------------------------------------------------------------------===// +/// +/// \file +/// This file contains enumerations for MSP430 ELF build attributes as +/// defined in the MSP430 ELF psABI specification. +/// +/// MSP430 ELF psABI specification +/// +/// https://www.ti.com/lit/pdf/slaa534 +/// +//===----------------------------------------------------------------------===// +#ifndef LLVM_SUPPORT_MSP430ATTRIBUTES_H +#define LLVM_SUPPORT_MSP430ATTRIBUTES_H + +#include "llvm/Support/ELFAttributes.h" + +namespace llvm { +namespace MSP430Attrs { + +const TagNameMap &getMSP430AttributeTags(); + +enum AttrType : unsigned { + // Attribute types in ELF/.MSP430.attributes. + TagISA = 4, + TagCodeModel = 6, + TagDataModel = 8, + TagEnumSize = 10 +}; + +enum ISA { ISAMSP430 = 1, ISAMSP430X = 2 }; +enum CodeModel { CMSmall = 1, CMLarge = 2 }; +enum DataModel { DMSmall = 1, DMLarge = 2, DMRestricted = 3 }; +enum EnumSize { ESSmall = 1, ESInteger = 2, ESDontCare = 3 }; + +} // namespace MSP430Attrs +} // namespace llvm + +#endif diff --git a/llvm/lib/Object/ELF.cpp b/llvm/lib/Object/ELF.cpp --- a/llvm/lib/Object/ELF.cpp +++ b/llvm/lib/Object/ELF.cpp @@ -246,6 +246,9 @@ STRINGIFY_ENUM_CASE(ELF, SHT_MIPS_ABIFLAGS); } break; + case ELF::EM_MSP430: + switch (Type) { STRINGIFY_ENUM_CASE(ELF, SHT_MSP430_ATTRIBUTES); } + break; case ELF::EM_RISCV: switch (Type) { STRINGIFY_ENUM_CASE(ELF, SHT_RISCV_ATTRIBUTES); } break; diff --git a/llvm/lib/ObjectYAML/ELFYAML.cpp b/llvm/lib/ObjectYAML/ELFYAML.cpp --- a/llvm/lib/ObjectYAML/ELFYAML.cpp +++ b/llvm/lib/ObjectYAML/ELFYAML.cpp @@ -655,6 +655,9 @@ case ELF::EM_RISCV: ECase(SHT_RISCV_ATTRIBUTES); break; + case ELF::EM_MSP430: + ECase(SHT_MSP430_ATTRIBUTES); + break; default: // Nothing to do. break; diff --git a/llvm/lib/Support/CMakeLists.txt b/llvm/lib/Support/CMakeLists.txt --- a/llvm/lib/Support/CMakeLists.txt +++ b/llvm/lib/Support/CMakeLists.txt @@ -171,6 +171,8 @@ MemoryBuffer.cpp MemoryBufferRef.cpp MD5.cpp + MSP430Attributes.cpp + MSP430AttributeParser.cpp NativeFormatting.cpp OptimizedStructLayout.cpp Optional.cpp diff --git a/llvm/lib/Support/MSP430AttributeParser.cpp b/llvm/lib/Support/MSP430AttributeParser.cpp new file mode 100644 --- /dev/null +++ b/llvm/lib/Support/MSP430AttributeParser.cpp @@ -0,0 +1,53 @@ +//===-- MSP430AttributeParser.cpp - MSP430 Attribute Parser ---------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "llvm/Support/MSP430AttributeParser.h" +#include "llvm/ADT/StringExtras.h" + +using namespace llvm; +using namespace llvm::MSP430Attrs; + +constexpr std::array + MSP430AttributeParser::DisplayRoutines{ + {{MSP430Attrs::TagISA, &MSP430AttributeParser::parseISA}, + {MSP430Attrs::TagCodeModel, &MSP430AttributeParser::parseCodeModel}, + {MSP430Attrs::TagDataModel, &MSP430AttributeParser::parseDataModel}, + {MSP430Attrs::TagEnumSize, &MSP430AttributeParser::parseEnumSize}}}; + +Error MSP430AttributeParser::parseISA(AttrType Tag) { + static const char *StringVals[] = {"None", "MSP430", "MSP430X"}; + return parseStringAttribute("ISA", Tag, makeArrayRef(StringVals)); +} + +Error MSP430AttributeParser::parseCodeModel(AttrType Tag) { + static const char *StringVals[] = {"None", "Small", "Large"}; + return parseStringAttribute("Code Model", Tag, makeArrayRef(StringVals)); +} + +Error MSP430AttributeParser::parseDataModel(AttrType Tag) { + static const char *StringVals[] = {"None", "Small", "Large", "Restricted"}; + return parseStringAttribute("Data Model", Tag, makeArrayRef(StringVals)); +} + +Error MSP430AttributeParser::parseEnumSize(AttrType Tag) { + static const char *StringVals[] = {"None", "Small", "Integer", "Don't Care"}; + return parseStringAttribute("Enum Size", Tag, makeArrayRef(StringVals)); +} + +Error MSP430AttributeParser::handler(uint64_t Tag, bool &Handled) { + Handled = false; + for (const DisplayHandler &Disp : DisplayRoutines) { + if (uint64_t(Disp.Attribute) != Tag) + continue; + if (Error E = (this->*Disp.Routine)(static_cast(Tag))) + return E; + Handled = true; + break; + } + return Error::success(); +} diff --git a/llvm/lib/Support/MSP430Attributes.cpp b/llvm/lib/Support/MSP430Attributes.cpp new file mode 100644 --- /dev/null +++ b/llvm/lib/Support/MSP430Attributes.cpp @@ -0,0 +1,22 @@ +//===-- MSP430Attributes.cpp - MSP430 Attributes --------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "llvm/Support/MSP430Attributes.h" + +using namespace llvm; +using namespace llvm::MSP430Attrs; + +static constexpr TagNameItem TagData[] = {{TagISA, "Tag_ISA"}, + {TagCodeModel, "Tag_Code_Model"}, + {TagDataModel, "Tag_Data_Model"}, + {TagEnumSize, "Tag_Enum_Size"}}; + +constexpr TagNameMap MSP430AttributeTags{TagData}; +const TagNameMap &llvm::MSP430Attrs::getMSP430AttributeTags() { + return MSP430AttributeTags; +} diff --git a/llvm/lib/Target/MSP430/MCTargetDesc/MSP430ELFStreamer.cpp b/llvm/lib/Target/MSP430/MCTargetDesc/MSP430ELFStreamer.cpp --- a/llvm/lib/Target/MSP430/MCTargetDesc/MSP430ELFStreamer.cpp +++ b/llvm/lib/Target/MSP430/MCTargetDesc/MSP430ELFStreamer.cpp @@ -17,8 +17,10 @@ #include "llvm/MC/MCSectionELF.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSubtargetInfo.h" +#include "llvm/Support/MSP430Attributes.h" using namespace llvm; +using namespace llvm::MSP430Attrs; namespace llvm { @@ -54,15 +56,14 @@ Streamer.emitInt8(1); // Attribute vector length. Streamer.emitInt32(11); - // OFBA_MSPABI_Tag_ISA(4) = 1, MSP430 - Streamer.emitInt8(4); - Streamer.emitInt8(1); - // OFBA_MSPABI_Tag_Code_Model(6) = 1, Small - Streamer.emitInt8(6); - Streamer.emitInt8(1); - // OFBA_MSPABI_Tag_Data_Model(8) = 1, Small - Streamer.emitInt8(8); - Streamer.emitInt8(1); + + Streamer.emitInt8(TagISA); + Streamer.emitInt8(STI.hasFeature(MSP430::FeatureX) ? ISAMSP430X : ISAMSP430); + Streamer.emitInt8(TagCodeModel); + Streamer.emitInt8(CMSmall); + Streamer.emitInt8(TagDataModel); + Streamer.emitInt8(DMSmall); + // Don't emit TagEnumSize, for full GCC compatibility. } MCELFStreamer &MSP430TargetELFStreamer::getStreamer() { diff --git a/llvm/test/CodeGen/MSP430/build-attrs.ll b/llvm/test/CodeGen/MSP430/build-attrs.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/MSP430/build-attrs.ll @@ -0,0 +1,41 @@ +; Test that the -mcpu= option sets the correct ELF build attributes. + +; RUN: llc -mtriple=msp430 -filetype=obj < %s \ +; RUN: | llvm-readelf -A - | FileCheck %s --check-prefixes COMMON,MSP430,SMALL +; RUN: llc -mtriple=msp430 -mcpu=generic -filetype=obj < %s \ +; RUN: | llvm-readelf -A - | FileCheck %s --check-prefixes COMMON,MSP430,SMALL +; RUN: llc -mtriple=msp430 -mcpu=msp430 -filetype=obj < %s \ +; RUN: | llvm-readelf -A - | FileCheck %s --check-prefixes COMMON,MSP430,SMALL +; RUN: llc -mtriple=msp430 -mcpu=msp430x -filetype=obj < %s \ +; RUN: | llvm-readelf -A - | FileCheck %s --check-prefixes COMMON,MSP430X,SMALL + +; COMMON: BuildAttributes { +; COMMON: FormatVersion: 0x41 +; COMMON: SectionLength: 22 +; COMMON: Vendor: mspabi +; COMMON: Tag: Tag_File (0x1) +; COMMON: Size: 11 + +; MSP430: Tag: 4 +; MSP430-NEXT: Value: 1 +; MSP430-NEXT: TagName: ISA +; MSP430-NEXT: Description: MSP430 + +; MSP430X: Tag: 4 +; MSP430X-NEXT: Value: 2 +; MSP430X-NEXT: TagName: ISA +; MSP430X-NEXT: Description: MSP430X + +; SMALL: Tag: 6 +; SMALL-NEXT: Value: 1 +; SMALL-NEXT: TagName: Code_Model +; SMALL-NEXT: Description: Small + +; SMALL: Tag: 8 +; SMALL-NEXT: Value: 1 +; SMALL-NEXT: TagName: Data_Model +; SMALL-NEXT: Description: Small + +define void @foo() { + ret void +} diff --git a/llvm/test/tools/llvm-readobj/ELF/MSP430/build-attributes.test b/llvm/test/tools/llvm-readobj/ELF/MSP430/build-attributes.test new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-readobj/ELF/MSP430/build-attributes.test @@ -0,0 +1,209 @@ +## Validate MSPABI ELF Build Attributes + +## The header of .MSP430.attributes can be specified with. +## ContentArray: [ 0x41, 0x16, 0x00, 0x00, 0x00, 0x6D, 0x73, 0x70, 0x61, 0x62, +## 0x69, 0x00, 0x01, 0x0b, 0x00, 0x00, 0x00, +## +## Following that are individual bytes describing the ISA, code model, data +## model and optionally enum size. +## +## If enum size is being tested, then the second byte (indicating the length of +## the section), and last 32-bit int (indicating the length of the +## subsection) of the header should be incremented by 2. This is to account for +## the additional bytes for the enum size tag and value. + +# HEADER: BuildAttributes { +# HEADER-NEXT: FormatVersion: 0x41 +# HEADER-NEXT: Section 1 { +# HEADER-NEXT: SectionLength: 22 +# HEADER-NEXT: Vendor: mspabi +# HEADER-NEXT: Tag: Tag_File (0x1) +# HEADER-NEXT: Size: 11 + +# ENUM_HEADER: BuildAttributes { +# ENUM_HEADER-NEXT: FormatVersion: 0x41 +# ENUM_HEADER-NEXT: Section 1 { +# ENUM_HEADER-NEXT: SectionLength: 24 +# ENUM_HEADER-NEXT: Vendor: mspabi +# ENUM_HEADER-NEXT: Tag: Tag_File (0x1) +# ENUM_HEADER-NEXT: Size: 13 + +# MSP430: Tag: 4 +# MSP430-NEXT: Value: 1 +# MSP430-NEXT: TagName: ISA +# MSP430-NEXT: Description: MSP430 + +# MSP430X: Tag: 4 +# MSP430X-NEXT: Value: 2 +# MSP430X-NEXT: TagName: ISA +# MSP430X-NEXT: Description: MSP430X + +# SMALL_CODE: Tag: 6 +# SMALL_CODE-NEXT: Value: 1 +# SMALL_CODE-NEXT: TagName: Code_Model +# SMALL_CODE-NEXT: Description: Small + +# LARGE_CODE: Tag: 6 +# LARGE_CODE-NEXT: Value: 2 +# LARGE_CODE-NEXT: TagName: Code_Model +# LARGE_CODE-NEXT: Description: Large + +# SMALL_DATA: Tag: 8 +# SMALL_DATA-NEXT: Value: 1 +# SMALL_DATA-NEXT: TagName: Data_Model +# SMALL_DATA-NEXT: Description: Small + +# LARGE_DATA: Tag: 8 +# LARGE_DATA-NEXT: Value: 2 +# LARGE_DATA-NEXT: TagName: Data_Model +# LARGE_DATA-NEXT: Description: Large + +# RESTRICTED_DATA: Tag: 8 +# RESTRICTED_DATA-NEXT: Value: 3 +# RESTRICTED_DATA-NEXT: TagName: Data_Model +# RESTRICTED_DATA-NEXT: Description: Restricted + +# SMALL_ENUM: Tag: 10 +# SMALL_ENUM-NEXT: Value: 1 +# SMALL_ENUM-NEXT: TagName: Enum_Size +# SMALL_ENUM-NEXT: Description: Small + +# INTEGER_ENUM: Tag: 10 +# INTEGER_ENUM-NEXT: Value: 2 +# INTEGER_ENUM-NEXT: TagName: Enum_Size +# INTEGER_ENUM-NEXT: Description: Integer + +# DONT_CARE_ENUM: Tag: 10 +# DONT_CARE_ENUM-NEXT: Value: 3 +# DONT_CARE_ENUM-NEXT: TagName: Enum_Size +# DONT_CARE_ENUM-NEXT: Description: Don't Care + +## MSP430 ISA +# RUN: yaml2obj --docnum=1 %s -o %t.o +# RUN: llvm-readobj -A %t.o | FileCheck %s --check-prefixes HEADER,MSP430,SMALL_CODE,SMALL_DATA +--- !ELF +FileHeader: + Class: ELFCLASS32 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_MSP430 +Sections: + - Name: .MSP430.attributes + Type: SHT_MSP430_ATTRIBUTES + ContentArray: [ 0x41, 0x16, 0x00, 0x00, 0x00, 0x6D, 0x73, 0x70, 0x61, 0x62, + 0x69, 0x00, 0x01, 0x0b, 0x00, 0x00, 0x00, + 0x04, 0x01, 0x06, 0x01, 0x08, 0x01 ] + + +## MSP430X ISA, Small Code Model, Small Data Model +# RUN: yaml2obj --docnum=2 %s -o %t.o +# RUN: llvm-readobj -A %t.o | FileCheck %s --check-prefixes HEADER,MSP430X,SMALL_CODE,SMALL_DATA +--- !ELF +FileHeader: + Class: ELFCLASS32 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_MSP430 +Sections: + - Name: .MSP430.attributes + Type: SHT_MSP430_ATTRIBUTES + ContentArray: [ 0x41, 0x16, 0x00, 0x00, 0x00, 0x6D, 0x73, 0x70, 0x61, 0x62, + 0x69, 0x00, 0x01, 0x0b, 0x00, 0x00, 0x00, + 0x04, 0x02, 0x06, 0x01, 0x08, 0x01 ] + +## MSP430X Large Code Model, Small Data Model +# RUN: yaml2obj --docnum=3 %s -o %t.o +# RUN: llvm-readobj -A %t.o | FileCheck %s --check-prefixes HEADER,MSP430X,LARGE_CODE,SMALL_DATA +--- !ELF +FileHeader: + Class: ELFCLASS32 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_MSP430 +Sections: + - Name: .MSP430.attributes + Type: SHT_MSP430_ATTRIBUTES + ContentArray: [ 0x41, 0x16, 0x00, 0x00, 0x00, 0x6D, 0x73, 0x70, 0x61, 0x62, + 0x69, 0x00, 0x01, 0x0b, 0x00, 0x00, 0x00, + 0x04, 0x02, 0x06, 0x02, 0x08, 0x01 ] + +## MSP430X Small Code Model, Large Data Model +# RUN: yaml2obj --docnum=4 %s -o %t.o +# RUN: llvm-readobj -A %t.o | FileCheck %s --check-prefixes HEADER,MSP430X,SMALL_CODE,LARGE_DATA +--- !ELF +FileHeader: + Class: ELFCLASS32 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_MSP430 +Sections: + - Name: .MSP430.attributes + Type: SHT_MSP430_ATTRIBUTES + ContentArray: [ 0x41, 0x16, 0x00, 0x00, 0x00, 0x6D, 0x73, 0x70, 0x61, 0x62, + 0x69, 0x00, 0x01, 0x0b, 0x00, 0x00, 0x00, + 0x04, 0x02, 0x06, 0x01, 0x08, 0x02 ] + +## MSP430X Small Code Model, Restricted Data Model +# RUN: yaml2obj --docnum=5 %s -o %t.o +# RUN: llvm-readobj -A %t.o | FileCheck %s --check-prefixes HEADER,MSP430X,SMALL_CODE,RESTRICTED_DATA +--- !ELF +FileHeader: + Class: ELFCLASS32 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_MSP430 +Sections: + - Name: .MSP430.attributes + Type: SHT_MSP430_ATTRIBUTES + ContentArray: [ 0x41, 0x16, 0x00, 0x00, 0x00, 0x6D, 0x73, 0x70, 0x61, 0x62, + 0x69, 0x00, 0x01, 0x0b, 0x00, 0x00, 0x00, + 0x04, 0x02, 0x06, 0x01, 0x08, 0x03 ] + +## MSP430X Small Code Model, Small Data Model, Small Enums +# RUN: yaml2obj --docnum=6 %s -o %t.o +# RUN: llvm-readobj -A %t.o | FileCheck %s --check-prefixes ENUM_HEADER,MSP430X,SMALL_CODE,SMALL_DATA,SMALL_ENUM +--- !ELF +FileHeader: + Class: ELFCLASS32 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_MSP430 +Sections: + - Name: .MSP430.attributes + Type: SHT_MSP430_ATTRIBUTES + ContentArray: [ 0x41, 0x18, 0x00, 0x00, 0x00, 0x6D, 0x73, 0x70, 0x61, 0x62, + 0x69, 0x00, 0x01, 0x0d, 0x00, 0x00, 0x00, + 0x04, 0x02, 0x06, 0x01, 0x08, 0x01, 0x0a, 0x01 ] + +## MSP430X Small Code Model, Small Data Model, Integer Enums +# RUN: yaml2obj --docnum=7 %s -o %t.o +# RUN: llvm-readobj -A %t.o | FileCheck %s --check-prefixes ENUM_HEADER,MSP430X,SMALL_CODE,SMALL_DATA,INTEGER_ENUM +--- !ELF +FileHeader: + Class: ELFCLASS32 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_MSP430 +Sections: + - Name: .MSP430.attributes + Type: SHT_MSP430_ATTRIBUTES + ContentArray: [ 0x41, 0x18, 0x00, 0x00, 0x00, 0x6D, 0x73, 0x70, 0x61, 0x62, + 0x69, 0x00, 0x01, 0x0d, 0x00, 0x00, 0x00, + 0x04, 0x02, 0x06, 0x01, 0x08, 0x01, 0x0a, 0x02 ] + + +## MSP430X Small Code Model, Small Data Model, "Don't Care" Enums +# RUN: yaml2obj --docnum=8 %s -o %t.o +# RUN: llvm-readobj -A %t.o | FileCheck %s --check-prefixes ENUM_HEADER,MSP430X,SMALL_CODE,SMALL_DATA,DONT_CARE_ENUM +--- !ELF +FileHeader: + Class: ELFCLASS32 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_MSP430 +Sections: + - Name: .MSP430.attributes + Type: SHT_MSP430_ATTRIBUTES + ContentArray: [ 0x41, 0x18, 0x00, 0x00, 0x00, 0x6D, 0x73, 0x70, 0x61, 0x62, + 0x69, 0x00, 0x01, 0x0d, 0x00, 0x00, 0x00, + 0x04, 0x02, 0x06, 0x01, 0x08, 0x01, 0x0a, 0x03 ] diff --git a/llvm/test/tools/llvm-readobj/ELF/MSP430/lit.local.cfg b/llvm/test/tools/llvm-readobj/ELF/MSP430/lit.local.cfg new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-readobj/ELF/MSP430/lit.local.cfg @@ -0,0 +1,2 @@ +if not 'MSP430' in config.root.targets: + config.unsupported = True diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -49,6 +49,8 @@ #include "llvm/Support/FormatVariadic.h" #include "llvm/Support/FormattedStream.h" #include "llvm/Support/LEB128.h" +#include "llvm/Support/MSP430AttributeParser.h" +#include "llvm/Support/MSP430Attributes.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/MipsABIFlags.h" #include "llvm/Support/RISCVAttributeParser.h" @@ -2575,6 +2577,11 @@ reportUniqueWarning("attribute printing not implemented for big-endian " "RISC-V objects"); break; + case EM_MSP430: + printAttributes(ELF::SHT_MSP430_ATTRIBUTES, + std::make_unique(&W), + support::little); + break; case EM_MIPS: { printMipsABIFlags(); printMipsOptions();