Added global big and little endian support to the pattern parser

This commit is contained in:
WerWolv
2020-11-22 16:22:02 +01:00
parent 989eade5d7
commit 8297e22f10
6 changed files with 79 additions and 11 deletions

View File

@@ -5,8 +5,8 @@
namespace hex::lang {
Evaluator::Evaluator(prv::Provider* &provider) : m_provider(provider) {
Evaluator::Evaluator(prv::Provider* &provider, std::endian dataEndianess) : m_provider(provider), m_dataEndianess(dataEndianess) {
PatternData::setEndianess(dataEndianess);
}
std::pair<PatternData*, size_t> Evaluator::createStructPattern(ASTNodeVariableDecl *varDeclNode, u64 offset) {
@@ -23,8 +23,11 @@ namespace hex::lang {
u64 memberOffset = 0;
if (member->getPointerSize().has_value())
if (member->getPointerSize().has_value()) {
this->m_provider->read(offset + structSize, &memberOffset, member->getPointerSize().value());
memberOffset = hex::changeEndianess(memberOffset, member->getPointerSize().value(), this->m_dataEndianess);
}
else
memberOffset = offset + structSize;
@@ -52,6 +55,9 @@ namespace hex::lang {
if (prevMember->getPatternType() == PatternData::Type::Unsigned && prevMember->getName() == member->getArraySizeVariable()) {
u64 value = 0;
this->m_provider->read(prevMember->getOffset(), &value, prevMember->getSize());
value = hex::changeEndianess(value, prevMember->getSize(), this->m_dataEndianess);
arraySize = value;
}
}
@@ -100,8 +106,11 @@ namespace hex::lang {
u64 memberOffset = 0;
if (member->getPointerSize().has_value())
if (member->getPointerSize().has_value()) {
this->m_provider->read(offset + unionSize, &memberOffset, member->getPointerSize().value());
memberOffset = hex::changeEndianess(memberOffset, member->getPointerSize().value(), this->m_dataEndianess);
}
else
memberOffset = offset;
@@ -132,6 +141,9 @@ namespace hex::lang {
if (prevMember->getPatternType() == PatternData::Type::Unsigned && prevMember->getName() == member->getArraySizeVariable()) {
u64 value = 0;
this->m_provider->read(prevMember->getOffset(), &value, prevMember->getSize());
value = hex::changeEndianess(value, prevMember->getSize(), this->m_dataEndianess);
arraySize = value;
}
}

View File

@@ -172,6 +172,9 @@ namespace hex::lang {
this->addPragmaHandler("MIME", [](std::string value) {
return !std::all_of(value.begin(), value.end(), isspace) && !value.ends_with('\n') && !value.ends_with('\r');
});
this->addPragmaHandler("endian", [](std::string value) {
return value == "big" || value == "little" || value == "native";
});
}
}

View File

@@ -237,26 +237,38 @@ namespace hex {
}
void ViewPattern::parsePattern(char *buffer) {
hex::lang::Preprocessor preprocessor;
hex::lang::Lexer lexer;
hex::lang::Parser parser;
hex::lang::Validator validator;
hex::lang::Evaluator evaluator(this->m_dataProvider);
this->clearPatternData();
this->postEvent(Events::PatternChanged);
hex::lang::Preprocessor preprocessor;
std::endian dataEndianess = std::endian::native;
preprocessor.addPragmaHandler("endian", [&dataEndianess](std::string value) {
if (value == "big") {
dataEndianess = std::endian::big;
return true;
} else if (value == "little") {
dataEndianess = std::endian::little;
return true;
} else if (value == "native") {
dataEndianess = std::endian::native;
return true;
} else
return false;
});
preprocessor.addDefaultPragramHandlers();
auto [preprocessingResult, preprocesedCode] = preprocessor.preprocess(buffer);
if (preprocessingResult.failed())
return;
hex::lang::Lexer lexer;
auto [lexResult, tokens] = lexer.lex(preprocesedCode);
if (lexResult.failed()) {
return;
}
hex::lang::Parser parser;
auto [parseResult, ast] = parser.parse(tokens);
if (parseResult.failed()) {
return;
@@ -264,11 +276,13 @@ namespace hex {
hex::ScopeExit deleteAst([&ast]{ for(auto &node : ast) delete node; });
hex::lang::Validator validator;
auto validatorResult = validator.validate(ast);
if (!validatorResult) {
return;
}
hex::lang::Evaluator evaluator(this->m_dataProvider, dataEndianess);
auto [evaluateResult, patternData] = evaluator.evaluate(ast);
if (evaluateResult.failed()) {
return;