aboutsummaryrefslogtreecommitdiff
path: root/devel/mprof/files/patch-02
blob: 03ce455001225589cde8f605bc2b22889c4ab0f0 (plain) (blame)
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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
--- mprof.c.orig	Tue Apr 20 21:36:20 1993
+++ mprof.c	Wed Nov 25 14:20:44 1998
@@ -8,6 +8,9 @@
 #include	<stdio.h>
 #include	<sys/file.h>
 #include	<ctype.h>
+#ifdef __ELF__
+#include	<elf.h>
+#endif
 #include	<a.out.h>
 #include	<stab.h>
 #include 	"mprof.h"
@@ -699,6 +702,108 @@
 st_read(exec_name)
 char	*exec_name;
 {
+#ifdef __ELF__
+    int		elf_file = open(exec_name, (O_RDONLY));
+    Elf_Ehdr	ehdr;
+    Elf_Shdr	shdr, shstrhdr, symhdr, strhdr, stabhdr, stabstrhdr;
+    int		gotsym, gotstr, gotstab, gotstabstr;
+    char	*sh_strings;
+    char	*stab_strings;
+    Elf_Sym	asym;
+    extern char *index();
+    extern char *malloc();
+    char	*stmp;
+    int		string_size;
+    unsigned char type;
+    char	*fname;
+    int		i;
+    
+    read(elf_file, &ehdr, sizeof(ehdr));
+    if (!ehdr.e_shnum) {
+	fprintf(stdout, "st_read -- no symbols in executable\n");
+	exit(1);
+    }
+
+    /* read the section names */
+    lseek(elf_file, ehdr.e_shoff + ehdr.e_shstrndx * ehdr.e_shentsize, L_SET);
+    read(elf_file, &shstrhdr, ehdr.e_shentsize);
+    sh_strings = malloc(shstrhdr.sh_size);
+    lseek(elf_file, shstrhdr.sh_offset, L_SET);
+    read(elf_file, sh_strings, shstrhdr.sh_size);
+
+    /* find the stab sections */
+    gotsym = gotstr = 0;
+    for (i = 0; i < ehdr.e_shnum; i++) {
+	lseek(elf_file, ehdr.e_shoff + i * ehdr.e_shentsize, L_SET);
+	read(elf_file, &shdr, ehdr.e_shentsize);
+	if (!strcmp(sh_strings + shdr.sh_name, ".stab")) {
+	    stabhdr = shdr;
+	    gotstab = 1;
+	} else if (!strcmp(sh_strings + shdr.sh_name, ".stabstr")) {
+	    stabstrhdr = shdr;
+	    gotstabstr = 1;
+	} else if (shdr.sh_type == SHT_SYMTAB) {
+	    symhdr = shdr;
+	    gotsym = 1;
+	} else if (shdr.sh_type == SHT_STRTAB) {
+	    strhdr = shdr;
+	    gotstr = 1;
+	}
+    }
+    if (!gotsym || !gotstr) {
+	fprintf(stdout, "st_read -- no symbols in executable\n");
+	exit(1);
+    }
+
+    /* read in the string table
+     */
+    st_strings = malloc(strhdr.sh_size);
+    lseek(elf_file, strhdr.sh_offset, L_SET);
+    read(elf_file, st_strings, strhdr.sh_size);
+
+    if (gotstabstr) {
+	stab_strings = malloc(stabstrhdr.sh_size);
+	lseek(elf_file, stabstrhdr.sh_offset, L_SET);
+	read(elf_file, stab_strings, stabstrhdr.sh_size);
+    }
+
+    /* read in the symbols one at a time
+     */
+    lseek(elf_file, symhdr.sh_offset, L_SET);
+    for (i = 0; i < symhdr.sh_size / sizeof(Elf_Sym); i++) {
+	read(elf_file, &asym, sizeof(asym));
+	type = ELF_ST_TYPE(asym.st_info);
+	if (type == STT_FUNC) {
+	    /* here's a candidate for a function name
+	     */
+	    fname = (char *) (st_strings + asym.st_name);
+	    stab_name(stab_i) = fname;
+	    stab_addr(stab_i) = asym.st_value;
+	    stab_incr(stab_i);
+	}
+    }
+
+    /* read the stab sections to look for structures */
+    if (gotstab) {
+	struct nlist stab;
+	lseek(elf_file, stabhdr.sh_offset, L_SET);
+	for (i = 0; i < stabhdr.sh_size / sizeof(struct nlist); i++) {
+	    read(elf_file, &stab, sizeof(stab));
+	    if (stab.n_type == N_LSYM || stab.n_type == N_GSYM) {
+		st_read_structure((char *) (stab_strings + stab.n_un.n_strx));
+	    }
+	}
+    }
+
+    stab_name(stab_i) = "unknown";
+    stab_addr(stab_i) = stab_addr(stab_i - 1) + 0x10000;
+    stab_incr(stab_i);
+    stab_name(stab_i) = "end_marker";
+    stab_addr(stab_i) = 0xffffffff;
+    stab_incr(stab_i);
+    qsort(stab, stab_i, sizeof(struct finfo), stab_compare);
+    close(elf_file);
+#else
     int		aout_file = open(exec_name, (O_RDONLY));
     struct	exec	hdr;
     struct	nlist	asym;
@@ -772,6 +877,7 @@
     stab_addr(stab_i) = 0xffffffff;
     stab_incr(stab_i);
     qsort(stab, stab_i, sizeof(struct finfo), stab_compare);
+#endif
 }
 
 void