#include <iostream>
#include <fstream>
#include <vector>
#include <assert.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <libelf/libelf.h>
using namespace std;
void output(ostream &os, unsigned base_addr, size_t len,
unsigned char *bytes)
{
assert(base_addr < 0x10000);
assert(base_addr + len <= 0x10000);
os << uppercase << hex << right;
while (len > 0)
{
os << "S1";
size_t line = min(len, (size_t)0x20);
os.fill('0');
os.width(2);
os << line+3;
os.fill('0');
os.width(4);
os << base_addr;
unsigned char checksum = line + 3 +
(base_addr & 0x00ff) +
((base_addr & 0xff00) >> 8);
base_addr += line;
len -= line;
while (line > 0)
{
os.fill('0');
os.width(2);
os << static_cast<unsigned>(*bytes);
checksum += *bytes;
bytes++;
line--;
}
checksum = ~checksum;
os.fill('0');
os.width(2);
os << static_cast<unsigned>(checksum) << "\n";
}
}
void closing(ostream &os)
{
os << "S9030000FC\n";
}
void usage(int argc, char **argv)
{
cerr << "Usage: " << argv[0] << " infile outfile\n\n";
}
int main(int argc, char **argv)
{
if (argc != 3)
{
usage(argc, argv);
return 1;
}
char *fn = argv[1];
ofstream ofs(argv[2]);
if (elf_version(EV_CURRENT) == EV_NONE)
{
cerr << "libelf out of date. Please rebuild " << argv[0] << "\n";
return -1;
}
int fd = open(fn, 0);
if (!fd)
{
cerr << "failed to open " << fn << ".\n";
return -1;
}
Elf *elf = elf_begin(fd, ELF_C_READ, NULL);
if (!elf)
{
cerr << fn << " not an elf.\n";
return -1;
}
Elf32_Ehdr *header = elf32_getehdr(elf);
Elf32_Phdr *segment = elf32_getphdr(elf);
for (int i = 0; i < header->e_phnum; ++i)
{
lseek(fd, segment[i].p_offset, SEEK_SET);
#if 0
assert(segment[i].p_memsz >= segment[i].p_filesz);
vector<unsigned char> bytes(segment[i].p_memsz, 0);
read(fd, &bytes[0], segment[i].p_filesz);
#else
vector<unsigned char> bytes(segment[i].p_filesz, 0);
read(fd, &bytes[0], segment[i].p_filesz);
#endif
output(ofs, segment[i].p_vaddr, bytes.size(), &bytes[0]);
}
elf_end(elf);
closing(ofs);
return 0;
}
(download)