Skip to content

Commit

Permalink
Merge pull request #1 from artart78/master
Browse files Browse the repository at this point in the history
New option and 6.60 sysmem.prx relocations fix
  • Loading branch information
artart78 committed Jan 15, 2012
2 parents 6c342f0 + 05bd70e commit 185103a
Show file tree
Hide file tree
Showing 2 changed files with 150 additions and 22 deletions.
96 changes: 77 additions & 19 deletions ProcessPrx.C
Original file line number Diff line number Diff line change
Expand Up @@ -489,8 +489,8 @@ bool CProcessPrx::FillModule(u8 *pData, u32 iAddr)
m_modInfo.info.exp_end = LW(m_modInfo.info.exp_end);
m_modInfo.info.imports = LW(m_modInfo.info.imports);
m_modInfo.info.imp_end = LW(m_modInfo.info.imp_end);
m_stubBottom = m_modInfo.info.exports - 4; // ".lib.ent.top"
COutput::Printf(LEVEL_DEBUG, "Stub bottom 0x%08X\n", m_stubBottom);
m_stubBottom = m_modInfo.info.exports - 4; // ".lib.ent.top"
COutput::Printf(LEVEL_DEBUG, "Stub bottom 0x%08X\n", m_stubBottom);
blRet = true;

if(COutput::GetDebug())
Expand Down Expand Up @@ -972,12 +972,19 @@ bool CProcessPrx::LoadFromFile(const char *szFilename)

