michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: /* michael@0: michael@0: A program that reverse-maps a binary stream of address references to michael@0: function names. michael@0: michael@0: */ michael@0: michael@0: #include michael@0: #include michael@0: #include michael@0: #include michael@0: michael@0: #include "elf_symbol_table.h" michael@0: michael@0: #define _GNU_SOURCE michael@0: #include michael@0: michael@0: static int michael@0: map_addrs(int fd, elf_symbol_table &table) michael@0: { michael@0: // Read the binary addresses from stdin. michael@0: unsigned int buf[128]; michael@0: ssize_t cb; michael@0: michael@0: while ((cb = read(fd, buf, sizeof buf)) > 0) { michael@0: if (cb % sizeof buf[0]) michael@0: fprintf(stderr, "unaligned read\n"); michael@0: michael@0: unsigned int *addr = buf; michael@0: unsigned int *limit = buf + (cb / 4); michael@0: michael@0: for (; addr < limit; ++addr) { michael@0: const Elf32_Sym *sym = table.lookup(*addr); michael@0: if (sym) michael@0: cout << table.get_symbol_name(sym) << endl; michael@0: } michael@0: } michael@0: michael@0: return 0; michael@0: } michael@0: michael@0: static struct option long_options[] = { michael@0: { "exe", required_argument, 0, 'e' }, michael@0: { 0, 0, 0, 0 } michael@0: }; michael@0: michael@0: static void michael@0: usage() michael@0: { michael@0: cerr << "usage: mapaddrs --exe=exe file ..." << endl; michael@0: } michael@0: michael@0: int michael@0: main(int argc, char *argv[]) michael@0: { michael@0: elf_symbol_table table; michael@0: michael@0: while (1) { michael@0: int option_index = 0; michael@0: int c = getopt_long(argc, argv, "e:", long_options, &option_index); michael@0: michael@0: if (c < 0) michael@0: break; michael@0: michael@0: switch (c) { michael@0: case 'e': michael@0: table.init(optarg); michael@0: break; michael@0: michael@0: default: michael@0: usage(); michael@0: return 1; michael@0: } michael@0: } michael@0: michael@0: if (optind >= argc) { michael@0: map_addrs(STDIN_FILENO, table); michael@0: } michael@0: else { michael@0: do { michael@0: int fd = open(argv[optind], O_RDONLY); michael@0: if (fd < 0) { michael@0: perror(argv[optind]); michael@0: return 1; michael@0: } michael@0: michael@0: map_addrs(fd, table); michael@0: close(fd); michael@0: } while (++optind < argc); michael@0: } michael@0: michael@0: return 0; michael@0: }