From 772bb53d88022c8db881f2ef04b6bdefce53fb83 Mon Sep 17 00:00:00 2001 From: Daniel Sumorok Date: Sun, 28 Apr 2013 20:35:07 -0400 Subject: [PATCH 01/35] Added etherslave network option of OS X that uses bpf to read and write raw ethernet frames. Separated out OSX video and sound options so you build with gtk video but with OS X sound support. Changed ordering native video modes are searched to work around an issue on OS X with 16-bit color under xwindows. --- BasiliskII/src/MacOSX/etherslavetool.c | 291 +++++++++++++++++++++++++ BasiliskII/src/MacOSX/runtool.m | 78 +++++++ BasiliskII/src/Unix/.gitignore | 1 + BasiliskII/src/Unix/Makefile.in | 9 +- BasiliskII/src/Unix/configure.ac | 22 +- BasiliskII/src/Unix/ether_unix.cpp | 179 ++++++++++++++- BasiliskII/src/Unix/prefs_unix.cpp | 3 + BasiliskII/src/Unix/video_x.cpp | 2 +- 8 files changed, 581 insertions(+), 4 deletions(-) create mode 100644 BasiliskII/src/MacOSX/etherslavetool.c create mode 100644 BasiliskII/src/MacOSX/runtool.m diff --git a/BasiliskII/src/MacOSX/etherslavetool.c b/BasiliskII/src/MacOSX/etherslavetool.c new file mode 100644 index 00000000..2f3b3a4f --- /dev/null +++ b/BasiliskII/src/MacOSX/etherslavetool.c @@ -0,0 +1,291 @@ +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include + +#include + +static int openBpf(char *ifname); +static int retreiveAuthInfo(void); +static int mainLoop(int sd); + +int main(int argc, char **argv) { + char *ifName; + int ret; + int sd; + + if(argc != 2) { + return 255; + } + + ifName = argv[1]; + + ret = retreiveAuthInfo(); + if(ret != 0) { + return 254; + } + + fflush(stdout); + + sd = openBpf(ifName); + if(sd < 0) { + return 253; + } + + fflush(stdout); + + ret = mainLoop(sd); + + close(sd); + + if(ret < 0) { + return 252; + } + + return 0; +} + +static int mainLoop(int sd) { + fd_set readSet; + char *outgoing, *incoming; + unsigned short *outLen; + unsigned short *inLen; + int inIndex, outIndex; + u_int blen = 0; + int ret; + int fret = 0; + struct bpf_hdr *hdr; + int pktLen; + int frameLen; + int pad; + + if(ioctl(sd, BIOCGBLEN, &blen) < 0) { + return -1; + } + + incoming = malloc(blen); + if(incoming == NULL) { + return -2; + } + + outgoing = malloc(blen); + if(outgoing == NULL) { + free(outgoing); + return -3; + } + + inIndex = 0; + outIndex = 0; + + outLen = (unsigned short *)outgoing; + + while(1) { + int i; + FD_ZERO(&readSet); + FD_SET(0, &readSet); + FD_SET(sd, &readSet); + + ret = select(sd + 1, &readSet, NULL, NULL, NULL); + if(ret < 0) { + fret = -4; + break; + } + + if(FD_ISSET(0, &readSet)) { + if(outIndex < 2) { + ret = read(0, outgoing + outIndex, 2-outIndex); + } else { + ret = read(0, outgoing + outIndex, *outLen - outIndex + 2); + } + + if(ret < 1) { + fret = -5; + break; + } + + outIndex += ret; + if(outIndex > 1) { + fflush(stdout); + + if((*outLen + 2) > blen) { + fret = -6; + break; + } + + if(outIndex == (*outLen + 2)) { + ret = write(sd, outLen + 1, *outLen); + if(ret != *outLen) { + fret = -7; + break; + } + outIndex = 0; + } + } + + } + + if(FD_ISSET(sd, &readSet)) { + int i; + + ret = read(sd, incoming, blen); + if(ret < 1) { + fret = -8; + break; + } + + hdr = (struct bpf_hdr *)incoming; + inLen = (unsigned short *)(incoming + 16); + + do { + pktLen = hdr->bh_caplen; + frameLen = pktLen + 18; + + if((pktLen < 0) || (frameLen > ret) || (frameLen < 0)) { + fret = -9; + break; + } + *inLen = pktLen; + + write(0, inLen, pktLen + 2); + /* printf("%02X%02X %02X%02X %02X%02X %02X%02X\n", */ + /* *((unsigned char *)inLen + 0), */ + /* *((unsigned char *)inLen + 1), */ + /* *((unsigned char *)inLen + 2), */ + /* *((unsigned char *)inLen + 3), */ + /* *((unsigned char *)inLen + 4), */ + /* *((unsigned char *)inLen + 5), */ + /* *((unsigned char *)inLen + 6), */ + /* *((unsigned char *)inLen + 7)); */ + + /* printf("Read %d, len = %d, diff = %d.\n", ret, pktLen, */ + /* ret - pktLen); */ + /* fflush(stdout); */ + + if((frameLen & 0x03) == 0) { + pad = 0; + } else { + pad = 4 - (frameLen & 0x03); + } + + ret -= (frameLen + pad); + hdr = (struct bpf_hdr *)((unsigned char *)hdr + frameLen + pad); + inLen = (unsigned short *)((unsigned char *)hdr + 16); + } while (ret > 0); + + if(fret != 0) { + break; + } + } + } + + free(incoming); + free(outgoing); + + return fret; +} + +static int retreiveAuthInfo(void) { + AuthorizationRef aRef; + OSStatus status; + AuthorizationRights myRights; + AuthorizationRights *newRights; + AuthorizationItem *myItem; + AuthorizationItem myItems[1]; + AuthorizationItemSet *mySet; + int i; + + status = AuthorizationCopyPrivilegedReference(&aRef, kAuthorizationFlagDefaults); + if(status != errAuthorizationSuccess) { + return -1; + } + + status = AuthorizationCopyInfo(aRef, NULL, &mySet); + if(status != errAuthorizationSuccess) { + AuthorizationFree(aRef, kAuthorizationFlagDestroyRights); + return -1; + } + + myItems[0].name = "system.privilege.admin"; + myItems[0].valueLength = 0; + myItems[0].value = NULL; + myItems[0].flags = 0; + + myRights.count = sizeof (myItems) / sizeof (myItems[0]); + myRights.items = myItems; + + status = AuthorizationCopyRights(aRef, &myRights, NULL, + kAuthorizationFlagExtendRights, + &newRights); + if(status != errAuthorizationSuccess) { + AuthorizationFreeItemSet(mySet); + AuthorizationFree(aRef, kAuthorizationFlagDestroyRights); + return -2; + } + + AuthorizationFreeItemSet(newRights); + AuthorizationFreeItemSet(mySet); + AuthorizationFree(aRef, kAuthorizationFlagDestroyRights); + + return 0; +} + +static int openBpf(char *ifname) { + u_int blen = 0; + struct ifreq ifreq; + u_int arg; + + int sd = open("/dev/bpf2", O_RDWR); + + if(sd < 0) { + return -1; + } + + if(ioctl(sd, BIOCGBLEN, &blen) < 0) { + close(sd); + return -2; + } + + bzero(&ifreq, sizeof(ifreq)); + strncpy(ifreq.ifr_name, ifname, IFNAMSIZ); + + arg = 0; + if(ioctl(sd, BIOCSETIF, &ifreq) < 0) { + close(sd); + return -3; + } + + arg = 0; + if(ioctl(sd, BIOCSSEESENT, &arg) < 0) { + close(sd); + return -4; + } + + arg = 1; + if(ioctl(sd, BIOCPROMISC, &arg) < 0) { + close(sd); + return -5; + } + + arg = 1; + if(ioctl(sd, BIOCIMMEDIATE, &arg) < 0) { + close(sd); + return -6; + } + + return sd; +} diff --git a/BasiliskII/src/MacOSX/runtool.m b/BasiliskII/src/MacOSX/runtool.m new file mode 100644 index 00000000..5fc2b69e --- /dev/null +++ b/BasiliskII/src/MacOSX/runtool.m @@ -0,0 +1,78 @@ +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include + +#include + +FILE * runTool(const char *ifName); + +FILE * runTool(const char *ifName) { + OSStatus authStatus; + FILE *fp; + char *args[] = {"ethsheeptool", NULL, NULL}; + int ret; + const char *path; + + path = [[[NSBundle mainBundle] pathForResource:@"etherslavetool" ofType: nil] UTF8String]; + + if(path == NULL) { + return NULL; + } + + AuthorizationFlags authFlags; + AuthorizationRef authRef; + AuthorizationItem authItems[1]; + AuthorizationRights authRights; + + args[1] = (char *)ifName; + + authFlags = kAuthorizationFlagExtendRights | + kAuthorizationFlagInteractionAllowed | + kAuthorizationFlagPreAuthorize; + + authItems[0].name = "system.privilege.admin"; + authItems[0].valueLength = 0; + authItems[0].value = NULL; + authItems[0].flags = 0; + + authRights.count = sizeof (authItems) / sizeof (authItems[0]); + authRights.items = authItems; + + authStatus = AuthorizationCreate(&authRights, + kAuthorizationEmptyEnvironment, + authFlags, + &authRef); + + if(authStatus != errAuthorizationSuccess) { + fprintf(stderr, "%s: AuthorizationCreate() failed.\n", __func__); + return NULL; + } + + authStatus = AuthorizationExecuteWithPrivileges(authRef, + path, + kAuthorizationFlagDefaults, + args + 1, + &fp); + + if(authStatus != errAuthorizationSuccess) { + fprintf(stderr, "%s: AuthorizationExecWithPrivileges() failed.\n", __func__); + return NULL; + } + + return fp; +} diff --git a/BasiliskII/src/Unix/.gitignore b/BasiliskII/src/Unix/.gitignore index cc9e93f6..6d074222 100644 --- a/BasiliskII/src/Unix/.gitignore +++ b/BasiliskII/src/Unix/.gitignore @@ -1,6 +1,7 @@ # Object files obj/* BasiliskII +etherslavetool # Autotools generated files Makefile diff --git a/BasiliskII/src/Unix/Makefile.in b/BasiliskII/src/Unix/Makefile.in index e50326a8..c0d74188 100644 --- a/BasiliskII/src/Unix/Makefile.in +++ b/BasiliskII/src/Unix/Makefile.in @@ -74,6 +74,10 @@ CXXFLAGS += $(GUI_CFLAGS) LIBS += $(GUI_LIBS) endif +ifeq (@MACOSX_ETHERSLAVE@,yes) +PROGS += etherslavetool +endif + ## Rules .PHONY: modules install installdirs uninstall mostlyclean clean distclean depend dep .SUFFIXES: @@ -138,6 +142,9 @@ $(GUI_APP)_app: $(GUI_APP) ../MacOSX/Info.plist ../MacOSX/$(APP).icns mkdir -p $(GUI_APP_APP)/Contents/Resources ./cpr.sh ../MacOSX/$(APP).icns $(GUI_APP_APP)/Contents/Resources/$(GUI_APP).icns +etherslavetool: ../MacOSX/etherslavetool.c + $(CC) $(CPPFLAGS) $(DEFS) $(CFLAGS) $(LIBS) $< -o $@ + modules: cd Linux/NetDriver; make @@ -167,7 +174,7 @@ mostlyclean: rm -f $(PROGS) $(OBJ_DIR)/* core* *.core *~ *.bak clean: mostlyclean - rm -f cpuemu.cpp cpudefs.cpp cputmp*.s cpufast*.s cpustbl.cpp cputbl.h compemu.cpp compstbl.cpp comptbl.h + rm -f cpuemu.cpp cpudefs.cpp cputmp*.s cpufast*.s cpustbl.cpp cputbl.h compemu.cpp compstbl.cpp comptbl.h Darwin/lowmem Darwin/pagezero distclean: clean rm -rf $(OBJ_DIR) diff --git a/BasiliskII/src/Unix/configure.ac b/BasiliskII/src/Unix/configure.ac index 62d45f57..0816b19c 100644 --- a/BasiliskII/src/Unix/configure.ac +++ b/BasiliskII/src/Unix/configure.ac @@ -21,6 +21,12 @@ AC_ARG_ENABLE(standalone-gui,[ --enable-standalone-gui enable a standalone GUI dnl Mac OS X GUI. AC_ARG_ENABLE(macosx-gui, [ --enable-macosx-gui enable Mac OS X GUI [default=no]], [WANT_MACOSX_GUI=$enableval], [WANT_MACOSX_GUI=no]) +dnl Mac OS X Sound +AC_ARG_ENABLE(macosx-sound, [ --enable-macosx-sound enable Mac OS X Sound [default=no]], [WANT_MACOSX_SOUND=$enableval], [WANT_MACOSX_SOUND=no]) + +dnl Mac OS X etherslave support +AC_ARG_ENABLE(macosx-etherslave, [ --enable-macosx-etherslave enable Mac OS X Sound [default=no]], [WANT_MACOSX_ETHERSLAVE=$enableval], [WANT_MACOSX_ETHERSLAVE=no]) + dnl Video options. AC_ARG_ENABLE(xf86-dga, [ --enable-xf86-dga use the XFree86 DGA extension [default=yes]], [WANT_XF86_DGA=$enableval], [WANT_XF86_DGA=yes]) AC_ARG_ENABLE(xf86-vidmode, [ --enable-xf86-vidmode use the XFree86 VidMode extension [default=yes]], [WANT_XF86_VIDMODE=$enableval], [WANT_XF86_VIDMODE=yes]) @@ -509,6 +515,7 @@ mips-sony-bsd|mips-sony-newsos4) ;; *-*-darwin*) no_dev_ptmx=1 + LIBS="$LIBS -lstdc++" ;; esac @@ -678,6 +685,8 @@ darwin*) if [[ "x$ac_cv_framework_Carbon" = "xyes" ]]; then EXTFSSRC=../MacOSX/extfs_macosx.cpp fi + EXTRASYSSRCS="$EXTRASYSSRCS ../MacOSX/runtool.m" + LIBS="$LIBS -framework Security" ;; cygwin*) SERIALSRC="../dummy/serial_dummy.cpp" @@ -719,11 +728,21 @@ if [[ "x$WANT_MACOSX_GUI" = "xyes" ]]; then EXTRASYSSRCS="$EXTRASYSSRCS ../MacOSX/prefs_macosx.cpp" VIDEOSRCS="../MacOSX/video_macosx.mm" - AUDIOSRC="../MacOSX/audio_macosx.cpp ../MacOSX/AudioBackEnd.cpp ../MacOSX/AudioDevice.cpp ../MacOSX/MacOSX_sound_if.cpp" else EXTRASYSSRCS="$EXTRASYSSRCS main_unix.cpp prefs_unix.cpp" fi +if [[ "x$WANT_MACOSX_SOUND" = "xyes" ]]; then + AUDIOSRC="../MacOSX/audio_macosx.cpp ../MacOSX/AudioBackEnd.cpp ../MacOSX/AudioDevice.cpp ../MacOSX/MacOSX_sound_if.cpp" + LIBS="$LIBS -framework AudioToolbox -framework AudioUnit -framework CoreAudio" +fi + +if [[ "x$WANT_MACOSX_ETHERSLAVE" = "xyes" ]]; then + AC_DEFINE(ENABLE_MACOSX_ETHERSLAVE, 1, [Define if supporting "etherslave" network device.]) +fi + +AC_SUBST(MACOSX_ETHERSLAVE, $WANT_MACOSX_ETHERSLAVE) + dnl SDL overrides if [[ "x$WANT_SDL" = "xyes" ]]; then AC_DEFINE(USE_SDL, 1, [Define to enble SDL support]) @@ -1748,6 +1767,7 @@ echo echo Basilisk II configuration summary: echo echo Mac OS X GUI ........................... : $WANT_MACOSX_GUI +echo Mac OS X Sound ......................... : $WANT_MACOSX_SOUND echo SDL support ............................ : $SDL_SUPPORT echo BINCUE support ......................... : $have_bincue echo LIBVHD support ......................... : $have_libvhd diff --git a/BasiliskII/src/Unix/ether_unix.cpp b/BasiliskII/src/Unix/ether_unix.cpp index 526ee29c..ba6ea800 100644 --- a/BasiliskII/src/Unix/ether_unix.cpp +++ b/BasiliskII/src/Unix/ether_unix.cpp @@ -41,6 +41,12 @@ #endif #include #include + +#ifdef ENABLE_MACOSX_ETHERSLAVE +#include +#include +#endif + #include #include #include @@ -93,9 +99,17 @@ enum { NET_IF_SHEEPNET, NET_IF_ETHERTAP, NET_IF_TUNTAP, - NET_IF_SLIRP + NET_IF_SLIRP, + NET_IF_ETHERSLAVE }; + +#ifdef ENABLE_MACOSX_ETHERSLAVE +extern "C" { + extern FILE * runTool(const char *ifName); +} +#endif + // Constants #if ENABLE_TUNTAP static const char ETHERCONFIG_FILE_NAME[] = DATADIR "/tunconfig"; @@ -122,6 +136,11 @@ static uint8 ether_addr[6]; // Our Ethernet address const bool ether_driver_opened = true; // Flag: is the MacOS driver opened? #endif + +#ifdef ENABLE_MACOSX_ETHERSLAVE +static uint8 packet_buffer[2048]; +#endif + // Attached network protocols, maps protocol type to MacOS handler address static map net_protocols; @@ -135,6 +154,11 @@ static void ether_do_interrupt(void); static void slirp_add_redirs(); static int slirp_add_redir(const char *redir_str); +#ifdef ENABLE_MACOSX_ETHERSLAVE +static int getmacaddress(const char* dev, unsigned char *addr); +static bool openEtherSlave(const char *ifName); +static int readpacket(void); +#endif /* * Start packet reception thread @@ -235,6 +259,9 @@ bool ether_init(void) // Do nothing if no Ethernet device specified const char *name = PrefsFindString("ether"); +#ifdef ENABLE_MACOSX_ETHERSLAVE + const char *slaveDev = PrefsFindString("etherslavedev"); +#endif if (name == NULL) return false; @@ -249,6 +276,10 @@ bool ether_init(void) #ifdef HAVE_SLIRP else if (strcmp(name, "slirp") == 0) net_if_type = NET_IF_SLIRP; +#endif +#ifdef ENABLE_MACOSX_ETHERSLAVE + else if (strcmp(name, "etherslave") == 0) + net_if_type = NET_IF_ETHERSLAVE; #endif else net_if_type = NET_IF_SHEEPNET; @@ -300,6 +331,14 @@ bool ether_init(void) case NET_IF_SHEEPNET: strcpy(dev_name, "/dev/sheep_net"); break; +#ifdef ENABLE_MACOSX_ETHERSLAVE + case NET_IF_ETHERSLAVE: + if(slaveDev == NULL) { + WarningAlert("etherslavedev not defined in preferences."); + return false; + } + return openEtherSlave(slaveDev); +#endif } if (net_if_type != NET_IF_SLIRP) { fd = open(dev_name, O_RDWR); @@ -750,6 +789,21 @@ static int16 ether_do_write(uint32 arg) write(slirp_input_fd, packet, len); return noErr; } else +#endif +#ifdef ENABLE_MACOSX_ETHERSLAVE + if (net_if_type == NET_IF_ETHERSLAVE) { + unsigned short pktlen; + + pktlen = len; + if(write(fd, &pktlen, 2) < 2) { + return excessCollsns; + } + + if(write(fd, packet, len) < len) { + return excessCollsns; + } + return noErr; + } else #endif if (write(fd, packet, len) < 0) { D(bug("WARNING: Couldn't transmit packet\n")); @@ -884,6 +938,13 @@ static void *receive_func(void *arg) if (res <= 0) break; +#ifdef ENABLE_MACOSX_ETHERSLAVE + if (net_if_type == NET_IF_ETHERSLAVE) { + if(readpacket() < 1) { + break; + } + } +#endif if (ether_driver_opened) { // Trigger Ethernet interrupt D(bug(" packet received, triggering Ethernet interrupt\n")); @@ -923,6 +984,18 @@ void ether_do_interrupt(void) ether_udp_read(packet, length, &from); } else +#endif +#ifdef ENABLE_MACOSX_ETHERSLAVE + if (net_if_type == NET_IF_ETHERSLAVE) { + unsigned short *pktlen; + uint32 p = packet; + + pktlen = (unsigned short *)packet_buffer; + length = *pktlen; + memcpy(Mac2HostAddr(packet), pktlen + 1, length); + ether_dispatch_packet(p, length); + break; + } else #endif { @@ -1049,3 +1122,107 @@ static int slirp_add_redir(const char *redir_str) WarningAlert(str); return -1; } + +#ifdef ENABLE_MACOSX_ETHERSLAVE +static int getmacaddress(const char* dev, unsigned char *addr) { + struct ifaddrs *ifaddrs, *next; + int ret = -1; + struct sockaddr_dl *sa; + + if(getifaddrs(&ifaddrs) != 0) { + perror("getifaddrs"); + return -1; + } + + next = ifaddrs; + while(next != NULL) { + switch(next->ifa_addr->sa_family) { + case AF_LINK: + if(!strcmp(dev, next->ifa_name)) { + sa = (struct sockaddr_dl *)next->ifa_addr; + memcpy(addr, LLADDR(sa), 6); + ret = 0; + } + break; + default: + break; + } + next = next->ifa_next; + } + + freeifaddrs(ifaddrs); + + return ret; +} + +static bool openEtherSlave(const char *ifName) { + FILE *fp; + char str[64]; + + str[sizeof(str)-1] = '\0'; + + if(getmacaddress(ifName, ether_addr) != 0) { + snprintf(str, sizeof(str)-1, "Unable to find interface %s.", + ifName); + WarningAlert(str); + return false; + } + + fp = runTool(ifName); + if(fp == NULL) { + snprintf(str, sizeof(str)-1, "Unable to run ether slave helper tool."); + WarningAlert(str); + return false; + } + + fd = dup(fileno(fp)); + fclose(fp); + + if(start_thread() == false) { + close(fd); + fd = -1; + return false; + } + + return true; +} + +static int readpacket() { + int index; + unsigned short *pktLen; + int ret = -1; + + pktLen = (unsigned short *)packet_buffer; + + index = 0; + while(1) { + if(index < 2) { + ret = read(fd, packet_buffer + index, 2 - index); + } else { + ret = read(fd, packet_buffer + index, *pktLen - index + 2); + } + + if(ret < 1) { + fprintf(stderr, "%s: read() returned %d.\n", __func__, ret); + break; + } + + index += ret; + + if(index > 1) { + if(*pktLen > (sizeof(packet_buffer) + 2)) { + fprintf(stderr, "%s: pktLen (%d) too large.\n", __func__, *pktLen); + break; + } + + if(index == (*pktLen + 2)) { + ret = *pktLen; + break; + } + } + } + + return ret; +} + +#endif diff --git a/BasiliskII/src/Unix/prefs_unix.cpp b/BasiliskII/src/Unix/prefs_unix.cpp index a92cd640..43f70fb6 100644 --- a/BasiliskII/src/Unix/prefs_unix.cpp +++ b/BasiliskII/src/Unix/prefs_unix.cpp @@ -40,6 +40,9 @@ prefs_desc platform_prefs_items[] = { {"mixer", TYPE_STRING, false, "audio mixer device name"}, #ifdef HAVE_SIGSEGV_SKIP_INSTRUCTION {"ignoresegv", TYPE_BOOLEAN, false, "ignore illegal memory accesses"}, +#endif +#ifdef ENABLE_MACOSX_ETHERSLAVE + {"etherslavedev", TYPE_STRING, false, "ethernet device for etherslave ethernet"}, #endif {"idlewait", TYPE_BOOLEAN, false, "sleep when idle"}, {NULL, TYPE_END, false, NULL} // End of list diff --git a/BasiliskII/src/Unix/video_x.cpp b/BasiliskII/src/Unix/video_x.cpp index 6f8ef67f..aa3c678f 100644 --- a/BasiliskII/src/Unix/video_x.cpp +++ b/BasiliskII/src/Unix/video_x.cpp @@ -328,7 +328,7 @@ static bool find_visual_for_depth(video_depth depth) bool visual_found = false; for (int i=0; i max_depth) continue; From a250b40c80e2ec055091291a5a753b0e28c4d893 Mon Sep 17 00:00:00 2001 From: Dan Sumorok Date: Tue, 30 Apr 2013 20:46:31 -0400 Subject: [PATCH 02/35] Added new etherlave network option for OS X. --- BasiliskII/src/MacOSX/etherslavetool.c | 277 +++++++++++++++++++++++++ BasiliskII/src/MacOSX/runtool.m | 79 +++++++ BasiliskII/src/Unix/.gitignore | 1 + BasiliskII/src/Unix/Makefile.in | 7 + BasiliskII/src/Unix/configure.ac | 11 + BasiliskII/src/Unix/ether_unix.cpp | 182 +++++++++++++++- BasiliskII/src/Unix/prefs_unix.cpp | 3 + 7 files changed, 559 insertions(+), 1 deletion(-) create mode 100644 BasiliskII/src/MacOSX/etherslavetool.c create mode 100644 BasiliskII/src/MacOSX/runtool.m diff --git a/BasiliskII/src/MacOSX/etherslavetool.c b/BasiliskII/src/MacOSX/etherslavetool.c new file mode 100644 index 00000000..08a18d97 --- /dev/null +++ b/BasiliskII/src/MacOSX/etherslavetool.c @@ -0,0 +1,277 @@ +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include + +#include + +static int openBpf(char *ifname); +static int retreiveAuthInfo(void); +static int mainLoop(int sd); + +int main(int argc, char **argv) { + char *ifName; + int ret; + int sd; + + if(argc != 2) { + return 255; + } + + ifName = argv[1]; + + ret = retreiveAuthInfo(); + if(ret != 0) { + return 254; + } + + fflush(stdout); + + sd = openBpf(ifName); + if(sd < 0) { + return 253; + } + + fflush(stdout); + + ret = mainLoop(sd); + + close(sd); + + if(ret < 0) { + return 252; + } + + return 0; +} + +static int mainLoop(int sd) { + fd_set readSet; + char *outgoing, *incoming; + unsigned short *outLen; + unsigned short *inLen; + int inIndex, outIndex; + u_int blen = 0; + int ret; + int fret = 0; + struct bpf_hdr *hdr; + int pktLen; + int frameLen; + int pad; + + if(ioctl(sd, BIOCGBLEN, &blen) < 0) { + return -1; + } + + incoming = malloc(blen); + if(incoming == NULL) { + return -2; + } + + outgoing = malloc(blen); + if(outgoing == NULL) { + free(outgoing); + return -3; + } + + inIndex = 0; + outIndex = 0; + + outLen = (unsigned short *)outgoing; + + while(1) { + int i; + FD_ZERO(&readSet); + FD_SET(0, &readSet); + FD_SET(sd, &readSet); + + ret = select(sd + 1, &readSet, NULL, NULL, NULL); + if(ret < 0) { + fret = -4; + break; + } + + if(FD_ISSET(0, &readSet)) { + if(outIndex < 2) { + ret = read(0, outgoing + outIndex, 2-outIndex); + } else { + ret = read(0, outgoing + outIndex, *outLen - outIndex + 2); + } + + if(ret < 1) { + fret = -5; + break; + } + + outIndex += ret; + if(outIndex > 1) { + fflush(stdout); + + if((*outLen + 2) > blen) { + fret = -6; + break; + } + + if(outIndex == (*outLen + 2)) { + ret = write(sd, outLen + 1, *outLen); + if(ret != *outLen) { + fret = -7; + break; + } + outIndex = 0; + } + } + + } + + if(FD_ISSET(sd, &readSet)) { + int i; + + ret = read(sd, incoming, blen); + if(ret < 1) { + fret = -8; + break; + } + + hdr = (struct bpf_hdr *)incoming; + inLen = (unsigned short *)(incoming + 16); + + do { + pktLen = hdr->bh_caplen; + frameLen = pktLen + 18; + + if((pktLen < 0) || (frameLen > ret) || (frameLen < 0)) { + fret = -9; + break; + } + *inLen = pktLen; + + write(0, inLen, pktLen + 2); + if((frameLen & 0x03) == 0) { + pad = 0; + } else { + pad = 4 - (frameLen & 0x03); + } + + ret -= (frameLen + pad); + hdr = (struct bpf_hdr *)((unsigned char *)hdr + frameLen + pad); + inLen = (unsigned short *)((unsigned char *)hdr + 16); + } while (ret > 0); + + if(fret != 0) { + break; + } + } + } + + free(incoming); + free(outgoing); + + return fret; +} + +static int retreiveAuthInfo(void) { + AuthorizationRef aRef; + OSStatus status; + AuthorizationRights myRights; + AuthorizationRights *newRights; + AuthorizationItem *myItem; + AuthorizationItem myItems[1]; + AuthorizationItemSet *mySet; + int i; + + status = AuthorizationCopyPrivilegedReference(&aRef, kAuthorizationFlagDefaults); + if(status != errAuthorizationSuccess) { + return -1; + } + + status = AuthorizationCopyInfo(aRef, NULL, &mySet); + if(status != errAuthorizationSuccess) { + AuthorizationFree(aRef, kAuthorizationFlagDestroyRights); + return -1; + } + + myItems[0].name = "system.privilege.admin"; + myItems[0].valueLength = 0; + myItems[0].value = NULL; + myItems[0].flags = 0; + + myRights.count = sizeof (myItems) / sizeof (myItems[0]); + myRights.items = myItems; + + status = AuthorizationCopyRights(aRef, &myRights, NULL, + kAuthorizationFlagExtendRights, + &newRights); + if(status != errAuthorizationSuccess) { + AuthorizationFreeItemSet(mySet); + AuthorizationFree(aRef, kAuthorizationFlagDestroyRights); + return -2; + } + + AuthorizationFreeItemSet(newRights); + AuthorizationFreeItemSet(mySet); + AuthorizationFree(aRef, kAuthorizationFlagDestroyRights); + + return 0; +} + +static int openBpf(char *ifname) { + u_int blen = 0; + struct ifreq ifreq; + u_int arg; + + int sd = open("/dev/bpf2", O_RDWR); + + if(sd < 0) { + return -1; + } + + if(ioctl(sd, BIOCGBLEN, &blen) < 0) { + close(sd); + return -2; + } + + bzero(&ifreq, sizeof(ifreq)); + strncpy(ifreq.ifr_name, ifname, IFNAMSIZ); + + arg = 0; + if(ioctl(sd, BIOCSETIF, &ifreq) < 0) { + close(sd); + return -3; + } + + arg = 0; + if(ioctl(sd, BIOCSSEESENT, &arg) < 0) { + close(sd); + return -4; + } + + arg = 1; + if(ioctl(sd, BIOCPROMISC, &arg) < 0) { + close(sd); + return -5; + } + + arg = 1; + if(ioctl(sd, BIOCIMMEDIATE, &arg) < 0) { + close(sd); + return -6; + } + + return sd; +} diff --git a/BasiliskII/src/MacOSX/runtool.m b/BasiliskII/src/MacOSX/runtool.m new file mode 100644 index 00000000..64f39f9d --- /dev/null +++ b/BasiliskII/src/MacOSX/runtool.m @@ -0,0 +1,79 @@ +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include + +#include + +FILE * runTool(const char *ifName); + +FILE * runTool(const char *ifName) { + OSStatus authStatus; + FILE *fp; + char *args[] = {"ethsheeptool", NULL, NULL}; + int ret; + const char *path; + + path = [[[NSBundle mainBundle] + pathForResource:@"etherslavetool" ofType: nil] UTF8String]; + + if(path == NULL) { + return NULL; + } + + AuthorizationFlags authFlags; + AuthorizationRef authRef; + AuthorizationItem authItems[1]; + AuthorizationRights authRights; + + args[1] = (char *)ifName; + + authFlags = kAuthorizationFlagExtendRights | + kAuthorizationFlagInteractionAllowed | + kAuthorizationFlagPreAuthorize; + + authItems[0].name = "system.privilege.admin"; + authItems[0].valueLength = 0; + authItems[0].value = NULL; + authItems[0].flags = 0; + + authRights.count = sizeof (authItems) / sizeof (authItems[0]); + authRights.items = authItems; + + authStatus = AuthorizationCreate(&authRights, + kAuthorizationEmptyEnvironment, + authFlags, + &authRef); + + if(authStatus != errAuthorizationSuccess) { + fprintf(stderr, "%s: AuthorizationCreate() failed.\n", __func__); + return NULL; + } + + authStatus = AuthorizationExecuteWithPrivileges(authRef, + path, + kAuthorizationFlagDefaults, + args + 1, + &fp); + + if(authStatus != errAuthorizationSuccess) { + fprintf(stderr, "%s: AuthorizationExecWithPrivileges() failed.\n", __func__); + return NULL; + } + + return fp; +} diff --git a/BasiliskII/src/Unix/.gitignore b/BasiliskII/src/Unix/.gitignore index cc9e93f6..6d074222 100644 --- a/BasiliskII/src/Unix/.gitignore +++ b/BasiliskII/src/Unix/.gitignore @@ -1,6 +1,7 @@ # Object files obj/* BasiliskII +etherslavetool # Autotools generated files Makefile diff --git a/BasiliskII/src/Unix/Makefile.in b/BasiliskII/src/Unix/Makefile.in index e50326a8..57a1c9d9 100644 --- a/BasiliskII/src/Unix/Makefile.in +++ b/BasiliskII/src/Unix/Makefile.in @@ -74,6 +74,10 @@ CXXFLAGS += $(GUI_CFLAGS) LIBS += $(GUI_LIBS) endif +ifeq (@MACOSX_ETHERSLAVE@,yes) +PROGS += etherslavetool +endif + ## Rules .PHONY: modules install installdirs uninstall mostlyclean clean distclean depend dep .SUFFIXES: @@ -138,6 +142,9 @@ $(GUI_APP)_app: $(GUI_APP) ../MacOSX/Info.plist ../MacOSX/$(APP).icns mkdir -p $(GUI_APP_APP)/Contents/Resources ./cpr.sh ../MacOSX/$(APP).icns $(GUI_APP_APP)/Contents/Resources/$(GUI_APP).icns +etherslavetool: ../MacOSX/etherslavetool.c + $(CC) $(CPPFLAGS) $(DEFS) $(CFLAGS) $(LIBS) $< -o $@ + modules: cd Linux/NetDriver; make diff --git a/BasiliskII/src/Unix/configure.ac b/BasiliskII/src/Unix/configure.ac index 62d45f57..93ff7aac 100644 --- a/BasiliskII/src/Unix/configure.ac +++ b/BasiliskII/src/Unix/configure.ac @@ -21,6 +21,9 @@ AC_ARG_ENABLE(standalone-gui,[ --enable-standalone-gui enable a standalone GUI dnl Mac OS X GUI. AC_ARG_ENABLE(macosx-gui, [ --enable-macosx-gui enable Mac OS X GUI [default=no]], [WANT_MACOSX_GUI=$enableval], [WANT_MACOSX_GUI=no]) +dnl Mac OS X etherslave support +AC_ARG_ENABLE(macosx-etherslave, [ --enable-macosx-etherslave enable Mac OS X Sound [default=no]], [WANT_MACOSX_ETHERSLAVE=$enableval], [WANT_MACOSX_ETHERSLAVE=no]) + dnl Video options. AC_ARG_ENABLE(xf86-dga, [ --enable-xf86-dga use the XFree86 DGA extension [default=yes]], [WANT_XF86_DGA=$enableval], [WANT_XF86_DGA=yes]) AC_ARG_ENABLE(xf86-vidmode, [ --enable-xf86-vidmode use the XFree86 VidMode extension [default=yes]], [WANT_XF86_VIDMODE=$enableval], [WANT_XF86_VIDMODE=yes]) @@ -724,6 +727,14 @@ else EXTRASYSSRCS="$EXTRASYSSRCS main_unix.cpp prefs_unix.cpp" fi +if [[ "x$WANT_MACOSX_ETHERSLAVE" = "xyes" ]]; then + EXTRASYSSRCS="$EXTRASYSSRCS ../MacOSX/runtool.m" + LIBS="$LIBS -framework Security" + AC_DEFINE(ENABLE_MACOSX_ETHERSLAVE, 1, [Define if supporting "etherslave" network device.]) +fi + +AC_SUBST(MACOSX_ETHERSLAVE, $WANT_MACOSX_ETHERSLAVE) + dnl SDL overrides if [[ "x$WANT_SDL" = "xyes" ]]; then AC_DEFINE(USE_SDL, 1, [Define to enble SDL support]) diff --git a/BasiliskII/src/Unix/ether_unix.cpp b/BasiliskII/src/Unix/ether_unix.cpp index 526ee29c..a2c07d2a 100644 --- a/BasiliskII/src/Unix/ether_unix.cpp +++ b/BasiliskII/src/Unix/ether_unix.cpp @@ -41,6 +41,12 @@ #endif #include #include + +#ifdef ENABLE_MACOSX_ETHERSLAVE +#include +#include +#endif + #include #include #include @@ -93,9 +99,17 @@ enum { NET_IF_SHEEPNET, NET_IF_ETHERTAP, NET_IF_TUNTAP, - NET_IF_SLIRP + NET_IF_SLIRP, + NET_IF_ETHERSLAVE }; + +#ifdef ENABLE_MACOSX_ETHERSLAVE +extern "C" { + extern FILE * runTool(const char *ifName); +} +#endif + // Constants #if ENABLE_TUNTAP static const char ETHERCONFIG_FILE_NAME[] = DATADIR "/tunconfig"; @@ -122,6 +136,11 @@ static uint8 ether_addr[6]; // Our Ethernet address const bool ether_driver_opened = true; // Flag: is the MacOS driver opened? #endif + +#ifdef ENABLE_MACOSX_ETHERSLAVE +static uint8 packet_buffer[2048]; +#endif + // Attached network protocols, maps protocol type to MacOS handler address static map net_protocols; @@ -135,6 +154,11 @@ static void ether_do_interrupt(void); static void slirp_add_redirs(); static int slirp_add_redir(const char *redir_str); +#ifdef ENABLE_MACOSX_ETHERSLAVE +static int getmacaddress(const char* dev, unsigned char *addr); +static bool openEtherSlave(const char *ifName); +static int readpacket(void); +#endif /* * Start packet reception thread @@ -235,6 +259,9 @@ bool ether_init(void) // Do nothing if no Ethernet device specified const char *name = PrefsFindString("ether"); +#ifdef ENABLE_MACOSX_ETHERSLAVE + const char *slaveDev = PrefsFindString("etherslavedev"); +#endif if (name == NULL) return false; @@ -249,6 +276,10 @@ bool ether_init(void) #ifdef HAVE_SLIRP else if (strcmp(name, "slirp") == 0) net_if_type = NET_IF_SLIRP; +#endif +#ifdef ENABLE_MACOSX_ETHERSLAVE + else if (strcmp(name, "etherslave") == 0) + net_if_type = NET_IF_ETHERSLAVE; #endif else net_if_type = NET_IF_SHEEPNET; @@ -300,6 +331,14 @@ bool ether_init(void) case NET_IF_SHEEPNET: strcpy(dev_name, "/dev/sheep_net"); break; +#ifdef ENABLE_MACOSX_ETHERSLAVE + case NET_IF_ETHERSLAVE: + if(slaveDev == NULL) { + WarningAlert("etherslavedev not defined in preferences."); + return false; + } + return openEtherSlave(slaveDev); +#endif } if (net_if_type != NET_IF_SLIRP) { fd = open(dev_name, O_RDWR); @@ -750,6 +789,21 @@ static int16 ether_do_write(uint32 arg) write(slirp_input_fd, packet, len); return noErr; } else +#endif +#ifdef ENABLE_MACOSX_ETHERSLAVE + if (net_if_type == NET_IF_ETHERSLAVE) { + unsigned short pktlen; + + pktlen = len; + if(write(fd, &pktlen, 2) < 2) { + return excessCollsns; + } + + if(write(fd, packet, len) < len) { + return excessCollsns; + } + return noErr; + } else #endif if (write(fd, packet, len) < 0) { D(bug("WARNING: Couldn't transmit packet\n")); @@ -884,6 +938,13 @@ static void *receive_func(void *arg) if (res <= 0) break; +#ifdef ENABLE_MACOSX_ETHERSLAVE + if (net_if_type == NET_IF_ETHERSLAVE) { + if(readpacket() < 1) { + break; + } + } +#endif if (ether_driver_opened) { // Trigger Ethernet interrupt D(bug(" packet received, triggering Ethernet interrupt\n")); @@ -923,6 +984,18 @@ void ether_do_interrupt(void) ether_udp_read(packet, length, &from); } else +#endif +#ifdef ENABLE_MACOSX_ETHERSLAVE + if (net_if_type == NET_IF_ETHERSLAVE) { + unsigned short *pktlen; + uint32 p = packet; + + pktlen = (unsigned short *)packet_buffer; + length = *pktlen; + memcpy(Mac2HostAddr(packet), pktlen + 1, length); + ether_dispatch_packet(p, length); + break; + } else #endif { @@ -1049,3 +1122,110 @@ static int slirp_add_redir(const char *redir_str) WarningAlert(str); return -1; } + +#ifdef ENABLE_MACOSX_ETHERSLAVE +static int getmacaddress(const char* dev, unsigned char *addr) +{ + struct ifaddrs *ifaddrs, *next; + int ret = -1; + struct sockaddr_dl *sa; + + if(getifaddrs(&ifaddrs) != 0) { + perror("getifaddrs"); + return -1; + } + + next = ifaddrs; + while(next != NULL) { + switch(next->ifa_addr->sa_family) { + case AF_LINK: + if(!strcmp(dev, next->ifa_name)) { + sa = (struct sockaddr_dl *)next->ifa_addr; + memcpy(addr, LLADDR(sa), 6); + ret = 0; + } + break; + default: + break; + } + next = next->ifa_next; + } + + freeifaddrs(ifaddrs); + + return ret; +} + +static bool openEtherSlave(const char *ifName) +{ + FILE *fp; + char str[64]; + + str[sizeof(str)-1] = '\0'; + + if(getmacaddress(ifName, ether_addr) != 0) { + snprintf(str, sizeof(str)-1, "Unable to find interface %s.", + ifName); + WarningAlert(str); + return false; + } + + fp = runTool(ifName); + if(fp == NULL) { + snprintf(str, sizeof(str)-1, "Unable to run ether slave helper tool."); + WarningAlert(str); + return false; + } + + fd = dup(fileno(fp)); + fclose(fp); + + if(start_thread() == false) { + close(fd); + fd = -1; + return false; + } + + return true; +} + +static int readpacket() +{ + int index; + unsigned short *pktLen; + int ret = -1; + + pktLen = (unsigned short *)packet_buffer; + + index = 0; + while(1) { + if(index < 2) { + ret = read(fd, packet_buffer + index, 2 - index); + } else { + ret = read(fd, packet_buffer + index, *pktLen - index + 2); + } + + if(ret < 1) { + fprintf(stderr, "%s: read() returned %d.\n", __func__, ret); + break; + } + + index += ret; + + if(index > 1) { + if(*pktLen > (sizeof(packet_buffer) + 2)) { + fprintf(stderr, "%s: pktLen (%d) too large.\n", __func__, *pktLen); + break; + } + + if(index == (*pktLen + 2)) { + ret = *pktLen; + break; + } + } + } + + return ret; +} + +#endif diff --git a/BasiliskII/src/Unix/prefs_unix.cpp b/BasiliskII/src/Unix/prefs_unix.cpp index a92cd640..43f70fb6 100644 --- a/BasiliskII/src/Unix/prefs_unix.cpp +++ b/BasiliskII/src/Unix/prefs_unix.cpp @@ -40,6 +40,9 @@ prefs_desc platform_prefs_items[] = { {"mixer", TYPE_STRING, false, "audio mixer device name"}, #ifdef HAVE_SIGSEGV_SKIP_INSTRUCTION {"ignoresegv", TYPE_BOOLEAN, false, "ignore illegal memory accesses"}, +#endif +#ifdef ENABLE_MACOSX_ETHERSLAVE + {"etherslavedev", TYPE_STRING, false, "ethernet device for etherslave ethernet"}, #endif {"idlewait", TYPE_BOOLEAN, false, "sleep when idle"}, {NULL, TYPE_END, false, NULL} // End of list From cf3b2786aeef6dca77ba11bbbde176c893738bd0 Mon Sep 17 00:00:00 2001 From: Dan Sumorok Date: Wed, 1 May 2013 06:39:15 -0400 Subject: [PATCH 03/35] Revert previous changes. Changes have been moved to branches. --- BasiliskII/src/MacOSX/etherslavetool.c | 291 ------------------------- BasiliskII/src/MacOSX/runtool.m | 78 ------- BasiliskII/src/Unix/.gitignore | 1 - BasiliskII/src/Unix/Makefile.in | 9 +- BasiliskII/src/Unix/configure.ac | 22 +- BasiliskII/src/Unix/ether_unix.cpp | 179 +-------------- BasiliskII/src/Unix/prefs_unix.cpp | 3 - BasiliskII/src/Unix/video_x.cpp | 2 +- 8 files changed, 4 insertions(+), 581 deletions(-) delete mode 100644 BasiliskII/src/MacOSX/etherslavetool.c delete mode 100644 BasiliskII/src/MacOSX/runtool.m diff --git a/BasiliskII/src/MacOSX/etherslavetool.c b/BasiliskII/src/MacOSX/etherslavetool.c deleted file mode 100644 index 2f3b3a4f..00000000 --- a/BasiliskII/src/MacOSX/etherslavetool.c +++ /dev/null @@ -1,291 +0,0 @@ -#include -#include - -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include - -#include - -#include - -static int openBpf(char *ifname); -static int retreiveAuthInfo(void); -static int mainLoop(int sd); - -int main(int argc, char **argv) { - char *ifName; - int ret; - int sd; - - if(argc != 2) { - return 255; - } - - ifName = argv[1]; - - ret = retreiveAuthInfo(); - if(ret != 0) { - return 254; - } - - fflush(stdout); - - sd = openBpf(ifName); - if(sd < 0) { - return 253; - } - - fflush(stdout); - - ret = mainLoop(sd); - - close(sd); - - if(ret < 0) { - return 252; - } - - return 0; -} - -static int mainLoop(int sd) { - fd_set readSet; - char *outgoing, *incoming; - unsigned short *outLen; - unsigned short *inLen; - int inIndex, outIndex; - u_int blen = 0; - int ret; - int fret = 0; - struct bpf_hdr *hdr; - int pktLen; - int frameLen; - int pad; - - if(ioctl(sd, BIOCGBLEN, &blen) < 0) { - return -1; - } - - incoming = malloc(blen); - if(incoming == NULL) { - return -2; - } - - outgoing = malloc(blen); - if(outgoing == NULL) { - free(outgoing); - return -3; - } - - inIndex = 0; - outIndex = 0; - - outLen = (unsigned short *)outgoing; - - while(1) { - int i; - FD_ZERO(&readSet); - FD_SET(0, &readSet); - FD_SET(sd, &readSet); - - ret = select(sd + 1, &readSet, NULL, NULL, NULL); - if(ret < 0) { - fret = -4; - break; - } - - if(FD_ISSET(0, &readSet)) { - if(outIndex < 2) { - ret = read(0, outgoing + outIndex, 2-outIndex); - } else { - ret = read(0, outgoing + outIndex, *outLen - outIndex + 2); - } - - if(ret < 1) { - fret = -5; - break; - } - - outIndex += ret; - if(outIndex > 1) { - fflush(stdout); - - if((*outLen + 2) > blen) { - fret = -6; - break; - } - - if(outIndex == (*outLen + 2)) { - ret = write(sd, outLen + 1, *outLen); - if(ret != *outLen) { - fret = -7; - break; - } - outIndex = 0; - } - } - - } - - if(FD_ISSET(sd, &readSet)) { - int i; - - ret = read(sd, incoming, blen); - if(ret < 1) { - fret = -8; - break; - } - - hdr = (struct bpf_hdr *)incoming; - inLen = (unsigned short *)(incoming + 16); - - do { - pktLen = hdr->bh_caplen; - frameLen = pktLen + 18; - - if((pktLen < 0) || (frameLen > ret) || (frameLen < 0)) { - fret = -9; - break; - } - *inLen = pktLen; - - write(0, inLen, pktLen + 2); - /* printf("%02X%02X %02X%02X %02X%02X %02X%02X\n", */ - /* *((unsigned char *)inLen + 0), */ - /* *((unsigned char *)inLen + 1), */ - /* *((unsigned char *)inLen + 2), */ - /* *((unsigned char *)inLen + 3), */ - /* *((unsigned char *)inLen + 4), */ - /* *((unsigned char *)inLen + 5), */ - /* *((unsigned char *)inLen + 6), */ - /* *((unsigned char *)inLen + 7)); */ - - /* printf("Read %d, len = %d, diff = %d.\n", ret, pktLen, */ - /* ret - pktLen); */ - /* fflush(stdout); */ - - if((frameLen & 0x03) == 0) { - pad = 0; - } else { - pad = 4 - (frameLen & 0x03); - } - - ret -= (frameLen + pad); - hdr = (struct bpf_hdr *)((unsigned char *)hdr + frameLen + pad); - inLen = (unsigned short *)((unsigned char *)hdr + 16); - } while (ret > 0); - - if(fret != 0) { - break; - } - } - } - - free(incoming); - free(outgoing); - - return fret; -} - -static int retreiveAuthInfo(void) { - AuthorizationRef aRef; - OSStatus status; - AuthorizationRights myRights; - AuthorizationRights *newRights; - AuthorizationItem *myItem; - AuthorizationItem myItems[1]; - AuthorizationItemSet *mySet; - int i; - - status = AuthorizationCopyPrivilegedReference(&aRef, kAuthorizationFlagDefaults); - if(status != errAuthorizationSuccess) { - return -1; - } - - status = AuthorizationCopyInfo(aRef, NULL, &mySet); - if(status != errAuthorizationSuccess) { - AuthorizationFree(aRef, kAuthorizationFlagDestroyRights); - return -1; - } - - myItems[0].name = "system.privilege.admin"; - myItems[0].valueLength = 0; - myItems[0].value = NULL; - myItems[0].flags = 0; - - myRights.count = sizeof (myItems) / sizeof (myItems[0]); - myRights.items = myItems; - - status = AuthorizationCopyRights(aRef, &myRights, NULL, - kAuthorizationFlagExtendRights, - &newRights); - if(status != errAuthorizationSuccess) { - AuthorizationFreeItemSet(mySet); - AuthorizationFree(aRef, kAuthorizationFlagDestroyRights); - return -2; - } - - AuthorizationFreeItemSet(newRights); - AuthorizationFreeItemSet(mySet); - AuthorizationFree(aRef, kAuthorizationFlagDestroyRights); - - return 0; -} - -static int openBpf(char *ifname) { - u_int blen = 0; - struct ifreq ifreq; - u_int arg; - - int sd = open("/dev/bpf2", O_RDWR); - - if(sd < 0) { - return -1; - } - - if(ioctl(sd, BIOCGBLEN, &blen) < 0) { - close(sd); - return -2; - } - - bzero(&ifreq, sizeof(ifreq)); - strncpy(ifreq.ifr_name, ifname, IFNAMSIZ); - - arg = 0; - if(ioctl(sd, BIOCSETIF, &ifreq) < 0) { - close(sd); - return -3; - } - - arg = 0; - if(ioctl(sd, BIOCSSEESENT, &arg) < 0) { - close(sd); - return -4; - } - - arg = 1; - if(ioctl(sd, BIOCPROMISC, &arg) < 0) { - close(sd); - return -5; - } - - arg = 1; - if(ioctl(sd, BIOCIMMEDIATE, &arg) < 0) { - close(sd); - return -6; - } - - return sd; -} diff --git a/BasiliskII/src/MacOSX/runtool.m b/BasiliskII/src/MacOSX/runtool.m deleted file mode 100644 index 5fc2b69e..00000000 --- a/BasiliskII/src/MacOSX/runtool.m +++ /dev/null @@ -1,78 +0,0 @@ -#include -#include - -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include - -#include - -#include - -FILE * runTool(const char *ifName); - -FILE * runTool(const char *ifName) { - OSStatus authStatus; - FILE *fp; - char *args[] = {"ethsheeptool", NULL, NULL}; - int ret; - const char *path; - - path = [[[NSBundle mainBundle] pathForResource:@"etherslavetool" ofType: nil] UTF8String]; - - if(path == NULL) { - return NULL; - } - - AuthorizationFlags authFlags; - AuthorizationRef authRef; - AuthorizationItem authItems[1]; - AuthorizationRights authRights; - - args[1] = (char *)ifName; - - authFlags = kAuthorizationFlagExtendRights | - kAuthorizationFlagInteractionAllowed | - kAuthorizationFlagPreAuthorize; - - authItems[0].name = "system.privilege.admin"; - authItems[0].valueLength = 0; - authItems[0].value = NULL; - authItems[0].flags = 0; - - authRights.count = sizeof (authItems) / sizeof (authItems[0]); - authRights.items = authItems; - - authStatus = AuthorizationCreate(&authRights, - kAuthorizationEmptyEnvironment, - authFlags, - &authRef); - - if(authStatus != errAuthorizationSuccess) { - fprintf(stderr, "%s: AuthorizationCreate() failed.\n", __func__); - return NULL; - } - - authStatus = AuthorizationExecuteWithPrivileges(authRef, - path, - kAuthorizationFlagDefaults, - args + 1, - &fp); - - if(authStatus != errAuthorizationSuccess) { - fprintf(stderr, "%s: AuthorizationExecWithPrivileges() failed.\n", __func__); - return NULL; - } - - return fp; -} diff --git a/BasiliskII/src/Unix/.gitignore b/BasiliskII/src/Unix/.gitignore index 6d074222..cc9e93f6 100644 --- a/BasiliskII/src/Unix/.gitignore +++ b/BasiliskII/src/Unix/.gitignore @@ -1,7 +1,6 @@ # Object files obj/* BasiliskII -etherslavetool # Autotools generated files Makefile diff --git a/BasiliskII/src/Unix/Makefile.in b/BasiliskII/src/Unix/Makefile.in index c0d74188..e50326a8 100644 --- a/BasiliskII/src/Unix/Makefile.in +++ b/BasiliskII/src/Unix/Makefile.in @@ -74,10 +74,6 @@ CXXFLAGS += $(GUI_CFLAGS) LIBS += $(GUI_LIBS) endif -ifeq (@MACOSX_ETHERSLAVE@,yes) -PROGS += etherslavetool -endif - ## Rules .PHONY: modules install installdirs uninstall mostlyclean clean distclean depend dep .SUFFIXES: @@ -142,9 +138,6 @@ $(GUI_APP)_app: $(GUI_APP) ../MacOSX/Info.plist ../MacOSX/$(APP).icns mkdir -p $(GUI_APP_APP)/Contents/Resources ./cpr.sh ../MacOSX/$(APP).icns $(GUI_APP_APP)/Contents/Resources/$(GUI_APP).icns -etherslavetool: ../MacOSX/etherslavetool.c - $(CC) $(CPPFLAGS) $(DEFS) $(CFLAGS) $(LIBS) $< -o $@ - modules: cd Linux/NetDriver; make @@ -174,7 +167,7 @@ mostlyclean: rm -f $(PROGS) $(OBJ_DIR)/* core* *.core *~ *.bak clean: mostlyclean - rm -f cpuemu.cpp cpudefs.cpp cputmp*.s cpufast*.s cpustbl.cpp cputbl.h compemu.cpp compstbl.cpp comptbl.h Darwin/lowmem Darwin/pagezero + rm -f cpuemu.cpp cpudefs.cpp cputmp*.s cpufast*.s cpustbl.cpp cputbl.h compemu.cpp compstbl.cpp comptbl.h distclean: clean rm -rf $(OBJ_DIR) diff --git a/BasiliskII/src/Unix/configure.ac b/BasiliskII/src/Unix/configure.ac index 0816b19c..62d45f57 100644 --- a/BasiliskII/src/Unix/configure.ac +++ b/BasiliskII/src/Unix/configure.ac @@ -21,12 +21,6 @@ AC_ARG_ENABLE(standalone-gui,[ --enable-standalone-gui enable a standalone GUI dnl Mac OS X GUI. AC_ARG_ENABLE(macosx-gui, [ --enable-macosx-gui enable Mac OS X GUI [default=no]], [WANT_MACOSX_GUI=$enableval], [WANT_MACOSX_GUI=no]) -dnl Mac OS X Sound -AC_ARG_ENABLE(macosx-sound, [ --enable-macosx-sound enable Mac OS X Sound [default=no]], [WANT_MACOSX_SOUND=$enableval], [WANT_MACOSX_SOUND=no]) - -dnl Mac OS X etherslave support -AC_ARG_ENABLE(macosx-etherslave, [ --enable-macosx-etherslave enable Mac OS X Sound [default=no]], [WANT_MACOSX_ETHERSLAVE=$enableval], [WANT_MACOSX_ETHERSLAVE=no]) - dnl Video options. AC_ARG_ENABLE(xf86-dga, [ --enable-xf86-dga use the XFree86 DGA extension [default=yes]], [WANT_XF86_DGA=$enableval], [WANT_XF86_DGA=yes]) AC_ARG_ENABLE(xf86-vidmode, [ --enable-xf86-vidmode use the XFree86 VidMode extension [default=yes]], [WANT_XF86_VIDMODE=$enableval], [WANT_XF86_VIDMODE=yes]) @@ -515,7 +509,6 @@ mips-sony-bsd|mips-sony-newsos4) ;; *-*-darwin*) no_dev_ptmx=1 - LIBS="$LIBS -lstdc++" ;; esac @@ -685,8 +678,6 @@ darwin*) if [[ "x$ac_cv_framework_Carbon" = "xyes" ]]; then EXTFSSRC=../MacOSX/extfs_macosx.cpp fi - EXTRASYSSRCS="$EXTRASYSSRCS ../MacOSX/runtool.m" - LIBS="$LIBS -framework Security" ;; cygwin*) SERIALSRC="../dummy/serial_dummy.cpp" @@ -728,21 +719,11 @@ if [[ "x$WANT_MACOSX_GUI" = "xyes" ]]; then EXTRASYSSRCS="$EXTRASYSSRCS ../MacOSX/prefs_macosx.cpp" VIDEOSRCS="../MacOSX/video_macosx.mm" + AUDIOSRC="../MacOSX/audio_macosx.cpp ../MacOSX/AudioBackEnd.cpp ../MacOSX/AudioDevice.cpp ../MacOSX/MacOSX_sound_if.cpp" else EXTRASYSSRCS="$EXTRASYSSRCS main_unix.cpp prefs_unix.cpp" fi -if [[ "x$WANT_MACOSX_SOUND" = "xyes" ]]; then - AUDIOSRC="../MacOSX/audio_macosx.cpp ../MacOSX/AudioBackEnd.cpp ../MacOSX/AudioDevice.cpp ../MacOSX/MacOSX_sound_if.cpp" - LIBS="$LIBS -framework AudioToolbox -framework AudioUnit -framework CoreAudio" -fi - -if [[ "x$WANT_MACOSX_ETHERSLAVE" = "xyes" ]]; then - AC_DEFINE(ENABLE_MACOSX_ETHERSLAVE, 1, [Define if supporting "etherslave" network device.]) -fi - -AC_SUBST(MACOSX_ETHERSLAVE, $WANT_MACOSX_ETHERSLAVE) - dnl SDL overrides if [[ "x$WANT_SDL" = "xyes" ]]; then AC_DEFINE(USE_SDL, 1, [Define to enble SDL support]) @@ -1767,7 +1748,6 @@ echo echo Basilisk II configuration summary: echo echo Mac OS X GUI ........................... : $WANT_MACOSX_GUI -echo Mac OS X Sound ......................... : $WANT_MACOSX_SOUND echo SDL support ............................ : $SDL_SUPPORT echo BINCUE support ......................... : $have_bincue echo LIBVHD support ......................... : $have_libvhd diff --git a/BasiliskII/src/Unix/ether_unix.cpp b/BasiliskII/src/Unix/ether_unix.cpp index ba6ea800..526ee29c 100644 --- a/BasiliskII/src/Unix/ether_unix.cpp +++ b/BasiliskII/src/Unix/ether_unix.cpp @@ -41,12 +41,6 @@ #endif #include #include - -#ifdef ENABLE_MACOSX_ETHERSLAVE -#include -#include -#endif - #include #include #include @@ -99,17 +93,9 @@ enum { NET_IF_SHEEPNET, NET_IF_ETHERTAP, NET_IF_TUNTAP, - NET_IF_SLIRP, - NET_IF_ETHERSLAVE + NET_IF_SLIRP }; - -#ifdef ENABLE_MACOSX_ETHERSLAVE -extern "C" { - extern FILE * runTool(const char *ifName); -} -#endif - // Constants #if ENABLE_TUNTAP static const char ETHERCONFIG_FILE_NAME[] = DATADIR "/tunconfig"; @@ -136,11 +122,6 @@ static uint8 ether_addr[6]; // Our Ethernet address const bool ether_driver_opened = true; // Flag: is the MacOS driver opened? #endif - -#ifdef ENABLE_MACOSX_ETHERSLAVE -static uint8 packet_buffer[2048]; -#endif - // Attached network protocols, maps protocol type to MacOS handler address static map net_protocols; @@ -154,11 +135,6 @@ static void ether_do_interrupt(void); static void slirp_add_redirs(); static int slirp_add_redir(const char *redir_str); -#ifdef ENABLE_MACOSX_ETHERSLAVE -static int getmacaddress(const char* dev, unsigned char *addr); -static bool openEtherSlave(const char *ifName); -static int readpacket(void); -#endif /* * Start packet reception thread @@ -259,9 +235,6 @@ bool ether_init(void) // Do nothing if no Ethernet device specified const char *name = PrefsFindString("ether"); -#ifdef ENABLE_MACOSX_ETHERSLAVE - const char *slaveDev = PrefsFindString("etherslavedev"); -#endif if (name == NULL) return false; @@ -276,10 +249,6 @@ bool ether_init(void) #ifdef HAVE_SLIRP else if (strcmp(name, "slirp") == 0) net_if_type = NET_IF_SLIRP; -#endif -#ifdef ENABLE_MACOSX_ETHERSLAVE - else if (strcmp(name, "etherslave") == 0) - net_if_type = NET_IF_ETHERSLAVE; #endif else net_if_type = NET_IF_SHEEPNET; @@ -331,14 +300,6 @@ bool ether_init(void) case NET_IF_SHEEPNET: strcpy(dev_name, "/dev/sheep_net"); break; -#ifdef ENABLE_MACOSX_ETHERSLAVE - case NET_IF_ETHERSLAVE: - if(slaveDev == NULL) { - WarningAlert("etherslavedev not defined in preferences."); - return false; - } - return openEtherSlave(slaveDev); -#endif } if (net_if_type != NET_IF_SLIRP) { fd = open(dev_name, O_RDWR); @@ -789,21 +750,6 @@ static int16 ether_do_write(uint32 arg) write(slirp_input_fd, packet, len); return noErr; } else -#endif -#ifdef ENABLE_MACOSX_ETHERSLAVE - if (net_if_type == NET_IF_ETHERSLAVE) { - unsigned short pktlen; - - pktlen = len; - if(write(fd, &pktlen, 2) < 2) { - return excessCollsns; - } - - if(write(fd, packet, len) < len) { - return excessCollsns; - } - return noErr; - } else #endif if (write(fd, packet, len) < 0) { D(bug("WARNING: Couldn't transmit packet\n")); @@ -938,13 +884,6 @@ static void *receive_func(void *arg) if (res <= 0) break; -#ifdef ENABLE_MACOSX_ETHERSLAVE - if (net_if_type == NET_IF_ETHERSLAVE) { - if(readpacket() < 1) { - break; - } - } -#endif if (ether_driver_opened) { // Trigger Ethernet interrupt D(bug(" packet received, triggering Ethernet interrupt\n")); @@ -984,18 +923,6 @@ void ether_do_interrupt(void) ether_udp_read(packet, length, &from); } else -#endif -#ifdef ENABLE_MACOSX_ETHERSLAVE - if (net_if_type == NET_IF_ETHERSLAVE) { - unsigned short *pktlen; - uint32 p = packet; - - pktlen = (unsigned short *)packet_buffer; - length = *pktlen; - memcpy(Mac2HostAddr(packet), pktlen + 1, length); - ether_dispatch_packet(p, length); - break; - } else #endif { @@ -1122,107 +1049,3 @@ static int slirp_add_redir(const char *redir_str) WarningAlert(str); return -1; } - -#ifdef ENABLE_MACOSX_ETHERSLAVE -static int getmacaddress(const char* dev, unsigned char *addr) { - struct ifaddrs *ifaddrs, *next; - int ret = -1; - struct sockaddr_dl *sa; - - if(getifaddrs(&ifaddrs) != 0) { - perror("getifaddrs"); - return -1; - } - - next = ifaddrs; - while(next != NULL) { - switch(next->ifa_addr->sa_family) { - case AF_LINK: - if(!strcmp(dev, next->ifa_name)) { - sa = (struct sockaddr_dl *)next->ifa_addr; - memcpy(addr, LLADDR(sa), 6); - ret = 0; - } - break; - default: - break; - } - next = next->ifa_next; - } - - freeifaddrs(ifaddrs); - - return ret; -} - -static bool openEtherSlave(const char *ifName) { - FILE *fp; - char str[64]; - - str[sizeof(str)-1] = '\0'; - - if(getmacaddress(ifName, ether_addr) != 0) { - snprintf(str, sizeof(str)-1, "Unable to find interface %s.", - ifName); - WarningAlert(str); - return false; - } - - fp = runTool(ifName); - if(fp == NULL) { - snprintf(str, sizeof(str)-1, "Unable to run ether slave helper tool."); - WarningAlert(str); - return false; - } - - fd = dup(fileno(fp)); - fclose(fp); - - if(start_thread() == false) { - close(fd); - fd = -1; - return false; - } - - return true; -} - -static int readpacket() { - int index; - unsigned short *pktLen; - int ret = -1; - - pktLen = (unsigned short *)packet_buffer; - - index = 0; - while(1) { - if(index < 2) { - ret = read(fd, packet_buffer + index, 2 - index); - } else { - ret = read(fd, packet_buffer + index, *pktLen - index + 2); - } - - if(ret < 1) { - fprintf(stderr, "%s: read() returned %d.\n", __func__, ret); - break; - } - - index += ret; - - if(index > 1) { - if(*pktLen > (sizeof(packet_buffer) + 2)) { - fprintf(stderr, "%s: pktLen (%d) too large.\n", __func__, *pktLen); - break; - } - - if(index == (*pktLen + 2)) { - ret = *pktLen; - break; - } - } - } - - return ret; -} - -#endif diff --git a/BasiliskII/src/Unix/prefs_unix.cpp b/BasiliskII/src/Unix/prefs_unix.cpp index 43f70fb6..a92cd640 100644 --- a/BasiliskII/src/Unix/prefs_unix.cpp +++ b/BasiliskII/src/Unix/prefs_unix.cpp @@ -40,9 +40,6 @@ prefs_desc platform_prefs_items[] = { {"mixer", TYPE_STRING, false, "audio mixer device name"}, #ifdef HAVE_SIGSEGV_SKIP_INSTRUCTION {"ignoresegv", TYPE_BOOLEAN, false, "ignore illegal memory accesses"}, -#endif -#ifdef ENABLE_MACOSX_ETHERSLAVE - {"etherslavedev", TYPE_STRING, false, "ethernet device for etherslave ethernet"}, #endif {"idlewait", TYPE_BOOLEAN, false, "sleep when idle"}, {NULL, TYPE_END, false, NULL} // End of list diff --git a/BasiliskII/src/Unix/video_x.cpp b/BasiliskII/src/Unix/video_x.cpp index aa3c678f..6f8ef67f 100644 --- a/BasiliskII/src/Unix/video_x.cpp +++ b/BasiliskII/src/Unix/video_x.cpp @@ -328,7 +328,7 @@ static bool find_visual_for_depth(video_depth depth) bool visual_found = false; for (int i=0; i max_depth) continue; From 94b790728e192f12e7b8a023dcfeff44779ce35b Mon Sep 17 00:00:00 2001 From: Dan Sumorok Date: Wed, 1 May 2013 06:54:20 -0400 Subject: [PATCH 04/35] Added file-level comments. --- BasiliskII/src/MacOSX/etherslavetool.c | 23 +++++++++++++++++++++++ BasiliskII/src/MacOSX/runtool.m | 23 ++++++++++++++++++++++- 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/BasiliskII/src/MacOSX/etherslavetool.c b/BasiliskII/src/MacOSX/etherslavetool.c index 08a18d97..dfc4bec0 100644 --- a/BasiliskII/src/MacOSX/etherslavetool.c +++ b/BasiliskII/src/MacOSX/etherslavetool.c @@ -1,3 +1,26 @@ +/* + * etherslavetool.c - Reads and writes raw ethernet packets usng bpf + * interface. + * + * Copyright (C) 2010, Daniel Sumorok + * + * Basilisk II (C) 1997-2008 Christian Bauer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + #include #include diff --git a/BasiliskII/src/MacOSX/runtool.m b/BasiliskII/src/MacOSX/runtool.m index 64f39f9d..925e50fc 100644 --- a/BasiliskII/src/MacOSX/runtool.m +++ b/BasiliskII/src/MacOSX/runtool.m @@ -1,3 +1,24 @@ +/* + * runtool.m - Run an external program as root for networking + * Copyright (C) 2010, Daniel Sumorok + * + * Basilisk II (C) 1997-2008 Christian Bauer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + #include #include @@ -24,7 +45,7 @@ FILE * runTool(const char *ifName); FILE * runTool(const char *ifName) { OSStatus authStatus; FILE *fp; - char *args[] = {"ethsheeptool", NULL, NULL}; + char *args[] = {"etherslavetool", NULL, NULL}; int ret; const char *path; From 01ba04139fda8602e7c6daf85aa2f7624ed1e3a8 Mon Sep 17 00:00:00 2001 From: Dan Sumorok Date: Sat, 4 May 2013 20:36:11 -0400 Subject: [PATCH 05/35] Updated coding style. --- BasiliskII/src/MacOSX/etherslavetool.c | 126 ++++++++++++------------- BasiliskII/src/MacOSX/runtool.m | 53 +++++------ BasiliskII/src/Unix/ether_unix.cpp | 84 ++++++++--------- 3 files changed, 130 insertions(+), 133 deletions(-) diff --git a/BasiliskII/src/MacOSX/etherslavetool.c b/BasiliskII/src/MacOSX/etherslavetool.c index dfc4bec0..766c7968 100644 --- a/BasiliskII/src/MacOSX/etherslavetool.c +++ b/BasiliskII/src/MacOSX/etherslavetool.c @@ -43,160 +43,160 @@ #include -static int openBpf(char *ifname); -static int retreiveAuthInfo(void); -static int mainLoop(int sd); +static int open_bpf(char *ifname); +static int retreive_auth_info(void); +static int main_loop(int sd); int main(int argc, char **argv) { - char *ifName; + char *if_name; int ret; int sd; - if(argc != 2) { + if (argc != 2) { return 255; } - ifName = argv[1]; + if_name = argv[1]; - ret = retreiveAuthInfo(); - if(ret != 0) { + ret = retreive_auth_info(); + if (ret != 0) { return 254; } fflush(stdout); - sd = openBpf(ifName); - if(sd < 0) { + sd = open_bpf(if_name); + if (sd < 0) { return 253; } fflush(stdout); - ret = mainLoop(sd); + ret = main_loop(sd); close(sd); - if(ret < 0) { + if (ret < 0) { return 252; } return 0; } -static int mainLoop(int sd) { +static int main_loop(int sd) { fd_set readSet; char *outgoing, *incoming; - unsigned short *outLen; - unsigned short *inLen; - int inIndex, outIndex; + unsigned short *out_len; + unsigned short *in_len; + int in_index, out_index; u_int blen = 0; int ret; int fret = 0; struct bpf_hdr *hdr; - int pktLen; - int frameLen; + int pkt_len; + int frame_len; int pad; - if(ioctl(sd, BIOCGBLEN, &blen) < 0) { + if (ioctl(sd, BIOCGBLEN, &blen) < 0) { return -1; } incoming = malloc(blen); - if(incoming == NULL) { + if (incoming == NULL) { return -2; } outgoing = malloc(blen); - if(outgoing == NULL) { + if (outgoing == NULL) { free(outgoing); return -3; } - inIndex = 0; - outIndex = 0; + in_index = 0; + out_index = 0; - outLen = (unsigned short *)outgoing; + out_len = (unsigned short *)outgoing; - while(1) { + while (1) { int i; FD_ZERO(&readSet); FD_SET(0, &readSet); FD_SET(sd, &readSet); ret = select(sd + 1, &readSet, NULL, NULL, NULL); - if(ret < 0) { + if (ret < 0) { fret = -4; break; } - if(FD_ISSET(0, &readSet)) { - if(outIndex < 2) { - ret = read(0, outgoing + outIndex, 2-outIndex); + if (FD_ISSET(0, &readSet)) { + if (out_index < 2) { + ret = read(0, outgoing + out_index, 2-out_index); } else { - ret = read(0, outgoing + outIndex, *outLen - outIndex + 2); + ret = read(0, outgoing + out_index, *out_len - out_index + 2); } - if(ret < 1) { + if (ret < 1) { fret = -5; break; } - outIndex += ret; - if(outIndex > 1) { + out_index += ret; + if (out_index > 1) { fflush(stdout); - if((*outLen + 2) > blen) { + if ((*out_len + 2) > blen) { fret = -6; break; } - if(outIndex == (*outLen + 2)) { - ret = write(sd, outLen + 1, *outLen); - if(ret != *outLen) { + if (out_index == (*out_len + 2)) { + ret = write(sd, out_len + 1, *out_len); + if (ret != *out_len) { fret = -7; break; } - outIndex = 0; + out_index = 0; } } } - if(FD_ISSET(sd, &readSet)) { + if (FD_ISSET(sd, &readSet)) { int i; ret = read(sd, incoming, blen); - if(ret < 1) { + if (ret < 1) { fret = -8; break; } hdr = (struct bpf_hdr *)incoming; - inLen = (unsigned short *)(incoming + 16); + in_len = (unsigned short *)(incoming + 16); do { - pktLen = hdr->bh_caplen; - frameLen = pktLen + 18; + pkt_len = hdr->bh_caplen; + frame_len = pkt_len + 18; - if((pktLen < 0) || (frameLen > ret) || (frameLen < 0)) { + if ((pkt_len < 0) || (frame_len > ret) || (frame_len < 0)) { fret = -9; break; } - *inLen = pktLen; + *in_len = pkt_len; - write(0, inLen, pktLen + 2); - if((frameLen & 0x03) == 0) { + write(0, in_len, pkt_len + 2); + if ((frame_len & 0x03) == 0) { pad = 0; } else { - pad = 4 - (frameLen & 0x03); + pad = 4 - (frame_len & 0x03); } - ret -= (frameLen + pad); - hdr = (struct bpf_hdr *)((unsigned char *)hdr + frameLen + pad); - inLen = (unsigned short *)((unsigned char *)hdr + 16); + ret -= (frame_len + pad); + hdr = (struct bpf_hdr *)((unsigned char *)hdr + frame_len + pad); + in_len = (unsigned short *)((unsigned char *)hdr + 16); } while (ret > 0); - if(fret != 0) { + if (fret != 0) { break; } } @@ -208,7 +208,7 @@ static int mainLoop(int sd) { return fret; } -static int retreiveAuthInfo(void) { +static int retreive_auth_info(void) { AuthorizationRef aRef; OSStatus status; AuthorizationRights myRights; @@ -219,12 +219,12 @@ static int retreiveAuthInfo(void) { int i; status = AuthorizationCopyPrivilegedReference(&aRef, kAuthorizationFlagDefaults); - if(status != errAuthorizationSuccess) { + if (status != errAuthorizationSuccess) { return -1; } status = AuthorizationCopyInfo(aRef, NULL, &mySet); - if(status != errAuthorizationSuccess) { + if (status != errAuthorizationSuccess) { AuthorizationFree(aRef, kAuthorizationFlagDestroyRights); return -1; } @@ -240,7 +240,7 @@ static int retreiveAuthInfo(void) { status = AuthorizationCopyRights(aRef, &myRights, NULL, kAuthorizationFlagExtendRights, &newRights); - if(status != errAuthorizationSuccess) { + if (status != errAuthorizationSuccess) { AuthorizationFreeItemSet(mySet); AuthorizationFree(aRef, kAuthorizationFlagDestroyRights); return -2; @@ -253,18 +253,18 @@ static int retreiveAuthInfo(void) { return 0; } -static int openBpf(char *ifname) { +static int open_bpf(char *ifname) { u_int blen = 0; struct ifreq ifreq; u_int arg; int sd = open("/dev/bpf2", O_RDWR); - if(sd < 0) { + if (sd < 0) { return -1; } - if(ioctl(sd, BIOCGBLEN, &blen) < 0) { + if (ioctl(sd, BIOCGBLEN, &blen) < 0) { close(sd); return -2; } @@ -273,25 +273,25 @@ static int openBpf(char *ifname) { strncpy(ifreq.ifr_name, ifname, IFNAMSIZ); arg = 0; - if(ioctl(sd, BIOCSETIF, &ifreq) < 0) { + if (ioctl(sd, BIOCSETIF, &ifreq) < 0) { close(sd); return -3; } arg = 0; - if(ioctl(sd, BIOCSSEESENT, &arg) < 0) { + if (ioctl(sd, BIOCSSEESENT, &arg) < 0) { close(sd); return -4; } arg = 1; - if(ioctl(sd, BIOCPROMISC, &arg) < 0) { + if (ioctl(sd, BIOCPROMISC, &arg) < 0) { close(sd); return -5; } arg = 1; - if(ioctl(sd, BIOCIMMEDIATE, &arg) < 0) { + if (ioctl(sd, BIOCIMMEDIATE, &arg) < 0) { close(sd); return -6; } diff --git a/BasiliskII/src/MacOSX/runtool.m b/BasiliskII/src/MacOSX/runtool.m index 925e50fc..261f3054 100644 --- a/BasiliskII/src/MacOSX/runtool.m +++ b/BasiliskII/src/MacOSX/runtool.m @@ -40,58 +40,57 @@ #include -FILE * runTool(const char *ifName); +FILE * run_tool(const char *ifName); -FILE * runTool(const char *ifName) { - OSStatus authStatus; +FILE * run_tool(const char *ifName) { + OSStatus auth_status; FILE *fp; char *args[] = {"etherslavetool", NULL, NULL}; int ret; const char *path; + AuthorizationFlags auth_flags; + AuthorizationRef auth_ref; + AuthorizationItem auth_items[1]; + AuthorizationRights auth_rights; path = [[[NSBundle mainBundle] pathForResource:@"etherslavetool" ofType: nil] UTF8String]; - if(path == NULL) { + if (path == NULL) { return NULL; } - AuthorizationFlags authFlags; - AuthorizationRef authRef; - AuthorizationItem authItems[1]; - AuthorizationRights authRights; - args[1] = (char *)ifName; - authFlags = kAuthorizationFlagExtendRights | + auth_flags = kAuthorizationFlagExtendRights | kAuthorizationFlagInteractionAllowed | kAuthorizationFlagPreAuthorize; - authItems[0].name = "system.privilege.admin"; - authItems[0].valueLength = 0; - authItems[0].value = NULL; - authItems[0].flags = 0; + auth_items[0].name = "system.privilege.admin"; + auth_items[0].valueLength = 0; + auth_items[0].value = NULL; + auth_items[0].flags = 0; - authRights.count = sizeof (authItems) / sizeof (authItems[0]); - authRights.items = authItems; + auth_rights.count = sizeof (auth_items) / sizeof (auth_items[0]); + auth_rights.items = auth_items; - authStatus = AuthorizationCreate(&authRights, - kAuthorizationEmptyEnvironment, - authFlags, - &authRef); + auth_status = AuthorizationCreate(&auth_rights, + kAuthorizationEmptyEnvironment, + auth_flags, + &auth_ref); - if(authStatus != errAuthorizationSuccess) { + if (auth_status != errAuthorizationSuccess) { fprintf(stderr, "%s: AuthorizationCreate() failed.\n", __func__); return NULL; } - authStatus = AuthorizationExecuteWithPrivileges(authRef, - path, - kAuthorizationFlagDefaults, - args + 1, - &fp); + auth_status = AuthorizationExecuteWithPrivileges(auth_ref, + path, + kAuthorizationFlagDefaults, + args + 1, + &fp); - if(authStatus != errAuthorizationSuccess) { + if (auth_status != errAuthorizationSuccess) { fprintf(stderr, "%s: AuthorizationExecWithPrivileges() failed.\n", __func__); return NULL; } diff --git a/BasiliskII/src/Unix/ether_unix.cpp b/BasiliskII/src/Unix/ether_unix.cpp index a2c07d2a..2c030c7b 100644 --- a/BasiliskII/src/Unix/ether_unix.cpp +++ b/BasiliskII/src/Unix/ether_unix.cpp @@ -106,7 +106,7 @@ enum { #ifdef ENABLE_MACOSX_ETHERSLAVE extern "C" { - extern FILE * runTool(const char *ifName); + extern FILE * run_tool(const char *if_name); } #endif @@ -155,9 +155,9 @@ static void slirp_add_redirs(); static int slirp_add_redir(const char *redir_str); #ifdef ENABLE_MACOSX_ETHERSLAVE -static int getmacaddress(const char* dev, unsigned char *addr); -static bool openEtherSlave(const char *ifName); -static int readpacket(void); +static int get_mac_address(const char* dev, unsigned char *addr); +static bool open_ether_slave(const char *if_name); +static int read_packet(void); #endif /* @@ -260,7 +260,7 @@ bool ether_init(void) // Do nothing if no Ethernet device specified const char *name = PrefsFindString("ether"); #ifdef ENABLE_MACOSX_ETHERSLAVE - const char *slaveDev = PrefsFindString("etherslavedev"); + const char *slave_dev = PrefsFindString("etherslavedev"); #endif if (name == NULL) return false; @@ -333,11 +333,11 @@ bool ether_init(void) break; #ifdef ENABLE_MACOSX_ETHERSLAVE case NET_IF_ETHERSLAVE: - if(slaveDev == NULL) { + if (slave_dev == NULL) { WarningAlert("etherslavedev not defined in preferences."); return false; } - return openEtherSlave(slaveDev); + return open_ether_slave(slave_dev); #endif } if (net_if_type != NET_IF_SLIRP) { @@ -792,14 +792,14 @@ static int16 ether_do_write(uint32 arg) #endif #ifdef ENABLE_MACOSX_ETHERSLAVE if (net_if_type == NET_IF_ETHERSLAVE) { - unsigned short pktlen; + unsigned short pkt_len; - pktlen = len; - if(write(fd, &pktlen, 2) < 2) { + pkt_len = len; + if (write(fd, &pkt_len, 2) < 2) { return excessCollsns; } - if(write(fd, packet, len) < len) { + if (write(fd, packet, len) < len) { return excessCollsns; } return noErr; @@ -940,7 +940,7 @@ static void *receive_func(void *arg) #ifdef ENABLE_MACOSX_ETHERSLAVE if (net_if_type == NET_IF_ETHERSLAVE) { - if(readpacket() < 1) { + if (read_packet() < 1) { break; } } @@ -987,12 +987,12 @@ void ether_do_interrupt(void) #endif #ifdef ENABLE_MACOSX_ETHERSLAVE if (net_if_type == NET_IF_ETHERSLAVE) { - unsigned short *pktlen; + unsigned short *pkt_len; uint32 p = packet; - pktlen = (unsigned short *)packet_buffer; - length = *pktlen; - memcpy(Mac2HostAddr(packet), pktlen + 1, length); + pkt_len = (unsigned short *)packet_buffer; + length = *pkt_len; + memcpy(Mac2HostAddr(packet), pkt_len + 1, length); ether_dispatch_packet(p, length); break; } else @@ -1124,22 +1124,22 @@ static int slirp_add_redir(const char *redir_str) } #ifdef ENABLE_MACOSX_ETHERSLAVE -static int getmacaddress(const char* dev, unsigned char *addr) +static int get_mac_address(const char* dev, unsigned char *addr) { struct ifaddrs *ifaddrs, *next; int ret = -1; struct sockaddr_dl *sa; - if(getifaddrs(&ifaddrs) != 0) { + if (getifaddrs(&ifaddrs) != 0) { perror("getifaddrs"); return -1; } next = ifaddrs; - while(next != NULL) { - switch(next->ifa_addr->sa_family) { + while (next != NULL) { + switch (next->ifa_addr->sa_family) { case AF_LINK: - if(!strcmp(dev, next->ifa_name)) { + if (!strcmp(dev, next->ifa_name)) { sa = (struct sockaddr_dl *)next->ifa_addr; memcpy(addr, LLADDR(sa), 6); ret = 0; @@ -1156,23 +1156,21 @@ static int getmacaddress(const char* dev, unsigned char *addr) return ret; } -static bool openEtherSlave(const char *ifName) +static bool open_ether_slave(const char *if_name) { FILE *fp; char str[64]; - str[sizeof(str)-1] = '\0'; - - if(getmacaddress(ifName, ether_addr) != 0) { - snprintf(str, sizeof(str)-1, "Unable to find interface %s.", - ifName); + if (get_mac_address(if_name, ether_addr) != 0) { + snprintf(str, sizeof(str), "Unable to find interface %s.", + if_name); WarningAlert(str); return false; } - fp = runTool(ifName); - if(fp == NULL) { - snprintf(str, sizeof(str)-1, "Unable to run ether slave helper tool."); + fp = run_tool(if_name); + if (fp == NULL) { + snprintf(str, sizeof(str), "Unable to run ether slave helper tool."); WarningAlert(str); return false; } @@ -1180,7 +1178,7 @@ static bool openEtherSlave(const char *ifName) fd = dup(fileno(fp)); fclose(fp); - if(start_thread() == false) { + if (start_thread() == false) { close(fd); fd = -1; return false; @@ -1189,37 +1187,37 @@ static bool openEtherSlave(const char *ifName) return true; } -static int readpacket() +static int read_packet() { int index; - unsigned short *pktLen; + unsigned short *pkt_len; int ret = -1; - pktLen = (unsigned short *)packet_buffer; + pkt_len = (unsigned short *)packet_buffer; index = 0; - while(1) { - if(index < 2) { + while (1) { + if (index < 2) { ret = read(fd, packet_buffer + index, 2 - index); } else { - ret = read(fd, packet_buffer + index, *pktLen - index + 2); + ret = read(fd, packet_buffer + index, *pkt_len - index + 2); } - if(ret < 1) { + if (ret < 1) { fprintf(stderr, "%s: read() returned %d.\n", __func__, ret); break; } index += ret; - if(index > 1) { - if(*pktLen > (sizeof(packet_buffer) + 2)) { - fprintf(stderr, "%s: pktLen (%d) too large.\n", __func__, *pktLen); + if (index > 1) { + if (*pkt_len > (sizeof(packet_buffer) + 2)) { + fprintf(stderr, "%s: pkt_len (%d) too large.\n", __func__, *pkt_len); break; } - if(index == (*pktLen + 2)) { - ret = *pktLen; + if (index == (*pkt_len + 2)) { + ret = *pkt_len; break; } } From f1c78e659c6aad962536a43f18c4260f38698f21 Mon Sep 17 00:00:00 2001 From: Dan Sumorok Date: Sat, 4 May 2013 20:37:29 -0400 Subject: [PATCH 06/35] More coding style updates. --- BasiliskII/src/MacOSX/etherslavetool.c | 12 ++++++++---- BasiliskII/src/MacOSX/runtool.m | 3 ++- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/BasiliskII/src/MacOSX/etherslavetool.c b/BasiliskII/src/MacOSX/etherslavetool.c index 766c7968..57642774 100644 --- a/BasiliskII/src/MacOSX/etherslavetool.c +++ b/BasiliskII/src/MacOSX/etherslavetool.c @@ -47,7 +47,8 @@ static int open_bpf(char *ifname); static int retreive_auth_info(void); static int main_loop(int sd); -int main(int argc, char **argv) { +int main(int argc, char **argv) +{ char *if_name; int ret; int sd; @@ -83,7 +84,8 @@ int main(int argc, char **argv) { return 0; } -static int main_loop(int sd) { +static int main_loop(int sd) +{ fd_set readSet; char *outgoing, *incoming; unsigned short *out_len; @@ -208,7 +210,8 @@ static int main_loop(int sd) { return fret; } -static int retreive_auth_info(void) { +static int retreive_auth_info(void) +{ AuthorizationRef aRef; OSStatus status; AuthorizationRights myRights; @@ -253,7 +256,8 @@ static int retreive_auth_info(void) { return 0; } -static int open_bpf(char *ifname) { +static int open_bpf(char *ifname) +{ u_int blen = 0; struct ifreq ifreq; u_int arg; diff --git a/BasiliskII/src/MacOSX/runtool.m b/BasiliskII/src/MacOSX/runtool.m index 261f3054..b866599c 100644 --- a/BasiliskII/src/MacOSX/runtool.m +++ b/BasiliskII/src/MacOSX/runtool.m @@ -42,7 +42,8 @@ FILE * run_tool(const char *ifName); -FILE * run_tool(const char *ifName) { +FILE * run_tool(const char *ifName) +{ OSStatus auth_status; FILE *fp; char *args[] = {"etherslavetool", NULL, NULL}; From 57b9ad0d95835299da6914943b3a93438b122c0a Mon Sep 17 00:00:00 2001 From: Dan Sumorok Date: Sun, 5 May 2013 14:11:09 -0400 Subject: [PATCH 07/35] Remove 15 bit video for OS X. This mode doesn't seem to work. This also fixes 2-bit, 4-bit, and 8-bit modes. --- BasiliskII/src/Unix/video_x.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/BasiliskII/src/Unix/video_x.cpp b/BasiliskII/src/Unix/video_x.cpp index 6f8ef67f..b02e2854 100644 --- a/BasiliskII/src/Unix/video_x.cpp +++ b/BasiliskII/src/Unix/video_x.cpp @@ -1637,6 +1637,12 @@ bool VideoInit(bool classic) return false; } std::sort(avail_depths, avail_depths + num_depths); + +#ifdef __APPLE__ + // 15-bit color does not seem to work on OS X + int *last = std::remove(avail_depths, avail_depths + num_depths, 15); + num_depths = ( (size_t)last - (size_t)avail_depths ) / sizeof(int); +#endif #ifdef ENABLE_FBDEV_DGA // Frame buffer name From e91a03f40f02474bc03d752f2ab3f24be3c0b117 Mon Sep 17 00:00:00 2001 From: Dan Sumorok Date: Sun, 5 May 2013 14:20:33 -0400 Subject: [PATCH 08/35] Added clean rule for etherslavetool. --- BasiliskII/src/Unix/Makefile.in | 1 + 1 file changed, 1 insertion(+) diff --git a/BasiliskII/src/Unix/Makefile.in b/BasiliskII/src/Unix/Makefile.in index 57a1c9d9..0094fae7 100644 --- a/BasiliskII/src/Unix/Makefile.in +++ b/BasiliskII/src/Unix/Makefile.in @@ -175,6 +175,7 @@ mostlyclean: clean: mostlyclean rm -f cpuemu.cpp cpudefs.cpp cputmp*.s cpufast*.s cpustbl.cpp cputbl.h compemu.cpp compstbl.cpp comptbl.h + rm -rf etherslavetool.dSYM distclean: clean rm -rf $(OBJ_DIR) From 241162f261e1d68d698cb39e61915d59cdfc24c9 Mon Sep 17 00:00:00 2001 From: Dan Sumorok Date: Sun, 5 May 2013 16:20:37 -0400 Subject: [PATCH 09/35] Fixed code that removed 15-bit color mode. 15-bit color mode is now removed on all platforms. The removal of 15-bit color mode now happens before the sort. Updated a variable name. Changed list length calculation to use C++'s clever pointer subtraction. --- BasiliskII/src/Unix/video_x.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/BasiliskII/src/Unix/video_x.cpp b/BasiliskII/src/Unix/video_x.cpp index b02e2854..6f8be92a 100644 --- a/BasiliskII/src/Unix/video_x.cpp +++ b/BasiliskII/src/Unix/video_x.cpp @@ -1636,13 +1636,12 @@ bool VideoInit(bool classic) ErrorAlert(STR_UNSUPP_DEPTH_ERR); return false; } - std::sort(avail_depths, avail_depths + num_depths); -#ifdef __APPLE__ // 15-bit color does not seem to work on OS X - int *last = std::remove(avail_depths, avail_depths + num_depths, 15); - num_depths = ( (size_t)last - (size_t)avail_depths ) / sizeof(int); -#endif + int *list_end = std::remove(avail_depths, avail_depths + num_depths, + 15); + num_depths = list_end - avail_depths; + std::sort(avail_depths, avail_depths + num_depths); #ifdef ENABLE_FBDEV_DGA // Frame buffer name From c939be2d2d8a8b34133d55f54d80f2e5a43a7e18 Mon Sep 17 00:00:00 2001 From: Dan Sumorok Date: Sat, 25 May 2013 10:48:15 -0400 Subject: [PATCH 10/35] Removed objective-c from runtool source so it can be built with newer (not from Apple) versions of gcc. --- .../src/MacOSX/{runtool.m => runtool.c} | 54 ++++++++++++++----- BasiliskII/src/Unix/configure.ac | 2 +- BasiliskII/src/Unix/ether_unix.cpp | 4 +- 3 files changed, 45 insertions(+), 15 deletions(-) rename BasiliskII/src/MacOSX/{runtool.m => runtool.c} (68%) diff --git a/BasiliskII/src/MacOSX/runtool.m b/BasiliskII/src/MacOSX/runtool.c similarity index 68% rename from BasiliskII/src/MacOSX/runtool.m rename to BasiliskII/src/MacOSX/runtool.c index b866599c..691a2765 100644 --- a/BasiliskII/src/MacOSX/runtool.m +++ b/BasiliskII/src/MacOSX/runtool.c @@ -40,28 +40,56 @@ #include -FILE * run_tool(const char *ifName); +FILE * run_tool(const char *if_name, const char *tool_name); -FILE * run_tool(const char *ifName) +FILE * run_tool(const char *if_name, const char *tool_name) { OSStatus auth_status; - FILE *fp; + FILE *fp = NULL; char *args[] = {"etherslavetool", NULL, NULL}; int ret; - const char *path; + char path_buffer[256]; AuthorizationFlags auth_flags; AuthorizationRef auth_ref; AuthorizationItem auth_items[1]; AuthorizationRights auth_rights; + CFBundleRef bundle_ref; + CFURLRef url_ref; + CFStringRef path_str; + CFStringRef tool_name_str; - path = [[[NSBundle mainBundle] - pathForResource:@"etherslavetool" ofType: nil] UTF8String]; - - if (path == NULL) { + bundle_ref = CFBundleGetMainBundle(); + if(bundle_ref == NULL) { return NULL; } - args[1] = (char *)ifName; + tool_name_str = CFStringCreateWithCString(NULL, tool_name, + kCFStringEncodingUTF8); + + url_ref = CFBundleCopyResourceURL(bundle_ref, tool_name_str, + NULL, NULL); + + if(url_ref == NULL) { + return NULL; + } + + path_str = CFURLCopyFileSystemPath(url_ref, kCFURLPOSIXPathStyle); + CFRelease(url_ref); + + if(path_str == NULL) { + return NULL; + } + + CFIndex index = CFStringGetLength(path_str); + if(!CFStringGetCString(path_str, path_buffer, sizeof(path_buffer), + kCFStringEncodingUTF8)) { + CFRelease(path_str); + return NULL; + } + CFRelease(path_str); + + args[0] = (char *)tool_name; + args[1] = (char *)if_name; auth_flags = kAuthorizationFlagExtendRights | kAuthorizationFlagInteractionAllowed | @@ -81,18 +109,20 @@ FILE * run_tool(const char *ifName) &auth_ref); if (auth_status != errAuthorizationSuccess) { - fprintf(stderr, "%s: AuthorizationCreate() failed.\n", __func__); + fprintf(stderr, "%s: AuthorizationCreate() failed.\n", + __func__); return NULL; } auth_status = AuthorizationExecuteWithPrivileges(auth_ref, - path, + path_buffer, kAuthorizationFlagDefaults, args + 1, &fp); if (auth_status != errAuthorizationSuccess) { - fprintf(stderr, "%s: AuthorizationExecWithPrivileges() failed.\n", __func__); + fprintf(stderr, "%s: AuthorizationExecWithPrivileges() failed.\n", + __func__); return NULL; } diff --git a/BasiliskII/src/Unix/configure.ac b/BasiliskII/src/Unix/configure.ac index e0608635..e4d862d5 100644 --- a/BasiliskII/src/Unix/configure.ac +++ b/BasiliskII/src/Unix/configure.ac @@ -736,7 +736,7 @@ if [[ "x$WANT_MACOSX_SOUND" = "xyes" ]]; then fi if [[ "x$WANT_MACOSX_ETHERSLAVE" = "xyes" ]]; then - EXTRASYSSRCS="$EXTRASYSSRCS ../MacOSX/runtool.m" + EXTRASYSSRCS="$EXTRASYSSRCS ../MacOSX/runtool.c" LIBS="$LIBS -framework Security" AC_DEFINE(ENABLE_MACOSX_ETHERSLAVE, 1, [Define if supporting "etherslave" network device.]) fi diff --git a/BasiliskII/src/Unix/ether_unix.cpp b/BasiliskII/src/Unix/ether_unix.cpp index 2c030c7b..55c19426 100644 --- a/BasiliskII/src/Unix/ether_unix.cpp +++ b/BasiliskII/src/Unix/ether_unix.cpp @@ -106,7 +106,7 @@ enum { #ifdef ENABLE_MACOSX_ETHERSLAVE extern "C" { - extern FILE * run_tool(const char *if_name); + extern FILE * run_tool(const char *if_name, const char *tool_name); } #endif @@ -1168,7 +1168,7 @@ static bool open_ether_slave(const char *if_name) return false; } - fp = run_tool(if_name); + fp = run_tool(if_name, "etherslavetool"); if (fp == NULL) { snprintf(str, sizeof(str), "Unable to run ether slave helper tool."); WarningAlert(str); From 19b53082a3f0b30bebe9c7c55e339f516a838b1b Mon Sep 17 00:00:00 2001 From: Dan Sumorok Date: Sat, 25 May 2013 22:01:21 -0400 Subject: [PATCH 11/35] Added tap support to etherslave tool. --- BasiliskII/src/MacOSX/etherslavetool.c | 219 ++++++++++++++++++++++--- BasiliskII/src/MacOSX/runtool.c | 8 +- BasiliskII/src/Unix/ether_unix.cpp | 12 +- 3 files changed, 207 insertions(+), 32 deletions(-) diff --git a/BasiliskII/src/MacOSX/etherslavetool.c b/BasiliskII/src/MacOSX/etherslavetool.c index 57642774..1788fb8b 100644 --- a/BasiliskII/src/MacOSX/etherslavetool.c +++ b/BasiliskII/src/MacOSX/etherslavetool.c @@ -43,15 +43,27 @@ #include +#define STR_MAX 256 +#define MAX_ARGV 10 + static int open_bpf(char *ifname); +static int open_tap(char *ifname); static int retreive_auth_info(void); -static int main_loop(int sd); +static int main_loop(int sd, int use_bpf); +static int run_cmd(const char *cmd); +static void handler(int signum); +static int install_signal_handlers(); +static void do_exit(); + +static int removeBridge = 0; int main(int argc, char **argv) { char *if_name; - int ret; + int ret = 255; int sd; + int tapNum; + int use_bpf; if (argc != 2) { return 255; @@ -59,32 +71,41 @@ int main(int argc, char **argv) if_name = argv[1]; - ret = retreive_auth_info(); - if (ret != 0) { - return 254; - } + do { + ret = retreive_auth_info(); + if (ret != 0) { + ret = 254; + break; + } - fflush(stdout); + if(sscanf(if_name, "tap%d", &tapNum) == 1) { + sd = open_tap(if_name); + use_bpf = 0; + } else { + sd = open_bpf(if_name); + use_bpf = 0; + } - sd = open_bpf(if_name); - if (sd < 0) { - return 253; - } + if (sd < 0) { + ret = 253; + break; + } - fflush(stdout); + if(install_signal_handlers() != 0) { + ret = 252; + break; + } - ret = main_loop(sd); + ret = main_loop(sd, use_bpf); + close(sd); + } while(0); - close(sd); + do_exit(); - if (ret < 0) { - return 252; - } - - return 0; + return ret; } -static int main_loop(int sd) +static int main_loop(int sd, int use_bpf) { fd_set readSet; char *outgoing, *incoming; @@ -98,10 +119,15 @@ static int main_loop(int sd) int pkt_len; int frame_len; int pad; + char c = 0; - if (ioctl(sd, BIOCGBLEN, &blen) < 0) { - return -1; - } + if(use_bpf) { + if (ioctl(sd, BIOCGBLEN, &blen) < 0) { + return -1; + } + } else { + blen = 2048; + } incoming = malloc(blen); if (incoming == NULL) { @@ -119,6 +145,9 @@ static int main_loop(int sd) out_len = (unsigned short *)outgoing; + /* Let our parent know we are ready for business. */ + write(0, &c, 1); + while (1) { int i; FD_ZERO(&readSet); @@ -164,7 +193,7 @@ static int main_loop(int sd) } - if (FD_ISSET(sd, &readSet)) { + if (use_bpf && FD_ISSET(sd, &readSet)) { int i; ret = read(sd, incoming, blen); @@ -186,7 +215,11 @@ static int main_loop(int sd) } *in_len = pkt_len; - write(0, in_len, pkt_len + 2); + if(write(0, in_len, pkt_len + 2) < (pkt_len + 2)) { + fret = -10; + break; + } + if ((frame_len & 0x03) == 0) { pad = 0; } else { @@ -202,6 +235,24 @@ static int main_loop(int sd) break; } } + + if (!use_bpf && FD_ISSET(sd, &readSet)) { + in_len = (unsigned short *)incoming; + + pkt_len = read(sd, incoming+2, blen-2); + if (pkt_len < 14) { + fret = -8; + break; + } + + *in_len = ret; + if(write(0, in_len, pkt_len + 2) < (pkt_len + 2)) { + fret = -10; + break; + } + + } + } free(incoming); @@ -255,6 +306,44 @@ static int retreive_auth_info(void) return 0; } + +static int open_tap(char *ifname) +{ + char str[STR_MAX] = {0}; + int sd; + + snprintf(str, STR_MAX, "/dev/%s", ifname); + + sd = open(str, O_RDWR); + if(sd < 0) { + return -1; + } + + snprintf(str, STR_MAX, "/sbin/ifconfig %s up", ifname); + if(run_cmd(str) != 0) { + close(sd); + return -1; + } + + snprintf(str, STR_MAX, "/sbin/ifconfig bridge0 create"); + if(run_cmd(str) == 0) { + removeBridge = 1; + } + + snprintf(str, STR_MAX, "/sbin/ifconfig bridge0 addm %s", ifname); + if(run_cmd(str) != 0) { + close(sd); + return -1; + } + + snprintf(str, STR_MAX, "/sbin/ifconfig bridge0 up"); + if(run_cmd(str) != 0) { + close(sd); + return -1; + } + + return sd; +} static int open_bpf(char *ifname) { @@ -302,3 +391,83 @@ static int open_bpf(char *ifname) return sd; } + +static int run_cmd(const char *cmd) { + char cmd_buffer[STR_MAX] = {0}; + char *argv[MAX_ARGV + 1] = {0}; + int i; + pid_t pid, waitpid; + int status = 0; + + /* Collect arguments */ + strncpy(cmd_buffer, cmd, STR_MAX-1); + + argv[0] = strtok(cmd_buffer, " "); + for (i=1; i Date: Sun, 26 May 2013 20:58:03 -0400 Subject: [PATCH 12/35] More work on new tap interface. --- BasiliskII/src/MacOSX/etherslavetool.c | 179 +++++++++++++++---------- BasiliskII/src/Unix/ether_unix.cpp | 40 ++++-- 2 files changed, 141 insertions(+), 78 deletions(-) diff --git a/BasiliskII/src/MacOSX/etherslavetool.c b/BasiliskII/src/MacOSX/etherslavetool.c index 1788fb8b..e60c6ce9 100644 --- a/BasiliskII/src/MacOSX/etherslavetool.c +++ b/BasiliskII/src/MacOSX/etherslavetool.c @@ -74,16 +74,16 @@ int main(int argc, char **argv) do { ret = retreive_auth_info(); if (ret != 0) { - ret = 254; - break; + ret = 254; + break; } - if(sscanf(if_name, "tap%d", &tapNum) == 1) { + if (strncmp(if_name, "tap", 3) == 0) { sd = open_tap(if_name); use_bpf = 0; } else { sd = open_bpf(if_name); - use_bpf = 0; + use_bpf = 1; } if (sd < 0) { @@ -91,14 +91,14 @@ int main(int argc, char **argv) break; } - if(install_signal_handlers() != 0) { + if (install_signal_handlers() != 0) { ret = 252; break; } ret = main_loop(sd, use_bpf); close(sd); - } while(0); + } while (0); do_exit(); @@ -121,7 +121,7 @@ static int main_loop(int sd, int use_bpf) int pad; char c = 0; - if(use_bpf) { + if (use_bpf) { if (ioctl(sd, BIOCGBLEN, &blen) < 0) { return -1; } @@ -215,7 +215,7 @@ static int main_loop(int sd, int use_bpf) } *in_len = pkt_len; - if(write(0, in_len, pkt_len + 2) < (pkt_len + 2)) { + if (write(0, in_len, pkt_len + 2) < (pkt_len + 2)) { fret = -10; break; } @@ -245,8 +245,8 @@ static int main_loop(int sd, int use_bpf) break; } - *in_len = ret; - if(write(0, in_len, pkt_len + 2) < (pkt_len + 2)) { + *in_len = pkt_len; + if (write(0, in_len, pkt_len + 2) < (pkt_len + 2)) { fret = -10; break; } @@ -310,37 +310,80 @@ static int retreive_auth_info(void) static int open_tap(char *ifname) { char str[STR_MAX] = {0}; + char ifstr[STR_MAX] = {0}; + char *interface; + char *address = NULL; + char *netmask = NULL; + char *bridge = NULL; + char *bridged_if = NULL; int sd; - snprintf(str, STR_MAX, "/dev/%s", ifname); + snprintf(ifstr, STR_MAX, "%s", ifname); + interface = strtok(ifstr, "/"); + bridge = strtok(NULL, "/"); + if (bridge != NULL) { + bridged_if = strtok(NULL, "/"); + } + interface = strtok(ifstr, ":"); + + address = strtok(NULL, ":"); + + if (address != NULL) { + netmask = strtok(NULL, ":"); + } + + snprintf(str, STR_MAX, "/dev/%s", interface); sd = open(str, O_RDWR); - if(sd < 0) { + if (sd < 0) { return -1; } - snprintf(str, STR_MAX, "/sbin/ifconfig %s up", ifname); - if(run_cmd(str) != 0) { + if (address == NULL) { + snprintf(str, STR_MAX, "/sbin/ifconfig %s up", interface); + } else if (netmask == NULL) { + snprintf(str, STR_MAX, "/sbin/ifconfig %s %s", + interface, address); + } else { + snprintf(str, STR_MAX, "/sbin/ifconfig %s %s netmask %s", + interface, address, netmask); + } + + if (run_cmd(str) != 0) { close(sd); return -1; } - snprintf(str, STR_MAX, "/sbin/ifconfig bridge0 create"); - if(run_cmd(str) == 0) { - removeBridge = 1; - } + if (bridge != NULL) { + snprintf(str, STR_MAX, "/sbin/ifconfig %s create", bridge); + if (run_cmd(str) == 0) { + removeBridge = 1; + } - snprintf(str, STR_MAX, "/sbin/ifconfig bridge0 addm %s", ifname); - if(run_cmd(str) != 0) { - close(sd); - return -1; - } + snprintf(str, STR_MAX, "/sbin/ifconfig %s up", bridge); + if (run_cmd(str) != 0) { + close(sd); + return -1; + } - snprintf(str, STR_MAX, "/sbin/ifconfig bridge0 up"); - if(run_cmd(str) != 0) { - close(sd); - return -1; - } + if (bridged_if != NULL) { + snprintf(str, STR_MAX, "/sbin/ifconfig %s addm %s", + bridge, bridged_if); + if (run_cmd(str) != 0) { + close(sd); + return -1; + } + } + + snprintf(str, STR_MAX, "/sbin/ifconfig %s addm %s", + bridge, interface); + if (run_cmd(str) != 0) { + close(sd); + return -1; + } + + + } return sd; } @@ -393,49 +436,49 @@ static int open_bpf(char *ifname) } static int run_cmd(const char *cmd) { - char cmd_buffer[STR_MAX] = {0}; - char *argv[MAX_ARGV + 1] = {0}; - int i; - pid_t pid, waitpid; - int status = 0; + char cmd_buffer[STR_MAX] = {0}; + char *argv[MAX_ARGV + 1] = {0}; + int i; + pid_t pid, waitpid; + int status = 0; - /* Collect arguments */ - strncpy(cmd_buffer, cmd, STR_MAX-1); + /* Collect arguments */ + strncpy(cmd_buffer, cmd, STR_MAX-1); - argv[0] = strtok(cmd_buffer, " "); - for (i=1; i #include #include +#include #if defined(__FreeBSD__) || defined(sgi) || (defined(__APPLE__) && defined(__MACH__)) #include @@ -156,7 +157,7 @@ static int slirp_add_redir(const char *redir_str); #ifdef ENABLE_MACOSX_ETHERSLAVE static int get_mac_address(const char* dev, unsigned char *addr); -static bool open_ether_slave(const char *if_name); +static bool open_ether_slave(const std::string &if_name); static int read_packet(void); #endif @@ -260,7 +261,7 @@ bool ether_init(void) // Do nothing if no Ethernet device specified const char *name = PrefsFindString("ether"); #ifdef ENABLE_MACOSX_ETHERSLAVE - const char *slave_dev = PrefsFindString("etherslavedev"); + std::string slave_dev; #endif if (name == NULL) return false; @@ -278,7 +279,7 @@ bool ether_init(void) net_if_type = NET_IF_SLIRP; #endif #ifdef ENABLE_MACOSX_ETHERSLAVE - else if (strcmp(name, "etherslave") == 0) + else if (strncmp(name, "etherslave", 10) == 0) net_if_type = NET_IF_ETHERSLAVE; #endif else @@ -332,12 +333,23 @@ bool ether_init(void) strcpy(dev_name, "/dev/sheep_net"); break; #ifdef ENABLE_MACOSX_ETHERSLAVE - case NET_IF_ETHERSLAVE: - if (slave_dev == NULL) { - WarningAlert("etherslavedev not defined in preferences."); + case NET_IF_ETHERSLAVE: { + std::string device(name); + size_t pos; + + pos = device.find('/'); + if(pos != device.npos) { + slave_dev = device.substr(pos + 1); + } + + if(slave_dev.size() == 0) { + WarningAlert("No network device specified."); return false; } + return open_ether_slave(slave_dev); + } + #endif } if (net_if_type != NET_IF_SLIRP) { @@ -1156,21 +1168,29 @@ static int get_mac_address(const char* dev, unsigned char *addr) return ret; } -static bool open_ether_slave(const char *if_name) +static bool open_ether_slave(const std::string &if_name) { FILE *fp; char str[64]; + std::string dev_name; + size_t pos; - fp = run_tool(if_name, "etherslavetool"); + fp = run_tool(if_name.c_str(), "etherslavetool"); if (fp == NULL) { snprintf(str, sizeof(str), "Unable to run ether slave helper tool."); WarningAlert(str); return false; } - if (get_mac_address(if_name, ether_addr) != 0) { + pos = if_name.find('/'); + dev_name = if_name; + if(pos != if_name.npos) { + dev_name.erase(pos); + } + + if (get_mac_address(dev_name.c_str(), ether_addr) != 0) { snprintf(str, sizeof(str), "Unable to find interface %s.", - if_name); + dev_name.c_str()); WarningAlert(str); return false; } From 5aa782acc063597252b17d70b91e7005a9cee16c Mon Sep 17 00:00:00 2001 From: Dan Sumorok Date: Mon, 27 May 2013 13:55:38 -0400 Subject: [PATCH 13/35] Changed ethernet address when using tap interface. --- BasiliskII/src/MacOSX/etherslavetool.c | 4 ++-- BasiliskII/src/Unix/ether_unix.cpp | 21 ++++++++++++++++----- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/BasiliskII/src/MacOSX/etherslavetool.c b/BasiliskII/src/MacOSX/etherslavetool.c index e60c6ce9..baa5b46f 100644 --- a/BasiliskII/src/MacOSX/etherslavetool.c +++ b/BasiliskII/src/MacOSX/etherslavetool.c @@ -126,7 +126,7 @@ static int main_loop(int sd, int use_bpf) return -1; } } else { - blen = 2048; + blen = 4096; } incoming = malloc(blen); @@ -239,7 +239,7 @@ static int main_loop(int sd, int use_bpf) if (!use_bpf && FD_ISSET(sd, &readSet)) { in_len = (unsigned short *)incoming; - pkt_len = read(sd, incoming+2, blen-2); + pkt_len = read(sd, in_len + 1, blen-2); if (pkt_len < 14) { fret = -8; break; diff --git a/BasiliskII/src/Unix/ether_unix.cpp b/BasiliskII/src/Unix/ether_unix.cpp index 947ea080..8e005308 100644 --- a/BasiliskII/src/Unix/ether_unix.cpp +++ b/BasiliskII/src/Unix/ether_unix.cpp @@ -1188,11 +1188,22 @@ static bool open_ether_slave(const std::string &if_name) dev_name.erase(pos); } - if (get_mac_address(dev_name.c_str(), ether_addr) != 0) { - snprintf(str, sizeof(str), "Unable to find interface %s.", - dev_name.c_str()); - WarningAlert(str); - return false; + if(strncmp(if_name.c_str(), "tap", 3) != 0) { + if (get_mac_address(dev_name.c_str(), ether_addr) != 0) { + snprintf(str, sizeof(str), "Unable to find interface %s.", + dev_name.c_str()); + WarningAlert(str); + return false; + } + } else { + /* There is something special about this address. */ + pid_t p = getpid(); + ether_addr[0] = 0xfe; + ether_addr[1] = 0xfd; + ether_addr[2] = p >> 24; + ether_addr[3] = p >> 16; + ether_addr[4] = p >> 8; + ether_addr[5] = p; } fd = dup(fileno(fp)); From 8f863effbcf54ebfab1f8104621d1cda7fb6f110 Mon Sep 17 00:00:00 2001 From: Dan Sumorok Date: Tue, 28 May 2013 19:33:12 -0400 Subject: [PATCH 14/35] Added error messages. --- BasiliskII/src/MacOSX/etherslavetool.c | 52 +++++++++++++++++++++++--- 1 file changed, 46 insertions(+), 6 deletions(-) diff --git a/BasiliskII/src/MacOSX/etherslavetool.c b/BasiliskII/src/MacOSX/etherslavetool.c index baa5b46f..b49f17fe 100644 --- a/BasiliskII/src/MacOSX/etherslavetool.c +++ b/BasiliskII/src/MacOSX/etherslavetool.c @@ -55,7 +55,8 @@ static void handler(int signum); static int install_signal_handlers(); static void do_exit(); -static int removeBridge = 0; +static int remove_bridge = 0; +static const char *exec_name = "etherslavetool"; int main(int argc, char **argv) { @@ -68,12 +69,14 @@ int main(int argc, char **argv) if (argc != 2) { return 255; } - + if_name = argv[1]; do { ret = retreive_auth_info(); if (ret != 0) { + fprintf(stderr, "%s: authorization failed.\n", + exec_name); ret = 254; break; } @@ -87,11 +90,16 @@ int main(int argc, char **argv) } if (sd < 0) { + fprintf(stderr, "%s: open device failed.\n", + exec_name); ret = 253; break; } if (install_signal_handlers() != 0) { + fprintf(stderr, + "%s: failed to install signal handers.\n", + exec_name); ret = 252; break; } @@ -123,6 +131,9 @@ static int main_loop(int sd, int use_bpf) if (use_bpf) { if (ioctl(sd, BIOCGBLEN, &blen) < 0) { + fprintf(stderr, + "%s: ioctl() failed.\n", + exec_name); return -1; } } else { @@ -131,12 +142,18 @@ static int main_loop(int sd, int use_bpf) incoming = malloc(blen); if (incoming == NULL) { + fprintf(stderr, + "%s: malloc() failed.\n", + exec_name); return -2; } outgoing = malloc(blen); if (outgoing == NULL) { free(outgoing); + fprintf(stderr, + "%s: malloc() failed.\n", + exec_name); return -3; } @@ -156,6 +173,9 @@ static int main_loop(int sd, int use_bpf) ret = select(sd + 1, &readSet, NULL, NULL, NULL); if (ret < 0) { + fprintf(stderr, + "%s: select() failed.\n", + exec_name); fret = -4; break; } @@ -168,14 +188,17 @@ static int main_loop(int sd, int use_bpf) } if (ret < 1) { + if(ret < 0) { + fprintf(stderr, + "%s: read() failed.\n", + exec_name); + } fret = -5; break; } out_index += ret; if (out_index > 1) { - fflush(stdout); - if ((*out_len + 2) > blen) { fret = -6; break; @@ -184,6 +207,9 @@ static int main_loop(int sd, int use_bpf) if (out_index == (*out_len + 2)) { ret = write(sd, out_len + 1, *out_len); if (ret != *out_len) { + fprintf(stderr, + "%s: write() failed.\n", + exec_name); fret = -7; break; } @@ -198,6 +224,11 @@ static int main_loop(int sd, int use_bpf) ret = read(sd, incoming, blen); if (ret < 1) { + if(ret < 0) { + fprintf(stderr, + "%s: read() failed %d.\n", + exec_name, errno); + } fret = -8; break; } @@ -232,6 +263,9 @@ static int main_loop(int sd, int use_bpf) } while (ret > 0); if (fret != 0) { + fprintf(stderr, + "%s: fret == %d.\n", + exec_name, fret); break; } } @@ -241,12 +275,18 @@ static int main_loop(int sd, int use_bpf) pkt_len = read(sd, in_len + 1, blen-2); if (pkt_len < 14) { + fprintf(stderr, + "%s: read() returned %d.\n", + exec_name, pkt_len); fret = -8; break; } *in_len = pkt_len; if (write(0, in_len, pkt_len + 2) < (pkt_len + 2)) { + fprintf(stderr, + "%s: write() failed\n", + exec_name); fret = -10; break; } @@ -357,7 +397,7 @@ static int open_tap(char *ifname) if (bridge != NULL) { snprintf(str, STR_MAX, "/sbin/ifconfig %s create", bridge); if (run_cmd(str) == 0) { - removeBridge = 1; + remove_bridge = 1; } snprintf(str, STR_MAX, "/sbin/ifconfig %s up", bridge); @@ -510,7 +550,7 @@ static int install_signal_handlers() { } static void do_exit() { - if (removeBridge) { + if (remove_bridge) { run_cmd("/sbin/ifconfig bridge0 destroy"); } } From fc8835aa6fad68d86fdcc4a440a3b5cffefdc69a Mon Sep 17 00:00:00 2001 From: Dan Sumorok Date: Wed, 29 May 2013 07:00:44 -0400 Subject: [PATCH 15/35] Added more debug output. No longer add ethernet interface to bridge if bridge already exists. --- BasiliskII/src/MacOSX/etherslavetool.c | 66 +++++++++++++++++--------- 1 file changed, 44 insertions(+), 22 deletions(-) diff --git a/BasiliskII/src/MacOSX/etherslavetool.c b/BasiliskII/src/MacOSX/etherslavetool.c index b49f17fe..251765c6 100644 --- a/BasiliskII/src/MacOSX/etherslavetool.c +++ b/BasiliskII/src/MacOSX/etherslavetool.c @@ -376,6 +376,8 @@ static int open_tap(char *ifname) sd = open(str, O_RDWR); if (sd < 0) { + fprintf(stderr, "%s: Failed to open %s\n", + exec_name, interface); return -1; } @@ -390,39 +392,59 @@ static int open_tap(char *ifname) } if (run_cmd(str) != 0) { + fprintf(stderr, "%s: Failed to configure %s\n", + exec_name, interface); close(sd); return -1; } if (bridge != NULL) { - snprintf(str, STR_MAX, "/sbin/ifconfig %s create", bridge); + /* Check to see if bridge is alread up */ + snprintf(str, STR_MAX, "/sbin/ifconfig %s", bridge); if (run_cmd(str) == 0) { - remove_bridge = 1; - } - - snprintf(str, STR_MAX, "/sbin/ifconfig %s up", bridge); - if (run_cmd(str) != 0) { - close(sd); - return -1; - } - - if (bridged_if != NULL) { - snprintf(str, STR_MAX, "/sbin/ifconfig %s addm %s", - bridge, bridged_if); + /* bridge is already up */ + if (bridged_if != NULL) { + fprintf(stderr, "%s: Warning: %s already exists, so %s was not added.\n", + exec_name, bridge, bridged_if); + } + } else { + snprintf(str, STR_MAX, "/sbin/ifconfig %s create", bridge); if (run_cmd(str) != 0) { + fprintf(stderr, "%s: Failed to create %s\n", + exec_name, bridge); + close(sd); + return -1; + } + remove_bridge = 1; + + snprintf(str, STR_MAX, "/sbin/ifconfig %s up", bridge); + if (run_cmd(str) != 0) { + fprintf(stderr, "%s: Failed to open %s\n", + exec_name, bridge); + close(sd); + return -1; + } + + if (bridged_if != NULL) { + snprintf(str, STR_MAX, "/sbin/ifconfig %s addm %s", + bridge, bridged_if); + if (run_cmd(str) != 0) { + fprintf(stderr, "%s: Failed to add %s to %s\n", + exec_name, bridged_if, bridge); + close(sd); + return -1; + } + } + + snprintf(str, STR_MAX, "/sbin/ifconfig %s addm %s", + bridge, interface); + if (run_cmd(str) != 0) { + fprintf(stderr, "%s: Failed to add %s to %s\n", + exec_name, interface, bridge); close(sd); return -1; } } - - snprintf(str, STR_MAX, "/sbin/ifconfig %s addm %s", - bridge, interface); - if (run_cmd(str) != 0) { - close(sd); - return -1; - } - - } return sd; From 5db556214c5f2425001536cf9b9b6679472f1e01 Mon Sep 17 00:00:00 2001 From: Dan Sumorok Date: Wed, 29 May 2013 19:30:51 -0400 Subject: [PATCH 16/35] Renamed "etherslave" to "etherhelper". --- BasiliskII/src/MacOSX/{etherslavetool.c => etherhelpertool.c} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename BasiliskII/src/MacOSX/{etherslavetool.c => etherhelpertool.c} (100%) diff --git a/BasiliskII/src/MacOSX/etherslavetool.c b/BasiliskII/src/MacOSX/etherhelpertool.c similarity index 100% rename from BasiliskII/src/MacOSX/etherslavetool.c rename to BasiliskII/src/MacOSX/etherhelpertool.c From 8a021284733f38d1d65eba449c8756294fb0be12 Mon Sep 17 00:00:00 2001 From: Dan Sumorok Date: Wed, 29 May 2013 19:42:59 -0400 Subject: [PATCH 17/35] More changes of etherslave to etherhelper. --- BasiliskII/src/MacOSX/etherhelpertool.c | 4 +-- BasiliskII/src/MacOSX/runtool.c | 2 +- BasiliskII/src/Unix/.gitignore | 2 +- BasiliskII/src/Unix/Makefile.in | 8 ++--- BasiliskII/src/Unix/configure.ac | 10 +++--- BasiliskII/src/Unix/ether_unix.cpp | 46 ++++++++++++------------- BasiliskII/src/Unix/prefs_unix.cpp | 3 -- 7 files changed, 36 insertions(+), 39 deletions(-) diff --git a/BasiliskII/src/MacOSX/etherhelpertool.c b/BasiliskII/src/MacOSX/etherhelpertool.c index 251765c6..392f871a 100644 --- a/BasiliskII/src/MacOSX/etherhelpertool.c +++ b/BasiliskII/src/MacOSX/etherhelpertool.c @@ -1,5 +1,5 @@ /* - * etherslavetool.c - Reads and writes raw ethernet packets usng bpf + * etherhelpertool.c - Reads and writes raw ethernet packets usng bpf * interface. * * Copyright (C) 2010, Daniel Sumorok @@ -56,7 +56,7 @@ static int install_signal_handlers(); static void do_exit(); static int remove_bridge = 0; -static const char *exec_name = "etherslavetool"; +static const char *exec_name = "etherhelpertool"; int main(int argc, char **argv) { diff --git a/BasiliskII/src/MacOSX/runtool.c b/BasiliskII/src/MacOSX/runtool.c index b4bb21f4..77c38a43 100644 --- a/BasiliskII/src/MacOSX/runtool.c +++ b/BasiliskII/src/MacOSX/runtool.c @@ -46,7 +46,7 @@ FILE * run_tool(const char *if_name, const char *tool_name) { OSStatus auth_status; FILE *fp = NULL; - char *args[] = {"etherslavetool", NULL, NULL}; + char *args[] = {NULL, NULL, NULL}; int ret; char path_buffer[256]; AuthorizationFlags auth_flags; diff --git a/BasiliskII/src/Unix/.gitignore b/BasiliskII/src/Unix/.gitignore index 6d074222..a9dc119b 100644 --- a/BasiliskII/src/Unix/.gitignore +++ b/BasiliskII/src/Unix/.gitignore @@ -1,7 +1,7 @@ # Object files obj/* BasiliskII -etherslavetool +etherhelpertool # Autotools generated files Makefile diff --git a/BasiliskII/src/Unix/Makefile.in b/BasiliskII/src/Unix/Makefile.in index 0094fae7..21a0e6da 100644 --- a/BasiliskII/src/Unix/Makefile.in +++ b/BasiliskII/src/Unix/Makefile.in @@ -74,8 +74,8 @@ CXXFLAGS += $(GUI_CFLAGS) LIBS += $(GUI_LIBS) endif -ifeq (@MACOSX_ETHERSLAVE@,yes) -PROGS += etherslavetool +ifeq (@MACOSX_ETHERHELPER@,yes) +PROGS += etherhelpertool endif ## Rules @@ -142,7 +142,7 @@ $(GUI_APP)_app: $(GUI_APP) ../MacOSX/Info.plist ../MacOSX/$(APP).icns mkdir -p $(GUI_APP_APP)/Contents/Resources ./cpr.sh ../MacOSX/$(APP).icns $(GUI_APP_APP)/Contents/Resources/$(GUI_APP).icns -etherslavetool: ../MacOSX/etherslavetool.c +etherhelpertool: ../MacOSX/etherhelpertool.c $(CC) $(CPPFLAGS) $(DEFS) $(CFLAGS) $(LIBS) $< -o $@ modules: @@ -175,7 +175,7 @@ mostlyclean: clean: mostlyclean rm -f cpuemu.cpp cpudefs.cpp cputmp*.s cpufast*.s cpustbl.cpp cputbl.h compemu.cpp compstbl.cpp comptbl.h - rm -rf etherslavetool.dSYM + rm -rf etherhelpertool.dSYM distclean: clean rm -rf $(OBJ_DIR) diff --git a/BasiliskII/src/Unix/configure.ac b/BasiliskII/src/Unix/configure.ac index e4d862d5..161a2c50 100644 --- a/BasiliskII/src/Unix/configure.ac +++ b/BasiliskII/src/Unix/configure.ac @@ -24,8 +24,8 @@ AC_ARG_ENABLE(macosx-gui, [ --enable-macosx-gui enable Mac OS X GUI [def dnl Mac OS X Sound AC_ARG_ENABLE(macosx-sound, [ --enable-macosx-sound enable Mac OS X Sound [default=no]], [WANT_MACOSX_SOUND=$enableval], [WANT_MACOSX_SOUND=no]) -dnl Mac OS X etherslave support -AC_ARG_ENABLE(macosx-etherslave, [ --enable-macosx-etherslave enable Mac OS X Sound [default=no]], [WANT_MACOSX_ETHERSLAVE=$enableval], [WANT_MACOSX_ETHERSLAVE=no]) +dnl Mac OS X etherhelper support +AC_ARG_ENABLE(macosx-etherhelper, [ --enable-macosx-etherhelper enable Mac OS X Sound [default=no]], [WANT_MACOSX_ETHERHELPER=$enableval], [WANT_MACOSX_ETHERHELPER=no]) dnl Video options. AC_ARG_ENABLE(xf86-dga, [ --enable-xf86-dga use the XFree86 DGA extension [default=yes]], [WANT_XF86_DGA=$enableval], [WANT_XF86_DGA=yes]) @@ -735,13 +735,13 @@ if [[ "x$WANT_MACOSX_SOUND" = "xyes" ]]; then LIBS="$LIBS -framework AudioToolbox -framework AudioUnit -framework CoreAudio" fi -if [[ "x$WANT_MACOSX_ETHERSLAVE" = "xyes" ]]; then +if [[ "x$WANT_MACOSX_ETHERHELPER" = "xyes" ]]; then EXTRASYSSRCS="$EXTRASYSSRCS ../MacOSX/runtool.c" LIBS="$LIBS -framework Security" - AC_DEFINE(ENABLE_MACOSX_ETHERSLAVE, 1, [Define if supporting "etherslave" network device.]) + AC_DEFINE(ENABLE_MACOSX_ETHERHELPER, 1, [Define if supporting "etherhelper" network device.]) fi -AC_SUBST(MACOSX_ETHERSLAVE, $WANT_MACOSX_ETHERSLAVE) +AC_SUBST(MACOSX_ETHERHELPER, $WANT_MACOSX_ETHERHELPER) dnl SDL overrides if [[ "x$WANT_SDL" = "xyes" ]]; then diff --git a/BasiliskII/src/Unix/ether_unix.cpp b/BasiliskII/src/Unix/ether_unix.cpp index 8e005308..3c588dd1 100644 --- a/BasiliskII/src/Unix/ether_unix.cpp +++ b/BasiliskII/src/Unix/ether_unix.cpp @@ -42,7 +42,7 @@ #include #include -#ifdef ENABLE_MACOSX_ETHERSLAVE +#ifdef ENABLE_MACOSX_ETHERHELPER #include #include #endif @@ -101,11 +101,11 @@ enum { NET_IF_ETHERTAP, NET_IF_TUNTAP, NET_IF_SLIRP, - NET_IF_ETHERSLAVE + NET_IF_ETHERHELPER }; -#ifdef ENABLE_MACOSX_ETHERSLAVE +#ifdef ENABLE_MACOSX_ETHERHELPER extern "C" { extern FILE * run_tool(const char *if_name, const char *tool_name); } @@ -138,7 +138,7 @@ const bool ether_driver_opened = true; // Flag: is the MacOS driver opened? #endif -#ifdef ENABLE_MACOSX_ETHERSLAVE +#ifdef ENABLE_MACOSX_ETHERHELPER static uint8 packet_buffer[2048]; #endif @@ -155,9 +155,9 @@ static void ether_do_interrupt(void); static void slirp_add_redirs(); static int slirp_add_redir(const char *redir_str); -#ifdef ENABLE_MACOSX_ETHERSLAVE +#ifdef ENABLE_MACOSX_ETHERHELPER static int get_mac_address(const char* dev, unsigned char *addr); -static bool open_ether_slave(const std::string &if_name); +static bool open_ether_helper(const std::string &if_name); static int read_packet(void); #endif @@ -260,7 +260,7 @@ bool ether_init(void) // Do nothing if no Ethernet device specified const char *name = PrefsFindString("ether"); -#ifdef ENABLE_MACOSX_ETHERSLAVE +#ifdef ENABLE_MACOSX_ETHERHELPER std::string slave_dev; #endif if (name == NULL) @@ -278,9 +278,9 @@ bool ether_init(void) else if (strcmp(name, "slirp") == 0) net_if_type = NET_IF_SLIRP; #endif -#ifdef ENABLE_MACOSX_ETHERSLAVE - else if (strncmp(name, "etherslave", 10) == 0) - net_if_type = NET_IF_ETHERSLAVE; +#ifdef ENABLE_MACOSX_ETHERHELPER + else if (strncmp(name, "etherhelper", 10) == 0) + net_if_type = NET_IF_ETHERHELPER; #endif else net_if_type = NET_IF_SHEEPNET; @@ -332,8 +332,8 @@ bool ether_init(void) case NET_IF_SHEEPNET: strcpy(dev_name, "/dev/sheep_net"); break; -#ifdef ENABLE_MACOSX_ETHERSLAVE - case NET_IF_ETHERSLAVE: { +#ifdef ENABLE_MACOSX_ETHERHELPER + case NET_IF_ETHERHELPER: { std::string device(name); size_t pos; @@ -347,7 +347,7 @@ bool ether_init(void) return false; } - return open_ether_slave(slave_dev); + return open_ether_helper(slave_dev); } #endif @@ -802,8 +802,8 @@ static int16 ether_do_write(uint32 arg) return noErr; } else #endif -#ifdef ENABLE_MACOSX_ETHERSLAVE - if (net_if_type == NET_IF_ETHERSLAVE) { +#ifdef ENABLE_MACOSX_ETHERHELPER + if (net_if_type == NET_IF_ETHERHELPER) { unsigned short pkt_len; pkt_len = len; @@ -950,8 +950,8 @@ static void *receive_func(void *arg) if (res <= 0) break; -#ifdef ENABLE_MACOSX_ETHERSLAVE - if (net_if_type == NET_IF_ETHERSLAVE) { +#ifdef ENABLE_MACOSX_ETHERHELPER + if (net_if_type == NET_IF_ETHERHELPER) { if (read_packet() < 1) { break; } @@ -997,8 +997,8 @@ void ether_do_interrupt(void) } else #endif -#ifdef ENABLE_MACOSX_ETHERSLAVE - if (net_if_type == NET_IF_ETHERSLAVE) { +#ifdef ENABLE_MACOSX_ETHERHELPER + if (net_if_type == NET_IF_ETHERHELPER) { unsigned short *pkt_len; uint32 p = packet; @@ -1135,7 +1135,7 @@ static int slirp_add_redir(const char *redir_str) return -1; } -#ifdef ENABLE_MACOSX_ETHERSLAVE +#ifdef ENABLE_MACOSX_ETHERHELPER static int get_mac_address(const char* dev, unsigned char *addr) { struct ifaddrs *ifaddrs, *next; @@ -1168,16 +1168,16 @@ static int get_mac_address(const char* dev, unsigned char *addr) return ret; } -static bool open_ether_slave(const std::string &if_name) +static bool open_ether_helper(const std::string &if_name) { FILE *fp; char str[64]; std::string dev_name; size_t pos; - fp = run_tool(if_name.c_str(), "etherslavetool"); + fp = run_tool(if_name.c_str(), "etherhelpertool"); if (fp == NULL) { - snprintf(str, sizeof(str), "Unable to run ether slave helper tool."); + snprintf(str, sizeof(str), "Unable to run ether helper helper tool."); WarningAlert(str); return false; } diff --git a/BasiliskII/src/Unix/prefs_unix.cpp b/BasiliskII/src/Unix/prefs_unix.cpp index 43f70fb6..a92cd640 100644 --- a/BasiliskII/src/Unix/prefs_unix.cpp +++ b/BasiliskII/src/Unix/prefs_unix.cpp @@ -40,9 +40,6 @@ prefs_desc platform_prefs_items[] = { {"mixer", TYPE_STRING, false, "audio mixer device name"}, #ifdef HAVE_SIGSEGV_SKIP_INSTRUCTION {"ignoresegv", TYPE_BOOLEAN, false, "ignore illegal memory accesses"}, -#endif -#ifdef ENABLE_MACOSX_ETHERSLAVE - {"etherslavedev", TYPE_STRING, false, "ethernet device for etherslave ethernet"}, #endif {"idlewait", TYPE_BOOLEAN, false, "sleep when idle"}, {NULL, TYPE_END, false, NULL} // End of list From eedf6880dbaaa0b08c05c77d53529fc66756f7f6 Mon Sep 17 00:00:00 2001 From: Dan Sumorok Date: Sun, 9 Jun 2013 16:27:24 -0400 Subject: [PATCH 18/35] A bit of apple sound chip support. --- BasiliskII/src/MacOSX/AudioBackEnd.cpp | 46 +++-- BasiliskII/src/MacOSX/AudioBackEnd.h | 2 +- BasiliskII/src/MacOSX/MacOSX_sound_if.cpp | 3 +- BasiliskII/src/MacOSX/MacOSX_sound_if.h | 2 +- BasiliskII/src/Unix/configure.ac | 8 + BasiliskII/src/emul_op.cpp | 22 +++ BasiliskII/src/uae_cpu/basilisk_glue.cpp | 208 ++++++++++++++++++++++ BasiliskII/src/uae_cpu/memory.h | 39 ++++ 8 files changed, 309 insertions(+), 21 deletions(-) diff --git a/BasiliskII/src/MacOSX/AudioBackEnd.cpp b/BasiliskII/src/MacOSX/AudioBackEnd.cpp index 65a8cb5d..f8c31f29 100644 --- a/BasiliskII/src/MacOSX/AudioBackEnd.cpp +++ b/BasiliskII/src/MacOSX/AudioBackEnd.cpp @@ -191,20 +191,22 @@ OSStatus AudioBackEnd::SetupBuffers() { asbd.mFormatID = 0x6c70636d; // 'lpcm' - asbd.mFormatFlags = (kAudioFormatFlagIsSignedInteger | - kAudioFormatFlagIsBigEndian | - kAudioFormatFlagIsPacked); - asbd.mChannelsPerFrame = mNumChannels; - asbd.mSampleRate = mSampleRate; - - if(asbd.mFormatFlags & kAudioFormatFlagIsSignedInteger) { - asbd.mBitsPerChannel = mBitsPerSample; - } else if(asbd.mFormatFlags & kAudioFormatFlagIsFloat) { - asbd.mBitsPerChannel = 32; + if(mBitsPerSample == 16) { + asbd.mFormatFlags = (kAudioFormatFlagIsSignedInteger | + kAudioFormatFlagIsBigEndian | + kAudioFormatFlagIsPacked); + } else if(mBitsPerSample == 8) { + asbd.mFormatFlags = kAudioFormatFlagIsPacked; } else { - asbd.mBitsPerChannel = 0; + asbd.mFormatFlags = kAudioFormatFlagsAreAllClear; } + asbd.mChannelsPerFrame = mNumChannels; + + asbd.mSampleRate = mSampleRate; + + asbd.mBitsPerChannel = mBitsPerSample; + asbd.mFramesPerPacket = 1; asbd.mBytesPerFrame = (asbd.mBitsPerChannel / 8) * asbd.mChannelsPerFrame; asbd.mBytesPerPacket = asbd.mBytesPerFrame * asbd.mFramesPerPacket; @@ -269,7 +271,6 @@ OSStatus AudioBackEnd::OutputProc(void *inRefCon, This->mAudioBufferReadIndex += bytesToCopy; } - while(This->mFramesProcessed >= This->mBufferSizeFrames) { This->mFramesProcessed -= This->mBufferSizeFrames; if(This->mCallback != NULL) { @@ -289,19 +290,28 @@ UInt32 AudioBackEnd::BufferSizeFrames() { return mBufferSizeFrames; } -int AudioBackEnd::sendAudioBuffer(void *buffer, int numFrames) { +int AudioBackEnd::sendAudioBuffer(const void *buffer, int numFrames) { UInt8 *dstBuffer; int totalBytes; - + int framesWritten; + + if(numFrames > mBufferSizeFrames) { + framesWritten = mBufferSizeFrames; + } else { + framesWritten = numFrames; + } + mAudioBufferWriteIndex += (mAudioBufferSize / 2); mAudioBufferWriteIndex &= (mAudioBufferSize - 1); dstBuffer = &mAudioBuffer[mAudioBufferWriteIndex]; - totalBytes = mBytesPerFrame * numFrames; + totalBytes = mBytesPerFrame * framesWritten; memcpy(dstBuffer, buffer, totalBytes); - dstBuffer += totalBytes; - bzero(dstBuffer, (mBufferSizeFrames * mBytesPerFrame) - totalBytes); + if(framesWritten < mBufferSizeFrames) { + dstBuffer += totalBytes; + bzero(dstBuffer, (mBufferSizeFrames * mBytesPerFrame) - totalBytes); + } - return numFrames; + return framesWritten; } diff --git a/BasiliskII/src/MacOSX/AudioBackEnd.h b/BasiliskII/src/MacOSX/AudioBackEnd.h index 455d42ff..d17c746e 100644 --- a/BasiliskII/src/MacOSX/AudioBackEnd.h +++ b/BasiliskII/src/MacOSX/AudioBackEnd.h @@ -51,7 +51,7 @@ class AudioBackEnd { Boolean IsRunning(); void setCallback(playthruCallback func, void *arg); UInt32 BufferSizeFrames(); - int sendAudioBuffer(void *buffer, int numFrames); + int sendAudioBuffer(const void *buffer, int numFrames); private: OSStatus SetupGraph(); OSStatus CallbackSetup(); diff --git a/BasiliskII/src/MacOSX/MacOSX_sound_if.cpp b/BasiliskII/src/MacOSX/MacOSX_sound_if.cpp index bb463c65..86064c53 100644 --- a/BasiliskII/src/MacOSX/MacOSX_sound_if.cpp +++ b/BasiliskII/src/MacOSX/MacOSX_sound_if.cpp @@ -18,6 +18,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + #include "AudioBackEnd.h" #include "MacOSX_sound_if.h" @@ -77,7 +78,7 @@ unsigned int OSXsoundOutput::bufferSizeFrames() { return 0; } -int OSXsoundOutput::sendAudioBuffer(void *buffer, int numFrames) { +int OSXsoundOutput::sendAudioBuffer(const void *buffer, int numFrames) { if(player != NULL) { return player->sendAudioBuffer(buffer, numFrames); } diff --git a/BasiliskII/src/MacOSX/MacOSX_sound_if.h b/BasiliskII/src/MacOSX/MacOSX_sound_if.h index 5cfdd438..1e81a38f 100644 --- a/BasiliskII/src/MacOSX/MacOSX_sound_if.h +++ b/BasiliskII/src/MacOSX/MacOSX_sound_if.h @@ -37,5 +37,5 @@ class OSXsoundOutput { int putBuffer(void *buffer, int numSamples); void setCallback(audioCallback fn); unsigned int bufferSizeFrames(); - int sendAudioBuffer(void *buffer, int numFrames); + int sendAudioBuffer(const void *buffer, int numFrames); }; diff --git a/BasiliskII/src/Unix/configure.ac b/BasiliskII/src/Unix/configure.ac index 161a2c50..b5be6988 100644 --- a/BasiliskII/src/Unix/configure.ac +++ b/BasiliskII/src/Unix/configure.ac @@ -24,6 +24,9 @@ AC_ARG_ENABLE(macosx-gui, [ --enable-macosx-gui enable Mac OS X GUI [def dnl Mac OS X Sound AC_ARG_ENABLE(macosx-sound, [ --enable-macosx-sound enable Mac OS X Sound [default=no]], [WANT_MACOSX_SOUND=$enableval], [WANT_MACOSX_SOUND=no]) +dnl Apple Sound Chip Emulation +AC_ARG_ENABLE(asc-emu, [ --enable-asc-emu enable Apple Sound Chip emulation [default=no]], [WANT_ASC_EMU=$enableval], [WANT_ASC_EMU=no]) + dnl Mac OS X etherhelper support AC_ARG_ENABLE(macosx-etherhelper, [ --enable-macosx-etherhelper enable Mac OS X Sound [default=no]], [WANT_MACOSX_ETHERHELPER=$enableval], [WANT_MACOSX_ETHERHELPER=no]) @@ -741,6 +744,11 @@ if [[ "x$WANT_MACOSX_ETHERHELPER" = "xyes" ]]; then AC_DEFINE(ENABLE_MACOSX_ETHERHELPER, 1, [Define if supporting "etherhelper" network device.]) fi +if [[ "x$WANT_ASC_EMU" = "xyes" ]]; then + AC_DEFINE(ENABLE_ASC_EMU, 1, [Define if supporting Apple Sound Chip Emulation.]) + AUDIOSRC+=" ../MacOSX/asc.cpp" +fi + AC_SUBST(MACOSX_ETHERHELPER, $WANT_MACOSX_ETHERHELPER) dnl SDL overrides diff --git a/BasiliskII/src/emul_op.cpp b/BasiliskII/src/emul_op.cpp index af5bb7dc..1b1b2958 100644 --- a/BasiliskII/src/emul_op.cpp +++ b/BasiliskII/src/emul_op.cpp @@ -251,12 +251,34 @@ void EmulOp(uint16 opcode, M68kRegisters *r) // Setup fake ASC registers if (ROMVersion == ROM_VERSION_32) { +#ifdef ENABLE_ASC_EMU + uae_u32 paramBlk; + uae_u32 ioNamePtr; + uae_u32 namePtr; + + r.d[0] = 100; + Execute68kTrap(0xa71e, &r); // NewPtrSysClear() + + paramBlk = r.a[0]; // pointer to a ParamBlockRec + ioNamePtr = paramBlk + 18; // Pointer to ioNamePtr field + namePtr = r.a[0] + 80; // Storage for ".sound" string + + memcpy(Mac2HostAddr(namePtr), "\006.sound", 7); + *((uae_u32*)Mac2HostAddr(ioNamePtr)) = ntohl(namePtr); + + Execute68kTrap(0xa000, &r); // PBOpenSync() + + r.a[0] = paramBlk; + Execute68kTrap(0x101f, &r); // DisposePtr(); + +#else r.d[0] = 0x1000; Execute68kTrap(0xa71e, &r); // NewPtrSysClear() uint32 asc_regs = r.a[0]; D(bug("ASC registers at %08lx\n", asc_regs)); WriteMacInt8(asc_regs + 0x800, 0x0f); // Set ASC version number WriteMacInt32(0xcc0, asc_regs); // Set ASCBase +#endif } break; } diff --git a/BasiliskII/src/uae_cpu/basilisk_glue.cpp b/BasiliskII/src/uae_cpu/basilisk_glue.cpp index b29c7702..5dd8704c 100644 --- a/BasiliskII/src/uae_cpu/basilisk_glue.cpp +++ b/BasiliskII/src/uae_cpu/basilisk_glue.cpp @@ -264,3 +264,211 @@ void Execute68k(uint32 addr, struct M68kRegisters *r) r->a[i] = m68k_areg(regs, i); quit_program = false; } + +#ifdef ENABLE_ASC_EMU +#include + +static uae_u8 ASCRegs[0x2000] = {0}; +static const int fifoCapacity = 2048; +static uint32 fifoInA = 0; +static uint32 fifoInB = 0; +static uint32 fifoWriteA = 0; +static uint32 fifoWriteB = 0; +static uint32 fifoOutA = 0; +static uint32 fifoOutB = 0; +static uae_u8 fifoA[fifoCapacity]; +static uae_u8 fifoB[fifoCapacity]; +static int32 ascBufferSize = -1; +static int soundRunning = 0; +static int soundStop = 0; +static uae_u8 zeros[1024] = {0}; + +extern uae_u32 io_read(uaecptr addr, int width_bits) { + if((addr & 0x00ff000) == 0x0014000) { + // Apple Sound Chip + + uaecptr offset = addr & 0x00000fff; + uae_u32 val; + + if(offset < 0x400) { + /* Read of FIFO A. */ + } else if(offset < 0x800) { + /* Read of Fifo B */ + } else { + if(width_bits > 8) { + fprintf(stderr, + "Unexpected ASC read width %d\n", width_bits); + return 0; + } + + switch(offset) { + case 0x800: + // VERSION + return 0; + + case 0x804: + // FIFO IRQ STATUS + val = 0; + if((fifoInA - fifoWriteA) >= 0x200) { + val = 0x1; + } + if((fifoInA - fifoWriteA) >= 0x400) { + val = 0x2; + } + + val |= (val << 2); + return val; + + default: + return ASCRegs[offset]; + break; + } + } + + } + + return 0x00; +} + +extern void io_write(uaecptr addr, uae_u32 b, int width_bits) { + static int downsample = 0; + + if((addr & 0x00ff000) == 0x0014000) { + if(soundStop) { + asc_stop(); + soundRunning = 0; + soundStop = 0; + } + + // Apple Sound Chip + if(width_bits > 8) { + fprintf(stderr, + "Unexpected ASC read width %d, addr 0x%08x\n", + width_bits, addr); + return; + } + + uaecptr offset = addr & 0x00000fff; + uae_u32 val; + + if(offset < 0x400) { + if(ASCRegs[0x801] != 2) { + static int counter = 0; + static int32 depthA = fifoInA - fifoWriteA; + + // FIFO Mode + if(depthA == fifoCapacity) { + return; + } + + if(ASCRegs[0x807] == 0) { + downsample += 22050; + if(downsample >= 22257) { + downsample -= 22257; + fifoA[(fifoInA++) % fifoCapacity] = b; + } + } else { + fifoA[(fifoInA++) % fifoCapacity] = b; + } + + if(soundRunning == 0) { + depthA = fifoInA - fifoWriteA; + + if(depthA >= 1024) { + if(ASCRegs[0x807] == 3) { + asc_init(44100); + } else { + asc_init(22050); + } + ascBufferSize = asc_get_buffer_size(); + soundRunning = 1; + + while(((fifoWriteA - fifoOutA) < (ascBufferSize*2)) && + ((fifoInA - fifoWriteA) > ascBufferSize) ){ + asc_process_samples(&fifoA[fifoWriteA % fifoCapacity], + ascBufferSize); + fifoWriteA += ascBufferSize; + } + } + } + } else { + // Non fifo mode write + } + } else if(offset < 0x800) { + } else { + switch(offset) { + case 0x801: + // MODE + // 1 = FIFO mode, 2 = wavetable mode + ASCRegs[0x801] = b & 0x03; + asc_stop(); + soundRunning = 0; + break; + + case 0x802: + // CONTROL + // bit 0: analog or PWM output + // bit 1: stereo/mono + // bit 7: processing time exceeded + ASCRegs[0x802] = b; + break; + + case 0x803: + // FIFO Mode + if(b & 0x80) { + downsample = 0; + asc_stop(); + soundRunning = 0; + } + break; + + case 0x804: + // fifo status + break; + + case 0x805: + // wavetable control + break; + + case 0x806: + // Volume + break; + + case 0x807: + // Clock rate 0 = 22257, 2 = 22050, 3 = 44100 + downsample = 0; + ASCRegs[0x807] = b; + break; + + case 0x80f: + printf("ASC Test\n"); + break; + + default: + break; + } + } + } + +} + +void asc_callback() { + if(zeros[0] == 0) { + memset(zeros, 128, sizeof(zeros)); + } + if(soundRunning == 0) { + asc_process_samples(zeros, ascBufferSize); + return; + } + + fifoOutA += ascBufferSize; + + if((fifoInA - fifoWriteA) >= ascBufferSize) { + asc_process_samples(&fifoA[fifoWriteA % fifoCapacity], ascBufferSize); + fifoWriteA += ascBufferSize; + } else { + static int ucount = 0; + asc_process_samples(zeros, ascBufferSize); + } +} +#endif diff --git a/BasiliskII/src/uae_cpu/memory.h b/BasiliskII/src/uae_cpu/memory.h index 75a6303b..a2acce2b 100644 --- a/BasiliskII/src/uae_cpu/memory.h +++ b/BasiliskII/src/uae_cpu/memory.h @@ -23,6 +23,10 @@ #ifndef UAE_MEMORY_H #define UAE_MEMORY_H +#ifdef HAVE_CONFIG_H +#include +#endif + #if !DIRECT_ADDRESSING && !REAL_ADDRESSING /* Enabling this adds one additional native memory reference per 68k memory @@ -124,6 +128,9 @@ extern uintptr MEMBaseDiff; #endif #if REAL_ADDRESSING || DIRECT_ADDRESSING +extern uae_u32 io_read(uaecptr addr, int width_bits); +extern void io_write(uaecptr addr, uae_u32 b, int width_bits); + static __inline__ uae_u8 *do_get_real_address(uaecptr addr) { return (uae_u8 *)MEMBaseDiff + addr; @@ -134,31 +141,63 @@ static __inline__ uae_u32 do_get_virtual_address(uae_u8 *addr) } static __inline__ uae_u32 get_long(uaecptr addr) { + if(addr & 0x40000000) { + return io_read(addr, 32); + } + uae_u32 * const m = (uae_u32 *)do_get_real_address(addr); return do_get_mem_long(m); } static __inline__ uae_u32 get_word(uaecptr addr) { +#ifdef ENABLE_ASC_EMU + if(addr & 0x40000000) { + return io_read(addr, 16); + } +#endif uae_u16 * const m = (uae_u16 *)do_get_real_address(addr); return do_get_mem_word(m); } static __inline__ uae_u32 get_byte(uaecptr addr) { +#ifdef ENABLE_ASC_EMU uae_u8 * const m = (uae_u8 *)do_get_real_address(addr); + if(addr & 0x40000000) { + return io_read(addr, 8); + } +#endif return do_get_mem_byte(m); } static __inline__ void put_long(uaecptr addr, uae_u32 l) { +#ifdef ENABLE_ASC_EMU + if(addr & 0x40000000) { + io_write(addr, l, 32); + return; + } +#endif uae_u32 * const m = (uae_u32 *)do_get_real_address(addr); do_put_mem_long(m, l); } static __inline__ void put_word(uaecptr addr, uae_u32 w) { +#ifdef ENABLE_ASC_EMU + if(addr & 0x40000000) { + io_write(addr, w, 16); + return; + } +#endif uae_u16 * const m = (uae_u16 *)do_get_real_address(addr); do_put_mem_word(m, w); } static __inline__ void put_byte(uaecptr addr, uae_u32 b) { +#ifdef ENABLE_ASC_EMU + if(addr & 0x40000000) { + io_write(addr, b, 8); + return; + } +#endif uae_u8 * const m = (uae_u8 *)do_get_real_address(addr); do_put_mem_byte(m, b); } From ce68f366cb042993e3dbe5401b2d81e06ed0e099 Mon Sep 17 00:00:00 2001 From: Dan Sumorok Date: Sun, 9 Jun 2013 19:34:19 -0400 Subject: [PATCH 19/35] Added asc.c, and asc.h. Don't stop sound if we don't have to. --- BasiliskII/src/MacOSX/asc.cpp | 51 ++++++++++++++++++++++++ BasiliskII/src/include/asc.h | 13 ++++++ BasiliskII/src/uae_cpu/basilisk_glue.cpp | 36 ++++++++++------- 3 files changed, 85 insertions(+), 15 deletions(-) create mode 100644 BasiliskII/src/MacOSX/asc.cpp create mode 100644 BasiliskII/src/include/asc.h diff --git a/BasiliskII/src/MacOSX/asc.cpp b/BasiliskII/src/MacOSX/asc.cpp new file mode 100644 index 00000000..2780d704 --- /dev/null +++ b/BasiliskII/src/MacOSX/asc.cpp @@ -0,0 +1,51 @@ +#include +#include +#include "MacOSX_sound_if.h" + +static OSXsoundOutput *soundOutput = NULL; + +static int audioInt(void); + +bool asc_init(int32 sample_rate) { + if(soundOutput != NULL) { + delete soundOutput; + soundOutput = NULL; + } + + soundOutput = new OSXsoundOutput(); + soundOutput->start(8, 1, sample_rate); + soundOutput->setCallback(audioInt); + + return true; +} + +bool asc_process_samples(const uae_u8 *samples, int count) { + if(soundOutput == NULL) { + return false; + } + + if(soundOutput->sendAudioBuffer((const void *)samples, count) != 0) { + return false; + } + + return true; +} + +static int audioInt(void) { + asc_callback(); + + return 0; +} + +int32 asc_get_buffer_size() { + if(soundOutput == NULL) { + return -1; + } + + return (int32) soundOutput->bufferSizeFrames(); +} + +void asc_stop() { + delete soundOutput; + soundOutput = NULL; +} diff --git a/BasiliskII/src/include/asc.h b/BasiliskII/src/include/asc.h new file mode 100644 index 00000000..2b52ed43 --- /dev/null +++ b/BasiliskII/src/include/asc.h @@ -0,0 +1,13 @@ +#ifndef ASC_H +#define ASC_H + +#include "sysdeps.h" +#include "cpu_emulation.h" + +bool asc_init(int32 sample_rate); +bool asc_process_samples(const uae_u8 *samples, int count); +int32 asc_get_buffer_size(); +void asc_callback(); +void asc_stop(); + +#endif diff --git a/BasiliskII/src/uae_cpu/basilisk_glue.cpp b/BasiliskII/src/uae_cpu/basilisk_glue.cpp index 5dd8704c..eb40d014 100644 --- a/BasiliskII/src/uae_cpu/basilisk_glue.cpp +++ b/BasiliskII/src/uae_cpu/basilisk_glue.cpp @@ -280,8 +280,8 @@ static uae_u8 fifoA[fifoCapacity]; static uae_u8 fifoB[fifoCapacity]; static int32 ascBufferSize = -1; static int soundRunning = 0; -static int soundStop = 0; static uae_u8 zeros[1024] = {0}; +static uae_u8 lastMode = 0; extern uae_u32 io_read(uaecptr addr, int width_bits) { if((addr & 0x00ff000) == 0x0014000) { @@ -334,12 +334,6 @@ extern void io_write(uaecptr addr, uae_u32 b, int width_bits) { static int downsample = 0; if((addr & 0x00ff000) == 0x0014000) { - if(soundStop) { - asc_stop(); - soundRunning = 0; - soundStop = 0; - } - // Apple Sound Chip if(width_bits > 8) { fprintf(stderr, @@ -383,8 +377,8 @@ extern void io_write(uaecptr addr, uae_u32 b, int width_bits) { ascBufferSize = asc_get_buffer_size(); soundRunning = 1; - while(((fifoWriteA - fifoOutA) < (ascBufferSize*2)) && - ((fifoInA - fifoWriteA) > ascBufferSize) ){ + while( //((fifoWriteA - fifoOutA) < (ascBufferSize*2)) && + ((fifoInA - fifoWriteA) > ascBufferSize) ) { asc_process_samples(&fifoA[fifoWriteA % fifoCapacity], ascBufferSize); fifoWriteA += ascBufferSize; @@ -401,11 +395,22 @@ extern void io_write(uaecptr addr, uae_u32 b, int width_bits) { // MODE // 1 = FIFO mode, 2 = wavetable mode ASCRegs[0x801] = b & 0x03; - asc_stop(); - soundRunning = 0; + if(b == 0) { + break; + } + + if(ASCRegs[0x801] != lastMode) { + asc_stop(); + soundRunning = 0; + fifoWriteA = fifoInA; + } + lastMode = ASCRegs[0x801]; break; case 0x802: + if(ASCRegs[0x802] == b) { + break; + } // CONTROL // bit 0: analog or PWM output // bit 1: stereo/mono @@ -416,9 +421,9 @@ extern void io_write(uaecptr addr, uae_u32 b, int width_bits) { case 0x803: // FIFO Mode if(b & 0x80) { - downsample = 0; - asc_stop(); - soundRunning = 0; + if(fifoInA > (fifoWriteA + ascBufferSize)) { + fifoInA = fifoWriteA + ascBufferSize; + } } break; @@ -463,7 +468,8 @@ void asc_callback() { fifoOutA += ascBufferSize; - if((fifoInA - fifoWriteA) >= ascBufferSize) { + if( ((fifoInA - fifoWriteA) >= ascBufferSize) && + (ASCRegs[0x801] == 1)) { asc_process_samples(&fifoA[fifoWriteA % fifoCapacity], ascBufferSize); fifoWriteA += ascBufferSize; } else { From b7cfe894457fabaab2bc3a5776e6c964b395de82 Mon Sep 17 00:00:00 2001 From: Dan Sumorok Date: Sat, 15 Jun 2013 16:21:26 -0400 Subject: [PATCH 20/35] More asc fixes. --- BasiliskII/src/uae_cpu/basilisk_glue.cpp | 121 ++++++++++++----------- 1 file changed, 65 insertions(+), 56 deletions(-) diff --git a/BasiliskII/src/uae_cpu/basilisk_glue.cpp b/BasiliskII/src/uae_cpu/basilisk_glue.cpp index eb40d014..84ed137e 100644 --- a/BasiliskII/src/uae_cpu/basilisk_glue.cpp +++ b/BasiliskII/src/uae_cpu/basilisk_glue.cpp @@ -266,22 +266,20 @@ void Execute68k(uint32 addr, struct M68kRegisters *r) } #ifdef ENABLE_ASC_EMU + #include static uae_u8 ASCRegs[0x2000] = {0}; static const int fifoCapacity = 2048; static uint32 fifoInA = 0; -static uint32 fifoInB = 0; static uint32 fifoWriteA = 0; -static uint32 fifoWriteB = 0; static uint32 fifoOutA = 0; -static uint32 fifoOutB = 0; static uae_u8 fifoA[fifoCapacity]; -static uae_u8 fifoB[fifoCapacity]; +static int underrun = 0; +static int clearFifo = 0; static int32 ascBufferSize = -1; static int soundRunning = 0; static uae_u8 zeros[1024] = {0}; -static uae_u8 lastMode = 0; extern uae_u32 io_read(uaecptr addr, int width_bits) { if((addr & 0x00ff000) == 0x0014000) { @@ -291,9 +289,9 @@ extern uae_u32 io_read(uaecptr addr, int width_bits) { uae_u32 val; if(offset < 0x400) { - /* Read of FIFO A. */ + return 0; } else if(offset < 0x800) { - /* Read of Fifo B */ + return 0; } else { if(width_bits > 8) { fprintf(stderr, @@ -317,6 +315,7 @@ extern uae_u32 io_read(uaecptr addr, int width_bits) { } val |= (val << 2); + return val; default: @@ -327,7 +326,7 @@ extern uae_u32 io_read(uaecptr addr, int width_bits) { } - return 0x00; + return 0; } extern void io_write(uaecptr addr, uae_u32 b, int width_bits) { @@ -361,33 +360,9 @@ extern void io_write(uaecptr addr, uae_u32 b, int width_bits) { downsample -= 22257; fifoA[(fifoInA++) % fifoCapacity] = b; } - } else { - fifoA[(fifoInA++) % fifoCapacity] = b; } - - if(soundRunning == 0) { - depthA = fifoInA - fifoWriteA; - - if(depthA >= 1024) { - if(ASCRegs[0x807] == 3) { - asc_init(44100); - } else { - asc_init(22050); - } - ascBufferSize = asc_get_buffer_size(); - soundRunning = 1; - - while( //((fifoWriteA - fifoOutA) < (ascBufferSize*2)) && - ((fifoInA - fifoWriteA) > ascBufferSize) ) { - asc_process_samples(&fifoA[fifoWriteA % fifoCapacity], - ascBufferSize); - fifoWriteA += ascBufferSize; - } - } - } - } else { - // Non fifo mode write } + } else if(offset < 0x800) { } else { switch(offset) { @@ -395,22 +370,9 @@ extern void io_write(uaecptr addr, uae_u32 b, int width_bits) { // MODE // 1 = FIFO mode, 2 = wavetable mode ASCRegs[0x801] = b & 0x03; - if(b == 0) { - break; - } - - if(ASCRegs[0x801] != lastMode) { - asc_stop(); - soundRunning = 0; - fifoWriteA = fifoInA; - } - lastMode = ASCRegs[0x801]; break; case 0x802: - if(ASCRegs[0x802] == b) { - break; - } // CONTROL // bit 0: analog or PWM output // bit 1: stereo/mono @@ -420,9 +382,10 @@ extern void io_write(uaecptr addr, uae_u32 b, int width_bits) { case 0x803: // FIFO Mode - if(b & 0x80) { + if((b & 0x80) && (underrun == 0)) { if(fifoInA > (fifoWriteA + ascBufferSize)) { - fifoInA = fifoWriteA + ascBufferSize; + fifoInA = 0; + clearFifo = 1; } } break; @@ -441,7 +404,52 @@ extern void io_write(uaecptr addr, uae_u32 b, int width_bits) { case 0x807: // Clock rate 0 = 22257, 2 = 22050, 3 = 44100 - downsample = 0; + { + int newRate, oldRate; + + if(ASCRegs[0x807] == 3) { + oldRate = 44100; + } else { + oldRate = 22050; + } + + if(b == 3) { + newRate = 44100; + } else { + newRate = 22050; + } + + if(newRate != oldRate) { + asc_stop(); + soundRunning = 0; + } + + if(soundRunning == 0) { + int32 depthA = fifoInA - fifoWriteA; + + soundRunning = 1; + downsample = 0; + if(zeros[0] == 0) { + memset(zeros, 128, sizeof(zeros)); + } + + asc_init(newRate); + + ascBufferSize = asc_get_buffer_size(); + + if(depthA >= ascBufferSize) { + asc_process_samples(&fifoA[fifoWriteA % fifoCapacity], + ascBufferSize); + fifoWriteA += ascBufferSize; + underrun = 0; + } else { + underrun = 1; + asc_process_samples(zeros, ascBufferSize); + } + + } + } + ASCRegs[0x807] = b; break; @@ -458,22 +466,23 @@ extern void io_write(uaecptr addr, uae_u32 b, int width_bits) { } void asc_callback() { - if(zeros[0] == 0) { - memset(zeros, 128, sizeof(zeros)); - } if(soundRunning == 0) { asc_process_samples(zeros, ascBufferSize); return; } - fifoOutA += ascBufferSize; + if(clearFifo) { + fifoWriteA = 0; + clearFifo = 0; + } - if( ((fifoInA - fifoWriteA) >= ascBufferSize) && - (ASCRegs[0x801] == 1)) { + if((fifoInA > fifoWriteA) && + ((fifoInA - fifoWriteA) >= ascBufferSize)) { asc_process_samples(&fifoA[fifoWriteA % fifoCapacity], ascBufferSize); fifoWriteA += ascBufferSize; + underrun = 0; } else { - static int ucount = 0; + underrun = 1; asc_process_samples(zeros, ascBufferSize); } } From 9aec39d3cb8c031635f5e2225d72bb7069a02e7a Mon Sep 17 00:00:00 2001 From: Dan Sumorok Date: Tue, 18 Jun 2013 07:02:42 -0400 Subject: [PATCH 21/35] Added extra ifdefs. --- BasiliskII/src/uae_cpu/memory.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/BasiliskII/src/uae_cpu/memory.h b/BasiliskII/src/uae_cpu/memory.h index a2acce2b..6bff799d 100644 --- a/BasiliskII/src/uae_cpu/memory.h +++ b/BasiliskII/src/uae_cpu/memory.h @@ -128,8 +128,11 @@ extern uintptr MEMBaseDiff; #endif #if REAL_ADDRESSING || DIRECT_ADDRESSING + +#ifdef ENABLE_ASC_EMU extern uae_u32 io_read(uaecptr addr, int width_bits); extern void io_write(uaecptr addr, uae_u32 b, int width_bits); +#endif static __inline__ uae_u8 *do_get_real_address(uaecptr addr) { @@ -141,9 +144,11 @@ static __inline__ uae_u32 do_get_virtual_address(uae_u8 *addr) } static __inline__ uae_u32 get_long(uaecptr addr) { +#ifdef ENABLE_ASC_EMU if(addr & 0x40000000) { return io_read(addr, 32); } +#endif uae_u32 * const m = (uae_u32 *)do_get_real_address(addr); return do_get_mem_long(m); From e08090095fb0e3161b5685d1f9445ccde5e49786 Mon Sep 17 00:00:00 2001 From: Dan Sumorok Date: Wed, 19 Jun 2013 19:09:40 -0400 Subject: [PATCH 22/35] Fixed compile error when asc emu is not enabled. --- BasiliskII/src/uae_cpu/memory.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BasiliskII/src/uae_cpu/memory.h b/BasiliskII/src/uae_cpu/memory.h index 6bff799d..d13dd62c 100644 --- a/BasiliskII/src/uae_cpu/memory.h +++ b/BasiliskII/src/uae_cpu/memory.h @@ -166,11 +166,11 @@ static __inline__ uae_u32 get_word(uaecptr addr) static __inline__ uae_u32 get_byte(uaecptr addr) { #ifdef ENABLE_ASC_EMU - uae_u8 * const m = (uae_u8 *)do_get_real_address(addr); if(addr & 0x40000000) { return io_read(addr, 8); } #endif + uae_u8 * const m = (uae_u8 *)do_get_real_address(addr); return do_get_mem_byte(m); } static __inline__ void put_long(uaecptr addr, uae_u32 l) From 3583b00a775282d84e9c15d8178d2fd6855caccd Mon Sep 17 00:00:00 2001 From: Dan Sumorok Date: Fri, 21 Jun 2013 18:59:04 -0400 Subject: [PATCH 23/35] Copy etherhelpertool into application bundle. Ignore -psn_ command line argument so OS X application bundle can be launched. --- BasiliskII/src/Unix/Makefile.in | 3 +++ BasiliskII/src/Unix/main_unix.cpp | 2 ++ 2 files changed, 5 insertions(+) diff --git a/BasiliskII/src/Unix/Makefile.in b/BasiliskII/src/Unix/Makefile.in index 21a0e6da..c52eab26 100644 --- a/BasiliskII/src/Unix/Makefile.in +++ b/BasiliskII/src/Unix/Makefile.in @@ -130,6 +130,9 @@ $(APP)_app: $(APP) $(OSX_DOCS) ../../README ../MacOSX/Info.plist ../MacOSX/$(APP ./cpr.sh ../MacOSX/English.lproj $(APP_APP)/Contents/Resources/ cp -f $(OSX_DOCS) $(APP_APP)/Contents/Resources/ cp -f ../../README $(APP_APP)/Contents/Resources/README.txt +ifeq (@MACOSX_ETHERHELPER@,yes) + cp -f etherhelpertool $(APP_APP)/Contents/Resources +endif $(GUI_APP)_app: $(GUI_APP) ../MacOSX/Info.plist ../MacOSX/$(APP).icns rm -rf $(GUI_APP_APP)/Contents diff --git a/BasiliskII/src/Unix/main_unix.cpp b/BasiliskII/src/Unix/main_unix.cpp index 3505335e..19e744b2 100644 --- a/BasiliskII/src/Unix/main_unix.cpp +++ b/BasiliskII/src/Unix/main_unix.cpp @@ -404,6 +404,8 @@ int main(int argc, char **argv) if (i < argc) x_display_name = strdup(argv[i]); #endif + } else if (strncmp(argv[i], "-psn_", 5) == 0) {// OS X process identifier + argv[i++] = NULL; } else if (strcmp(argv[i], "--gui-connection") == 0) { argv[i++] = NULL; if (i < argc) { From b609065bc47b6279514464c5bcb5ed4c65b6ec13 Mon Sep 17 00:00:00 2001 From: Dan Sumorok Date: Sat, 22 Jun 2013 12:43:41 -0400 Subject: [PATCH 24/35] Always start sound. --- BasiliskII/src/uae_cpu/basilisk_glue.cpp | 27 ++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/BasiliskII/src/uae_cpu/basilisk_glue.cpp b/BasiliskII/src/uae_cpu/basilisk_glue.cpp index 84ed137e..7a333e61 100644 --- a/BasiliskII/src/uae_cpu/basilisk_glue.cpp +++ b/BasiliskII/src/uae_cpu/basilisk_glue.cpp @@ -460,6 +460,33 @@ extern void io_write(uaecptr addr, uae_u32 b, int width_bits) { default: break; } + + if(soundRunning == 0) { + int32 depthA = fifoInA - fifoWriteA; + + soundRunning = 1; + downsample = 0; + + if(zeros[0] == 0) { + memset(zeros, 128, sizeof(zeros)); + } + + asc_init(22050); + + ascBufferSize = asc_get_buffer_size(); + + if(depthA >= ascBufferSize) { + asc_process_samples(&fifoA[fifoWriteA % fifoCapacity], + ascBufferSize); + fifoWriteA += ascBufferSize; + underrun = 0; + } else { + underrun = 1; + asc_process_samples(zeros, ascBufferSize); + } + + } + } } From c4276955baed99d00df2760d5a0e9cb16ab61f0e Mon Sep 17 00:00:00 2001 From: Dan Sumorok Date: Fri, 28 Jun 2013 07:11:52 -0400 Subject: [PATCH 25/35] Fixed some 64-bit releated problems on os x. --- BasiliskII/src/Unix/configure.ac | 16 +- BasiliskII/src/Unix/mach_excServer.c | 749 +++++++++++++++++++++++++++ BasiliskII/src/Unix/mach_excUser.c | 738 ++++++++++++++++++++++++++ BasiliskII/src/Unix/sigsegv.cpp | 6 +- BasiliskII/src/Unix/sigsegv.h | 1 + BasiliskII/src/Unix/sysdeps.h | 6 +- BasiliskII/src/Unix/vm_alloc.cpp | 41 +- 7 files changed, 1550 insertions(+), 7 deletions(-) create mode 100644 BasiliskII/src/Unix/mach_excServer.c create mode 100644 BasiliskII/src/Unix/mach_excUser.c diff --git a/BasiliskII/src/Unix/configure.ac b/BasiliskII/src/Unix/configure.ac index b5be6988..095ee4c5 100644 --- a/BasiliskII/src/Unix/configure.ac +++ b/BasiliskII/src/Unix/configure.ac @@ -30,6 +30,9 @@ AC_ARG_ENABLE(asc-emu, [ --enable-asc-emu enable Apple Sound Chip dnl Mac OS X etherhelper support AC_ARG_ENABLE(macosx-etherhelper, [ --enable-macosx-etherhelper enable Mac OS X Sound [default=no]], [WANT_MACOSX_ETHERHELPER=$enableval], [WANT_MACOSX_ETHERHELPER=no]) +dnl 32-bit build +AC_ARG_ENABLE(32-bit-build, [ --enable-32-bit-build enable a 32-bit build [default=no]], [WANT_32BIT_BUILD=$enableval], [WANT_32BIT_BUILD=no]) + dnl Video options. AC_ARG_ENABLE(xf86-dga, [ --enable-xf86-dga use the XFree86 DGA extension [default=yes]], [WANT_XF86_DGA=$enableval], [WANT_XF86_DGA=yes]) AC_ARG_ENABLE(xf86-vidmode, [ --enable-xf86-vidmode use the XFree86 VidMode extension [default=yes]], [WANT_XF86_VIDMODE=$enableval], [WANT_XF86_VIDMODE=yes]) @@ -125,7 +128,7 @@ case "$target_cpu" in esac dnl Check if we should really be assuming x86_64 even if we detected HAVE_I386 above. -if [[ "x$HAVE_I386" = "xyes" ]]; then +if [[ "x$HAVE_I386" == "xyes" ]]; then AC_TRY_RUN([ int main(void) { #if defined(__x86_64__) @@ -140,6 +143,11 @@ if [[ "x$HAVE_I386" = "xyes" ]]; then ]) fi +if [[ "x$HAVE_X86_64" == "xyes" ] && [ "x$WANT_32BIT_BUILD" == "xyes" ]]; then + HAVE_I386=yes + HAVE_X86_64=no +fi + dnl Checks for programs. AC_PROG_CC AC_PROG_CC_C_O @@ -149,6 +157,12 @@ AC_PROG_MAKE_SET AC_PROG_INSTALL AC_PROG_EGREP +if [[ "x$WANT_32BIT_BUILD" == "xyes" ]]; then +CFLAGS+=" -m32" +CXXFLAGS+=" -m32" +LDFLAGS+=" -m32" +fi + dnl We use mon if possible. MONSRCS= if [[ "x$WANT_MON" = "xyes" ]]; then diff --git a/BasiliskII/src/Unix/mach_excServer.c b/BasiliskII/src/Unix/mach_excServer.c new file mode 100644 index 00000000..c9d59240 --- /dev/null +++ b/BasiliskII/src/Unix/mach_excServer.c @@ -0,0 +1,749 @@ +/* + * IDENTIFICATION: + * stub generated Wed Jun 26 19:11:26 2013 + * with a MiG generated by bootstrap_cmds-85 + * OPTIONS: + */ + +/* Module mach_exc */ + +#define __MIG_check__Request__mach_exc_subsystem__ 1 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#ifndef mig_internal +#define mig_internal static __inline__ +#endif /* mig_internal */ + +#ifndef mig_external +#define mig_external +#endif /* mig_external */ + +#if !defined(__MigTypeCheck) && defined(TypeCheck) +#define __MigTypeCheck TypeCheck /* Legacy setting */ +#endif /* !defined(__MigTypeCheck) */ + +#if !defined(__MigKernelSpecificCode) && defined(_MIG_KERNEL_SPECIFIC_CODE_) +#define __MigKernelSpecificCode _MIG_KERNEL_SPECIFIC_CODE_ /* Legacy setting */ +#endif /* !defined(__MigKernelSpecificCode) */ + +#ifndef LimitCheck +#define LimitCheck 0 +#endif /* LimitCheck */ + +#ifndef min +#define min(a,b) ( ((a) < (b))? (a): (b) ) +#endif /* min */ + +#if !defined(_WALIGN_) +#define _WALIGN_(x) (((x) + 3) & ~3) +#endif /* !defined(_WALIGN_) */ + +#if !defined(_WALIGNSZ_) +#define _WALIGNSZ_(x) _WALIGN_(sizeof(x)) +#endif /* !defined(_WALIGNSZ_) */ + +#ifndef UseStaticTemplates +#define UseStaticTemplates 0 +#endif /* UseStaticTemplates */ + +#ifndef __DeclareRcvRpc +#define __DeclareRcvRpc(_NUM_, _NAME_) +#endif /* __DeclareRcvRpc */ + +#ifndef __BeforeRcvRpc +#define __BeforeRcvRpc(_NUM_, _NAME_) +#endif /* __BeforeRcvRpc */ + +#ifndef __AfterRcvRpc +#define __AfterRcvRpc(_NUM_, _NAME_) +#endif /* __AfterRcvRpc */ + +#ifndef __DeclareRcvSimple +#define __DeclareRcvSimple(_NUM_, _NAME_) +#endif /* __DeclareRcvSimple */ + +#ifndef __BeforeRcvSimple +#define __BeforeRcvSimple(_NUM_, _NAME_) +#endif /* __BeforeRcvSimple */ + +#ifndef __AfterRcvSimple +#define __AfterRcvSimple(_NUM_, _NAME_) +#endif /* __AfterRcvSimple */ + +#define novalue void + +#define msgh_request_port msgh_local_port +#define MACH_MSGH_BITS_REQUEST(bits) MACH_MSGH_BITS_LOCAL(bits) +#define msgh_reply_port msgh_remote_port +#define MACH_MSGH_BITS_REPLY(bits) MACH_MSGH_BITS_REMOTE(bits) + +#define MIG_RETURN_ERROR(X, code) {\ + ((mig_reply_error_t *)X)->RetCode = code;\ + ((mig_reply_error_t *)X)->NDR = NDR_record;\ + return;\ + } + +/* typedefs for all requests */ + +#ifndef __Request__mach_exc_subsystem__defined +#define __Request__mach_exc_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t thread; + mach_msg_port_descriptor_t task; + /* end of the kernel processed data */ + NDR_record_t NDR; + exception_type_t exception; + mach_msg_type_number_t codeCnt; + int64_t code[2]; + } __Request__mach_exception_raise_t; +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + exception_type_t exception; + mach_msg_type_number_t codeCnt; + int64_t code[2]; + int flavor; + mach_msg_type_number_t old_stateCnt; + natural_t old_state[224]; + } __Request__mach_exception_raise_state_t; +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t thread; + mach_msg_port_descriptor_t task; + /* end of the kernel processed data */ + NDR_record_t NDR; + exception_type_t exception; + mach_msg_type_number_t codeCnt; + int64_t code[2]; + int flavor; + mach_msg_type_number_t old_stateCnt; + natural_t old_state[224]; + } __Request__mach_exception_raise_state_identity_t; +#ifdef __MigPackStructs +#pragma pack() +#endif +#endif /* !__Request__mach_exc_subsystem__defined */ + +/* typedefs for all replies */ + +#ifndef __Reply__mach_exc_subsystem__defined +#define __Reply__mach_exc_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__mach_exception_raise_t; +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + int flavor; + mach_msg_type_number_t new_stateCnt; + natural_t new_state[224]; + } __Reply__mach_exception_raise_state_t; +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + int flavor; + mach_msg_type_number_t new_stateCnt; + natural_t new_state[224]; + } __Reply__mach_exception_raise_state_identity_t; +#ifdef __MigPackStructs +#pragma pack() +#endif +#endif /* !__Reply__mach_exc_subsystem__defined */ + + +/* union of all replies */ + +#ifndef __ReplyUnion__catch_mach_exc_subsystem__defined +#define __ReplyUnion__catch_mach_exc_subsystem__defined +union __ReplyUnion__catch_mach_exc_subsystem { + __Reply__mach_exception_raise_t Reply_mach_exception_raise; + __Reply__mach_exception_raise_state_t Reply_mach_exception_raise_state; + __Reply__mach_exception_raise_state_identity_t Reply_mach_exception_raise_state_identity; +}; +#endif /* __RequestUnion__catch_mach_exc_subsystem__defined */ +/* Forward Declarations */ + + +mig_internal novalue _Xmach_exception_raise + (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); + +mig_internal novalue _Xmach_exception_raise_state + (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); + +mig_internal novalue _Xmach_exception_raise_state_identity + (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); + + +#if ( __MigTypeCheck ) +#if __MIG_check__Request__mach_exc_subsystem__ +#if !defined(__MIG_check__Request__mach_exception_raise_t__defined) +#define __MIG_check__Request__mach_exception_raise_t__defined + +mig_internal kern_return_t __MIG_check__Request__mach_exception_raise_t(__attribute__((__unused__)) __Request__mach_exception_raise_t *In0P) +{ + + typedef __Request__mach_exception_raise_t __Request; +#if __MigTypeCheck + unsigned int msgh_size; +#endif /* __MigTypeCheck */ + +#if __MigTypeCheck + msgh_size = In0P->Head.msgh_size; + if (!(In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || + (In0P->msgh_body.msgh_descriptor_count != 2) || + (msgh_size < (mach_msg_size_t)(sizeof(__Request) - 16)) || (msgh_size > (mach_msg_size_t)sizeof(__Request))) + return MIG_BAD_ARGUMENTS; +#endif /* __MigTypeCheck */ + +#if __MigTypeCheck + if (In0P->thread.type != MACH_MSG_PORT_DESCRIPTOR || + In0P->thread.disposition != 17) + return MIG_TYPE_ERROR; +#endif /* __MigTypeCheck */ + +#if __MigTypeCheck + if (In0P->task.type != MACH_MSG_PORT_DESCRIPTOR || + In0P->task.disposition != 17) + return MIG_TYPE_ERROR; +#endif /* __MigTypeCheck */ + +#if defined(__NDR_convert__int_rep__Request__mach_exception_raise_t__codeCnt__defined) + if (In0P->NDR.int_rep != NDR_record.int_rep) + __NDR_convert__int_rep__Request__mach_exception_raise_t__codeCnt(&In0P->codeCnt, In0P->NDR.int_rep); +#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_t__codeCnt__defined */ +#if __MigTypeCheck + if ( In0P->codeCnt > 2 ) + return MIG_BAD_ARGUMENTS; + if (((msgh_size - (mach_msg_size_t)(sizeof(__Request) - 16)) / 8 < In0P->codeCnt) || + (msgh_size != (mach_msg_size_t)(sizeof(__Request) - 16) + (8 * In0P->codeCnt))) + return MIG_BAD_ARGUMENTS; +#endif /* __MigTypeCheck */ + + return MACH_MSG_SUCCESS; +} +#endif /* !defined(__MIG_check__Request__mach_exception_raise_t__defined) */ +#endif /* __MIG_check__Request__mach_exc_subsystem__ */ +#endif /* ( __MigTypeCheck ) */ + + +/* Routine mach_exception_raise */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t catch_mach_exception_raise +( + mach_port_t exception_port, + mach_port_t thread, + mach_port_t task, + exception_type_t exception, + mach_exception_data_t code, + mach_msg_type_number_t codeCnt +); + +/* Routine mach_exception_raise */ +mig_internal novalue _Xmach_exception_raise + (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) +{ + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t thread; + mach_msg_port_descriptor_t task; + /* end of the kernel processed data */ + NDR_record_t NDR; + exception_type_t exception; + mach_msg_type_number_t codeCnt; + int64_t code[2]; + mach_msg_trailer_t trailer; + } Request; +#ifdef __MigPackStructs +#pragma pack() +#endif + typedef __Request__mach_exception_raise_t __Request; + typedef __Reply__mach_exception_raise_t Reply; + + /* + * typedef struct { + * mach_msg_header_t Head; + * NDR_record_t NDR; + * kern_return_t RetCode; + * } mig_reply_error_t; + */ + + Request *In0P = (Request *) InHeadP; + Reply *OutP = (Reply *) OutHeadP; +#ifdef __MIG_check__Request__mach_exception_raise_t__defined + kern_return_t check_result; +#endif /* __MIG_check__Request__mach_exception_raise_t__defined */ + + __DeclareRcvRpc(2405, "mach_exception_raise") + __BeforeRcvRpc(2405, "mach_exception_raise") + +#if defined(__MIG_check__Request__mach_exception_raise_t__defined) + check_result = __MIG_check__Request__mach_exception_raise_t((__Request *)In0P); + if (check_result != MACH_MSG_SUCCESS) + { MIG_RETURN_ERROR(OutP, check_result); } +#endif /* defined(__MIG_check__Request__mach_exception_raise_t__defined) */ + + OutP->RetCode = catch_mach_exception_raise(In0P->Head.msgh_request_port, In0P->thread.name, In0P->task.name, In0P->exception, In0P->code, In0P->codeCnt); + + OutP->NDR = NDR_record; + + + __AfterRcvRpc(2405, "mach_exception_raise") +} + +#if ( __MigTypeCheck ) +#if __MIG_check__Request__mach_exc_subsystem__ +#if !defined(__MIG_check__Request__mach_exception_raise_state_t__defined) +#define __MIG_check__Request__mach_exception_raise_state_t__defined + +mig_internal kern_return_t __MIG_check__Request__mach_exception_raise_state_t(__attribute__((__unused__)) __Request__mach_exception_raise_state_t *In0P, __attribute__((__unused__)) __Request__mach_exception_raise_state_t **In1PP) +{ + + typedef __Request__mach_exception_raise_state_t __Request; + __Request *In1P; +#if __MigTypeCheck + unsigned int msgh_size; +#endif /* __MigTypeCheck */ + unsigned int msgh_size_delta; + +#if __MigTypeCheck + msgh_size = In0P->Head.msgh_size; + if ((In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || + (msgh_size < (mach_msg_size_t)(sizeof(__Request) - 912)) || (msgh_size > (mach_msg_size_t)sizeof(__Request))) + return MIG_BAD_ARGUMENTS; +#endif /* __MigTypeCheck */ + +#if defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_t__codeCnt__defined) + if (In0P->NDR.int_rep != NDR_record.int_rep) + __NDR_convert__int_rep__Request__mach_exception_raise_state_t__codeCnt(&In0P->codeCnt, In0P->NDR.int_rep); +#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_t__codeCnt__defined */ + msgh_size_delta = (8 * In0P->codeCnt); +#if __MigTypeCheck + if ( In0P->codeCnt > 2 ) + return MIG_BAD_ARGUMENTS; + if (((msgh_size - (mach_msg_size_t)(sizeof(__Request) - 912)) / 8 < In0P->codeCnt) || + (msgh_size < (mach_msg_size_t)(sizeof(__Request) - 912) + (8 * In0P->codeCnt))) + return MIG_BAD_ARGUMENTS; + msgh_size -= msgh_size_delta; +#endif /* __MigTypeCheck */ + + *In1PP = In1P = (__Request *) ((pointer_t) In0P + msgh_size_delta - 16); + +#if defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_stateCnt__defined) + if (In0P->NDR.int_rep != NDR_record.int_rep) + __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_stateCnt(&In1P->old_stateCnt, In1P->NDR.int_rep); +#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_stateCnt__defined */ +#if __MigTypeCheck + if ( In1P->old_stateCnt > 224 ) + return MIG_BAD_ARGUMENTS; + if (((msgh_size - (mach_msg_size_t)(sizeof(__Request) - 912)) / 4 < In1P->old_stateCnt) || + (msgh_size != (mach_msg_size_t)(sizeof(__Request) - 912) + (4 * In1P->old_stateCnt))) + return MIG_BAD_ARGUMENTS; +#endif /* __MigTypeCheck */ + + return MACH_MSG_SUCCESS; +} +#endif /* !defined(__MIG_check__Request__mach_exception_raise_state_t__defined) */ +#endif /* __MIG_check__Request__mach_exc_subsystem__ */ +#endif /* ( __MigTypeCheck ) */ + + +/* Routine mach_exception_raise_state */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t catch_mach_exception_raise_state +( + mach_port_t exception_port, + exception_type_t exception, + const mach_exception_data_t code, + mach_msg_type_number_t codeCnt, + int *flavor, + const thread_state_t old_state, + mach_msg_type_number_t old_stateCnt, + thread_state_t new_state, + mach_msg_type_number_t *new_stateCnt +); + +/* Routine mach_exception_raise_state */ +mig_internal novalue _Xmach_exception_raise_state + (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) +{ + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + exception_type_t exception; + mach_msg_type_number_t codeCnt; + int64_t code[2]; + int flavor; + mach_msg_type_number_t old_stateCnt; + natural_t old_state[224]; + mach_msg_trailer_t trailer; + } Request; +#ifdef __MigPackStructs +#pragma pack() +#endif + typedef __Request__mach_exception_raise_state_t __Request; + typedef __Reply__mach_exception_raise_state_t Reply; + + /* + * typedef struct { + * mach_msg_header_t Head; + * NDR_record_t NDR; + * kern_return_t RetCode; + * } mig_reply_error_t; + */ + + Request *In0P = (Request *) InHeadP; + Request *In1P; + Reply *OutP = (Reply *) OutHeadP; +#ifdef __MIG_check__Request__mach_exception_raise_state_t__defined + kern_return_t check_result; +#endif /* __MIG_check__Request__mach_exception_raise_state_t__defined */ + + __DeclareRcvRpc(2406, "mach_exception_raise_state") + __BeforeRcvRpc(2406, "mach_exception_raise_state") + +#if defined(__MIG_check__Request__mach_exception_raise_state_t__defined) + check_result = __MIG_check__Request__mach_exception_raise_state_t((__Request *)In0P, (__Request **)&In1P); + if (check_result != MACH_MSG_SUCCESS) + { MIG_RETURN_ERROR(OutP, check_result); } +#endif /* defined(__MIG_check__Request__mach_exception_raise_state_t__defined) */ + + OutP->new_stateCnt = 224; + + OutP->RetCode = catch_mach_exception_raise_state(In0P->Head.msgh_request_port, In0P->exception, In0P->code, In0P->codeCnt, &In1P->flavor, In1P->old_state, In1P->old_stateCnt, OutP->new_state, &OutP->new_stateCnt); + if (OutP->RetCode != KERN_SUCCESS) { + MIG_RETURN_ERROR(OutP, OutP->RetCode); + } + + OutP->NDR = NDR_record; + + + OutP->flavor = In1P->flavor; + OutP->Head.msgh_size = (mach_msg_size_t)(sizeof(Reply) - 896) + (((4 * OutP->new_stateCnt))); + + __AfterRcvRpc(2406, "mach_exception_raise_state") +} + +#if ( __MigTypeCheck ) +#if __MIG_check__Request__mach_exc_subsystem__ +#if !defined(__MIG_check__Request__mach_exception_raise_state_identity_t__defined) +#define __MIG_check__Request__mach_exception_raise_state_identity_t__defined + +mig_internal kern_return_t __MIG_check__Request__mach_exception_raise_state_identity_t(__attribute__((__unused__)) __Request__mach_exception_raise_state_identity_t *In0P, __attribute__((__unused__)) __Request__mach_exception_raise_state_identity_t **In1PP) +{ + + typedef __Request__mach_exception_raise_state_identity_t __Request; + __Request *In1P; +#if __MigTypeCheck + unsigned int msgh_size; +#endif /* __MigTypeCheck */ + unsigned int msgh_size_delta; + +#if __MigTypeCheck + msgh_size = In0P->Head.msgh_size; + if (!(In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || + (In0P->msgh_body.msgh_descriptor_count != 2) || + (msgh_size < (mach_msg_size_t)(sizeof(__Request) - 912)) || (msgh_size > (mach_msg_size_t)sizeof(__Request))) + return MIG_BAD_ARGUMENTS; +#endif /* __MigTypeCheck */ + +#if __MigTypeCheck + if (In0P->thread.type != MACH_MSG_PORT_DESCRIPTOR || + In0P->thread.disposition != 17) + return MIG_TYPE_ERROR; +#endif /* __MigTypeCheck */ + +#if __MigTypeCheck + if (In0P->task.type != MACH_MSG_PORT_DESCRIPTOR || + In0P->task.disposition != 17) + return MIG_TYPE_ERROR; +#endif /* __MigTypeCheck */ + +#if defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__codeCnt__defined) + if (In0P->NDR.int_rep != NDR_record.int_rep) + __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__codeCnt(&In0P->codeCnt, In0P->NDR.int_rep); +#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__codeCnt__defined */ + msgh_size_delta = (8 * In0P->codeCnt); +#if __MigTypeCheck + if ( In0P->codeCnt > 2 ) + return MIG_BAD_ARGUMENTS; + if (((msgh_size - (mach_msg_size_t)(sizeof(__Request) - 912)) / 8 < In0P->codeCnt) || + (msgh_size < (mach_msg_size_t)(sizeof(__Request) - 912) + (8 * In0P->codeCnt))) + return MIG_BAD_ARGUMENTS; + msgh_size -= msgh_size_delta; +#endif /* __MigTypeCheck */ + + *In1PP = In1P = (__Request *) ((pointer_t) In0P + msgh_size_delta - 16); + +#if defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_stateCnt__defined) + if (In0P->NDR.int_rep != NDR_record.int_rep) + __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_stateCnt(&In1P->old_stateCnt, In1P->NDR.int_rep); +#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_stateCnt__defined */ +#if __MigTypeCheck + if ( In1P->old_stateCnt > 224 ) + return MIG_BAD_ARGUMENTS; + if (((msgh_size - (mach_msg_size_t)(sizeof(__Request) - 912)) / 4 < In1P->old_stateCnt) || + (msgh_size != (mach_msg_size_t)(sizeof(__Request) - 912) + (4 * In1P->old_stateCnt))) + return MIG_BAD_ARGUMENTS; +#endif /* __MigTypeCheck */ + + return MACH_MSG_SUCCESS; +} +#endif /* !defined(__MIG_check__Request__mach_exception_raise_state_identity_t__defined) */ +#endif /* __MIG_check__Request__mach_exc_subsystem__ */ +#endif /* ( __MigTypeCheck ) */ + + +/* Routine mach_exception_raise_state_identity */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t catch_mach_exception_raise_state_identity +( + mach_port_t exception_port, + mach_port_t thread, + mach_port_t task, + exception_type_t exception, + mach_exception_data_t code, + mach_msg_type_number_t codeCnt, + int *flavor, + thread_state_t old_state, + mach_msg_type_number_t old_stateCnt, + thread_state_t new_state, + mach_msg_type_number_t *new_stateCnt +); + +/* Routine mach_exception_raise_state_identity */ +mig_internal novalue _Xmach_exception_raise_state_identity + (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) +{ + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t thread; + mach_msg_port_descriptor_t task; + /* end of the kernel processed data */ + NDR_record_t NDR; + exception_type_t exception; + mach_msg_type_number_t codeCnt; + int64_t code[2]; + int flavor; + mach_msg_type_number_t old_stateCnt; + natural_t old_state[224]; + mach_msg_trailer_t trailer; + } Request; +#ifdef __MigPackStructs +#pragma pack() +#endif + typedef __Request__mach_exception_raise_state_identity_t __Request; + typedef __Reply__mach_exception_raise_state_identity_t Reply; + + /* + * typedef struct { + * mach_msg_header_t Head; + * NDR_record_t NDR; + * kern_return_t RetCode; + * } mig_reply_error_t; + */ + + Request *In0P = (Request *) InHeadP; + Request *In1P; + Reply *OutP = (Reply *) OutHeadP; +#ifdef __MIG_check__Request__mach_exception_raise_state_identity_t__defined + kern_return_t check_result; +#endif /* __MIG_check__Request__mach_exception_raise_state_identity_t__defined */ + + __DeclareRcvRpc(2407, "mach_exception_raise_state_identity") + __BeforeRcvRpc(2407, "mach_exception_raise_state_identity") + +#if defined(__MIG_check__Request__mach_exception_raise_state_identity_t__defined) + check_result = __MIG_check__Request__mach_exception_raise_state_identity_t((__Request *)In0P, (__Request **)&In1P); + if (check_result != MACH_MSG_SUCCESS) + { MIG_RETURN_ERROR(OutP, check_result); } +#endif /* defined(__MIG_check__Request__mach_exception_raise_state_identity_t__defined) */ + + OutP->new_stateCnt = 224; + + OutP->RetCode = catch_mach_exception_raise_state_identity(In0P->Head.msgh_request_port, In0P->thread.name, In0P->task.name, In0P->exception, In0P->code, In0P->codeCnt, &In1P->flavor, In1P->old_state, In1P->old_stateCnt, OutP->new_state, &OutP->new_stateCnt); + if (OutP->RetCode != KERN_SUCCESS) { + MIG_RETURN_ERROR(OutP, OutP->RetCode); + } + + OutP->NDR = NDR_record; + + + OutP->flavor = In1P->flavor; + OutP->Head.msgh_size = (mach_msg_size_t)(sizeof(Reply) - 896) + (((4 * OutP->new_stateCnt))); + + __AfterRcvRpc(2407, "mach_exception_raise_state_identity") +} + + +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +boolean_t mach_exc_server( + mach_msg_header_t *InHeadP, + mach_msg_header_t *OutHeadP); + +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +mig_routine_t mach_exc_server_routine( + mach_msg_header_t *InHeadP); + + +/* Description of this subsystem, for use in direct RPC */ +const struct catch_mach_exc_subsystem { + mig_server_routine_t server; /* Server routine */ + mach_msg_id_t start; /* Min routine number */ + mach_msg_id_t end; /* Max routine number + 1 */ + unsigned int maxsize; /* Max msg size */ + vm_address_t reserved; /* Reserved */ + struct routine_descriptor /*Array of routine descriptors */ + routine[3]; +} catch_mach_exc_subsystem = { + mach_exc_server_routine, + 2405, + 2408, + (mach_msg_size_t)sizeof(union __ReplyUnion__catch_mach_exc_subsystem), + (vm_address_t)0, + { + { (mig_impl_routine_t) 0, + (mig_stub_routine_t) _Xmach_exception_raise, 6, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__mach_exception_raise_t)}, + { (mig_impl_routine_t) 0, + (mig_stub_routine_t) _Xmach_exception_raise_state, 9, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__mach_exception_raise_state_t)}, + { (mig_impl_routine_t) 0, + (mig_stub_routine_t) _Xmach_exception_raise_state_identity, 11, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__mach_exception_raise_state_identity_t)}, + } +}; + +mig_external boolean_t mach_exc_server + (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) +{ + /* + * typedef struct { + * mach_msg_header_t Head; + * NDR_record_t NDR; + * kern_return_t RetCode; + * } mig_reply_error_t; + */ + + register mig_routine_t routine; + + OutHeadP->msgh_bits = MACH_MSGH_BITS(MACH_MSGH_BITS_REPLY(InHeadP->msgh_bits), 0); + OutHeadP->msgh_remote_port = InHeadP->msgh_reply_port; + /* Minimal size: routine() will update it if different */ + OutHeadP->msgh_size = (mach_msg_size_t)sizeof(mig_reply_error_t); + OutHeadP->msgh_local_port = MACH_PORT_NULL; + OutHeadP->msgh_id = InHeadP->msgh_id + 100; + + if ((InHeadP->msgh_id > 2407) || (InHeadP->msgh_id < 2405) || + ((routine = catch_mach_exc_subsystem.routine[InHeadP->msgh_id - 2405].stub_routine) == 0)) { + ((mig_reply_error_t *)OutHeadP)->NDR = NDR_record; + ((mig_reply_error_t *)OutHeadP)->RetCode = MIG_BAD_ID; + return FALSE; + } + (*routine) (InHeadP, OutHeadP); + return TRUE; +} + +mig_external mig_routine_t mach_exc_server_routine + (mach_msg_header_t *InHeadP) +{ + register int msgh_id; + + msgh_id = InHeadP->msgh_id - 2405; + + if ((msgh_id > 2) || (msgh_id < 0)) + return 0; + + return catch_mach_exc_subsystem.routine[msgh_id].stub_routine; +} diff --git a/BasiliskII/src/Unix/mach_excUser.c b/BasiliskII/src/Unix/mach_excUser.c new file mode 100644 index 00000000..0070bd04 --- /dev/null +++ b/BasiliskII/src/Unix/mach_excUser.c @@ -0,0 +1,738 @@ +/* + * IDENTIFICATION: + * stub generated Wed Jun 26 19:11:26 2013 + * with a MiG generated by bootstrap_cmds-85 + * OPTIONS: + */ +#define __MIG_check__Reply__mach_exc_subsystem__ 1 + +#include "mach_exc.h" + + +#ifndef mig_internal +#define mig_internal static __inline__ +#endif /* mig_internal */ + +#ifndef mig_external +#define mig_external +#endif /* mig_external */ + +#if !defined(__MigTypeCheck) && defined(TypeCheck) +#define __MigTypeCheck TypeCheck /* Legacy setting */ +#endif /* !defined(__MigTypeCheck) */ + +#if !defined(__MigKernelSpecificCode) && defined(_MIG_KERNEL_SPECIFIC_CODE_) +#define __MigKernelSpecificCode _MIG_KERNEL_SPECIFIC_CODE_ /* Legacy setting */ +#endif /* !defined(__MigKernelSpecificCode) */ + +#ifndef LimitCheck +#define LimitCheck 0 +#endif /* LimitCheck */ + +#ifndef min +#define min(a,b) ( ((a) < (b))? (a): (b) ) +#endif /* min */ + +#if !defined(_WALIGN_) +#define _WALIGN_(x) (((x) + 3) & ~3) +#endif /* !defined(_WALIGN_) */ + +#if !defined(_WALIGNSZ_) +#define _WALIGNSZ_(x) _WALIGN_(sizeof(x)) +#endif /* !defined(_WALIGNSZ_) */ + +#ifndef UseStaticTemplates +#define UseStaticTemplates 0 +#endif /* UseStaticTemplates */ + +#ifndef __MachMsgErrorWithTimeout +#define __MachMsgErrorWithTimeout(_R_) { \ + switch (_R_) { \ + case MACH_SEND_INVALID_DATA: \ + case MACH_SEND_INVALID_DEST: \ + case MACH_SEND_INVALID_HEADER: \ + mig_put_reply_port(InP->Head.msgh_reply_port); \ + break; \ + case MACH_SEND_TIMED_OUT: \ + case MACH_RCV_TIMED_OUT: \ + default: \ + mig_dealloc_reply_port(InP->Head.msgh_reply_port); \ + } \ +} +#endif /* __MachMsgErrorWithTimeout */ + +#ifndef __MachMsgErrorWithoutTimeout +#define __MachMsgErrorWithoutTimeout(_R_) { \ + switch (_R_) { \ + case MACH_SEND_INVALID_DATA: \ + case MACH_SEND_INVALID_DEST: \ + case MACH_SEND_INVALID_HEADER: \ + mig_put_reply_port(InP->Head.msgh_reply_port); \ + break; \ + default: \ + mig_dealloc_reply_port(InP->Head.msgh_reply_port); \ + } \ +} +#endif /* __MachMsgErrorWithoutTimeout */ + +#ifndef __DeclareSendRpc +#define __DeclareSendRpc(_NUM_, _NAME_) +#endif /* __DeclareSendRpc */ + +#ifndef __BeforeSendRpc +#define __BeforeSendRpc(_NUM_, _NAME_) +#endif /* __BeforeSendRpc */ + +#ifndef __AfterSendRpc +#define __AfterSendRpc(_NUM_, _NAME_) +#endif /* __AfterSendRpc */ + +#ifndef __DeclareSendSimple +#define __DeclareSendSimple(_NUM_, _NAME_) +#endif /* __DeclareSendSimple */ + +#ifndef __BeforeSendSimple +#define __BeforeSendSimple(_NUM_, _NAME_) +#endif /* __BeforeSendSimple */ + +#ifndef __AfterSendSimple +#define __AfterSendSimple(_NUM_, _NAME_) +#endif /* __AfterSendSimple */ + +#define msgh_request_port msgh_remote_port +#define msgh_reply_port msgh_local_port + + + +#if ( __MigTypeCheck ) +#if __MIG_check__Reply__mach_exc_subsystem__ +#if !defined(__MIG_check__Reply__mach_exception_raise_t__defined) +#define __MIG_check__Reply__mach_exception_raise_t__defined + +mig_internal kern_return_t __MIG_check__Reply__mach_exception_raise_t(__Reply__mach_exception_raise_t *Out0P) +{ + + typedef __Reply__mach_exception_raise_t __Reply; + if (Out0P->Head.msgh_id != 2505) { + if (Out0P->Head.msgh_id == MACH_NOTIFY_SEND_ONCE) + { return MIG_SERVER_DIED; } + else + { return MIG_REPLY_MISMATCH; } + } + +#if __MigTypeCheck + if ((Out0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || + (Out0P->Head.msgh_size != (mach_msg_size_t)sizeof(__Reply))) + { return MIG_TYPE_ERROR ; } +#endif /* __MigTypeCheck */ + + { + return Out0P->RetCode; + } +} +#endif /* !defined(__MIG_check__Reply__mach_exception_raise_t__defined) */ +#endif /* __MIG_check__Reply__mach_exc_subsystem__ */ +#endif /* ( __MigTypeCheck ) */ + + +/* Routine mach_exception_raise */ +mig_external kern_return_t mach_exception_raise +( + mach_port_t exception_port, + mach_port_t thread, + mach_port_t task, + exception_type_t exception, + mach_exception_data_t code, + mach_msg_type_number_t codeCnt +) +{ + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t thread; + mach_msg_port_descriptor_t task; + /* end of the kernel processed data */ + NDR_record_t NDR; + exception_type_t exception; + mach_msg_type_number_t codeCnt; + int64_t code[2]; + } Request; +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_msg_trailer_t trailer; + } Reply; +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply; +#ifdef __MigPackStructs +#pragma pack() +#endif + /* + * typedef struct { + * mach_msg_header_t Head; + * NDR_record_t NDR; + * kern_return_t RetCode; + * } mig_reply_error_t; + */ + + union { + Request In; + Reply Out; + } Mess; + + Request *InP = &Mess.In; + Reply *Out0P = &Mess.Out; + + mach_msg_return_t msg_result; + unsigned int msgh_size; + +#ifdef __MIG_check__Reply__mach_exception_raise_t__defined + kern_return_t check_result; +#endif /* __MIG_check__Reply__mach_exception_raise_t__defined */ + + __DeclareSendRpc(2405, "mach_exception_raise") + +#if UseStaticTemplates + const static mach_msg_port_descriptor_t threadTemplate = { + /* name = */ MACH_PORT_NULL, + /* pad1 = */ 0, + /* pad2 = */ 0, + /* disp = */ 19, + /* type = */ MACH_MSG_PORT_DESCRIPTOR, + }; +#endif /* UseStaticTemplates */ + +#if UseStaticTemplates + const static mach_msg_port_descriptor_t taskTemplate = { + /* name = */ MACH_PORT_NULL, + /* pad1 = */ 0, + /* pad2 = */ 0, + /* disp = */ 19, + /* type = */ MACH_MSG_PORT_DESCRIPTOR, + }; +#endif /* UseStaticTemplates */ + + InP->msgh_body.msgh_descriptor_count = 2; +#if UseStaticTemplates + InP->thread = threadTemplate; + InP->thread.name = thread; +#else /* UseStaticTemplates */ + InP->thread.name = thread; + InP->thread.disposition = 19; + InP->thread.type = MACH_MSG_PORT_DESCRIPTOR; +#endif /* UseStaticTemplates */ + +#if UseStaticTemplates + InP->task = taskTemplate; + InP->task.name = task; +#else /* UseStaticTemplates */ + InP->task.name = task; + InP->task.disposition = 19; + InP->task.type = MACH_MSG_PORT_DESCRIPTOR; +#endif /* UseStaticTemplates */ + + InP->NDR = NDR_record; + + InP->exception = exception; + + if (codeCnt > 2) { + { return MIG_ARRAY_TOO_LARGE; } + } + (void)memcpy((char *) InP->code, (const char *) code, 8 * codeCnt); + + InP->codeCnt = codeCnt; + + msgh_size = (mach_msg_size_t)(sizeof(Request) - 16) + ((8 * codeCnt)); + InP->Head.msgh_bits = MACH_MSGH_BITS_COMPLEX| + MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE); + /* msgh_size passed as argument */ + InP->Head.msgh_request_port = exception_port; + InP->Head.msgh_reply_port = mig_get_reply_port(); + InP->Head.msgh_id = 2405; + + __BeforeSendRpc(2405, "mach_exception_raise") + msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE, msgh_size, (mach_msg_size_t)sizeof(Reply), InP->Head.msgh_reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); + __AfterSendRpc(2405, "mach_exception_raise") + if (msg_result != MACH_MSG_SUCCESS) { + __MachMsgErrorWithoutTimeout(msg_result); + { return msg_result; } + } + + +#if defined(__MIG_check__Reply__mach_exception_raise_t__defined) + check_result = __MIG_check__Reply__mach_exception_raise_t((__Reply__mach_exception_raise_t *)Out0P); + if (check_result != MACH_MSG_SUCCESS) + { return check_result; } +#endif /* defined(__MIG_check__Reply__mach_exception_raise_t__defined) */ + + return KERN_SUCCESS; +} + +#if ( __MigTypeCheck ) +#if __MIG_check__Reply__mach_exc_subsystem__ +#if !defined(__MIG_check__Reply__mach_exception_raise_state_t__defined) +#define __MIG_check__Reply__mach_exception_raise_state_t__defined + +mig_internal kern_return_t __MIG_check__Reply__mach_exception_raise_state_t(__Reply__mach_exception_raise_state_t *Out0P) +{ + + typedef __Reply__mach_exception_raise_state_t __Reply; +#if __MigTypeCheck + unsigned int msgh_size; +#endif /* __MigTypeCheck */ + + if (Out0P->Head.msgh_id != 2506) { + if (Out0P->Head.msgh_id == MACH_NOTIFY_SEND_ONCE) + { return MIG_SERVER_DIED; } + else + { return MIG_REPLY_MISMATCH; } + } + +#if __MigTypeCheck + msgh_size = Out0P->Head.msgh_size; + + if ((Out0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || + ((msgh_size > (mach_msg_size_t)sizeof(__Reply) || msgh_size < (mach_msg_size_t)(sizeof(__Reply) - 896)) && + (msgh_size != (mach_msg_size_t)sizeof(mig_reply_error_t) || + Out0P->RetCode == KERN_SUCCESS))) + { return MIG_TYPE_ERROR ; } +#endif /* __MigTypeCheck */ + + if (Out0P->RetCode != KERN_SUCCESS) { + return ((mig_reply_error_t *)Out0P)->RetCode; + } + +#if __MigTypeCheck + if ( Out0P->new_stateCnt > 224 ) + return MIG_TYPE_ERROR; + if (((msgh_size - (mach_msg_size_t)(sizeof(__Reply) - 896)) / 4< Out0P->new_stateCnt) || + (msgh_size != (mach_msg_size_t)(sizeof(__Reply) - 896) + Out0P->new_stateCnt * 4)) + { return MIG_TYPE_ERROR ; } +#endif /* __MigTypeCheck */ + + return MACH_MSG_SUCCESS; +} +#endif /* !defined(__MIG_check__Reply__mach_exception_raise_state_t__defined) */ +#endif /* __MIG_check__Reply__mach_exc_subsystem__ */ +#endif /* ( __MigTypeCheck ) */ + + +/* Routine mach_exception_raise_state */ +mig_external kern_return_t mach_exception_raise_state +( + mach_port_t exception_port, + exception_type_t exception, + const mach_exception_data_t code, + mach_msg_type_number_t codeCnt, + int *flavor, + const thread_state_t old_state, + mach_msg_type_number_t old_stateCnt, + thread_state_t new_state, + mach_msg_type_number_t *new_stateCnt +) +{ + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + exception_type_t exception; + mach_msg_type_number_t codeCnt; + int64_t code[2]; + int flavor; + mach_msg_type_number_t old_stateCnt; + natural_t old_state[224]; + } Request; +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + int flavor; + mach_msg_type_number_t new_stateCnt; + natural_t new_state[224]; + mach_msg_trailer_t trailer; + } Reply; +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + int flavor; + mach_msg_type_number_t new_stateCnt; + natural_t new_state[224]; + } __Reply; +#ifdef __MigPackStructs +#pragma pack() +#endif + /* + * typedef struct { + * mach_msg_header_t Head; + * NDR_record_t NDR; + * kern_return_t RetCode; + * } mig_reply_error_t; + */ + + union { + Request In; + Reply Out; + } Mess; + + Request *InP = &Mess.In; + Reply *Out0P = &Mess.Out; + + mach_msg_return_t msg_result; + unsigned int msgh_size; + unsigned int msgh_size_delta; + + +#ifdef __MIG_check__Reply__mach_exception_raise_state_t__defined + kern_return_t check_result; +#endif /* __MIG_check__Reply__mach_exception_raise_state_t__defined */ + + __DeclareSendRpc(2406, "mach_exception_raise_state") + + InP->NDR = NDR_record; + + InP->exception = exception; + + if (codeCnt > 2) { + { return MIG_ARRAY_TOO_LARGE; } + } + (void)memcpy((char *) InP->code, (const char *) code, 8 * codeCnt); + + InP->codeCnt = codeCnt; + + msgh_size_delta = (8 * codeCnt); + msgh_size = (mach_msg_size_t)(sizeof(Request) - 912) + msgh_size_delta; + InP = (Request *) ((pointer_t) InP + msgh_size_delta - 16); + + InP->flavor = *flavor; + + if (old_stateCnt > 224) { + { return MIG_ARRAY_TOO_LARGE; } + } + (void)memcpy((char *) InP->old_state, (const char *) old_state, 4 * old_stateCnt); + + InP->old_stateCnt = old_stateCnt; + + msgh_size += (4 * old_stateCnt); + InP = &Mess.In; + InP->Head.msgh_bits = + MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE); + /* msgh_size passed as argument */ + InP->Head.msgh_request_port = exception_port; + InP->Head.msgh_reply_port = mig_get_reply_port(); + InP->Head.msgh_id = 2406; + + __BeforeSendRpc(2406, "mach_exception_raise_state") + msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE, msgh_size, (mach_msg_size_t)sizeof(Reply), InP->Head.msgh_reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); + __AfterSendRpc(2406, "mach_exception_raise_state") + if (msg_result != MACH_MSG_SUCCESS) { + __MachMsgErrorWithoutTimeout(msg_result); + { return msg_result; } + } + + +#if defined(__MIG_check__Reply__mach_exception_raise_state_t__defined) + check_result = __MIG_check__Reply__mach_exception_raise_state_t((__Reply__mach_exception_raise_state_t *)Out0P); + if (check_result != MACH_MSG_SUCCESS) + { return check_result; } +#endif /* defined(__MIG_check__Reply__mach_exception_raise_state_t__defined) */ + + *flavor = Out0P->flavor; + + if (Out0P->new_stateCnt > 224) { + (void)memcpy((char *) new_state, (const char *) Out0P->new_state, 4 * 224); + *new_stateCnt = Out0P->new_stateCnt; + { return MIG_ARRAY_TOO_LARGE; } + } + (void)memcpy((char *) new_state, (const char *) Out0P->new_state, 4 * Out0P->new_stateCnt); + + *new_stateCnt = Out0P->new_stateCnt; + + return KERN_SUCCESS; +} + +#if ( __MigTypeCheck ) +#if __MIG_check__Reply__mach_exc_subsystem__ +#if !defined(__MIG_check__Reply__mach_exception_raise_state_identity_t__defined) +#define __MIG_check__Reply__mach_exception_raise_state_identity_t__defined + +mig_internal kern_return_t __MIG_check__Reply__mach_exception_raise_state_identity_t(__Reply__mach_exception_raise_state_identity_t *Out0P) +{ + + typedef __Reply__mach_exception_raise_state_identity_t __Reply; +#if __MigTypeCheck + unsigned int msgh_size; +#endif /* __MigTypeCheck */ + + if (Out0P->Head.msgh_id != 2507) { + if (Out0P->Head.msgh_id == MACH_NOTIFY_SEND_ONCE) + { return MIG_SERVER_DIED; } + else + { return MIG_REPLY_MISMATCH; } + } + +#if __MigTypeCheck + msgh_size = Out0P->Head.msgh_size; + + if ((Out0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || + ((msgh_size > (mach_msg_size_t)sizeof(__Reply) || msgh_size < (mach_msg_size_t)(sizeof(__Reply) - 896)) && + (msgh_size != (mach_msg_size_t)sizeof(mig_reply_error_t) || + Out0P->RetCode == KERN_SUCCESS))) + { return MIG_TYPE_ERROR ; } +#endif /* __MigTypeCheck */ + + if (Out0P->RetCode != KERN_SUCCESS) { + return ((mig_reply_error_t *)Out0P)->RetCode; + } + +#if __MigTypeCheck + if ( Out0P->new_stateCnt > 224 ) + return MIG_TYPE_ERROR; + if (((msgh_size - (mach_msg_size_t)(sizeof(__Reply) - 896)) / 4< Out0P->new_stateCnt) || + (msgh_size != (mach_msg_size_t)(sizeof(__Reply) - 896) + Out0P->new_stateCnt * 4)) + { return MIG_TYPE_ERROR ; } +#endif /* __MigTypeCheck */ + + return MACH_MSG_SUCCESS; +} +#endif /* !defined(__MIG_check__Reply__mach_exception_raise_state_identity_t__defined) */ +#endif /* __MIG_check__Reply__mach_exc_subsystem__ */ +#endif /* ( __MigTypeCheck ) */ + + +/* Routine mach_exception_raise_state_identity */ +mig_external kern_return_t mach_exception_raise_state_identity +( + mach_port_t exception_port, + mach_port_t thread, + mach_port_t task, + exception_type_t exception, + mach_exception_data_t code, + mach_msg_type_number_t codeCnt, + int *flavor, + thread_state_t old_state, + mach_msg_type_number_t old_stateCnt, + thread_state_t new_state, + mach_msg_type_number_t *new_stateCnt +) +{ + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t thread; + mach_msg_port_descriptor_t task; + /* end of the kernel processed data */ + NDR_record_t NDR; + exception_type_t exception; + mach_msg_type_number_t codeCnt; + int64_t code[2]; + int flavor; + mach_msg_type_number_t old_stateCnt; + natural_t old_state[224]; + } Request; +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + int flavor; + mach_msg_type_number_t new_stateCnt; + natural_t new_state[224]; + mach_msg_trailer_t trailer; + } Reply; +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + int flavor; + mach_msg_type_number_t new_stateCnt; + natural_t new_state[224]; + } __Reply; +#ifdef __MigPackStructs +#pragma pack() +#endif + /* + * typedef struct { + * mach_msg_header_t Head; + * NDR_record_t NDR; + * kern_return_t RetCode; + * } mig_reply_error_t; + */ + + union { + Request In; + Reply Out; + } Mess; + + Request *InP = &Mess.In; + Reply *Out0P = &Mess.Out; + + mach_msg_return_t msg_result; + unsigned int msgh_size; + unsigned int msgh_size_delta; + + +#ifdef __MIG_check__Reply__mach_exception_raise_state_identity_t__defined + kern_return_t check_result; +#endif /* __MIG_check__Reply__mach_exception_raise_state_identity_t__defined */ + + __DeclareSendRpc(2407, "mach_exception_raise_state_identity") + +#if UseStaticTemplates + const static mach_msg_port_descriptor_t threadTemplate = { + /* name = */ MACH_PORT_NULL, + /* pad1 = */ 0, + /* pad2 = */ 0, + /* disp = */ 19, + /* type = */ MACH_MSG_PORT_DESCRIPTOR, + }; +#endif /* UseStaticTemplates */ + +#if UseStaticTemplates + const static mach_msg_port_descriptor_t taskTemplate = { + /* name = */ MACH_PORT_NULL, + /* pad1 = */ 0, + /* pad2 = */ 0, + /* disp = */ 19, + /* type = */ MACH_MSG_PORT_DESCRIPTOR, + }; +#endif /* UseStaticTemplates */ + + InP->msgh_body.msgh_descriptor_count = 2; +#if UseStaticTemplates + InP->thread = threadTemplate; + InP->thread.name = thread; +#else /* UseStaticTemplates */ + InP->thread.name = thread; + InP->thread.disposition = 19; + InP->thread.type = MACH_MSG_PORT_DESCRIPTOR; +#endif /* UseStaticTemplates */ + +#if UseStaticTemplates + InP->task = taskTemplate; + InP->task.name = task; +#else /* UseStaticTemplates */ + InP->task.name = task; + InP->task.disposition = 19; + InP->task.type = MACH_MSG_PORT_DESCRIPTOR; +#endif /* UseStaticTemplates */ + + InP->NDR = NDR_record; + + InP->exception = exception; + + if (codeCnt > 2) { + { return MIG_ARRAY_TOO_LARGE; } + } + (void)memcpy((char *) InP->code, (const char *) code, 8 * codeCnt); + + InP->codeCnt = codeCnt; + + msgh_size_delta = (8 * codeCnt); + msgh_size = (mach_msg_size_t)(sizeof(Request) - 912) + msgh_size_delta; + InP = (Request *) ((pointer_t) InP + msgh_size_delta - 16); + + InP->flavor = *flavor; + + if (old_stateCnt > 224) { + { return MIG_ARRAY_TOO_LARGE; } + } + (void)memcpy((char *) InP->old_state, (const char *) old_state, 4 * old_stateCnt); + + InP->old_stateCnt = old_stateCnt; + + msgh_size += (4 * old_stateCnt); + InP = &Mess.In; + InP->Head.msgh_bits = MACH_MSGH_BITS_COMPLEX| + MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE); + /* msgh_size passed as argument */ + InP->Head.msgh_request_port = exception_port; + InP->Head.msgh_reply_port = mig_get_reply_port(); + InP->Head.msgh_id = 2407; + + __BeforeSendRpc(2407, "mach_exception_raise_state_identity") + msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE, msgh_size, (mach_msg_size_t)sizeof(Reply), InP->Head.msgh_reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); + __AfterSendRpc(2407, "mach_exception_raise_state_identity") + if (msg_result != MACH_MSG_SUCCESS) { + __MachMsgErrorWithoutTimeout(msg_result); + { return msg_result; } + } + + +#if defined(__MIG_check__Reply__mach_exception_raise_state_identity_t__defined) + check_result = __MIG_check__Reply__mach_exception_raise_state_identity_t((__Reply__mach_exception_raise_state_identity_t *)Out0P); + if (check_result != MACH_MSG_SUCCESS) + { return check_result; } +#endif /* defined(__MIG_check__Reply__mach_exception_raise_state_identity_t__defined) */ + + *flavor = Out0P->flavor; + + if (Out0P->new_stateCnt > 224) { + (void)memcpy((char *) new_state, (const char *) Out0P->new_state, 4 * 224); + *new_stateCnt = Out0P->new_stateCnt; + { return MIG_ARRAY_TOO_LARGE; } + } + (void)memcpy((char *) new_state, (const char *) Out0P->new_state, 4 * Out0P->new_stateCnt); + + *new_stateCnt = Out0P->new_stateCnt; + + return KERN_SUCCESS; +} diff --git a/BasiliskII/src/Unix/sigsegv.cpp b/BasiliskII/src/Unix/sigsegv.cpp index 951b4c66..347e0f4f 100644 --- a/BasiliskII/src/Unix/sigsegv.cpp +++ b/BasiliskII/src/Unix/sigsegv.cpp @@ -614,8 +614,10 @@ extern "C" { #include #include -#ifndef HAVE_MACH64_VM - +#ifdef __LP64__ +#include "mach_excServer.c" +#include "mach_excUser.c" +#else // Undefine this to prevent a preprocessor warning when compiling on a // 32-bit machine with Mac OS X 10.5. #undef MACH_EXCEPTION_CODES diff --git a/BasiliskII/src/Unix/sigsegv.h b/BasiliskII/src/Unix/sigsegv.h index 4f97668d..8fdada9e 100644 --- a/BasiliskII/src/Unix/sigsegv.h +++ b/BasiliskII/src/Unix/sigsegv.h @@ -110,6 +110,7 @@ extern "C" { #else #define SIGSEGV_FAULT_ADDRESS_FAST code[1] #endif + #define SIGSEGV_FAULT_INSTRUCTION_FAST SIGSEGV_INVALID_ADDRESS #define SIGSEGV_FAULT_HANDLER_ARGLIST mach_port_t thread, mach_exception_data_t code #define SIGSEGV_FAULT_HANDLER_ARGS thread, code diff --git a/BasiliskII/src/Unix/sysdeps.h b/BasiliskII/src/Unix/sysdeps.h index f53293a7..c1b2b9f4 100644 --- a/BasiliskII/src/Unix/sysdeps.h +++ b/BasiliskII/src/Unix/sysdeps.h @@ -25,7 +25,10 @@ #error "Your compiler is not ANSI. Get a real one." #endif +#ifdef HAVE_CONFIG_H #include "config.h" +#endif + #include "user_strings_unix.h" #ifndef STDC_HEADERS @@ -210,7 +213,8 @@ typedef struct timeval tm_time_t; #define uae_u32 uint32 #define uae_s64 int64 #define uae_u64 uint64 -typedef uae_u32 uaecptr; +//typedef uae_u32 uaecptr; +typedef size_t uaecptr; /* Alignment restrictions */ #if defined(__i386__) || defined(__powerpc__) || defined(__m68k__) || defined(__x86_64__) diff --git a/BasiliskII/src/Unix/vm_alloc.cpp b/BasiliskII/src/Unix/vm_alloc.cpp index 11c3fddc..57dd8169 100644 --- a/BasiliskII/src/Unix/vm_alloc.cpp +++ b/BasiliskII/src/Unix/vm_alloc.cpp @@ -38,6 +38,7 @@ #include #include #include "vm_alloc.h" +#include "sysdeps.h" #if defined(__APPLE__) && defined(__MACH__) #include @@ -237,8 +238,36 @@ void * vm_acquire(size_t size, int options) #endif #if defined(HAVE_MACH_VM) - // vm_allocate() returns a zero-filled memory region - kern_return_t ret_code = vm_allocate(mach_task_self(), (vm_address_t *)&addr, size, TRUE); + static size_t addrOffset = 0x80000000; + kern_return_t ret_code; + static uint8 *base32 = NULL; + + if(options & VM_MAP_32BIT) { +#ifdef __LP64__ + if((size < 0x08000000) && (addrOffset < 0x100000000ULL) && (base32 != NULL)) { + addr = (void *)(base32 + addrOffset); + ret_code = vm_allocate(mach_task_self(), (vm_address_t *)&addr, + size, VM_FLAGS_FIXED); + addrOffset += 0x08000000; + } else { + ret_code = vm_allocate(mach_task_self(), (vm_address_t *)&addr, + size, VM_FLAGS_ANYWHERE); + if((ret_code == KERN_SUCCESS) && (base32 == NULL)) { + base32 = (uint8_t *)addr; + } + + } +#else + // vm_allocate() returns a zero-filled memory region + ret_code = vm_allocate(mach_task_self(), (vm_address_t *)&addr, + size, VM_FLAGS_ANYWHERE); +#endif + } else { + // vm_allocate() returns a zero-filled memory region + ret_code = vm_allocate(mach_task_self(), (vm_address_t *)&addr, + size, VM_FLAGS_ANYWHERE); + } + if (ret_code != KERN_SUCCESS) { errno = vm_error(ret_code); return VM_MAP_FAILED; @@ -296,7 +325,13 @@ int vm_acquire_fixed(void * addr, size_t size, int options) #if defined(HAVE_MACH_VM) // vm_allocate() returns a zero-filled memory region - kern_return_t ret_code = vm_allocate(mach_task_self(), (vm_address_t *)&addr, size, 0); +#ifdef __LP64__ + kern_return_t ret_code = vm_allocate(mach_task_self(), (vm_address_t *)&addr, size, + VM_FLAGS_FIXED | VM_FLAGS_OVERWRITE); +#else + kern_return_t ret_code = vm_allocate(mach_task_self(), (vm_address_t *)&addr, size, + VM_FLAGS_FIXED); +#endif if (ret_code != KERN_SUCCESS) { errno = vm_error(ret_code); return -1; From 1c99d52b91853244f0dfbb27aff9e5282b1916ff Mon Sep 17 00:00:00 2001 From: Dan Sumorok Date: Fri, 28 Jun 2013 07:12:38 -0400 Subject: [PATCH 26/35] Added missing file. --- BasiliskII/src/Unix/mach_exc.h | 258 +++++++++++++++++++++++++++++++++ 1 file changed, 258 insertions(+) create mode 100644 BasiliskII/src/Unix/mach_exc.h diff --git a/BasiliskII/src/Unix/mach_exc.h b/BasiliskII/src/Unix/mach_exc.h new file mode 100644 index 00000000..716325f7 --- /dev/null +++ b/BasiliskII/src/Unix/mach_exc.h @@ -0,0 +1,258 @@ +#ifndef _mach_exc_user_ +#define _mach_exc_user_ + +/* Module mach_exc */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef AUTOTEST +#ifndef FUNCTION_PTR_T +#define FUNCTION_PTR_T +typedef void (*function_ptr_t)(mach_port_t, char *, mach_msg_type_number_t); +typedef struct { + char *name; + function_ptr_t function; +} function_table_entry; +typedef function_table_entry *function_table_t; +#endif /* FUNCTION_PTR_T */ +#endif /* AUTOTEST */ + +#ifndef mach_exc_MSG_COUNT +#define mach_exc_MSG_COUNT 3 +#endif /* mach_exc_MSG_COUNT */ + +#include +#include +#include +#include + +#ifdef __BeforeMigUserHeader +__BeforeMigUserHeader +#endif /* __BeforeMigUserHeader */ + +#include +__BEGIN_DECLS + + +/* Routine mach_exception_raise */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_exception_raise +( + mach_port_t exception_port, + mach_port_t thread, + mach_port_t task, + exception_type_t exception, + mach_exception_data_t code, + mach_msg_type_number_t codeCnt +); + +/* Routine mach_exception_raise_state */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_exception_raise_state +( + mach_port_t exception_port, + exception_type_t exception, + const mach_exception_data_t code, + mach_msg_type_number_t codeCnt, + int *flavor, + const thread_state_t old_state, + mach_msg_type_number_t old_stateCnt, + thread_state_t new_state, + mach_msg_type_number_t *new_stateCnt +); + +/* Routine mach_exception_raise_state_identity */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_exception_raise_state_identity +( + mach_port_t exception_port, + mach_port_t thread, + mach_port_t task, + exception_type_t exception, + mach_exception_data_t code, + mach_msg_type_number_t codeCnt, + int *flavor, + thread_state_t old_state, + mach_msg_type_number_t old_stateCnt, + thread_state_t new_state, + mach_msg_type_number_t *new_stateCnt +); + +__END_DECLS + +/********************** Caution **************************/ +/* The following data types should be used to calculate */ +/* maximum message sizes only. The actual message may be */ +/* smaller, and the position of the arguments within the */ +/* message layout may vary from what is presented here. */ +/* For example, if any of the arguments are variable- */ +/* sized, and less than the maximum is sent, the data */ +/* will be packed tight in the actual message to reduce */ +/* the presence of holes. */ +/********************** Caution **************************/ + +/* typedefs for all requests */ + +#ifndef __Request__mach_exc_subsystem__defined +#define __Request__mach_exc_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t thread; + mach_msg_port_descriptor_t task; + /* end of the kernel processed data */ + NDR_record_t NDR; + exception_type_t exception; + mach_msg_type_number_t codeCnt; + int64_t code[2]; + } __Request__mach_exception_raise_t; +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + exception_type_t exception; + mach_msg_type_number_t codeCnt; + int64_t code[2]; + int flavor; + mach_msg_type_number_t old_stateCnt; + natural_t old_state[224]; + } __Request__mach_exception_raise_state_t; +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t thread; + mach_msg_port_descriptor_t task; + /* end of the kernel processed data */ + NDR_record_t NDR; + exception_type_t exception; + mach_msg_type_number_t codeCnt; + int64_t code[2]; + int flavor; + mach_msg_type_number_t old_stateCnt; + natural_t old_state[224]; + } __Request__mach_exception_raise_state_identity_t; +#ifdef __MigPackStructs +#pragma pack() +#endif +#endif /* !__Request__mach_exc_subsystem__defined */ + +/* union of all requests */ + +#ifndef __RequestUnion__mach_exc_subsystem__defined +#define __RequestUnion__mach_exc_subsystem__defined +union __RequestUnion__mach_exc_subsystem { + __Request__mach_exception_raise_t Request_mach_exception_raise; + __Request__mach_exception_raise_state_t Request_mach_exception_raise_state; + __Request__mach_exception_raise_state_identity_t Request_mach_exception_raise_state_identity; +}; +#endif /* !__RequestUnion__mach_exc_subsystem__defined */ +/* typedefs for all replies */ + +#ifndef __Reply__mach_exc_subsystem__defined +#define __Reply__mach_exc_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__mach_exception_raise_t; +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + int flavor; + mach_msg_type_number_t new_stateCnt; + natural_t new_state[224]; + } __Reply__mach_exception_raise_state_t; +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + int flavor; + mach_msg_type_number_t new_stateCnt; + natural_t new_state[224]; + } __Reply__mach_exception_raise_state_identity_t; +#ifdef __MigPackStructs +#pragma pack() +#endif +#endif /* !__Reply__mach_exc_subsystem__defined */ + +/* union of all replies */ + +#ifndef __ReplyUnion__mach_exc_subsystem__defined +#define __ReplyUnion__mach_exc_subsystem__defined +union __ReplyUnion__mach_exc_subsystem { + __Reply__mach_exception_raise_t Reply_mach_exception_raise; + __Reply__mach_exception_raise_state_t Reply_mach_exception_raise_state; + __Reply__mach_exception_raise_state_identity_t Reply_mach_exception_raise_state_identity; +}; +#endif /* !__RequestUnion__mach_exc_subsystem__defined */ + +#ifndef subsystem_to_name_map_mach_exc +#define subsystem_to_name_map_mach_exc \ + { "mach_exception_raise", 2405 },\ + { "mach_exception_raise_state", 2406 },\ + { "mach_exception_raise_state_identity", 2407 } +#endif + +#ifdef __AfterMigUserHeader +__AfterMigUserHeader +#endif /* __AfterMigUserHeader */ + +#endif /* _mach_exc_user_ */ From c01bd008dba6dadfda37e1964a1cc3359ed4ff50 Mon Sep 17 00:00:00 2001 From: Dan Sumorok Date: Sat, 6 Jul 2013 17:09:37 -0400 Subject: [PATCH 27/35] Hack to load code below 4GB, and to make 32-bit vm allocates work. --- BasiliskII/src/Unix/configure.ac | 26 +++++++++++++++++++------- BasiliskII/src/Unix/sigsegv.h | 2 +- BasiliskII/src/Unix/vm_alloc.cpp | 32 ++++++++++++++++++-------------- 3 files changed, 38 insertions(+), 22 deletions(-) diff --git a/BasiliskII/src/Unix/configure.ac b/BasiliskII/src/Unix/configure.ac index 095ee4c5..e5c3cd27 100644 --- a/BasiliskII/src/Unix/configure.ac +++ b/BasiliskII/src/Unix/configure.ac @@ -772,18 +772,20 @@ if [[ "x$WANT_SDL" = "xyes" ]]; then EXTRASYSSRCS="$EXTRASYSSRCS ../SDL/SDLMain.m" fi fi + +AC_MSG_CHECKING([whether __LP64__ is defined]) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#if !defined(__LP64__) + # error __LP64__ not defined + #endif + ]])], + [AC_MSG_RESULT(yes); LP64_DEFINED=yes], + [AC_MSG_RESULT(no)]) + if [[ "x$WANT_SDL_VIDEO" = "xyes" ]]; then AC_DEFINE(USE_SDL_VIDEO, 1, [Define to enable SDL video graphics support]) VIDEOSRCS="../SDL/video_sdl.cpp" KEYCODES="../SDL/keycodes" if [[ "x$ac_cv_framework_Carbon" = "xyes" ]]; then - AC_MSG_CHECKING([whether __LP64__ is defined]) - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#if !defined(__LP64__) - # error __LP64__ not defined - #endif - ]])], - [AC_MSG_RESULT(yes); LP64_DEFINED=yes], - [AC_MSG_RESULT(no)]) if [[ "x$LP64_DEFINED" = "xyes" ]]; then EXTRASYSSRCS="$EXTRASYSSRCS ../MacOSX/clip_macosx64.mm ../pict.c" else @@ -1774,6 +1776,16 @@ if [[ "x$HAVE_IPA" = "xyes" ]]; then LDFLAGS="$LDFLAGS -O3 -OPT:Olimit=0 -IPA" fi +if [[ "x$LP64_DEFINED" = "xyes" ] && [ "x$have_mach_vm" = "xyes" ]]; then +LIBS+=" -Wl,-pagezero_size,0x20000000" +LIBS+=" -Wl,-segaddr,__TEXT,0x60000000" +LIBS+=" -Wl,-segaddr,__PAGEZERO,0x20000000" +fi + +if [[ ${OS_TYPE} = darwin ]]; then +LIBS+=" -Wl,-no_pie" +fi + dnl Generate Makefile. AC_SUBST(DEFINES) AC_SUBST(SYSSRCS) diff --git a/BasiliskII/src/Unix/sigsegv.h b/BasiliskII/src/Unix/sigsegv.h index 8fdada9e..26a9e5eb 100644 --- a/BasiliskII/src/Unix/sigsegv.h +++ b/BasiliskII/src/Unix/sigsegv.h @@ -106,7 +106,7 @@ extern "C" { #define SIGSEGV_REGISTER_FILE ((SIGSEGV_REGISTER_TYPE *)&SIP->thr_state.MACH_FIELD_NAME(rax)) /* RAX is the first GPR we consider */ #endif #ifdef __x86_64__ -#define SIGSEGV_FAULT_ADDRESS_FAST (((uint64_t)code[1])|0x100000000) +#define SIGSEGV_FAULT_ADDRESS_FAST code[1] #else #define SIGSEGV_FAULT_ADDRESS_FAST code[1] #endif diff --git a/BasiliskII/src/Unix/vm_alloc.cpp b/BasiliskII/src/Unix/vm_alloc.cpp index 57dd8169..4d3569c0 100644 --- a/BasiliskII/src/Unix/vm_alloc.cpp +++ b/BasiliskII/src/Unix/vm_alloc.cpp @@ -221,6 +221,9 @@ void vm_exit(void) /* Allocate zero-filled memory of SIZE bytes. The mapping is private and default protection bits are read / write. The return value is the actual mapping address chosen or VM_MAP_FAILED for errors. */ +#if defined(HAVE_MACH_VM) +static void *last_alloc = NULL; +#endif void * vm_acquire(size_t size, int options) { @@ -238,24 +241,18 @@ void * vm_acquire(size_t size, int options) #endif #if defined(HAVE_MACH_VM) - static size_t addrOffset = 0x80000000; + static size_t addrOffset = 0x20000000; kern_return_t ret_code; static uint8 *base32 = NULL; if(options & VM_MAP_32BIT) { #ifdef __LP64__ - if((size < 0x08000000) && (addrOffset < 0x100000000ULL) && (base32 != NULL)) { - addr = (void *)(base32 + addrOffset); - ret_code = vm_allocate(mach_task_self(), (vm_address_t *)&addr, - size, VM_FLAGS_FIXED); - addrOffset += 0x08000000; - } else { - ret_code = vm_allocate(mach_task_self(), (vm_address_t *)&addr, - size, VM_FLAGS_ANYWHERE); - if((ret_code == KERN_SUCCESS) && (base32 == NULL)) { - base32 = (uint8_t *)addr; - } - + addr = base32 + addrOffset; + ret_code = vm_allocate(mach_task_self(), (vm_address_t *)&addr, + size, VM_FLAGS_FIXED | VM_FLAGS_OVERWRITE); + if(ret_code == KERN_SUCCESS) { + last_alloc = addr; + base32 = base32 + size; } #else // vm_allocate() returns a zero-filled memory region @@ -325,9 +322,16 @@ int vm_acquire_fixed(void * addr, size_t size, int options) #if defined(HAVE_MACH_VM) // vm_allocate() returns a zero-filled memory region + #ifdef __LP64__ - kern_return_t ret_code = vm_allocate(mach_task_self(), (vm_address_t *)&addr, size, + if(addr != last_alloc) { + return -1; + } + + kern_return_t ret_code = vm_allocate(mach_task_self(), + (vm_address_t *)&addr, size, VM_FLAGS_FIXED | VM_FLAGS_OVERWRITE); + #else kern_return_t ret_code = vm_allocate(mach_task_self(), (vm_address_t *)&addr, size, VM_FLAGS_FIXED); From 3c6788fd268920a8a7aca79f493d099c781cb302 Mon Sep 17 00:00:00 2001 From: Dan Sumorok Date: Mon, 8 Jul 2013 06:51:24 -0400 Subject: [PATCH 28/35] Tweak of the linker commands. --- BasiliskII/src/Unix/configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BasiliskII/src/Unix/configure.ac b/BasiliskII/src/Unix/configure.ac index e5c3cd27..96f48f32 100644 --- a/BasiliskII/src/Unix/configure.ac +++ b/BasiliskII/src/Unix/configure.ac @@ -1778,7 +1778,7 @@ fi if [[ "x$LP64_DEFINED" = "xyes" ] && [ "x$have_mach_vm" = "xyes" ]]; then LIBS+=" -Wl,-pagezero_size,0x20000000" -LIBS+=" -Wl,-segaddr,__TEXT,0x60000000" +#LIBS+=" -Wl,-segaddr,__TEXT,0x60000000" LIBS+=" -Wl,-segaddr,__PAGEZERO,0x20000000" fi From 4f162dc6e376970b557b05885f31367c4a7b4ee8 Mon Sep 17 00:00:00 2001 From: Dan Sumorok Date: Sat, 29 Nov 2014 19:25:31 -0500 Subject: [PATCH 29/35] Minor build fixes. --- BasiliskII/src/Unix/Makefile.in | 2 +- BasiliskII/src/uae_cpu/fpu/fpu_ieee.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/BasiliskII/src/Unix/Makefile.in b/BasiliskII/src/Unix/Makefile.in index c52eab26..d1c8bb70 100644 --- a/BasiliskII/src/Unix/Makefile.in +++ b/BasiliskII/src/Unix/Makefile.in @@ -146,7 +146,7 @@ $(GUI_APP)_app: $(GUI_APP) ../MacOSX/Info.plist ../MacOSX/$(APP).icns ./cpr.sh ../MacOSX/$(APP).icns $(GUI_APP_APP)/Contents/Resources/$(GUI_APP).icns etherhelpertool: ../MacOSX/etherhelpertool.c - $(CC) $(CPPFLAGS) $(DEFS) $(CFLAGS) $(LIBS) $< -o $@ + $(CC) $(CPPFLAGS) $(DEFS) $(CFLAGS) $(LIBS) $(LDFLAGS) $< -o $@ modules: cd Linux/NetDriver; make diff --git a/BasiliskII/src/uae_cpu/fpu/fpu_ieee.cpp b/BasiliskII/src/uae_cpu/fpu/fpu_ieee.cpp index f5a1aeb4..002618b4 100644 --- a/BasiliskII/src/uae_cpu/fpu/fpu_ieee.cpp +++ b/BasiliskII/src/uae_cpu/fpu/fpu_ieee.cpp @@ -726,7 +726,7 @@ PRIVATE inline int FFPU get_fp_value (uae_u32 opcode, uae_u16 extra, fpu_registe } /* Convert the FP value to integer according to the current m68k rounding mode */ -PRIVATE inline uae_s32 FFPU toint(fpu_register const & src) +PRIVATE uae_s32 FFPU toint(fpu_register const & src) { fpu_register result; switch (get_fpcr() & 0x30) { From b1270264a1e1fa5aac4e969ec5c5f42b5b979d31 Mon Sep 17 00:00:00 2001 From: Dan Sumorok Date: Sat, 29 Nov 2014 19:45:47 -0500 Subject: [PATCH 30/35] Changed page zero size to 4 kB to fix problem on OS X 10.10. --- BasiliskII/src/Unix/configure.ac | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/BasiliskII/src/Unix/configure.ac b/BasiliskII/src/Unix/configure.ac index 96f48f32..7dc71bce 100644 --- a/BasiliskII/src/Unix/configure.ac +++ b/BasiliskII/src/Unix/configure.ac @@ -1777,9 +1777,7 @@ if [[ "x$HAVE_IPA" = "xyes" ]]; then fi if [[ "x$LP64_DEFINED" = "xyes" ] && [ "x$have_mach_vm" = "xyes" ]]; then -LIBS+=" -Wl,-pagezero_size,0x20000000" -#LIBS+=" -Wl,-segaddr,__TEXT,0x60000000" -LIBS+=" -Wl,-segaddr,__PAGEZERO,0x20000000" +LIBS+=" -Wl,-pagezero_size,0x1000" fi if [[ ${OS_TYPE} = darwin ]]; then From b8fb05fbd0361bd404df560327c29c7fabb30677 Mon Sep 17 00:00:00 2001 From: Dan Sumorok Date: Wed, 31 Dec 2014 09:36:17 -0500 Subject: [PATCH 31/35] Minor build fixes Removed OS X -no_pie linker flag Fixed copy/paste error in ether helper help string Added missing distclean targets. --- BasiliskII/src/Unix/Makefile.in | 2 +- BasiliskII/src/Unix/configure.ac | 6 +----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/BasiliskII/src/Unix/Makefile.in b/BasiliskII/src/Unix/Makefile.in index cc82326d..54ae7fbd 100644 --- a/BasiliskII/src/Unix/Makefile.in +++ b/BasiliskII/src/Unix/Makefile.in @@ -184,7 +184,7 @@ distclean: clean rm -rf $(OBJ_DIR) rm -rf autom4te.cache rm -f Makefile - rm -f config.cache config.log config.status config.h + rm -f config.cache config.log config.status config.h config.h.in configure rm -f Darwin/lowmem Darwin/pagezero depend dep: diff --git a/BasiliskII/src/Unix/configure.ac b/BasiliskII/src/Unix/configure.ac index 62dd5adc..ad073b7e 100644 --- a/BasiliskII/src/Unix/configure.ac +++ b/BasiliskII/src/Unix/configure.ac @@ -28,7 +28,7 @@ dnl Apple Sound Chip Emulation AC_ARG_ENABLE(asc-emu, [ --enable-asc-emu enable Apple Sound Chip emulation [default=no]], [WANT_ASC_EMU=$enableval], [WANT_ASC_EMU=no]) dnl Mac OS X etherhelper support -AC_ARG_ENABLE(macosx-etherhelper, [ --enable-macosx-etherhelper enable Mac OS X Sound [default=no]], [WANT_MACOSX_ETHERHELPER=$enableval], [WANT_MACOSX_ETHERHELPER=no]) +AC_ARG_ENABLE(macosx-etherhelper, [ --enable-macosx-etherhelper enable Mac OS X Ethernet Helper Program [default=no]], [WANT_MACOSX_ETHERHELPER=$enableval], [WANT_MACOSX_ETHERHELPER=no]) dnl 32-bit build AC_ARG_ENABLE(32-bit-build, [ --enable-32-bit-build enable a 32-bit build [default=no]], [WANT_32BIT_BUILD=$enableval], [WANT_32BIT_BUILD=no]) @@ -1783,10 +1783,6 @@ if [[ "x$LP64_DEFINED" = "xyes" ] && [ "x$have_mach_vm" = "xyes" ]]; then LIBS+=" -Wl,-pagezero_size,0x1000" fi -if [[ ${OS_TYPE} = darwin ]]; then -LIBS+=" -Wl,-no_pie" -fi - dnl Generate Makefile. AC_SUBST(DEFINES) AC_SUBST(SYSSRCS) From fcc15980869f4e00619af9f967bf4e097b10e189 Mon Sep 17 00:00:00 2001 From: Dan Sumorok Date: Wed, 14 Jan 2015 19:23:26 -0500 Subject: [PATCH 32/35] Add no_pie linker flag for Mac OS X 10.6 and later. --- BasiliskII/src/Unix/configure.ac | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/BasiliskII/src/Unix/configure.ac b/BasiliskII/src/Unix/configure.ac index ad073b7e..bd7fbd8e 100644 --- a/BasiliskII/src/Unix/configure.ac +++ b/BasiliskII/src/Unix/configure.ac @@ -1779,6 +1779,13 @@ if [[ "x$HAVE_IPA" = "xyes" ]]; then LDFLAGS="$LDFLAGS -O3 -OPT:Olimit=0 -IPA" fi +if [[ `uname -s` = Darwin ]]; then + MACOSVERSION=`sw_vers -productVersion | cut -d. -f2` + if [[ ${MACOSVERSION} -gt 6 ]]; then + LIBS+=" -Wl,-no_pie" + fi +fi + if [[ "x$LP64_DEFINED" = "xyes" ] && [ "x$have_mach_vm" = "xyes" ]]; then LIBS+=" -Wl,-pagezero_size,0x1000" fi From 7710322fd3899d7a02c112fc9a7dc7e46c73a2ba Mon Sep 17 00:00:00 2001 From: Dan Sumorok Date: Tue, 15 Mar 2016 20:03:59 -0400 Subject: [PATCH 33/35] Linux etherhelper support. --- BasiliskII/src/Unix/Linux/etherhelpertool.c | 624 ++++++++++++++++++++ BasiliskII/src/Unix/Linux/runtool.c | 58 ++ BasiliskII/src/Unix/ether_unix.cpp | 28 +- 3 files changed, 709 insertions(+), 1 deletion(-) create mode 100644 BasiliskII/src/Unix/Linux/etherhelpertool.c create mode 100644 BasiliskII/src/Unix/Linux/runtool.c diff --git a/BasiliskII/src/Unix/Linux/etherhelpertool.c b/BasiliskII/src/Unix/Linux/etherhelpertool.c new file mode 100644 index 00000000..980643bc --- /dev/null +++ b/BasiliskII/src/Unix/Linux/etherhelpertool.c @@ -0,0 +1,624 @@ +/* + * etherhelpertool.c - Reads and writes raw ethernet packets usng bpf + * interface. + * + * Copyright (C) 2010, Daniel Sumorok + * + * Basilisk II (C) 1997-2008 Christian Bauer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#define STR_MAX 256 +#define MAX_ARGV 10 + +static int remove_bridge = 0; +static const char *exec_name = "etherhelpertool"; + +static int main_loop(int sd, int use_bpf); +static int open_tap(char *ifname); +static int run_cmd(const char *cmd); +static void handler(int signum); +static int install_signal_handlers(void); +static void do_exit(void); +static int open_bpf(char *ifname); + +int main(int argc, char **argv) +{ + char *if_name; + int ret = 255; + int sd = -1; + int tapNum; + int use_bpf; + + if (argc != 2) { + return 255; + } + + if_name = argv[1]; + + do { + if (strncmp(if_name, "tap", 3) == 0) { + sd = open_tap(if_name); + use_bpf = 0; + } else { + sd = open_bpf(if_name); + use_bpf = 1; + } + + if (sd < 0) { + fprintf(stderr, "%s: open device failed.\n", + exec_name); + ret = 253; + break; + } + + if (install_signal_handlers() != 0) { + fprintf(stderr, + "%s: failed to install signal handers.\n", + exec_name); + ret = 252; + break; + } + + ret = main_loop(sd, use_bpf); + close(sd); + } while (0); + + do_exit(); + + return ret; +} + +static int main_loop(int sd, int use_bpf) +{ + fd_set readSet; + char *outgoing, *incoming; + unsigned short *out_len; + unsigned short *in_len; + int in_index, out_index; + u_int blen = 0; + int ret; + int fret = 0; + int pkt_len; + int frame_len; + int pad; + char c = 0; + + blen = 4096; + + incoming = malloc(blen); + if (incoming == NULL) { + fprintf(stderr, + "%s: malloc() failed.\n", + exec_name); + return -2; + } + + outgoing = malloc(blen); + if (outgoing == NULL) { + free(outgoing); + fprintf(stderr, + "%s: malloc() failed.\n", + exec_name); + return -3; + } + + in_index = 0; + out_index = 0; + + out_len = (unsigned short *)outgoing; + + /* Let our parent know we are ready for business. */ + if(write(0, &c, 1) != 1) { + fprintf(stderr, "%s: Failed to notify main application: %s\n", + __func__, strerror(errno)); + } + + while (1) { + int i; + FD_ZERO(&readSet); + FD_SET(0, &readSet); + FD_SET(sd, &readSet); + + ret = select(sd + 1, &readSet, NULL, NULL, NULL); + if (ret < 0) { + fprintf(stderr, + "%s: select() failed.\n", + exec_name); + fret = -4; + break; + } + + if (FD_ISSET(0, &readSet)) { + if (out_index < 2) { + ret = read(0, outgoing + out_index, 2-out_index); + } else { + ret = read(0, outgoing + out_index, *out_len - out_index + 2); + } + + if (ret < 1) { + if(ret < 0) { + fprintf(stderr, + "%s: read() failed.\n", + exec_name); + } + fret = -5; + break; + } + + out_index += ret; + + if (out_index > 1) { + if ((*out_len + 2) > blen) { + fret = -6; + break; + } + + if (out_index == (*out_len + 2)) { + ret = write(sd, out_len + 1, *out_len); + if (ret != *out_len) { + fprintf(stderr, + "%s: write() failed.\n", + exec_name); + fret = -7; + break; + } + + out_index = 0; + } + } + + } + + if (FD_ISSET(sd, &readSet)) { + in_len = (unsigned short *)incoming; + + pkt_len = read(sd, in_len + 1, blen-2); + if (pkt_len < 14) { + fprintf(stderr, + "%s: read() returned %d.\n", + exec_name, pkt_len); + fret = -8; + break; + } + *in_len = pkt_len; + + if (write(0, in_len, pkt_len + 2) < (pkt_len + 2)) { + fprintf(stderr, + "%s: write() failed\n", + exec_name); + fret = -10; + break; + } + } + } + + free(incoming); + free(outgoing); + + return fret; +} + + +static int open_tap(char *ifname) +{ + char str[STR_MAX] = {0}; + char ifstr[STR_MAX] = {0}; + char *interface; + char *address = NULL; + char *netmask = NULL; + char *bridge = NULL; + char *bridged_if = NULL; + int sd; + + snprintf(ifstr, STR_MAX, "%s", ifname); + interface = strtok(ifstr, "/"); + bridge = strtok(NULL, "/"); + if (bridge != NULL) { + bridged_if = strtok(NULL, "/"); + } + interface = strtok(ifstr, ":"); + + address = strtok(NULL, ":"); + + if (address != NULL) { + netmask = strtok(NULL, ":"); + } + + snprintf(str, STR_MAX, "/dev/%s", interface); + + sd = open(str, O_RDWR); + if (sd < 0) { + fprintf(stderr, "%s: Failed to open %s\n", + exec_name, interface); + return -1; + } + + if (address == NULL) { + snprintf(str, STR_MAX, "/sbin/ifconfig %s up", interface); + } else if (netmask == NULL) { + snprintf(str, STR_MAX, "/sbin/ifconfig %s %s", + interface, address); + } else { + snprintf(str, STR_MAX, "/sbin/ifconfig %s %s netmask %s", + interface, address, netmask); + } + + if (run_cmd(str) != 0) { + fprintf(stderr, "%s: Failed to configure %s\n", + exec_name, interface); + close(sd); + return -1; + } + + if (bridge != NULL) { + /* Check to see if bridge is alread up */ + snprintf(str, STR_MAX, "/sbin/ifconfig %s", bridge); + if (run_cmd(str) == 0) { + /* bridge is already up */ + if (bridged_if != NULL) { + fprintf(stderr, "%s: Warning: %s already exists, so %s was not added.\n", + exec_name, bridge, bridged_if); + } + } else { + snprintf(str, STR_MAX, "/sbin/ifconfig %s create", bridge); + if (run_cmd(str) != 0) { + fprintf(stderr, "%s: Failed to create %s\n", + exec_name, bridge); + close(sd); + return -1; + } + remove_bridge = 1; + + snprintf(str, STR_MAX, "/sbin/ifconfig %s up", bridge); + if (run_cmd(str) != 0) { + fprintf(stderr, "%s: Failed to open %s\n", + exec_name, bridge); + close(sd); + return -1; + } + + if (bridged_if != NULL) { + snprintf(str, STR_MAX, "/sbin/ifconfig %s addm %s", + bridge, bridged_if); + if (run_cmd(str) != 0) { + fprintf(stderr, "%s: Failed to add %s to %s\n", + exec_name, bridged_if, bridge); + close(sd); + return -1; + } + } + + snprintf(str, STR_MAX, "/sbin/ifconfig %s addm %s", + bridge, interface); + if (run_cmd(str) != 0) { + fprintf(stderr, "%s: Failed to add %s to %s\n", + exec_name, interface, bridge); + close(sd); + return -1; + } + } + } + + return sd; +} + +static int run_cmd(const char *cmd) { + char cmd_buffer[STR_MAX] = {0}; + char *argv[MAX_ARGV + 1] = {0}; + int i; + pid_t pid, waitpid; + int status = 0; + + /* Collect arguments */ + strncpy(cmd_buffer, cmd, STR_MAX-1); + + argv[0] = strtok(cmd_buffer, " "); + for (i=1; i +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define STR_MAX 1024 +#define MAX_ARGV 10 + +FILE * run_tool(const char *if_name, const char *tool_name) { + char cmd_buffer[STR_MAX] = {0}; + char * const argv[3] = {NULL, NULL, NULL}; + int i; + pid_t pid, waitpid; + int status = 0; + int fds[2]; + char c; + + if(socketpair(PF_LOCAL, SOCK_STREAM, 0, fds) != 0) { + fprintf(stderr, "%s: socketpair() failed: %s\n", + __func__, strerror(errno)); + return NULL; + } + + ((const char**)argv)[0] = tool_name; + ((const char**)argv)[1] = if_name; + + /* Run sub process */ + pid = fork(); + if (pid == 0) { + /* Child process */ + fclose(stdout); + fclose(stdin); + dup2(fds[0], 0); + close(fds[1]); + close(fds[0]); + + if (execve(tool_name, argv, NULL) < 0) { + perror("execve"); + exit(1); + } + } + + + close(fds[0]); + + if(read(fds[1], &c, 1) < 1) { + close(fds[1]); + return NULL; + } + + return fdopen(fds[1], "rw"); +} diff --git a/BasiliskII/src/Unix/ether_unix.cpp b/BasiliskII/src/Unix/ether_unix.cpp index 3c588dd1..26f90a7b 100644 --- a/BasiliskII/src/Unix/ether_unix.cpp +++ b/BasiliskII/src/Unix/ether_unix.cpp @@ -43,7 +43,16 @@ #include #ifdef ENABLE_MACOSX_ETHERHELPER + +#ifdef __APPLE__ #include +#endif + +#ifdef __linux__ +#include +#endif + +#include #include #endif @@ -1140,8 +1149,13 @@ static int get_mac_address(const char* dev, unsigned char *addr) { struct ifaddrs *ifaddrs, *next; int ret = -1; +#ifdef __APPLE__ struct sockaddr_dl *sa; +#endif +#ifdef __linux__ + struct sockaddr_ll *sa; +#endif if (getifaddrs(&ifaddrs) != 0) { perror("getifaddrs"); return -1; @@ -1150,6 +1164,7 @@ static int get_mac_address(const char* dev, unsigned char *addr) next = ifaddrs; while (next != NULL) { switch (next->ifa_addr->sa_family) { +#ifdef __APPLE__ case AF_LINK: if (!strcmp(dev, next->ifa_name)) { sa = (struct sockaddr_dl *)next->ifa_addr; @@ -1157,6 +1172,17 @@ static int get_mac_address(const char* dev, unsigned char *addr) ret = 0; } break; +#endif + +#ifdef __linux__ + case AF_PACKET: + if (!strcmp(dev, next->ifa_name)) { + sa = (struct sockaddr_ll *)next->ifa_addr; + memcpy(addr, sa->sll_addr, 6); + ret = 0; + } + break; +#endif default: break; } @@ -1240,7 +1266,7 @@ static int read_packet() } index += ret; - + if (index > 1) { if (*pkt_len > (sizeof(packet_buffer) + 2)) { fprintf(stderr, "%s: pkt_len (%d) too large.\n", __func__, *pkt_len); From 1d84d4051889896e4fd1a7d147fa5ebe8b7c61dd Mon Sep 17 00:00:00 2001 From: Dan Sumorok Date: Wed, 16 Mar 2016 18:40:33 -0400 Subject: [PATCH 34/35] Linux etherhelper build updates. --- BasiliskII/src/Unix/Makefile.in | 4 +++- BasiliskII/src/Unix/configure.ac | 14 ++++++++++++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/BasiliskII/src/Unix/Makefile.in b/BasiliskII/src/Unix/Makefile.in index 54ae7fbd..6caa0768 100644 --- a/BasiliskII/src/Unix/Makefile.in +++ b/BasiliskII/src/Unix/Makefile.in @@ -43,6 +43,8 @@ GUI_LIBS = @GUI_LIBS@ GUI_SRCS = ../prefs.cpp prefs_unix.cpp prefs_editor_gtk.cpp ../prefs_items.cpp \ ../user_strings.cpp user_strings_unix.cpp xpram_unix.cpp sys_unix.cpp rpc_unix.cpp +ETHERHELPERDIR = @ETHERHELPERDIR@ + ## Files SRCS = ../main.cpp ../prefs.cpp ../prefs_items.cpp \ sys_unix.cpp ../rom_patches.cpp ../slot_rom.cpp ../rsrc_patches.cpp \ @@ -145,7 +147,7 @@ $(GUI_APP)_app: $(GUI_APP) ../MacOSX/Info.plist ../MacOSX/$(APP).icns mkdir -p $(GUI_APP_APP)/Contents/Resources ./cpr.sh ../MacOSX/$(APP).icns $(GUI_APP_APP)/Contents/Resources/$(GUI_APP).icns -etherhelpertool: ../MacOSX/etherhelpertool.c +etherhelpertool: $(ETHERHELPERDIR)/etherhelpertool.c $(CC) $(CPPFLAGS) $(DEFS) $(CFLAGS) $(LIBS) $(LDFLAGS) $< -o $@ modules: diff --git a/BasiliskII/src/Unix/configure.ac b/BasiliskII/src/Unix/configure.ac index bd7fbd8e..9389f5a1 100644 --- a/BasiliskII/src/Unix/configure.ac +++ b/BasiliskII/src/Unix/configure.ac @@ -756,8 +756,18 @@ if [[ "x$WANT_MACOSX_SOUND" = "xyes" ]]; then fi if [[ "x$WANT_MACOSX_ETHERHELPER" = "xyes" ]]; then - EXTRASYSSRCS="$EXTRASYSSRCS ../MacOSX/runtool.c" - LIBS="$LIBS -framework Security" + if [[ ${OS_TYPE} = "linux" ]]; then + EXTRASYSSRCS="$EXTRASYSSRCS ../Linux/runtool.c" + ETHERHELPERDIR=../Linux + fi + + if [[ ${OS_TYPE} = "darwin" ]]; then + EXTRASYSSRCS="$EXTRASYSSRCS ../MacOSX/runtool.c" + LIBS="$LIBS -framework Security" + ETHERHELPERDIR=../MacOSX + fi + + AC_SUBST(ETHERHELPERDIR, ${ETHERHELPERDIR}) AC_DEFINE(ENABLE_MACOSX_ETHERHELPER, 1, [Define if supporting "etherhelper" network device.]) fi From dee3f7e1c50437d3da5da2f06a7649e9f51157e4 Mon Sep 17 00:00:00 2001 From: Dan Sumorok Date: Sat, 19 Mar 2016 19:17:48 -0400 Subject: [PATCH 35/35] Added tap/bridge support to ether helper. --- BasiliskII/src/Unix/Linux/etherhelpertool.c | 246 +++++--------------- 1 file changed, 64 insertions(+), 182 deletions(-) diff --git a/BasiliskII/src/Unix/Linux/etherhelpertool.c b/BasiliskII/src/Unix/Linux/etherhelpertool.c index 980643bc..5d6117bc 100644 --- a/BasiliskII/src/Unix/Linux/etherhelpertool.c +++ b/BasiliskII/src/Unix/Linux/etherhelpertool.c @@ -50,6 +50,7 @@ #define MAX_ARGV 10 static int remove_bridge = 0; +static char bridge_name[STR_MAX]; static const char *exec_name = "etherhelpertool"; static int main_loop(int sd, int use_bpf); @@ -193,13 +194,24 @@ static int main_loop(int sd, int use_bpf) } if (out_index == (*out_len + 2)) { - ret = write(sd, out_len + 1, *out_len); - if (ret != *out_len) { - fprintf(stderr, - "%s: write() failed.\n", - exec_name); - fret = -7; - break; + if(use_bpf) { + ret = write(sd, out_len + 1, *out_len); + if (ret != *out_len) { + fprintf(stderr, + "%s: write() failed.\n", + exec_name); + fret = -7; + break; + } + } else { + ret = write(sd, out_len + 1, *out_len); + if (ret != *out_len) { + fprintf(stderr, + "%s: write() failed.\n", + exec_name); + fret = -7; + break; + } } out_index = 0; @@ -213,7 +225,7 @@ static int main_loop(int sd, int use_bpf) pkt_len = read(sd, in_len + 1, blen-2); if (pkt_len < 14) { - fprintf(stderr, + fprintf(stderr, "%s: read() returned %d.\n", exec_name, pkt_len); fret = -8; @@ -222,7 +234,7 @@ static int main_loop(int sd, int use_bpf) *in_len = pkt_len; if (write(0, in_len, pkt_len + 2) < (pkt_len + 2)) { - fprintf(stderr, + fprintf(stderr, "%s: write() failed\n", exec_name); fret = -10; @@ -248,6 +260,7 @@ static int open_tap(char *ifname) char *bridge = NULL; char *bridged_if = NULL; int sd; + struct ifreq ifr = {0}; snprintf(ifstr, STR_MAX, "%s", ifname); interface = strtok(ifstr, "/"); @@ -263,24 +276,33 @@ static int open_tap(char *ifname) netmask = strtok(NULL, ":"); } - snprintf(str, STR_MAX, "/dev/%s", interface); - - sd = open(str, O_RDWR); + sd = open("/dev/net/tun", O_RDWR); if (sd < 0) { fprintf(stderr, "%s: Failed to open %s\n", exec_name, interface); return -1; } - if (address == NULL) { - snprintf(str, STR_MAX, "/sbin/ifconfig %s up", interface); - } else if (netmask == NULL) { - snprintf(str, STR_MAX, "/sbin/ifconfig %s %s", - interface, address); - } else { - snprintf(str, STR_MAX, "/sbin/ifconfig %s %s netmask %s", - interface, address, netmask); - } + snprintf(str, STR_MAX, "/dev/%s", interface); + ifr.ifr_flags = IFF_TAP | IFF_NO_PI; + strncpy(ifr.ifr_name, interface, IFNAMSIZ); + + if(ioctl(sd, TUNSETIFF, (void *)&ifr) != 0) { + fprintf(stderr, "%s: ioctl(TUNSETIFF): %s\n", + __func__, strerror(errno)); + close(sd); + return -1; + } + + if (address == NULL) { + snprintf(str, STR_MAX, "/sbin/ifconfig %s up", interface); + } else if (netmask == NULL) { + snprintf(str, STR_MAX, "/sbin/ifconfig %s %s", + interface, address); + } else { + snprintf(str, STR_MAX, "/sbin/ifconfig %s %s netmask %s", + interface, address, netmask); + } if (run_cmd(str) != 0) { fprintf(stderr, "%s: Failed to configure %s\n", @@ -299,7 +321,7 @@ static int open_tap(char *ifname) exec_name, bridge, bridged_if); } } else { - snprintf(str, STR_MAX, "/sbin/ifconfig %s create", bridge); + snprintf(str, STR_MAX, "/sbin/brctl addbr %s", bridge); if (run_cmd(str) != 0) { fprintf(stderr, "%s: Failed to create %s\n", exec_name, bridge); @@ -308,6 +330,8 @@ static int open_tap(char *ifname) } remove_bridge = 1; + strncpy(bridge_name, bridge, STR_MAX); + snprintf(str, STR_MAX, "/sbin/ifconfig %s up", bridge); if (run_cmd(str) != 0) { fprintf(stderr, "%s: Failed to open %s\n", @@ -317,7 +341,7 @@ static int open_tap(char *ifname) } if (bridged_if != NULL) { - snprintf(str, STR_MAX, "/sbin/ifconfig %s addm %s", + snprintf(str, STR_MAX, "/sbin/brctl addif %s %s", bridge, bridged_if); if (run_cmd(str) != 0) { fprintf(stderr, "%s: Failed to add %s to %s\n", @@ -326,8 +350,8 @@ static int open_tap(char *ifname) return -1; } } - - snprintf(str, STR_MAX, "/sbin/ifconfig %s addm %s", + + snprintf(str, STR_MAX, "/sbin/brctl addif %s %s", bridge, interface); if (run_cmd(str) != 0) { fprintf(stderr, "%s: Failed to add %s to %s\n", @@ -416,8 +440,22 @@ static int install_signal_handlers() { } static void do_exit() { + char cmd[STR_MAX]; + if (remove_bridge) { - run_cmd("/sbin/ifconfig bridge0 destroy"); + snprintf(cmd, STR_MAX, "/sbin/ifconfig %s down", + bridge_name); + + if(run_cmd(cmd) != 0) { + fprintf(stderr, "Failed to bring bridge down\n"); + } + + snprintf(cmd, STR_MAX, "/sbin/brctl delbr %s", + bridge_name); + + if(run_cmd(cmd) != 0) { + fprintf(stderr, "Failed to destroy bridge\n"); + } } } @@ -466,159 +504,3 @@ static int open_bpf(char *ifname) return sd; } - -#if 0 -static int retreive_auth_info(void); - - -static int retreive_auth_info(void) -{ - AuthorizationRef aRef; - OSStatus status; - AuthorizationRights myRights; - AuthorizationRights *newRights; - AuthorizationItem *myItem; - AuthorizationItem myItems[1]; - AuthorizationItemSet *mySet; - int i; - - status = AuthorizationCopyPrivilegedReference(&aRef, kAuthorizationFlagDefaults); - if (status != errAuthorizationSuccess) { - return -1; - } - - status = AuthorizationCopyInfo(aRef, NULL, &mySet); - if (status != errAuthorizationSuccess) { - AuthorizationFree(aRef, kAuthorizationFlagDestroyRights); - return -1; - } - - myItems[0].name = "system.privilege.admin"; - myItems[0].valueLength = 0; - myItems[0].value = NULL; - myItems[0].flags = 0; - - myRights.count = sizeof (myItems) / sizeof (myItems[0]); - myRights.items = myItems; - - status = AuthorizationCopyRights(aRef, &myRights, NULL, - kAuthorizationFlagExtendRights, - &newRights); - if (status != errAuthorizationSuccess) { - AuthorizationFreeItemSet(mySet); - AuthorizationFree(aRef, kAuthorizationFlagDestroyRights); - return -2; - } - - AuthorizationFreeItemSet(newRights); - AuthorizationFreeItemSet(mySet); - AuthorizationFree(aRef, kAuthorizationFlagDestroyRights); - - return 0; -} - -static int open_tap(char *ifname) -{ - char str[STR_MAX] = {0}; - char ifstr[STR_MAX] = {0}; - char *interface; - char *address = NULL; - char *netmask = NULL; - char *bridge = NULL; - char *bridged_if = NULL; - int sd; - - snprintf(ifstr, STR_MAX, "%s", ifname); - interface = strtok(ifstr, "/"); - bridge = strtok(NULL, "/"); - if (bridge != NULL) { - bridged_if = strtok(NULL, "/"); - } - interface = strtok(ifstr, ":"); - - address = strtok(NULL, ":"); - - if (address != NULL) { - netmask = strtok(NULL, ":"); - } - - snprintf(str, STR_MAX, "/dev/%s", interface); - - sd = open(str, O_RDWR); - if (sd < 0) { - fprintf(stderr, "%s: Failed to open %s\n", - exec_name, interface); - return -1; - } - - if (address == NULL) { - snprintf(str, STR_MAX, "/sbin/ifconfig %s up", interface); - } else if (netmask == NULL) { - snprintf(str, STR_MAX, "/sbin/ifconfig %s %s", - interface, address); - } else { - snprintf(str, STR_MAX, "/sbin/ifconfig %s %s netmask %s", - interface, address, netmask); - } - - if (run_cmd(str) != 0) { - fprintf(stderr, "%s: Failed to configure %s\n", - exec_name, interface); - close(sd); - return -1; - } - - if (bridge != NULL) { - /* Check to see if bridge is alread up */ - snprintf(str, STR_MAX, "/sbin/ifconfig %s", bridge); - if (run_cmd(str) == 0) { - /* bridge is already up */ - if (bridged_if != NULL) { - fprintf(stderr, "%s: Warning: %s already exists, so %s was not added.\n", - exec_name, bridge, bridged_if); - } - } else { - snprintf(str, STR_MAX, "/sbin/ifconfig %s create", bridge); - if (run_cmd(str) != 0) { - fprintf(stderr, "%s: Failed to create %s\n", - exec_name, bridge); - close(sd); - return -1; - } - remove_bridge = 1; - - snprintf(str, STR_MAX, "/sbin/ifconfig %s up", bridge); - if (run_cmd(str) != 0) { - fprintf(stderr, "%s: Failed to open %s\n", - exec_name, bridge); - close(sd); - return -1; - } - - if (bridged_if != NULL) { - snprintf(str, STR_MAX, "/sbin/ifconfig %s addm %s", - bridge, bridged_if); - if (run_cmd(str) != 0) { - fprintf(stderr, "%s: Failed to add %s to %s\n", - exec_name, bridged_if, bridge); - close(sd); - return -1; - } - } - - snprintf(str, STR_MAX, "/sbin/ifconfig %s addm %s", - bridge, interface); - if (run_cmd(str) != 0) { - fprintf(stderr, "%s: Failed to add %s to %s\n", - exec_name, interface, bridge); - close(sd); - return -1; - } - } - } - - return sd; -} - - -#endif