Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IMP sceKernelFindModuleByUID and sceKernelFindModuleByName. #13592

Merged
merged 3 commits into from
Oct 28, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion Core/ELF/ElfReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -410,8 +410,10 @@ int ElfReader::LoadInto(u32 loadAddress, bool fromTop)
for (int i = 0; i < header->e_phnum; i++) {
const Elf32_Phdr *p = &segments[i];
if (p->p_type == PT_LOAD) {
if (p->p_vaddr < totalStart)
if (p->p_vaddr < totalStart) {
totalStart = p->p_vaddr;
firstSegAlign = p->p_align;
}
if (p->p_vaddr + p->p_memsz > totalEnd)
totalEnd = p->p_vaddr + p->p_memsz;
}
Expand Down Expand Up @@ -612,6 +614,16 @@ u32 ElfReader::GetTotalTextSize() const {
return total;
}

u32 ElfReader::GetTotalTextSizeFromSeg() const {
u32 total = 0;
for (int i = 0; i < GetNumSegments(); ++i) {
if ((segments[i].p_flags & PF_X) != 0) {
total += segments[i].p_filesz;
}
}
return total;
}

u32 ElfReader::GetTotalDataSize() const {
u32 total = 0;
for (int i = 0; i < GetNumSections(); ++i) {
Expand Down
6 changes: 6 additions & 0 deletions Core/ELF/ElfReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,10 @@ class ElfReader {
return segments[segment].p_memsz;
}

u32 GetFirstSegmentAlign() const {
return firstSegAlign;
}

bool DidRelocate() const {
return bRelocate;
}
Expand All @@ -127,6 +131,7 @@ class ElfReader {
}

u32 GetTotalTextSize() const;
u32 GetTotalTextSizeFromSeg() const;
u32 GetTotalDataSize() const;
u32 GetTotalSectionSizeByPrefix(const std::string &prefix) const;

Expand All @@ -151,4 +156,5 @@ class ElfReader {
u32 vaddr = 0;
u32 segmentVAddr[32];
size_t size_ = 0;
u32 firstSegAlign = 0;
};
81 changes: 72 additions & 9 deletions Core/HLE/sceKernelModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ struct NativeModule {
char name[28];
u32_le status;
u32_le unk1;
u32_le modid; // 0x2C
u32_le usermod_thid;
u32_le memid;
u32_le mpidtext;
Expand Down Expand Up @@ -233,7 +234,7 @@ enum NativeModuleStatus {

class PSPModule : public KernelObject {
public:
PSPModule() : textStart(0), textEnd(0), libstub(0), libstubend(0), memoryBlockAddr(0), isFake(false) {}
PSPModule() : textStart(0), textEnd(0), libstub(0), libstubend(0), memoryBlockAddr(0), isFake(false), modulePtr(0) {}
~PSPModule() {
if (memoryBlockAddr) {
// If it's either below user memory, or using a high kernel bit, it's in kernel.
Expand All @@ -244,6 +245,11 @@ class PSPModule : public KernelObject {
}
g_symbolMap->UnloadModule(memoryBlockAddr, memoryBlockSize);
}

if (modulePtr) {
//Only alloc at kernel memory.
kernelMemory.Free(modulePtr);
}
}
const char *GetName() override { return nm.name; }
const char *GetTypeName() override { return GetStaticTypeName(); }
Expand All @@ -263,11 +269,23 @@ class PSPModule : public KernelObject {

void DoState(PointerWrap &p) override
{
auto s = p.Section("Module", 1, 4);
auto s = p.Section("Module", 1, 5);
if (!s)
return;

Do(p, nm);
if (s >= 5) {
Do(p, nm);
} else {
char temp[192];
NativeModule *pnm = &nm;
char *ptemp = temp;
DoArray(p, ptemp, 0xC0);
memcpy(pnm, ptemp, 0x2C);
pnm->modid = GetUID();
pnm += 0x30;
ptemp += 0x2C;
memcpy(pnm, ptemp, 0xC0 - 0x2C);
}
Do(p, memoryBlockAddr);
Copy link
Contributor

@aliaspider aliaspider Oct 27, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not just put modid last in NativeModule to keep the struct backwards compatible and avoid this hack ? or is NativeModule something the real PSP OS uses and it just had wrong offsets before ?

Copy link
Contributor Author

@shenweip shenweip Oct 27, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NativeModule is a native struct of PSP, its members have fixed order(offset).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok I see.
why are you increasing both pnmand ptemp by 0x30 though ? shouldn't ptempbe increased by 0x2C instead ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, thanks.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Turns out the math was wrong - have to cast the pointers to bytes first :)

Fixed in 2f4dfed

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops again, thanks:p

Do(p, memoryBlockSize);
Do(p, isFake);
Expand All @@ -290,6 +308,10 @@ class PSPModule : public KernelObject {
Do(p, libstubend);
}

if (s >= 5) {
Do(p, modulePtr);
}

ModuleWaitingThread mwt = {0};
Do(p, waitingThreads, mwt);
FuncSymbolExport fsx = {{0}};
Expand Down Expand Up @@ -422,6 +444,7 @@ class PSPModule : public KernelObject {

u32 memoryBlockAddr;
u32 memoryBlockSize;
u32 modulePtr;
bool isFake;
};

Expand Down Expand Up @@ -1104,6 +1127,8 @@ static PSPModule *__KernelLoadELFFromPtr(const u8 *ptr, size_t elfSize, u32 load
loadedModules.insert(module->GetUID());
memset(&module->nm, 0, sizeof(module->nm));

module->nm.modid = module->GetUID();

bool reportedModule = false;
u32 devkitVersion = 0;
u8 *newptr = 0;
Expand Down Expand Up @@ -1310,6 +1335,12 @@ static PSPModule *__KernelLoadELFFromPtr(const u8 *ptr, size_t elfSize, u32 load
if (textSection == -1) {
module->textStart = reader.GetVaddr();
module->textEnd = firstImportStubAddr - 4;
// Reference Jpcsp.
if (reader.GetFirstSegmentAlign() > 0)
module->textStart &= ~(reader.GetFirstSegmentAlign() - 1);
// PSP set these values even if no section.
module->nm.text_addr = module->textStart;
module->nm.text_size = reader.GetTotalTextSizeFromSeg();
}

if (!module->isFake) {
Expand Down Expand Up @@ -1540,6 +1571,15 @@ static PSPModule *__KernelLoadELFFromPtr(const u8 *ptr, size_t elfSize, u32 load
}
}

u32 moduleSize = sizeof(module->nm);
char tag[32];
snprintf(tag, sizeof(tag), "SceModule-%d", module->nm.modid);
module->modulePtr = kernelMemory.Alloc(moduleSize, true, tag);

// Fill the struct.
if (Memory::IsValidAddress(module->modulePtr))
Memory::WriteStruct(module->modulePtr, &module->nm);

error = 0;
return module;
}
Expand Down Expand Up @@ -1896,6 +1936,15 @@ u32 sceKernelLoadModule(const char *name, u32 flags, u32 optionAddr) {
module->nm.entry_addr = -1;
module->nm.gp_value = -1;

u32 moduleSize = sizeof(module->nm);
char tag[32];
snprintf(tag, sizeof(tag), "SceModule-%d", module->nm.modid);
module->modulePtr = kernelMemory.Alloc(moduleSize, true, tag);

// Fill the struct.
if(Memory::IsValidAddress(module->modulePtr))
Memory::WriteStruct(module->modulePtr, &module->nm);

// TODO: It would be more ideal to allocate memory for this module.

return hleLogSuccessInfoI(LOADER, module->GetUID(), "created fake module");
Expand Down Expand Up @@ -2367,16 +2416,30 @@ static u32 sceKernelGetModuleId()

u32 sceKernelFindModuleByUID(u32 uid)
{
ERROR_LOG(SCEMODULE, "UNIMPL sceKernelFindModuleByUID(%d)", uid);
return 0;
u32 error;
PSPModule *module = kernelObjects.Get<PSPModule>(uid, error);
if (!module || module->isFake) {
ERROR_LOG(SCEMODULE, "0 = sceKernelFindModuleByUID(%d): Module Not Found or Fake", uid);
return 0;
}
INFO_LOG(SCEMODULE, "%d = sceKernelFindModuleByUID(%d)", module->modulePtr, uid);
return module->modulePtr;
}

u32 sceKernelFindModuleByName(const char *name)
{
int index = GetModuleIndex(name);
u32 temp = index + 1;
INFO_LOG(SCEMODULE, "%d = sceKernelFindModuleByName(%s)", temp, name);
return temp;
u32 error;
for (SceUID moduleId : loadedModules) {
PSPModule *module = kernelObjects.Get<PSPModule>(moduleId, error);
if (!module)
continue;
if (!module->isFake && strcmp(name, module->nm.name) == 0) {
INFO_LOG(SCEMODULE, "%d = sceKernelFindModuleByName(%s)", module->modulePtr, name);
return module->modulePtr;
}
}
WARN_LOG(SCEMODULE, "0 = sceKernelFindModuleByName(%s): Module Not Found or Fake", name);
return 0;
}

static u32 sceKernelLoadModuleByID(u32 id, u32 flags, u32 lmoptionPtr)
Expand Down