Revision a1d1bb31 gdbstub.c

b/gdbstub.c
1145 1145
    }
1146 1146
}
1147 1147

  
1148
/* GDB breakpoint/watchpoint types */
1149
#define GDB_BREAKPOINT_SW        0
1150
#define GDB_BREAKPOINT_HW        1
1151
#define GDB_WATCHPOINT_WRITE     2
1152
#define GDB_WATCHPOINT_READ      3
1153
#define GDB_WATCHPOINT_ACCESS    4
1154

  
1155
#ifndef CONFIG_USER_ONLY
1156
static const int xlat_gdb_type[] = {
1157
    [GDB_WATCHPOINT_WRITE]  = BP_GDB | BP_MEM_WRITE,
1158
    [GDB_WATCHPOINT_READ]   = BP_GDB | BP_MEM_READ,
1159
    [GDB_WATCHPOINT_ACCESS] = BP_GDB | BP_MEM_ACCESS,
1160
};
1161
#endif
1162

  
1163
static int gdb_breakpoint_insert(CPUState *env, target_ulong addr,
1164
                                 target_ulong len, int type)
1165
{
1166
    switch (type) {
1167
    case GDB_BREAKPOINT_SW:
1168
    case GDB_BREAKPOINT_HW:
1169
        return cpu_breakpoint_insert(env, addr, BP_GDB, NULL);
1170
#ifndef CONFIG_USER_ONLY
1171
    case GDB_WATCHPOINT_WRITE:
1172
    case GDB_WATCHPOINT_READ:
1173
    case GDB_WATCHPOINT_ACCESS:
1174
        return cpu_watchpoint_insert(env, addr, len, xlat_gdb_type[type],
1175
                                     NULL);
1176
#endif
1177
    default:
1178
        return -ENOSYS;
1179
    }
1180
}
1181

  
1182
static int gdb_breakpoint_remove(CPUState *env, target_ulong addr,
1183
                                 target_ulong len, int type)
