blob: 0b5802c893bbbfe10573041bfe26a1141ed6e8a4 [file] [log] [blame]
Jon Medhurstaaf37a32013-06-11 12:10:56 +01001/**
Jon Medhurst15ce78d2014-04-10 09:02:02 +01002 * Copyright (C) ARM Limited 2010-2014. All rights reserved.
Jon Medhurstaaf37a32013-06-11 12:10:56 +01003 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
Jon Medhurst15ce78d2014-04-10 09:02:02 +01009#include "CapturedXML.h"
10
Jon Medhurstaaf37a32013-06-11 12:10:56 +010011#include <stdlib.h>
12#include <string.h>
13#include <dirent.h>
Jon Medhurst15ce78d2014-04-10 09:02:02 +010014
Jon Medhurstaaf37a32013-06-11 12:10:56 +010015#include "SessionData.h"
Jon Medhurstaaf37a32013-06-11 12:10:56 +010016#include "Logging.h"
17#include "OlyUtility.h"
18
19CapturedXML::CapturedXML() {
20}
21
22CapturedXML::~CapturedXML() {
23}
24
25mxml_node_t* CapturedXML::getTree(bool includeTime) {
26 mxml_node_t *xml;
27 mxml_node_t *captured;
28 mxml_node_t *target;
29 int x;
30
31 xml = mxmlNewXML("1.0");
32
33 captured = mxmlNewElement(xml, "captured");
34 mxmlElementSetAttr(captured, "version", "1");
Jon Medhurst15ce78d2014-04-10 09:02:02 +010035 if (gSessionData->perf.isSetup()) {
Jon Medhurste31266f2014-08-04 15:47:44 +010036 mxmlElementSetAttr(captured, "type", "Perf");
Jon Medhurst96b56152014-10-30 18:01:15 +000037 mxmlElementSetAttr(captured, "perf_beta", "yes");
Jon Medhurst15ce78d2014-04-10 09:02:02 +010038 }
Jon Medhurstaaf37a32013-06-11 12:10:56 +010039 mxmlElementSetAttrf(captured, "protocol", "%d", PROTOCOL_VERSION);
40 if (includeTime) { // Send the following only after the capture is complete
41 if (time(NULL) > 1267000000) { // If the time is reasonable (after Feb 23, 2010)
42 mxmlElementSetAttrf(captured, "created", "%lu", time(NULL)); // Valid until the year 2038
43 }
44 }
45
46 target = mxmlNewElement(captured, "target");
47 mxmlElementSetAttr(target, "name", gSessionData->mCoreName);
48 mxmlElementSetAttrf(target, "sample_rate", "%d", gSessionData->mSampleRate);
49 mxmlElementSetAttrf(target, "cores", "%d", gSessionData->mCores);
Jon Medhurst15ce78d2014-04-10 09:02:02 +010050 mxmlElementSetAttrf(target, "cpuid", "0x%x", gSessionData->mMaxCpuId);
Jon Medhurstaaf37a32013-06-11 12:10:56 +010051
Jon Medhurstd3698592013-10-10 16:48:56 +010052 if (!gSessionData->mOneShot && (gSessionData->mSampleRate > 0)) {
53 mxmlElementSetAttr(target, "supports_live", "yes");
54 }
55
56 if (gSessionData->mLocalCapture) {
57 mxmlElementSetAttr(target, "local_capture", "yes");
58 }
59
Jon Medhurstaaf37a32013-06-11 12:10:56 +010060 mxml_node_t *counters = NULL;
61 for (x = 0; x < MAX_PERFORMANCE_COUNTERS; x++) {
62 const Counter & counter = gSessionData->mCounters[x];
63 if (counter.isEnabled()) {
64 if (counters == NULL) {
65 counters = mxmlNewElement(captured, "counters");
66 }
67 mxml_node_t *const node = mxmlNewElement(counters, "counter");
68 mxmlElementSetAttrf(node, "key", "0x%x", counter.getKey());
69 mxmlElementSetAttr(node, "type", counter.getType());
Jon Medhurste31266f2014-08-04 15:47:44 +010070 if (counter.getEvent() != -1) {
71 mxmlElementSetAttrf(node, "event", "0x%x", counter.getEvent());
72 }
Jon Medhurstaaf37a32013-06-11 12:10:56 +010073 if (counter.getCount() > 0) {
74 mxmlElementSetAttrf(node, "count", "%d", counter.getCount());
75 }
Jon Medhurste31266f2014-08-04 15:47:44 +010076 if (counter.getCores() > 0) {
77 mxmlElementSetAttrf(node, "cores", "%d", counter.getCores());
78 }
Jon Medhurstaaf37a32013-06-11 12:10:56 +010079 }
80 }
81
82 return xml;
83}
84
85char* CapturedXML::getXML(bool includeTime) {
86 char* xml_string;
87 mxml_node_t *xml = getTree(includeTime);
88 xml_string = mxmlSaveAllocString(xml, mxmlWhitespaceCB);
89 mxmlDelete(xml);
90 return xml_string;
91}
92
93void CapturedXML::write(char* path) {
94 char file[PATH_MAX];
95
96 // Set full path
97 snprintf(file, PATH_MAX, "%s/captured.xml", path);
Jon Medhurste31266f2014-08-04 15:47:44 +010098
Jon Medhurstaaf37a32013-06-11 12:10:56 +010099 char* xml = getXML(true);
100 if (util->writeToDisk(file, xml) < 0) {
101 logg->logError(__FILE__, __LINE__, "Error writing %s\nPlease verify the path.", file);
102 handleException();
103 }
104
105 free(xml);
106}
107
108// whitespace callback utility function used with mini-xml
109const char * mxmlWhitespaceCB(mxml_node_t *node, int loc) {
110 const char *name;
111
112 name = mxmlGetElement(node);
113
114 if (loc == MXML_WS_BEFORE_OPEN) {
115 // Single indentation
116 if (!strcmp(name, "target") || !strcmp(name, "counters"))
Jon Medhurst96b56152014-10-30 18:01:15 +0000117 return "\n ";
Jon Medhurstaaf37a32013-06-11 12:10:56 +0100118
119 // Double indentation
120 if (!strcmp(name, "counter"))
Jon Medhurst96b56152014-10-30 18:01:15 +0000121 return "\n ";
Jon Medhurstaaf37a32013-06-11 12:10:56 +0100122
123 // Avoid a carriage return on the first line of the xml file
124 if (!strncmp(name, "?xml", 4))
Jon Medhurst96b56152014-10-30 18:01:15 +0000125 return NULL;
Jon Medhurstaaf37a32013-06-11 12:10:56 +0100126
127 // Default - no indentation
Jon Medhurst96b56152014-10-30 18:01:15 +0000128 return "\n";
Jon Medhurstaaf37a32013-06-11 12:10:56 +0100129 }
130
131 if (loc == MXML_WS_BEFORE_CLOSE) {
132 // No indentation
133 if (!strcmp(name, "captured"))
Jon Medhurst96b56152014-10-30 18:01:15 +0000134 return "\n";
Jon Medhurstaaf37a32013-06-11 12:10:56 +0100135
136 // Single indentation
137 if (!strcmp(name, "counters"))
Jon Medhurst96b56152014-10-30 18:01:15 +0000138 return "\n ";
Jon Medhurstaaf37a32013-06-11 12:10:56 +0100139
140 // Default - no carriage return
Jon Medhurst96b56152014-10-30 18:01:15 +0000141 return NULL;
Jon Medhurstaaf37a32013-06-11 12:10:56 +0100142 }
143
Jon Medhurst96b56152014-10-30 18:01:15 +0000144 return NULL;
Jon Medhurstaaf37a32013-06-11 12:10:56 +0100145}