diff options
author | PikalaxALT <pikalaxalt@gmail.com> | 2020-05-26 12:46:29 -0400 |
---|---|---|
committer | PikalaxALT <pikalaxalt@gmail.com> | 2020-05-26 12:46:29 -0400 |
commit | 8e08eaa6e8cbf31ff27fd319278f824b68320e4c (patch) | |
tree | b3f801877a3f77252fe9363b4b67ff2a4436f7df | |
parent | 8c8a5a07c5e6b1a2d0d0592a30be31ccd140fc1e (diff) |
Implement calcrom
-rw-r--r-- | .travis.yml | 7 | ||||
-rw-r--r-- | .travis/calcrom/.gitignore | 1 | ||||
-rw-r--r-- | .travis/calcrom/Makefile | 17 | ||||
-rw-r--r-- | .travis/calcrom/calcrom.cpp | 107 | ||||
-rw-r--r-- | .travis/calcrom/webhook.sh | 17 | ||||
-rw-r--r-- | CMakeLists.txt | 3 |
6 files changed, 151 insertions, 1 deletions
diff --git a/.travis.yml b/.travis.yml index bf0c9a04..681bddc5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,9 @@ dist: bionic sudo: false language: c +env: + global: + - LM_LICENSE_FILE="$TRAVIS_BUILD_DIR/tools/mwccarm/license.dat" addons: apt: packages: @@ -24,8 +27,10 @@ install: - mv NITRO\ SDK\ v3.0/include/nitro/specfiles/ARM9-TS.lcf.template arm9 script: - - export LM_LICENSE_FILE="$(pwd)/tools/mwccarm/license.dat" - make notifications: email: false + +after_success: + - .travis/calcrom/webhook.sh diff --git a/.travis/calcrom/.gitignore b/.travis/calcrom/.gitignore new file mode 100644 index 00000000..a2e06b56 --- /dev/null +++ b/.travis/calcrom/.gitignore @@ -0,0 +1 @@ +calcrom diff --git a/.travis/calcrom/Makefile b/.travis/calcrom/Makefile new file mode 100644 index 00000000..e3b6ff50 --- /dev/null +++ b/.travis/calcrom/Makefile @@ -0,0 +1,17 @@ +CXX := g++ +CXXFLAGS := -O3 -std=c++11 + +ifeq ($(OS),Windows_NT) +EXE := .exe +else +EXE := +endif + +TARGET := calcrom$(EXE) + +.PHONY: all + +all: $(TARGET) + +$(TARGET): calcrom.cpp + $(CXX) $(CXXFLAGS) -o $@ $^ diff --git a/.travis/calcrom/calcrom.cpp b/.travis/calcrom/calcrom.cpp new file mode 100644 index 00000000..13a95b29 --- /dev/null +++ b/.travis/calcrom/calcrom.cpp @@ -0,0 +1,107 @@ +#include <iostream> +#include <fstream> +#include <sstream> +#include <elf.h> +#include <glob.h> +#include <string.h> +#include <vector> +#include <string> + +using namespace std; + +struct Glob : public vector<char const *> { + glob_t glob_result; +public: + void glob(string const & pattern) { + clear(); + int result = ::glob(pattern.c_str(), GLOB_TILDE | GLOB_BRACE, NULL, &glob_result); + if (result) { + stringstream ss; + ss << "Glob::glob(" << pattern << ") failed with error " << result << endl; + throw runtime_error(ss.str()); + } + assign(glob_result.gl_pathv, glob_result.gl_pathv + glob_result.gl_pathc); + } + Glob(string const & pattern) { + glob(pattern); + }; + void operator~() { + globfree(&glob_result); + } +}; + +int main() +{ + fstream elf; + Elf32_Ehdr ehdr; + Elf32_Shdr shdr_buf; + vector<Elf32_Shdr> shdr(0); + + // Accumulate sizes + // src asm + // data _____|_____ + // text | + unsigned sizes[2][2] = {{0, 0}, {0, 0}}; + char * shstrtab = NULL; + size_t shstrsz = 0; + for (char const * & fname : Glob("../../arm9/{src,asm,lib/{src,asm},modules/*/{src,asm}}/*.{c,s,cpp}")) + { + string fname_s(fname); + string ext = fname_s.substr(fname_s.rfind('.'), 4); + bool is_asm = ext == ".s"; + fname_s = fname_s.replace(fname_s.find("arm9"), 4, "arm9/build"); + fname_s = fname_s.replace(fname_s.rfind('.'), 4, ".o"); + elf.open(fname_s, ios_base::in | ios_base::binary); + elf.read((char *)&ehdr, sizeof(ehdr)); + if (memcmp(ehdr.e_ident, ELFMAG, SELFMAG) != 0) { + elf.close(); + stringstream ss; + ss << "Error validating " << fname_s << " as an ELF file" << endl; + throw runtime_error(ss.str()); + } + // Read ELF sections + elf.seekg(ehdr.e_shoff); + shdr.resize(ehdr.e_shnum); + elf.read((char *)shdr.data(), ehdr.e_shnum * ehdr.e_shentsize); + // Read .shstrtab + if (shstrsz < shdr[ehdr.e_shstrndx].sh_size) { + shstrtab = (char *)realloc(shstrtab, shdr[ehdr.e_shstrndx].sh_size); + shstrsz = shdr[ehdr.e_shstrndx].sh_size; + } + elf.seekg(shdr[ehdr.e_shstrndx].sh_offset); + elf.read(shstrtab, shdr[ehdr.e_shstrndx].sh_size); + elf.close(); + for (Elf32_Shdr & hdr : shdr) { + string shname = shstrtab + hdr.sh_name; + bool is_text = (shname == ".text" || shname == ".init"); + bool is_data = (shname == ".data" || shname == ".rodata" || shname == ".sdata"); + size_t size = hdr.sh_size + (hdr.sh_size & 3 ? 4 - (hdr.sh_size & 3) : 0); + if (is_text || is_data) + { + sizes[is_text][is_asm] += size; + } + } + } + free(shstrtab); + + cout << "Analysis of ARM9 binary:" << endl; + // Report code + unsigned total_text = sizes[1][0] + sizes[1][1]; + double total_text_d = total_text; + double src_text_d = sizes[1][0]; + double asm_text_d = sizes[1][1]; + cout << total_text << " total bytes of code" << endl; + cout << " " << sizes[1][0] << " bytes of code in src (" << (src_text_d / total_text_d * 100.0) << "%)" << endl; + cout << " " << sizes[1][1] << " bytes of code in asm (" << (asm_text_d / total_text_d * 100.0) << "%)" << endl; + cout << endl; + // Report data + unsigned total_data = sizes[0][0] + sizes[0][1]; + double total_data_d = total_data; + double src_data_d = sizes[0][0]; + double asm_data_d = sizes[0][1]; + cout << total_data << " total bytes of data" << endl; + cout << " " << sizes[0][0] << " bytes of data in src (" << (src_data_d / total_data_d * 100.0) << "%)" << endl; + cout << " " << sizes[0][1] << " bytes of data in asm (" << (asm_data_d / total_data_d * 100.0) << "%)" << endl; + // Let vectors fall to gc + return 0; +} diff --git a/.travis/calcrom/webhook.sh b/.travis/calcrom/webhook.sh new file mode 100644 index 00000000..cb467cf0 --- /dev/null +++ b/.travis/calcrom/webhook.sh @@ -0,0 +1,17 @@ +#!/bin/bash -ex + +# Only run this script if it's the master branch build. +if [[ "$TRAVIS_BRANCH" != "master" || "$TRAVIS_PULL_REQUEST" != "false" ]]; then + exit 0 +fi + +build_name=$1 +map_file=$(dirname "$0")/../../arm9/build/arm9.elf.xMAP +if [ ! -f $map_file ]; then + echo "$map_file does not exist!" + exit 1 +fi + +make -C $(dirname "$0") +output=$($(dirname "$0")/calcrom | sed -E ':a;N;$!ba;s/\r{0,1}\n/\\n/g') +curl -d "{\"username\": \"$CALCROM_DISCORD_WEBHOOK_USERNAME\", \"avatar_url\": \"$CALCROM_DISCORD_WEBHOOK_AVATAR_URL\", \"content\":\"\`\`\`$build_name progress:\\n$output\`\`\`\"}" -H "Content-Type: application/json" -X POST $CALCROM_DISCORD_WEBHOOK_URL diff --git a/CMakeLists.txt b/CMakeLists.txt index f2537aad..3eb28627 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,3 +9,6 @@ file(GLOB_RECURSE SOURCES RELATIVE ${CMAKE_SOURCE_DIR} "*.c" "*.cpp") add_executable(PokeDiamond ${SOURCES}) target_include_directories(PokeDiamond PRIVATE include include-mw arm9/lib/include) + +add_executable(calcrom scratch.cpp) +target_include_directories(calcrom PRIVATE /usr/local/include) |