blob: 03918aa5fc52927c9186e7da98911f2e28bcf124 [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>
Juan Cespedes96935a91997-08-09 23:45:39 +02008#include <sys/types.h>
Juan Cespedes96935a91997-08-09 23:45:39 +02009#include <sys/stat.h>
10#include <fcntl.h>
11#include <linux/elf.h>
12#include <sys/mman.h>
13#include <string.h>
Juan Cespedes96935a91997-08-09 23:45:39 +020014
15#include "elf.h"
16#include "ltrace.h"
Juan Cespedesc9a48b91997-08-17 02:45:40 +020017#include "symbols.h"
Juan Cespedes3268a161997-08-25 16:45:22 +020018#include "output.h"
Juan Cespedes96935a91997-08-09 23:45:39 +020019
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
Juan Cespedes1afec691997-08-23 21:31:46 +020032 if (opt_d>0) {
Juan Cespedes3268a161997-08-25 16:45:22 +020033 send_line("Reading symbol table from %s...", filename);
Juan Cespedes1afec691997-08-23 21:31:46 +020034 }
35
Juan Cespedes96935a91997-08-09 23:45:39 +020036 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) {
Juan Cespedes96935a91997-08-09 23:45:39 +020073 strtab = (char *)(addr + shdr->sh_offset);
Juan Cespedes96935a91997-08-09 23:45:39 +020074 }
75 }
76 }
Juan Cespedes1afec691997-08-23 21:31:46 +020077 if (opt_d>1) {
Juan Cespedes3268a161997-08-25 16:45:22 +020078 send_line("symtab: 0x%08x", (unsigned)symtab);
79 send_line("symtab_len: %lu", symtab_len);
80 send_line("strtab: 0x%08x", (unsigned)strtab);
Juan Cespedes96935a91997-08-09 23:45:39 +020081 }
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;
Juan Cespedes1afec691997-08-23 21:31:46 +020097 if (opt_d>1) {
Juan Cespedes3268a161997-08-25 16:45:22 +020098 send_line("addr: 0x%08x, symbol: \"%s\"",
Juan Cespedes96935a91997-08-09 23:45:39 +020099 (unsigned)((symtab+i)->st_value),
100 (strtab+(symtab+i)->st_name));
101 }
102 }
103 }
104 return 1;
105}
106