Merge pull request #88 from rofl0r/fixup_imp

improve psp-fixup-imports
This commit is contained in:
Wouter Wijsman
2023-03-08 10:24:29 +01:00
committed by GitHub

View File

@@ -59,6 +59,8 @@ static struct ElfSection *g_modinfo = NULL;
static struct ElfSection *g_libstub = NULL; static struct ElfSection *g_libstub = NULL;
static struct ElfSection *g_stubtext = NULL; static struct ElfSection *g_stubtext = NULL;
static struct ElfSection *g_nid = NULL; static struct ElfSection *g_nid = NULL;
static struct ElfSection *g_symtab = NULL;
static struct ElfSection *g_strtab = NULL;
static struct ImportMap *g_map = NULL; static struct ImportMap *g_map = NULL;
static int g_reversemap = 0; static int g_reversemap = 0;
@@ -151,6 +153,27 @@ const unsigned char *find_data(unsigned int iAddr)
return NULL; return NULL;
} }
/* find symbol name. addr needs to be in host endianness */
static const char *getsymname(unsigned addr)
{
if(!g_symtab || !g_strtab) return 0;
if(g_symtab->iSize == 0 || g_symtab->pData == 0) return 0;
if(g_strtab->iSize == 0 || g_strtab->pData == 0) return 0;
Elf32_Sym *curr = (void*)g_symtab->pData;
Elf32_Sym *end = curr + (g_symtab->iSize / sizeof(Elf32_Sym));
addr = LW(addr);
while(curr < end) {
if(curr->st_value == addr) {
if(curr->st_name && curr->st_name < g_strtab->iSize)
return (char*)g_strtab->pData + curr->st_name;
else
return 0;
}
++curr;
}
return 0;
}
struct ImportMap *find_map_by_name(const char *name) struct ImportMap *find_map_by_name(const char *name)
{ {
struct ImportMap *currmap = g_map; struct ImportMap *currmap = g_map;
@@ -244,14 +267,14 @@ int validate_header(unsigned char *data)
if(g_verbose) if(g_verbose)
{ {
fprintf(stderr, "Magic %08X, Class %02X, Data %02X, Idver %02X\n", g_elfhead.iMagic, fprintf(stderr, "Magic %08x, Class %02x, Data %02x, Idver %02x\n", g_elfhead.iMagic,
g_elfhead.iClass, g_elfhead.iData, g_elfhead.iIdver); g_elfhead.iClass, g_elfhead.iData, g_elfhead.iIdver);
fprintf(stderr, "Type %04X, Machine %04X, Version %08X, Entry %08X\n", g_elfhead.iType, fprintf(stderr, "Type %04x, Machine %04x, Version %08x, Entry %08x\n", g_elfhead.iType,
g_elfhead.iMachine, g_elfhead.iVersion, g_elfhead.iEntry); g_elfhead.iMachine, g_elfhead.iVersion, g_elfhead.iEntry);
fprintf(stderr, "Phoff %08X, Shoff %08X, Flags %08X, Ehsize %08X\n", g_elfhead.iPhoff, fprintf(stderr, "Phoff %08x, Shoff %08x, Flags %08x, Ehsize %08x\n", g_elfhead.iPhoff,
g_elfhead.iShoff, g_elfhead.iFlags, g_elfhead.iEhsize); g_elfhead.iShoff, g_elfhead.iFlags, g_elfhead.iEhsize);
fprintf(stderr, "Phentsize %04X, Phnum %04X\n", g_elfhead.iPhentsize, g_elfhead.iPhnum); fprintf(stderr, "Phentsize %04x, Phnum %04x\n", g_elfhead.iPhentsize, g_elfhead.iPhnum);
fprintf(stderr, "Shentsize %04X, Shnum %08X, Shstrndx %04X\n", g_elfhead.iShentsize, fprintf(stderr, "Shentsize %04x, Shnum %08x, Shstrndx %04x\n", g_elfhead.iShentsize,
g_elfhead.iShnum, g_elfhead.iShstrndx); g_elfhead.iShnum, g_elfhead.iShstrndx);
} }
@@ -365,6 +388,14 @@ int load_sections(unsigned char *data)
{ {
g_nid = &g_elfsections[i]; g_nid = &g_elfsections[i];
} }
else if(strcmp(g_elfsections[i].szName, ".symtab") == 0)
{
g_symtab = &g_elfsections[i];
}
else if(strcmp(g_elfsections[i].szName, ".strtab") == 0)
{
g_strtab = &g_elfsections[i];
}
} }
if(g_verbose) if(g_verbose)
@@ -372,18 +403,18 @@ int load_sections(unsigned char *data)
for(i = 0; i < g_elfhead.iShnum; i++) for(i = 0; i < g_elfhead.iShnum; i++)
{ {
fprintf(stderr, "\nSection %d: %s\n", i, g_elfsections[i].szName); fprintf(stderr, "\nSection %d: %s\n", i, g_elfsections[i].szName);
fprintf(stderr, "Name %08X, Type %08X, Flags %08X, Addr %08X\n", fprintf(stderr, "Name %08x, Type %08x, Flags %08x, Addr %08x\n",
g_elfsections[i].iName, g_elfsections[i].iType, g_elfsections[i].iName, g_elfsections[i].iType,
g_elfsections[i].iFlags, g_elfsections[i].iAddr); g_elfsections[i].iFlags, g_elfsections[i].iAddr);
fprintf(stderr, "Offset %08X, Size %08X, Link %08X, Info %08X\n", fprintf(stderr, "Offset %08x, Size %08x, Link %08x, Info %08x\n",
g_elfsections[i].iOffset, g_elfsections[i].iSize, g_elfsections[i].iOffset, g_elfsections[i].iSize,
g_elfsections[i].iLink, g_elfsections[i].iInfo); g_elfsections[i].iLink, g_elfsections[i].iInfo);
fprintf(stderr, "Addralign %08X, Entsize %08X pData %p\n", fprintf(stderr, "Addralign %08x, Entsize %08x pData %p\n",
g_elfsections[i].iAddralign, g_elfsections[i].iEntsize, g_elfsections[i].iAddralign, g_elfsections[i].iEntsize,
g_elfsections[i].pData); g_elfsections[i].pData);
} }
fprintf(stderr, "ELF Load Base address %08X\n", load_addr); fprintf(stderr, "ELF Load Base address %08x\n", load_addr);
} }
if(g_modinfo == NULL) if(g_modinfo == NULL)
@@ -504,15 +535,13 @@ int load_mapfile(const char *mapfile)
struct ImportMap *currmap = NULL; struct ImportMap *currmap = NULL;
int line = 0; int line = 0;
if(mapfile != NULL) if(mapfile == NULL) return ret;
{
do do
{ {
FILE *fp; FILE *fp;
fp = fopen(mapfile, "r"); fp = fopen(mapfile, "r");
if(fp != NULL) if(fp == NULL) return ret;
{
while(fgets(buf, sizeof(buf), fp)) while(fgets(buf, sizeof(buf), fp))
{ {
line++; line++;
@@ -600,7 +629,7 @@ int load_mapfile(const char *mapfile)
newnid = strtoul(endp+1, &endp, 16); newnid = strtoul(endp+1, &endp, 16);
if(g_verbose) if(g_verbose)
{ {
fprintf(stderr, "NID Mapping 0x%08X to 0x%08X\n", oldnid, newnid); fprintf(stderr, "NID Mapping 0x%08x to 0x%08x\n", oldnid, newnid);
} }
currmap->nids[currmap->count].oldnid = oldnid; currmap->nids[currmap->count].oldnid = oldnid;
@@ -611,9 +640,7 @@ int load_mapfile(const char *mapfile)
} }
fclose(fp); fclose(fp);
} }
}
while(0); while(0);
}
return ret; return ret;
} }
@@ -662,7 +689,8 @@ int fixup_imports(void)
if(g_verbose) if(g_verbose)
{ {
fprintf(stderr, "Found import to fixup. pStub %08X, Nid %08X, NidInSect %08X\n", stub_addr, stub_nid, sect_nid); const char *tmp = getsymname(stub_addr);
fprintf(stderr, "Found import to fixup. pStub %08x (%s), Nid %08x, NidInSect %08x\n", stub_addr, tmp ? tmp : "", stub_nid, sect_nid);
} }
if(stub_nid != sect_nid) if(stub_nid != sect_nid)
@@ -680,8 +708,9 @@ int fixup_imports(void)
pImport = (struct PspModuleImport *) (g_libstub->pData + (stub_addr - g_libstub->iAddr)); pImport = (struct PspModuleImport *) (g_libstub->pData + (stub_addr - g_libstub->iAddr));
if(g_verbose) if(g_verbose)
{ {
fprintf(stderr, "Import Stub %p, %08X, %08X, %02X, %02X, %04X, %08X, %08X\n", pImport, const char *tmp = getsymname(LW(pImport->name));
LW(pImport->name), LW(pImport->flags), pImport->entry_size, pImport->var_count, fprintf(stderr, "Import Stub %p, %08x (%s), %08x, %02x, %02x, %04x, %08x, %08x\n", pImport,
LW(pImport->name), tmp?tmp:"", LW(pImport->flags), pImport->entry_size, pImport->var_count,
LH(pImport->func_count), LW(pImport->nids), LW(pImport->funcs)); LH(pImport->func_count), LW(pImport->nids), LW(pImport->funcs));
} }
@@ -697,9 +726,9 @@ int fixup_imports(void)
{ {
if((pLastImport) && (pImport != pLastImport)) if((pLastImport) && (pImport != pLastImport))
{ {
fprintf(stderr, "Error, could not fixup imports, stubs out of order.\n"); fprintf(stderr, "Warning: could not fixup imports, stubs out of order.\n");
fprintf(stderr, "Ensure the SDK libraries are linked in last to correct this error\n"); fprintf(stderr, "Ensure the SDK libraries are linked in last to correct this.\n");
return 0; fprintf(stderr, "Continuing, your binary may or not work.\n");
} }
} }
@@ -788,7 +817,7 @@ int fixup_nidmap(void)
{ {
if(g_verbose) if(g_verbose)
{ {
fprintf(stderr, "Mapping 0x%08X to 0x%08X\n", oldnid, newnid); fprintf(stderr, "Mapping 0x%08x to 0x%08x\n", oldnid, newnid);
} }
*pNid = newnid; *pNid = newnid;