freebsd-ports/devel/mprof/files/patch-02
David E. O'Brien 279cf52593 Support ELF.
Submitted by:	Doug Rabson <dfr@calcaphon.com>
1998-12-01 09:42:46 +00:00

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