279cf52593
Submitted by: Doug Rabson <dfr@calcaphon.com>
130 lines
3.6 KiB
Plaintext
130 lines
3.6 KiB
Plaintext
--- 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
|