void write_map_file( void ) { char *filename; FILE *file; SymbolHash *map_symtab; /* use first module filename to create global map file */ filename = get_map_filename( get_first_module( NULL )->filename ); /* set '.map' extension */ /* Create MAP file */ file = myfopen( filename, "w" ); if (file) { if (opts.verbose) puts("Creating map..."); /* BUG_0036, BUG_0051 */ map_symtab = select_symbols(cond_all_symbols); if (SymbolHash_empty(map_symtab)) { fputs("None.\n", file); } else { /* Write map symbols alphabetically */ SymbolHash_sort(map_symtab, SymbolHash_by_name); write_map_syms(file, map_symtab); fputs("\n\n", file); /* Write map symbols numerically */ SymbolHash_sort(map_symtab, SymbolHash_by_value); write_map_syms(file, map_symtab); } OBJ_DELETE(map_symtab); myfclose(file); } }
/* * nm() is the routine that gets called by ofile_process() to process single * object files. */ static void nm( struct ofile *ofile, char *arch_name, void *cookie) { struct cmd_flags *cmd_flags; struct process_flags process_flags; unsigned long i, j, k; struct load_command *lc; struct symtab_command *st; struct dysymtab_command *dyst; struct segment_command *sg; struct section *s; struct nlist *symbols; unsigned long nsymbols; cmd_flags = (struct cmd_flags *)cookie; process_flags.nsect = -1; process_flags.sect_addr = 0; process_flags.sect_size = 0; process_flags.sect_start_symbol = FALSE; process_flags.nsects = 0; process_flags.sections = NULL; process_flags.text_nsect = NO_SECT; process_flags.data_nsect = NO_SECT; process_flags.bss_nsect = NO_SECT; st = NULL; dyst = NULL; lc = ofile->load_commands; for(i = 0; i < ofile->mh->ncmds; i++){ if(st == NULL && lc->cmd == LC_SYMTAB){ st = (struct symtab_command *)lc; } else if(dyst == NULL && lc->cmd == LC_DYSYMTAB){ dyst = (struct dysymtab_command *)lc; } else if(lc->cmd == LC_SEGMENT){ sg = (struct segment_command *)lc; process_flags.nsects += sg->nsects; } lc = (struct load_command *)((char *)lc + lc->cmdsize); } if(st == NULL || st->nsyms == 0){ error("no name list"); return; } if(process_flags.nsects > 0){ process_flags.sections = (struct section **) malloc(sizeof(struct section *) * process_flags.nsects); k = 0; lc = ofile->load_commands; for (i = 0; i < ofile->mh->ncmds; i++){ if(lc->cmd == LC_SEGMENT){ sg = (struct segment_command *)lc; s = (struct section *) ((char *)sg + sizeof(struct segment_command)); for(j = 0; j < sg->nsects; j++){ if(strcmp((s + j)->sectname, SECT_TEXT) == 0 && strcmp((s + j)->segname, SEG_TEXT) == 0) process_flags.text_nsect = k + 1; else if(strcmp((s + j)->sectname, SECT_DATA) == 0 && strcmp((s + j)->segname, SEG_DATA) == 0) process_flags.data_nsect = k + 1; else if(strcmp((s + j)->sectname, SECT_BSS) == 0 && strcmp((s + j)->segname, SEG_DATA) == 0) process_flags.bss_nsect = k + 1; process_flags.sections[k++] = s + j; } } lc = (struct load_command *) ((char *)lc + lc->cmdsize); } } /* select symbols to print */ symbols = select_symbols(ofile, st, dyst, cmd_flags, &process_flags, &nsymbols); /* set names in the symbols to be printed */ strings = ofile->object_addr + st->stroff; strsize = st->strsize; for(i = 0; i < nsymbols; i++){ if(symbols[i].n_un.n_strx == 0) symbols[i].n_un.n_name = ""; else if(symbols[i].n_un.n_strx < 0 || (unsigned long)symbols[i].n_un.n_strx > st->strsize) symbols[i].n_un.n_name = "bad string index"; else symbols[i].n_un.n_name = symbols[i].n_un.n_strx + strings; if((symbols[i].n_type & N_TYPE) == N_INDR){ if(symbols[i].n_value == 0) symbols[i].n_value = (long)""; else if(symbols[i].n_value > st->strsize) symbols[i].n_value = (long)"bad string index"; else symbols[i].n_value = (long)(symbols[i].n_value + strings); } } /* sort the symbols if needed */ qsort(symbols, nsymbols, sizeof(struct nlist), (int (*)(const void *, const void *))compare); if (cmd_flags->c == TRUE) { /* print header */ fprintf(output, "#ifndef _%s.H_\n", cmd_flags->ofile_name); fprintf(output, "#define _%s.H_\n", cmd_flags->ofile_name); } /* now print the symbols as specified by the flags */ print_symbols(ofile, symbols, nsymbols, strings, st->strsize, cmd_flags, &process_flags, arch_name); free(symbols); if(process_flags.sections != NULL) free(process_flags.sections); if (cmd_flags->c == TRUE) { /* print footer */ fprintf(output, "#endif /* _%s.H_ */\n", cmd_flags->ofile_name); } }