diff --git a/.github/.keep b/.github/.keep new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/.github/.keep @@ -0,0 +1 @@ + diff --git a/buildtest.yml b/.github/workflows/buildtest.yml similarity index 95% rename from buildtest.yml rename to .github/workflows/buildtest.yml index eae1c09..9edb42e 100644 --- a/buildtest.yml +++ b/.github/workflows/buildtest.yml @@ -22,7 +22,6 @@ defaults: jobs: buildtest: - if: (github.actor == 'RonoveRaum') || (github.run_number < 16) strategy: fail-fast: false matrix: diff --git a/dump_disasm.txt b/.github/workflows/dump_disasm.txt similarity index 100% rename from dump_disasm.txt rename to .github/workflows/dump_disasm.txt diff --git a/read_disasm.txt b/.github/workflows/read_disasm.txt similarity index 100% rename from read_disasm.txt rename to .github/workflows/read_disasm.txt diff --git a/test.cc b/.github/workflows/test.cc similarity index 100% rename from test.cc rename to .github/workflows/test.cc diff --git a/test_elf b/.github/workflows/test_elf similarity index 100% rename from test_elf rename to .github/workflows/test_elf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea97818 --- /dev/null +++ b/.gitignore @@ -0,0 +1,445 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ +[Ll]ogs/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ + +# Others +.vscode/* +__build/ +.idea/ + + +# ------------------------------ C++ .gitignore ------------------------------ +# Prerequisites +*.d + +# Compiled Object files +*.slo +*.lo +*.o +*.obj + +# Precompiled Headers +*.gch +*.pch + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Fortran module files +*.mod +*.smod + +# Compiled Static libraries +*.lai +*.la +*.a +*.lib + +# Executables +*.exe +*.out +*.app + +# ------------------------------ C .gitignore ------------------------------ +# Prerequisites +*.d + +# Object files +*.o +*.ko +*.obj +*.elf + +# Linker output +*.ilk +*.map +*.exp + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + +# Debug files +*.dSYM/ +*.su +*.idb +*.pdb + +# Kernel Module Compile Results +*.mod* +*.cmd +.tmp_versions/ +modules.order +Module.symvers +Mkfile.old +dkms.conf + diff --git a/README.md b/README.md index 3e2d429..0baec3a 100644 --- a/README.md +++ b/README.md @@ -5,100 +5,60 @@ ### Compile complited (build log, can be empty): ``` -/home/runner/work/spbsu-comp-arch22-lab3-Matewl/spbsu-comp-arch22-lab3-Matewl/main.cpp:526:30: warning: object backing the pointer will be destroyed at the end of the full-expression [-Wdangling-gsl] - const char *rd = reg(rg).c_str(); - ^~~~~~~ -/home/runner/work/spbsu-comp-arch22-lab3-Matewl/spbsu-comp-arch22-lab3-Matewl/main.cpp:531:30: warning: object backing the pointer will be destroyed at the end of the full-expression [-Wdangling-gsl] - const char *rd = reg(rg).c_str(); - ^~~~~~~ -/home/runner/work/spbsu-comp-arch22-lab3-Matewl/spbsu-comp-arch22-lab3-Matewl/main.cpp:554:31: warning: object backing the pointer will be destroyed at the end of the full-expression [-Wdangling-gsl] - const char *rs1 = reg(rgs1).c_str(); - ^~~~~~~~~ -/home/runner/work/spbsu-comp-arch22-lab3-Matewl/spbsu-comp-arch22-lab3-Matewl/main.cpp:555:30: warning: object backing the pointer will be destroyed at the end of the full-expression [-Wdangling-gsl] - const char *rd = reg(rgd).c_str(); - ^~~~~~~~ -/home/runner/work/spbsu-comp-arch22-lab3-Matewl/spbsu-comp-arch22-lab3-Matewl/main.cpp:565:31: warning: object backing the pointer will be destroyed at the end of the full-expression [-Wdangling-gsl] - const char *rs1 = reg(rgs1).c_str(); - ^~~~~~~~~ -/home/runner/work/spbsu-comp-arch22-lab3-Matewl/spbsu-comp-arch22-lab3-Matewl/main.cpp:566:31: warning: object backing the pointer will be destroyed at the end of the full-expression [-Wdangling-gsl] - const char *rs2 = reg(rgs2).c_str(); - ^~~~~~~~~ -/home/runner/work/spbsu-comp-arch22-lab3-Matewl/spbsu-comp-arch22-lab3-Matewl/main.cpp:585:31: warning: object backing the pointer will be destroyed at the end of the full-expression [-Wdangling-gsl] - const char *rs1 = reg(rgs1).c_str(); - ^~~~~~~~~ -/home/runner/work/spbsu-comp-arch22-lab3-Matewl/spbsu-comp-arch22-lab3-Matewl/main.cpp:586:31: warning: object backing the pointer will be destroyed at the end of the full-expression [-Wdangling-gsl] - const char *rs2 = reg(rgs2).c_str(); - ^~~~~~~~~ -/home/runner/work/spbsu-comp-arch22-lab3-Matewl/spbsu-comp-arch22-lab3-Matewl/main.cpp:604:31: warning: object backing the pointer will be destroyed at the end of the full-expression [-Wdangling-gsl] - const char *rs1 = reg(rgs1).c_str(); - ^~~~~~~~~ -/home/runner/work/spbsu-comp-arch22-lab3-Matewl/spbsu-comp-arch22-lab3-Matewl/main.cpp:605:30: warning: object backing the pointer will be destroyed at the end of the full-expression [-Wdangling-gsl] - const char *rd = reg(rgd).c_str(); - ^~~~~~~~ -/home/runner/work/spbsu-comp-arch22-lab3-Matewl/spbsu-comp-arch22-lab3-Matewl/main.cpp:618:31: warning: object backing the pointer will be destroyed at the end of the full-expression [-Wdangling-gsl] - const char *rs1 = reg(rgs1).c_str(); - ^~~~~~~~~ -/home/runner/work/spbsu-comp-arch22-lab3-Matewl/spbsu-comp-arch22-lab3-Matewl/main.cpp:619:30: warning: object backing the pointer will be destroyed at the end of the full-expression [-Wdangling-gsl] - const char *rd = reg(rgd).c_str(); - ^~~~~~~~ -/home/runner/work/spbsu-comp-arch22-lab3-Matewl/spbsu-comp-arch22-lab3-Matewl/main.cpp:620:31: warning: object backing the pointer will be destroyed at the end of the full-expression [-Wdangling-gsl] - const char *rs2 = reg(rgs2).c_str(); - ^~~~~~~~~ -13 warnings generated. ``` ### Output: ``` -10074
: +00010074
: 10074: ff010113 addi sp, sp, -16 -10078: 00112623 sw ra, 0(ra) +10078: 00112623 sw ra, 12(sp) 1007c: 030000ef jal ra, 0x100ac -10080: 00c12083 lw ra, 12(ra) -10084: 00000513 addi a0, a0, 0 +10080: 00c12083 lw ra, 12(sp) +10084: 00000513 addi a0, zero, 0 10088: 01010113 addi sp, sp, 16 -1008c: 00008067 jalr zero, 0(zero) +1008c: 00008067 jalr zero, 0(ra) 10090: 00000013 addi zero, zero, 0 10094: 00100137 lui sp,0x100 10098: fddff0ef jal ra, 0x10074
-1009c: 00050593 addi a1, a1, 0 -100a0: 00a00893 addi a7, a7, 10 +1009c: 00050593 addi a1, a0, 0 +100a0: 00a00893 addi a7, zero, 10 100a4: 0ff0000f unknown_instruction 100a8: 00000073 ecall -100ac : +000100ac : 100ac: 00011f37 lui t5,0x11 -100b0: 124f0513 addi a0, a0, 292 +100b0: 124f0513 addi a0, t5, 292 100b4: 65450513 addi a0, a0, 1620 100b8: 124f0f13 addi t5, t5, 292 -100bc: e4018293 addi t0, t0, -448 -100c0: fd018f93 addi t6, t6, -48 -100c4: 02800e93 addi t4, t4, 40 -100c8 : -100c8: fec50e13 addi t3, t3, -20 -100cc: 000f0313 addi t1, t1, 0 -100d0: 000f8893 addi a7, a7, 0 -100d4: 00000813 addi a6, a6, 0 -100d8 : -100d8: 00088693 addi a3, a3, 0 -100dc: 000e0793 addi a5, a5, 0 -100e0: 00000613 addi a2, a2, 0 -100e4 : -100e4: 00078703 lb a4, 0(a4) -100e8: 00069583 lh a1, 0(a1) +100bc: e4018293 addi t0, gp, -448 +100c0: fd018f93 addi t6, gp, -48 +100c4: 02800e93 addi t4, zero, 40 +000100c8 : +100c8: fec50e13 addi t3, a0, -20 +100cc: 000f0313 addi t1, t5, 0 +100d0: 000f8893 addi a7, t6, 0 +100d4: 00000813 addi a6, zero, 0 +000100d8 : +100d8: 00088693 addi a3, a7, 0 +100dc: 000e0793 addi a5, t3, 0 +100e0: 00000613 addi a2, zero, 0 +000100e4 : +100e4: 00078703 lb a4, 0(a5) +100e8: 00069583 lh a1, 0(a3) 100ec: 00178793 addi a5, a5, 1 100f0: 02868693 addi a3, a3, 40 -100f4: 02b70733 mul a1, a1, a1 -100f8: 00e60633 add a4, a4, a4 -100fc: fea794e3 bne a0, a0, 0x100e4 -10100: 00c32023 sw a2, 0(a2) +100f4: 02b70733 mul a4, a4, a1 +100f8: 00e60633 add a2, a2, a4 +100fc: fea794e3 bne a5, a0, 0x100e4 +10100: 00c32023 sw a2, 0(t1) 10104: 00280813 addi a6, a6, 2 10108: 00430313 addi t1, t1, 4 1010c: 00288893 addi a7, a7, 2 -10110: fdd814e3 bne t4, t4, 0x100d8 +10110: fdd814e3 bne a6, t4, 0x100d8 10114: 050f0f13 addi t5, t5, 80 -10118: 01478513 addi a0, a0, 20 -1011c: fa5f16e3 bne t0, t0, 0x100c8 -10120: 00008067 jalr zero, 0(zero) +10118: 01478513 addi a0, a5, 20 +1011c: fa5f16e3 bne t5, t0, 0x100c8 +10120: 00008067 jalr zero, 0(ra) Symbol Value Size Type Bind Vis Index Name [ 0] 0x0 0 NOTYPE LOCAL DEFAULT UNDEF diff --git a/main.cpp b/main.cpp index a9b66e4..003ff0c 100644 --- a/main.cpp +++ b/main.cpp @@ -1,653 +1,713 @@ -#include -#include -#include -#include -#include - -using namespace std; - - -struct ELF_32_header { - unsigned char e_ident[16]; - uint16_t type;// - uint16_t machine;// - uint32_t version;// - uint32_t entry; // - uint32_t phoff; // offset to program header - uint32_t shoff; //offset to section header - uint32_t flags; // 0 - uint16_t ehsize; // size of elf header - uint16_t phentsize; // size of one program header - uint16_t phnum; //count of program header - uint16_t shentsize; //size of one section header - uint16_t shnum; //count of header - uint16_t shstrndx; //index of shstrheader -}; - -struct ELF_32_SECTION_HEADER { - uint32_t sh_name; // index of name = offset of name in shstrtable - uint32_t sh_type; // type of section - uint32_t sh_flags; // flags - uint32_t sh_addr; // - uint32_t sh_offset; // offset of own section - uint32_t sh_size; // size of own section - uint32_t sh_link; // ?? - uint32_t sh_info; // ?? - uint32_t sh_addralign; // выравнивание данной секции - uint32_t sh_entsize; // хранит размер одной записи, если секция хранит таблицу из записей фиксированного размера -}; - -struct ELF_32_SYMTAB { - unsigned int st_name; - unsigned int st_value; - unsigned int st_size; - unsigned char st_info; - unsigned char st_other; - unsigned short st_shndx; -}; - -ELF_32_header elf_header; -vector elf_section_header; -vector symtab; -string TEXT = ".text"; -string SYMTAB = ".symtab"; -FILE *f; -FILE *g; -int offset_symtab; -int offset_text; -ELF_32_SECTION_HEADER symtab_header; -ELF_32_SECTION_HEADER text_header; -int count_of_symbols; -map val_name; -map addr_name; -int addr; -int L_index = 0; - - -int header_of_need_section(string *name) { - int index = 0; - int offset_ofstr = int(elf_section_header[elf_header.shstrndx].sh_offset); - fseek(f, offset_ofstr, SEEK_SET); - string cur; - int current_index = 0; - while (true) { - char c; - fread(&c, sizeof(char), 1, f); - if (c) - cur.push_back(c); - else { - if (*name == cur) { - break; - } else { - cur.clear(); - current_index = index; - } - } - index++; - } - current_index++; - return current_index; -} - -int offset_of_needsection(int index) { - for (int i = 0; i < elf_header.shnum; i++) { - if (elf_section_header[i].sh_name == index) - return int(elf_section_header[i].sh_offset); - } - return 0; -} - - -string get_name(int offset) { - string s = ".strtab"; - int offset_strtab = offset_of_needsection(header_of_need_section(&s)); - fseek(f, offset_strtab + offset, SEEK_SET); - string returned; - while (true) { - char c; - fread(&c, sizeof(char), 1, f); - if (c) - returned.push_back(c); - else { - break; - } - } - - return returned; -} - -string get_command(int n) { - if ((n & 0b1111111) == 55) - return "lui"; - if ((n & 0b1111111) == 23) - return "auipc"; - if ((n & 0b1111111) == 111) - return "jal"; - if (((n & 0b1111111) == 103) && (((n & 0b111000000000000) >> 12) == 0)) - return "jalr"; - if (((n & 0b1111111) == 99) && (((n & 0b111000000000000) >> 12) == 0)) - return "bne"; - if (((n & 0b1111111) == 99) && (((n & 0b111000000000000) >> 12) == 1)) - return "bne"; - if (((n & 0b1111111) == 99) && (((n & 0b111000000000000) >> 12) == 4)) - return "blt"; - if (((n & 0b1111111) == 99) && (((n & 0b111000000000000) >> 12) == 5)) - return "bge"; - if (((n & 0b1111111) == 99) && (((n & 0b111000000000000) >> 12) == 6)) - return "bltu"; - if (((n & 0b1111111) == 99) && (((n & 0b111000000000000) >> 12) == 7)) - return "bgeu"; - if (((n & 0b1111111) == 3) && (((n & 0b111000000000000) >> 12) == 0)) - return "lb"; - if (((n & 0b1111111) == 3) && (((n & 0b111000000000000) >> 12) == 1)) - return "lh"; - if (((n & 0b1111111) == 3) && (((n & 0b111000000000000) >> 12) == 2)) - return "lw"; - if (((n & 0b1111111) == 3) && (((n & 0b111000000000000) >> 12) == 4)) - return "lbu"; - if (((n & 0b1111111) == 3) && (((n & 0b111000000000000) >> 12) == 5)) - return "lhu"; - if (((n & 0b1111111) == 35) && (((n & 0b111000000000000) >> 12) == 0)) - return "sb"; - if (((n & 0b1111111) == 35) && (((n & 0b111000000000000) >> 12) == 1)) - return "sh"; - if (((n & 0b1111111) == 35) && (((n & 0b111000000000000) >> 12) == 2)) - return "sw"; - if (((n & 0b1111111) == 19) && (((n & 0b111000000000000) >> 12) == 0)) - return "addi"; - if (((n & 0b1111111) == 19) && (((n & 0b111000000000000) >> 12) == 2)) - return "slti"; - if (((n & 0b1111111) == 19) && (((n & 0b111000000000000) >> 12) == 3)) - return "sltiu"; - if (((n & 0b1111111) == 19) && (((n & 0b111000000000000) >> 12) == 4)) - return "xori"; - if (((n & 0b1111111) == 19) && (((n & 0b111000000000000) >> 12) == 6)) - return "ori"; - if (((n & 0b1111111) == 19) && (((n & 0b111000000000000) >> 12) == 7)) - return "andi"; - if (((n & 0b1111111) == 19) && (((n & 0b111000000000000) >> 12) == 1) && - (((n & 0b11111110000000000000000000000000) >> 25) == 0)) - return "slli"; - if (((n & 0b1111111) == 19) && (((n & 0b111000000000000) >> 12) == 5) && - (((n & 0b11111110000000000000000000000000) >> 25) == 0)) - return "srli"; - if (((n & 0b1111111) == 19) && (((n & 0b111000000000000) >> 12) == 5) && - (((n & 0b11111110000000000000000000000000) >> 25) == 32)) - return "srai"; - if (((n & 0b1111111) == 51) && (((n & 0b111000000000000) >> 12) == 0) && - (((n & 0b11111110000000000000000000000000) >> 25) == 0)) - return "add"; - if (((n & 0b1111111) == 51) && (((n & 0b111000000000000) >> 12) == 0) && - (((n & 0b11111110000000000000000000000000) >> 25) == 32)) - return "sub"; - if (((n & 0b1111111) == 51) && (((n & 0b111000000000000) >> 12) == 1) && - (((n & 0b11111110000000000000000000000000) >> 25) == 0)) - return "sll"; - if (((n & 0b1111111) == 51) && (((n & 0b111000000000000) >> 12) == 2) && - (((n & 0b11111110000000000000000000000000) >> 25) == 0)) - return "slt"; - if (((n & 0b1111111) == 51) && (((n & 0b111000000000000) >> 12) == 3) && - (((n & 0b11111110000000000000000000000000) >> 25) == 0)) - return "sltu"; - if (((n & 0b1111111) == 51) && (((n & 0b111000000000000) >> 12) == 4) && - (((n & 0b11111110000000000000000000000000) >> 25) == 0)) - return "xor"; - if (((n & 0b1111111) == 51) && (((n & 0b111000000000000) >> 12) == 5) && - (((n & 0b11111110000000000000000000000000) >> 25) == 0)) - return "srl"; - if (((n & 0b1111111) == 51) && (((n & 0b111000000000000) >> 12) == 5) && - (((n & 0b11111110000000000000000000000000) >> 25) == 32)) - return "sra"; - if (((n & 0b1111111) == 51) && (((n & 0b111000000000000) >> 12) == 6) && - (((n & 0b11111110000000000000000000000000) >> 25) == 0)) - return "or"; - if (((n & 0b1111111) == 51) && (((n & 0b111000000000000) >> 12) == 7) && - (((n & 0b11111110000000000000000000000000) >> 25) == 0)) - return "and"; - if ((n & 0b1111111) == 115 && (((n & 0b11111111111100000000000000000000) >> 20) == 0)) - return "ecall"; - if ((n & 0b1111111) == 115 && (((n & 0b11111111111100000000000000000000) >> 20) == 1)) - return "ebreak"; - if (((n & 0b1111111) == 51) && (((n & 0b111000000000000) >> 12) == 0) && - (((n & 0b11111110000000000000000000000000) >> 25) == 1)) - return "mul"; - if (((n & 0b1111111) == 51) && (((n & 0b111000000000000) >> 12) == 1) && - (((n & 0b11111110000000000000000000000000) >> 25) == 1)) - return "mulh"; - if (((n & 0b1111111) == 51) && (((n & 0b111000000000000) >> 12) == 2) && - (((n & 0b11111110000000000000000000000000) >> 25) == 1)) - return "mulhsu"; - if (((n & 0b1111111) == 51) && (((n & 0b111000000000000) >> 12) == 3) && - (((n & 0b11111110000000000000000000000000) >> 25) == 1)) - return "mulhu"; - if (((n & 0b1111111) == 51) && (((n & 0b111000000000000) >> 12) == 4) && - (((n & 0b11111110000000000000000000000000) >> 25) == 1)) - return "div"; - if (((n & 0b1111111) == 51) && (((n & 0b111000000000000) >> 12) == 5) && - (((n & 0b11111110000000000000000000000000) >> 25) == 1)) - return "divu"; - if (((n & 0b1111111) == 51) && (((n & 0b111000000000000) >> 12) == 6) && - (((n & 0b11111110000000000000000000000000) >> 25) == 1)) - return "rem"; - if (((n & 0b1111111) == 51) && (((n & 0b111000000000000) >> 12) == 7) && - (((n & 0b11111110000000000000000000000000) >> 25) == 1)) - return "remu"; - - return "unknown_instruction"; -} - -string reg(int n) { - if (n == 0) - return "zero"; - if (n == 1) - return "ra"; - if (n == 2) - return "sp"; - if (n == 3) - return "gp"; - if (n == 4) - return "tp"; - if (n == 5) - return "t0"; - if (n == 6) - return "t1"; - if (n == 7) - return "t2"; - if (n == 8) - return "fp"; - if (n == 9) - return "s1"; - if (n == 10) - return "a0"; - if (n == 11) - return "a1"; - if (n == 12) - return "a2"; - if (n == 13) - return "a3"; - if (n == 14) - return "a4"; - if (n == 15) - return "a5"; - if (n == 16) - return "a6"; - if (n == 17) - return "a7"; - if (n == 18) - return "s2"; - if (n == 19) - return "s3"; - if (n == 20) - return "s4"; - if (n == 21) - return "s5"; - if (n == 22) - return "s6"; - if (n == 23) - return "s7"; - if (n == 24) - return "s8"; - if (n == 25) - return "s9"; - if (n == 26) - return "s10"; - if (n == 27) - return "s11"; - if (n == 28) - return "t3"; - if (n == 29) - return "t4"; - if (n == 30) - return "t5"; - if (n == 31) - return "t6"; - return "lkl"; -} - -string bind(int n) { - n = (n) >> 4; - if (n == 0) - return "LOCAL"; - if (n == 1) - return "GLOBAL"; - if (n == 2) - return "WEAK"; - if (n == 10) - return "LOOS"; - if (n == 12) - return "HIOS"; - if (n == 13) - return "LOPROC"; - if (n == 15) - return "HIPROC"; - return ""; -} - -string index(int n) { - if (n == 0) - return "UNDEF"; - if (n == 65280) - return "LORESERVE"; - if (n == 65281) - return "AFTER"; - if (n == 65311) - return "HIPROC"; - if (n == 65312) - return "LOOS"; - if (n == 65343) - return "HIOS"; - if (n == 65521) - return "ABS"; - if (n == 65522) - return "COMMON"; - if (n == 65535) - return "XINDEX"; - - return to_string(n); -} - -string vis(int n) { - if (n == 0) - return "DEFAULT"; - if (n == 1) - return "INTERNAL"; - if (n == 2) - return "HIDDEN"; - if (n == 3) - return "PROTECTED"; - if (n == 4) - return "EXPORTED"; - if (n == 5) - return "SINGLETON"; - if (n == 6) - return "ELIMINATE"; - return ""; -} - -string type(int n) { - n = (n) & 0xf; - if (n == 0) - return "NOTYPE"; - if (n == 1) - return "OBJECT"; - if (n == 2) - return "FUNC"; - if (n == 3) - return "SECTION"; - if (n == 4) - return "FILE"; - if (n == 5) - return "COMMON"; - if (n == 6) - return "TLS"; - if (n == 10) - return "LOOS"; - if (n == 12) - return "HIOS"; - if (n == 13) - return "LOPROC"; - if (n == 15) - return "HIPROC"; - return ""; -} - -int add_to_two(int n, int size) { - if (n < pow(2, size - 1)) - return n; - return int(n - pow(2, size)); - -} - -int main(int argc, char *argv[]) { - - f = fopen(argv[1], "r"); - g = fopen(argv[2], "w"); - - - fread(&elf_header, sizeof(ELF_32_header), 1, f); - - //читаем заголовки - fseek(f, int(elf_header.shoff), SEEK_SET); - - for (int i = 0; i < elf_header.shnum; i++) { - ELF_32_SECTION_HEADER cur{}; - fread(&cur, sizeof(ELF_32_SECTION_HEADER), 1, f); - elf_section_header.push_back(cur); - } - - for (int i = 0; i < elf_header.shnum; i++) { - if (elf_section_header[i].sh_name == header_of_need_section(&SYMTAB)) { - symtab_header = elf_section_header[i]; - break; - } - } - for (int i = 0; i < elf_header.shnum; i++) { - if (elf_section_header[i].sh_name == header_of_need_section(&TEXT)) { - text_header = elf_section_header[i]; - break; - } - } - addr = int(text_header.sh_addr); - count_of_symbols = int(symtab_header.sh_size) / int(sizeof(ELF_32_SYMTAB)); - offset_symtab = offset_of_needsection(header_of_need_section(&SYMTAB)); - - fseek(f, offset_symtab, SEEK_SET); - - for (int i = 0; i < count_of_symbols; i++) { - ELF_32_SYMTAB cur{}; - fseek(f, offset_symtab + 16 * i, SEEK_SET); - fread(&cur, sizeof(ELF_32_SYMTAB), 1, f); - symtab.push_back(cur); - string name = get_name(int(symtab[i].st_name)); - string type_ = type(cur.st_info); - int value = int(symtab[i].st_value); - if (type_ == "OBJECT" || type_ == "FUNC") { - val_name[value] = name; - } - } - - offset_text = offset_of_needsection(header_of_need_section(&TEXT)); - fseek(f, offset_text, SEEK_SET); - - for (int i = 0; i < text_header.sh_size / 4; i++) { - fseek(f, offset_text + i * 4, SEEK_SET); - int cur = 0; - fread(&cur, 4, 1, f); - string command = get_command(cur); - int imm = 0; - if (command == "jal") { - uint32_t immp1, immp2, immp3, immp4; - immp1 = ((cur & (uint32_t) 0b10000000000000000000000000000000) >> 31) << 1; - immp2 = ((cur & (uint32_t) 0b00000000000011111111000000000000) >> 12) << 1; - immp3 = ((cur & (uint32_t) 0b00000000000100000000000000000000) >> 20) << 1; - immp4 = ((cur & (uint32_t) 0b01111111111000000000000000000000) >> 21) << 1; - imm = int(immp4 + immp3 * 1024 + immp2 * 2048 + immp1 * pow(2, 19)); - - imm = add_to_two(int(imm), 20); - imm += addr; - imm = add_to_two(int(imm), 20); - - if (val_name.find(int(imm)) != val_name.end()) - addr_name[int(imm)] = val_name[int(imm)]; - else { - string s = "L"; - s += (to_string(L_index)); - addr_name[int(imm)] = s; - L_index++; - } - - } else if (command == "beq" || command == "bne" - || command == "blt" || command == "bgeu" - || command == "bge" || command == "bltu") { //1 111111 01010 01111 001 0100 1 - - - uint32_t immp1, immp2, immp3, immp4; - immp1 = ((cur & (uint32_t) 0b10000000000000000000000000000000) >> 31) << 1; - immp2 = ((cur & (uint32_t) 0b00000000000000000000000010000000) >> 7) << 1; - immp3 = ((cur & (uint32_t) 0b01111110000000000000000000000000) >> 25) << 1; - immp4 = ((cur & (uint32_t) 0b00000000000000000000111100000000) >> 8) << 1; - imm = immp1 * pow(2, 11) + immp2 * pow(2, 10) + immp3 * 16 + immp4; - imm = add_to_two(int(imm), 12); - imm += addr; - imm = add_to_two(int(imm), 12); - if (val_name.find(int(imm)) != val_name.end()) - addr_name[int(imm)] = val_name[int(imm)]; - else { - string s = "L"; - s += (to_string(L_index)); - addr_name[int(imm)] = s; - L_index++; - } - - } - - addr += 4; - - } - - addr = int(text_header.sh_addr); - - for (int i = 0; i < text_header.sh_size / 4; i++) { - - if (addr_name.find(int(addr)) != addr_name.end()) { - const char *adname = addr_name[addr].c_str(); - fprintf(g, "%x <%s>:\n", addr, adname); - } - - fseek(f, offset_text + i * 4, SEEK_SET); - int cur = 0; - fread(&cur, 4, 1, f); - string command = get_command(cur); - const char *com = command.c_str(); - fprintf(g, "%x:\t", addr); - - if (command == "lui" || command == "auipc") { - int rg = (cur & 0b111110000000) >> 7; - const char *rd = reg(rg).c_str(); - int imm = add_to_two(int((cur & 0b11111111111111111111000000000000) >> 12), 20); - fprintf(g, "%08x\t%7s\t%s,0x%x\n", cur, com, rd, imm); - } else if (command == "jal") { - int rg = (cur & 0b111110000000) >> 7; - const char *rd = reg(rg).c_str(); - - uint32_t immp1, immp2, immp3, immp4, imm; - immp1 = ((cur & (uint32_t) 0b10000000000000000000000000000000) >> 31) << 1; - immp2 = ((cur & (uint32_t) 0b00000000000011111111000000000000) >> 12) << 1; - immp3 = ((cur & (uint32_t) 0b00000000000100000000000000000000) >> 20) << 1; - immp4 = ((cur & (uint32_t) 0b01111111111000000000000000000000) >> 21) << 1; - imm = int(immp4 + immp3 * 1024 + immp2 * 2048 + immp1 * pow(2, 19)); - - imm = add_to_two(int(imm), 20); - imm += addr; - imm = add_to_two(int(imm), 20); - - const char *lable = addr_name[int(imm)].c_str(); - - fprintf(g, "%08x\t%7s\t%s, 0x%x <%s>\n", cur, com, rd, imm, lable); - - } else if (command == "jalr" || command == "lb" || command == "lh" - || command == "lbu" || command == "lw" - || command == "lhu") { - int rgd = (cur & 0b111110000000) >> 7; - int rgs1 = (cur & 0b11111000000000000000) >> 15; - string imm = to_string(add_to_two(int((cur & 0b11111111111100000000000000000000) >> 20), 12)); - const char *rs1 = reg(rgs1).c_str(); - const char *rd = reg(rgd).c_str(); - const char *imm1 = imm.c_str(); - - fprintf(g, "%08x\t%7s\t%s, %s(%s)\n", cur, com, rd, imm1, rs1); - } else if (command == "beq" || command == "bne" - || command == "blt" || command == "bgeu" - || command == "bge" || command == "bltu") { //1 111111 01010 01111 001 0100 1 - - int rgs2 = (cur & 0b1111100000000000000000000) >> 20; - int rgs1 = (cur & 0b11111000000000000000) >> 15; - const char *rs1 = reg(rgs1).c_str(); - const char *rs2 = reg(rgs2).c_str(); - - uint32_t immp1, immp2, immp3, immp4, imm; - immp1 = ((cur & (uint32_t) 0b10000000000000000000000000000000) >> 31) << 1; - immp2 = ((cur & (uint32_t) 0b00000000000000000000000010000000) >> 7) << 1; - immp3 = ((cur & (uint32_t) 0b01111110000000000000000000000000) >> 25) << 1; - immp4 = ((cur & (uint32_t) 0b00000000000000000000111100000000) >> 8) << 1; - imm = immp1 * pow(2, 11) + immp2 * pow(2, 10) + immp3 * 16 + immp4; - imm = add_to_two(int(imm), 12); - imm += addr; - imm = add_to_two(int(imm), 12); - - const char *lable = addr_name[int(imm)].c_str(); - - fprintf(g, "%08x\t%7s\t%s, %s, 0x%x <%s>\n", cur, com, rs1, rs2, imm, lable); - - } else if (command == "sh" || command == "sb" || command == "sw") { - int rgs2 = (cur & 0b1111100000000000000000000) >> 20; - int rgs1 = (cur & 0b11111000000000000000) >> 15; - const char *rs1 = reg(rgs1).c_str(); - const char *rs2 = reg(rgs2).c_str(); - uint32_t immp1, immp2, imm; - immp1 = ((cur & (uint32_t) 0b11111110000000000000000000000000) >> 31); - immp2 = ((cur & (uint32_t) 0b00000000000000000000111110000000) >> 12); - - imm = immp1 * 32 + immp2; - - fprintf(g, "%08x\t%7s\t%s, %d(%s)\n", cur, com, rs2, imm, rs1); - - - } else if (command == "slti" || command == "addi" - || command == "xori" || command == "sltiu" - || command == "ori" || command == "andi" || command == "slli" || command == "srli" || - command == "srai") { - int rgd = (cur & 0b111110000000) >> 7; - int rgs1 = (cur & 0b11111000000000000000) >> 15; - string imm = to_string(add_to_two(int((cur & 0b11111111111100000000000000000000) >> 20), 12)); - - const char *rs1 = reg(rgs1).c_str(); - const char *rd = reg(rgd).c_str(); - const char *imm1 = imm.c_str(); - fprintf(g, "%08x\t%7s\t%s, %s, %s\n", cur, com, rd, rs1, imm1); - } else if (command == "add" || command == "sub" || command == "sll" || - command == "slt" || command == "sltu" || command == "xor" || - command == "srl" || command == "sra" || command == "or" || command == "and" || - command == "mul" || command == "mulh" || command == "mulhsu" || - command == "divu" || command == "div" || command == "mulhu" || - command == "rem" || command == "remu") { - - int rgs2 = (cur & 0b1111100000000000000000000) >> 20; - int rgd = (cur & 0b111110000000) >> 7; - int rgs1 = (cur & 0b11111000000000000000) >> 15; - const char *rs1 = reg(rgs1).c_str(); - const char *rd = reg(rgd).c_str(); - const char *rs2 = reg(rgs2).c_str(); - fprintf(g, "%08x\t%7s\t%s, %s, %s\n", cur, com, rd, rs1, rs2); - - } else if (command == "ecall" || command == "ebreak") { - fprintf(g, "%08x\t%7s\n", cur, com); - } else { - fprintf(g, "%08x\tunknown_instruction\n", cur); - } - addr += 4; - } - fprintf(g, "\nSymbol Value Size Type \tBind Vis Index Name\n"); - for (int i = 0; i < count_of_symbols; i++) { - ELF_32_SYMTAB cur{}; - fseek(f, offset_symtab + sizeof(ELF_32_SYMTAB) * i, SEEK_SET); - fread(&cur, sizeof(ELF_32_SYMTAB), 1, f); - string sname = get_name(int(symtab[i].st_name)); - const char *name = sname.c_str(); - string stype = type(cur.st_info); - const char *type_ = stype.c_str(); - string sbind = bind(cur.st_info); - const char *bind_ = sbind.c_str(); - string svis = vis(cur.st_other); - const char *vis_ = svis.c_str(); - string sindex = index(cur.st_shndx); - const char *index_ = sindex.c_str(); - - int value = int(symtab[i].st_value); - int size = int(symtab[i].st_size); - fprintf(g, "[%4i] 0x%-15X %5i %-8s %-8s %-8s %6s %s\n", i, value, size, type_, bind_, vis_, index_, name); - } - - fclose(f); - fclose(g); -} +#include +#include +#include +#include +#include + +using namespace std; + + +struct ELF_32_header { + unsigned char e_ident[16]; + uint16_t type;// + uint16_t machine;// + uint32_t version;// + uint32_t entry; // + uint32_t phoff; // offset to program header + uint32_t shoff; //offset to section header + uint32_t flags; // 0 + uint16_t ehsize; // size of elf header + uint16_t phentsize; // size of one program header + uint16_t phnum; //count of program header + uint16_t shentsize; //size of one section header + uint16_t shnum; //count of header + uint16_t shstrndx; //index of shstrheader +}; + +struct ELF_32_SECTION_HEADER { + uint32_t sh_name; // index of name = offset of name in shstrtable + uint32_t sh_type; // type of section + uint32_t sh_flags; // flags + uint32_t sh_addr; // + uint32_t sh_offset; // offset of own section + uint32_t sh_size; // size of own section + uint32_t sh_link; // ?? + uint32_t sh_info; // ?? + uint32_t sh_addralign; // выравнивание данной секции + uint32_t sh_entsize; // хранит размер одной записи, если секция хранит таблицу из записей фиксированного размера +}; + +struct ELF_32_SYMTAB { + unsigned int st_name; + unsigned int st_value; + unsigned int st_size; + unsigned char st_info; + unsigned char st_other; + unsigned short st_shndx; +}; + +ELF_32_header elf_header; +vector elf_section_header; +vector symtab; +string TEXT = ".text"; +string SYMTAB = ".symtab"; +FILE *f; +FILE *g; +int offset_symtab; +int offset_text; +ELF_32_SECTION_HEADER symtab_header; +ELF_32_SECTION_HEADER text_header; +int count_of_symbols; +map val_name; +map addr_name; +int addr; +int L_index = 0; + + +int header_of_need_section(string *name) { + int index = 0; + int offset_ofstr = int(elf_section_header[elf_header.shstrndx].sh_offset); + fseek(f, offset_ofstr, SEEK_SET); + string cur; + int current_index = 0; + while (true) { + char c; + fread(&c, sizeof(char), 1, f); + if (c) + cur.push_back(c); + else { + if (*name == cur) { + break; + } else { + cur.clear(); + current_index = index; + } + } + index++; + } + current_index++; + return current_index; +} + +int offset_of_needsection(int index) { + for (int i = 0; i < elf_header.shnum; i++) { + if (elf_section_header[i].sh_name == index) + return int(elf_section_header[i].sh_offset); + } + return 0; +} + + +string get_name(int offset) { + string s = ".strtab"; + int offset_strtab = offset_of_needsection(header_of_need_section(&s)); + fseek(f, offset_strtab + offset, SEEK_SET); + string returned; + while (true) { + char c; + fread(&c, sizeof(char), 1, f); + if (c) + returned.push_back(c); + else { + break; + } + } + + return returned; +} + +string get_command(int n) { + if ((n & 0b1111111) == 55) + return "lui"; + if ((n & 0b1111111) == 23) + return "auipc"; + if ((n & 0b1111111) == 111) + return "jal"; + if (((n & 0b1111111) == 103) && (((n & 0b111000000000000) >> 12) == 0)) + return "jalr"; + if (((n & 0b1111111) == 99) && (((n & 0b111000000000000) >> 12) == 0)) + return "bne"; + if (((n & 0b1111111) == 99) && (((n & 0b111000000000000) >> 12) == 1)) + return "bne"; + if (((n & 0b1111111) == 99) && (((n & 0b111000000000000) >> 12) == 4)) + return "blt"; + if (((n & 0b1111111) == 99) && (((n & 0b111000000000000) >> 12) == 5)) + return "bge"; + if (((n & 0b1111111) == 99) && (((n & 0b111000000000000) >> 12) == 6)) + return "bltu"; + if (((n & 0b1111111) == 99) && (((n & 0b111000000000000) >> 12) == 7)) + return "bgeu"; + if (((n & 0b1111111) == 3) && (((n & 0b111000000000000) >> 12) == 0)) + return "lb"; + if (((n & 0b1111111) == 3) && (((n & 0b111000000000000) >> 12) == 1)) + return "lh"; + if (((n & 0b1111111) == 3) && (((n & 0b111000000000000) >> 12) == 2)) + return "lw"; + if (((n & 0b1111111) == 3) && (((n & 0b111000000000000) >> 12) == 4)) + return "lbu"; + if (((n & 0b1111111) == 3) && (((n & 0b111000000000000) >> 12) == 5)) + return "lhu"; + if (((n & 0b1111111) == 35) && (((n & 0b111000000000000) >> 12) == 0)) + return "sb"; + if (((n & 0b1111111) == 35) && (((n & 0b111000000000000) >> 12) == 1)) + return "sh"; + if (((n & 0b1111111) == 35) && (((n & 0b111000000000000) >> 12) == 2)) + return "sw"; + if (((n & 0b1111111) == 19) && (((n & 0b111000000000000) >> 12) == 0)) + return "addi"; + if (((n & 0b1111111) == 19) && (((n & 0b111000000000000) >> 12) == 2)) + return "slti"; + if (((n & 0b1111111) == 19) && (((n & 0b111000000000000) >> 12) == 3)) + return "sltiu"; + if (((n & 0b1111111) == 19) && (((n & 0b111000000000000) >> 12) == 4)) + return "xori"; + if (((n & 0b1111111) == 19) && (((n & 0b111000000000000) >> 12) == 6)) + return "ori"; + if (((n & 0b1111111) == 19) && (((n & 0b111000000000000) >> 12) == 7)) + return "andi"; + if (((n & 0b1111111) == 19) && (((n & 0b111000000000000) >> 12) == 1) && + (((n & 0b11111110000000000000000000000000) >> 25) == 0)) + return "slli"; + if (((n & 0b1111111) == 19) && (((n & 0b111000000000000) >> 12) == 5) && + (((n & 0b11111110000000000000000000000000) >> 25) == 0)) + return "srli"; + if (((n & 0b1111111) == 19) && (((n & 0b111000000000000) >> 12) == 5) && + (((n & 0b11111110000000000000000000000000) >> 25) == 32)) + return "srai"; + if (((n & 0b1111111) == 51) && (((n & 0b111000000000000) >> 12) == 0) && + (((n & 0b11111110000000000000000000000000) >> 25) == 0)) + return "add"; + if (((n & 0b1111111) == 51) && (((n & 0b111000000000000) >> 12) == 0) && + (((n & 0b11111110000000000000000000000000) >> 25) == 32)) + return "sub"; + if (((n & 0b1111111) == 51) && (((n & 0b111000000000000) >> 12) == 1) && + (((n & 0b11111110000000000000000000000000) >> 25) == 0)) + return "sll"; + if (((n & 0b1111111) == 51) && (((n & 0b111000000000000) >> 12) == 2) && + (((n & 0b11111110000000000000000000000000) >> 25) == 0)) + return "slt"; + if (((n & 0b1111111) == 51) && (((n & 0b111000000000000) >> 12) == 3) && + (((n & 0b11111110000000000000000000000000) >> 25) == 0)) + return "sltu"; + if (((n & 0b1111111) == 51) && (((n & 0b111000000000000) >> 12) == 4) && + (((n & 0b11111110000000000000000000000000) >> 25) == 0)) + return "xor"; + if (((n & 0b1111111) == 51) && (((n & 0b111000000000000) >> 12) == 5) && + (((n & 0b11111110000000000000000000000000) >> 25) == 0)) + return "srl"; + if (((n & 0b1111111) == 51) && (((n & 0b111000000000000) >> 12) == 5) && + (((n & 0b11111110000000000000000000000000) >> 25) == 32)) + return "sra"; + if (((n & 0b1111111) == 51) && (((n & 0b111000000000000) >> 12) == 6) && + (((n & 0b11111110000000000000000000000000) >> 25) == 0)) + return "or"; + if (((n & 0b1111111) == 51) && (((n & 0b111000000000000) >> 12) == 7) && + (((n & 0b11111110000000000000000000000000) >> 25) == 0)) + return "and"; + if ((n & 0b1111111) == 115 && (((n & 0b11111111111100000000000000000000) >> 20) == 0)) + return "ecall"; + if ((n & 0b1111111) == 115 && (((n & 0b11111111111100000000000000000000) >> 20) == 1)) + return "ebreak"; + if (((n & 0b1111111) == 51) && (((n & 0b111000000000000) >> 12) == 0) && + (((n & 0b11111110000000000000000000000000) >> 25) == 1)) + return "mul"; + if (((n & 0b1111111) == 51) && (((n & 0b111000000000000) >> 12) == 1) && + (((n & 0b11111110000000000000000000000000) >> 25) == 1)) + return "mulh"; + if (((n & 0b1111111) == 51) && (((n & 0b111000000000000) >> 12) == 2) && + (((n & 0b11111110000000000000000000000000) >> 25) == 1)) + return "mulhsu"; + if (((n & 0b1111111) == 51) && (((n & 0b111000000000000) >> 12) == 3) && + (((n & 0b11111110000000000000000000000000) >> 25) == 1)) + return "mulhu"; + if (((n & 0b1111111) == 51) && (((n & 0b111000000000000) >> 12) == 4) && + (((n & 0b11111110000000000000000000000000) >> 25) == 1)) + return "div"; + if (((n & 0b1111111) == 51) && (((n & 0b111000000000000) >> 12) == 5) && + (((n & 0b11111110000000000000000000000000) >> 25) == 1)) + return "divu"; + if (((n & 0b1111111) == 51) && (((n & 0b111000000000000) >> 12) == 6) && + (((n & 0b11111110000000000000000000000000) >> 25) == 1)) + return "rem"; + if (((n & 0b1111111) == 51) && (((n & 0b111000000000000) >> 12) == 7) && + (((n & 0b11111110000000000000000000000000) >> 25) == 1)) + return "remu"; + + return "unknown_instruction"; +} + +string reg(int n) { + if (n == 0) + return "zero"; + if (n == 1) + return "ra"; + if (n == 2) + return "sp"; + if (n == 3) + return "gp"; + if (n == 4) + return "tp"; + if (n == 5) + return "t0"; + if (n == 6) + return "t1"; + if (n == 7) + return "t2"; + if (n == 8) + return "fp"; + if (n == 9) + return "s1"; + if (n == 10) + return "a0"; + if (n == 11) + return "a1"; + if (n == 12) + return "a2"; + if (n == 13) + return "a3"; + if (n == 14) + return "a4"; + if (n == 15) + return "a5"; + if (n == 16) + return "a6"; + if (n == 17) + return "a7"; + if (n == 18) + return "s2"; + if (n == 19) + return "s3"; + if (n == 20) + return "s4"; + if (n == 21) + return "s5"; + if (n == 22) + return "s6"; + if (n == 23) + return "s7"; + if (n == 24) + return "s8"; + if (n == 25) + return "s9"; + if (n == 26) + return "s10"; + if (n == 27) + return "s11"; + if (n == 28) + return "t3"; + if (n == 29) + return "t4"; + if (n == 30) + return "t5"; + if (n == 31) + return "t6"; + return "invalid"; +} + +string bind(int n) { + n = (n) >> 4; + if (n == 0) + return "LOCAL"; + if (n == 1) + return "GLOBAL"; + if (n == 2) + return "WEAK"; + if (n == 10) + return "LOOS"; + if (n == 12) + return "HIOS"; + if (n == 13) + return "LOPROC"; + if (n == 15) + return "HIPROC"; + return "invalid"; +} + +string index(int n) { + if (n == 0) + return "UNDEF"; + if (n == 65280) + return "LORESERVE"; + if (n == 65281) + return "AFTER"; + if (n == 65311) + return "HIPROC"; + if (n == 65312) + return "LOOS"; + if (n == 65343) + return "HIOS"; + if (n == 65521) + return "ABS"; + if (n == 65522) + return "COMMON"; + if (n == 65535) + return "XINDEX"; + + return to_string(n); +} + +string vis(int n) { + if (n == 0) + return "DEFAULT"; + if (n == 1) + return "INTERNAL"; + if (n == 2) + return "HIDDEN"; + if (n == 3) + return "PROTECTED"; + if (n == 4) + return "EXPORTED"; + if (n == 5) + return "SINGLETON"; + if (n == 6) + return "ELIMINATE"; + return "invalid"; +} + +string type(int n) { + n = (n) & 0xf; + if (n == 0) + return "NOTYPE"; + if (n == 1) + return "OBJECT"; + if (n == 2) + return "FUNC"; + if (n == 3) + return "SECTION"; + if (n == 4) + return "FILE"; + if (n == 5) + return "COMMON"; + if (n == 6) + return "TLS"; + if (n == 10) + return "LOOS"; + if (n == 12) + return "HIOS"; + if (n == 13) + return "LOPROC"; + if (n == 15) + return "HIPROC"; + return "invalid"; +} + +int add_to_two(int n, int size) { + if (n < pow(2, size - 1)) + return n; + return int(n - pow(2, size)); + +} + +int main(int argc, char *argv[]) { + + f = fopen(argv[1], "r"); + g = fopen(argv[2], "w"); + if(!f){ + printf("input file is not available"); + return 0; + } + if(!g){ + printf("output file is not available"); + return 0; + } + + fread(&elf_header, sizeof(ELF_32_header), 1, f); + if(elf_header.version!=1){ + printf("invalid file version"); + return 0; + } + + //читаем заголовки + fseek(f, int(elf_header.shoff), SEEK_SET); + + for (int i = 0; i < elf_header.shnum; i++) { + ELF_32_SECTION_HEADER cur{}; + fread(&cur, sizeof(ELF_32_SECTION_HEADER), 1, f); + elf_section_header.push_back(cur); + } + + for (int i = 0; i < elf_header.shnum; i++) { + if (elf_section_header[i].sh_name == header_of_need_section(&SYMTAB)) { + symtab_header = elf_section_header[i]; + break; + } + } + for (int i = 0; i < elf_header.shnum; i++) { + if (elf_section_header[i].sh_name == header_of_need_section(&TEXT)) { + text_header = elf_section_header[i]; + break; + } + } + addr = int(text_header.sh_addr); + count_of_symbols = int(symtab_header.sh_size) / int(sizeof(ELF_32_SYMTAB)); + offset_symtab = offset_of_needsection(header_of_need_section(&SYMTAB)); + + fseek(f, offset_symtab, SEEK_SET); + + for (int i = 0; i < count_of_symbols; i++) { + ELF_32_SYMTAB cur{}; + fseek(f, offset_symtab + 16 * i, SEEK_SET); + fread(&cur, sizeof(ELF_32_SYMTAB), 1, f); + symtab.push_back(cur); + string name = get_name(int(symtab[i].st_name)); + string type_ = type(cur.st_info); + int value = int(symtab[i].st_value); + if (type_ == "OBJECT" || type_ == "FUNC") { + val_name[value] = name; + } + } + + offset_text = offset_of_needsection(header_of_need_section(&TEXT)); + fseek(f, offset_text, SEEK_SET); + + for (int i = 0; i < text_header.sh_size / 4; i++) { + fseek(f, offset_text + i * 4, SEEK_SET); + int cur = 0; + fread(&cur, 4, 1, f); + string command = get_command(cur); + int imm; + if (command == "jal") { + uint32_t immp1, immp2, immp3, immp4; + immp1 = ((cur & (uint32_t) 0b10000000000000000000000000000000) >> 31) << 1; + immp2 = ((cur & (uint32_t) 0b00000000000011111111000000000000) >> 12) << 1; + immp3 = ((cur & (uint32_t) 0b00000000000100000000000000000000) >> 20) << 1; + immp4 = ((cur & (uint32_t) 0b01111111111000000000000000000000) >> 21) << 1; + imm = int(immp4 + immp3 * 1024 + immp2 * 2048 + immp1 * pow(2, 19)); + + imm = add_to_two(int(imm), 20); + imm += addr; + imm = add_to_two(int(imm), 20); + + if (val_name.find(int(imm)) != val_name.end()) + addr_name[int(imm)] = val_name[int(imm)]; + else { + string s = "L"; + s += (to_string(L_index)); + addr_name[int(imm)] = s; + L_index++; + } + + } else if (command == "beq" || command == "bne" + || command == "blt" || command == "bgeu" + || command == "bge" || command == "bltu") { //1 111111 01010 01111 001 0100 1 + + + uint32_t immp1, immp2, immp3, immp4; + immp1 = ((cur & (uint32_t) 0b10000000000000000000000000000000) >> 31) << 1; + immp2 = ((cur & (uint32_t) 0b00000000000000000000000010000000) >> 7) << 1; + immp3 = ((cur & (uint32_t) 0b01111110000000000000000000000000) >> 25) << 1; + immp4 = ((cur & (uint32_t) 0b00000000000000000000111100000000) >> 8) << 1; + imm = immp1 * pow(2, 11) + immp2 * pow(2, 10) + immp3 * 16 + immp4; + imm = add_to_two(int(imm), 12); + imm += addr; + imm = add_to_two(int(imm), 12); + if (val_name.find(int(imm)) != val_name.end()) + addr_name[int(imm)] = val_name[int(imm)]; + else { + string s = "L"; + s += (to_string(L_index)); + addr_name[int(imm)] = s; + L_index++; + } + + } + + addr += 4; + + } + + addr = int(text_header.sh_addr); + + for (int i = 0; i < text_header.sh_size / 4; i++) { + if (addr_name.find(int(addr)) != addr_name.end()) { + const char *adname = addr_name[addr].c_str(); + fprintf(g, "%08x <%s>:\n", addr, adname); + } + + fseek(f, offset_text + i * 4, SEEK_SET); + int cur = 0; + fread(&cur, 4, 1, f); + string command = get_command(cur); + const char *com = command.c_str(); + fprintf(g, "%05x:\t", addr); + + if (command == "lui" || command == "auipc") { + int rg = (cur & 0b111110000000) >> 7; + string srd = reg(rg); + if(srd=="invalid"){ + printf("invalid reg"); + return 0; + } + const char *rd = srd.c_str(); + int imm = add_to_two(int((cur & 0b11111111111111111111000000000000) >> 12), 20); + fprintf(g, "%08x\t%7s\t%s,0x%x\n", cur, com, rd, imm); + } else if (command == "jal") { + int rg = (cur & 0b111110000000) >> 7; + string srg = reg(rg); + if(srg=="invalid"){ + printf("invalid reg"); + return 0; + } + + const char *rd = srg.c_str(); + + uint32_t immp1, immp2, immp3, immp4, imm; + immp1 = ((cur & (uint32_t) 0b10000000000000000000000000000000) >> 31) << 1; + immp2 = ((cur & (uint32_t) 0b00000000000011111111000000000000) >> 12) << 1; + immp3 = ((cur & (uint32_t) 0b00000000000100000000000000000000) >> 20) << 1; + immp4 = ((cur & (uint32_t) 0b01111111111000000000000000000000) >> 21) << 1; + imm = int(immp4 + immp3 * 1024 + immp2 * 2048 + immp1 * pow(2, 19)); + + imm = add_to_two(int(imm), 20); + imm += addr; + imm = add_to_two(int(imm), 20); + + const char *lable = addr_name[int(imm)].c_str(); + + fprintf(g, "%08x\t%7s\t%s, 0x%x <%s>\n", cur, com, rd, imm, lable); + + } else if (command == "jalr" || command == "lb" || command == "lh" + || command == "lbu" || command == "lw" + || command == "lhu") { + int rgd = (cur & 0b111110000000) >> 7; + int rgs1 = (cur & 0b11111000000000000000) >> 15; + string imm = to_string(add_to_two(int((cur & 0b11111111111100000000000000000000) >> 20), 12)); + string srgs1 = reg(rgs1); + string srgs2 = reg(rgd); + if(srgs1=="invalid" || srgs2=="invalid"){ + printf("invalid reg"); + return 0; + } + + const char *rs1 = srgs1.c_str(); + const char *rd = srgs2.c_str(); + const char *imm1 = imm.c_str(); + + fprintf(g, "%08x\t%7s\t%s, %s(%s)\n", cur, com, rd, imm1, rs1); + } else if (command == "beq" || command == "bne" + || command == "blt" || command == "bgeu" + || command == "bge" || command == "bltu") { //1 111111 01010 01111 001 0100 1 + + int rgs2 = (cur & 0b1111100000000000000000000) >> 20; + int rgs1 = (cur & 0b11111000000000000000) >> 15; + string srs1 = reg(rgs1); + const char *rs1 = srs1.c_str(); + string srs2 = reg(rgs2); + const char *rs2 = srs2.c_str(); + if(srs1=="invalid" || srs2=="invalid"){ + printf("invalid reg"); + return 0; + } + + + uint32_t immp1, immp2, immp3, immp4, imm; + immp1 = ((cur & (uint32_t) 0b10000000000000000000000000000000) >> 31) << 1; + immp2 = ((cur & (uint32_t) 0b00000000000000000000000010000000) >> 7) << 1; + immp3 = ((cur & (uint32_t) 0b01111110000000000000000000000000) >> 25) << 1; + immp4 = ((cur & (uint32_t) 0b00000000000000000000111100000000) >> 8) << 1; + imm = immp1 * pow(2, 11) + immp2 * pow(2, 10) + immp3 * 16 + immp4; + imm = add_to_two(int(imm), 12); + imm += addr; + imm = add_to_two(int(imm), 12); + + const char *lable = addr_name[int(imm)].c_str(); + + fprintf(g, "%08x\t%7s\t%s, %s, 0x%x <%s>\n", cur, com, rs1, rs2, imm, lable); + + } else if (command == "sh" || command == "sb" || command == "sw") { + int rgs2 = (cur & 0b1111100000000000000000000) >> 20; + int rgs1 = (cur & 0b11111000000000000000) >> 15; + string srs1 = reg(rgs1); + string srs2 = reg(rgs2); + if(srs1=="invalid" || srs2=="invalid"){ + printf("invalid reg"); + return 0; + } + + const char *rs1 = srs1.c_str(); + const char *rs2 = srs2.c_str(); + uint32_t immp1, immp2, imm; + immp1 = ((cur & (uint32_t) 0b11111110000000000000000000000000) >> 25); + immp2 = ((cur & (uint32_t) 0b00000000000000000000111110000000) >> 7); + + imm = immp1 * 32 + immp2; + + fprintf(g, "%08x\t%7s\t%s, %d(%s)\n", cur, com, rs2, imm, rs1); + + + } else if (command == "slti" || command == "addi" + || command == "xori" || command == "sltiu" + || command == "ori" || command == "andi" || command == "slli" || command == "srli" || + command == "srai") { + int rgd = (cur & 0b111110000000) >> 7; + int rgs1 = (cur & 0b11111000000000000000) >> 15; + string imm = to_string(add_to_two(int((cur & 0b11111111111100000000000000000000) >> 20), 12)); + string srs = reg(rgs1); + string srd = reg(rgd); + if(srs=="invalid" || srd=="invalid"){ + printf("invalid reg"); + return 0; + } + + const char *rs1 = srs.c_str(); + const char *rd = srd.c_str(); + const char *imm1 = imm.c_str(); + fprintf(g, "%08x\t%7s\t%s, %s, %s\n", cur, com, rd, rs1, imm1); + } else if (command == "add" || command == "sub" || command == "sll" || + command == "slt" || command == "sltu" || command == "xor" || + command == "srl" || command == "sra" || command == "or" || command == "and" || + command == "mul" || command == "mulh" || command == "mulhsu" || + command == "divu" || command == "div" || command == "mulhu" || + command == "rem" || command == "remu") { + + int rgs2 = (cur & 0b1111100000000000000000000) >> 20; + int rgd = (cur & 0b111110000000) >> 7; + int rgs1 = (cur & 0b11111000000000000000) >> 15; + string srs1 = reg(rgs1); + string srd = reg(rgd); + string srs2 = reg(rgs2); + if(srs1=="invalid" || srd=="invalid" || srs2=="invalid"){ + printf("invalid reg"); + return 0; + } + + const char *rs1 = srs1.c_str(); + const char *rd = srd.c_str(); + const char *rs2 = srs2.c_str(); + fprintf(g, "%08x\t%7s\t%s, %s, %s\n", cur, com, rd, rs1, rs2); + + } else if (command == "ecall" || command == "ebreak") { + fprintf(g, "%08x\t%7s\n", cur, com); + } else { + fprintf(g, "%08x\tunknown_instruction\n", cur); + } + addr += 4; + } + fprintf(g, "\nSymbol Value Size Type \tBind Vis Index Name\n"); + for (int i = 0; i < count_of_symbols; i++) { + ELF_32_SYMTAB cur{}; + fseek(f, offset_symtab + sizeof(ELF_32_SYMTAB) * i, SEEK_SET); + fread(&cur, sizeof(ELF_32_SYMTAB), 1, f); + string sname = get_name(int(symtab[i].st_name)); + const char *name = sname.c_str(); + string stype = type(cur.st_info); + const char *type_ = stype.c_str(); + string sbind = bind(cur.st_info); + const char *bind_ = sbind.c_str(); + string svis = vis(cur.st_other); + const char *vis_ = svis.c_str(); + string sindex = index(cur.st_shndx); + const char *index_ = sindex.c_str(); + + int value = int(symtab[i].st_value); + int size = int(symtab[i].st_size); + if(stype == "invalid" || sbind == "invalid" || svis=="invalid" || sindex == "invalid"){ + printf("invalid symtab"); + return 0; + } + fprintf(g, "[%4i] 0x%-15X %5i %-8s %-8s %-8s %6s %s\n", i, value, size, type_, bind_, vis_, index_, name); + } + + fclose(f); + fclose(g); +}