elk/src/stab-macho.c

109 lines
3.9 KiB
C

/* stab-macho.c
*
* $Id$
*
* Copyright 1990, 1991, 1992, 1993, 1994, 1995, Oliver Laumann, Berlin
* Copyright 2002, 2003 Sam Hocevar <sam@hocevar.net>, Paris
*
* This software was derived from Elk 1.2, which was Copyright 1987, 1988,
* 1989, Nixdorf Computer AG and TELES GmbH, Berlin (Elk 1.2 has been written
* by Oliver Laumann for TELES Telematic Services, Berlin, in a joint project
* between TELES and Nixdorf Microprocessor Engineering, Berlin).
*
* Oliver Laumann, TELES GmbH, Nixdorf Computer AG and Sam Hocevar, as co-
* owners or individual owners of copyright in this software, grant to any
* person or company a worldwide, royalty free, license to
*
* i) copy this software,
* ii) prepare derivative works based on this software,
* iii) distribute copies of this software or derivative works,
* iv) perform this software, or
* v) display this software,
*
* provided that this notice is not removed and that neither Oliver Laumann
* nor Teles nor Nixdorf are deemed to have made any representations as to
* the suitability of this software for any purpose nor are held responsible
* for any defects of this software.
*
* THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
*/
#include <nlist.h>
#include <mach-o/rld.h>
static SYMTAB *Grovel_Over_Nlist (symcmd, nl, strtab, text_sect)
struct symtab_command *symcmd; /* ptr to MACH-O symtab command */
struct nlist nl[]; /* ptr to symbol table */
char *strtab; /* ptr to string table */
long text_sect; /* # of text section */ {
SYMTAB *tab;
register SYM *sp, **nextp;
long i;
tab = (SYMTAB *) Safe_Malloc (sizeof (SYMTAB));
tab->first = 0;
tab->strings = 0;
nextp = &tab->first;
/* Grovel over the file's nlist, extracting global symbols that
* have a section mumber equal to the number of the text section:
*/
for (i = 0; i < symcmd->nsyms; i++) {
if ((nl[i].n_type & (N_TYPE|N_EXT)) == (N_SECT|N_EXT) &&
nl[i].n_sect == text_sect) {
sp = (SYM *)Safe_Malloc (sizeof (SYM));
sp->name = strtab + nl[i].n_un.n_strx;
sp->value = nl[i].n_value;
sp->next = 0;
*nextp = sp;
nextp = &sp->next;
}
}
return tab;
}
SYMTAB *Snarf_Symbols (struct mach_header *mhdr) {
struct load_command *ld_cmd;
struct symtab_command *sym_cmd;
struct segment_command *seg_cmd;
struct section *sp;
struct nlist *symtab = 0;
char *cmdptr, *strtab;
long i, j, text_sect = 0;
/* Loop through the load commands, find the symbol table and
* the segment command carrying the text section to determine
* the number of the text section:
*/
cmdptr = (char *)mhdr + sizeof (struct mach_header);
for (i = 0; i < mhdr->ncmds; i++) {
ld_cmd = (struct load_command *)cmdptr;
if (ld_cmd->cmd == LC_SYMTAB && !symtab) {
sym_cmd = (struct symtab_command *)ld_cmd;
symtab = (struct nlist *)((char *)mhdr + sym_cmd->symoff);
strtab = (char *)mhdr + sym_cmd->stroff;
} else if (ld_cmd->cmd == LC_SEGMENT && !text_sect) {
seg_cmd = (struct segment_command *)ld_cmd;
sp = (struct section *)
((char *)ld_cmd + sizeof (struct segment_command));
for (j = 1; j <= seg_cmd->nsects && !text_sect; j++, sp++)
if (strcmp (sp->sectname, SECT_TEXT) == 0)
text_sect = j;
}
cmdptr += ld_cmd->cmdsize;
}
if (!symtab)
Primitive_Error ("couldn't find symbol table in object file");
if (!text_sect)
Primitive_Error ("couldn't find text section in object file");
return Grovel_Over_Nlist (sym_cmd, symtab, strtab, text_sect);
}
#ifdef INIT_OBJECTS
SYMTAB *Open_File_And_Snarf_Symbols (char *name) {
extern char *_mh_execute_header;
return Snarf_Symbols ((struct mach_header *)&_mh_execute_header);
}
#endif /* INIT_OBJECTS */