diff --git a/direct/src/showutil/FreezeTool.py b/direct/src/showutil/FreezeTool.py index f8212c6f50..ceb85a6b11 100644 --- a/direct/src/showutil/FreezeTool.py +++ b/direct/src/showutil/FreezeTool.py @@ -1648,6 +1648,8 @@ class Freezer: strings = sorted(strings, key=lambda str:-len(str)) string_offsets = {} + # Now add the strings to the pool, and collect the offsets relative to + # the beginning of the pool. for string in strings: # First check whether it's already in there; it could be part of # a longer string. @@ -1710,55 +1712,50 @@ class Freezer: # on the platform. num_pointers = 10 stub_data = bytearray(stub_file.read()) - if self._is_executable_64bit(stub_data): - header_layout = 'I', data, 4) + bitnesses = set() + ptr = 8 + for i in range(num_fat): + cputype, cpusubtype, offset, size, align = \ + struct.unpack_from('>IIIII', data, ptr) + ptr += 20 - def _replace_symbol(self, data, symbol_name, replacement): + if (cputype & 0x1000000) != 0: + bitnesses.add(64) + else: + bitnesses.add(32) + return tuple(bitnesses) + + elif data[:4] in (b'\xCA\xFE\xBA\xBF', b'\xBF\xBA\xFE\xCA'): + # Universal binary with 64-bit offsets. + num_fat, = struct.unpack_from('>I', data, 4) + bitnesses = set() + ptr = 8 + for i in range(num_fat): + cputype, cpusubtype, offset, size, align = \ + struct.unpack_from('>QQQQQ', data, ptr) + ptr += 40 + + if (cputype & 0x1000000) != 0: + bitnesses.add(64) + else: + bitnesses.add(32) + return tuple(bitnesses) + + def _replace_symbol(self, data, symbol_name, replacement, bitness=None): """We store a custom section in the binary file containing a header - containing offsets to the binary data.""" + containing offsets to the binary data. + If bitness is set, and the binary in question is a macOS universal + binary, it only replaces for binaries with the given bitness. """ if data.startswith(b'MZ'): # A Windows PE file. @@ -1866,11 +1929,49 @@ class Freezer: elif data[:4] in (b'\xCA\xFE\xBA\xBE', b'\xBE\xBA\xFE\xCA'): # Universal binary with 32-bit offsets. - return self._replace_symbol_fat(data, b'_' + symbol_name, replacement, False) + num_fat, = struct.unpack_from('>I', data, 4) + replaced = False + ptr = 8 + for i in range(num_fat): + cputype, cpusubtype, offset, size, align = \ + struct.unpack_from('>IIIII', data, ptr) + ptr += 20 + + # Does this match the requested bitness? + if bitness is not None and ((cputype & 0x1000000) != 0) != (bitness == 64): + continue + + macho_data = data[offset:offset+size] + off = self._find_symbol_macho(macho_data, symbol_name) + if off is not None: + off += offset + data[off:off+len(replacement)] = replacement + replaced = True + + return replaced elif data[:4] in (b'\xCA\xFE\xBA\xBF', b'\xBF\xBA\xFE\xCA'): # Universal binary with 64-bit offsets. - return self._replace_symbol_fat(data, b'_' + symbol_name, replacement, True) + num_fat, = struct.unpack_from('>I', data, 4) + replaced = False + ptr = 8 + for i in range(num_fat): + cputype, cpusubtype, offset, size, align = \ + struct.unpack_from('>QQQQQ', data, ptr) + ptr += 40 + + # Does this match the requested bitness? + if bitness is not None and ((cputype & 0x1000000) != 0) != (bitness == 64): + continue + + macho_data = data[offset:offset+size] + off = self._find_symbol_macho(macho_data, symbol_name) + if off is not None: + off += offset + data[off:off+len(replacement)] = replacement + replaced = True + + return replaced # We don't know what kind of file this is. return False @@ -1988,7 +2089,7 @@ class Freezer: symoff += nlist_size name = strings[strx : strings.find(b'\0', strx)] - if name == symbol_name: + if name == b'_' + symbol_name: # Find out in which segment this is. for vmaddr, vmsize, fileoff in segments: # Is it defined in this segment? @@ -1996,33 +2097,7 @@ class Freezer: if rel >= 0 and rel < vmsize: # Yes, so return the symbol offset. return fileoff + rel - - def _replace_symbol_fat(self, fat_data, symbol_name, replacement, is_64bit): - """ Implementation of _replace_symbol for universal binaries. """ - num_fat, = struct.unpack_from('>I', fat_data, 4) - - # After the header we get a table of executables in this fat file, - # each one with a corresponding offset into the file. - replaced = False - ptr = 8 - for i in range(num_fat): - if is_64bit: - cputype, cpusubtype, offset, size, align = \ - struct.unpack_from('>QQQQQ', fat_data, ptr) - ptr += 40 - else: - cputype, cpusubtype, offset, size, align = \ - struct.unpack_from('>IIIII', fat_data, ptr) - ptr += 20 - - macho_data = fat_data[offset:offset+size] - off = self._find_symbol_macho(macho_data, symbol_name) - if off is not None: - off += offset - fat_data[off:off+len(replacement)] = replacement - replaced = True - - return replaced + print("Could not find memory address for symbol %s" % (symbol_name)) def makeModuleDef(self, mangledName, code): result = '' diff --git a/dtool/src/prc/configPageManager.cxx b/dtool/src/prc/configPageManager.cxx index a7fc128371..39541212cb 100644 --- a/dtool/src/prc/configPageManager.cxx +++ b/dtool/src/prc/configPageManager.cxx @@ -117,8 +117,10 @@ reload_implicit_pages() { }; #ifdef _MSC_VER const BlobInfo *blobinfo = (const BlobInfo *)GetProcAddress(GetModuleHandle(NULL), "blobinfo"); -#elif defined(RTLD_SELF) - const BlobInfo *blobinfo = (const BlobInfo *)dlsym(RTLD_SELF, "blobinfo"); +#elif defined(RTLD_MAIN_ONLY) + const BlobInfo *blobinfo = (const BlobInfo *)dlsym(RTLD_MAIN_ONLY, "blobinfo"); +//#elif defined(RTLD_SELF) +// const BlobInfo *blobinfo = (const BlobInfo *)dlsym(RTLD_SELF, "blobinfo"); #else const BlobInfo *blobinfo = (const BlobInfo *)dlsym(dlopen(NULL, RTLD_NOW), "blobinfo"); #endif