mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 04:02:41 +01:00
[ARM] Rewrite ARMAttributeParser
* Delete boilerplate * Change functions to return `Error` * Test parsing errors * Update callers of ARMAttributeParser::parse() to check the `Error` return value. Since this patch touches nearly everything in the file, I apply http://llvm.org/docs/Proposals/VariableNames.html and change variable names to lower case. Reviewed By: compnerd Differential Revision: https://reviews.llvm.org/D75015
This commit is contained in:
parent
bcae288a5c
commit
02300509f3
@ -380,7 +380,8 @@ protected:
|
||||
if (Contents[0] != ARMBuildAttrs::Format_Version || Contents.size() == 1)
|
||||
return Error::success();
|
||||
|
||||
Attributes.parse(Contents, ELFT::TargetEndianness);
|
||||
if (Error E = Attributes.parse(Contents, ELFT::TargetEndianness))
|
||||
return E;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,10 @@
|
||||
|
||||
#include "ARMBuildAttributes.h"
|
||||
#include "ScopedPrinter.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/Support/DataExtractor.h"
|
||||
#include "llvm/Support/Endian.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
@ -19,120 +22,76 @@ namespace llvm {
|
||||
class StringRef;
|
||||
|
||||
class ARMAttributeParser {
|
||||
ScopedPrinter *SW;
|
||||
ScopedPrinter *sw;
|
||||
|
||||
std::map<unsigned, unsigned> Attributes;
|
||||
std::map<unsigned, unsigned> attributes;
|
||||
DataExtractor de{ArrayRef<uint8_t>{}, true, 0};
|
||||
DataExtractor::Cursor cursor{0};
|
||||
|
||||
struct DisplayHandler {
|
||||
ARMBuildAttrs::AttrType Attribute;
|
||||
void (ARMAttributeParser::*Routine)(ARMBuildAttrs::AttrType,
|
||||
const uint8_t *, uint32_t &);
|
||||
ARMBuildAttrs::AttrType attribute;
|
||||
Error (ARMAttributeParser::*routine)(ARMBuildAttrs::AttrType);
|
||||
};
|
||||
static const DisplayHandler DisplayRoutines[];
|
||||
static const DisplayHandler displayRoutines[];
|
||||
|
||||
uint64_t ParseInteger(const uint8_t *Data, uint32_t &Offset);
|
||||
StringRef ParseString(const uint8_t *Data, uint32_t &Offset);
|
||||
Error parseAttributeList(uint32_t length);
|
||||
void parseIndexList(SmallVectorImpl<uint8_t> &indexList);
|
||||
Error parseSubsection(uint32_t length);
|
||||
Error parseStringAttribute(const char *name, ARMBuildAttrs::AttrType tag,
|
||||
const ArrayRef<const char *> array);
|
||||
void printAttribute(unsigned tag, unsigned value, StringRef valueDesc);
|
||||
|
||||
void IntegerAttribute(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
|
||||
uint32_t &Offset);
|
||||
void StringAttribute(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
|
||||
uint32_t &Offset);
|
||||
Error stringAttribute(ARMBuildAttrs::AttrType tag);
|
||||
|
||||
void PrintAttribute(unsigned Tag, unsigned Value, StringRef ValueDesc);
|
||||
Error CPU_arch(ARMBuildAttrs::AttrType tag);
|
||||
Error CPU_arch_profile(ARMBuildAttrs::AttrType tag);
|
||||
Error ARM_ISA_use(ARMBuildAttrs::AttrType tag);
|
||||
Error THUMB_ISA_use(ARMBuildAttrs::AttrType tag);
|
||||
Error FP_arch(ARMBuildAttrs::AttrType tag);
|
||||
Error WMMX_arch(ARMBuildAttrs::AttrType tag);
|
||||
Error Advanced_SIMD_arch(ARMBuildAttrs::AttrType tag);
|
||||
Error MVE_arch(ARMBuildAttrs::AttrType tag);
|
||||
Error PCS_config(ARMBuildAttrs::AttrType tag);
|
||||
Error ABI_PCS_R9_use(ARMBuildAttrs::AttrType tag);
|
||||
Error ABI_PCS_RW_data(ARMBuildAttrs::AttrType tag);
|
||||
Error ABI_PCS_RO_data(ARMBuildAttrs::AttrType tag);
|
||||
Error ABI_PCS_GOT_use(ARMBuildAttrs::AttrType tag);
|
||||
Error ABI_PCS_wchar_t(ARMBuildAttrs::AttrType tag);
|
||||
Error ABI_FP_rounding(ARMBuildAttrs::AttrType tag);
|
||||
Error ABI_FP_denormal(ARMBuildAttrs::AttrType tag);
|
||||
Error ABI_FP_exceptions(ARMBuildAttrs::AttrType tag);
|
||||
Error ABI_FP_user_exceptions(ARMBuildAttrs::AttrType tag);
|
||||
Error ABI_FP_number_model(ARMBuildAttrs::AttrType tag);
|
||||
Error ABI_align_needed(ARMBuildAttrs::AttrType tag);
|
||||
Error ABI_align_preserved(ARMBuildAttrs::AttrType tag);
|
||||
Error ABI_enum_size(ARMBuildAttrs::AttrType tag);
|
||||
Error ABI_HardFP_use(ARMBuildAttrs::AttrType tag);
|
||||
Error ABI_VFP_args(ARMBuildAttrs::AttrType tag);
|
||||
Error ABI_WMMX_args(ARMBuildAttrs::AttrType tag);
|
||||
Error ABI_optimization_goals(ARMBuildAttrs::AttrType tag);
|
||||
Error ABI_FP_optimization_goals(ARMBuildAttrs::AttrType tag);
|
||||
Error compatibility(ARMBuildAttrs::AttrType tag);
|
||||
Error CPU_unaligned_access(ARMBuildAttrs::AttrType tag);
|
||||
Error FP_HP_extension(ARMBuildAttrs::AttrType tag);
|
||||
Error ABI_FP_16bit_format(ARMBuildAttrs::AttrType tag);
|
||||
Error MPextension_use(ARMBuildAttrs::AttrType tag);
|
||||
Error DIV_use(ARMBuildAttrs::AttrType tag);
|
||||
Error DSP_extension(ARMBuildAttrs::AttrType tag);
|
||||
Error T2EE_use(ARMBuildAttrs::AttrType tag);
|
||||
Error Virtualization_use(ARMBuildAttrs::AttrType tag);
|
||||
Error nodefaults(ARMBuildAttrs::AttrType tag);
|
||||
|
||||
void CPU_arch(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
|
||||
uint32_t &Offset);
|
||||
void CPU_arch_profile(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
|
||||
uint32_t &Offset);
|
||||
void ARM_ISA_use(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
|
||||
uint32_t &Offset);
|
||||
void THUMB_ISA_use(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
|
||||
uint32_t &Offset);
|
||||
void FP_arch(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
|
||||
uint32_t &Offset);
|
||||
void WMMX_arch(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
|
||||
uint32_t &Offset);
|
||||
void Advanced_SIMD_arch(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
|
||||
uint32_t &Offset);
|
||||
void MVE_arch(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
|
||||
uint32_t &Offset);
|
||||
void PCS_config(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
|
||||
uint32_t &Offset);
|
||||
void ABI_PCS_R9_use(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
|
||||
uint32_t &Offset);
|
||||
void ABI_PCS_RW_data(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
|
||||
uint32_t &Offset);
|
||||
void ABI_PCS_RO_data(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
|
||||
uint32_t &Offset);
|
||||
void ABI_PCS_GOT_use(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
|
||||
uint32_t &Offset);
|
||||
void ABI_PCS_wchar_t(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
|
||||
uint32_t &Offset);
|
||||
void ABI_FP_rounding(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
|
||||
uint32_t &Offset);
|
||||
void ABI_FP_denormal(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
|
||||
uint32_t &Offset);
|
||||
void ABI_FP_exceptions(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
|
||||
uint32_t &Offset);
|
||||
void ABI_FP_user_exceptions(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
|
||||
uint32_t &Offset);
|
||||
void ABI_FP_number_model(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
|
||||
uint32_t &Offset);
|
||||
void ABI_align_needed(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
|
||||
uint32_t &Offset);
|
||||
void ABI_align_preserved(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
|
||||
uint32_t &Offset);
|
||||
void ABI_enum_size(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
|
||||
uint32_t &Offset);
|
||||
void ABI_HardFP_use(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
|
||||
uint32_t &Offset);
|
||||
void ABI_VFP_args(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
|
||||
uint32_t &Offset);
|
||||
void ABI_WMMX_args(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
|
||||
uint32_t &Offset);
|
||||
void ABI_optimization_goals(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
|
||||
uint32_t &Offset);
|
||||
void ABI_FP_optimization_goals(ARMBuildAttrs::AttrType Tag,
|
||||
const uint8_t *Data, uint32_t &Offset);
|
||||
void compatibility(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
|
||||
uint32_t &Offset);
|
||||
void CPU_unaligned_access(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
|
||||
uint32_t &Offset);
|
||||
void FP_HP_extension(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
|
||||
uint32_t &Offset);
|
||||
void ABI_FP_16bit_format(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
|
||||
uint32_t &Offset);
|
||||
void MPextension_use(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
|
||||
uint32_t &Offset);
|
||||
void DIV_use(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
|
||||
uint32_t &Offset);
|
||||
void DSP_extension(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
|
||||
uint32_t &Offset);
|
||||
void T2EE_use(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
|
||||
uint32_t &Offset);
|
||||
void Virtualization_use(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
|
||||
uint32_t &Offset);
|
||||
void nodefaults(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
|
||||
uint32_t &Offset);
|
||||
|
||||
void ParseAttributeList(const uint8_t *Data, uint32_t &Offset,
|
||||
uint32_t Length);
|
||||
void ParseIndexList(const uint8_t *Data, uint32_t &Offset,
|
||||
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) {}
|
||||
~ARMAttributeParser() { static_cast<void>(!cursor.takeError()); }
|
||||
|
||||
ARMAttributeParser() : SW(nullptr) { }
|
||||
Error parse(ArrayRef<uint8_t> section, support::endianness endian);
|
||||
|
||||
void parse(ArrayRef<uint8_t> Section, support::endianness E);
|
||||
bool hasAttribute(unsigned tag) const { return attributes.count(tag); }
|
||||
|
||||
bool hasAttribute(unsigned Tag) const {
|
||||
return Attributes.count(Tag);
|
||||
}
|
||||
|
||||
unsigned getAttributeValue(unsigned Tag) const {
|
||||
return Attributes.find(Tag)->second;
|
||||
unsigned getAttributeValue(unsigned tag) const {
|
||||
return attributes.find(tag)->second;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -197,6 +197,8 @@ public:
|
||||
/// is out of bounds, a default-initialized StringRef will be returned.
|
||||
StringRef getBytes(uint64_t *OffsetPtr, uint64_t Length) const;
|
||||
|
||||
StringRef getCStrRef(Cursor &C) const { return getCStrRef(&C.Offset); }
|
||||
|
||||
/// Extract an unsigned integer of size \a byte_size from \a
|
||||
/// *offset_ptr.
|
||||
///
|
||||
|
@ -157,8 +157,10 @@ SubtargetFeatures ELFObjectFileBase::getMIPSFeatures() const {
|
||||
SubtargetFeatures ELFObjectFileBase::getARMFeatures() const {
|
||||
SubtargetFeatures Features;
|
||||
ARMAttributeParser Attributes;
|
||||
if (Error E = getBuildAttributes(Attributes))
|
||||
if (Error E = getBuildAttributes(Attributes)) {
|
||||
consumeError(std::move(E));
|
||||
return SubtargetFeatures();
|
||||
}
|
||||
|
||||
// both ARMv7-M and R have to support thumb hardware div
|
||||
bool isV7 = false;
|
||||
@ -305,8 +307,11 @@ void ELFObjectFileBase::setARMSubArch(Triple &TheTriple) const {
|
||||
return;
|
||||
|
||||
ARMAttributeParser Attributes;
|
||||
if (Error E = getBuildAttributes(Attributes))
|
||||
if (Error E = getBuildAttributes(Attributes)) {
|
||||
// TODO Propagate Error.
|
||||
consumeError(std::move(E));
|
||||
return;
|
||||
}
|
||||
|
||||
std::string Triple;
|
||||
// Default to ARM, but use the triple if it's been set.
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -2690,7 +2690,9 @@ template <> void ELFDumper<ELF32LE>::printAttributes() {
|
||||
if (Contents.size() == 1)
|
||||
continue;
|
||||
|
||||
ARMAttributeParser(&W).parse(Contents, support::little);
|
||||
// TODO: Print error and delete the redundant FormatVersion check above.
|
||||
if (Error E = ARMAttributeParser(&W).parse(Contents, support::little))
|
||||
consumeError(std::move(E));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -34,16 +34,55 @@ bool testBuildAttr(unsigned Tag, unsigned Value,
|
||||
reinterpret_cast<const uint8_t*>(OS.str().c_str()), OS.str().size());
|
||||
|
||||
ARMAttributeParser Parser;
|
||||
Parser.parse(Bytes, support::little);
|
||||
cantFail(Parser.parse(Bytes, support::little));
|
||||
|
||||
return (Parser.hasAttribute(ExpectedTag) &&
|
||||
Parser.getAttributeValue(ExpectedTag) == ExpectedValue);
|
||||
}
|
||||
|
||||
void testParseError(ArrayRef<uint8_t> bytes, const char *msg) {
|
||||
ARMAttributeParser parser;
|
||||
Error e = parser.parse(bytes, support::little);
|
||||
EXPECT_STREQ(toString(std::move(e)).c_str(), msg);
|
||||
}
|
||||
|
||||
bool testTagString(unsigned Tag, const char *name) {
|
||||
return ARMBuildAttrs::AttrTypeAsString(Tag).str() == name;
|
||||
}
|
||||
|
||||
TEST(ARMAttributeParser, UnrecognizedFormatVersion) {
|
||||
static const uint8_t bytes[] = {1};
|
||||
testParseError(bytes, "unrecognized format-version: 0x1");
|
||||
}
|
||||
|
||||
TEST(ARMAttributeParser, InvalidSubsectionLength) {
|
||||
static const uint8_t bytes[] = {'A', 3, 0, 0, 0};
|
||||
testParseError(bytes, "invalid subsection length 3 at offset 0x1");
|
||||
}
|
||||
|
||||
TEST(ARMAttributeParser, UnrecognizedVendorName) {
|
||||
static const uint8_t bytes[] = {'A', 7, 0, 0, 0, 'x', 'y', 0};
|
||||
testParseError(bytes, "unrecognized vendor-name: xy");
|
||||
}
|
||||
|
||||
TEST(ARMAttributeParser, InvalidAttributeSize) {
|
||||
static const uint8_t bytes[] = {'A', 15, 0, 0, 0, 'a', 'e', 'a',
|
||||
'b', 'i', 0, 4, 4, 0, 0, 0};
|
||||
testParseError(bytes, "invalid attribute size 4 at offset 0xb");
|
||||
}
|
||||
|
||||
TEST(ARMAttributeParser, UnrecognizedTag) {
|
||||
static const uint8_t bytes[] = {'A', 15, 0, 0, 0, 'a', 'e', 'a',
|
||||
'b', 'i', 0, 4, 5, 0, 0, 0};
|
||||
testParseError(bytes, "unrecognized tag 0x4 at offset 0xb");
|
||||
}
|
||||
|
||||
TEST(ARMAttributeParser, UnknownCPU_arch) {
|
||||
static const uint8_t bytes[] = {'A', 15, 0, 0, 0, 'a', 'e', 'a', 'b',
|
||||
'i', 0, 1, 7, 0, 0, 0, 6, 22};
|
||||
testParseError(bytes, "unknown CPU_arch value: 22");
|
||||
}
|
||||
|
||||
TEST(CPUArchBuildAttr, testBuildAttr) {
|
||||
EXPECT_TRUE(testTagString(6, "Tag_CPU_arch"));
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user