231 lines
5 KiB
C++
231 lines
5 KiB
C++
//
|
|
// symfile.cpp
|
|
//
|
|
#include "symfile.h"
|
|
#include <stdio.h>
|
|
|
|
//------------------------------------------------------------------------------
|
|
// Static Helpers
|
|
|
|
static bool contains(char x, const char* pSeparators)
|
|
{
|
|
while (*pSeparators)
|
|
{
|
|
if (x == *pSeparators)
|
|
{
|
|
return true;
|
|
}
|
|
pSeparators++;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
static std::vector<std::string> split(const std::string& s, const char* separators)
|
|
{
|
|
std::vector<std::string> 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<std::string> 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 <program>.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;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|