Skip to content

Conversation

localcc
Copy link

@localcc localcc commented Jun 22, 2025

This PR adds almost complete ppc64 support to mlibc. There are mainly two issues with this port currently:

  • a couple of TODOs left unimplemented as i never got them to trigger in a testing environment so those will be fixed later.
  • long double support is not completely finished, some functions work properly and some are left broken due to the implementation being too complex to do right now for a feature I wouldn't use

I am also currently not sure if ppc64 support compiles on anything but my custom fork of llvm, so there might be dragons there. I will test it with gcc at some point and report the results. Considering the compilation difficulties I am first creating this as a draft PR so that code can be gradually reviewed.

@localcc
Copy link
Author

localcc commented Jun 22, 2025

also worth noting i based this off the v6.0.1 release so there are extraneous commits in here for some reason

@marv7000
Copy link
Contributor

Just rebase onto master

This also removes .init/.fini constructors as they're not needed
Copy link
Member

@no92 no92 left a comment

Choose a reason for hiding this comment

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

First pass on everything but the assembly.

A few general notes:

  • reformatting the codebase in this PR is out of scope, splitting that into its own PR would be reasonable
  • squashing the two remaining commits would be nice, too
  • the indent on assembly files is mixed

I don't know too much about ppc64 assembly so I'll have to read up on that first.

Comment on lines +101 to +103
#define FE_DOWNWARD 0b11
#define FE_TOWARDZERO 0b01
#define FE_UPWARD 0b10
Copy link
Member

Choose a reason for hiding this comment

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

Binary literals are compiler extensions and should therefore not be used in public headers.

#endif
#if defined(__powerpc64__)
case DT_LOPROC:
case 0x70000003: // unknown
Copy link
Member

Choose a reason for hiding this comment

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

From binutils source, this seems to be DT_PPC64_OPT which specifies what optimizations can be used with the ELFv2 ABI.

@@ -180,7 +189,159 @@ extern "C" void relocateSelf() {
}
}
}
#else
#elif defined(__powerpc64__)
// ppc64 elfv1 can't rely on the OPD before relocations, therefore calling the getLdsoBase function
Copy link
Member

Choose a reason for hiding this comment

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

I wonder if we could just force-inline the function on ppc64?

Copy link
Author

Choose a reason for hiding this comment

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

doesn't work unfortunately

@@ -405,6 +568,16 @@ extern "C" void *interpreterMain(uintptr_t *entry_stack) {
<< " in program interpreter" << frg::endlog;
break;
}
#if defined(__powerpc64__)
case DT_LOPROC:
case 0x70000003: // unknown
Copy link
Member

Choose a reason for hiding this comment

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

See above.

@@ -0,0 +1 @@
#pragma once
Copy link
Member

Choose a reason for hiding this comment

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

Leftover?

// tcbhead->hwcap_extn = (static_cast<uint64_t>(aux_vec.at_hwcap3) << 32) |
// aux_vec.at_hwcap4; tcbhead->at_platform = aux_vec.at_platform;

uintptr_t thread_data = reinterpret_cast<uintptr_t>(pointer) + 0x7000 + sizeof(Tcb);
Copy link
Member

Choose a reason for hiding this comment

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

It would be preferable to use the constant for the TCB offset.

#elif defined(__powerpc64__)
// TP should point to the address 0x7000 bytes after the TCB.
// TODO: We should change the sysdep so that we don't need to do this.
auto tp = reinterpret_cast<char *>(tcb) + sizeof(Tcb) + 0x7000;
Copy link
Member

Choose a reason for hiding this comment

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

Constant.

Comment on lines +138 to +142
// tcbhead_t* tcbhead = reinterpret_cast<tcbhead_t*>(reinterpret_cast<uintptr_t>(pointer) -
// sizeof(tcbhead_t)); const auto& aux_vec = get_aux_vec();
// tcbhead->hwcap = (static_cast<uint64_t>(aux_vec.at_hwcap) << 32) | aux_vec.at_hwcap2;
// tcbhead->hwcap_extn = (static_cast<uint64_t>(aux_vec.at_hwcap3) << 32) |
// aux_vec.at_hwcap4; tcbhead->at_platform = aux_vec.at_platform;
Copy link
Member

Choose a reason for hiding this comment

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

Why is hwcap setup done here instead of somewhere further up the callchain?

Copy link
Author

Choose a reason for hiding this comment

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

no clue tbh where it should be done

@@ -663,6 +694,11 @@ int sys_clone(void *tcb, pid_t *pid_out, void *stack) {
// TODO: We should change the sysdep so that we don't need to do this.
auto tp = reinterpret_cast<char *>(tcb) + sizeof(Tcb) - 0x10;
tcb = reinterpret_cast<void *>(tp);
#elif defined(__powerpc64__)
// TP should point to the address 0x7000 bytes after the TCB.
Copy link
Member

Choose a reason for hiding this comment

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

after the end of the TCB

Comment on lines +81 to +91
struct shmid_ds {
struct ipc_perm shm_perm;
time_t shm_atime;
time_t shm_dtime;
time_t shm_ctime;
size_t shm_segsz;
pid_t shm_cpid;
pid_t shm_lpid;
unsigned long shm_nattch;
unsigned long __unused[2];
};
Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure this is correct - this seems to match the definition of shmid64_ds for ppc64, which is a different struct. I think the correct definition is the one above.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants