Exemplo n.º 1
0
void ProcessImageLoad(const struct mach_header* mh, intptr_t slide)
{
	unsigned long size;
	std::vector<const char*> classNames;
	void* dataPtr = nullptr;

#ifdef OBJC_ABI_2
	const class_t** classes;
	ProcessProtocolsNew(mh, slide);

	classes = reinterpret_cast<const class_t**>(
		getsectdata(mh, SEG_OBJC_CLASSLIST_NEW, SECT_OBJC_CLASSLIST_NEW, &size)
	);
	if (classes)
	{
		classNames = ProcessClassesNew(mh, slide, classes, size);
		dataPtr = (void*)*classes;
	}

	ProcessCategoriesNew(mh, slide);
#else
	module_info* modinfo;
	ProcessProtocolsOld(mh, slide);

	modinfo = reinterpret_cast<module_info*>(
		getsectdata(mh, SEG_OBJC_MODINFO_OLD, SECT_OBJC_MODINFO_OLD, &size)
	);

	if (modinfo && modinfo->symtab)
	{
		classNames = ProcessClassesOld(mh, slide, modinfo);
		dataPtr = modinfo;
		ProcessCategoriesOld(mh, slide, modinfo);
	}
#endif

	UpdateClassRefs(mh);
	UpdateSelectors(mh, slide);

	// Do this only for dynamic libs (slide > 0)
	if (!classNames.empty() && slide > 0)
	{
		// Generate a NSFramework_XXXX class for GNUstep's NSBundle
		const char* path = dyld_image_path_containing_address(dataPtr);
		assert(path != nullptr);
		RegisterFramework(&classNames[0], classNames.size(), path);
	}

	static SEL selInit = sel_getUid("load");
	while (!g_pendingInitClasses.empty())
	{
		auto pair = g_pendingInitClasses.front();
		g_pendingInitClasses.pop();
		pair.second(reinterpret_cast<objc_object*>(pair.first), selInit);
	}
}
Exemplo n.º 2
0
static void* getStubAddr()
{
#if __LP64__
	uint64_t size;
#else
	uint32_t size;
#endif
	uintptr_t slide = (uintptr_t)&_mh_dylib_header; // assume dylib is zero-base so slide == load address
#if __i386__
	return getsectdatafromheader(&_mh_dylib_header, "__IMPORT", "__jump_table", &size) + slide;
#elif __ppc__
	return getsectdatafromheader(&_mh_dylib_header, "TEXT", "__picsymbolstub1", &size) + slide;
#elif __ppc64__
	return getsectdatafromheader_64(&_mh_dylib_header, "__TEXT", "__picsymbolstub1", &size) + slide;
#elif __x86_64__
	return getsectdatafromheader_64(&_mh_dylib_header, "__TEXT", "__symbol_stub1", &size) + slide;
#elif __arm__
	void* p = getsectdata("__TEXT", "__picsymbolstub4", (unsigned long*)&size);
	if ( p != NULL ) 
		return getsectdatafromheader(&_mh_dylib_header, "__TEXT", "__picsymbolstub4", &size) + slide;
	return getsectdatafromheader(&_mh_dylib_header, "__TEXT", "__symbolstub1", &size) + slide;
#else
	#error unknown arch
#endif
}
Exemplo n.º 3
0
std::vector<const char*> ProcessClassesNew(const struct mach_header* mh, intptr_t slide, const char* segment, const char* section, uint32_t image_index)
{
	class_t **classes, **classes_end;
	unsigned long size;
	std::vector<const char*> classNames;

	classes = reinterpret_cast<class_t**>(
		getsectdata(mh, segment, section, &size)
	);

	if (nullptr != classes)
	{
		classes_end = classes + size / sizeof(class_t*);

		while (classes < classes_end)
		{
			Class c = RegisterClass(*classes, slide, image_index);
			classNames.push_back(class_getName(c));
			LOG << "Fixup @" << classes << " " << *classes << " -> " << c <<std::endl;
			*classes = (class_t*)c;

			classes++;
		}
	}

	return classNames;
}
Exemplo n.º 4
0
void UpdateCFStrings(const struct mach_header* mh)
{
	unsigned long size;
	apple_cfstring* strings = reinterpret_cast<apple_cfstring*>(
		getsectdata(mh, "__DATA", "__cfstring", &size)
	);

	if (strings)
		FixupCFStrings(strings, size / sizeof(apple_cfstring));

	strings = reinterpret_cast<apple_cfstring*>(
		getsectdata(mh, "__DATA", "__ustring", &size)
	);

	if (strings)
		FixupCFStrings(strings, size / sizeof(apple_cfstring));
}
Exemplo n.º 5
0
void ProcessImageLoad(const struct mach_header* mh, intptr_t slide)
{
	unsigned long size;

#ifdef OBJC_ABI_2
	const class_t** classes;
	ProcessProtocolsNew(mh, slide);

	classes = reinterpret_cast<const class_t**>(
		getsectdata(mh, SEG_OBJC_CLASSLIST_NEW, SECT_OBJC_CLASSLIST_NEW, &size)
	);
	if (classes)
		ProcessClassesNew(mh, slide, classes, size);

	ProcessCategoriesNew(mh, slide);
#else
	module_info* modinfo;
	ProcessProtocolsOld(mh, slide);

	modinfo = reinterpret_cast<module_info*>(
		getsectdata(mh, SEG_OBJC_MODINFO_OLD, SECT_OBJC_MODINFO_OLD, &size)
	);

	if (modinfo && modinfo->symtab)
	{
		ProcessClassesOld(mh, slide, modinfo);
		ProcessCategoriesOld(mh, slide, modinfo);
	}
#endif

	UpdateClassRefs(mh);
	UpdateSelectors(mh, slide);

	static SEL selInit = sel_getUid("load");
	while (!g_pendingInitClasses.empty())
	{
		auto pair = g_pendingInitClasses.front();
		g_pendingInitClasses.pop();
		pair.second(reinterpret_cast<objc_object*>(pair.first), selInit);
	}
}
Exemplo n.º 6
0
void UpdateSelectors(const struct mach_header* mh, intptr_t slide)
{
	selref* sel_refs;
	msgref* msg_refs;
	unsigned long selsize, msgsize;

	sel_refs = reinterpret_cast<selref*>(
		getsectdata(mh, SEG_OBJC_SELREFS_NEW, SECT_OBJC_SELREFS_NEW, &selsize)
	);
	
	msg_refs = reinterpret_cast<msgref*>(
		getsectdata(mh, SEG_OBJC_MSGREFS_NEW, SECT_OBJC_MSGREFS_NEW, &msgsize)
	);
	
	if (!sel_refs)
	{
		sel_refs = reinterpret_cast<selref*>(
			getsectdata(mh, SEG_OBJC_SELREFS_OLD, SECT_OBJC_SELREFS_OLD, &selsize)
		);
	}

	if (sel_refs)
	{
		for (size_t i = 0; i < selsize / sizeof(selref); i++)
		{
			SEL native = sel_getUid(sel_refs[i].selName);
			LOG << "ObjC SEL fixup @" << (sel_refs+i) << ": " << sel_refs[i].sel << " -> " << native << std::endl;
			sel_refs[i].sel = native;
		}
	}
	if (msg_refs)
	{
		for (size_t i = 0; i < msgsize / sizeof(msgref); i++)
		{
			SEL native = sel_getUid(msg_refs[i].sel.selName);
			LOG << "ObjC msgref fixup @" << &msg_refs[i].sel.sel << ": " << msg_refs[i].sel.sel << " -> " << native << std::endl;
			msg_refs[i].sel.sel = native;
		}
	}
}
Exemplo n.º 7
0
void UpdateClassRefs(const struct mach_header* mh)
{
	unsigned long refsize, refsize_s;
	class_t **class_refs, **class_refs_end, **super_refs, **super_refs_end;
	
	class_refs = reinterpret_cast<class_t**>(
		getsectdata(mh, SEG_OBJC_CLASSREFS_NEW, SECT_OBJC_CLASSREFS_NEW, &refsize)
	);
	super_refs = reinterpret_cast<class_t**>(
		getsectdata(mh, SEG_OBJC_SUPERREFS_NEW, SECT_OBJC_SUPERREFS_NEW, &refsize_s)
	);
	if (class_refs)
		class_refs_end = class_refs + refsize / sizeof(class_t*);
	
	if (super_refs)
		super_refs_end = super_refs + refsize_s / sizeof(class_t*);
	
	if (class_refs)
		find_and_fix((void**) class_refs, (void**) class_refs_end, g_classPointers);
	
	if (super_refs)
		find_and_fix((void**) super_refs, (void**) super_refs_end, g_classPointers);
}
Exemplo n.º 8
0
void ProcessProtocolsNew(const struct mach_header* mh, intptr_t slide)
{
	const protocol_t** protocol_list;
	unsigned long protosize;

	protocol_list = reinterpret_cast<const protocol_t**>(
		getsectdata(mh, SEG_OBJC_PROTOLIST_NEW, SECT_OBJC_PROTOLIST_NEW, &protosize)
	);

	if (protocol_list)
	{
		unsigned long refsize;
		protocol_t** protocol_refs;
		protocol_t** protocol_refs_end;
		std::set<const protocol_t*> setProtocols;
		std::vector<const protocol_t*> vecProtocols;

		protocol_refs = reinterpret_cast<protocol_t**>(
			getsectdata(mh, SEG_OBJC_PROTOREFS_NEW, SECT_OBJC_PROTOREFS_NEW, &refsize)
		);

		if (protocol_refs)
			protocol_refs_end = protocol_refs + refsize / sizeof(protocol_t*);

		std::copy(protocol_list, protocol_list+protosize/sizeof(protocol_t*), std::inserter(setProtocols, setProtocols.begin()));
		topology_sort<const protocol_t>(setProtocols, vecProtocols,
			[&setProtocols,slide](const protocol_t* p) { return p->protocols ?  std::set<const protocol_t*>(p->protocols->begin(slide), p->protocols->end(slide)) : std::set<const protocol_t*>();  });

		for (const protocol_t* proto : vecProtocols)
		{
			Protocol* p = RegisterProtocol(proto, slide);
			
			if (protocol_refs)
				find_and_fix(protocol_refs, protocol_refs_end, proto, p);
		}
	}
}
Exemplo n.º 9
0
rs_bool mapf_open( const char *path )
{
kern_return_t rc;

    if (strncmp(path,"sect:",5) == 0)
    {
    char *s, name[1000];
    
	strcpy( name, path+5 );
	s = strchr( name, ':' );
	*s++ = 0;
	
	image_file = -1;
	image_mapping_addr = 
	    (vm_address_t)getsectdata( name, s, (int *)&image_mapping_size );
	if (!image_mapping_addr)
	{
	    fprintf( stderr, "could not map segment %s, section %s\n",
	    			name, s );
	    return NO;
	}
    }
    else
    {
	image_file = open( path, O_RDONLY, 0 );
	if (image_file < 0)
	{
	    perror( path );
	    return NO;
	}
	image_mapping_size = lseek( image_file, 0L, SEEK_END );
	
	rc = map_fd( image_file, 
		    (vm_offset_t)0, 
		    &image_mapping_addr, 
		    /* find_space */ TRUE,
		    image_mapping_size );
	if (rc != KERN_SUCCESS)
	{
	    fprintf( stderr, "could not map file: %s\n", path );
	    close( image_file );
	    return NO;
	}
    }
    image_mapping_ptr = (void *)image_mapping_addr;
    return YES;
}
Exemplo n.º 10
0
void UpdateClassRefs(const struct mach_header* mh)
{
	clsref* class_refs;
	unsigned long refsize;

	class_refs = reinterpret_cast<clsref*>(
		getsectdata(mh, SEG_OBJC_CLASSREFS_OLD, SECT_OBJC_CLASSREFS_OLD, &refsize)
	);

	if (class_refs)
	{
		for (size_t i = 0; i < refsize / sizeof(clsref); i++)
		{
			Class c = (Class) objc_getClass(class_refs[i].clsName);
			LOG << "ObjC fixup classref @" << &class_refs[i].cls << ": " << class_refs[i].cls << " -> " << c << std::endl;
			class_refs[i].cls = c;
		}
	}
}
Exemplo n.º 11
0
Bool ML_(read_macho_debug_info)( struct _DebugInfo* di )
{
   struct symtab_command *symcmd = NULL;
   struct dysymtab_command *dysymcmd = NULL;
   HChar* dsymfilename = NULL;
   Bool have_uuid = False;
   UChar uuid[16];
   ImageInfo ii;  /* main file */
   ImageInfo iid; /* auxiliary .dSYM file */
   Bool ok;

   /* mmap the object file to look for di->soname and di->text_bias 
      and uuid and nlist and STABS */

   if (VG_(clo_verbosity) > 1)
      VG_(message)(Vg_DebugMsg,
                   "%s (%#lx)\n", di->filename, di->rx_map_avma );

   /* This should be ensured by our caller. */
   vg_assert(di->have_rx_map);
   vg_assert(di->have_rw_map);

   VG_(memset)(&ii,   0, sizeof(ii));
   VG_(memset)(&iid,  0, sizeof(iid));
   VG_(memset)(&uuid, 0, sizeof(uuid));

   ok = map_image_aboard( di, &ii, di->filename );
   if (!ok) goto fail;

   vg_assert(ii.macho_img != NULL && ii.macho_img_szB > 0);

   /* Poke around in the Mach-O header, to find some important
      stuff. */
   // Find LC_SYMTAB and LC_DYSYMTAB, if present.
   // Read di->soname from LC_ID_DYLIB if present, 
   //    or from LC_ID_DYLINKER if present, 
   //    or use "NONE".
   // Get di->text_bias (aka slide) based on the corresponding LC_SEGMENT
   // Get uuid for later dsym search

   di->text_bias = 0;

   { struct MACH_HEADER *mh = (struct MACH_HEADER *)ii.macho_img;
      struct load_command *cmd;
      Int c;

      for (c = 0, cmd = (struct load_command *)(mh+1);
           c < mh->ncmds;
           c++, cmd = (struct load_command *)(cmd->cmdsize
                                              + (unsigned long)cmd)) {
         if (cmd->cmd == LC_SYMTAB) {
            symcmd = (struct symtab_command *)cmd;
         } 
         else if (cmd->cmd == LC_DYSYMTAB) {
            dysymcmd = (struct dysymtab_command *)cmd;
         } 
         else if (cmd->cmd == LC_ID_DYLIB && mh->filetype == MH_DYLIB) {
            // GrP fixme bundle?
            struct dylib_command *dcmd = (struct dylib_command *)cmd;
            UChar *dylibname = dcmd->dylib.name.offset + (UChar *)dcmd;
            UChar *soname = VG_(strrchr)(dylibname, '/');
            if (!soname) soname = dylibname;
            else soname++;
            di->soname = ML_(dinfo_strdup)("di.readmacho.dylibname",
                                           soname);
         }
         else if (cmd->cmd==LC_ID_DYLINKER  &&  mh->filetype==MH_DYLINKER) {
            struct dylinker_command *dcmd = (struct dylinker_command *)cmd;
            UChar *dylinkername = dcmd->name.offset + (UChar *)dcmd;
            UChar *soname = VG_(strrchr)(dylinkername, '/');
            if (!soname) soname = dylinkername;
            else soname++;
            di->soname = ML_(dinfo_strdup)("di.readmacho.dylinkername",
                                           soname);
         }

         // A comment from Julian about why varinfo[35] fail:
         //
         // My impression is, from comparing the output of otool -l for these
         // executables with the logic in ML_(read_macho_debug_info),
         // specifically the part that begins "else if (cmd->cmd ==
         // LC_SEGMENT_CMD) {", that it's a complete hack which just happens
         // to work ok for text symbols.  In particular, it appears to assume
         // that in a "struct load_command" of type LC_SEGMENT_CMD, the first
         // "struct SEGMENT_COMMAND" inside it is going to contain the info we
         // need.  However, otool -l shows, and also the Apple docs state,
         // that a struct load_command may contain an arbitrary number of
         // struct SEGMENT_COMMANDs, so I'm not sure why it's OK to merely
         // snarf the first.  But I'm not sure about this.
         //
         // The "Try for __DATA" block below simply adds acquisition of data
         // svma/bias values using the same assumption.  It also needs
         // (probably) to deal with bss sections, but I don't understand how
         // this all ties together really, so it requires further study.
         //
         // If you can get your head around the relationship between MachO
         // segments, sections and load commands, this might be relatively
         // easy to fix properly.
         //
         // Basically we need to come up with plausible numbers for di->
         // {text,data,bss}_{avma,svma}, from which the _bias numbers are
         // then trivially derived.  Then I think the debuginfo reader should
         // work pretty well.
         else if (cmd->cmd == LC_SEGMENT_CMD) {
            struct SEGMENT_COMMAND *seg = (struct SEGMENT_COMMAND *)cmd;
            /* Try for __TEXT */
            if (!di->text_present
                && 0 == VG_(strcmp)(seg->segname, "__TEXT")
                /* DDD: is the  next line a kludge? -- JRS */
                && seg->fileoff == 0 && seg->filesize != 0) {
               di->text_present = True;
               di->text_svma = (Addr)seg->vmaddr;
               di->text_avma = di->rx_map_avma;
               di->text_size = seg->vmsize;
               di->text_bias = di->text_avma - di->text_svma;
               /* Make the _debug_ values be the same as the
                  svma/bias for the primary object, since there is
                  no secondary (debuginfo) object, but nevertheless
                  downstream biasing of Dwarf3 relies on the
                  _debug_ values. */
               di->text_debug_svma = di->text_svma;
               di->text_debug_bias = di->text_bias;
            }
            /* Try for __DATA */
            if (!di->data_present
                && 0 == VG_(strcmp)(seg->segname, "__DATA")
                /* && DDD:seg->fileoff == 0 */ && seg->filesize != 0) {
               di->data_present = True;
               di->data_svma = (Addr)seg->vmaddr;
               di->data_avma = di->rw_map_avma;
               di->data_size = seg->vmsize;
               di->data_bias = di->data_avma - di->data_svma;
               di->data_debug_svma = di->data_svma;
               di->data_debug_bias = di->data_bias;
            }
         }
         else if (cmd->cmd == LC_UUID) {
             struct uuid_command *uuid_cmd = (struct uuid_command *)cmd;
             VG_(memcpy)(uuid, uuid_cmd->uuid, sizeof(uuid));
             have_uuid = True;
         }
      }
   }

   if (!di->soname) {
      di->soname = ML_(dinfo_strdup)("di.readmacho.noname", "NONE");
   }

   /* Now we have the base object to hand.  Read symbols from it. */

   if (ii.macho_img && ii.macho_img_szB > 0 && symcmd && dysymcmd) {

      /* Read nlist symbol table */
      struct NLIST *syms;
      UChar *strs;
      XArray* /* DiSym */ candSyms = NULL;
      Word i, nCandSyms;

      if (ii.macho_img_szB < symcmd->stroff + symcmd->strsize
          || ii.macho_img_szB < symcmd->symoff + symcmd->nsyms
                                                 * sizeof(struct NLIST)) {
         ML_(symerr)(di, False, "Invalid Mach-O file (5 too small).");
         goto fail;
      }   
      if (dysymcmd->ilocalsym + dysymcmd->nlocalsym > symcmd->nsyms
          || dysymcmd->iextdefsym + dysymcmd->nextdefsym > symcmd->nsyms) {
         ML_(symerr)(di, False, "Invalid Mach-O file (bad symbol table).");
         goto fail;
      }
      
      syms = (struct NLIST *)(ii.macho_img + symcmd->symoff);
      strs = (UChar *)(ii.macho_img + symcmd->stroff);
      
      if (VG_(clo_verbosity) > 1)
         VG_(message)(Vg_DebugMsg,
            "   reading syms   from primary file (%d %d)\n",
            dysymcmd->nextdefsym, dysymcmd->nlocalsym );

      /* Read candidate symbols into 'candSyms', so we can truncate
         overlapping ends and generally tidy up, before presenting
         them to ML_(addSym). */
      candSyms = VG_(newXA)(
                    ML_(dinfo_zalloc), "di.readmacho.candsyms.1",
                    ML_(dinfo_free), sizeof(DiSym)
                 );
      vg_assert(candSyms);

      // extern symbols
      read_symtab(candSyms,
                  di, 
                  syms + dysymcmd->iextdefsym, dysymcmd->nextdefsym, 
                  strs, symcmd->strsize);
      // static and private_extern symbols
      read_symtab(candSyms,
                  di, 
                  syms + dysymcmd->ilocalsym, dysymcmd->nlocalsym, 
                  strs, symcmd->strsize);

      /* tidy up the cand syms -- trim overlapping ends.  May resize
         candSyms. */
      tidy_up_cand_syms( candSyms, di->trace_symtab );

      /* and finally present them to ML_(addSym) */
      nCandSyms = VG_(sizeXA)( candSyms );
      for (i = 0; i < nCandSyms; i++) {
         DiSym* cand = (DiSym*) VG_(indexXA)( candSyms, i );
         if (di->trace_symtab)
            VG_(printf)("nlist final: acquire  avma %010lx-%010lx  %s\n",
                        cand->addr, cand->addr + cand->size - 1, cand->name );
         ML_(addSym)( di, cand );
      }
      VG_(deleteXA)( candSyms );
   }

   /* If there's no UUID in the primary, don't even bother to try and
      read any DWARF, since we won't be able to verify it matches.
      Our policy is not to load debug info unless we can verify that
      it matches the primary.  Just declare success at this point.
      And don't complain to the user, since that would cause us to
      complain on objects compiled without -g.  (Some versions of
      XCode are observed to omit a UUID entry for object linked(?)
      without -g.  Others don't appear to omit it.) */
   if (!have_uuid)
      goto success;

   /* mmap the dSYM file to look for DWARF debug info.  If successful,
      use the .macho_img and .macho_img_szB in iid. */

   dsymfilename = find_separate_debug_file( di->filename );

   /* Try to load it. */
   if (dsymfilename) {
      Bool valid;

      if (VG_(clo_verbosity) > 1)
         VG_(message)(Vg_DebugMsg, "   dSYM= %s\n", dsymfilename);

      ok = map_image_aboard( di, &iid, dsymfilename );
      if (!ok) goto fail;

      /* check it has the right uuid. */
      vg_assert(have_uuid);
      valid = iid.macho_img && iid.macho_img_szB > 0 
              && check_uuid_matches( (Addr)iid.macho_img,
                                     iid.macho_img_szB, uuid );
      if (valid)
         goto read_the_dwarf;

      if (VG_(clo_verbosity) > 1)
         VG_(message)(Vg_DebugMsg, "   dSYM does not have "
                                   "correct UUID (out of date?)\n");
   }

   /* There was no dsym file, or it doesn't match.  We'll have to try
      regenerating it, unless --dsymutil=no, in which case just complain
      instead. */

   /* If this looks like a lib that we shouldn't run dsymutil on, just
      give up.  (possible reasons: is system lib, or in /usr etc, or
      the dsym dir would not be writable by the user, or we're running
      as root) */
   vg_assert(di->filename);
   if (is_systemish_library_name(di->filename))
      goto success;

   if (!VG_(clo_dsymutil)) {
      if (VG_(clo_verbosity) == 1) {
         VG_(message)(Vg_DebugMsg, "%s:\n", di->filename);
      }
      if (VG_(clo_verbosity) > 0)
         VG_(message)(Vg_DebugMsg, "%sdSYM directory %s; consider using "
                      "--dsymutil=yes\n",
                      VG_(clo_verbosity) > 1 ? "   " : "",
                      dsymfilename ? "has wrong UUID" : "is missing"); 
      goto success;
   }

   /* Run dsymutil */

   { Int r;
     HChar* dsymutil = "/usr/bin/dsymutil ";
     HChar* cmd = ML_(dinfo_zalloc)( "di.readmacho.tmp1", 
                                     VG_(strlen)(dsymutil)
                                     + VG_(strlen)(di->filename)
                                     + 30 /* misc */ );
     VG_(strcpy)(cmd, dsymutil);
     if (0) VG_(strcat)(cmd, "--verbose ");
     VG_(strcat)(cmd, di->filename);
     VG_(message)(Vg_DebugMsg, "run: %s\n", cmd);
     r = VG_(system)( cmd );
     if (r)
        VG_(message)(Vg_DebugMsg, "run: %s FAILED\n", dsymutil);
     ML_(dinfo_free)(cmd);
     dsymfilename = find_separate_debug_file(di->filename);
   }

   /* Try again to load it. */
   if (dsymfilename) {
      Bool valid;

      if (VG_(clo_verbosity) > 1)
         VG_(message)(Vg_DebugMsg, "   dsyms= %s\n", dsymfilename);

      ok = map_image_aboard( di, &iid, dsymfilename );
      if (!ok) goto fail;

      /* check it has the right uuid. */
      vg_assert(have_uuid);
      valid = iid.macho_img && iid.macho_img_szB > 0 
              && check_uuid_matches( (Addr)iid.macho_img,
                                     iid.macho_img_szB, uuid );
      if (!valid) {
         if (VG_(clo_verbosity) > 0) {
            VG_(message)(Vg_DebugMsg,
               "WARNING: did not find expected UUID %02X%02X%02X%02X"
               "-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X"
               " in dSYM dir\n",
               (UInt)uuid[0], (UInt)uuid[1], (UInt)uuid[2], (UInt)uuid[3],
               (UInt)uuid[4], (UInt)uuid[5], (UInt)uuid[6], (UInt)uuid[7],
               (UInt)uuid[8], (UInt)uuid[9], (UInt)uuid[10],
               (UInt)uuid[11], (UInt)uuid[12], (UInt)uuid[13],
               (UInt)uuid[14], (UInt)uuid[15] );
            VG_(message)(Vg_DebugMsg,
                         "WARNING: for %s\n", di->filename);
         }
         unmap_image( &iid );
         /* unmap_image zeroes the fields, so the following test makes
            sense. */
         goto fail;
      }
   }

   /* Right.  Finally we have our best try at the dwarf image, so go
      on to reading stuff out of it. */

  read_the_dwarf:
   if (iid.macho_img && iid.macho_img_szB > 0) {
      UChar* debug_info_img = NULL;
      Word   debug_info_sz;
      UChar* debug_abbv_img;
      Word   debug_abbv_sz;
      UChar* debug_line_img;
      Word   debug_line_sz;
      UChar* debug_str_img;
      Word   debug_str_sz;
      UChar* debug_ranges_img;
      Word   debug_ranges_sz;
      UChar* debug_loc_img;
      Word   debug_loc_sz;
      UChar* debug_name_img;
      Word   debug_name_sz;

      debug_info_img = 
          getsectdata(iid.macho_img, iid.macho_img_szB, 
                      "__DWARF", "__debug_info", &debug_info_sz);
      debug_abbv_img = 
          getsectdata(iid.macho_img, iid.macho_img_szB, 
                      "__DWARF", "__debug_abbrev", &debug_abbv_sz);
      debug_line_img = 
          getsectdata(iid.macho_img, iid.macho_img_szB, 
                      "__DWARF", "__debug_line", &debug_line_sz);
      debug_str_img = 
          getsectdata(iid.macho_img, iid.macho_img_szB, 
                      "__DWARF", "__debug_str", &debug_str_sz);
      debug_ranges_img = 
          getsectdata(iid.macho_img, iid.macho_img_szB, 
                      "__DWARF", "__debug_ranges", &debug_ranges_sz);
      debug_loc_img = 
          getsectdata(iid.macho_img, iid.macho_img_szB, 
                      "__DWARF", "__debug_loc", &debug_loc_sz);
      debug_name_img = 
          getsectdata(iid.macho_img, iid.macho_img_szB, 
                      "__DWARF", "__debug_pubnames", &debug_name_sz);
   
      if (debug_info_img) {
         if (VG_(clo_verbosity) > 1) {
            if (0)
            VG_(message)(Vg_DebugMsg,
                         "Reading dwarf3 for %s (%#lx) from %s"
                         " (%ld %ld %ld %ld %ld %ld)\n",
                         di->filename, di->text_avma, dsymfilename,
                         debug_info_sz, debug_abbv_sz, debug_line_sz, 
                         debug_str_sz, debug_ranges_sz, debug_loc_sz
                         );
            VG_(message)(Vg_DebugMsg,
               "   reading dwarf3 from dsyms file\n");
         }
         /* The old reader: line numbers and unwind info only */
         ML_(read_debuginfo_dwarf3) ( di,
                                      debug_info_img, debug_info_sz,
                                      debug_abbv_img, debug_abbv_sz,
                                      debug_line_img, debug_line_sz,
                                      debug_str_img,  debug_str_sz );

         /* The new reader: read the DIEs in .debug_info to acquire
            information on variable types and locations.  But only if
            the tool asks for it, or the user requests it on the
            command line. */
         if (VG_(needs).var_info /* the tool requires it */
             || VG_(clo_read_var_info) /* the user asked for it */) {
            ML_(new_dwarf3_reader)(
               di, debug_info_img,   debug_info_sz,
                   debug_abbv_img,   debug_abbv_sz,
                   debug_line_img,   debug_line_sz,
                   debug_str_img,    debug_str_sz,
                   debug_ranges_img, debug_ranges_sz,
                   debug_loc_img,    debug_loc_sz
            );
         }
      }
   }

   if (dsymfilename) ML_(dinfo_free)(dsymfilename);

  success:
   if (ii.img)
      unmap_image(&ii);
   if (iid.img)
      unmap_image(&iid);
   return True;

   /* NOTREACHED */

  fail:
   ML_(symerr)(di, True, "Error reading Mach-O object.");
   if (ii.img)
      unmap_image(&ii);
   if (iid.img)
      unmap_image(&iid);
   return False;
}
Exemplo n.º 12
0
void *get_osx_section_end(const char *section) {
    unsigned long secsize;
    char *section_start = getsectdata("__DATA", section, &secsize);
    return get_real_address(section_start) + secsize;
}
Exemplo n.º 13
0
void *get_osx_section_start(const char *section) {
    unsigned long secsize;
    return get_real_address(getsectdata("__DATA", section, &secsize));
}
Exemplo n.º 14
0
const char *find_system_image( const char *arg0, const char *dflt )
{
static char temp[1024];
char *p;
#ifdef __NeXT__
int n;

   if (getsectdata( "IMAGE", "system", &n ))
     {
       return "sect:IMAGE:system";
     }
#endif

  /* if the default is specified and exists, use it
   *
   * this is used by applications that supply their own
   * image
   */

  if (dflt && os_file_exists_p(dflt))
     return dflt;

  /* look in ~/lib/rs/$RSCHEME_VERSION/system.img  */

  if (os_getenv("HOME"))
    {
      strcpy( temp, os_getenv( "HOME" ) );
      strcat( temp, "/lib/rs/" RSCHEME_VERSION "/system.img" );
      if (os_file_exists_p(temp))
	return temp;
    }

  /* look in [install]/resource/system.img */

  strcpy( temp, rs_install_dir );
  strcat( temp, "/resource/system.img" );
  if (os_file_exists_p(temp))
    return temp;

  /*  If argv[0] is of the form foo/bin/blech
      then look for foo/resource/blech.img
  */

  if ((p = strrchr(arg0,'/')))
    {
      char *p2;

      strncpy( temp, arg0, p - arg0 );
      temp[p - arg0] = 0;

      p2 = strrchr( temp, '/' );
      if (p2)
	p2[1] = 0;

      strcat( temp, "resource/" );
      strcat( temp, p+1 );
      strcat( temp, ".img" );
    }
  else
    strcpy( temp, "../resource/system.img" );

  if (os_file_exists_p(temp))
    return temp;

  return NULL;
}