1184
{
1185
    switch (type) {
1186
    case GDB_BREAKPOINT_SW:
1187
    case GDB_BREAKPOINT_HW:
1188
        return cpu_breakpoint_remove(env, addr, BP_GDB);
1189
#ifndef CONFIG_USER_ONLY
1190
    case GDB_WATCHPOINT_WRITE:
1191
    case GDB_WATCHPOINT_READ:
1192
    case GDB_WATCHPOINT_ACCESS:
1193
        return cpu_watchpoint_remove(env, addr, len, xlat_gdb_type[type]);
1194
#endif
1195
    default:
1196
        return -ENOSYS;
1197
    }
1198
}
1199

  
1200
static void gdb_breakpoint_remove_all(CPUState *env)
1201
{
1202
    cpu_breakpoint_remove_all(env, BP_GDB);
1203
#ifndef CONFIG_USER_ONLY
1204
    cpu_watchpoint_remove_all(env, BP_GDB);
1205
#endif
1206
}
1207

  
1148 1208
static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf)
1149 1209
{
1150 1210
    const char *p;
1151
    int ch, reg_size, type;
1211
    int ch, reg_size, type, res;
1152 1212
    char buf[MAX_PACKET_LENGTH];
1153 1213
    uint8_t mem_buf[MAX_PACKET_LENGTH];
1154 1214
    uint8_t *registers;
......
1168 1228
         * because gdb is doing and initial connect and the state
1169 1229
         * should be cleaned up.
1170 1230
         */
1171
        cpu_breakpoint_remove_all(env);
1172
        cpu_watchpoint_remove_all(env);
1231
        gdb_breakpoint_remove_all(env);
1173 1232
        break;
1174 1233
    case 'c':
1175 1234
        if (*p != '\0') {
......
1203 1262
        exit(0);
1204 1263
    case 'D':
1205 1264
        /* Detach packet */
1206
        cpu_breakpoint_remove_all(env);
1207
        cpu_watchpoint_remove_all(env);
1265
        gdb_breakpoint_remove_all(env);
1208 1266
        gdb_continue(s);
1209 1267
        put_packet(s, "OK");
1210 1268
        break;
......
1327 1385
        put_packet(s, "OK");
1328 1386
        break;
1329 1387
    case 'Z':
1330
        type = strtoul(p, (char **)&p, 16);
1331
        if (*p == ',')
1332
            p++;
1333
        addr = strtoull(p, (char **)&p, 16);
1334
        if (*p == ',')
1335
            p++;
1336
        len = strtoull(p, (char **)&p, 16);
1337
        switch (type) {
1338
        case 0:
1339
        case 1:
1340
            if (cpu_breakpoint_insert(env, addr) < 0)
1341
                goto breakpoint_error;
1342
            put_packet(s, "OK");
1343
            break;
1344
#ifndef CONFIG_USER_ONLY
1345
        case 2:
1346
            type = PAGE_WRITE;
1347
            goto insert_watchpoint;
1348
        case 3:
1349
            type = PAGE_READ;
1350
            goto insert_watchpoint;
1351
        case 4:
1352
            type = PAGE_READ | PAGE_WRITE;
1353
        insert_watchpoint:
1354
            if (cpu_watchpoint_insert(env, addr, type) < 0)
1355
                goto breakpoint_error;
1356
            put_packet(s, "OK");
1357
            break;
1358
#endif
1359
        default:
1360
            put_packet(s, "");
1361
            break;
1362
        }
1363
        break;
1364
    breakpoint_error:
1365
        put_packet(s, "E22");
1366
        break;
1367

  
1368 1388
    case 'z':
1369 1389
        type = strtoul(p, (char **)&p, 16);
1370 1390
        if (*p == ',')
......
1373 1393
        if (*p == ',')
1374 1394
            p++;
1375 1395
        len = strtoull(p, (char **)&p, 16);
1376
        if (type == 0 || type == 1) {
1377
            cpu_breakpoint_remove(env, addr);
1378
            put_packet(s, "OK");
1379
#ifndef CONFIG_USER_ONLY
1380
        } else if (type >= 2 || type <= 4) {
1381
            cpu_watchpoint_remove(env, addr);
1382
            put_packet(s, "OK");
1383
#endif
1384
        } else {
1396
        if (ch == 'Z')
1397
            res = gdb_breakpoint_insert(env, addr, len, type);
1398
        else
1399
            res = gdb_breakpoint_remove(env, addr, len, type);
1400
        if (res >= 0)
1401
             put_packet(s, "OK");
1402
        else if (res == -ENOSYS)
1385 1403
            put_packet(s, "");
1386
        }
1404
        else
1405
            put_packet(s, "E22");
1387 1406
        break;
1388 1407
    case 'q':
1389 1408
    case 'Q':
......
1504 1523

  
1505 1524
    if (reason == EXCP_DEBUG) {
1506 1525
        if (s->env->watchpoint_hit) {
1507
            switch (s->env->watchpoint[s->env->watchpoint_hit - 1].type &
1508
                    (PAGE_READ | PAGE_WRITE)) {
1509
            case PAGE_READ:
1526
            switch (s->env->watchpoint_hit->flags & BP_MEM_ACCESS) {
1527
            case BP_MEM_READ:
1510 1528
                type = "r";
1511 1529
                break;
1512
            case PAGE_READ | PAGE_WRITE:
1530
            case BP_MEM_ACCESS:
1513 1531
                type = "a";
1514 1532
                break;
1515 1533
            default:
......
1517 1535
                break;
1518 1536
            }
1519 1537
            snprintf(buf, sizeof(buf), "T%02x%swatch:" TARGET_FMT_lx ";",
1520
                     SIGTRAP, type,
1521
                     s->env->watchpoint[s->env->watchpoint_hit - 1].vaddr);
1538
                     SIGTRAP, type, s->env->watchpoint_hit->vaddr);
1522 1539
            put_packet(s, buf);
1523
            s->env->watchpoint_hit = 0;
1540
            s->env->watchpoint_hit = NULL;
1524 1541
            return;
1525 1542
        }
1526 1543
	tb_flush(s->env);

Also available in: Unified diff