-
Notifications
You must be signed in to change notification settings - Fork 1
/
agent.c
145 lines (111 loc) · 3.48 KB
/
agent.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/* Top level stuff for dagent, the Debugging Agent.
Copyright (C) 2012 Mentor Graphics.
This file is part of dagent, the Debugging Agent.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License version 2.1 as published by the Free Software Foundation.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdio.h>
#include <unistd.h>
#include <sys/mman.h>
#include <string.h>
#include <stddef.h>
#include "agent.h"
#include "tracepoint.h"
#include "thread.h"
#include "backend.h"
#include "config.h"
#include "log.h"
/* Global variable of agent configuration. */
struct agent_config *agent_config;
void
agent_config_set (struct agent_config *config)
{
agent_config = config;
}
int
agent_config_capa_get (struct agent_config *agent_config,
enum AGENT_CAPA_TYPE type)
{
return agent_config->capas[type];
}
/* Helper of agent to read and write memory. */
/* Read memory from address ADDR of length LEGNTH to BUF. *NBYTES is the
actual number of bytes read. Return 0 on success, otherwise return
non-zero. */
int
agent_read_mem (gdb_addr_t addr, gdb_size_t length,
unsigned char *buf, size_t *nbytes)
{
memcpy ((void *) buf, (void *) (ptrdiff_t) addr, length);
*nbytes = length;
return 0;
}
/* Write memory from BUF to address ADDR of length LENGTH. Return 0 if
success, otherwise return non-zero. */
int
agent_write_mem (gdb_addr_t addr, gdb_size_t length,
const unsigned char *buf)
{
int err;
if (!agent_config_capa_get (agent_config, AGENT_CAPA_WRITE_MEM))
{
gdb_verbose ("Memory writing not permitted");
return 1;
}
err = mprotect ((void *) (ptrdiff_t) (addr & 0xfffff000UL),
(length + 4095) & 0xfffff000UL,
PROT_READ|PROT_WRITE|PROT_EXEC);
if (err)
return 1;
memcpy ((void *) (ptrdiff_t) addr, (void *) buf, length);
return 0;
}
/* Return the system's pagesize. The value returned by the system is
memoized. */
int
agent_get_pagesize (void)
{
static int pagesize = 0;
/* This should be safe as long as only the debug thread calls this,
which is true currently. */
if (pagesize == 0)
{
pagesize = sysconf (_SC_PAGE_SIZE);
if (pagesize == -1)
agent_fatal ("sysconf");
}
return pagesize;
}
#if defined BUILD_UST
void initialize_ust (void);
#endif
void initialize_helper_thread (void);
struct backend *agent_backend;
/* Initialization of the whole agent. */
static void __attribute__ ((constructor))
initialize_agent (void)
{
/* AGENT_verbosity = AGENT_VERBOSITY_NOISY; */
agent_backend = initialize_backend ();
/* Initialize tracepoints module. */
initialize_tracepoint ();
extern struct agent_config agent_config_gdb;
agent_config_set (&agent_config_gdb);
agent_config->init ();
initialize_helper_thread ();
#if defined BUILD_UST
initialize_ust ();
#endif
}
int GDB_AGENT_SYM(ust_loaded) = 0;
/* The last two bits represent the capability of installing fast tracepoint
and install static tracepoint respectively. */
int GDB_AGENT_SYM(capability) = 0x1 | 0x2;