File: stab-macho.c

package info (click to toggle)
elk 3.99.8-2.1
  • links: PTS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 5,004 kB
  • ctags: 3,435
  • sloc: ansic: 22,294; lisp: 6,208; makefile: 821; sh: 171; awk: 154; cpp: 92
file content (108 lines) | stat: -rw-r--r-- 4,043 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
/* 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 */