SXXXXXXX_PyDownloadFwViaSRIO/_OLD/Vecchia_app/FpgaBeamMeUp/binaryverifier.cpp
2026-01-22 17:10:05 +01:00

244 lines
5.2 KiB
C++

#include "binaryverifier.h"
#include <QFile>
#include <stdio.h>
#include "elf32.h"
#include <string.h>
//++
typedef char g_sign_string16_t[16];
typedef char g_sign_string32_t[32];
typedef char g_sign_string64_t[64];
typedef char g_sign_string128_t[128];
typedef char g_sign_string256_t[256];
typedef char g_sign_string512_t[256];
typedef uint8_t g_sign_id_t[16]; /*exactly 8 chars*/
struct g_sign_static_data_t
{
g_sign_string16_t nickname;
g_sign_string16_t vstr;
g_sign_string32_t pn;
g_sign_string32_t fullname;
g_sign_string64_t info;
};
struct g_sign_static_t
{
g_sign_id_t marker_begin; /* '<<GS++>>' */
g_sign_id_t signversion;
g_sign_static_data_t data;
uint32_t dummy_signversion_align;
g_sign_id_t marker_end; /* '<<GS-->>' */
};
#define G_SIGN_STATIC_BEGIN(INAME_) const struct g_sign_static_t INAME_={ "<<GS+>>@!#!", "0.0",{
#define G_SIGN_STATIC_END }, 0, "<<GS->>@!#!"}
#define G_SIGN_STR_VER2(vmajor_, vminor_) #vmajor_ "." #vminor_
#define G_SIGN_STR_VER3(vmajor_, vminor_, vbrach_) #vmajor_ "." #vminor_ "." ##vbrach_
struct g_sign_extern_data_t
{
g_sign_string64_t fullname;
g_sign_string64_t filename;
g_sign_string16_t buildid;
g_sign_string64_t date;
g_sign_string64_t host;
g_sign_string64_t md5_hash_str;
g_sign_string16_t md5_hash_bin;
g_sign_string512_t cms_signature; /*from CMS, that is SVN or GIT or what else*/
g_sign_string512_t userinfo;
};
struct g_sign_extern_t
{
g_sign_id_t marker_begin; /* '((GS++))' */
g_sign_id_t signversion;
g_sign_extern_data_t data;
uint32_t dummy_signversion_align;
g_sign_id_t marker_end; /* '((GS--))' */
};
//--
class BinaryVerifier::Implementation
{
public:
QString errorString;
BinaryInfo info;
Implementation()
{
}
};
BinaryVerifier::BinaryVerifier():
p_(*new Implementation)
{
}
BinaryVerifier::~BinaryVerifier()
{
delete &p_;
}
BinaryInfo BinaryVerifier::info() const
{
return p_.info;
}
bool BinaryVerifier::verify(const QString &filename)
{
QFile f(filename);
bool ok=f.open(QIODevice::ReadOnly);
if (!ok)
{
p_.errorString=f.errorString();
return false;
}
QByteArray d=f.readAll();
return verify(d);
}
bool BinaryVerifier::verify(const QByteArray& d)
{
Elf32_Ehdr h;
qint64 r=d.size(); //f.read((char*)&h, sizeof h);
if (r<sizeof h)
{
p_.errorString="Reading header";
return false;
}
h=*(Elf32_Ehdr*)d.constData();
if (!((h.e_ident[0]==ELFMAG0) || (h.e_ident[1]==ELFMAG1) || (h.e_ident[2]==ELFMAG2) || (h.e_ident[3]==ELFMAG3)))
{
p_.info.m_ftm=BinaryInfo::Binary;
p_.info.m_fmtName="Binary";
//A Xilinx bitstream?
return true;
}
p_.info.m_ftm=BinaryInfo::ELF;
p_.info.m_fmtName="ELF";
if (h.e_ident[EI_DATA]!=ELFDATA2LSB)
{
p_.errorString="Big Endian";
return false;
}
if (h.e_ident[EI_CLASS]!=ELFCLASS32)
{
p_.errorString="64bits";
return false;
}
if (h.e_type!=ET_EXEC)
{
p_.errorString="not ELF EXEC";
return false;
}
switch(h.e_machine)
{
case EM_TI_C6000:
p_.info.m_arch=BinaryInfo::C6000;
p_.info.m_archName="C6000";
p_.info.m_pn="TMS320C6XXX";
p_.info.m_partType="XMC-DSP";
break;
case EM_ARM:
p_.info.m_arch=BinaryInfo::ARM;
p_.info.m_archName="ARM";
p_.info.m_partType="XMC-ZynQ(?)";
break;
default:
break;
}
//QByteArray d=f.readAll();
p_.info.m_hasInfo=false;
{
int spos=0;
int epos=0;
QString markerBegin("<<GS+>>");
QString markerEnd("<<GS->>");
int expected_size=sizeof(g_sign_static_t)-sizeof(g_sign_id_t);
do
{
spos=d.indexOf(markerBegin, spos+1);
epos=d.indexOf(markerEnd, spos);
int size=epos-spos;
if ((spos>=0) || (epos>spos))
{
if (size>=expected_size)
{
g_sign_static_t s=*reinterpret_cast<const g_sign_static_t*>(&(d.data()[spos]));
p_.info.m_hasInfo=true;
p_.info.m_name=s.data.fullname;
p_.info.m_usr=s.data.info;
p_.info.m_ibc=s.data.pn;
p_.info.m_version=s.data.vstr;
break;
}
}
} while(spos>=0);
}
{
int spos=0;
int epos=0;
QString markerBegin("<<GX+>>");
QString markerEnd("<<GX->>");
int expected_size=sizeof(g_sign_extern_t)-sizeof(g_sign_id_t);
do
{
spos=d.indexOf(markerBegin, spos+1);
epos=d.indexOf(markerEnd, spos);
int size=epos-spos;
if ((spos>=0) || (epos>spos))
{
if (size>=expected_size)
{
g_sign_extern_t s=*reinterpret_cast<const g_sign_extern_t*>(&(d.data()[spos]));
p_.info.m_hasInfo=true;
//p_.info.m_name=s.data.fullname;
p_.info.m_host=s.data.host;
p_.info.m_bid=s.data.buildid;
p_.info.m_md5=s.data.md5_hash_str;
//p_.info.m_usr=s.data.userinfo;
p_.info.m_date=s.data.date;
break;
}
}
} while(spos>=0);
}
return true;
}