#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <mach-o/loader.h>
#include <vector>
#include "mach-o/dyld_gdb.h"
#if OLD_GDB_DYLD_INTERFACE
unsigned int gdb_dyld_version = 2;
void gdb_dyld_state_changed()
{
}
#define NLIBRARY_IMAGES 200
#define NOBJECT_IMAGES 1
struct image {
const char* physical_name; uint32_t vmaddr_slide; const mach_header* mh; uint32_t valid; const char* name; };
struct library_images {
struct image images[NLIBRARY_IMAGES];
uint32_t nimages;
struct library_images* next_images;
};
struct object_images {
struct image images[NOBJECT_IMAGES];
uint32_t nimages;
struct library_images* next_images;
};
unsigned int gdb_nobject_images = NOBJECT_IMAGES;
unsigned int gdb_object_image_size = sizeof(image);
unsigned int gdb_nlibrary_images = NLIBRARY_IMAGES;
unsigned int gdb_library_image_size = sizeof(image);
extern "C" {
object_images object_images = { {}, 0 , NULL };
library_images library_images = { {}, 0 , NULL };
void send_event(const struct dyld_event* event);
}
enum dyld_event_type {
DYLD_IMAGE_ADDED = 0,
DYLD_IMAGE_REMOVED = 5
};
struct dyld_event {
enum dyld_event_type type;
const struct mach_header* header;
uintptr_t slide;
};
void send_event(const struct dyld_event* event);
void (*send_event_ptr)(const struct dyld_event* event) = &send_event;
void addImageForgdb(const mach_header* mh, uintptr_t slide, const char* physicalPath, const char* logicalPath)
{
struct library_images* li = &library_images;
while ( li->nimages >= NLIBRARY_IMAGES ) {
if ( li->next_images == NULL ) {
struct library_images* li2 = new struct library_images();
li2->nimages = 0;
li2->next_images = NULL;
li->next_images = li2;
li = li2;
}
else {
li = li->next_images;
}
}
image* info = &li->images[li->nimages++];
info->physical_name = physicalPath;
info->vmaddr_slide = slide;
info->mh = mh;
info->valid = 1;
info->name = logicalPath;
dyld_event event;
event.type = DYLD_IMAGE_ADDED;
event.header = mh;
event.slide = slide;
(*send_event_ptr)(&event);
}
void send_event(const struct dyld_event* event)
{
}
void removeImageForgdb(const mach_header* mh)
{
for (struct library_images* li = &library_images; li != NULL; li = li->next_images) {
for( uint32_t n=0; n < li->nimages; ++n) {
struct image* image = &li->images[n];
if ( image->mh == mh ) {
image->physical_name = NULL;
image->vmaddr_slide = 0;
image->mh = 0;
image->valid = 0;
image->name = NULL;
return;
}
}
}
}
#endif
static std::vector<dyld_image_info> sImageInfos;
void addImagesToAllImages(uint32_t infoCount, const dyld_image_info info[])
{
dyld_all_image_infos.infoArray = NULL;
for (uint32_t i=0; i < infoCount; ++i)
sImageInfos.push_back(info[i]);
dyld_all_image_infos.infoArrayCount = sImageInfos.size();
dyld_all_image_infos.infoArray = &sImageInfos[0];
dyld_all_image_infos.notification(dyld_image_adding, infoCount, info);
}
void removeImageFromAllImages(const struct mach_header* loadAddress)
{
dyld_image_info goingAway;
dyld_all_image_infos.infoArray = NULL;
for (std::vector<dyld_image_info>::iterator it=sImageInfos.begin(); it != sImageInfos.end(); it++) {
if ( it->imageLoadAddress == loadAddress ) {
goingAway = *it;
sImageInfos.erase(it);
break;
}
}
dyld_all_image_infos.infoArrayCount = sImageInfos.size();
dyld_all_image_infos.infoArray = &sImageInfos[0];
dyld_all_image_infos.notification(dyld_image_removing, 1, &goingAway);
}
static void gdb_image_notifier(enum dyld_image_mode mode, uint32_t infoCount, const dyld_image_info info[])
{
}
struct dyld_all_image_infos dyld_all_image_infos = { 1, 0, NULL, &gdb_image_notifier, false };