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