//#include <stdio.h> // _snprintf
//#include <string.h> // strcmp
//#include <stdlib.h> // getenv
#include "esptool.h" // Fatal()
#include "elffile.h"
#include <io.h> // mktemp - igitt!!
ELFFile::ELFFile(const char*n):name(n),symbols(0),nsym(0) {}
bool ELFFile::valid(byte*fdata,uint32 fsize) {
return fsize>=32 && reinterpret_cast<HDR*>(fdata)->magic==MAGIC;
}
bool ELFFile::parse(Dumpfile&df,cb2_t cb,void*cbd,uint32*sadr) {
HDR&e=*(HDR*)df.data();
if (sadr) *sadr=e.entry;
for (int i=0; i<e.phnum; i++) {
ProgHdr32&ph=*(ProgHdr32*)(df.data()+e.phoff+i*e.phentsize);
if (ph.type==1 && ph.filesz) {
Dumpfile sub(df.data()+ph.offset,ph.filesz,ph.paddr);
if (!cb(cbd,sub)) return 0;
}
}
return true;
}
bool ELFFile::is_lx106() {
return !strcmp(getenv("XTENSA_CORE"),"lx106");
}
void ELFFile::add_sym(const char*n,uint32 v) {
uint32 k=nsym;
symbols=(SYM*)realloc(symbols,++nsym*sizeof*symbols);
symbols[k].name=_strdup(n);
symbols[k].value=v;
}
void ELFFile::_fetch_symbols() {
if (symbols) return;
const char*tool_nm = is_lx106() ? "xt-nm" : "xtensa-lx106-elf-nm";
char s[256];
_snprintf(s,sizeof s,"%s \"%s\"",tool_nm,name);
FILE*proc = _popen(s,"rb");
if (!proc) Fatal("Error calling %s, do you have Xtensa toolchain in PATH?", tool_nm);
char line[260];
while (fgets(line,sizeof line,proc)) {
char*p=line; while (strchr(" \t",*p)) ++p; // TrimLeft
char f0[32],f1[32];
if (sscanf(p,"%32s %32s",f0,f1)==2) {
if (f0[0]=='U') {
printf("Warning: ELF binary has undefined symbol %s\n",f1);
continue;
}
add_sym(f1,strtoul(f0,0,0));
}
}
// except ValueError:
// Fatal("Failed to strip symbol output from nm: %s", fields);
}
uint32 ELFFile::get_symbol_addr(const char*sym) {
_fetch_symbols();
for (uint32 i=0; i<nsym; i++) if (!strcmp(sym,symbols[i].name)) return symbols[i].value;
return (uint32)-1;
}
uint32 ELFFile::get_entry_point() {
const char*tool_readelf = is_lx106() ? "xt-readelf" : "xtensa-lx106-elf-readelf";
char s[256];
_snprintf(s,sizeof s,"%s -h \"%s\"",tool_readelf,name);
FILE*proc = _popen(s,"rb");
if (!proc) Fatal("Error calling %s, do you have Xtensa toolchain in PATH?",tool_readelf);
char line[260];
while (fgets(line,sizeof line,proc)) {
char*p=line; while (strchr(" \t",*p)) ++p; // TrimLeft
uint32 e;
if (sscanf(p,"Entry %u",&e)==1) {
fclose(proc);
return e;
}
}
fclose(proc);
return (uint32)-1;
}
bool ELFFile::load_section_cb(void*cbd,const Dumpfile&df) {
return true;
}
bool ELFFile::load_section(const void*section,const void*&data) {
const char*tool_objcopy = is_lx106() ? "xt-objcopy" : "xtensa-lx106-elf-objcopy";
const char*tmpsection = _mktemp("sec");
char s[256];
_snprintf(s,sizeof s,"%s --only-section %s -Obinary \"%s\" %s",tool_objcopy,section,name,tmpsection);
FILE*proc = _popen(s,"rb");
char line[260];
while (fgets(line,sizeof line,proc)); // warten bis fertig und stdout absaugen
fclose(proc);
bool ok=parseBinFile(tmpsection,load_section_cb,&data,0);
remove(tmpsection);
return ok;
}
ELFFile::~ELFFile() {
if (!symbols) return;
for (unsigned i=0; i<nsym; i++) free(const_cast<char*>(symbols[i].name));
delete[] symbols;
}
Detected encoding: ASCII (7 bit) | 2
|