Skip to content

Commit

Permalink
[ARM] Enable objdump to construct triple for ARM
Browse files Browse the repository at this point in the history
Now that The ARMAttributeParser has been moved into the library,
it has been modified so that it can parse the attributes without
printing them and stores them in a map. ELFObjectFile now queries
the attributes to fill out the architecture details of a provided
triple for 'arm' and 'thumb' targets. llvm-objdump uses this new
functionality.

Differential Revision: https://reviews.llvm.org/D28281



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@291898 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
sparker-arm committed Jan 13, 2017
1 parent e2892e1 commit 6968dd2
Show file tree
Hide file tree
Showing 19 changed files with 681 additions and 56 deletions.
25 changes: 25 additions & 0 deletions include/llvm/Object/ELFObjectFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "llvm/Object/Error.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Object/SymbolicFile.h"
#include "llvm/Support/ARMAttributeParser.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ELF.h"
#include "llvm/Support/Endian.h"
Expand Down Expand Up @@ -72,6 +73,8 @@ class ELFObjectFileBase : public ObjectFile {
static inline bool classof(const Binary *v) { return v->isELF(); }

SubtargetFeatures getFeatures() const override;

void setARMSubArch(Triple &TheTriple) const override;
};

class ELFSectionRef : public SectionRef {
Expand Down Expand Up @@ -356,6 +359,28 @@ template <class ELFT> class ELFObjectFile : public ELFObjectFileBase {
return std::error_code();
}

std::error_code getBuildAttributes(ARMAttributeParser &Attributes) const override {
auto SectionsOrErr = EF.sections();
if (!SectionsOrErr)
return errorToErrorCode(SectionsOrErr.takeError());

for (const Elf_Shdr &Sec : *SectionsOrErr) {
if (Sec.sh_type == ELF::SHT_ARM_ATTRIBUTES) {
auto ErrorOrContents = EF.getSectionContents(&Sec);
if (!ErrorOrContents)
return errorToErrorCode(ErrorOrContents.takeError());

auto Contents = ErrorOrContents.get();
if (Contents[0] != ARMBuildAttrs::Format_Version || Contents.size() == 1)
return std::error_code();

Attributes.Parse(Contents, ELFT::TargetEndianness == support::little);
break;
}
}
return std::error_code();
}

const ELFFile<ELFT> *getELFFile() const { return &EF; }

bool isDyldType() const { return isDyldELFObject; }
Expand Down
8 changes: 8 additions & 0 deletions include/llvm/Object/ObjectFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
#include <cstring>

namespace llvm {
class ARMAttributeParser;

namespace object {

class ObjectFile;
Expand Down Expand Up @@ -265,13 +267,19 @@ class ObjectFile : public SymbolicFile {
virtual StringRef getFileFormatName() const = 0;
virtual /* Triple::ArchType */ unsigned getArch() const = 0;
virtual SubtargetFeatures getFeatures() const = 0;
virtual void setARMSubArch(Triple &TheTriple) const { }

/// Returns platform-specific object flags, if any.
virtual std::error_code getPlatformFlags(unsigned &Result) const {
Result = 0;
return object_error::invalid_file_type;
}

virtual std::error_code
getBuildAttributes(ARMAttributeParser &Attributes) const {
return std::error_code();
}

/// True if this is a relocatable object (.o/.obj).
virtual bool isRelocatableObject() const = 0;

Expand Down
20 changes: 17 additions & 3 deletions include/llvm/Support/ARMAttributeParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,15 @@
#include "ARMBuildAttributes.h"
#include "ScopedPrinter.h"

#include <map>

namespace llvm {
class StringRef;

class ARMAttributeParser {
ScopedPrinter &SW;
ScopedPrinter *SW;

std::map<unsigned, unsigned> Attributes;

struct DisplayHandler {
ARMBuildAttrs::AttrType Attribute;
Expand Down Expand Up @@ -115,9 +119,19 @@ class ARMAttributeParser {
SmallVectorImpl<uint8_t> &IndexList);
void ParseSubsection(const uint8_t *Data, uint32_t Length);
public:
ARMAttributeParser(ScopedPrinter &SW) : SW(SW) {}
ARMAttributeParser(ScopedPrinter *SW) : SW(SW) {}

ARMAttributeParser() : SW(nullptr) { }

void Parse(ArrayRef<uint8_t> Section, bool isLittle);

bool hasAttribute(unsigned Tag) const {
return Attributes.count(Tag);
}

void Parse(ArrayRef<uint8_t> Section);
unsigned getAttributeValue(unsigned Tag) const {
return Attributes.find(Tag)->second;
}
};

}
Expand Down
14 changes: 13 additions & 1 deletion include/llvm/Support/ARMBuildAttributes.h
Original file line number Diff line number Diff line change
Expand Up @@ -176,14 +176,25 @@ enum {
WCharWidth2Bytes = 2, // sizeof(wchar_t) == 2
WCharWidth4Bytes = 4, // sizeof(wchar_t) == 4

// Tag_ABI_align_needed, (=24), uleb128
Align8Byte = 1,
Align4Byte = 2,
AlignReserved = 3,

// Tag_ABI_align_needed, (=25), uleb128
AlignNotPreserved = 0,
AlignPreserve8Byte = 1,
AlignPreserveAll = 2,

// Tag_ABI_FP_denormal, (=20), uleb128
PositiveZero = 0,
IEEEDenormals = 1,
PreserveFPSign = 2, // sign when flushed-to-zero is preserved

// Tag_ABI_FP_number_model, (=23), uleb128
AllowIEEENormal = 1,
AllowRTABI = 2, // numbers, infinities, and one quiet NaN (see [RTABI])
AllowIEE754 = 3, // this code to use all the IEEE 754-defined FP encodings
AllowIEEE754 = 3, // this code to use all the IEEE 754-defined FP encodings

// Tag_ABI_enum_size, (=26), uleb128
EnumProhibited = 0, // The user prohibited the use of enums when building
Expand All @@ -208,6 +219,7 @@ enum {

// Tag_FP_16bit_format, (=38), uleb128
FP16FormatIEEE = 1,
FP16VFP3 = 2,

// Tag_MPextension_use, (=42), uleb128
AllowMP = 1, // Allow use of MP extensions
Expand Down
65 changes: 65 additions & 0 deletions lib/Object/ELFObjectFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,4 +122,69 @@ SubtargetFeatures ELFObjectFileBase::getFeatures() const {
}
}

// FIXME Encode from a tablegen description or target parser.
void ELFObjectFileBase::setARMSubArch(Triple &TheTriple) const {
if (TheTriple.getSubArch() != Triple::NoSubArch)
return;

ARMAttributeParser Attributes;
std::error_code EC = getBuildAttributes(Attributes);
if (EC)
return;

std::string Triple;
// Default to ARM, but use the triple if it's been set.
if (TheTriple.getArch() == Triple::thumb ||
TheTriple.getArch() == Triple::thumbeb)
Triple = "thumb";
else
Triple = "arm";

switch(Attributes.getAttributeValue(ARMBuildAttrs::CPU_arch)) {
case ARMBuildAttrs::v4:
Triple += "v4";
break;
case ARMBuildAttrs::v4T:
Triple += "v4t";
break;
case ARMBuildAttrs::v5T:
Triple += "v5t";
break;
case ARMBuildAttrs::v5TE:
Triple += "v5te";
break;
case ARMBuildAttrs::v5TEJ:
Triple += "v5tej";
break;
case ARMBuildAttrs::v6:
Triple += "v6";
break;
case ARMBuildAttrs::v6KZ:
Triple += "v6kz";
break;
case ARMBuildAttrs::v6T2:
Triple += "v6t2";
break;
case ARMBuildAttrs::v6K:
Triple += "v6k";
break;
case ARMBuildAttrs::v7:
Triple += "v7";
break;
case ARMBuildAttrs::v6_M:
Triple += "v6m";
break;
case ARMBuildAttrs::v6S_M:
Triple += "v6sm";
break;
case ARMBuildAttrs::v7E_M:
Triple += "v7em";
break;
}
if (!isLittleEndian())
Triple += "eb";

TheTriple.setArchName(Triple);
}

} // end namespace llvm
Loading

0 comments on commit 6968dd2

Please sign in to comment.