if(pData != NULL)
{
if((FillModule(pData, iAddr)) && (LoadExports()) && (LoadImports()) && (CreateFakeSections()) && (LoadRelocs()))
if((FillModule(pData, iAddr)) && (LoadRelocs()))
{
COutput::Printf(LEVEL_INFO, "Loaded PRX %s successfully\n", szFilename);
blRet = true;
m_blPrxLoaded = true;
BuildMaps();
if(m_pElfRelocs)
{
FixupRelocs(m_dwBase, m_imms);
}
if ((LoadExports()) && (LoadImports()) && (CreateFakeSections()))
{
COutput::Printf(LEVEL_INFO, "Loaded PRX %s successfully\n", szFilename);
BuildMaps();
blRet = true;
}
}
}
else
Expand Down Expand Up @@ -1570,8 +1577,59 @@ void CProcessPrx::FixupRelocs(u32 dwBase, ImmMap &imms)
SW(*pData, hiinst);
}
break;
case R_MIPS_X_J26:
case R_MIPS_X_JAL26:
case R_MIPS_X_J26: {
u32 dwData, dwInst;
u32 off = 0;
int base = iLoop;
ImmEntry *imm;
ElfReloc *rel2 = NULL;
u32 offs2 = 0;
while (++iLoop < m_iRelocCount)
{
rel2 = &m_pElfRelocs[iLoop];
if (rel2->type == R_MIPS_X_JAL26 && (dwBase + m_pElfPrograms[(rel2->symbol >> 8) & 0xFF].iVaddr) == dwCurrBase)
break;
}

if (iLoop < m_iRelocCount) {
offs2 = rel2->offset + m_pElfPrograms[rel2->symbol & 0xFF].iVaddr;
off = LW(*(u32*) m_vMem.GetPtr(offs2));
}

dwInst = LW(*pData);
dwData = dwInst + (dwCurrBase >> 16);
SW(*pData, dwData);

if ((dwData >> 26) != 2) // not J instruction
{
imm = new ImmEntry;
imm->addr = dwRealOfs + dwBase;
imm->target = dwCurrBase + (((dwInst & 0xFFFF) << 16) | (off & 0xFFFF));
imm->text = ElfAddrIsText(imm->target - dwBase);
imms[dwRealOfs + dwBase] = imm;
}
// already add the JAL26 symbol so we don't have to search for the J26 there
if (iLoop < m_iRelocCount && (dwData >> 26) != 3) // not JAL instruction
{
imm = new ImmEntry;
imm->addr = offs2 + dwBase;
imm->target = dwCurrBase + (((dwInst & 0xFFFF) << 16) | (off & 0xFFFF));
imm->text = ElfAddrIsText(imm->target - dwBase);
imms[offs2 + dwBase] = imm;
}

iLoop = base;
}
break;
case R_MIPS_X_JAL26: {
u32 dwData, dwInst;
ImmEntry *imm;

dwInst = LW(*pData);
dwData = dwInst + (dwCurrBase & 0xFFFF);
SW(*pData, dwData);
}
break;
case R_MIPS_26: {
u32 dwAddr;
u32 dwInst;
Expand All @@ -1585,19 +1643,23 @@ void CProcessPrx::FixupRelocs(u32 dwBase, ImmMap &imms)
SW(*pData, dwInst);
}
break;
case R_MIPS_32: {
case R_MIPS_32: {
u32 dwData;
ImmEntry *imm;

dwData = LW(*pData);
dwData += dwCurrBase;
dwData += (dwCurrBase & 0x03FFFFFF);
dwData += (dwBase >> 2) & 0x03FFFFFF;
SW(*pData, dwData);

imm = new ImmEntry;
imm->addr = dwRealOfs + dwBase;
imm->target = dwData;
imm->text = ElfAddrIsText(dwData - dwBase);
imms[dwRealOfs + dwBase] = imm;
if ((dwData >> 26) != 2) // not J instruction
{
imm = new ImmEntry;
imm->addr = dwRealOfs + dwBase;
imm->target = (dwData & 0x03FFFFFF) << 2;;
imm->text = ElfAddrIsText(dwData - dwBase);
imms[dwRealOfs + dwBase] = imm;
}
}
break;
default: /* Do nothing */
Expand Down Expand Up @@ -2353,10 +2415,6 @@ bool CProcessPrx::BuildMaps()
{
int iLoop;

if(m_pElfRelocs)
{
FixupRelocs(m_dwBase, m_imms);
}
BuildSymbols(m_syms, m_dwBase);

ImmMap::iterator start = m_imms.begin();
Expand Down
76 changes: 73 additions & 3 deletions main.C
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ enum OutputMode
OUTPUT_SYMBOLS = 11,
OUTPUT_DISASM = 12,
OUTPUT_XMLDB = 13,
OUTPUT_ENT = 14,
};

static char **g_ppInfiles;
Expand Down Expand Up @@ -127,6 +128,8 @@ static struct ArgEntry cmd_options[] = {
" : Print the module and library information to screen"},
{"impexp", 'f', ARG_TYPE_INT, ARG_OPT_NONE, (void*) &g_outputMode, OUTPUT_IMPEXP,
" : Print the imports and exports of a prx"},
{"exports", 'p', ARG_TYPE_INT, ARG_OPT_NONE, (void*) &g_outputMode, OUTPUT_ENT,
" : Output an export file (.exp)"},
{"disasm", 'w', ARG_TYPE_INT, ARG_OPT_NONE, (void*) &g_outputMode, OUTPUT_DISASM,
" : Disasm the executable sections of the files (if more than one file output name is automatic)"},
{"disopts", 'i', ARG_TYPE_STR, ARG_OPT_REQUIRED, (void*) &g_disopts, 0,
Expand All @@ -149,7 +152,7 @@ void DoOutput(OutputLevel level, const char *str)
{
switch(level)
{
case LEVEL_INFO: fprintf(stderr, str);
case LEVEL_INFO: fprintf(stderr, "%s", str);
break;
case LEVEL_WARNING: fprintf(stderr, "Warning: %s", str);
break;
Expand Down Expand Up @@ -671,6 +674,39 @@ void write_stub(const char *szDirectory, PspLibExport *pExp, CProcessPrx *pPrx)
}
}

void write_ent(PspLibExport *pExp, FILE *fp)
{
char szPath[MAXPATH];
COutput::Printf(LEVEL_DEBUG, "Library %s\n", pExp->name);
if(fp != NULL)
{
int i;
char *nidName = (char*)malloc(strlen(pExp->name) + 10);

fprintf(fp, "PSP_EXPORT_START(%s, 0x%04X, 0x%04X)\n", pExp->name, pExp->stub.flags & 0xFFFF, pExp->stub.flags >> 16);

for(i = 0; i < pExp->f_count; i++)
{
sprintf(nidName, "%s_%08X", pExp->name, pExp->funcs[i].nid);
if (strcmp(nidName, pExp->funcs[i].name) == 0)
fprintf(fp, "PSP_EXPORT_FUNC_NID(%s, 0x%08X)\n", pExp->funcs[i].name, pExp->funcs[i].nid);
else
fprintf(fp, "PSP_EXPORT_FUNC_HASH(%s)\n", pExp->funcs[i].name);
}
for (i = 0; i < pExp->v_count; i++)
{
sprintf(nidName, "%s_%08X", pExp->name, pExp->vars[i].nid);
if (strcmp(nidName, pExp->vars[i].name) == 0)
fprintf(fp, "PSP_EXPORT_VAR_NID(%s, 0x%08X)\n", pExp->vars[i].name, pExp->vars[i].nid);
else
fprintf(fp, "PSP_EXPORT_VAR_HASH(%s)\n", pExp->vars[i].name);
}

fprintf(fp, "PSP_EXPORT_END\n\n");
free(nidName);
}
}

void write_stub_new(const char *szDirectory, PspLibExport *pExp, CProcessPrx *pPrx)
{
char szPath[MAXPATH];
Expand Down Expand Up @@ -755,9 +791,7 @@ void output_stubs_prx(const char *file, CNidMgr *pNids)
else
{
PspLibExport *pHead;
int i;

i = 0;
COutput::Printf(LEVEL_INFO, "Dependancy list for %s\n", file);
pHead = prx.GetExports();
while(pHead != NULL)
Expand All @@ -778,6 +812,29 @@ void output_stubs_prx(const char *file, CNidMgr *pNids)
}
}

void output_ents(const char *file, CNidMgr *pNids, FILE *f)
{
CProcessPrx prx(g_dwBase);

prx.SetNidMgr(pNids);
if(prx.LoadFromFile(file) == false)
{
COutput::Puts(LEVEL_ERROR, "Couldn't load prx file structures\n");
}
else
{
PspLibExport *pHead;

COutput::Printf(LEVEL_INFO, "Dependancy list for %s\n", file);
pHead = prx.GetExports();
while(pHead != NULL)
{
write_ent(pHead, f);
pHead = pHead->next;
}
}
}

void output_stubs_xml(CNidMgr *pNids)
{
LibraryEntry *pLib = NULL;
Expand Down Expand Up @@ -940,6 +997,19 @@ int main(int argc, char **argv)
}
fprintf(out_fp, "</firmware>\n");
}
else if(g_outputMode == OUTPUT_ENT)
{
FILE *f = fopen("exports.exp", "w");

if (f != NULL)
{
fprintf(f, "# Export file automatically generated with prxtool\n");
fprintf(f, "PSP_BEGIN_EXPORTS\n\n");
output_ents(g_ppInfiles[0], &nids, f);
fprintf(f, "PSP_END_EXPORTS\n");
fclose(f);
}
}
else if(g_outputMode == OUTPUT_DISASM)
{
int iLoop;
Expand Down

0 comments on commit 185103a

Please sign in to comment.