// // symfile.cpp // #include "symfile.h" #include //------------------------------------------------------------------------------ // Static Helpers static bool contains(char x, const char* pSeparators) { while (*pSeparators) { if (x == *pSeparators) { return true; } pSeparators++; } return false; } static std::vector split(const std::string& s, const char* separators) { std::vector output; std::string::size_type prev_pos = 0, pos = 0; for (int index = 0; index < s.length(); ++index) { pos = index; // if the index is a separator if (contains(s[index], separators)) { // if we've skipped a token, collect it if (prev_pos != index) { output.push_back(s.substr(prev_pos, index-prev_pos)); // skip white space here while (index < s.length()) { if (contains(s[index], separators)) { ++index; } else { prev_pos = index; pos = index; break; } } } else { prev_pos++; } } } output.push_back(s.substr(prev_pos, pos-prev_pos+1)); // Last word return output; } // make this string lowercase static void tolower(std::string& s) { for (int index = 0; index < s.length(); ++index) { s[index] = tolower( s[index] ); } } //------------------------------------------------------------------------------ SYMFile::SYMFile( std::string filepath ) : m_filepath( filepath ) { FILE* pFile = nullptr; errno_t err = fopen_s(&pFile, filepath.c_str(), "rb"); if (0==err) { fseek(pFile, 0, SEEK_END); size_t length = ftell(pFile); fseek(pFile, 0, SEEK_SET); printf("\n// SYMFile %s - %lld bytes\n", filepath.c_str(), length); printf("// Reading %s\n", filepath.c_str()); printf("//\n"); printf("// This file generated by blockgen.exe\n"); printf("//\n"); printf("//\n"); u8* pData = new u8[ length ]; fread(pData, sizeof(u8), length / sizeof(u8), pFile); // Now we have a buffer, with the whole SYM File // Read in the Sections { MemoryStream memStream(pData, length); while (memStream.NumBytesAvailable()) { std::string lineData = memStream.ReadLine(); // symbols are case sensitive // we care about the first 32 bit value in hex, and the last value on the line, the symbol std::vector tokens = split(lineData, " \t"); if (tokens.size() >= 3) { if (IsHexAddress(tokens[0])) { // We're only interested in lines that start with a hex address std::string sym_name = tokens[ tokens.size() - 1 ]; u32 address = strtoul(tokens[0].c_str(), nullptr, 16); //printf("address = %08x\n", address); if (0 != (address >> 24)) { printf("#define %s_BLOCK %d\n", sym_name.c_str(), address>>24); } else if (0 != (address & 0xFF0000)) { printf("#define %s_high %d\n", sym_name.c_str(), (address>>16) & 0xFF); printf("#define %s_BLOCK %d\n", sym_name.c_str(), ((address&0xFFFFFF) / 0x2000)); } } } } } delete[] pData; fclose(pFile); printf("\n// Read Completed\n"); } else { printf("// SYMFile could not open %s\n", filepath.c_str()); printf("//\n"); printf("Feed in a symbol dump file, and I will print out a header file\n"); printf("Capture my output with a pipe.\n"); printf("\nGenerate a .sym file like this:\n"); printf("\nllvm-objdump --syms .elf > program.sym\n"); } } //------------------------------------------------------------------------------ SYMFile::~SYMFile() { } //------------------------------------------------------------------------------ u32 SYMFile::GetAddress(std::string symbolName) { u32 result_address = 0; // If the address is in there, return it // First remove trailing spaces from the sectionName const size_t strEnd = symbolName.find_last_not_of(" "); if (strEnd != std::string::npos) { if ((strEnd+1) != symbolName.length()) { symbolName.resize(strEnd+1); } } // Make sure not case sensitive tolower(symbolName); for (int labelIndex = 0; labelIndex < m_symbols.size(); ++labelIndex) { if (symbolName == m_symbols[labelIndex]) { result_address = m_addresses[labelIndex]; break; } } return result_address; } //------------------------------------------------------------------------------ bool SYMFile::IsHexAddress(const std::string& address) { if (8 == address.size()) { for (int idx = 0; idx < 8; ++idx) { if ((address[idx] >= '0')&&(address[idx] <= '9')) { continue; // this is good } else if ((address[idx] >= 'a')&&(address[idx] <= 'f')) { continue; // this is good } else if ((address[idx] >= 'A')&&(address[idx] <= 'F')) { continue; // this is good } else { return false; } } return true; } return false; } //------------------------------------------------------------------------------