01167 {
01168
01169
01170
01171
unsigned long i;
01172
unsigned long j;
01173
unsigned long count = _dyld_image_count();
01174
struct mach_header *mh = 0;
01175
struct load_command *lc = 0;
01176
unsigned long addr = NULL;
01177
unsigned long table_off = (
unsigned long)0;
01178
int found = 0;
01179
if (!info)
01180
return 0;
01181 dolock();
01182 resetdlerror();
01183 info->
dli_fname = 0;
01184 info->
dli_fbase = 0;
01185 info->
dli_sname = 0;
01186 info->
dli_saddr = 0;
01187
01188
01189
01190
for (i = 0; i < count; i++)
01191 {
01192 addr = (
unsigned long)p - _dyld_get_image_vmaddr_slide(i);
01193 mh = _dyld_get_image_header(i);
01194
if (mh)
01195 {
01196 lc = (
struct load_command *)((
char *)mh +
sizeof(
struct mach_header));
01197
for (j = 0; j < mh->ncmds; j++, lc = (
struct load_command *)((
char *)lc + lc->cmdsize))
01198 {
01199
if (LC_SEGMENT == lc->cmd &&
01200 addr >= ((
struct segment_command *)lc)->vmaddr &&
01201 addr <
01202 ((
struct segment_command *)lc)->vmaddr + ((
struct segment_command *)lc)->vmsize)
01203 {
01204 info->
dli_fname = _dyld_get_image_name(i);
01205 info->
dli_fbase = (
void *)mh;
01206 found = 1;
01207
break;
01208 }
01209 }
01210
if (found)
01211
break;
01212 }
01213 }
01214
if (!found)
01215 {
01216 dounlock();
01217
return 0;
01218 }
01219 lc = (
struct load_command *)((
char *)mh +
sizeof(
struct mach_header));
01220
for (j = 0; j < mh->ncmds; j++, lc = (
struct load_command *)((
char *)lc + lc->cmdsize))
01221 {
01222
if (LC_SEGMENT == lc->cmd)
01223 {
01224
if (!strcmp(((
struct segment_command *)lc)->segname,
"__LINKEDIT"))
01225
break;
01226 }
01227 }
01228 table_off =
01229 ((
unsigned long)((
struct segment_command *)lc)->vmaddr) -
01230 ((
unsigned long)((
struct segment_command *)lc)->fileoff) + _dyld_get_image_vmaddr_slide(i);
01231 debug(
"table off %x", table_off);
01232
01233 lc = (
struct load_command *)((
char *)mh +
sizeof(
struct mach_header));
01234
for (j = 0; j < mh->ncmds; j++, lc = (
struct load_command *)((
char *)lc + lc->cmdsize))
01235 {
01236
if (LC_SYMTAB == lc->cmd)
01237 {
01238
01239
struct nlist *symtable = (
struct nlist *)(((
struct symtab_command *)lc)->symoff + table_off);
01240
unsigned long numsyms = ((
struct symtab_command *)lc)->nsyms;
01241
struct nlist *nearest = NULL;
01242
unsigned long diff = 0xffffffff;
01243
unsigned long strtable = (
unsigned long)(((
struct symtab_command *)lc)->stroff + table_off);
01244 debug(
"symtable %x", symtable);
01245
for (i = 0; i < numsyms; i++)
01246 {
01247
01248
if ((!symtable->n_value)
01249 || (symtable->n_type >= N_PEXT)
01250 || (!(symtable->n_type & N_EXT))
01251 )
01252 {
01253 symtable++;
01254
continue;
01255 }
01256
if ((addr >= symtable->n_value) && (diff >= (symtable->n_value - addr)))
01257 {
01258 diff = (
unsigned long)symtable->n_value - addr;
01259 nearest = symtable;
01260 }
01261 symtable++;
01262 }
01263
if (nearest)
01264 {
01265 info->
dli_saddr = nearest->n_value + ((
void *)p - addr);
01266 info->
dli_sname = (
char *)(strtable + nearest->n_un.n_strx);
01267 }
01268 }
01269 }
01270 dounlock();
01271
return 1;
01272 }