blob: 24fcb740abe39dea4bd484a15e64e690972b525a [file] [log] [blame]
Juan Cespedes96935a91997-08-09 23:45:39 +02001#include <stdio.h>
2#include <errno.h>
3#include <stdlib.h>
4#include <unistd.h>
5#include <sys/types.h>
6#include <sys/ptrace.h>
7#include <sys/resource.h>
8#include <sys/wait.h>
9#include <sys/stat.h>
10#include <fcntl.h>
11#include <linux/elf.h>
12#include <sys/mman.h>
13#include <string.h>
14#include <signal.h>
15
16#include "elf.h"
17#include "ltrace.h"
18#include "trace.h"
19
20int read_elf(const char *filename)
21{
22 struct stat sbuf;
23 int fd;
24 void * addr;
25 struct elf32_hdr * hdr;
26 Elf32_Shdr * shdr;
27 struct elf32_sym * symtab = NULL;
28 int i;
29 char * strtab = NULL;
30 u_long symtab_len = 0;
31
32 fd = open(filename, O_RDONLY);
33 if (fd==-1) {
34 fprintf(stderr, "Can't open \"%s\": %s\n", filename, sys_errlist[errno]);
35 exit(1);
36 }
37 if (fstat(fd, &sbuf)==-1) {
38 fprintf(stderr, "Can't stat \"%s\": %s\n", filename, sys_errlist[errno]);
39 exit(1);
40 }
41 if (sbuf.st_size < sizeof(struct elf32_hdr)) {
42 fprintf(stderr, "\"%s\" is not an ELF object\n", filename);
43 exit(1);
44 }
45 addr = mmap(NULL, sbuf.st_size, PROT_READ, MAP_SHARED, fd, 0);
46 if (addr==(void*)-1) {
47 fprintf(stderr, "Can't mmap \"%s\": %s\n", filename, sys_errlist[errno]);
48 exit(1);
49 }
50 hdr = addr;
51 if (strncmp(hdr->e_ident, ELFMAG, SELFMAG)) {
52 fprintf(stderr, "\"%s\" is not an ELF object\n", filename);
53 exit(1);
54 }
55 for(i=0; i<hdr->e_shnum; i++) {
56 shdr = addr + hdr->e_shoff + i*hdr->e_shentsize;
57 if (shdr->sh_type == SHT_DYNSYM) {
58 if (!symtab) {
59#if 0
60 symtab = (struct elf32_sym *)shdr->sh_addr;
61#else
62 symtab = (struct elf32_sym *)(addr + shdr->sh_offset);
63#endif
64 symtab_len = shdr->sh_size;
65 }
66 }
67 if (shdr->sh_type == SHT_STRTAB) {
68 if (!strtab) {
69#if 0
70 strtab = (char *)(addr + shdr->sh_offset);
71#else
72 strtab = (char *)(addr + shdr->sh_offset);
73#endif
74 }
75 }
76 }
77 if (debug>0) {
78 fprintf(output, "symtab: 0x%08x\n", (unsigned)symtab);
79 fprintf(output, "symtab_len: %lu\n", symtab_len);
80 fprintf(output, "strtab: 0x%08x\n", (unsigned)strtab);
81 }
82 if (!symtab) {
83 return 0;
84 }
85 for(i=0; i<symtab_len/sizeof(struct elf32_sym); i++) {
86 if (!((symtab+i)->st_shndx) && (symtab+i)->st_value) {
87 struct library_symbol * tmp = library_symbols;
88
89 library_symbols = malloc(sizeof(struct library_symbol));
90 if (!library_symbols) {
91 perror("malloc");
92 exit(1);
93 }
94 library_symbols->addr = ((symtab+i)->st_value);
95 library_symbols->name = strtab+(symtab+i)->st_name;
96 library_symbols->next = tmp;
97 if (debug>0) {
98 fprintf(output, "addr: 0x%08x, symbol: \"%s\"\n",
99 (unsigned)((symtab+i)->st_value),
100 (strtab+(symtab+i)->st_name));
101 }
102 }
103 }
104 return 1;
105}
106