@@ -1306,8 +1306,103 @@ verify_namelist()
1306
1306
program_usage (SHORT_FORM );
1307
1307
}
1308
1308
1309
+ /*
1310
+ * From either a syment pointer, or a virtual address evaluated
1311
+ * from a symbol name plus an offset value, determine whether
1312
+ * there are multiple symbols with the same name.
1313
+
1314
+ * If there are multiple text symbols with the same name, then
1315
+ * display a "duplicate text symbols found" message followed by
1316
+ * a list of each symbol's information, and return FALSE.
1317
+ *
1318
+ * If there is one text symbol and one or more data symbols with
1319
+ * the same name, reset the incoming address based upon the
1320
+ * single text symbol, and return TRUE.
1321
+ *
1322
+ * All of the remaining possibilities return TRUE without changing
1323
+ * the incoming address:
1324
+ *
1325
+ * (1) if an evaluated address cannot be resolved to any symbol.
1326
+ * (2) if an evaluated address argument did not contain a symbol name.
1327
+ * (3) if there is only one possible symbol resolution.
1328
+ * (4) if there are multiple data symbols.
1329
+ */
1330
+ static int
1331
+ resolve_text_symbol (char * arg , struct syment * sp_in , struct gnu_request * req , int radix )
1332
+ {
1333
+ int text_symbols ;
1334
+ struct syment * sp , * sp_orig , * first_text_sp ;
1335
+ ulong offset , radix_flag ;
1336
+
1337
+ if (sp_in ) {
1338
+ sp_orig = sp_in ;
1339
+ offset = 0 ;
1340
+ } else if ((sp_orig = value_search (req -> addr , & offset ))) {
1341
+ if (!strstr (arg , sp_orig -> name ))
1342
+ return TRUE;
1343
+ } else {
1344
+ if (CRASHDEBUG (1 ))
1345
+ error (INFO , "%s: no text symbol found\n" , arg );
1346
+ return TRUE;
1347
+ }
1348
+
1349
+ if (symbol_name_count (sp_orig -> name ) <= 1 )
1350
+ return TRUE;
1351
+
1352
+ text_symbols = 0 ;
1353
+ first_text_sp = NULL ;
1354
+ sp = sp_orig ;
1355
+
1356
+ do {
1357
+ if (is_symbol_text (sp )) {
1358
+ if (!first_text_sp )
1359
+ first_text_sp = sp ;
1360
+ text_symbols ++ ;
1361
+ }
1362
+ } while ((sp = symbol_search_next (sp -> name , sp )));
1363
+
1364
+ /*
1365
+ * If no text symbols for a symbol name exist, let it be...
1366
+ */
1367
+ if (!text_symbols ) {
1368
+ if (CRASHDEBUG (1 ))
1369
+ error (INFO , "%s: no text symbol found\n" , arg );
1370
+ return TRUE;
1371
+ }
1309
1372
1373
+ /*
1374
+ * If only one symbol with the specified name is text,
1375
+ * reset the req->addr as appropriate in case a
1376
+ * lower-value data symbol was originally selected.
1377
+ */
1378
+ if (text_symbols == 1 ) {
1379
+ if (sp_in )
1380
+ req -> addr = first_text_sp -> value ;
1381
+ else
1382
+ req -> addr = first_text_sp -> value + offset ;
1383
+ return TRUE;
1384
+ }
1310
1385
1386
+ /*
1387
+ * Multiple text symbols with the same name exist.
1388
+ * Display them all and return FALSE.
1389
+ */
1390
+ error (INFO , "%s: duplicate text symbols found:\n" , arg );
1391
+
1392
+ radix_flag = radix == 10 ? SHOW_DEC_OFFS : SHOW_HEX_OFFS ;
1393
+ sp = sp_orig ;
1394
+
1395
+ do {
1396
+ if (is_symbol_text (sp )) {
1397
+ if (module_symbol (sp -> value , NULL , NULL , NULL , 0 ))
1398
+ show_symbol (sp , offset , SHOW_LINENUM |SHOW_MODULE |radix_flag );
1399
+ else
1400
+ show_symbol (sp , offset , SHOW_LINENUM |radix_flag );
1401
+ }
1402
+ } while ((sp = symbol_search_next (sp -> name , sp )));
1403
+
1404
+ return FALSE;
1405
+ }
1311
1406
1312
1407
/*
1313
1408
* This routine disassembles text in one of four manners. A starting
@@ -1363,7 +1458,7 @@ cmd_dis(void)
1363
1458
unfiltered = user_mode = do_machdep_filter = do_load_module_filter = 0 ;
1364
1459
radix = 0 ;
1365
1460
1366
- req = (struct gnu_request * )getbuf (sizeof (struct gnu_request ));
1461
+ req = (struct gnu_request * )GETBUF (sizeof (struct gnu_request ));
1367
1462
req -> buf = GETBUF (BUFSIZE );
1368
1463
req -> flags |= GNU_FROM_TTY_OFF |GNU_RETURN_ON_ERROR ;
1369
1464
req -> count = 1 ;
@@ -1425,22 +1520,34 @@ cmd_dis(void)
1425
1520
radix = pc -> output_radix ;
1426
1521
1427
1522
if (args [optind ]) {
1428
- if (can_eval (args [optind ]))
1523
+ if (can_eval (args [optind ])) {
1429
1524
req -> addr = eval (args [optind ], FAULT_ON_ERROR , NULL );
1430
- else if (hexadecimal (args [optind ], 0 )) {
1525
+ if (!user_mode &&
1526
+ !resolve_text_symbol (args [optind ], NULL , req , radix )) {
1527
+ FREEBUF (req -> buf );
1528
+ FREEBUF (req );
1529
+ return ;
1530
+ }
1531
+ } else if (hexadecimal (args [optind ], 0 )) {
1431
1532
req -> addr = htol (args [optind ], FAULT_ON_ERROR , NULL );
1432
- if (! user_mode &&
1433
- !( sp = value_search ( req -> addr , & offset )) ) {
1533
+ sp = value_search ( req -> addr , & offset );
1534
+ if (! user_mode && ! sp ) {
1434
1535
error (WARNING ,
1435
1536
"%lx: no associated kernel symbol found\n" ,
1436
1537
req -> addr );
1437
1538
unfiltered = TRUE;
1438
1539
}
1439
- if (!offset )
1540
+ if (!offset && sp && is_symbol_text ( sp ) )
1440
1541
req -> flags |= GNU_FUNCTION_ONLY ;
1441
1542
} else if ((sp = symbol_search (args [optind ]))) {
1442
1543
req -> addr = sp -> value ;
1443
- req -> flags |= GNU_FUNCTION_ONLY ;
1544
+ if (!resolve_text_symbol (args [optind ], sp , req , radix )) {
1545
+ FREEBUF (req -> buf );
1546
+ FREEBUF (req );
1547
+ return ;
1548
+ }
1549
+ if (is_symbol_text (sp ))
1550
+ req -> flags |= GNU_FUNCTION_ONLY ;
1444
1551
} else {
1445
1552
fprintf (fp , "symbol not found: %s\n" , args [optind ]);
1446
1553
fprintf (fp , "possible alternatives:\n" );
0 commit comments