1/* Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file. */
4
5
6/* XRay -- a simple profiler for Native Client */
7
8#include <stdint.h>
9#include <stdio.h>
10#include <stdlib.h>
11#include <string.h>
12#include <unistd.h>
13#include "xray/xray_priv.h"
14
15#if defined(XRAY)
16
17struct XRaySymbol* XRaySymbolTableCreateEntry(struct XRaySymbolTable* symtab,
18                                              char* line) {
19  uint32_t addr;
20  unsigned int uiaddr;
21  char symbol_text[XRAY_LINE_SIZE];
22  char* parsed_symbol;
23  char* newln;
24  if (2 != sscanf(line, "%x %1023s", &uiaddr, symbol_text))
25    return NULL;
26  if (uiaddr > 0x07FFFFFF) {
27    fprintf(stderr, "While parsing the mapfile, XRay encountered:\n");
28    fprintf(stderr, "%s\n", line);
29    fprintf(stderr,
30        "XRay only works with code addresses 0x00000000 - 0x07FFFFFF\n");
31    fprintf(stderr, "All functions must reside in this address space.\n");
32    exit(-1);
33  }
34  addr = (uint32_t)uiaddr;
35  parsed_symbol = strstr(line, symbol_text);
36  newln = strstr(parsed_symbol, "\n");
37  if (NULL != newln) {
38    *newln = 0;
39  }
40  return XRaySymbolTableAddByName(symtab, parsed_symbol, addr);
41}
42
43
44void XRaySymbolTableParseMapfile(struct XRaySymbolTable* symtab,
45                                 const char* mapfile) {
46  FILE* f;
47  char line[XRAY_LINE_SIZE];
48  bool in_text = false;
49  bool in_link_once = false;
50  int in_link_once_counter = 0;
51  int num_symbols = 0;
52
53  printf("XRay: opening mapfile %s\n", mapfile);
54  f = fopen(mapfile, "rt");
55  if (0 == f) {
56    fprintf(stderr, "XRay: failed to open %s\n", mapfile);
57    return;
58  }
59  printf("XRay: parsing...\n");
60  while (NULL != fgets(line, XRAY_LINE_SIZE, f)) {
61    if (line == strstr(line, " .text ")) {
62      in_text = true;
63      continue;
64    }
65    if (line == strstr(line, " .gnu.linkonce.t.")) {
66      in_link_once = true;
67      in_link_once_counter = 0;
68      continue;
69    }
70    if (line == strstr(line, " .text.")) {
71      in_link_once = true;
72      in_link_once_counter = 0;
73      continue;
74    }
75    if (line == strstr(line, "                0x")) {
76      if (in_text) {
77        XRaySymbolTableCreateEntry(symtab, line);
78        ++num_symbols;
79      } else if (in_link_once) {
80        if (in_link_once_counter != 0) {
81          if (NULL != XRaySymbolTableCreateEntry(symtab, line))
82            ++num_symbols;
83        } else {
84          ++in_link_once_counter;
85        }
86      }
87    } else {
88      in_text = false;
89      in_link_once = false;
90    }
91  }
92  fclose(f);
93  printf("XRay: parsed %d symbols into symbol table\n", num_symbols);
94}
95
96#endif  // XRAY
97