Skip to content

Commit

Permalink
Import 64-bit fixes from dcload-ip
Browse files Browse the repository at this point in the history
This was fixed by BlueCrab in 2013 for dcload-ip
and just never made it into dcload-serial. The issue
is that the original dcload was set up to just sent
the raw host-side `DIR *` over to the target. This
worked fine when those pointers were 32-bit, but as
hosts moved to 64-bit it simply broke.

Now instead, we keep a cache of those pointers and
assign an fd before sending over to the target.
This is maintaining the offset like dcload-ip, but
a PR will be forthcoming to update fs_dcload to
undo the hack on the dc side.
  • Loading branch information
QuzarDC committed Jan 11, 2025
1 parent dd88dcc commit 52939d6
Showing 1 changed file with 47 additions and 14 deletions.
61 changes: 47 additions & 14 deletions host-src/tool/syscalls.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,14 @@
#define O_BINARY 0
#endif

/* Sigh... KOS treats anything under 100 as invalid for a dirent from dcload, so
we need to offset by a bit. This aught to do. */
#define DIRENT_OFFSET 1337

#define MAX_OPEN_DIRS 512

static DIR *opendirs[MAX_OPEN_DIRS];

void dc_fstat(void) {
int filedes;
struct stat filestat;
Expand Down Expand Up @@ -362,38 +370,58 @@ void dc_opendir(void) {
DIR *somedir;
unsigned char *dirname;
int namelen;
uint32_t i;

namelen = recv_uint();

dirname = malloc(namelen);

recv_data(dirname, namelen, 0);

somedir = opendir((const char *)dirname);
/* Find an open entry */
for(i = 0; i < MAX_OPEN_DIRS; ++i) {
if(!opendirs[i])
break;
}

if(i < MAX_OPEN_DIRS) {
if(!(opendirs[i] = opendir((const char *)dirname)))
i = 0;
else
i += DIRENT_OFFSET;
}
else {
i = 0;
}

send_uint((unsigned int)somedir);
send_uint(i);

free(dirname);
}

void dc_closedir(void) {
DIR *somedir;
int retval;
uint32_t i = recv_uint();

somedir = (DIR *) recv_uint();

retval = closedir(somedir);
if(i >= DIRENT_OFFSET && i < MAX_OPEN_DIRS + DIRENT_OFFSET) {
retval = closedir(opendirs[i - DIRENT_OFFSET]);
opendirs[i - DIRENT_OFFSET] = NULL;
}
else {
retval = -1;
}

send_uint(retval);
}

void dc_readdir(void) {
DIR *somedir;
struct dirent *somedirent;
uint32_t i = recv_uint();

somedir = (DIR *) recv_uint();

somedirent = readdir(somedir);
if(i >= DIRENT_OFFSET && i < MAX_OPEN_DIRS + DIRENT_OFFSET)
somedirent = readdir(opendirs[i - DIRENT_OFFSET]);
else
somedirent = NULL;

if(!somedirent) {
send_uint(0);
Expand Down Expand Up @@ -424,12 +452,17 @@ void dc_readdir(void) {
}

void dc_rewinddir(void) {
DIR *somedir;
int retval;
uint32_t i = recv_uint();

somedir = (DIR *) recv_uint();

rewinddir(somedir);
if(i >= DIRENT_OFFSET && i < MAX_OPEN_DIRS + DIRENT_OFFSET) {
rewinddir(opendirs[i - DIRENT_OFFSET]);
opendirs[i - DIRENT_OFFSET] = NULL;
retval = 0;
}
else {
retval = -1;
}

send_uint(0);
}
Expand Down

0 comments on commit 52939d6

Please sign in to comment.