dvander@2250: #include dvander@2250: #include dvander@2250: #include "string.h" dvander@2250: #include "malloc.h" dvander@2250: dvander@2250: extern "C" char * cplus_demangle(const char *, int); dvander@2250: #define DMGL_PARAMS (1 << 0) dvander@2250: dvander@2250: struct VOffset dvander@2250: { dvander@2250: int linux_offset; dvander@2250: int windows_offset; dvander@2250: }; dvander@2250: dvander@2250: static bool FindVFunc(void *handle, void **vtable, const char* vtable_end, const char *class_function, const char *params, VOffset *offsets); dvander@2250: dvander@2250: int main(int argc, char **argv) dvander@2250: { dvander@2250: void *handle; dvander@2250: void **pVtable; dvander@2250: dvander@2250: VOffset offsets; dvander@2250: char *params = NULL; dvander@2250: bool ret; dvander@2250: dvander@2250: if (argc < 4) dvander@2250: { dvander@2250: fprintf(stderr, "Usage: \n"); dvander@2250: return -1; dvander@2250: } dvander@2250: pred@2464: handle = dlopen(argv[1], RTLD_NOW); pred@2464: dvander@2250: if (handle == NULL) dvander@2250: { dvander@2250: fprintf(stderr, "Failed to open server image, error [%s]\n", dlerror()); dvander@2250: return -1; dvander@2250: } dvander@2250: dvander@2250: pVtable = (void **)dlsym(handle, argv[2]); dvander@2250: dvander@2250: if (pVtable == NULL) dvander@2250: { dvander@2250: fprintf(stderr, "Invalid vtable symbol \"%s\"\n", argv[2]); pred@2464: dlclose(handle); dvander@2250: return -1; dvander@2250: } dvander@2250: dvander@2250: if (argc >= 5) dvander@2250: { dvander@2250: params = argv[4]; dvander@2250: dvander@2250: if (params[0] == '"') dvander@2250: { dvander@2250: params++; dvander@2250: } dvander@2250: dvander@2250: int len = strlen(params)-1; dvander@2250: dvander@2250: if (params[len] == '"') dvander@2250: { dvander@2250: params[len] = '\0'; dvander@2250: } dvander@2250: dvander@2250: if (params[0] == 0) dvander@2250: { dvander@2250: params = NULL; dvander@2250: } dvander@2250: } dvander@2250: dvander@2250: if (argc == 6) dvander@2250: { dvander@2250: ret = FindVFunc(handle, pVtable, argv[5], argv[3], params, &offsets); dvander@2250: } dvander@2250: else dvander@2250: { dvander@2250: ret = FindVFunc(handle, pVtable, "_ZTI", argv[3], params, &offsets); dvander@2250: } dvander@2250: dvander@2250: if (ret) dvander@2250: { dvander@2250: if (params != NULL) dvander@2250: { dvander@2250: printf("%s%s - Win: %i Linux : %i\n", argv[3], params, offsets.windows_offset, offsets.linux_offset); dvander@2250: } dvander@2250: else dvander@2250: { dvander@2250: printf("%s - Win: %i Linux : %i\n", argv[3], offsets.windows_offset, offsets.linux_offset); dvander@2250: } dvander@2250: pred@2464: dlclose(handle); dvander@2250: return 0; dvander@2250: } dvander@2250: dvander@2250: fprintf(stderr, "Failed to find function!"); pred@2464: dlclose(handle); dvander@2250: return -1; dvander@2250: } dvander@2250: dvander@2250: static bool FindVFunc(void *handle, void **vtable, const char* vtable_end, const char *class_function, const char *params, VOffset *offsets) dvander@2250: { dvander@2250: Dl_info d; dvander@2250: dvander@2250: int linux_offset = -1; dvander@2250: int windows_offset = -1; dvander@2250: dvander@2250: int overloads = 0; dvander@2250: int location = 0; dvander@2250: int start_offset = -1; dvander@2250: dvander@2250: for (int i=0; i< 1000; i++) dvander@2250: { dvander@2250: void *FuncPtr = vtable[i]; dvander@2250: dvander@2250: int status = dladdr(FuncPtr, &d); dvander@2250: dvander@2250: if (!status) dvander@2250: { dvander@2250: continue; dvander@2250: } dvander@2250: dvander@2250: if (i > 1 && strncmp(d.dli_sname, vtable_end, strlen(vtable_end)) == 0) dvander@2250: { dvander@2250: break; dvander@2250: } dvander@2250: dvander@2250: char *name = cplus_demangle(d.dli_sname, DMGL_PARAMS); dvander@2250: dvander@2250: if (name == NULL) dvander@2250: { dvander@2250: printf("Demangling failed\n"); dvander@2250: continue; dvander@2250: } dvander@2250: dvander@2250: char *foundfunction = strpbrk(name, ":"); dvander@2250: dvander@2250: if (foundfunction == NULL) dvander@2250: { dvander@2250: //printf("Couldnt split function\n"); dvander@2250: free(name); dvander@2250: continue; dvander@2250: } dvander@2250: dvander@2250: //Skip both ':' chars dvander@2250: foundfunction += 2; dvander@2250: dvander@2250: dvander@2250: if (strncmp(foundfunction, class_function, strlen(class_function)) == 0 && foundfunction[strlen(class_function)] == '(') dvander@2250: { dvander@2250: //printf("Symbol: %s Demangled: %s Offset: %i\n", d.dli_sname, name, i); dvander@2250: dvander@2250: //We have a pointer to a function, but it may be overloaded. dvander@2250: overloads++; dvander@2250: dvander@2250: if (start_offset == -1) dvander@2250: { dvander@2250: start_offset = i-1; dvander@2250: } dvander@2250: dvander@2250: char *foundparams = strpbrk(foundfunction, "("); dvander@2250: dvander@2250: if (foundparams == NULL) dvander@2250: { dvander@2250: printf("ARGH\n"); dvander@2250: free(name); dvander@2250: continue; dvander@2250: } dvander@2250: dvander@2250: if(params == NULL || strcmp(foundparams, params) == 0) dvander@2250: { dvander@2250: //This is actually our function - So this is the linux offset dvander@2250: linux_offset = i; dvander@2250: location = overloads; dvander@2250: } dvander@2250: } dvander@2250: dvander@2250: free(name); dvander@2250: } dvander@2250: dvander@2250: windows_offset = (overloads-location) + start_offset; dvander@2250: dvander@2250: offsets->linux_offset = linux_offset - 2; dvander@2250: offsets->windows_offset = windows_offset - 2; dvander@2250: dvander@2250: return true; dvander@2250: }