diff --git a/tools/psp-fixup-imports.c b/tools/psp-fixup-imports.c index 1f3b082e..2f6a6ad5 100644 --- a/tools/psp-fixup-imports.c +++ b/tools/psp-fixup-imports.c @@ -59,6 +59,8 @@ static struct ElfSection *g_modinfo = NULL; static struct ElfSection *g_libstub = NULL; static struct ElfSection *g_stubtext = 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 int g_reversemap = 0; @@ -151,6 +153,27 @@ const unsigned char *find_data(unsigned int iAddr) 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 *currmap = g_map; @@ -244,14 +267,14 @@ int validate_header(unsigned char *data) 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); - 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); - 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); - 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, "Phentsize %04x, Phnum %04x\n", g_elfhead.iPhentsize, g_elfhead.iPhnum); + fprintf(stderr, "Shentsize %04x, Shnum %08x, Shstrndx %04x\n", g_elfhead.iShentsize, g_elfhead.iShnum, g_elfhead.iShstrndx); } @@ -365,6 +388,14 @@ int load_sections(unsigned char *data) { 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) @@ -372,18 +403,18 @@ int load_sections(unsigned char *data) for(i = 0; i < g_elfhead.iShnum; i++) { 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].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].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].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) @@ -504,116 +535,112 @@ int load_mapfile(const char *mapfile) struct ImportMap *currmap = NULL; int line = 0; - if(mapfile != NULL) + if(mapfile == NULL) return ret; + do { - do + FILE *fp; + + fp = fopen(mapfile, "r"); + if(fp == NULL) return ret; + while(fgets(buf, sizeof(buf), fp)) { - FILE *fp; - - fp = fopen(mapfile, "r"); - if(fp != NULL) + line++; + strip_wsp(buf); + if((buf[0]) && (buf[0] != '#')) { - while(fgets(buf, sizeof(buf), fp)) + if(buf[0] == '@') { - line++; - strip_wsp(buf); - if((buf[0]) && (buf[0] != '#')) + struct ImportMap *temp; + + temp = (struct ImportMap *) malloc(sizeof(struct ImportMap)); + if(temp == NULL) { - if(buf[0] == '@') - { - struct ImportMap *temp; + printf("Error allocating memory for import map\n"); + ret = 0; + break; + } - temp = (struct ImportMap *) malloc(sizeof(struct ImportMap)); - if(temp == NULL) - { - printf("Error allocating memory for import map\n"); - ret = 0; - break; - } + memset(temp, 0, sizeof(struct ImportMap)); + if(currmap == NULL) + { + g_map = temp; + } + else + { + temp->next = currmap; + g_map = temp; + } - memset(temp, 0, sizeof(struct ImportMap)); - if(currmap == NULL) - { - g_map = temp; - } - else - { - temp->next = currmap; - g_map = temp; - } + currmap = temp; + if(buf[1]) + { + strncpy(currmap->name, &buf[1], 32); + currmap->name[31] = 0; + } + else + { + printf("Invalid library name at line %d\n", line); + break; + } - currmap = temp; - if(buf[1]) - { - strncpy(currmap->name, &buf[1], 32); - currmap->name[31] = 0; - } - else - { - printf("Invalid library name at line %d\n", line); - break; - } - - if(g_verbose) - { - printf("Mapping library %s\n", currmap->name); - } - } - else - { - unsigned int oldnid; - unsigned int newnid; - char *endp; - - if(currmap->count == MAX_MAPNIDS) - { - printf("Error, number of defined nids exceed maximum\n"); - break; - } - - /* Hex data should be prefixed with 0 */ - if(buf[0] == '0') - { - errno = 0; - oldnid = strtoul(buf, &endp, 16); - if((errno != 0) || (*endp != ':')) - { - printf("Invalid NID entry on line %d\n", line); - continue; - } - } - else - { - unsigned char hash[SHA1_DIGEST_SIZE]; - - endp = strchr(buf, ':'); - if(endp == NULL) - { - printf("Invalid NID entry on line %d\n", line); - continue; - } - - sha1(hash, (unsigned char *) buf, endp-buf); - oldnid = hash[0] | (hash[1] << 8) | (hash[2] << 16) | (hash[3] << 24); - } - - newnid = strtoul(endp+1, &endp, 16); - if(g_verbose) - { - fprintf(stderr, "NID Mapping 0x%08X to 0x%08X\n", oldnid, newnid); - } - - currmap->nids[currmap->count].oldnid = oldnid; - currmap->nids[currmap->count].newnid = newnid; - currmap->count++; - } + if(g_verbose) + { + printf("Mapping library %s\n", currmap->name); } } - fclose(fp); + else + { + unsigned int oldnid; + unsigned int newnid; + char *endp; + + if(currmap->count == MAX_MAPNIDS) + { + printf("Error, number of defined nids exceed maximum\n"); + break; + } + + /* Hex data should be prefixed with 0 */ + if(buf[0] == '0') + { + errno = 0; + oldnid = strtoul(buf, &endp, 16); + if((errno != 0) || (*endp != ':')) + { + printf("Invalid NID entry on line %d\n", line); + continue; + } + } + else + { + unsigned char hash[SHA1_DIGEST_SIZE]; + + endp = strchr(buf, ':'); + if(endp == NULL) + { + printf("Invalid NID entry on line %d\n", line); + continue; + } + + sha1(hash, (unsigned char *) buf, endp-buf); + oldnid = hash[0] | (hash[1] << 8) | (hash[2] << 16) | (hash[3] << 24); + } + + newnid = strtoul(endp+1, &endp, 16); + if(g_verbose) + { + fprintf(stderr, "NID Mapping 0x%08x to 0x%08x\n", oldnid, newnid); + } + + currmap->nids[currmap->count].oldnid = oldnid; + currmap->nids[currmap->count].newnid = newnid; + currmap->count++; + } } } - while(0); + fclose(fp); } + while(0); return ret; } @@ -662,7 +689,8 @@ int fixup_imports(void) 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) @@ -680,8 +708,9 @@ int fixup_imports(void) pImport = (struct PspModuleImport *) (g_libstub->pData + (stub_addr - g_libstub->iAddr)); if(g_verbose) { - fprintf(stderr, "Import Stub %p, %08X, %08X, %02X, %02X, %04X, %08X, %08X\n", pImport, - LW(pImport->name), LW(pImport->flags), pImport->entry_size, pImport->var_count, + const char *tmp = getsymname(LW(pImport->name)); + 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)); } @@ -697,9 +726,9 @@ int fixup_imports(void) { if((pLastImport) && (pImport != pLastImport)) { - fprintf(stderr, "Error, could not fixup imports, stubs out of order.\n"); - fprintf(stderr, "Ensure the SDK libraries are linked in last to correct this error\n"); - return 0; + 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.\n"); + fprintf(stderr, "Continuing, your binary may or not work.\n"); } } @@ -788,7 +817,7 @@ int fixup_nidmap(void) { 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;