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 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099 4100 4101 4102 4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167 4168 4169 4170 4171 4172 4173 4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192 4193 4194 4195 4196 4197 4198 4199 4200 4201 4202 4203 4204 4205 4206 4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 4221 4222 4223 4224 4225 4226 4227 4228 4229 4230 4231 4232 4233 4234 4235 4236 4237 4238 4239 4240 4241 4242 4243 4244 4245 4246 4247 4248 4249 4250 4251 4252 4253 4254 4255 4256 4257 4258 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 4278 4279 4280 4281 4282 4283 4284 4285 4286 4287 4288 4289 4290 4291 4292 4293 4294 4295 4296 4297 4298 4299 4300 4301 4302 4303 4304 4305 4306 4307 4308 4309 4310 4311 4312 4313 4314 4315 4316 4317 4318 4319 4320 4321 4322 4323 4324 4325 4326 4327 4328 4329 4330 4331 4332 4333 4334 4335 4336 4337 4338 4339 4340 4341 4342 4343 4344 4345 4346 4347 4348 4349 4350 4351 4352 4353 4354 4355 4356 4357 4358 4359 4360 4361 4362 4363 4364 4365 4366 4367 4368 4369 4370 4371 4372 4373 4374 4375 4376 4377 4378 4379 4380 4381 4382 4383 4384 4385 4386 4387 4388 4389 4390 4391 4392 4393 4394 4395 4396 4397 4398 4399 4400 4401 4402 4403 4404 4405 4406 4407 4408 4409 4410 4411 4412 4413 4414 4415 4416 4417 4418 4419 4420 4421 4422 4423 4424 4425 4426 4427 4428 4429 4430 4431 4432 4433 4434 4435 4436 4437 4438 4439 4440 4441 4442 4443 4444 4445 4446 4447 4448 4449 4450 4451 4452 4453 4454 4455 4456 4457 4458 4459 4460 4461 4462 4463 4464 4465 4466 4467 4468 4469 4470 4471 4472 4473 4474 4475 4476 4477 4478 4479 4480 4481 4482 4483 4484 4485 4486 4487 4488 4489 4490 4491 4492 4493 4494 4495 4496 4497 4498 4499 4500 4501 4502 4503 4504 4505 4506 4507 4508 4509 4510 4511 4512 4513 4514 4515 4516 4517 4518 4519 4520 4521 4522 4523 4524 4525 4526 4527 4528 4529 4530 4531 4532 4533 4534 4535 4536 4537 4538 4539 4540 4541 4542 4543 4544 4545 4546 4547 4548 4549 4550 4551 4552 4553 4554 4555 4556 4557 4558 4559 4560 4561 4562 4563 4564 4565 4566 4567 4568 4569 4570 4571 4572 4573 4574 4575 4576 4577 4578 4579 4580 4581 4582 4583 4584 4585 4586 4587 4588 4589 4590 4591 4592 4593 4594 4595 4596 4597 4598 4599 4600 4601 4602 4603 4604 4605 4606 4607 4608 4609 4610 4611 4612 4613 4614 4615 4616 4617 4618 4619 4620 4621 4622 4623 4624 4625 4626 4627 4628 4629 4630 4631 4632 4633 4634 4635 4636 4637 4638 4639 4640 4641 4642 4643 4644 4645 4646 4647 4648 4649 4650 4651 4652 4653 4654 4655 4656 4657 4658 4659 4660 4661 4662 4663 4664 4665 4666 4667 4668 4669 4670 4671 4672 4673 4674 4675 4676 4677 4678 4679 4680 4681 4682 4683 4684 4685 4686 4687 4688 4689 4690 4691 4692 4693 4694 4695 4696 4697 4698 4699 4700 4701 4702 4703 4704 4705 4706 4707 4708 4709 4710 4711 4712 4713 4714 4715 4716 4717 4718 4719 4720 4721 4722 4723 4724 4725 4726 4727 4728 4729 4730 4731 4732 4733 4734 4735 4736 4737 4738 4739 4740 4741 4742 4743 4744 4745 4746 4747 4748 4749 4750 4751 4752 4753 4754 4755 4756 4757 4758 4759 4760 4761 4762 4763 4764 4765 4766 4767 4768 4769 4770 4771 4772 4773 4774 4775 4776 4777 4778 4779 4780 4781 4782 4783 4784 4785 4786 4787 4788 4789 4790 4791 4792 4793 4794 4795 4796 4797 4798 4799 4800 4801 4802 4803 4804 4805 4806 4807 4808 4809 4810 4811 4812 4813 4814 4815 4816 4817 4818 4819 4820 4821 4822 4823 4824 4825 4826 4827 4828 4829 4830 4831 4832 4833 4834 4835 4836 4837 4838 4839 4840 4841 4842 4843 4844 4845 4846 4847 4848 4849 4850 4851 4852 4853 4854 4855 4856 4857 4858 4859 4860 4861 4862 4863 4864 4865 4866 4867 4868 4869 4870 4871 4872 4873 4874 4875 4876 4877 4878 4879 4880 4881 4882 4883 4884 4885 4886 4887 4888 4889 4890 4891 4892 4893 4894 4895 4896 4897 4898 4899 4900 4901 4902 4903 4904 4905 4906 4907 4908 4909 4910 4911 4912 4913 4914 4915 4916 4917 4918 4919 4920 4921 4922 4923 4924 4925 4926 4927 4928 4929 4930 4931 4932 4933 4934 4935 4936 4937 4938 4939 4940 4941 4942 4943 4944 4945 4946 4947 4948 4949 4950 4951 4952 4953 4954 4955 4956 4957 4958 4959 4960 4961 4962 4963 4964 4965 4966 4967 4968 4969 4970 4971 4972 4973 4974 4975 4976 4977 4978 4979 4980 4981 4982 4983 4984 4985 4986 4987 4988 4989 4990 4991 4992 4993 4994 4995 4996 4997 4998 4999 5000 5001 5002 5003 5004 5005 5006 5007 5008 5009 5010 5011 5012 5013 5014 5015 5016 5017 5018 5019 5020 5021 5022 5023 5024 5025 5026 5027 5028 5029 5030 5031 5032 5033 5034 5035 5036 5037 5038 5039 5040 5041 5042 5043 5044 5045 5046 5047 5048 5049 5050 5051 5052 5053 5054 5055 5056 5057 5058 5059 5060 5061 5062 5063 5064 5065 5066 5067 5068 5069 5070 5071 5072 5073 5074 5075 5076 5077 5078 5079 5080 5081 5082 5083 5084 5085 5086 5087 5088 5089 5090 5091 5092 5093 5094 5095 5096 5097 5098 5099 5100 5101 5102 5103 5104 5105 5106 5107 5108 5109 5110 5111 5112 5113 5114 5115 5116 5117 5118 5119 5120 5121 5122 5123 5124 5125 5126 5127 5128 5129 5130 5131 5132 5133 5134 5135 5136 5137 5138 5139 5140 5141 5142 5143 5144 5145 5146 5147 5148 5149 5150 5151 5152 5153 5154 5155 5156 5157 5158 5159 5160 5161 5162 5163 5164 5165 5166 5167 5168 5169 5170 5171 5172 5173 5174 5175 5176 5177 5178 5179 5180 5181 5182 5183 5184 5185 5186 5187 5188 5189 5190 5191 5192 5193 5194 5195 5196 5197 5198 5199 5200 5201 5202 5203 5204 5205 5206 5207 5208 5209 5210 5211 5212 5213 5214 5215 5216 5217 5218 5219 5220 5221 5222 5223 5224 5225 5226 5227 5228 5229 5230 5231 5232 5233 5234 5235 5236 5237 5238 5239 5240 5241 5242 5243 5244 5245 5246 5247 5248 5249 5250 5251 5252 5253 5254 5255 5256 5257 5258 5259 5260 5261 5262 5263 5264 5265 5266 5267 5268 5269 5270 5271 5272 5273 5274 5275 5276 5277 5278 5279 5280 5281 5282 5283 5284 5285 5286 5287 5288 5289 5290 5291 5292 5293 5294 5295 5296 5297 5298 5299 5300 5301 5302 5303 5304 5305 5306 5307 5308 5309 5310 5311 5312 5313 5314 5315 5316 5317 5318 5319 5320 5321 5322 5323 5324 5325 5326 5327 5328 5329 5330 5331 5332 5333 5334 5335 5336 5337 5338 5339 5340 5341 5342 5343 5344 5345 5346 5347 5348 5349 5350 5351 5352 5353 5354 5355 5356 5357 5358 5359 5360 5361 5362 5363 5364 5365 5366 5367 5368 5369 5370 5371 5372 5373 5374 5375 5376 5377 5378 5379 5380 5381 5382 5383 5384 5385 5386 5387 5388 5389 5390 5391 5392 5393 5394 5395 5396 5397 5398 5399 5400 5401 5402 5403 5404 5405 5406 5407 5408 5409 5410 5411 5412 5413 5414 5415 5416 5417 5418 5419 5420 5421 5422 5423 5424 5425 5426 5427 5428 5429 5430 5431 5432 5433 5434 5435 5436 5437 5438 5439 5440 5441 5442 5443 5444 5445 5446 5447 5448 5449 5450 5451 5452 5453 5454 5455 5456 5457 5458 5459 5460 5461 5462 5463 5464 5465 5466 5467 5468 5469 5470 5471 5472 5473 5474 5475 5476 5477 5478 5479 5480 5481 5482 5483 5484 5485 5486 5487 5488 5489 5490 5491 5492 5493 5494 5495 5496 5497 5498 5499 5500 5501 5502 5503 5504 5505 5506 5507 5508 5509 5510 5511 5512 5513 5514 5515 5516 5517 5518 5519 5520 5521 5522 5523 5524 5525 5526 5527 5528 5529 5530 5531 5532 5533 5534 5535 5536 5537 5538 5539 5540 5541 5542 5543 5544 5545 5546 5547 5548 5549 5550 5551 5552 5553 5554 5555 5556 5557 5558 5559 5560 5561 5562 5563 5564 5565 5566 5567 5568 5569 5570 5571 5572 5573 5574 5575 5576 5577 5578 5579 5580 5581 5582 5583 5584 5585 5586 5587 5588 5589 5590 5591 5592 5593 5594 5595 5596 5597 5598 5599 5600 5601 5602 5603 5604 5605 5606 5607 5608 5609 5610 5611 5612 5613 5614 5615 5616 5617 5618 5619 5620 5621 5622 5623 5624 5625 5626 5627 5628 5629 5630 5631 5632 5633 5634 5635 5636 5637 5638 5639 5640 5641 5642 5643 5644 5645 5646 5647 5648 5649 5650 5651 5652 5653 5654 5655 5656 5657 5658 5659 5660 5661 5662 5663 5664 5665 5666 5667 5668 5669 5670 5671 5672 5673 5674 5675 5676 5677 5678 5679 5680 5681 5682 5683 5684 5685 5686 5687 5688 5689 5690 5691 5692 5693 5694 5695 5696 5697 5698 5699 5700 5701 5702 5703 5704 5705 5706 5707 5708 5709 5710 5711 5712 5713 5714 5715 5716 5717 5718 5719 5720 5721 5722 5723 5724 5725 5726 5727 5728 5729 5730 5731 5732 5733 5734 5735 5736 5737 5738 5739 5740 5741 5742 5743 5744 5745 5746 5747 5748 5749 5750 5751 5752 5753 5754 5755 5756 5757 5758 5759 5760 5761 5762 5763 5764 5765 5766 5767 5768 5769 5770 5771 5772 5773 5774 5775 5776 5777 5778 5779 5780 5781 5782 5783 5784 5785 5786 5787 5788 5789 5790 5791 5792 5793 5794 5795 5796 5797 5798 5799 5800 5801 5802 5803 5804 5805 5806 5807 5808 5809 5810 5811 5812 5813 5814 5815 5816 5817 5818 5819 5820 5821 5822 5823 5824 5825 5826 5827 5828 5829 5830 5831 5832 5833 5834 5835 5836 5837 5838 5839 5840 5841 5842 5843 5844 5845 5846 5847 5848 5849 5850 5851 5852 5853 5854 5855 5856 5857 5858 5859 5860 5861 5862 5863 5864 5865 5866 5867 5868 5869 5870 5871 5872 5873 5874 5875 5876 5877 5878 5879 5880 5881 5882 5883 5884 5885 5886 5887 5888 5889 5890 5891 5892 5893 5894 5895 5896 5897 5898 5899 5900 5901 5902 5903 5904 5905 5906 5907 5908 5909 5910 5911 5912 5913 5914 5915 5916 5917 5918 5919 5920 5921 5922 5923 5924 5925 5926 5927 5928 5929 5930 5931 5932 5933 5934 5935 5936 5937 5938 5939 5940 5941 5942 5943 5944 5945 5946 5947 5948 5949 5950 5951 5952 5953 5954 5955 5956 5957 5958 5959 5960 5961 5962 5963 5964 5965 5966 5967 5968 5969 5970 5971 5972 5973 5974 5975 5976 5977 5978 5979 5980 5981 5982 5983 5984 5985 5986 5987 5988 5989 5990 5991 5992 5993 5994 5995 5996 5997 5998 5999 6000 6001 6002 6003 6004 6005 6006 6007 6008 6009 6010 6011 6012 6013 6014 6015 6016 6017 6018 6019 6020 6021 6022 6023 6024 6025 6026 6027 6028 6029 6030 6031 6032 6033 6034 6035 6036 6037 6038 6039 6040 6041 6042 6043 6044 6045 6046 6047 6048 6049 6050 6051 6052 6053 6054 6055 6056 6057 6058 6059 6060 6061 6062 6063 6064 6065 6066 6067 6068 6069 6070 6071 6072 6073 6074 6075 6076 6077 6078 6079 6080 6081 6082 6083 6084 6085 6086 6087 6088 6089 6090 6091 6092 6093 6094 6095 6096 6097 6098 6099 6100 6101 6102 6103 6104 6105 6106 6107 6108 6109 6110 6111 6112 6113 6114 6115 6116 6117 6118 6119 6120 6121 6122 6123 6124 6125 6126 6127 6128 6129 6130 6131 6132 6133 6134 6135 6136 6137 6138 6139 6140 6141 6142 6143 6144 6145 6146 6147 6148 6149 6150 6151 6152 6153 6154 6155 6156 6157 6158 6159 6160 6161 6162 6163 6164 6165 6166 6167 6168 6169 6170 6171 6172 6173 6174 6175 6176 6177 6178 6179 6180 6181 6182 6183 6184 6185 6186 6187 6188 6189 6190 6191 6192 6193 6194 6195 6196 6197 6198 6199 6200 6201 6202 6203 6204 6205 6206 6207 6208 6209 6210 6211 6212 6213 6214 6215 6216 6217 6218 6219 6220 6221 6222 6223 6224 6225 6226 6227 6228 6229 6230 6231 6232 6233 6234 6235 6236 6237 6238 6239 6240 6241 6242 6243 6244 6245 6246 6247 6248 6249 6250 6251 6252 6253 6254 6255 6256 6257 6258 6259 6260 6261 6262 6263 6264 6265 6266 6267 6268 6269 6270 6271 6272 6273 6274 6275 6276 6277 6278 6279 6280 6281 6282 6283 6284 6285 6286 6287 6288 6289 6290 6291 6292 6293 6294 6295 6296 6297 6298 6299 6300 6301 6302 6303 6304 6305 6306 6307 6308 6309 6310 6311 6312 6313 6314 6315 6316 6317 6318 6319 6320 6321 6322 6323 6324 6325 6326 6327 6328 6329 6330 6331 6332 6333 6334 6335 6336 6337 6338 6339 6340 6341 6342 6343 6344 6345 6346 6347 6348 6349 6350 6351 6352 6353 6354 6355 6356 6357 6358 6359 6360 6361 6362 6363 6364 6365 6366 6367 6368 6369 6370 6371 6372 6373 6374 6375 6376 6377 6378 6379 6380 6381 6382 6383 6384 6385 6386 6387 6388 6389 6390 6391 6392 6393 6394 6395 6396 6397 6398 6399 6400 6401 6402 6403 6404 6405 6406 6407 6408 6409 6410 6411 6412 6413 6414 6415 6416 6417 6418 6419 6420 6421 6422 6423 6424 6425 6426 6427 6428 6429 6430 6431 6432 6433 6434 6435 6436 6437 6438 6439 6440 6441 6442 6443 6444 6445 6446 6447 6448 6449 6450 6451 6452 6453 6454 6455 6456 6457 6458 6459 6460 6461 6462 6463 6464 6465 6466 6467 6468 6469 6470 6471 6472 6473 6474 6475 6476 6477 6478 6479 6480 6481 6482 6483 6484 6485 6486 6487 6488 6489 6490 6491 6492 6493 6494 6495 6496 6497 6498 6499 6500 6501 6502 6503 6504 6505 6506 6507 6508 6509 6510 6511 6512 6513 6514 6515 6516 6517 6518 6519 6520 6521 6522 6523 6524 6525 6526 6527 6528 6529 6530 6531 6532 6533 6534 6535 6536 6537 6538 6539 6540 6541 6542 6543 6544 6545 6546 6547 6548 6549 6550 6551 6552 6553 6554 6555 6556 6557 6558 6559 6560 6561 6562 6563 6564 6565 6566 6567 6568 6569 6570 6571 6572 6573 6574 6575 6576 6577 6578 6579 6580 6581 6582 6583 6584 6585 6586 6587 6588 6589 6590 6591 6592 6593 6594 6595 6596 6597 6598 6599 6600 6601 6602 6603 6604 6605 6606 6607 6608 6609 6610 6611 6612 6613 6614 6615 6616 6617 6618 6619 6620 6621 6622 6623 6624 6625 6626 6627 6628 6629 6630 6631 6632 6633 6634 6635 6636 6637 6638 6639 6640 6641 6642 6643 6644 6645 6646 6647 6648 6649 6650 6651 6652 6653 6654 6655 6656 6657 6658 6659 6660 6661 6662 6663 6664 6665 6666 6667 6668 6669 6670 6671 6672 6673 6674 6675 6676 6677 6678 6679 6680 6681 6682 6683 6684 6685 6686 6687 6688 6689 6690 6691 6692 6693 6694 6695 6696 6697 6698 6699 6700 6701 6702 6703 6704 6705 6706 6707 6708 6709 6710 6711 6712 6713 6714 6715 6716 6717 6718 6719 6720 6721 6722 6723 6724 6725 6726 6727 6728 6729 6730 6731 6732 6733 6734 6735 6736 6737 6738 6739 6740 6741 6742 6743 6744 6745 6746 6747 6748 6749 6750 6751 6752 6753 6754 6755 6756 6757 6758 6759 6760 6761 6762 6763 6764 6765 6766 6767 6768 6769 6770 6771 6772 6773 6774 6775 6776 6777 6778 6779 6780 6781 6782 6783 6784 6785 6786 6787 6788 6789 6790 6791 6792 6793 6794 6795 6796 6797 6798 6799 6800 6801 6802 6803 6804 6805 6806 6807 6808 6809 6810 6811 6812 6813 6814 6815 6816 6817 6818 6819 6820 6821 6822 6823 6824 6825 6826 6827 6828 6829 6830 6831 6832 6833 6834 6835 6836 6837 6838 6839 6840 6841 6842 6843 6844 6845 6846 6847 6848 6849 6850 6851 6852 6853 6854 6855 6856 6857 6858 6859 6860 6861 6862 6863 6864 6865 6866 6867 6868 6869 6870 6871 6872 6873 6874 6875 6876 6877 6878 6879 6880 6881 6882 6883 6884 6885 6886 6887 6888 6889 6890 6891 6892 6893 6894 6895 6896 6897 6898 6899 6900 6901 6902 6903 6904 6905 6906 6907 6908 6909 6910 6911 6912 6913 6914 6915 6916 6917 6918 6919 6920 6921 6922 6923 6924 6925 6926 6927 6928 6929 6930 6931 6932 6933 6934 6935 6936 6937 6938 6939 6940 6941 6942 6943 6944 6945 6946 6947 6948 6949 6950 6951 6952 6953 6954 6955 6956 6957 6958 6959 6960 6961 6962 6963 6964 6965 6966 6967 6968 6969 6970 6971 6972 6973 6974 6975 6976 6977 6978 6979 6980 6981 6982 6983 6984 6985 6986 6987 6988 6989 6990 6991 6992 6993 6994 6995 6996 6997 6998 6999 7000 7001 7002 7003 7004 7005 7006 7007 7008 7009 7010 7011 7012 7013 7014 7015 7016 7017 7018 7019 7020 7021 7022 7023 7024 7025 7026 7027 7028 7029 7030 7031 7032 7033 7034 7035 7036 7037 7038 7039 7040 7041 7042 7043 7044 7045 7046 7047 7048 7049 7050 7051 7052 7053 7054 7055 7056 7057 7058 7059 7060 7061 7062 7063 7064 7065 7066 7067 7068 7069 7070 7071 7072 7073 7074 7075 7076 7077 7078 7079 7080 7081 7082 7083 7084 7085 7086 7087 7088 7089 7090 7091 7092 7093 7094 7095 7096 7097 7098 7099 7100 7101 7102 7103 7104 7105 7106 7107 7108 7109 7110 7111 7112 7113 7114 7115 7116 7117 7118 7119 7120 7121 7122 7123 7124 7125 7126 7127 7128 7129 7130 7131 7132 7133 7134 7135 7136 7137 7138 7139 7140 7141 7142 7143 7144 7145 7146 7147 7148 7149 7150 7151 7152 7153 7154 7155 7156 7157 7158 7159 7160 7161 7162 7163 7164 7165 7166 7167 7168 7169 7170 7171 7172 7173 7174 7175 7176 7177 7178 7179 7180 7181 7182 7183 7184 7185 7186 7187 7188 7189 7190 7191 7192 7193 7194 7195 7196 7197 7198 7199 7200 7201 7202 7203 7204 7205 7206 7207 7208 7209 7210 7211 7212 7213 7214 7215 7216 7217 7218 7219 7220 7221 7222 7223 7224 7225 7226 7227 7228 7229 7230 7231 7232 7233 7234 7235 7236 7237 7238 7239 7240 7241 7242 7243 7244 7245 7246 7247 7248 7249 7250 7251 7252 7253 7254 7255 7256 7257 7258 7259 7260 7261 7262 7263 7264 7265 7266 7267 7268 7269 7270 7271 7272 7273 7274 7275 7276 7277 7278 7279 7280 7281 7282 7283 7284 7285 7286 7287 7288 7289 7290 7291 7292 7293 7294 7295 7296 7297 7298 7299 7300 7301 7302 7303 7304 7305 7306 7307 7308 7309 7310 7311 7312 7313 7314 7315 7316 7317 7318 7319 7320 7321 7322 7323 7324 7325 7326 7327 7328 7329 7330 7331 7332 7333 7334 7335 7336 7337 7338 7339 7340 7341 7342 7343 7344 7345 7346 7347 7348 7349 7350 7351 7352 7353 7354 7355 7356 7357 7358 7359 7360 7361 7362 7363 7364 7365 7366 7367 7368 7369 7370 7371 7372 7373 7374 7375 7376 7377 7378 7379 7380 7381 7382 7383 7384 7385 7386 7387 7388 7389 7390 7391 7392 7393 7394 7395 7396 7397 7398 7399 7400 7401 7402 7403 7404 7405 7406 7407 7408 7409 7410 7411 7412 7413 7414 7415 7416 7417 7418 7419 7420 7421 7422 7423 7424 7425 7426 7427 7428 7429 7430 7431 7432 7433 7434 7435 7436 7437 7438 7439 7440 7441 7442 7443 7444 7445 7446 7447 7448 7449 7450 7451 7452 7453 7454 7455 7456 7457 7458 7459 7460 7461 7462 7463 7464 7465 7466 7467 7468 7469 7470 7471 7472 7473 7474 7475 7476 7477 7478 7479 7480 7481 7482 7483 7484 7485 7486 7487 7488 7489 7490 7491 7492 7493 7494 7495 7496 7497 7498 7499 7500 7501 7502 7503 7504 7505 7506 7507 7508 7509 7510 7511 7512 7513 7514 7515 7516 7517 7518 7519 7520 7521 7522 7523 7524 7525 7526 7527 7528 7529 7530 7531 7532 7533 7534 7535 7536 7537 7538 7539 7540 7541 7542 7543 7544 7545 7546 7547 7548 7549 7550 7551 7552 7553 7554 7555 7556 7557 7558 7559 7560 7561 7562 7563 7564 7565 7566 7567 7568 7569 7570 7571 7572 7573 7574 7575 7576 7577 7578 7579 7580 7581 7582 7583 7584 7585 7586 7587 7588 7589 7590 7591 7592 7593 7594 7595 7596 7597 7598 7599 7600 7601 7602 7603 7604 7605 7606 7607 7608 7609 7610 7611 7612 7613 7614 7615 7616 7617 7618 7619 7620 7621 7622 7623 7624 7625 7626 7627 7628 7629 7630 7631 7632 7633 7634 7635 7636 7637 7638 7639 7640 7641 7642 7643 7644 7645 7646 7647 7648 7649 7650 7651 7652 7653 7654 7655 7656 7657 7658 7659 7660 7661 7662 7663 7664 7665 7666 7667 7668 7669 7670 7671 7672 7673 7674 7675 7676 7677 7678 7679 7680 7681 7682 7683 7684 7685 7686 7687 7688 7689 7690 7691 7692 7693 7694 7695 7696 7697 7698 7699 7700 7701 7702 7703 7704 7705 7706 7707 7708 7709 7710 7711 7712 7713 7714 7715 7716 7717 7718 7719 7720 7721 7722 7723 7724 7725 7726 7727 7728 7729 7730 7731 7732 7733 7734 7735 7736 7737 7738 7739 7740 7741 7742 7743 7744 7745 7746 7747 7748 7749 7750 7751 7752 7753 7754 7755 7756 7757 7758 7759 7760 7761 7762 7763 7764 7765 7766 7767 7768 7769 7770 7771 7772 7773 7774 7775 7776 7777 7778 7779 7780 7781 7782 7783 7784 7785 7786 7787 7788 7789 7790 7791 7792 7793 7794 7795 7796 7797 7798 7799 7800 7801 7802 7803 7804 7805 7806 7807 7808 7809 7810 7811 7812 7813 7814 7815 7816 7817 7818 7819 7820 7821 7822 7823 7824 7825 7826 7827 7828 7829 7830 7831 7832 7833 7834 7835 7836 7837 7838 7839 7840 7841 7842 7843 7844 7845 7846 7847 7848 7849 7850 7851 7852 7853 7854 7855 7856 7857 7858 7859 7860 7861 7862 7863 7864 7865 7866 7867 7868 7869 7870 7871 7872 7873 7874 7875 7876 7877 7878 7879 7880 7881 7882 7883 7884 7885 7886 7887 7888 7889 7890 7891 7892 7893 7894 7895 7896 7897 7898 7899 7900 7901 7902 7903 7904 7905 7906 7907 7908 7909 7910 7911 7912 7913 7914 7915 7916 7917 7918 7919 7920 7921 7922 7923 7924 7925 7926 7927 7928 7929 7930 7931 7932 7933 7934 7935 7936 7937 7938 7939 7940 7941 7942 7943 7944 7945 7946 7947 7948 7949 7950 7951 7952 7953 7954 7955 7956 7957 7958 7959 7960 7961 7962 7963 7964 7965 7966 7967 7968 7969 7970 7971 7972 7973 7974 7975 7976 7977 7978 7979 7980 7981 7982 7983 7984 7985 7986 7987 7988 7989 7990 7991 7992 7993 7994 7995 7996 7997 7998 7999 8000 8001 8002 8003 8004 8005 8006 8007 8008 8009 8010 8011 8012 8013 8014 8015 8016 8017 8018 8019 8020 8021 8022 8023 8024 8025 8026 8027 8028 8029 8030 8031 8032 8033 8034 8035 8036 8037 8038 8039 8040 8041 8042 8043 8044 8045 8046 8047 8048 8049 8050 8051 8052 8053 8054 8055 8056 8057 8058 8059 8060 8061 8062 8063 8064 8065 8066 8067 8068 8069 8070 8071 8072 8073 8074 8075 8076 8077 8078 8079 8080 8081 8082 8083 8084 8085 8086 8087 8088 8089 8090 8091 8092 8093 8094 8095 8096 8097 8098 8099 8100 8101 8102 8103 8104 8105 8106 8107 8108 8109 8110 8111 8112 8113 8114 8115 8116 8117 8118 8119 8120 8121 8122 8123 8124 8125 8126 8127 8128 8129 8130 8131 8132 8133 8134 8135 8136 8137 8138 8139 8140 8141 8142 8143 8144 8145 8146 8147 8148 8149 8150 8151 8152 8153 8154 8155 8156 8157 8158 8159 8160 8161 8162 8163 8164 8165 8166 8167 8168 8169 8170 8171 8172 8173 8174 8175 8176 8177 8178 8179 8180 8181 8182 8183 8184 8185 8186 8187 8188 8189 8190 8191 8192 8193 8194 8195 8196 8197 8198 8199 8200 8201 8202 8203 8204 8205 8206 8207 8208 8209 8210 8211 8212 8213 8214 8215 8216 8217 8218 8219 8220 8221 8222 8223 8224 8225 8226 8227 8228 8229 8230 8231 8232 8233 8234 8235 8236 8237 8238 8239 8240 8241 8242 8243 8244 8245 8246 8247 8248 8249 8250 8251 8252 8253 8254 8255 8256 8257 8258 8259 8260 8261 8262 8263 8264 8265 8266 8267 8268 8269 8270 8271 8272 8273 8274 8275 8276 8277 8278 8279 8280 8281 8282 8283 8284 8285 8286 8287 8288 8289 8290 8291 8292 8293 8294 8295 8296 8297 8298 8299 8300 8301 8302 8303 8304 8305 8306 8307 8308 8309 8310 8311 8312 8313 8314 8315 8316 8317 8318 8319 8320 8321 8322 8323 8324 8325 8326 8327 8328 8329 8330 8331 8332 8333 8334 8335 8336 8337 8338 8339 8340 8341 8342 8343 8344 8345 8346 8347 8348 8349 8350 8351 8352 8353 8354 8355 8356 8357 8358 8359 8360 8361 8362 8363 8364 8365 8366 8367 8368 8369 8370 8371 8372 8373 8374 8375 8376 8377 8378 8379 8380 8381 8382 8383 8384 8385 8386 8387 8388 8389 8390 8391 8392 8393 8394 8395 8396 8397 8398 8399 8400 8401 8402 8403 8404 8405 8406 8407 8408 8409 8410 8411 8412 8413 8414 8415 8416 8417 8418 8419 8420 8421 8422 8423 8424 8425 8426 8427 8428 8429 8430 8431 8432 8433 8434 8435 8436 8437 8438 8439 8440 8441 8442 8443 8444 8445 8446 8447 8448 8449 8450 8451 8452 8453 8454 8455 8456 8457 8458 8459 8460 8461 8462 8463 8464 8465 8466 8467 8468 8469 8470 8471 8472 8473 8474 8475 8476 8477 8478 8479 8480 8481 8482 8483 8484 8485 8486 8487 8488 8489 8490 8491 8492 8493 8494 8495 8496 8497 8498 8499 8500 8501 8502 8503 8504 8505 8506 8507 8508 8509 8510 8511 8512 8513 8514 8515 8516 8517 8518 8519 8520 8521 8522 8523 8524 8525 8526 8527 8528 8529 8530 8531 8532 8533 8534 8535 8536 8537 8538 8539 8540 8541 8542 8543 8544 8545 8546 8547 8548 8549 8550 8551 8552 8553 8554 8555 8556 8557 8558 8559 8560 8561 8562 8563 8564 8565 8566 8567 8568 8569 8570 8571 8572 8573 8574 8575 8576 8577 8578 8579 8580 8581 8582 8583 8584 8585 8586 8587 8588 8589 8590 8591 8592 8593 8594 8595 8596 8597 8598 8599 8600 8601 8602 8603 8604 8605 8606 8607 8608 8609 8610 8611 8612 8613 8614 8615 8616 8617 8618 8619 8620 8621 8622 8623 8624 8625 8626 8627 8628 8629 8630 8631 8632 8633 8634 8635 8636 8637 8638 8639 8640 8641 8642 8643 8644 8645 8646 8647 8648 8649 8650 8651 8652 8653 8654 8655 8656 8657 8658 8659 8660 8661 8662 8663 8664 8665 8666 8667 8668 8669 8670 8671 8672 8673 8674 8675 8676 8677 8678 8679 8680 8681 8682 8683 8684 8685 8686 8687 8688 8689 8690 8691 8692 8693 8694 8695 8696 8697 8698 8699 8700 8701 8702 8703 8704 8705 8706 8707 8708 8709 8710 8711 8712 8713 8714 8715 8716 8717 8718 8719 8720 8721 8722 8723 8724 8725 8726 8727 8728 8729 8730 8731 8732 8733 8734 8735 8736 8737 8738 8739 8740 8741 8742 8743 8744 8745 8746 8747 8748 8749 8750 8751 8752 8753 8754 8755 8756 8757 8758 8759 8760 8761 8762 8763 8764 8765 8766 8767 8768 8769 8770 8771 8772 8773 8774 8775 8776 8777 8778 8779 8780 8781 8782 8783 8784 8785 8786 8787 8788 8789 8790 8791 8792 8793 8794 8795 8796 8797 8798 8799 8800 8801 8802 8803 8804 8805 8806 8807 8808 8809 8810 8811 8812 8813 8814 8815 8816 8817 8818 8819 8820 8821 8822 8823 8824 8825 8826 8827 8828 8829 8830 8831 8832 8833 8834 8835 8836 8837 8838 8839 8840 8841 8842 8843 8844 8845 8846 8847 8848 8849 8850 8851 8852 8853 8854 8855 8856 8857 8858 8859 8860 8861 8862 8863 8864 8865 8866 8867 8868 8869 8870 8871 8872 8873 8874 8875 8876 8877 8878 8879 8880 8881 8882 8883 8884 8885 8886 8887 8888 8889 8890 8891 8892 8893 8894 8895 8896 8897 8898 8899 8900 8901 8902 8903 8904 8905 8906 8907 8908 8909 8910 8911 8912 8913 8914 8915 8916 8917 8918 8919 8920 8921 8922 8923 8924 8925 8926 8927 8928 8929 8930 8931 8932 8933 8934 8935 8936 8937 8938 8939 8940 8941 8942 8943 8944 8945 8946 8947 8948 8949 8950 8951 8952 8953 8954 8955 8956 8957 8958 8959 8960 8961 8962 8963 8964 8965 8966 8967 8968 8969 8970 8971 8972 8973 8974 8975 8976 8977 8978 8979 8980 8981 8982 8983 8984 8985 8986 8987 8988 8989 8990 8991 8992 8993 8994 8995 8996 8997 8998 8999 9000 9001 9002 9003 9004 9005 9006 9007 9008 9009 9010 9011 9012 9013 9014 9015 9016 9017 9018 9019 9020 9021 9022 9023 9024 9025 9026 9027 9028 9029 9030 9031 9032 9033 9034 9035 9036 9037 9038 9039 9040 9041 9042 9043 9044 9045 9046 9047 9048 9049 9050 9051 9052 9053 9054 9055 9056 9057 9058 9059 9060 9061 9062 9063 9064 9065 9066 9067 9068 9069 9070 9071 9072 9073 9074 9075 9076 9077 9078 9079 9080 9081 9082 9083 9084 9085 9086 9087 9088 9089 9090 9091 9092 9093 9094 9095 9096 9097 9098 9099 9100 9101 9102 9103 9104 9105 9106 9107 9108 9109 9110 9111 9112 9113 9114 9115 9116 9117 9118 9119 9120 9121 9122 9123 9124 9125 9126 9127 9128 9129 9130 9131 9132 9133 9134 9135 9136 9137 9138 9139 9140 9141 9142 9143 9144 9145 9146 9147 9148 9149 9150 9151 9152 9153 9154 9155 9156 9157 9158 9159 9160 9161 9162 9163 9164 9165 9166 9167 9168 9169 9170 9171 9172 9173 9174 9175 9176 9177 9178 9179 9180 9181 9182 9183 9184 9185 9186 9187 9188 9189 9190 9191 9192 9193 9194 9195 9196 9197 9198 9199 9200 9201 9202 9203 9204 9205 9206 9207 9208 9209 9210 9211 9212 9213 9214 9215 9216 9217 9218 9219 9220 9221 9222 9223 9224 9225 9226 9227 9228 9229 9230 9231 9232 9233 9234 9235 9236 9237 9238 9239 9240 9241 9242 9243 9244 9245 9246 9247 9248 9249 9250 9251 9252 9253 9254 9255 9256 9257 9258 9259 9260 9261 9262 9263 9264 9265 9266 9267 9268 9269 9270 9271 9272 9273 9274 9275 9276 9277 9278 9279 9280 9281 9282 9283 9284 9285 9286 9287 9288 9289 9290 9291 9292 9293 9294 9295 9296 9297 9298 9299 9300 9301 9302 9303 9304 9305 9306 9307 9308 9309 9310 9311 9312 9313 9314 9315 9316 9317 9318 9319 9320 9321 9322 9323 9324 9325 9326 9327 9328 9329 9330 9331 9332 9333 9334 9335 9336 9337 9338 9339 9340 9341 9342 9343 9344 9345 9346 9347 9348 9349 9350 9351 9352 9353 9354 9355 9356 9357 9358 9359 9360 9361 9362 9363 9364 9365 9366 9367 9368 9369 9370 9371 9372 9373 9374 9375 9376 9377 9378 9379 9380 9381 9382 9383 9384 9385 9386 9387 9388 9389 9390 9391 9392 9393 9394 9395 9396 9397 9398 9399 9400 9401 9402 9403 9404 9405 9406 9407 9408 9409 9410 9411 9412 9413 9414 9415 9416 9417 9418 9419 9420 9421 9422 9423 9424 9425 9426 9427 9428 9429 9430 9431 9432 9433 9434 9435 9436 9437 9438 9439 9440 9441 9442 9443 9444 9445 9446 9447 9448 9449 9450 9451 9452 9453 9454 9455 9456 9457 9458 9459 9460 9461 9462 9463 9464 9465 9466 9467 9468 9469 9470 9471 9472 9473 9474 9475 9476 9477 9478 9479 9480 9481 9482 9483 9484 9485 9486 9487 9488 9489 9490 9491 9492 9493 9494 9495 9496 9497 9498 9499 9500 9501 9502 9503 9504 9505 9506 9507 9508 9509 9510 9511 9512 9513 9514 9515 9516 9517 9518 9519 9520 9521 9522 9523 9524 9525 9526 9527 9528 9529 9530 9531 9532 9533 9534 9535 9536 9537 9538 9539 9540 9541 9542 9543 9544 9545 9546 9547 9548 9549 9550 9551 9552 9553 9554 9555 9556 9557 9558 9559 9560 9561 9562 9563 9564 9565 9566 9567 9568 9569 9570 9571 9572 9573 9574 9575 9576 9577 9578 9579 9580 9581 9582 9583 9584 9585 9586 9587 9588 9589 9590 9591 9592 9593 9594 9595 9596 9597 9598 9599 9600 9601 9602 9603 9604 9605 9606 9607 9608 9609 9610 9611 9612 9613 9614 9615 9616 9617 9618 9619 9620 9621 9622 9623 9624 9625 9626 9627 9628 9629 9630 9631 9632 9633 9634 9635 9636 9637 9638 9639 9640 9641 9642 9643 9644 9645 9646 9647 9648 9649 9650 9651 9652 9653 9654 9655 9656 9657 9658 9659 9660 9661 9662 9663 9664 9665 9666 9667 9668 9669 9670 9671 9672 9673 9674 9675 9676 9677 9678 9679 9680 9681 9682 9683 9684 9685 9686 9687 9688 9689 9690 9691 9692 9693 9694 9695 9696 9697 9698 9699 9700 9701 9702 9703 9704 9705 9706 9707 9708 9709 9710 9711 9712 9713 9714 9715 9716 9717 9718 9719 9720 9721 9722 9723 9724 9725 9726 9727 9728 9729 9730 9731 9732 9733 9734 9735 9736 9737 9738 9739 9740 9741 9742 9743 9744 9745 9746 9747 9748 9749 9750 9751 9752 9753 9754 9755 9756 9757 9758 9759 9760 9761 9762 9763 9764 9765 9766 9767 9768 9769 9770 9771 9772 9773 9774 9775 9776 9777 9778 9779 9780 9781 9782 9783 9784 9785 9786 9787 9788 9789 9790 9791 9792 9793 9794 9795 9796 9797 9798 9799 9800 9801 9802 9803 9804 9805 9806 9807 9808 9809 9810 9811 9812 9813 9814 9815 9816 9817 9818 9819 9820 9821 9822 9823 9824 9825 9826 9827 9828 9829 9830 9831 9832 9833 9834 9835 9836 9837 9838 9839 9840 9841 9842 9843 9844 9845 9846 9847 9848 9849 9850 9851 9852 9853 9854 9855 9856 9857 9858 9859 9860 9861 9862 9863 9864 9865 9866 9867 9868 9869 9870 9871 9872 9873 9874 9875 9876 9877 9878 9879 9880 9881 9882 9883 9884 9885 9886 9887 9888 9889 9890 9891 9892 9893 9894 9895 9896 9897 9898 9899 9900 9901 9902 9903 9904 9905 9906 9907 9908 9909 9910 9911 9912 9913 9914 9915 9916 9917 9918 9919 9920 9921 9922 9923 9924 9925 9926 9927 9928 9929 9930 9931 9932 9933 9934 9935 9936 9937 9938 9939 9940 9941 9942 9943 9944 9945 9946 9947 9948 9949 9950 9951 9952 9953 9954 9955 9956 9957 9958 9959 9960 9961 9962 9963 9964 9965 9966 9967 9968 9969 9970 9971 9972 9973 9974 9975 9976 9977 9978 9979 9980 9981 9982 9983 9984 9985 9986 9987 9988 9989 9990 9991 9992 9993 9994 9995 9996 9997 9998 9999 10000 10001 10002 10003 10004 10005 10006 10007 10008 10009 10010 10011 10012 10013 10014 10015 10016 10017 10018 10019 10020 10021 10022 10023 10024 10025 10026 10027 10028 10029 10030 10031 10032 10033 10034 10035 10036 10037 10038 10039 10040 10041 10042 10043 10044 10045 10046 10047 10048 10049 10050 10051 10052 10053 10054 10055 10056 10057 10058 10059 10060 10061 10062 10063 10064 10065 10066 10067 10068 10069 10070 10071 10072 10073 10074 10075 10076 10077 10078 10079 10080 10081 10082 10083 10084 10085 10086 10087 10088 10089 10090 10091 10092 10093 10094 10095 10096 10097 10098 10099 10100 10101 10102 10103 10104 10105 10106 10107 10108 10109 10110 10111 10112 10113 10114 10115 10116 10117 10118 10119 10120 10121 10122 10123 10124 10125 10126 10127 10128 10129 10130 10131 10132 10133 10134 10135 10136 10137 10138 10139 10140 10141 10142 10143 10144 10145 10146 10147 10148 10149 10150 10151 10152 10153 10154 10155 10156 10157 10158 10159 10160 10161 10162 10163 10164 10165 10166 10167 10168 10169 10170 10171 10172 10173 10174 10175 10176 10177 10178 10179 10180 10181 10182 10183 10184 10185 10186 10187 10188 10189 10190 10191 10192 10193 10194 10195 10196 10197 10198 10199 10200 10201 10202 10203 10204 10205 10206 10207 10208 10209 10210 10211 10212 10213 10214 10215 10216 10217 10218 10219 10220 10221 10222 10223 10224 10225 10226 10227 10228 10229 10230 10231 10232 10233 10234 10235 10236 10237 10238 10239 10240 10241 10242 10243 10244 10245 10246 10247 10248 10249 10250 10251 10252 10253 10254 10255 10256 10257 10258 10259 10260 10261 10262 10263 10264 10265 10266 10267 10268 10269 10270 10271 10272 10273 10274 10275 10276 10277 10278 10279 10280 10281 10282 10283 10284 10285 10286 10287 10288 10289 10290 10291 10292 10293 10294 10295 10296 10297 10298 10299 10300 10301 10302 10303 10304 10305 10306 10307 10308 10309 10310 10311 10312 10313 10314 10315 10316 10317 10318 10319 10320 10321 10322 10323 10324 10325 10326 10327 10328 10329 10330 10331 10332 10333 10334 10335 10336 10337 10338 10339 10340 10341 10342 10343 10344 10345 10346 10347 10348 10349 10350 10351 10352 10353 10354 10355 10356 10357 10358 10359 10360 10361 10362 10363 10364 10365 10366 10367 10368 10369 10370 10371 10372 10373 10374 10375 10376 10377 10378 10379 10380 10381 10382 10383 10384 10385 10386 10387 10388 10389 10390 10391 10392 10393 10394 10395 10396 10397 10398 10399 10400 10401 10402 10403 10404 10405 10406 10407 10408 10409 10410 10411 10412 10413 10414 10415 10416 10417 10418 10419 10420 10421 10422 10423 10424 10425 10426 10427 10428 10429 10430 10431 10432 10433 10434 10435 10436 10437 10438 10439 10440 10441 10442 10443 10444 10445 10446 10447 10448 10449 10450 10451 10452 10453 10454 10455 10456 10457 10458 10459 10460 10461 10462 10463 10464 10465 10466 10467 10468 10469 10470 10471 10472 10473 10474 10475 10476 10477 10478 10479 10480 10481 10482 10483 10484 10485 10486 10487 10488 10489 10490 10491 10492 10493 10494 10495 10496 10497 10498 10499 10500 10501 10502 10503 10504 10505 10506 10507 10508 10509 10510 10511 10512 10513 10514 10515 10516 10517 10518 10519 10520 10521 10522 10523 10524 10525 10526 10527 10528 10529 10530 10531 10532 10533 10534 10535 10536 10537 10538 10539 10540 10541 10542 10543 10544 10545 10546 10547 10548 10549 10550 10551 10552 10553 10554 10555 10556 10557 10558 10559 10560 10561 10562 10563 10564 10565 10566 10567 10568 10569 10570 10571 10572 10573 10574 10575 10576 10577 10578 10579 10580 10581 10582 10583 10584 10585 10586 10587 10588 10589 10590 10591 10592 10593 10594 10595 10596 10597 10598 10599 10600 10601 10602 10603 10604 10605 10606 10607 10608 10609 10610 10611 10612 10613 10614 10615 10616 10617 10618 10619 10620 10621 10622 10623 10624 10625 10626 10627 10628 10629 10630 10631 10632 10633 10634 10635 10636 10637 10638 10639 10640 10641 10642 10643 10644 10645 10646 10647 10648 10649 10650 10651 10652 10653 10654 10655 10656 10657 10658 10659 10660 10661 10662 10663 10664 10665 10666 10667 10668 10669 10670 10671 10672 10673 10674 10675 10676 10677 10678 10679 10680 10681 10682 10683 10684 10685 10686 10687 10688 10689 10690 10691 10692 10693 10694 10695 10696 10697 10698 10699 10700 10701 10702 10703 10704 10705 10706 10707 10708 10709 10710 10711 10712 10713 10714 10715 10716 10717 10718 10719 10720 10721 10722 10723 10724 10725 10726 10727 10728 10729 10730 10731 10732 10733 10734 10735 10736 10737 10738 10739 10740 10741 10742 10743 10744 10745 10746 10747 10748 10749 10750 10751 10752 10753 10754 10755 10756 10757 10758 10759 10760 10761 10762 10763 10764 10765 10766 10767 10768 10769 10770 10771 10772 10773 10774 10775 10776 10777 10778 10779 10780 10781 10782 10783 10784 10785 10786 10787 10788 10789 10790 10791 10792 10793 10794 10795 10796 10797 10798 10799 10800 10801 10802 10803 10804 10805 10806 10807 10808 10809 10810 10811 10812 10813 10814 10815 10816 10817 10818 10819 10820 10821 10822 10823 10824 10825 10826 10827 10828 10829 10830 10831 10832 10833 10834 10835 10836 10837 10838 10839 10840 10841 10842 10843 10844 10845 10846 10847 10848 10849 10850 10851 10852 10853 10854 10855 10856 10857 10858 10859 10860 10861 10862 10863 10864 10865 10866 10867 10868 10869 10870 10871 10872 10873 10874 10875 10876 10877 10878 10879 10880 10881 10882 10883 10884 10885 10886 10887 10888 10889 10890 10891 10892 10893 10894 10895 10896 10897 10898 10899 10900 10901 10902 10903 10904 10905 10906 10907 10908 10909 10910 10911 10912 10913 10914 10915 10916 10917 10918 10919 10920 10921 10922 10923 10924 10925 10926 10927 10928 10929 10930 10931 10932 10933 10934 10935 10936 10937 10938 10939 10940 10941 10942 10943 10944 10945 10946 10947 10948 10949 10950 10951 10952 10953 10954 10955 10956 10957 10958 10959 10960 10961 10962 10963 10964 10965 10966 10967 10968 10969 10970 10971 10972 10973 10974 10975 10976 10977 10978 10979 10980 10981 10982 10983 10984 10985 10986 10987 10988 10989 10990 10991 10992 10993 10994 10995 10996 10997 10998 10999 11000 11001 11002 11003 11004 11005 11006 11007 11008 11009 11010 11011 11012 11013 11014 11015 11016 11017 11018 11019 11020 11021 11022 11023 11024 11025 11026 11027 11028 11029 11030 11031 11032 11033 11034 11035 11036 11037 11038 11039 11040 11041 11042 11043 11044 11045 11046 11047 11048 11049 11050 11051 11052 11053 11054 11055 11056 11057 11058 11059 11060 11061 11062 11063 11064 11065 11066 11067 11068 11069 11070 11071 11072 11073 11074 11075 11076 11077 11078 11079 11080 11081 11082 11083 11084 11085 11086 11087 11088 11089 11090 11091 11092 11093 11094 11095 11096 11097 11098 11099 11100 11101 11102 11103 11104 11105 11106 11107 11108 11109 11110 11111 11112 11113 11114 11115 11116 11117 11118 11119 11120 11121 11122 11123 11124 11125 11126 11127 11128 11129 11130 11131 11132 11133 11134 11135 11136 11137 11138 11139 11140 11141 11142 11143 11144 11145 11146 11147 11148 11149 11150 11151 11152 11153 11154 11155 11156 11157 11158 11159 11160 11161 11162 11163 11164 11165 11166 11167 11168 11169 11170 11171 11172 11173 11174 11175 11176 11177 11178 11179 11180 11181 11182 11183 11184 11185 11186 11187 11188 11189 11190 11191 11192 11193 11194 11195 11196 11197 11198 11199 11200 11201 11202 11203 11204 11205 11206 11207 11208 11209 11210 11211 11212 11213 11214 11215 11216 11217 11218 11219 11220 11221 11222 11223 11224 11225 11226 11227 11228 11229 11230 11231 11232 11233 11234 11235 11236 11237 11238 11239 11240 11241 11242 11243 11244 11245 11246 11247 11248 11249 11250 11251 11252 11253 11254 11255 11256 11257 11258 11259 11260 11261 11262 11263 11264 11265 11266 11267 11268 11269 11270 11271 11272 11273 11274 11275 11276 11277 11278 11279 11280 11281 11282 11283 11284 11285 11286 11287 11288 11289 11290 11291 11292 11293 11294 11295 11296 11297 11298 11299 11300 11301 11302 11303 11304 11305 11306 11307 11308 11309 11310 11311 11312 11313 11314 11315 11316 11317 11318 11319 11320 11321 11322 11323 11324 11325 11326 11327 11328 11329 11330 11331 11332 11333 11334 11335 11336 11337 11338 11339 11340 11341 11342 11343 11344 11345 11346 11347 11348 11349 11350 11351 11352 11353 11354 11355 11356 11357 11358 11359 11360 11361 11362 11363 11364 11365 11366 11367 11368 11369 11370 11371 11372 11373 11374 11375 11376 11377 11378 11379 11380 11381 11382 11383 11384 11385 11386 11387 11388 11389 11390 11391 11392 11393 11394 11395 11396 11397 11398 11399 11400 11401 11402 11403 11404 11405 11406 11407 11408 11409 11410 11411 11412 11413 11414 11415 11416 11417 11418 11419 11420 11421 11422 11423 11424 11425 11426 11427 11428 11429 11430 11431 11432 11433 11434 11435 11436 11437 11438 11439 11440 11441 11442 11443 11444 11445 11446 11447 11448 11449 11450 11451 11452 11453 11454 11455 11456 11457 11458 11459 11460 11461 11462 11463 11464 11465 11466 11467 11468 11469 11470 11471 11472 11473 11474 11475 11476 11477 11478 11479 11480 11481 11482 11483 11484 11485 11486 11487 11488 11489 11490 11491 11492 11493 11494 11495 11496 11497 11498 11499 11500 11501 11502 11503 11504 11505 11506 11507 11508 11509 11510 11511 11512 11513 11514 11515 11516 11517 11518 11519 11520 11521 11522 11523 11524 11525 11526 11527 11528 11529 11530 11531 11532 11533 11534 11535 11536 11537 11538 11539 11540 11541 11542 11543 11544 11545 11546 11547 11548 11549 11550 11551 11552 11553 11554 11555 11556 11557 11558 11559 11560 11561 11562 11563 11564 11565 11566 11567 11568 11569 11570 11571 11572 11573 11574 11575 11576 11577 11578 11579 11580 11581 11582 11583 11584 11585 11586 11587 11588 11589 11590 11591 11592 11593 11594 11595 11596 11597 11598 11599 11600 11601 11602 11603 11604 11605 11606 11607 11608 11609 11610 11611 11612 11613 11614 11615 11616 11617 11618 11619 11620 11621 11622 11623 11624 11625 11626 11627 11628 11629 11630 11631 11632 11633 11634 11635 11636 11637 11638 11639 11640 11641 11642 11643 11644 11645 11646 11647 11648 11649 11650 11651 11652 11653 11654 11655 11656 11657 11658 11659 11660 11661 11662 11663 11664 11665 11666 11667 11668 11669 11670 11671 11672 11673 11674 11675 11676 11677 11678 11679 11680 11681 11682 11683 11684 11685 11686 11687 11688 11689 11690 11691 11692 11693 11694 11695 11696 11697 11698 11699 11700 11701 11702 11703 11704 11705 11706 11707 11708 11709 11710 11711 11712 11713 11714 11715 11716 11717 11718 11719 11720 11721 11722 11723 11724 11725 11726 11727 11728 11729 11730 11731 11732 11733 11734 11735 11736 11737 11738 11739 11740 11741 11742 11743 11744 11745 11746 11747 11748 11749 11750 11751 11752 11753 11754 11755 11756 11757 11758 11759 11760 11761 11762 11763 11764 11765 11766 11767 11768 11769 11770 11771 11772 11773 11774 11775 11776 11777 11778 11779 11780 11781 11782 11783 11784 11785 11786 11787 11788 11789 11790 11791 11792 11793 11794 11795 11796 11797 11798 11799 11800 11801 11802 11803 11804 11805 11806 11807 11808 11809 11810 11811 11812 11813 11814 11815 11816 11817 11818 11819 11820 11821 11822 11823 11824 11825 11826 11827 11828 11829 11830 11831 11832 11833 11834 11835 11836 11837 11838 11839 11840 11841 11842 11843 11844 11845 11846 11847 11848 11849 11850 11851 11852 11853 11854 11855 11856 11857 11858 11859 11860 11861 11862 11863 11864 11865 11866 11867 11868 11869 11870 11871 11872 11873 11874 11875 11876 11877 11878 11879 11880 11881 11882 11883 11884 11885 11886 11887 11888 11889 11890 11891 11892 11893 11894 11895 11896 11897 11898 11899 11900 11901 11902 11903 11904 11905 11906 11907 11908 11909 11910 11911 11912 11913 11914 11915 11916 11917 11918 11919 11920 11921 11922 11923 11924 11925 11926 11927 11928 11929 11930 11931 11932 11933 11934 11935 11936 11937 11938 11939 11940 11941 11942 11943 11944 11945 11946 11947 11948 11949 11950 11951 11952 11953 11954 11955 11956 11957 11958 11959 11960 11961 11962 11963 11964 11965 11966 11967 11968 11969 11970 11971 11972 11973 11974 11975 11976 11977 11978 11979 11980 11981 11982 11983 11984 11985 11986 11987 11988 11989 11990 11991 11992 11993 11994 11995 11996 11997 11998 11999 12000 12001 12002 12003 12004 12005 12006 12007 12008 12009 12010 12011 12012 12013 12014 12015 12016 12017 12018 12019 12020 12021 12022 12023 12024 12025 12026 12027 12028 12029 12030 12031 12032 12033 12034 12035 12036 12037 12038 12039 12040 12041 12042 12043 12044 12045 12046 12047 12048 12049 12050 12051 12052 12053 12054 12055 12056 12057 12058 12059 12060 12061 12062 12063 12064 12065 12066 12067 12068 12069 12070 12071 12072 12073 12074 12075 12076 12077 12078 12079 12080 12081 12082 12083 12084 12085 12086 12087 12088 12089 12090 12091 12092 12093 12094 12095 12096 12097 12098 12099 12100 12101 12102 12103 12104 12105 12106 12107 12108 12109 12110 12111 12112 12113 12114 12115 12116 12117 12118 12119 12120 12121 12122 12123 12124 12125 12126 12127 12128 12129 12130 12131 12132 12133 12134 12135 12136 12137 12138 12139 12140 12141 12142 12143 12144 12145 12146 12147 12148 12149 12150 12151 12152 12153 12154 12155 12156 12157 12158 12159 12160 12161 12162 12163 12164 12165 12166 12167 12168 12169 12170 12171 12172 12173 12174 12175 12176 12177 12178 12179 12180 12181 12182 12183 12184 12185 12186 12187 12188 12189 12190 12191 12192 12193 12194 12195 12196 12197 12198 12199 12200 12201 12202 12203 12204 12205 12206 12207 12208 12209 12210 12211 12212 12213 12214 12215 12216 12217 12218 12219 12220 12221 12222 12223 12224 12225 12226 12227 12228 12229 12230 12231 12232 12233 12234 12235 12236 12237 12238 12239 12240 12241 12242 12243 12244 12245 12246 12247 12248 12249 12250 12251 12252 12253 12254 12255 12256 12257 12258 12259 12260 12261 12262 12263 12264 12265 12266 12267 12268 12269 12270 12271 12272 12273 12274 12275 12276 12277 12278 12279 12280 12281 12282 12283 12284 12285 12286 12287 12288 12289 12290 12291 12292 12293 12294 12295 12296 12297 12298 12299 12300 12301 12302 12303 12304 12305 12306 12307 12308 12309 12310 12311 12312 12313 12314 12315 12316 12317 12318 12319 12320 12321 12322 12323 12324 12325 12326 12327 12328 12329 12330 12331 12332 12333 12334 12335 12336 12337 12338 12339 12340 12341 12342 12343 12344 12345 12346 12347 12348 12349 12350 12351 12352 12353 12354 12355 12356 12357 12358 12359 12360 12361 12362 12363 12364 12365 12366 12367 12368 12369 12370 12371 12372 12373 12374 12375 12376 12377 12378 12379 12380 12381 12382 12383 12384 12385 12386 12387 12388 12389 12390 12391 12392 12393 12394 12395 12396 12397 12398 12399 12400 12401 12402 12403 12404 12405 12406 12407 12408 12409 12410 12411 12412 12413 12414 12415 12416 12417 12418 12419 12420 12421 12422 12423 12424 12425 12426 12427 12428 12429 12430 12431 12432 12433 12434 12435 12436 12437 12438 12439 12440 12441 12442 12443 12444 12445 12446 12447 12448 12449 12450 12451 12452 12453 12454 12455 12456 12457 12458 12459 12460 12461 12462 12463 12464 12465 12466 12467 12468 12469 12470 12471 12472 12473 12474 12475 12476 12477 12478 12479 12480 12481 12482 12483 12484 12485 12486 12487 12488 12489 12490 12491 12492 12493 12494 12495 12496 12497 12498 12499 12500 12501 12502 12503 12504 12505 12506 12507 12508 12509 12510 12511 12512 12513 12514 12515 12516 12517 12518 12519 12520 12521 12522 12523 12524 12525 12526 12527 12528 12529 12530 12531 12532 12533 12534 12535 12536 12537 12538 12539 12540 12541 12542 12543 12544 12545 12546 12547 12548 12549 12550 12551 12552 12553 12554 12555 12556 12557 12558 12559 12560 12561 12562 12563 12564 12565 12566 12567 12568 12569 12570 12571 12572 12573 12574 12575 12576 12577 12578 12579 12580 12581 12582 12583 12584 12585 12586 12587 12588 12589 12590 12591 12592 12593 12594 12595 12596 12597 12598 12599 12600 12601 12602 12603 12604 12605 12606 12607 12608 12609 12610 12611 12612 12613 12614 12615 12616 12617 12618 12619 12620 12621 12622 12623 12624 12625 12626 12627 12628 12629 12630 12631 12632 12633 12634 12635 12636 12637 12638 12639 12640 12641 12642 12643 12644 12645 12646 12647 12648 12649 12650 12651 12652 12653 12654 12655 12656 12657 12658 12659 12660 12661 12662 12663 12664 12665 12666 12667 12668 12669 12670 12671 12672 12673 12674 12675 12676 12677 12678 12679 12680 12681 12682 12683 12684 12685 12686 12687 12688 12689 12690 12691 12692 12693 12694 12695 12696 12697 12698 12699 12700 12701 12702 12703 12704 12705 12706 12707 12708 12709 12710 12711 12712 12713 12714 12715 12716 12717 12718 12719 12720 12721 12722 12723 12724 12725 12726 12727 12728 12729 12730 12731 12732 12733 12734 12735 12736 12737 12738 12739 12740 12741 12742 12743 12744 12745 12746 12747 12748 12749 12750 12751 12752 12753 12754 12755 12756 12757 12758 12759 12760 12761 12762 12763 12764 12765 12766 12767 12768 12769 12770 12771 12772 12773 12774 12775 12776 12777 12778 12779 12780 12781 12782 12783 12784 12785 12786 12787 12788 12789 12790 12791 12792 12793 12794 12795 12796 12797 12798 12799 12800 12801 12802 12803 12804 12805 12806 12807 12808 12809 12810 12811 12812 12813 12814 12815 12816 12817 12818 12819 12820 12821 12822 12823 12824 12825 12826 12827 12828 12829 12830 12831 12832 12833 12834 12835 12836 12837 12838 12839 12840 12841 12842 12843 12844 12845 12846 12847 12848 12849 12850 12851 12852 12853 12854 12855 12856 12857 12858 12859 12860 12861 12862 12863 12864 12865 12866 12867 12868 12869 12870 12871 12872 12873 12874 12875 12876 12877 12878 12879 12880 12881 12882 12883 12884 12885 12886 12887 12888 12889 12890 12891 12892 12893 12894 12895 12896 12897 12898 12899 12900 12901 12902 12903 12904 12905 12906 12907 12908 12909 12910 12911 12912 12913 12914 12915 12916 12917 12918 12919 12920 12921 12922 12923 12924 12925 12926 12927 12928 12929 12930 12931 12932 12933 12934 12935 12936 12937 12938 12939 12940 12941 12942 12943 12944 12945 12946 12947 12948 12949 12950 12951 12952 12953 12954 12955 12956 12957 12958 12959 12960 12961 12962 12963 12964 12965 12966 12967 12968 12969 12970 12971 12972 12973 12974 12975 12976 12977 12978 12979 12980 12981 12982 12983 12984 12985 12986 12987 12988 12989 12990 12991 12992 12993 12994 12995 12996 12997 12998 12999 13000 13001 13002 13003 13004 13005 13006 13007 13008 13009 13010 13011 13012 13013 13014 13015 13016 13017 13018 13019 13020 13021 13022 13023 13024 13025 13026 13027 13028 13029 13030 13031 13032 13033 13034 13035 13036 13037 13038 13039 13040 13041 13042 13043 13044 13045 13046 13047 13048 13049 13050 13051 13052 13053 13054 13055 13056 13057 13058 13059 13060 13061 13062 13063 13064 13065 13066 13067 13068 13069 13070 13071 13072 13073 13074 13075 13076 13077 13078 13079 13080 13081 13082 13083 13084 13085 13086 13087 13088 13089 13090 13091 13092 13093 13094 13095 13096 13097 13098 13099 13100 13101 13102 13103 13104 13105 13106 13107 13108 13109 13110 13111 13112 13113 13114 13115 13116 13117 13118 13119 13120 13121 13122 13123 13124 13125 13126 13127 13128 13129 13130 13131 13132 13133 13134 13135 13136 13137 13138 13139 13140 13141 13142 13143 13144 13145 13146 13147 13148 13149 13150 13151 13152 13153 13154 13155 13156 13157 13158 13159 13160 13161 13162 13163 13164 13165 13166 13167 13168 13169 13170 13171 13172 13173 13174 13175 13176 13177 13178 13179 13180 13181 13182 13183 13184 13185 13186 13187 13188 13189 13190 13191 13192 13193 13194 13195 13196 13197 13198 13199 13200 13201 13202 13203 13204 13205 13206 13207 13208 13209 13210 13211 13212 13213 13214 13215 13216 13217 13218 13219 13220 13221 13222 13223 13224 13225 13226 13227 13228 13229 13230 13231 13232 13233 13234 13235 13236 13237 13238 13239 13240 13241 13242 13243 13244 13245 13246 13247 13248 13249 13250 13251 13252 13253 13254 13255 13256 13257 13258 13259 13260 13261 13262 13263 13264 13265 13266 13267 13268 13269 13270 13271 13272 13273 13274 13275 13276 13277 13278 13279 13280 13281 13282 13283 13284 13285 13286 13287 13288 13289 13290 13291 13292 13293 13294 13295 13296 13297 13298 13299 13300 13301 13302 13303 13304 13305 13306 13307 13308 13309 13310 13311 13312 13313 13314 13315 13316 13317 13318 13319 13320 13321 13322 13323 13324 13325 13326 13327 13328 13329 13330 13331 13332 13333 13334 13335 13336 13337 13338 13339 13340 13341 13342 13343 13344 13345 13346 13347 13348 13349 13350 13351 13352 13353 13354 13355 13356 13357 13358 13359 13360 13361 13362 13363 13364 13365 13366 13367 13368 13369 13370 13371 13372 13373 13374 13375 13376 13377 13378 13379 13380 13381 13382 13383 13384 13385 13386 13387 13388 13389 13390 13391 13392 13393 13394 13395 13396 13397 13398 13399 13400 13401 13402 13403 13404 13405 13406 13407 13408 13409 13410 13411 13412 13413 13414 13415 13416 13417 13418 13419 13420 13421 13422 13423 13424 13425 13426 13427 13428 13429 13430 13431 13432 13433 13434 13435 13436 13437 13438 13439 13440 13441 13442 13443 13444 13445 13446 13447 13448 13449 13450 13451 13452 13453 13454 13455 13456 13457 13458 13459 13460 13461 13462 13463 13464 13465 13466 13467 13468 13469 13470 13471 13472 13473 13474 13475 13476 13477 13478 13479 13480 13481 13482 13483 13484 13485 13486 13487 13488 13489 13490 13491 13492 13493 13494 13495 13496 13497 13498 13499 13500 13501 13502 13503 13504 13505 13506 13507 13508 13509 13510 13511 13512 13513 13514 13515 13516 13517 13518 13519 13520 13521 13522 13523 13524 13525 13526 13527 13528 13529 13530 13531 13532 13533 13534 13535 13536 13537 13538 13539 13540 13541 13542 13543 13544 13545 13546 13547 13548 13549 13550 13551 13552 13553 13554 13555 13556 13557 13558 13559 13560 13561 13562 13563 13564 13565 13566 13567 13568 13569 13570 13571 13572 13573 13574 13575 13576 13577 13578 13579 13580 13581 13582 13583 13584 13585 13586 13587 13588 13589 13590 13591 13592 13593 13594 13595 13596 13597 13598 13599 13600 13601 13602 13603 13604 13605 13606 13607 13608 13609 13610 13611 13612 13613 13614 13615 13616 13617 13618 13619 13620 13621 13622 13623 13624 13625 13626 13627 13628 13629 13630 13631 13632 13633 13634 13635 13636 13637 13638 13639 13640 13641 13642 13643 13644 13645 13646 13647 13648 13649 13650 13651 13652 13653 13654 13655 13656 13657 13658 13659 13660 13661 13662 13663 13664 13665 13666 13667 13668 13669 13670 13671 13672 13673 13674 13675 13676 13677 13678 13679 13680 13681 13682 13683 13684 13685 13686 13687 13688 13689 13690 13691 13692 13693 13694 13695 13696 13697 13698 13699 13700 13701 13702 13703 13704 13705 13706 13707 13708 13709 13710 13711 13712 13713 13714 13715 13716 13717 13718 13719 13720 13721 13722 13723 13724 13725 13726 13727 13728 13729 13730 13731 13732 13733 13734 13735 13736 13737 13738 13739 13740 13741 13742 13743 13744 13745 13746 13747 13748 13749 13750 13751 13752 13753 13754 13755 13756 13757 13758 13759 13760 13761 13762 13763 13764 13765 13766 13767 13768 13769 13770 13771 13772 13773 13774 13775 13776 13777 13778 13779 13780 13781 13782 13783 13784 13785 13786 13787 13788 13789 13790 13791 13792 13793 13794 13795 13796 13797 13798 13799 13800 13801 13802 13803 13804 13805 13806 13807 13808 13809 13810 13811 13812 13813 13814 13815 13816 13817 13818 13819 13820 13821 13822 13823 13824 13825 13826 13827 13828 13829 13830 13831 13832 13833 13834 13835 13836 13837 13838 13839 13840 13841 13842 13843 13844 13845 13846 13847 13848 13849 13850 13851 13852 13853 13854 13855 13856 13857 13858 13859 13860 13861 13862 13863 13864 13865 13866 13867 13868 13869 13870 13871 13872 13873 13874 13875 13876 13877 13878 13879 13880 13881 13882 13883 13884 13885 13886 13887 13888 13889 13890 13891 13892 13893 13894 13895 13896 13897 13898 13899 13900 13901 13902 13903 13904 13905 13906 13907 13908 13909 13910 13911 13912 13913 13914 13915 13916 13917 13918 13919 13920 13921 13922 13923 13924 13925 13926 13927 13928 13929 13930 13931 13932 13933 13934 13935 13936 13937 13938 13939 13940 13941 13942 13943 13944 13945 13946 13947 13948 13949 13950 13951 13952 13953 13954 13955 13956 13957 13958 13959 13960 13961 13962 13963 13964 13965 13966 13967 13968 13969 13970 13971 13972 13973 13974 13975 13976 13977 13978 13979 13980 13981 13982 13983 13984 13985 13986 13987 13988 13989 13990 13991 13992 13993 13994 13995 13996 13997 13998 13999 14000 14001 14002 14003 14004 14005 14006 14007 14008 14009 14010 14011 14012 14013 14014 14015 14016 14017 14018 14019 14020 14021 14022 14023 14024 14025 14026 14027 14028 14029 14030 14031 14032 14033 14034 14035 14036 14037 14038 14039 14040 14041 14042 14043 14044 14045 14046 14047 14048 14049 14050 14051 14052 14053 14054 14055 14056 14057 14058 14059 14060 14061 14062 14063 14064 14065 14066 14067 14068 14069 14070 14071 14072 14073 14074 14075 14076 14077 14078 14079 14080 14081 14082 14083 14084 14085 14086 14087 14088 14089 14090 14091 14092 14093 14094 14095 14096 14097 14098 14099 14100 14101 14102 14103 14104 14105 14106 14107 14108 14109 14110 14111 14112 14113 14114 14115 14116 14117 14118 14119 14120 14121 14122 14123 14124 14125 14126 14127 14128 14129 14130 14131 14132 14133 14134 14135 14136 14137 14138 14139 14140 14141 14142 14143 14144 14145 14146 14147 14148 14149 14150 14151 14152 14153 14154 14155 14156 14157 14158 14159 14160 14161 14162 14163 14164 14165 14166 14167 14168 14169 14170 14171 14172 14173 14174 14175 14176 14177 14178 14179 14180 14181 14182 14183 14184 14185 14186 14187 14188 14189 14190 14191 14192 14193 14194 14195 14196 14197 14198 14199 14200 14201 14202 14203 14204 14205 14206 14207 14208 14209 14210 14211 14212 14213 14214 14215 14216 14217 14218 14219 14220 14221 14222 14223 14224 14225 14226 14227 14228 14229 14230 14231 14232 14233 14234 14235 14236 14237 14238 14239 14240 14241 14242 14243 14244 14245 14246 14247 14248 14249 14250 14251 14252 14253 14254 14255 14256 14257 14258 14259 14260 14261 14262 14263 14264 14265 14266 14267 14268 14269 14270 14271 14272 14273 14274 14275 14276 14277 14278 14279 14280 14281 14282 14283 14284 14285 14286 14287 14288 14289 14290 14291 14292 14293 14294 14295 14296 14297 14298 14299 14300 14301 14302 14303 14304 14305 14306 14307 14308 14309 14310 14311 14312 14313 14314 14315 14316 14317 14318 14319 14320 14321 14322 14323 14324 14325 14326 14327 14328 14329 14330 14331 14332 14333 14334 14335 14336 14337 14338 14339 14340 14341 14342 14343 14344 14345 14346 14347 14348 14349 14350 14351 14352 14353 14354 14355 14356 14357 14358 14359 14360 14361 14362 14363 14364 14365 14366 14367 14368 14369 14370 14371 14372 14373 14374 14375 14376 14377 14378 14379 14380 14381 14382 14383 14384 14385 14386 14387 14388 14389 14390 14391 14392 14393 14394 14395 14396 14397 14398 14399 14400 14401 14402 14403 14404 14405 14406 14407 14408 14409 14410 14411 14412 14413 14414 14415 14416 14417 14418 14419 14420 14421 14422 14423 14424 14425 14426 14427 14428 14429 14430 14431 14432 14433 14434 14435 14436 14437 14438 14439 14440 14441 14442 14443 14444 14445 14446 14447 14448 14449 14450 14451 14452 14453 14454 14455 14456 14457 14458 14459 14460 14461 14462 14463 14464 14465 14466 14467 14468 14469 14470 14471 14472 14473 14474 14475 14476 14477 14478 14479 14480 14481 14482 14483 14484 14485 14486 14487 14488 14489 14490 14491 14492 14493 14494 14495 14496 14497 14498 14499 14500 14501 14502 14503 14504 14505 14506 14507 14508 14509 14510 14511 14512 14513 14514 14515 14516 14517 14518 14519 14520 14521 14522 14523 14524 14525 14526 14527 14528 14529 14530 14531 14532 14533 14534 14535 14536 14537 14538 14539 14540 14541 14542 14543 14544 14545 14546 14547 14548 14549 14550 14551 14552 14553 14554 14555 14556 14557 14558 14559 14560 14561 14562 14563 14564 14565 14566 14567 14568 14569 14570 14571 14572 14573 14574 14575 14576 14577 14578 14579 14580 14581 14582 14583 14584 14585 14586 14587 14588 14589 14590 14591 14592 14593 14594 14595 14596 14597 14598 14599 14600 14601 14602 14603 14604 14605 14606 14607 14608 14609 14610 14611 14612 14613 14614 14615 14616 14617 14618 14619 14620 14621 14622 14623 14624 14625 14626 14627 14628 14629 14630 14631 14632 14633 14634 14635 14636 14637 14638 14639 14640 14641 14642 14643 14644 14645 14646 14647 14648 14649 14650 14651 14652 14653 14654 14655 14656 14657 14658 14659 14660 14661 14662 14663 14664 14665 14666 14667 14668 14669 14670 14671 14672 14673 14674 14675 14676 14677 14678 14679 14680 14681 14682 14683 14684 14685 14686 14687 14688 14689 14690 14691 14692 14693 14694 14695 14696 14697 14698 14699 14700 14701 14702 14703 14704 14705 14706 14707 14708 14709 14710 14711 14712 14713 14714 14715 14716 14717 14718 14719 14720 14721 14722 14723 14724 14725 14726 14727 14728 14729 14730 14731 14732 14733 14734 14735 14736 14737 14738 14739 14740 14741 14742 14743 14744 14745 14746 14747 14748 14749 14750 14751 14752 14753 14754 14755 14756 14757 14758 14759 14760 14761 14762 14763 14764 14765 14766 14767 14768 14769 14770 14771 14772 14773 14774 14775 14776 14777 14778 14779 14780 14781 14782 14783 14784 14785 14786 14787 14788 14789 14790 14791 14792 14793 14794 14795 14796 14797 14798 14799 14800 14801 14802 14803 14804 14805 14806 14807 14808 14809 14810 14811 14812 14813 14814 14815 14816 14817 14818 14819 14820 14821 14822 14823 14824 14825 14826 14827 14828 14829 14830 14831 14832 14833 14834 14835 14836 14837 14838 14839 14840 14841 14842 14843 14844 14845 14846 14847 14848 14849 14850 14851 14852 14853 14854 14855 14856 14857 14858 14859 14860 14861 14862 14863 14864 14865 14866 14867 14868 14869 14870 14871 14872 14873 14874 14875 14876 14877 14878 14879 14880 14881 14882 14883 14884 14885 14886 14887 14888 14889 14890 14891 14892 14893 14894 14895 14896 14897 14898 14899 14900 14901 14902 14903 14904 14905 14906 14907 14908 14909 14910 14911 14912 14913 14914 14915 14916 14917 14918 14919 14920 14921 14922 14923 14924 14925 14926 14927 14928 14929 14930 14931 14932 14933 14934 14935 14936 14937 14938 14939 14940 14941 14942 14943 14944 14945 14946 14947 14948 14949 14950 14951 14952 14953 14954 14955 14956 14957 14958 14959 14960 14961 14962 14963 14964 14965 14966 14967 14968 14969 14970 14971 14972 14973 14974 14975 14976 14977 14978 14979 14980 14981 14982 14983 14984 14985 14986 14987 14988 14989 14990 14991 14992 14993 14994 14995 14996 14997 14998 14999 15000 15001 15002 15003 15004 15005 15006 15007 15008 15009 15010 15011 15012 15013 15014 15015 15016 15017 15018 15019 15020 15021 15022 15023 15024 15025 15026 15027 15028 15029 15030 15031 15032 15033 15034 15035 15036 15037 15038 15039 15040 15041 15042 15043 15044 15045 15046 15047 15048 15049 15050 15051 15052 15053 15054 15055 15056 15057 15058 15059 15060 15061 15062 15063 15064 15065 15066 15067 15068 15069 15070 15071 15072 15073 15074 15075 15076 15077 15078 15079 15080 15081 15082 15083 15084 15085 15086 15087 15088 15089 15090 15091 15092 15093 15094 15095 15096 15097 15098 15099 15100 15101 15102 15103 15104 15105 15106 15107 15108 15109 15110 15111 15112 15113 15114 15115 15116 15117 15118 15119 15120 15121 15122 15123 15124 15125 15126 15127 15128 15129 15130 15131 15132 15133 15134 15135 15136 15137 15138 15139 15140 15141 15142 15143 15144 15145 15146 15147 15148 15149 15150 15151 15152 15153 15154 15155 15156 15157 15158 15159 15160 15161 15162 15163 15164 15165 15166 15167 15168 15169 15170 15171 15172 15173 15174 15175 15176 15177 15178 15179 15180 15181 15182 15183 15184 15185 15186 15187 15188 15189 15190 15191 15192 15193 15194 15195 15196 15197 15198 15199 15200 15201 15202 15203 15204 15205 15206 15207 15208 15209 15210 15211 15212 15213 15214 15215 15216 15217 15218 15219 15220 15221 15222 15223 15224 15225 15226 15227 15228 15229 15230 15231 15232 15233 15234 15235 15236 15237 15238 15239 15240 15241 15242 15243 15244 15245 15246 15247 15248 15249 15250 15251 15252 15253 15254 15255 15256 15257 15258 15259 15260 15261 15262 15263 15264 15265 15266 15267 15268 15269 15270 15271 15272 15273 15274 15275 15276 15277 15278 15279 15280 15281 15282 15283 15284 15285 15286 15287 15288 15289 15290 15291 15292 15293 15294 15295 15296 15297 15298 15299 15300 15301 15302 15303 15304 15305 15306 15307 15308 15309 15310 15311 15312 15313 15314 15315 15316 15317 15318 15319 15320 15321 15322 15323 15324 15325 15326 15327 15328 15329 15330 15331 15332 15333 15334 15335 15336 15337 15338 15339 15340 15341 15342 15343 15344 15345 15346 15347 15348 15349 15350 15351 15352 15353 15354 15355 15356 15357 15358 15359 15360 15361 15362 15363 15364 15365 15366 15367 15368 15369 15370 15371 15372 15373 15374 15375 15376 15377 15378 15379 15380 15381 15382 15383 15384 15385 15386 15387 15388 15389 15390 15391 15392 15393 15394 15395 15396 15397 15398 15399 15400 15401 15402 15403 15404 15405 15406 15407 15408 15409 15410 15411 15412 15413 15414 15415 15416 15417 15418 15419 15420 15421 15422 15423 15424 15425 15426 15427 15428 15429 15430 15431 15432 15433 15434 15435 15436 15437 15438 15439 15440 15441 15442 15443 15444 15445 15446 15447 15448 15449 15450 15451 15452 15453 15454 15455 15456 15457 15458 15459 15460 15461 15462 15463 15464 15465 15466 15467 15468 15469 15470 15471 15472 15473 15474 15475 15476 15477 15478 15479 15480 15481 15482 15483 15484 15485 15486 15487 15488 15489 15490 15491 15492 15493 15494 15495 15496 15497 15498 15499 15500 15501 15502 15503 15504 15505 15506 15507 15508 15509 15510 15511 15512 15513 15514 15515 15516 15517 15518 15519 15520 15521 15522 15523 15524 15525 15526 15527 15528 15529 15530 15531 15532 15533 15534 15535 15536 15537 15538 15539 15540 15541 15542 15543 15544 15545 15546 15547 15548 15549 15550 15551 15552 15553 15554 15555 15556 15557 15558 15559 15560 15561 15562 15563 15564 15565 15566 15567 15568 15569 15570 15571 15572 15573 15574 15575 15576 15577 15578 15579 15580 15581 15582 15583 15584 15585 15586 15587 15588 15589 15590 15591 15592 15593 15594 15595 15596 15597 15598 15599 15600 15601 15602 15603 15604 15605 15606 15607 15608 15609 15610 15611 15612 15613 15614 15615 15616 15617 15618 15619 15620 15621 15622 15623 15624 15625 15626 15627 15628 15629 15630 15631 15632 15633 15634 15635 15636 15637 15638 15639 15640 15641 15642 15643 15644 15645 15646 15647 15648 15649 15650 15651 15652 15653 15654 15655 15656 15657 15658 15659 15660 15661 15662 15663 15664 15665 15666 15667 15668 15669 15670 15671 15672 15673 15674 15675 15676 15677 15678 15679 15680 15681 15682 15683 15684 15685 15686 15687 15688 15689 15690 15691 15692 15693 15694 15695 15696 15697 15698 15699 15700 15701 15702 15703 15704 15705 15706 15707 15708 15709 15710 15711 15712 15713 15714 15715 15716 15717 15718 15719 15720 15721 15722 15723 15724 15725 15726 15727 15728 15729 15730 15731 15732 15733 15734 15735 15736 15737 15738 15739 15740 15741 15742 15743 15744 15745 15746 15747 15748 15749 15750 15751 15752 15753 15754 15755 15756 15757 15758 15759 15760 15761 15762 15763 15764 15765 15766 15767 15768 15769 15770 15771 15772 15773 15774 15775 15776 15777 15778 15779 15780 15781 15782 15783 15784 15785 15786 15787 15788 15789 15790 15791 15792 15793 15794 15795 15796 15797 15798 15799 15800 15801 15802 15803 15804 15805 15806 15807 15808 15809 15810 15811 15812 15813 15814 15815 15816 15817 15818 15819 15820 15821 15822 15823 15824 15825 15826 15827 15828 15829 15830 15831 15832 15833 15834 15835 15836 15837 15838 15839 15840 15841 15842 15843 15844 15845 15846 15847 15848 15849 15850 15851 15852 15853 15854 15855 15856 15857 15858 15859 15860 15861 15862 15863 15864 15865 15866 15867 15868 15869 15870 15871 15872 15873 15874 15875 15876 15877 15878 15879 15880 15881 15882 15883 15884 15885 15886 15887 15888 15889 15890 15891 15892 15893 15894 15895 15896 15897 15898 15899 15900 15901 15902 15903 15904 15905 15906 15907 15908 15909 15910 15911 15912 15913 15914 15915 15916 15917 15918 15919 15920 15921 15922 15923 15924 15925 15926 15927 15928 15929 15930 15931 15932 15933 15934 15935 15936 15937 15938 15939 15940 15941 15942 15943 15944 15945 15946 15947 15948 15949 15950 15951 15952 15953 15954 15955 15956 15957 15958 15959 15960 15961 15962 15963 15964 15965 15966 15967 15968 15969 15970 15971 15972 15973 15974 15975 15976 15977 15978 15979 15980 15981 15982 15983 15984 15985 15986 15987 15988 15989 15990 15991 15992 15993 15994 15995 15996 15997 15998 15999 16000 16001 16002 16003 16004 16005 16006 16007 16008 16009 16010 16011 16012 16013 16014 16015 16016 16017 16018 16019 16020 16021 16022 16023 16024 16025 16026 16027 16028 16029 16030 16031 16032 16033 16034 16035 16036 16037 16038 16039 16040 16041 16042 16043 16044 16045 16046 16047 16048 16049 16050 16051 16052 16053 16054 16055 16056 16057 16058 16059 16060 16061 16062 16063 16064 16065 16066 16067 16068 16069 16070 16071 16072 16073 16074 16075 16076 16077 16078 16079 16080 16081 16082 16083 16084 16085 16086 16087 16088 16089 16090 16091 16092 16093 16094 16095 16096 16097 16098 16099 16100 16101 16102 16103 16104 16105 16106 16107 16108 16109 16110 16111 16112 16113 16114 16115 16116 16117 16118 16119 16120 16121 16122 16123 16124 16125 16126 16127 16128 16129 16130 16131 16132 16133 16134 16135 16136 16137 16138 16139 16140 16141 16142 16143 16144 16145 16146 16147 16148 16149 16150 16151 16152 16153 16154 16155 16156 16157 16158 16159 16160 16161 16162 16163 16164 16165 16166 16167 16168 16169 16170 16171 16172 16173 16174 16175 16176 16177 16178 16179 16180 16181 16182 16183 16184 16185 16186 16187 16188 16189 16190 16191 16192 16193 16194 16195 16196 16197 16198 16199 16200 16201 16202 16203 16204 16205 16206 16207 16208 16209 16210 16211 16212 16213 16214 16215 16216 16217 16218 16219 16220 16221 16222 16223 16224 16225 16226 16227 16228 16229 16230 16231 16232 16233 16234 16235 16236 16237 16238 16239 16240 16241 16242 16243 16244 16245 16246 16247 16248 16249 16250 16251 16252 16253 16254 16255 16256 16257 16258 16259 16260 16261 16262 16263 16264 16265 16266 16267 16268 16269 16270 16271 16272 16273 16274 16275 16276 16277 16278 16279 16280 16281 16282 16283 16284 16285 16286 16287 16288 16289 16290 16291 16292 16293 16294 16295 16296 16297 16298 16299 16300 16301 16302 16303 16304 16305 16306 16307 16308 16309 16310 16311 16312 16313 16314 16315 16316 16317 16318 16319 16320 16321 16322 16323 16324 16325 16326 16327 16328 16329 16330 16331 16332 16333 16334 16335 16336 16337 16338 16339 16340 16341 16342 16343 16344 16345 16346 16347 16348 16349 16350 16351 16352 16353 16354 16355 16356 16357 16358 16359 16360 16361 16362 16363 16364 16365 16366 16367 16368 16369 16370 16371 16372 16373 16374 16375 16376 16377 16378 16379 16380 16381 16382 16383 16384 16385 16386 16387 16388 16389 16390 16391 16392 16393 16394 16395 16396 16397 16398 16399 16400 16401 16402 16403 16404 16405 16406 16407 16408 16409 16410 16411 16412 16413 16414 16415 16416 16417 16418 16419 16420 16421 16422 16423 16424 16425 16426 16427 16428 16429 16430 16431 16432 16433 16434 16435 16436 16437 16438 16439 16440 16441 16442 16443 16444 16445 16446 16447 16448 16449 16450 16451 16452 16453 16454 16455 16456 16457 16458 16459 16460 16461 16462 16463 16464 16465 16466 16467 16468 16469 16470 16471 16472 16473 16474 16475 16476 16477 16478 16479 16480 16481 16482 16483 16484 16485 16486 16487 16488 16489 16490 16491 16492 16493 16494 16495 16496 16497 16498 16499 16500 16501 16502 16503 16504 16505 16506 16507 16508 16509 16510 16511 16512 16513 16514 16515 16516 16517 16518 16519 16520 16521 16522 16523 16524 16525 16526 16527 16528 16529 16530 16531 16532 16533 16534 16535 16536 16537 16538 16539 16540 16541 16542 16543 16544 16545 16546 16547 16548 16549 16550 16551 16552 16553 16554 16555 16556 16557 16558 16559 16560 16561 16562 16563 16564 16565 16566 16567 16568 16569 16570 16571 16572 16573 16574 16575 16576 16577 16578 16579 16580 16581 16582 16583 16584 16585 16586 16587 16588 16589 16590 16591 16592 16593 16594 16595 16596 16597 16598 16599 16600 16601 16602 16603 16604 16605 16606 16607 16608 16609 16610 16611 16612 16613 16614 16615 16616 16617 16618 16619 16620 16621 16622 16623
|
\." the following line may be removed if the
\." ff ligature works on your machine
.lg 0
\." set up heading formats
.ds HF 3 3 3 3 3 2 2
.ds HP +2 +2 +1 +0 +0
.nr Hs 5
.nr Hb 5
\." Increment body point size
.S +2
\." ==============================================
\." Put current date in the following at each rev
.ds vE Rev 3.18 29 November 2020
\." ==============================================
\." ==============================================
.ds | |
.ds ~ ~
.ds ' '
.if t .ds Cw \&\f(CW
.if n .ds Cw \fB
.de Cf \" Place every other arg in Cw font, beginning with first
.if \\n(.$=1 \&\*(Cw\\$1\fP
.if \\n(.$=2 \&\*(Cw\\$1\fP\\$2
.if \\n(.$=3 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP
.if \\n(.$=4 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4
.if \\n(.$=5 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP
.if \\n(.$=6 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP\\$6
.if \\n(.$=7 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP\\$6\*(Cw\\$7\fP
.if \\n(.$=8 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP\\$6\*(Cw\\$7\fP\\$8
.if \\n(.$=9 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP\\$6\*(Cw\\$7\fP\\$8\
*(Cw
..
.nr Cl 4
.SA 1
.TL
A Consumer Library Interface to DWARF
.AF ""
.AU "David Anderson"
.PF "'\*(vE'- \\\\nP -''"
.AS 1
This document describes an interface to a library of functions
to access DWARF debugging information entries, DWARF line number
information, and other DWARF2/3/4/5 information).
.P
There are a few sections which are SGI-specific (those
are clearly identified in the document).
.P
\*(vE
.AE
.MT 4
.H 1 "INTRODUCTION"
This document describes an interface to \fIlibdwarf\fP, a
library of functions to provide access to DWARF debugging information
records, DWARF line number information, DWARF address range and global
names information, weak names information, DWARF frame description
information, DWARF static function names, DWARF static variables, and
DWARF type information.
.P
The document has long mentioned the
"Unix International Programming Languages Special Interest Group"
(PLSIG), under whose auspices the
DWARF committee was formed around 1991.
"Unix International"
was disbanded in the 1990s and no longer exists.
.P
The DWARF committee published DWARF2 July 27, 1993.
.P
In the mid 1990s this document and the library it describes
(which the committee never endorsed, having decided
not to endorse or approve any particular library interface)
was made available on the internet by Silicon Graphics, Inc.
.P
In 2005 the DWARF committee began an affiliation with FreeStandards.org.
In 2007 FreeStandards.org merged with The Linux Foundation.
The DWARF committee dropped its affiliation with FreeStandards.org
in 2007 and established the dwarfstd.org website.
See "http://www.dwarfstd.org" for current
information on standardization activities
and a copy of the standard.
.H 2 "Copyright"
Copyright 1993-2006 Silicon Graphics, Inc.
Copyright 2007-2019 David Anderson.
Permission is hereby granted to
copy or republish or use any or all of this document without
restriction except that when publishing more than a small amount
of the document
please acknowledge Silicon Graphics, Inc and David Anderson.
This document is distributed in the hope that it would be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
.H 2 "Purpose and Scope"
The purpose of this document is to document a library of functions
to access DWARF debugging information. There is no effort made in
this document to address the creation of these records as those
issues are addressed separately
(see "A Producer Library Interface to DWARF").
.P
Additionally, the focus of this document is the functional interface,
and as such, implementation as well as optimization issues are
intentionally ignored.
.H 2 "Document History"
.P
A document was written about 1991 which had similar
layout and interfaces.
Written by people from Hal Corporation,
That document described a library for reading DWARF1.
The authors distributed paper copies to the committee
with the clearly expressed intent to propose the document as
a supported interface definition.
The committee decided not to pursue a library definition.
.P
SGI wrote the document you are now reading in 1993
with a similar layout and content and organization, but
it was complete document rewrite with the intent to read DWARF2
(the DWARF version then in existence).
The intent was (and is) to also cover
future revisions of DWARF.
All the function interfaces were changed
in 1994 to uniformly
return a simple integer success-code (see DW_DLV_OK etc),
generally following
the recommendations in the chapter
titled "Candy Machine Interfaces"
of "Writing Solid Code", a book by
Steve Maguire (published by Microsoft Press).
.H 2 "Definitions"
DWARF debugging information entries (DIEs)
are the segments of information
placed in the \f(CW.debug_*\fP sections
by compilers, assemblers, and
linkage editors that, in conjunction
with line number entries, are
necessary for symbolic source-level debugging.
Refer to the latest
"\fIDWARF Debugging Information Format\fP"
from www.dwarfstd.org for a more
complete description of these entries.
.P
This document adopts all the terms and
definitions in "\fIDWARF Debugging
Information Format\fP" versions 2,3,4, and 5.
It originally focused on the implementation at
Silicon Graphics, Inc., but now
attempts to be more generally useful.
.H 2 "Overview"
The remaining sections of this document
describe the proposed interface
to \f(CWlibdwarf\fP, first by describing
the purpose of additional types
defined by the interface, followed
by descriptions of the available
operations.
This document assumes you are thoroughly familiar with the
information contained in the
\fIDWARF Debugging Information Format\fP
document.
.P
We separate the functions into several
categories to emphasize that not
all consumers want to use all the functions.
We call the categories
Debugger, Internal-level, High-level, and
Miscellaneous not because one is more
important than another but as a way of
making the rather large set of
function calls easier to understand.
.P
Unless otherwise specified,
all functions and structures should be
taken as being designed for Debugger consumers.
.P
The Debugger Interface of this library
is intended to be used by debuggers.
The interface is low-level (close to dwarf)
but suppresses irrelevant detail.
A debugger will want to absorb all of
some sections at startup and will
want to see little or nothing of some sections
except at need.
And even
then will probably want to absorb only the
information in a single compilation
unit at a time. A debugger does not care about
implementation details of the library.
.P
The Internal-level Interface is for a DWARF
prettyprinter and checker.
A thorough prettyprinter will want to know all kinds of
internal things (like actual FORM numbers and actual offsets)
so it can check for appropriate structure in the DWARF data
and print (on request) all that internal information for human
users and libdwarf authors and compiler-writers. Calls in this
interface provide data a debugger does not normally care about.
.P
The High-level Interface is for higher level access (it
is not really a high level interface!). Programs such
as disassemblers will want to be able to display relevant
information about functions and line numbers without having
to invest too much effort in looking at DWARF.
.P
The miscellaneous interface is just what is left over: the
error handler functions.
.P
The following is a brief mention of the changes in this
libdwarf from the libdwarf draft for DWARF Version 1 and
recent changes.
.H 2 "Items Changed"
.P
The description of dwarf_srcfiles()
now reflects the difference
in line table handling between
DWARF5 and other line table versions.
If using dwarf_srcfiles() do
read its documentation here
(Section 6.14, page 117 in this
version).
.P
Added functions dwarf_crc32()
and dwarf_basic_crc32()
so libdwarf can check
debuglink/build-id
CRC values.
.P
Clarified the DW_DLC*
value meaning here and in
libdwarf.h.
In the consumer/reader case
DW_DLC_READ
is zero and zero is the only
meaningful value to pass
as the 'access' argument
of dwarf_init(and the like)
consumer/reader
initialization functions.
All this has been true for many
years, it is only now being
clearly (one hopes) stated.
(September 28, 2020)
.P
Added dwarf_get_ranges_b()
so clients reading DWARF4
split dwarf (a GNU extension)
can get the final offset of the ranges.
(September 10, 2020)
.P
All the
dwarf_init*() and
dwarf_elf_init*() calls
have always been able to return
DW_DLV_ERROR with a Dwarf_Error
pointer returned too.
We now update the advice on
dealing with this situation,
unifying with the rest of
libdwarf errors.
(September 9, 2020)
.P
The documentation of dwarf_init_path()
was basically correct but omitted
meaningful mention of the dbg argument
and a little wrongly described the error argument
(July 22, 2020);
.P
Added dwarf_get_debug_sup() to retrived the DWARF5
section .debug_sup content.
(July 13, 2020);
.P
Added new functions for
reading .debug_gnu_pubtypes
and .debug_gnu_pubnames.
dwarf_get_gnu_index_head()
dwarf_gnu_index_dealloc
dwarf_get_gnu_index_block()
dwarf_get_gnu_index_block_entry()
(July 9, 2020);
.P
Added new functions for full .debug_loclists
access:
dwarf_get_locdesc_entry_d(),
dwarf_get_loclist_head_basics(),
dwarf_get_loclist_head_kind(), and
dwarf_loc_head_c_dealloc().
For accessing certain DWARF5 new location
operators (for example DW_OP_const_type)
as well as all other operators we add
dwarf_get_location_op_value_d().
Added functions allowing simple reporting
of .debug_loclists without involving
other sections:
dwarf_load_loclists(),
dwarf_get_loclist_context_basics(),
dwarf_get_loclist_lle(),
dwarf_get_loclist_offset_index_value(),
and
dwarf_get_loclist_raw_entry_detail().
(June 10, 2020);
.P
Added new functions for full .debug_rnglists support
and fixed issues with DWARF5 .debug_addr
index FORMs.
New functions for general use:
dwarf_addr_form_is_indexed(),
dwarf_get_rnglists_entry_fields_a(),
dwarf_rnglists_get_rle_head(),
dwarf_dealloc_rnglists_head(),
New functions for a complete listing
of the .debug_rnglists section.
dwarf_load_rnglists(),
dwarf_get_rnglist_offset_index_value(),
dwarf_get_rnglist_context(),
dwarf_get_rnglist_head_basics(),
dwarf_get_rnglist_context_basics(),
dwarf_get_rnglist_rle().
Also added new functions
dwarf_dealloc_die(), dwarf_dealloc_error(),
and dwarf_dealloc_attribute() to provide
type-safe calls for deallocation of the
specific data types.
(May 20, 2020)
.P
What was historically called 'length_size' in
libdwarf and dwarfdump is actually the size of
an offset (4 or 8 in DWARF2,3,4 and 5).
For readability all instances of 'length_size'
are being converted, as time permits,
to 'offset_size'.
(May 1, 2020)
.P
Added a new function dwarf_set_de_alloc_flag()
which allows turning-off of libdwarf-internal
allocation tracking to improve libdwarf
performance a few percent (which only
really matters with giant DWARF sections).
The downside of turning off the flag is
consumer code must do all the dwarf_dealloc()
calls itself to avoid memory leaks.
(March 14, 2020)
.P
Corrected the documentation of dwarf_diename:
It was never appropriate to use dwarf_dealloc
on the string pointer returned but
Up till now this document said such
a call was required.
(March 14, 2020)
.P
Now we document here
that if one uses dwarf_init() or
dwarf_init_b() or dwarf_init_path()
that the function dwarf_get_elf()
cannot succeed as there is no longer
any Elf pointer (from libelf)
to return.
(November 26, 2019)
.P
New function
dwarf_gnu_debuglink()
allow callers to access fields that
GNU compilers create and use to link an
executable to its separate
DWARF debugging content object file.
(September 9, 2019, updated October 2019)
.P
dwarf_next_cu_header_d() (and the other earlier
versions of this) now allow a null
in place of a pointer for next_cu_offset.
dwarf_hipc_b() now allows a null
in place of the return_form and/or
return_class arguments.
Unless you know a sufficiently recent
libdwarf is to be used it is not safe to
pass those arguments as null pointers.
This allowance of null is because
we've become aware that the relevant
NetBSD man pages
on these functions incorrectly specified that
null was allowed.
(April 22,2019)
.P
The dwarf_elf_init() and dwarf_elf_init_b()
are now deprecated as they require the use
of elf.h and libelf.h and libelf.
Use dwarf_init_path()
or
dwarf_init_b()
instead.
The new non-libelf reader code checks
elf header values more thoroughly
than libelf and detects corrupted Elf
earlier and in more cases than libelf.
Since the reports of elf corruption
from libdwarf/dwarfdump
are not detailed we suggest
one use an object dumper to
check the object file in question.
Two useful
object dumpers are GNU readelf (part
of GNU binutils) and readelfobj
(part of the readelfobj project
on sourceforge.net).
readelfobj uses essentially the same
algorithms as libdwarf does and
should report something meaningful.
(April 20,2019)
.P
Added support for MacOS dSYM objects and
PE object files as well as an initialization
function allowing a path instead of a
Posix/Unix fd or a libelf Elf*.
(January 2019)
.P
Added a libdwarf interface dwarf_errmsg_by_number()
so that places in the code that can have errors but
do not want the Dwarf_Error complexities
can report more details than just an error number.
(December 19, 2018)
.P
Now Mach-o dSYM files containing dwarf
are readable by libdwarf and their DWARF
dumped by dwarfdump.
There are no new options or choices,
libdwarf and dwarfdump notice which
kind of object they are processing.
New functions added to libdwarf.h.in:
dwarf_init_path(),dwarf_object_detector_path(),
and dwarf_object_detector_fd().
(October 24, 2018)
.P
All references to Dwarf_Frame_Op3 have been removed
as that struct was never created or available.
The new function dwarf_get_fde_info_for_reg3_b()
is documented.
(May 12, 2018)
.P
With DWARF5 it became harder to use
dwarf_srclines_data_b() as DWARF5 changed
each line table header file table to zero-based
indexing from one-based (and made the primary
file index zero).
So a new function dwarf_srclines_file_indexes()
returns values that make it easy to step through
and call dwarf_srclines_data_b() sensibly whether
the line table is DWARF2,3,4, or 5.
(March 23, 2018)
.P
Added COMDAT support.
Recent compilers generate COMDAT sections (for some DWARF
information) routinely so this became important
recently. The new libdwarf COMDAT support
extends the groupnumber
idea as suggested just below.
(May 17, 2017)
.P
Adding dwarf_init_b() and dwarf_elf_init_b()
and dwarf_object_init_b() with a groupnumber
option added. DWARF5 adds split-dwarf and
we call original sections like .debug_info
group one and new sections like .debug_info.dwo
group two.
It has not escaped our attention that this
numbering can be extended to deal with
Elf COMDAT
section groups of DWARF information, though
COMDAT groups are not currently supported.
(April 02, 2017)
.P
Adding support for DWARF5 .debug_loc.dwo
and split dwarf range tables.
Added dwarf_get_offset_size().
(November 08, 2015)
.P
Adding support for reading DWARF5 line tables
and GNU two-level line tables.
The function dwarf_srclines() still works
but those using DWARF4 or DWARF5 are
advised to switch to dwarf_srclines_b().
dwarf_srclines()
cannot handle skeleton line tables sensibly
and a new interface was needed for two-level
line tables so the new approach satisfies both.
(October 5,2015)
.P
Adding support for Package Files (DWARF5)
to enable access of address data using DW_FORM_addrx.
See dwarf_set_tied_dbg().
(September 13, 2015)
.P
Adding some DWARF5 support and improved DWP Package File
support, using dwarf_next_cu_header_d().
.P
Added a note about dwarf_errmsg(): the string pointer
returned should be considered ephemeral, not a
string which remains valid permanently.
User code should print it or copy it before calling
other libdwarf functions on the specific Dwarf_Debug
instance.
(May 15, 2014)
.P
Added a printf-callback so libdwarf will not actually print
to \f(CWstdout\fP.
Added dwarf_highpc_b()
so return of a DWARF4 DW_AT_high_pc of class constant
can be returned properly.
(August 15 2013)
.P
Defined how the new operator DW_OP_GNU_const_type is handled.
(January 26 2013)
.P
Added dwarf_loclist_from_expr_b()
function which adds arguments of the DWARF version
(2 for DWARF2, etc) and the offset size
to the dwarf_loclist_from_expr_a()
function. Because the DW_OP_GNU_implicit_pointer
opcode is defined differently for DWARF2 than for
later versions.
(November 2012)
.P
Added new functions (some for libdwarf client code)
and internal logic support for the
DWARF4 .debug_types section.
The new functions are
dwarf_next_cu_header_c(),
dwarf_siblingof_b(), dwarf_offdie_b(),
dwarf_get_cu_die_offset_given_cu_header_offset_b(),
dwarf_get_die_infotypes_flag(),
dwarf_get_section_max_offsets_b().
.P
New functions and logic support additional detailed error reporting
so that more compiler bugs can be reported sensibly
by consumer code (as opposed
to having libdwarf just assume
things are ok and blindly continuing on
with erroneous data).
November 20, 2010
.P
It seems impossible to default to both DW_FRAME_CFA_COL
and DW_FRAME_CFA_COL3 in a single build of libdwarf,
so the default is now unambiguously DW_FRAME_CFA_COL3
unless the configure option --enable-oldframecol
is specified at configure time.
The function dwarf_set_frame_cfa_value()
may be used to override the default : using that function gives
consumer applications full control (its use is highly
recommended).
(January 17,2010)
.P
Added dwarf_set_reloc_application() and the default
automatic application of Elf 'rela' relocations
to DWARF sections (such rela sections appear in .o files, not
in executables or shared objects, in general).
The dwarf_set_reloc_application() routine lets a consumer
turn off the automatic application of 'rela' relocations
if desired (it is not clear why anyone would really want to do that,
but possibly a consumer could write its own relocation application).
An example application that traverses a set of DIEs
was added to the new dwarfexample directory (not
in this libdwarf directory, but in parallel to it).
(July 10, 2009)
.P
Added dwarf_get_TAG_name() (and the FORM AT and so on)
interface functions so applications can get the string
of the TAG, Attribute, etc as needed. (June 2009)
.P
Added dwarf_get_ranges_a() and dwarf_loclist_from_expr_a()
functions which add arguments allowing a correct address_size
when the address_size varies by compilation unit (a varying
address_size is quite rare as of May 2009).
(May 2009)
.P
Added dwarf_set_frame_same_value(), and
dwarf_set_frame_undefined_value() to complete
the set of frame-information functions needed to allow
an application get all frame information
returned correctly (meaning that it
can be correctly interpreted) for all ABIs.
Documented dwarf_set_frame_cfa_value().
Corrected spelling to dwarf_set_frame_rule_initial_value().
(April 2009).
.P
Added support for various DWARF3 features, but primarily
a new frame-information interface tailorable at run-time
to more than a single ABI.
See dwarf_set_frame_rule_initial_value(), dwarf_set_frame_rule_table_size(),
dwarf_set_frame_cfa_value().
See also dwarf_get_fde_info_for_reg3() and
dwarf_get_fde_info_for_cfa_reg3(). (April 2006)
.P
Added support for DWARF3 .debug_pubtypes section.
Corrected various leaks (revising dealloc() calls, adding
new functions) and corrected dwarf_formstring() documentation.
.P
Added dwarf_srclines_dealloc() as the previous deallocation
method documented for data returned by
dwarf_srclines() was incapable of freeing
all the allocated storage (14 July 2005).
.P
dwarf_nextglob(), dwarf_globname(), and dwarf_globdie() were all changed
to operate on the items in the .debug_pubnames section.
.P
All functions were modified to return solely an error code.
Data is returned through pointer arguments.
This makes writing safe and correct library-using-code far easier.
For justification for this approach, see
the chapter titled "Candy Machine Interfaces"
in the book "Writing Solid Code" by
Steve Maguire.
.H 2 "Items Removed"
.P
Dwarf_Type
was removed since types are no longer special.
.P
dwarf_typeof()
was removed since types are no longer special.
.P
Dwarf_Ellist
was removed since element lists no longer are a special format.
.P
Dwarf_Bounds
was removed since bounds have been generalized.
.P
dwarf_nextdie()
was replaced by dwarf_next_cu_header() to reflect the
real way DWARF is organized.
The dwarf_nextdie() was only useful for getting to compilation
unit beginnings, so it does not seem harmful to remove it in favor
of a more direct function.
.P
dwarf_childcnt() is removed on grounds
that no good use was apparent.
.P
dwarf_prevline() and dwarf_nextline() were removed on grounds this
is better left to a debugger to do.
Similarly, dwarf_dieline() was removed.
.P
dwarf_is1stline() was removed as it was not meaningful for the
revised DWARF line operations.
.P
Any libdwarf implementation might well decide to support all the
removed functionality and to retain the DWARF Version 1 meanings
of that functionality.
This would be difficult because the
original libdwarf draft
specification used traditional C library interfaces which
confuse the values returned by successful calls with
exceptional conditions like failures and 'no more data' indications.
.H 2 "Revision History"
.VL 15
.LI "September 2020"
A new approach (simpler, more uniform)
to deal with a failure of a dwarf_init*()
or dwarf_elf_init*() call is described in
Chapter 4.
Improved support for split dwarf.
Added dwarf_get_ranges_b().
.LI "May 2020"
Adding support for DWARF5
sections .debug_rnglists and .debug_loclists.
.LI "March 2020"
Added dwarf_set_de_alloc_flag()
so consumers get a little better
performance from libdwarf.
At a price. See the description
a bit later here.
.LI "January 2019"
Added support for reading DWARF in PE object files.
.LI "October 2018"
Added support for reading MacOS dSYM object files.
.LI "2017"
Added support for nearly all of DWARF5.
.LI "July 2014"
Added support for the .gdb_index section and
started support for the .debug_cu_index and .debug_tu_index
sections.
.LI "October 2011"
DWARF4 support for reading .debug_types added.
.LI "March 93"
Work on DWARF2 SGI draft begins
.LI "June 94"
The function returns are changed to return an error/success code
only.
.LI "April 2006"
Support for DWARF3 consumer operations is close to completion.
.LI "November 2010"
Added various new functions and improved error checking.
.LI "March 2017"
Adding support for DWARF5 split dwarf.
.LE
.H 1 "Types Definitions"
.H 2 "General Description"
The \fIlibdwarf.h\fP header file contains typedefs and preprocessor
definitions of types and symbolic names used to reference objects
of \fIlibdwarf\fP. The types defined by typedefs contained in
\fIlibdwarf.h\fP all use the convention of adding \f(CWDwarf_\fP
as a prefix and can be placed in three categories:
.BL
.LI
Scalar types : The scalar types defined in \fIlibdwarf.h\fP are
defined primarily for notational convenience and identification.
Depending on the individual definition, they are interpreted as a
value, a pointer, or as a flag.
.LI
Aggregate types : Some values can not be represented by a single
scalar type; they must be represented by a collection of, or as a
union of, scalar and/or aggregate types.
.LI
Opaque types : The complete definition of these types is intentionally
omitted; their use is as handles for query operations, which will yield
either an instance of another opaque type to be used in another query, or
an instance of a scalar or aggregate type, which is the actual result.
.P
.H 2 "Scalar Types"
The following are the defined by \fIlibdwarf.h\fP:
.DS
\f(CW
typedef int Dwarf_Bool;
typedef unsigned long long Dwarf_Off;
typedef unsigned long long Dwarf_Unsigned;
typedef unsigned short Dwarf_Half;
typedef unsigned char Dwarf_Small;
typedef signed long long Dwarf_Signed;
typedef unsigned long long Dwarf_Addr;
typedef void *Dwarf_Ptr;
typedef void (*Dwarf_Handler)(Dwarf_Error error, Dwarf_Ptr errarg);
.DE
.nr aX \n(Fg+1
Dwarf_Ptr is an address for use by the host program calling the library,
not for representing pc-values/addresses within the target object file.
Dwarf_Addr is for pc-values within the target object file. The sample
scalar type assignments above are for a \fIlibdwarf.h\fP that can read
and write
32-bit or 64-bit binaries on a 32-bit or 64-bit host machine.
The types must be defined appropriately
for each implementation of libdwarf.
A description of these scalar types in the SGI/MIPS
environment is given in Figure \n(aX.
.DS
.TS
center box, tab(:);
lfB lfB lfB lfB
l c c l.
NAME:SIZE:ALIGNMENT:PURPOSE
_
Dwarf_Bool:4:4:Boolean states
Dwarf_Off:8:8:Unsigned file offset
Dwarf_Unsigned:8:8:Unsigned large integer
Dwarf_Half:2:2:Unsigned medium integer
Dwarf_Small:1:1:Unsigned small integer
Dwarf_Signed:8:8:Signed large integer
Dwarf_Addr:8:8:Program address
:::(target program)
Dwarf_Ptr:4|8:4|8:Dwarf section pointer
:::(host program)
Dwarf_Handler:4|8:4|8:Pointer to
:::error handler function
.TE
.FG "Scalar Types"
.DE
.H 2 "Aggregate Types"
The following aggregate types are defined by
\fIlibdwarf.h\fP:
\f(CWDwarf_Loc\fP,
\f(CWDwarf_Locdesc\fP,
\f(CWDwarf_Block\fP,
\f(CWDwarf_Frame_Op\fP.
\f(CWDwarf_Regtable\fP.
\f(CWDwarf_Regtable3\fP.
While most of \f(CWlibdwarf\fP acts on or returns simple values or
opaque pointer types, this small set of structures seems useful.
Yet, at the same time, these public structures are inflexible
as any change in format or content
breaks binary (and possibly source in some cases)
compatibility.
.H 3 "Location Record"
The \f(CWDwarf_Loc\fP
type identifies a single atom of a location description
or a location expression.
This is obsolete and should not be used,
though it works adequately for DWARF2.
.DS
\f(CWtypedef struct {
Dwarf_Small lr_atom;
Dwarf_Unsigned lr_number;
Dwarf_Unsigned lr_number2;
Dwarf_Unsigned lr_offset;
} Dwarf_Loc;\fP
.DE
The \f(CWlr_atom\fP
identifies the atom corresponding to the
\f(CWDW_OP_*\fP
definition in \fIdwarf.h\fP
and it represents the operation to be performed
in order to locate the item in question.
.P
The \f(CWlr_number\fP field is the operand
to be used in the calculation
specified by the \f(CWlr_atom\fP
field; not all atoms use this field.
Some atom operations imply signed numbers
so it is necessary to cast
this to a
\f(CWDwarf_Signed\fP type for those operations.
.P
The
\f(CWlr_number2\fP
field is the second operand specified by the
\f(CWlr_atom\fP field; only
\f(CWDW_OP_BREGX\fP has this field. Some
atom operations imply signed numbers so
it may be necessary to cast
this to a
\f(CWDwarf_Signed\fP type for those operations.
.P
For a
\f(CWDW_OP_implicit_value\fP operator the
\f(CWlr_number2\fP
field is a pointer to the bytes of the value.
The field pointed to
is \f(CWlr_number\fP bytes long.
There is no explicit terminator.
Do not attempt to
\f(CWfree\fP the bytes which
\f(CWlr_number2\fP
points at and do not alter those bytes. The pointer value
remains valid till the open Dwarf_Debug is closed.
This is a rather ugly use of a host integer to hold a pointer.
You will normally have to do a 'cast' operation to use the value.
.P
For a
\f(CWDW_OP_GNU_const_type\fP operator the
\f(CWlr_number2\fP
field is a pointer to a block with an initial
unsigned byte giving the number of bytes
following, followed immediately that number of const
value bytes.
There is no explicit terminator.
Do not attempt to
\f(CWfree\fP the bytes which
\f(CWlr_number2\fP
points at and do not alter those bytes.
The pointer value
remains valid till the open Dwarf_Debug is closed.
This is a rather ugly use of a host integer to hold a pointer.
You will normally have to do
a 'cast' operation to use the value.
.P
The
\f(CWlr_offset\fP field is the byte offset
(within the block the
location record came from)
of the atom specified by the \f(CWlr_atom\fP
field. This is set on all atoms.
This is useful for operations
\f(CWDW_OP_SKIP\fP and
\f(CWDW_OP_BRA\fP.
.H 3 "Location Description"
This is obsolete and should not be used,
though it works ok for DWARF2..
The
\f(CWDwarf_Locdesc\fP type represents an ordered list of
\f(CWDwarf_Loc\fP records used in the calculation to locate
an item. Note that in many cases, the location can only be
calculated at runtime of the associated program.
.DS
\f(CWtypedef struct {
Dwarf_Addr ld_lopc;
Dwarf_Addr ld_hipc;
Dwarf_Unsigned ld_cents;
Dwarf_Loc* ld_s;
} Dwarf_Locdesc;\fP
.DE
The
\f(CWld_lopc\fP and
\f(CWld_hipc\fP fields provide an address range for
which this location descriptor is valid.
Both of these fields are set to
\fIzero\fP if the location descriptor is
valid throughout the scope of the
item it is associated with.
These addresses are virtual memory addresses,
not offsets-from-something.
The virtual memory addresses do not account
for dso movement (none of the pc values from
libdwarf do that, it is up to
the consumer to do that).
.P
The \f(CWld_cents\fP field contains a count
of the number of
\f(CWDwarf_Loc\fP
entries pointed to by the
\f(CWld_s\fP field.
.P
The
\f(CWld_s\fP field points to an array of
\f(CWDwarf_Loc\fP records.
.H 3 "Data Block"
.SP
This is obsolete and should not be used,
though it works ok for DWARF2.
The \f(CWDwarf_Block\fP type is
used to contain the value of an attribute
whose form is either
\f(CWDW_FORM_block1\fP,
\f(CWDW_FORM_block2\fP,
\f(CWDW_FORM_block4\fP,
\f(CWDW_FORM_block8\fP,
or \f(CWDW_FORM_block\fP.
Its intended use is to deliver the
value for an attribute of any of these
forms.
.DS
\f(CWtypedef struct {
Dwarf_Unsigned bl_len;
Dwarf_Ptr bl_data;
Dwarf_Small bl_from_loclist;
Dwarf_Unsigned bl_section_offset;
} Dwarf_Block;\fP
.DE
.P
The \f(CWbl_len\fP field contains the length in
bytes of the data pointed
to by the \f(CWbl_data\fP field.
.P
The \f(CWbl_data\fP field contains a pointer
to the uninterpreted data.
Since we use a
\f(CWDwarf_Ptr\fP here one must copy the pointer to
some other type (typically an \f(CWunsigned char
*\fP) so one can add increments to index through
the data.
The data pointed to by \f(CWbl_data\fP
is not necessarily at any useful alignment.
.H 3 "Frame Operation Codes: DWARF 2"
This interface is adequate for DWARF2 but
not entirely suitable for DWARF3 or later.
A new (functional) interface is needed.
This DWARF2 interface is not sufficient
but at present is the only available interface.
.P
See also the section "Low Level Frame Operations" below.
.P
The DWARF2 \f(CWDwarf_Frame_Op\fP type is
used to contain the data of a single
instruction of an instruction-sequence of
low-level information from the
section containing frame information.
This is ordinarily used by
Internal-level Consumers trying to print everything in detail.
.DS
\f(CWtypedef struct {
Dwarf_Small fp_base_op;
Dwarf_Small fp_extended_op;
Dwarf_Half fp_register;
Dwarf_Signed fp_offset;
Dwarf_Offset fp_instr_offset;
} Dwarf_Frame_Op;
.DE
\f(CWfp_base_op\fP is the 2-bit basic op code.
\f(CWfp_extended_op\fP is
the 6-bit extended opcode (if
\f(CWfp_base_op\fP indicated there was an
extended op code) and is zero otherwise.
.P
\f(CWfp_register\fP
is any (or the first) register value as defined
in the \f(CWCall frame instruction encodings\fP
in the \f(CWdwarf\fP document
(in DWARF3 see Figure 40,in DWARF5 see table 7.29).
If not used with the operation it is 0.
.P
\f(CWfp_offset\fP
is the address, delta, offset, or second register as defined
in the
\f(CWCall frame instruction encodings\fP
documentation.
If this is an \f(CWaddress\fP then the value should be cast to
\f(CW(Dwarf_Addr)\fP before being used.
In any implementation this field *must* be as large as the
largest of Dwarf_Ptr, Dwarf_Signed, and Dwarf_Addr
for this to work properly.
If not used with the op it is 0.
If the fp_extended_op is
\f(CWDW_CFA_def_cfa\fP
or
\f(CWDW_CFA_val_expression\fP
or
\f(CWDW_CFA_expression\fP
then
\f(CWfp_offset\fP
is a pointer to an expression block in the in-memory
copy of the frame section.
.P
\f(CWfp_instr_offset\fP is the byte_offset (within the instruction
stream of the frame instructions) of this operation. It starts at 0
for a given frame descriptor.
.H 3 "Frame Regtable: DWARF 2"
This interface is adequate for DWARF2
and MIPS but not for DWARF3 or later.
A separate and preferred interface usable for DWARF3 and for DWARF2
is described below.
See also the section "Low Level Frame Operations" below.
.P
The \f(CWDwarf_Regtable\fP type is used to contain the
register-restore information for all registers at a given
PC value.
Normally used by debuggers.
If you wish to default to this interface and to the use
of DW_FRAME_CFA_COL, specify --enable_oldframecol
at libdwarf configure time.
Or add a call dwarf_set_frame_cfa_value(dbg,DW_FRAME_CFA_COL)
after your dwarf_init_b() call, this call replaces the
default libdwarf-compile-time value with DW_FRAME_CFA_COL.
.DS
/* DW_REG_TABLE_SIZE must reflect the number of registers
*(DW_FRAME_LAST_REG_NUM) as defined in dwarf.h
*/
#define DW_REG_TABLE_SIZE <fill in size here, 66 for MIPS/IRIX>
\f(CWtypedef struct {
struct {
Dwarf_Small dw_offset_relevant;
Dwarf_Half dw_regnum;
Dwarf_Addr dw_offset;
} rules[DW_REG_TABLE_SIZE];
} Dwarf_Regtable;\fP
.DE
.P
The array is indexed by register number.
The field values for each index are described next.
For clarity we describe the field values for index rules[M]
(M being any legal array element index).
.P
\f(CWdw_offset_relevant\fP is non-zero to indicate the
\f(CWdw_offset\fP
field is meaningful.
If zero then the
\f(CWdw_offset\fP is zero
and should be ignored.
.P
\f(CWdw_regnum \fPis the register number applicable.
If \f(CWdw_offset_relevant\fP is zero, then this is the register
number of the register containing the value for register M.
If \f(CWdw_offset_relevant\fP is non-zero, then this is
the register number of the register to use as a base (M may be
DW_FRAME_CFA_COL, for example) and the \f(CWdw_offset\fP
value applies.
The value of register M is therefore
the value of register \f(CWdw_regnum\fP.
.P
\f(CWdw_offset\fP should be ignored if
\f(CWdw_offset_relevant\fP is zero.
If \f(CWdw_offset_relevant\fP is non-zero, then
the consumer code should add the value to
the value of the register \f(CWdw_regnum\fP to produce the
value.
.H 3 "Frame Operation Codes: DWARF 3 (for DWARF2 and later )
This interface was intended
to be adequate for DWARF3 and for DWARF2 (and DWARF4)
but was never implemented.
.H 3 "Frame Regtable: DWARF 3 (for DWARF2 and later)"
This interface is adequate for DWARF2 and later versions.
It is new in libdwarf as of April 2006.
The default configure of libdwarf
inserts DW_FRAME_CFA_COL3 as the default CFA column.
Or add a call dwarf_set_frame_cfa_value(dbg,DW_FRAME_CFA_COL3)
after your dwarf_init_b() call, this call replaces the
default libdwarf-compile-time value with DW_FRAME_CFA_COL3.
.P
The \f(CWDwarf_Regtable3\fP type is used to contain the
register-restore information for all registers at a given
PC value.
Normally used by debuggers.
.DS
\f(CWtypedef struct Dwarf_Regtable_Entry3_s {
Dwarf_Small dw_offset_relevant;
Dwarf_Small dw_value_type;
Dwarf_Half dw_regnum;
Dwarf_Unsigned dw_offset_or_block_len;
Dwarf_Ptr dw_block_ptr;
}Dwarf_Regtable_Entry3;
typedef struct Dwarf_Regtable3_s {
struct Dwarf_Regtable_Entry3_s rt3_cfa_rule;
Dwarf_Half rt3_reg_table_size;
struct Dwarf_Regtable_Entry3_s * rt3_rules;
} Dwarf_Regtable3;\fP
.DE
.P
The array is indexed by register number.
The field values for each index are described next.
For clarity we describe the field values for index rules[M]
(M being any legal array element index).
(DW_FRAME_CFA_COL3 DW_FRAME_SAME_VAL, DW_FRAME_UNDEFINED_VAL
are not legal array indexes, nor is any index < 0 or >=
rt3_reg_table_size);
The caller of routines using this
struct must create data space for rt3_reg_table_size entries
of struct Dwarf_Regtable_Entry3_s and arrange that
rt3_rules points to that space and that rt3_reg_table_size
is set correctly. The caller need not (but may)
initialize the contents of the rt3_cfa_rule or the rt3_rules array.
The following applies to each rt3_rules rule M:
.P
.in +4
\f(CWdw_regnum\fP is the register number applicable.
If \f(CWdw_regnum\fP is DW_FRAME_UNDEFINED_VAL, then the
register I has undefined value.
If \f(CWdw_regnum\fP is DW_FRAME_SAME_VAL, then the
register I has the same value as in the previous frame.
.P
If \f(CWdw_regnum\fP is neither of these two,
then the following apply:
.P
.P
\f(CWdw_value_type\fP determines the meaning of the other fields.
It is one of DW_EXPR_OFFSET (0),
DW_EXPR_VAL_OFFSET(1), DW_EXPR_EXPRESSION(2) or
DW_EXPR_VAL_EXPRESSION(3).
.P
If \f(CWdw_value_type\fP is DW_EXPR_OFFSET (0) then
this is as in DWARF2 and the offset(N) rule or the register(R)
rule
of the DWARF3 and DWARF2 document applies.
The value is either:
.in +4
If \f(CWdw_offset_relevant\fP is non-zero, then \f(CWdw_regnum\fP
is effectively ignored but must be identical to
DW_FRAME_CFA_COL3 (and the \f(CWdw_offset\fP value applies.
The value of register M is therefore
the value of CFA plus the value
of \f(CWdw_offset\fP. The result of the calculation
is the address in memory where the value of register M resides.
This is the offset(N) rule of the DWARF2 and DWARF3 documents.
.P
\f(CWdw_offset_relevant\fP is zero it indicates the \f(CWdw_offset\fP
field is not meaningful.
The value of register M is
the value currently in register \f(CWdw_regnum\fP (the
value DW_FRAME_CFA_COL3 must not appear, only real registers).
This is the register(R) rule of the DWARF3 spec.
.in -4
.P
If \f(CWdw_value_type\fP is DW_EXPR_OFFSET (1) then
this is the the val_offset(N) rule of the DWARF3 spec applies.
The calculation is identical to that of DW_EXPR_OFFSET (0)
but the value is interpreted as the value of register M
(rather than the address where register M's value is stored).
.P
If \f(CWdw_value_type\fP is DW_EXPR_EXPRESSION (2) then
this is the the expression(E) rule of the DWARF3 document.
.P
.in +4
\f(CWdw_offset_or_block_len\fP is the length in bytes of
the in-memory block pointed at by \f(CWdw_block_ptr\fP.
\f(CWdw_block_ptr\fP is a DWARF expression.
Evaluate that expression and the result is the address
where the previous value of register M is found.
.in -4
.P
If \f(CWdw_value_type\fP is DW_EXPR_VAL_EXPRESSION (3) then
this is the the val_expression(E) rule of the DWARF3 spec.
.P
.in +4
\f(CWdw_offset_or_block_len\fP is the length in bytes of
the in-memory block pointed at by \f(CWdw_block_ptr\fP.
\f(CWdw_block_ptr\fP is a DWARF expression.
Evaluate that expression and the result is the
previous value of register M.
.in -4
.P
The rule \f(CWrt3_cfa_rule\fP is the current value of
the CFA. It is interpreted exactly like
any register M rule (as described just above) except that
\f(CWdw_regnum\fP cannot be CW_FRAME_CFA_REG3 or
DW_FRAME_UNDEFINED_VAL or DW_FRAME_SAME_VAL but must
be a real register number.
.in -4
.H 3 "Macro Details Record"
The \f(CWDwarf_Macro_Details\fP type gives information about
a single entry in the .debug.macinfo section (DWARF2,
DWARF3, and DWARF4).
It is not useful for DWARF 5 .debug_macro section data.
.DS
\f(CWstruct Dwarf_Macro_Details_s {
Dwarf_Off dmd_offset;
Dwarf_Small dmd_type;
Dwarf_Signed dmd_lineno;
Dwarf_Signed dmd_fileindex;
char * dmd_macro;
};
typedef struct Dwarf_Macro_Details_s Dwarf_Macro_Details;
.DE
.P
\f(CWdmd_offset\fP is the byte offset, within the .debug_macinfo
section, of this macro information.
.P
\f(CWdmd_type\fP is the type code of this macro info entry
(or 0, the type code indicating that this is the end of
macro information entries for a compilation unit.
See \f(CWDW_MACINFO_define\fP, etc in the DWARF document.
.P
\f(CWdmd_lineno\fP is the line number where this entry was found,
or 0 if there is no applicable line number.
.P
\f(CWdmd_fileindex\fP is the file index of the file involved.
This is only guaranteed meaningful on a \f(CWDW_MACINFO_start_file\fP
\f(CWdmd_type\fP. Set to -1 if unknown (see the functional
interface for more details).
.P
\f(CWdmd_macro\fP is the applicable string.
For a \f(CWDW_MACINFO_define\fP
this is the macro name and value.
For a
\f(CWDW_MACINFO_undef\fP, or
this is the macro name.
For a
\f(CWDW_MACINFO_vendor_ext\fP
this is the vendor-defined string value.
For other \f(CWdmd_type\fPs this is 0.
.H 2 "Opaque Types"
The opaque types declared in \fIlibdwarf.h\fP are used as descriptors
for queries against DWARF information stored in various debugging
sections. Each time an instance of an opaque type is returned as a
result of a \fIlibdwarf\fP operation (\f(CWDwarf_Debug\fP excepted),
it should be freed, using \f(CWdwarf_dealloc()\fP when it is no longer
of use (read the following documentation for details, as in at least
one case there is a special routine provided for deallocation
and \f(CWdwarf_dealloc()\fP is not directly called:
see \f(CWdwarf_srclines()\fP).
Some functions return a number of instances of an opaque type
in a block, by means of a pointer to the block
and a count of the number
of opaque descriptors in the block:
see the function description for deallocation
rules for such functions.
The list of opaque types defined in
\fIlibdwarf.h\fP that are pertinent to the
Consumer Library, and their
intended use is described below.
This is not a full list of the opaque types, see libdwarf.h
for the full list.
.DS
\f(CWtypedef struct Dwarf_Debug_s* Dwarf_Debug;\fP
.DE
An instance of the
\f(CWDwarf_Debug\fP type is created as a result of a
successful call to
\f(CWdwarf_init_b()\fP, or
\f(CWdwarf_elf_init_b()\fP,
and is used as a descriptor for subsequent access to most
\f(CWlibdwarf\fP
functions on that object.
The storage pointed to by this descriptor
should be not be freed, using the
\f(CWdwarf_dealloc()\fP function.
Instead free it with
\f(CWdwarf_finish()\fP.
.P
.DS
\f(CWtypedef struct Dwarf_Die_s* Dwarf_Die;\fP
.DE
An instance of a \f(CWDwarf_Die\fP type is returned from a successful
call to the \f(CWdwarf_siblingof()\fP, \f(CWdwarf_child\fP, or
\f(CWdwarf_offdie_b()\fP function,
and is used as a descriptor for queries
about information related to that DIE. The storage pointed to by this
descriptor should be freed, using
\f(CWdwarf_dealloc()\fP with the allocation
type \f(CWDW_DLA_DIE\fP when no longer needed,
or, preferably, call
\f(CWdwarf_dealloc_die()\fP instead.
.DS
\f(CWtypedef struct Dwarf_Line_s* Dwarf_Line;\fP
.DE
Instances of
\f(CWDwarf_Line\fP type are returned from a successful call
to the
\f(CWdwarf_srclines()\fP function, and are used as descriptors for
queries about source lines.
The storage pointed to by these descriptors
should be individually freed, using
\f(CWdwarf_dealloc()\fP with the
allocation type
\f(CWDW_DLA_LINE\fP when no longer needed.
.DS
\f(CWtypedef struct Dwarf_Global_s* Dwarf_Global;\fP
.DE
Instances of \f(CWDwarf_Global\fP type are returned from a successful
call to the \f(CWdwarf_get_globals()\fP function, and are used as
descriptors for queries about global names (pubnames).
.DS
\f(CWtypedef struct Dwarf_Weak_s* Dwarf_Weak;\fP
.DE
Instances of
\f(CWDwarf_Weak\fP type are returned from a successful call
to the
SGI-specific \f(CWdwarf_get_weaks()\fP
function, and are used as descriptors for
queries about weak names. The storage pointed to by these descriptors
should be individually freed, using \f(CWdwarf_dealloc()\fP with the
allocation type
\f(CWDW_DLA_WEAK_CONTEXT\fP
(or
\f(CWDW_DLA_WEAK\fP, an older name, supported for compatibility)
when no longer needed.
.DS
\f(CWtypedef struct Dwarf_Func_s* Dwarf_Func;\fP
.DE
Instances of \f(CWDwarf_Func\fP type are returned from a successful
call to the
SGI-specific \f(CWdwarf_get_funcs()\fP
function, and are used as
descriptors for queries about static function names.
.DS
\f(CWtypedef struct Dwarf_Type_s* Dwarf_Type;\fP
.DE
Instances of
\f(CWDwarf_Type\fP type are returned from a successful call
to the
SGI-specific \f(CWdwarf_get_types()\fP
function, and are used as descriptors for
queries about user defined types.
.DS
\f(CWtypedef struct Dwarf_Var_s* Dwarf_Var;\fP
.DE
Instances of
\f(CWDwarf_Var\fP type are returned from a successful call
to the SGI-specific \f(CWdwarf_get_vars()\fP
function, and are used as descriptors for
queries about static variables.
.DS
\f(CWtypedef struct Dwarf_Error_s* Dwarf_Error;\fP
.DE
This descriptor points to a structure that provides
detailed information about errors detected by
\f(CWlibdwarf\fP.
Users typically provide a location
for \f(CWlibdwarf\fP to store this descriptor for
the user to obtain more information about the error.
The storage pointed to by this descriptor should
be freed, using
\f(CWdwarf_dealloc()\fP with the
allocation type
\f(CWDW_DLA_ERROR\fP when no longer
needed or, preferably,
call
\f(CWdwarf_dealloc_error()\fP instead.
.DS
\f(CWtypedef struct Dwarf_Attribute_s* Dwarf_Attribute;\fP
.DE
Instances of
\f(CWDwarf_Attribute\fP type are returned from a successful
call to the
\f(CWdwarf_attrlist()\fP, or \f(CWdwarf_attr()\fP functions,
and are used as descriptors for queries about attribute values.
The storage
pointed to by this descriptor should be individually freed, using
\f(CWdwarf_dealloc()\fP with the allocation type
\f(CWDW_DLA_ATTR\fP when
no longer needed, or call
\f(CWdwarf_dealloc_attribute()\fP
instead.
.DS
\f(CWtypedef struct Dwarf_Abbrev_s* Dwarf_Abbrev;\fP
.DE
An instance of a \f(CWDwarf_Abbrev\fP
type is returned from a successful call to
\f(CWdwarf_get_abbrev()\fP, and is used as a
descriptor for queries about abbreviations in
the .debug_abbrev section.
The storage pointed
to by this descriptor should be freed, using
\f(CWdwarf_dealloc()\fP with the allocation type
\f(CWDW_DLA_ABBREV\fP when no longer needed.
.DS
\f(CWtypedef struct Dwarf_Fde_s* Dwarf_Fde;\fP
.DE
Instances of \f(CWDwarf_Fde\fP type
are returned from a successful call
to the \f(CWdwarf_get_fde_list()\fP,
\f(CWdwarf_get_fde_for_die()\fP, or
\f(CWdwarf_get_fde_at_pc()\fP functions, and are used
as descriptors for queries about frames descriptors.
.DS
\f(CWtypedef struct Dwarf_Cie_s* Dwarf_Cie;\fP
.DE
Instances of \f(CWDwarf_Cie\fP type are returned from
a successful call to the \f(CWdwarf_get_fde_list()\fP
function, and are used as descriptors for queries
about information that is common to several frames.
.DS
\f(CWtypedef struct Dwarf_Arange_s* Dwarf_Arange;\fP
.DE
Instances of \f(CWDwarf_Arange\fP type
are returned from successful calls
to the \f(CWdwarf_get_aranges()\fP, or
\f(CWdwarf_get_arange()\fP functions, and are used
as descriptors for queries about address ranges.
The storage pointed to by this descriptor should be
individually freed, using \f(CWdwarf_dealloc()\fP
with the allocation type \f(CWDW_DLA_ARANGE\fP when
no longer needed.
.DS
\f(CWtypedef struct Dwarf_Gdbindex_s* Dwarf_Gdbindex;\fP
.DE
Instances of \f(CWDwarf_Gdbindex\fP type
are returned from successful calls to the
\f(CWdwarf_gdbindex_header()\fP function and are
used to extract information from a .gdb_index
section. This section is a gcc/gdb extension
and is designed to allow a debugger fast access
to data in .debug_info. The storage pointed to
by this descriptor should be freed using a call
to \f(CWdwarf_gdbindex_free()\fP with a valid
\f(CWDwarf_Gdbindex\fP pointer as the argument.
.DS
\f(CWtypedef struct Dwarf_Xu_Index_Header_s* Dwarf_Xu_Index_header;\fP
.DE
Instances of \f(CWDwarf_Xu_Index_Header_s\fP
type are returned from successful calls to the
\f(CWdwarf_get_xu_index_header()\fP function and are
used to extract information from a .debug_cu_index
or .debug_tu_index section.
These sections are used
to make possible access to .dwo sections gathered
into a .dwp object as part of the DebugFission
(ie Split Dwarf)
project allowing separation of an executable from
most of its DWARF debugging information.
As of May
2015 these sections are accepted into DWARF5 but
the standard has not been released.
The storage
pointed to by this descriptor should be freed using
a call to
\f(CWdwarf_xh_header_free()\fP with a valid
\f(CWDwarf_XuIndexHeader\fP pointer as the argument.
.DS
\f(CWtypedef struct Dwarf_Line_Context_s * Dwarf_Line_Context;\fP
.DE
\f(CWdwarf_srclines_b()\fP returns a
Dwarf_Line_Context through an argument
and the new structure pointer lets us access line header information
conveniently.
.DS
\f(CWtypedef struct Dwarf_Locdesc_c_s * Dwarf_Locdesc_c;\fP
\f(CWtypedef struct Dwarf_Loc_Head_c_s * Dwarf_Loc_Head_c;\fP
.DE
\f(CWDwarf_Loc*\fP are involved in the DWARF5
interfaces to location lists.
The new interfaces are all functional and contents
of the above types
are not exposed.
.DS
\f(CWtypedef struct Dwarf_Macro_Context_s * Dwarf_Macro_Context;\fP
.DE
\f(CWdwarf_get_macro_context()\fP
and
\f(CWdwarf_get_macro_context_by_offset()\fP
return a Dwarf_Line_Context through an argument
and the new structure pointer lets us access
macro data from the .debug_macro section.
.DS
\f(CWtypedef struct Dwarf_Dsc_Head_s * Dwarf_Dsc_Head;\fP
.DE
\f(CWdwarf_discr_list()\fP
returns a Dwarf_Dsc_Head through an argument
and the new structure pointer lets us access
macro data from a
\f(CWDW_AT_discr_list\fP
attribute.
.H 1 "UTF-8 strings"
\fIlibdwarf\fP
is defined, at various points, to return
string pointers or to copy strings into
string areas you define.
DWARF allows the use of
\f(CWDW_AT_use_UTF8\fP
(DWARF3 and later)
\f(CWDW_ATE_UTF\fP
(DWARF4 and later)
to specify that the strings returned are actually
in UTF-8 format.
What this means is that if UTF-8 is specified on
a particular object it is up to callers that wish
to print all the characters properly to use language-appropriate
functions to print Unicode strings appropriately.
All ASCII characters in the strings will print properly
whether printed as wide characters or not.
The methods to convert UTF-8 strings so they will print
correctly for all such strings
is beyond the scope of this document.
.P
If UTF-8 is not specified then one is probably safe
in assuming the strings are iso_8859-15 and normal
C printf() will work fine..
.P
In either case one should be wary of corrupted
(accidentally or intentionally)
strings
with ASCII control characters in the text.
Such can cause bad effects if simply printed to a device
(such as a terminal).
.H 1 "Error Handling"
The method for detection and disposition of
error conditions that arise
during access of debugging information via
\fIlibdwarf\fP is consistent
across all
\fIlibdwarf\fP
functions that are capable of producing an
error. This section describes the method used by
\fIlibdwarf\fP in
notifying client programs of error conditions.
.P
Most functions within
\fIlibdwarf\fP accept as an argument a pointer to
a
\f(CWDwarf_Error\fP descriptor where a
\f(CWDwarf_Error\fP descriptor
is stored if an error is detected by the function.
Routines in the client
program that provide this argument can query the
\f(CWDwarf_Error\fP
descriptor to determine the nature of the error
and perform appropriate
processing.
The intent is that clients do the appropriate processing
immediately on encountering an error and then the client
calls
\f(CWdwarf_dealloc_error\fP to free the
Dwarf_Error descriptor (at which point the client
should zero that descriptor as the non-zero value is stale).
.P
We think the following is appropriate
as a general outline. See dwarfdump source
for many examples of both of the following
incomplete examples.
.in +2
.DS
\f(CW
int example_codea{Dwarf_Debug dbg,Dwarf_Die indie,
int is_info, Dwarf_Die *sibdie, Dwarf_Error *err)
{
int res = 0;
const char *secname = 0;
res = dwarf_siblingof_b(dbg,indie,is_info,sibdie,
err);
if (res == DW_DLV_ERROR) {
return res; /*let higher level decide what to do
and it will eventually need to do
dwarf_dealloc_error() appropriately */
} else if (res == DW_DLV_NO_ENTRY) {
/* No sibdie created. Nothing done. *.
return res;
}
/* sibdie created, caller will have to eventually
do dwarf_dealloc_die() appropriately. */
...
return DW_DLV_OK;
}
\fP
.DE
.in -2
.P
In a case where it is ok to suppress the error as
being unimporant, this is an outline, not
a useful function.
.in +2
.DS
\f(CW
int example_codeb{Dwarf_Debug dbg, const char **sec_name,
int is_info)
{
Dwarf_Error e = 0;
int res = 0;
res = dwarf_get_die_section_name(dbg,is_info,
sec_name, &e);
if (res == DW_DLV_ERROR) {
dwarf_dealloc_error(e);
e = 0;
return res; /*let higher level decide what to do,
Nothing allocated in the call still exists. */
} if (res == DW_DLV_NO_ENTRY) {
....
}
...
}
\fP
.DE
.in -2
.P
In the rare case where the malloc arena is exhausted when
trying to create a Dwarf_Error descriptor a
pointer to a statically allocated
descriptor will be returned.
This static descriptor is new in December 2014.
A call to
\f(CWdwarf_dealloc()\fP
to free the statically
allocated descriptor is harmless (it sets the error value
in the descriptor to DW_DLE_FAILSAFE_ERRVAL).
The possible conflation of errors when the arena
is exhausted
(and a dwarf_error descriptor is saved past
the next reader call in any thread)
is considered better than having
\fIlibdwarf\fP
call
\f(CWabort()\fP (as earlier
\fIlibdwarf\fP
did).
.P
We strongly suggest most applications calling
\fIlibdwarf\fP
follow the suggestion above (passing a valid
Dwarf_Error address in the last argument when
calling
\fIlibdwarf\fP
where there are such
Dwarf_Error arguments) there are other approaches
described just below that might be
worth considering
in small simple applications as they reduce the Dwarf_Error
argument to just passing 0 (null pointer)..
.P
The cases that arise when passing a null
for the Dwarf_Error and where there
is an error detected are
A) with an error handler
function libdwarf will call that function
and on return to
\fIlibdwarf\fP,
\fIlibdwarf\fP
will
return
\f(CWDW_DLV_ERROR\fP
to the original client call..
or
B) with no error handler
function (see below) libdwarf will print an error
and call \f(CWabort()\fP.
.P
.AL A
.LI
For the error-handler case
a client program can specify a function to be
invoked upon detection of an error at the time the
library is initialized (see
\f(CWdwarf_init_b()\fP
or
\f(CWdwarf_init_path()\fP
for example).
When a \fIlibdwarf\fP routine detects an error,
this function is called with two arguments: a code
indicating the nature of the error and a pointer
provided by the client at initialization (again
see
\f(CWdwarf_init_b()\fP
or
\f(CWdwarf_init_path()\fP).
This pointer argument
can be used to relay information between the error
handler and other routines of the client program.
A client program can specify or change both the
error handling function and the pointer argument
after initialization using
\f(CWdwarf_seterrhand()\fP
and
\f(CWdwarf_seterrarg()\fP.
When the client error function returns
libdwarf returns
\f(CWDW_DLV_ERROR\fP.
.P
If the client passed in a non-null
\f(CWerror\fP
argument in the libdwarf
call finding an error, the
\f(CWdwarf_seterrhand()\fP
function-invocation mentioned here does
not happen.
.P
.LI
In the final case, where
\fIlibdwarf\fP
functions are not provided a pointer
to a \f(CWDwarf_Error\fP descriptor,
and no error handling function was
provided at initialization,
\fIlibdwarf\fP functions
print a short message to
\f(CWstdout\fP
and terminate exectution with
\f(CWabort()\fP.
.P
Before March 2016
\fIlibdwarf\fP
gave up when there was no error handling
by
emitting a short message on
\f(CWstderr\fP
and
calling \f(CWabort(3C)\fP.
.LE
.P
The following lists the processing steps taken upon detection of an
error:
.AL 1
.LI
Check the \f(CWerror\fP argument; if not a
\fINULL\fP pointer, allocate and initialize a
\f(CWDwarf_Error\fP descriptor with information
describing the error, place this descriptor in the
area pointed to by \f(CWerror\fP, and return a value
indicating an error condition.
.LI
If an \f(CWerrhand\fP argument was provided to
\f(CWdwarf_init_b()\fP at initialization, call
\f(CWerrhand()\fP passing it the error descriptor and
the value of the \f(CWerrarg\fP argument provided
to \f(CWdwarf_init_b()\fP. If the error handling
function returns, return \f(CWDW_DLV_ERROR\fP
indicating an error condition.
.LI
If neither the \f(CWerror\fP argument nor
an \f(CWerrhand\fP argument was provided
Terminate program execution by calling
\f(CWabort(3C)\fP.
.LE
.SP
In all cases, it is clear from the value returned
from a function that an error occurred in executing
the function, since DW_DLV_ERROR is returned.
.P
As can be seen from the above steps, the
client program can provide an error handler at
initialization, and still provide an \f(CWerror\fP
argument to \fIlibdwarf\fP functions when it is not
desired to have the error handler invoked.
.P
If a \f(CWlibdwarf\fP function is called with
invalid arguments, the behavior is undefined.
In particular, supplying a \f(CWNULL\fP pointer to a
\f(CWlibdwarf\fP function (except where explicitly
permitted), or pointers to invalid addresses or
uninitialized data causes undefined behavior;
the return value in such cases is undefined, and
the function may fail to invoke the caller supplied
error handler or to return a meaningful error number.
Implementations also may abort execution for such
cases.
.P
Some errors are so inconsequential that it does not
warrant rejecting an object or returning an error.
Examples would be a frame length not being a
multiple of an address-size,
an arange in .debug_aranges has some padding
bytes, or a relocation could not be completed.
To make it
possible for a client to report such errors the
function \f(CWdwarf_get_harmless_error_list\fP
returns strings with error text in them.
This function may be ignored if client code does
not want to bother with such error reporting.
.P
.H 2 "Returned values in the functional interface"
Values returned by \f(CWlibdwarf\fP functions to indicate
success and errors
.nr aX \n(Fg+1
are enumerated in Figure \n(aX.
The \f(CWDW_DLV_NO_ENTRY\fP
case is useful for functions
need to indicate that while there was no data to return
there was no error either.
For example,
\f(CWdwarf_siblingof()\fP
may return
\f(CWDW_DLV_NO_ENTRY\fP to indicate that that there was
no sibling to return.
.DS
.TS
center box, tab(:);
lfB cfB lfB
l c l.
SYMBOLIC NAME:VALUE:MEANING
_
DW_DLV_ERROR:1:Error
DW_DLV_OK:0:Successful call
DW_DLV_NO_ENTRY:-1:No applicable value
.TE
.FG "Error Indications"
.DE
.P
Each function in the interface that returns a value returns one
of the integers in the above figure.
.P
If \f(CWDW_DLV_ERROR\fP is returned and a pointer
to a \f(CWDwarf_Error\fP pointer is passed to the
function, then a Dwarf_Error handle is returned
through the pointer. No other pointer value
in the interface returns a value. After the
\f(CWDwarf_Error\fP is no longer of interest, a
\f(CWdwarf_dealloc(dbg,dw_err,DW_DLA_ERROR)\fP on
the error pointer is appropriate to free any space
used by the error information.
.P
If \f(CWDW_DLV_NO_ENTRY\fP is returned no pointer value in the
interface returns a value.
.P
If \f(CWDW_DLV_OK\fP is returned, the
\f(CWDwarf_Error\fP pointer, if supplied, is not
touched, but any other values to be returned through
pointers are returned.
In this case calls (depending
on the exact function returning the error) to
\f(CWdwarf_dealloc()\fP may be appropriate once the
particular pointer returned is no longer of interest.
.P
Pointers passed to allow values to be
returned through them are
uniformly the last pointers
in each argument list.
.P
All the interface functions are defined from the
point of view of the writer-of-the-library (as is
traditional for UN*X library documentation), not
from the point of view of the user of the library.
The caller might code:
.P
.DS
\f(CWDwarf_Line line;
Dwarf_Signed ret_loff;
Dwarf_Error err;
int retval = dwarf_lineoff(line,&ret_loff,&err);\fP
.DE
for the function defined as
.P
.DS
\f(CWint dwarf_lineoff(Dwarf_Line line,
Dwarf_Signed *return_lineoff,
Dwarf_Error* err);\fP
.DE
and this document refers to the function as
returning the value through *err or *return_lineoff or
uses the phrase "returns in
the location pointed to by err".
Sometimes other similar phrases are used.
.H 1 "Memory Management"
Several of the functions that comprise \fIlibdwarf\fP
return pointers (opaque descriptors) to structures
that have been dynamically allocated by the
library. To manage dynamic memory the function
\f(CWdwarf_dealloc()\fP
is provided to free storage
allocated as a result of a call to a \fIlibdwarf\fP
function. Some additional functions (described
later) are provided to free storage in particular
circumstances. This section describes the general
strategy that should be taken by a client program
in managing dynamic storage.
.P
By default
\f(CWlibdwarf\fP
tracks its allocations and
\f(CWdwarf_finish()\fP
cleans up allocations
where
\f(CWdwarf_dealloc()\fP
was not called.
See
\f(CWdwarf_set_de_alloc_flag()\fP
below.
.H 2 "Read-only Properties"
All pointers (opaque descriptors) returned by or as a result of a
\fIlibdwarf Consumer Library\fP
call should be assumed to point to read-only memory.
The results are undefined for \fIlibdwarf\fP clients that attempt
to write to a region pointed to by a value returned by a
\fIlibdwarf Consumer Library\fP
call.
.H 2 "Storage Deallocation"
See the section "Returned values in the functional interface",
above, for the general rules where
calls to \f(CWdwarf_dealloc()\fP
are appropriate.
.P
As of May 2020 there are additional dealloc calls
which enable type-checking the calls:
\f(CWdwarf_dealloc_error()\fP,
\f(CWdwarf_dealloc_die()\fP, and
\f(CWdwarf_dealloc_attribute()\fP.
.P
.H 3 "dwarf_dealloc()"
The first prototype is the generic one that can
dealloc any of the libdwarf types, such as DW_DLA_DIE etc..
This has the disadvantages that the
\f(CWspace_to_dealloc\fP
argument
cannot be type checked and the
\f(CWappropriate_dla_name\fP
is a simple integer, hence not meaningfully
checkable either.
.P
Whenever possible, use
a type-safe deallocation call
(for several types that is the only
documented deallocation call)
and for
\f(CWDwarf_Die\fP
\f(CWDwarf_Attribute\fP
or
\f(CWDwarf_Error\fP
use the
following dealloc functions instead
of this one.
The use of this form remains fully supported,
.P
.DS
\f(CWvoid dwarf_dealloc(Dwarf_Debug dbg,
void *space_to_dealloc,
int appropriate_dla_name);\fP
.DE
.in +2
.DS
.FG "Example_dwarf_dealloc()"
\f(CW
void exampledealloc(Dwarf_Debug dbg,Dwarf_Die somedie)
{
dwarf_dealloc(dbg,somedie,DW_DLA_DIE);
}
\fP
.DE
.in -2
.H 3 "dwarf_dealloc_die()"
The second prototype is only to dealloc a Dwarf_Die.
Any call to this is typechecked.
.P
.DS
\f(CWvoid dwarf_dealloc_die(Dwarf_Die mydie);\fP
.DE
.in +2
.DS
.FG "Example_dwarf_dealloc_die()"
\f(CW
void exampledeallocdie(Dwarf_Die somedie)
{
dwarf_dealloc_die(somedie);
}
\fP
.DE
.in -2
.H 3 "dwarf_dealloc_attribute()"
The second prototype is only to dealloc a Dwarf_Attribute.
These arise from calls from
\f(CWdwarf_attrlist()\fP
Any call to this is typechecked.
.P
.DS
\f(CWvoid dwarf_dealloc_error(Dwarf_Debug dbg,
Dwarf_Die mydie);\fP
.DE
.in +2
.DS
.FG "Example_dwarf_dealloc_attribute()"
\f(CW
void exampledeallocerror(Dwarf_Attribute attr)
{
dwarf_dealloc_attribute(attr);'
}
\fP
.DE
.in -2
.H 3 "dwarf_dealloc_error()"
The second prototype is only to dealloc a Dwarf_Error.
These arise when some libdwarf call returns DW_DLV_ERROR.
Any call to this is typechecked.
.P
.DS
\f(CWvoid dwarf_dealloc_error(Dwarf_Debug dbg,
Dwarf_Die mydie);\fP
.DE
.in +2
.DS
.FG "Example_dwarf_dealloc_error()"
\f(CW
void exampledeallocerror(Dwarf_Debug dbg,Dwarf_Error err)
{
dwarf_dealloc_error(dbg,err);'
}
\fP
.DE
.in -2
.P
See also
\f(CWErrors Returned from dwarf_init* calls\fP
(below).
In some cases the pointers returned by a
\fIlibdwarf\fP call are pointers to data which is
not freeable.
The library knows from the allocation
type provided to it whether the space is freeable
or not and will not free inappropriately when
\f(CWdwarf_dealloc()\fP is called.
So it is vital
that \f(CWdwarf_dealloc()\fP be called with the
proper allocation type.
.P
For all storage allocated by \fIlibdwarf\fP, the
client can free the storage for reuse by calling
\f(CWdwarf_dealloc()\fP, providing it with the
\f(CWDwarf_Debug\fP descriptor specifying the
object for which the storage was allocated,
a pointer to the area to be free-ed, and an
identifier that specifies what the pointer points
to (the allocation type).
For example, to free
a \f(CWDwarf_Die die\fP belonging the the object
represented by \f(CWDwarf_Debug dbg\fP, allocated
by a call to \f(CWdwarf_siblingof()\fP, the call to
\f(CWdwarf_dealloc()\fP would be:
.DS
\f(CWdwarf_dealloc(dbg, die, DW_DLA_DIE);\fP
or, preferably,
\f(CWdwarf_dealloc_die(die);\fP
.DE
To free storage allocated in the
form of a list of pointers (opaque
descriptors), each member of the
list should be deallocated, followed
by deallocation of the actual list itself.
The following code fragment
uses an invocation of
\f(CWdwarf_attrlist()\fP as an example to illustrate
a technique that can be used to free storage
from any \fIlibdwarf\fP
routine that returns a list:
.in +2
.DS
.FG "Example1 dwarf_attrlist()"
\f(CW
void example1(Dwarf_Debug dbg,Dwarf_Die somedie)
{
Dwarf_Signed atcount = 0;
Dwarf_Attribute *atlist = 0;
Dwarf_Error error = 0;
Dwarf_Signed i = 0;
int errv = 0;
errv = dwarf_attrlist(somedie, &atlist,&atcount, &error);
if (errv == DW_DLV_OK) {
for (i = 0; i < atcount; ++i) {
/* use atlist[i] */
dwarf_dealloc_attribute(atlist[i]);
/* This origiginal form still works.
dwarf_dealloc(dbg, atlist[i], DW_DLA_ATTR);
*/
}
dwarf_dealloc(dbg, atlist, DW_DLA_LIST);
}
}
\fP
.DE
.in -2
\f(CWdwarf_finish()\fP
will deallocate all dynamic storage
associated with an instance of a
\f(CWDwarf_Debug\fP type.
In particular,
it will deallocate all
dynamically allocated space associated with the
\f(CWDwarf_Debug\fP
descriptor, and finally make the descriptor invalid.
.H 3 "Errors Returned from dwarf_init* calls"
These errors are almost always due to
fuzzing objects, injecting random
values into objects. Rarely seen in any
valid object file.
See "https://en.wikipedia.org/wiki/Fuzzing"
.P
A
\f(CWDwarf_Error\fP returned from
any
\f(CWdwarf_init*()\fP
or \f(CWdwarf_elf_init*()\fP
should be dealt with
like any other error.
We start with an example of
how to deal with this class of errors.
See just below the example for a further discussion.
.in +2
.DS
void exampleinitfail(const char *path,
char *true_pathbuf,
unsigned tpathlen,
unsigned access,
unsigned groupnumber)
{
Dwarf_Handler errhand = 0;
Dwarf_Ptr errarg = 0;
Dwarf_Error error = 0;
Dwarf_Debug dbg = 0;
const char *reserved1 = 0;
Dwarf_Unsigned reserved2 = 0;
Dwarf_Unsigned reserved3 = 0;
int res = 0;
res = dwarf_init_path(path,true_pathbuf,
tpathlen,access,groupnumber,errhand,
errarg,&dbg,reserved1,reserved2,
&reserved3,
&error);
/* Preferred version */
if (res == DW_DLV_ERROR) {
/* Valid call even though dbg is null! */
dwarf_dealloc(dbg,error,DW_DLA_ERROR);
/* Simpler newer form in
this comment, but use the
older form above for compatibility
with older libdwarf.
dwarf_dealloc_error(dbg,error);
With libdwarf before September 2020
these dealloc calls will leave
a few bytes allocated.
*/
/* The orginal recommendation to call
free(error) in this case is still
valid though it will not necessarily
free every byte allocated with
September 2020 and later libdwarf. */
}
/* Horrible messy alternative, best effort
if dwarf_package_version exists
(function created in October 2019
package version 20191106). */
if (res == DW_DLV_ERROR) {
const char *ver = dwarf_package_version();
int cmpres = 0;
cmpres = strcmp(ver,"20200822");
if (cmpres > 0) {
dwarf_dealloc_error(dbg,error);
} else {
free(error);
}
}
}
.DE
.in -2
.P
If your application needs to be absolutely
sure not even
a single byte leaks
from a failed libdwarf init function call
the only sure approach is to ensure you use
a September 2020 (version 20200908) or later libdwarf.
Versions between 20191104 and 20200908
have no available function that will
guarantee freeing these last few bytes.
.P
If your application does not care if
a failed libdwarf init function leaks a few
bytes then the September 2020 advice
of calling dwarf_dealloc(dbg,error,DW_DLA_ERROR)
is best, as though leaks a few bytes
with libdwarf before September 2020.
.P
If your application is using 20191104 or earlier
libdwarf the choice of free(error)
will avoid a leak from a failed
dwarf init call, though changing
to a more recent libdwarf
will then make a few bytes leak quite
possible until the application is changed
to use the dwarf_dealloc call.
.H 3 "Error DW_DLA error free types"
The codes that identify the storage pointed to in calls to
.nr aX \n(Fg+1
\f(CWdwarf_dealloc()\fP are described in figure \n(aX.
.DS
.TS
center box, tab(:);
lfB lfB
l l.
IDENTIFIER:USED TO FREE
_
DW_DLA_STRING : char*
DW_DLA_LOC : Dwarf_Loc
DW_DLA_LOCDESC : Dwarf_Locdesc
DW_DLA_ELLIST : Dwarf_Ellist (not used)
DW_DLA_BOUNDS : Dwarf_Bounds (not used)
DW_DLA_BLOCK : Dwarf_Block
DW_DLA_DEBUG : Dwarf_Debug (do not use)
DW_DLA_DIE : Dwarf_Die
DW_DLA_LINE : Dwarf_Line
DW_DLA_ATTR : Dwarf_Attribute
DW_DLA_TYPE : Dwarf_Type (not used)
DW_DLA_SUBSCR : Dwarf_Subscr (not used)
DW_DLA_GLOBAL : Dwarf_Global
DW_DLA_ERROR : Dwarf_Error
DW_DLA_LIST : a list of opaque descriptors
DW_DLA_LINEBUF : Dwarf_Line* (not used)
DW_DLA_ARANGE : Dwarf_Arange
DW_DLA_ABBREV : Dwarf_Abbrev
DW_DLA_FRAME_OP : Dwarf_Frame_Op
DW_DLA_CIE : Dwarf_Cie
DW_DLA_FDE : Dwarf_Fde
DW_DLA_LOC_BLOCK : Dwarf_Loc Block
DW_DLA_FRAME_BLOCK : Dwarf_Frame Block (not used)
DW_DLA_FUNC : Dwarf_Func
DW_DLA_TYPENAME : Dwarf_Type
DW_DLA_VAR : Dwarf_Var
DW_DLA_WEAK : Dwarf_Weak
DW_DLA_ADDR : Dwarf_Addr
DW_DLA_RANGES : Dwarf_Ranges
DW_DLA_GNU_INDEX_HEAD : .debug_gnu_type/pubnames
DW_DLA_RNGLISTS_HEAD : .debug_rnglists
DW_DLA_DGBINDEX : Dwarf_Gdbindex
DW_DLA_XU_INDEX : Dwarf_Xu_Index_Header
DW_DLA_LOC_BLOCK_C : Dwarf_Loc_c
DW_DLA_LOCDESC_C : Dwarf_Locdesc_c
DW_DLA_LOC_HEAD_C : Dwarf_Loc_Head_c
DW_DLA_MACRO_CONTEXT : Dwarf_Macro_Context
DW_DLA_DSC_HEAD : Dwarf_Dsc_Head
DW_DLA_DNAMES_HEAD : Dwarf_Dnames_Head
DW_DLA_STR_OFFSETS : Dwarf_Str_Offsets_Table
.TE
.FG "Allocation/Deallocation Identifiers"
.DE
.P
.H 1 "Functional Interface"
This section describes the functions available in the \fIlibdwarf\fP
library. Each function description includes its definition, followed
by one or more paragraph describing the function's operation.
.P
The following sections describe these functions.
.H 2 "Initialization Operations"
These functions are concerned with preparing an object file for subsequent
access by the functions in \fIlibdwarf\fP and with releasing allocated resources when access is complete.
\f(CWdwarf_init_path()\fP
or
\f(CWdwarf_init_path_dl()\fP
are the initialization functions
to use if one actually has a path
(if you just have an open fd or
open libelf handle you cannot
use the _path_ versions that's fine).
These both allow libdwarf to attempt
to follow
\f(CWGNU debuglink\fP
hints in a specially produced
executable/shared-object to find
the object file with the DWARF
sections to match tne executable(or
shared-object).
For non-debuglink executables
these two functions behave identically.
.P
\f(CWGNU debuglink\fP
is completely
different than and separate from Split Dwarf
and MacOS dSYM.
it would seem unlikely that these
could be combined in any
single executable/shared-object.
All are intended to have DWARF fully
available but not taking space in the
executable/shared object.
See
https://sourceware.org/gdb/onlinedocs/gdb/Separate-Debug-Files.html
for information on debuglink and the related build-id.
.P
\f(CWdwarf_init_path()\fP provides
no way
to add extra global paths to debuglink searches.
But
\f(CWdwarf_init_path_dl()\fP
has 2 extra arguments to make adding extra paths
easy.
.P
libdwarf lets one access the executable's
section .eh_frame with frame/backtrace
information by turning off recognition of
\f(CWGNU debuglink\fP in the Dwarf_Debug
being opened by passing in
\f(CWtrue_path_out_buffer\fP
\f(CWtrue_path_bufferlen\fP
as zero.
.H 3 "dwarf_init_path()"
.DS
\f(CWint dwarf_init_path(
const char * path,
char * true_path_out_buffer,
unsigned true_path_bufferlen,
Dwarf_Unsigned access,
unsigned groupnumber,
Dwarf_Handler errhand,
Dwarf_Ptr errarg,
Dwarf_Debug* dbg,
const char * reserved1,
Dwarf_Unsigned * reserved2,
Dwarf_Unsigned * reserved3,
Dwarf_Error* * error);
.DE
On success the function returns
\f(CWDW_DLV_OK\fP,
and returns a pointer to an initialized
Dwarf_Debug through the dbg argument.
All this work identically across all supported
object file types.
.P
If
\f(CWDW_DLV_NO_ENTRY\fP
is returned there is no such
file and nothing else is done or returned.
.P
If
\f(CWDW_DLV_ERROR\fP is returned
a Dwarf_Error is returned through the error pointer.
and nothing else is done or returned.
.P
Now we turn to the arguments.
.P
Pass in the name of the object file via
the
\f(CWpath\fP
argument.
.P
For MacOS
pass in a pointer
to \f(CWtrue_path_out_buffer\fP
big pointing to a buffer
large enough to hold the passed-in
path if that were doubled plus adding 100 characters.
Then pass that length in the
\f(CWtrue_path_bufferlen\fP argument.
If a file is found (the dSYM
path or if not that the original path)
the final path
is copied into
\f(CWtrue_path_out_buffer\fP.
In any case,
This is harmless with non-MacOS
executables, but for non-MacOS
non
\f(CWGNU_debuglink\fP objects
\f(CWtrue_path_out_buffer\fP
will just match
\f(CWpath\fP.
.P
For Elf executables/shared-objects
using
\f(CWGNU_debuglink\fP
The same considerations apply:
pass in a pointer
to \f(CWtrue_path_out_buffer\fP
big pointing to a buffer
large enough to hold the passed-in
path if that were doubled plus adding 100 characters
(a heuristic)
(the 100 is arbitrary:
\f(CWGNU_debuglink\fP paths can be
long but not likely longer than this
suggested size.
.P
When
you know you won't be
reading MacOS executables
and won't be accessing
\f(CWGNU_debuglink\fP
executables
special treatment
by passing 0 as arguments to
\f(CWtrue_path_out_buffer\fP
and
\f(CWtrue_path_bufferlen\fP.
If those are zero the
\f(CWMacOS\fP/
\f(CWGNU_debuglink\fP
special processing will not occur.
.P
Pass in zero with the
\f(CWaccess\fP
\f(CW
\fP
argument.
The
\f(CWDW_DLC_READ\fP
flag,
which only ever applied to libelf,
is zero.
.P
The
\f(CWgroupnumber\fP argument indicates which group is to
be accessed Group one is normal dwarf sections such as
\f(CW.debug_info\fP.
Group two is DWARF5 dwo split-dwarf dwarf
sections such as .debug_info.dwo.
Groups three and higher are for COMDAT groups. If an object
file has only sections from one of the groups then passing
zero will access that group. Otherwise passing zero will
access only group one.
See
\f(CWdwarf_sec_group_sizes()\fP
and
\f(CWdwarf_sec_group_map()\fP
for more group information.
Typically
pass in DW_GROUPNUMBER_ANY
to
\f(CWgroupnumber\fP.
Non-elf objects do not use
this field.
.P
The \f(CWerrhand\fP
argument is a pointer to a function that will be
invoked whenever an error is detected as a result of
a \fIlibdwarf\fP operation. The \f(CWerrarg\fP
argument is passed as an argument to the
\f(CWerrhand\fP function.
.P
\f(CWdbg\fP
is used to return an initialized Dwarf_Debug pointer.
.P
\f(CWreserved1\fP,
\f(CWreserved2\fP,
and
\f(CWreserved3\fP
are currently unused, pass 0
in to all three.
.P
Pass in a pointer
to a Dwarf_Error to the
\f(CWerror\fP
argument
if you wish libdwarf to return an
error code.
.H 3 "dwarf_init_path_dl()"
.DS
\f(CWint dwarf_init_path_dl(
const char * path,
char * true_path_out_buffer,
unsigned true_path_bufferlen,
Dwarf_Unsigned access,
unsigned groupnumber,
Dwarf_Handler errhand,
Dwarf_Ptr errarg,
char ** global_paths,
unsigned int global_paths_count
Dwarf_Debug* dbg,
const char * reserved1,
Dwarf_Unsigned * reserved2,
Dwarf_Unsigned * reserved3,
Dwarf_Error* * error);
\fP
.DE
This function is identical to
\f(CWdwarf_init_path()\fP
in every respect except if you
know that you must use special paths
to find the
\f(CWGNU debuglink\fP
target file with DWARF information.
.P
\f(CWglobal_paths\fP
allows you to specifiy such paths.
Pass in
\f(CWglobal_paths\fP
as a pointer to an array of
pointer-to-char, each
pointing to a global path string.
Pass in
\f(CWglobal_paths_count\fP
with the number of entries in the
pointer array.
Pass both as zero if there are
no debuglink global paths
other than the default standard
\f(CW/usr/lib/debug\fP.
.H 3 "dwarf_init_b()"
.DS
\f(CWint dwarf_init_b(
int fd,
Dwarf_Unsigned access,
unsigned group_number,
Dwarf_Handler errhand,
Dwarf_Ptr errarg,
Dwarf_Debug * dbg,
Dwarf_Error *error)\fP
.DE
When it returns
\f(CWDW_DLV_OK\fP,
the function \f(CWdwarf_init_b()\fP returns through
\f(CWdbg\fP a \f(CWDwarf_Debug\fP descriptor
that represents a handle for accessing
debugging records associated with
the open file descriptor \f(CWfd\fP.
\f(CWDW_DLV_NO_ENTRY\fP is returned if the object
does not contain DWARF debugging information.
\f(CWDW_DLV_ERROR\fP is returned if
an error occurred.
.P
The
\f(CWaccess\fP argument indicates what access is
allowed for the section.
The \f(CWDW_DLC_READ\fP macro value
is zero and
valid for read access (only read access
is defined or discussed in this document).
No value other than zero should be passed
in to these consumer/reader functions.
The value passed in is ignored.
.P
The
\f(CWgroupnumber\fP argument indicates which group is to
be accessed Group one is normal dwarf sections such as
\f(CW.debug_info\fP. Group two is DWARF5 dwo split-dwarf dwarf
sections such as .debug_info.dwo.
Groups three and higher are for COMDAT groups. If an object
file has only sections from one of the groups then passing
zero will access that group. Otherwise passing zero will
access only group one.
See
\f(CWdwarf_sec_group_sizes()\fP
and
\f(CWdwarf_sec_group_map()\fP
for more group information.
.P
The \f(CWerrhand\fP
argument is a pointer to a function that will be
invoked whenever an error is detected as a result of
a \fIlibdwarf\fP operation. The \f(CWerrarg\fP
argument is passed as an argument to the
\f(CWerrhand\fP function.
.P
The file descriptor associated with the \f(CWfd\fP
argument must refer to an ordinary file (i.e. not a
pipe, socket, device, /proc entry, etc.), be opened
with the at least as much permission as specified by
the \f(CWaccess\fP argument, and cannot be closed or
used as an argument to any system calls by the client
until after \f(CWdwarf_finish()\fP is called. The
seek position of the file associated with \f(CWfd\fP
is undefined upon return of \f(CWdwarf_init()\fP.
.P
Historical Note:
With SGI IRIX, by default it was allowed that
the app \f(CWclose()\fP \f(CWfd\fP immediately
after calling \f(CWdwarf_init()\fP, but that
is not a portable approach (that it worked was an
accidental side effect of the fact that SGI IRIX used
\f(CWELF_C_READ_MMAP\fP in its hidden internal call
to \f(CWelf_begin()\fP).
The portable approach is to
consider that \f(CWfd\fP must be left open till after
the corresponding dwarf_finish() call has returned.
.P
Since \f(CWdwarf_init()\fP uses the same error
handling processing as other \fIlibdwarf\fP functions
(see \fIError Handling\fP above), client programs
will generally supply an \f(CWerror\fP parameter
to bypass the default actions during initialization
unless the default actions are appropriate.
.H 3 "dwarf_init()"
.DS
\f(CWint dwarf_init(
int fd,
Dwarf_Unsigned access,
Dwarf_Handler errhand,
Dwarf_Ptr errarg,
Dwarf_Debug * dbg,
Dwarf_Error *error)\fP
.DE
\f(CWdwarf_init()\fP
is identical to
\f(CWdwarf_init_b()\fP
except that
\f(CWdwarf_init()\fP
is missing the groupnumber
argument so access to an object file containing
both dwo and non-dwo DWARF5 object sections will
access only group one (and will ignore the dwo sections).
.P
The \f(CWdwarf_get_elf()\fP
function
cannot succeed when using
\f(CWdwarf_init()\fP
or
\f(CWdwarf_init_b()\fP
or
\f(CWdwarf_init_path()\fP
to
open an object file.
.H 3 "dwarf_set_de_alloc_flag()"
.DS
\f(CWint dwarf_set_de_alloc_flag(
int v)\fP
.DE
\f(CWdwarf_set_de_alloc_flag()\fP
sets and returns a flag value
applying to the current running instance
of
\f(CWlibdwarf\fP.
It's action sets an internal value,
and that value should be set/changed
(if you wish to do that) before any
other
\f(CWlibdwarf\fP
calls.
.P
By default
\f(CWlibdwarf\fP keeps track of all its
internal allocations.
So if the documentation here says you should
do
\f(CWdwarf_dealloc()\fP
calls
(or other calls documented here
for specific functions) and you omit
some or all of them then
calling
\f(CWdwarf_finish()\fP
will clean up all those allocations
left undone.
.P
If you call
\f(CWdwarf_set_de_alloc_flag(0)\fP
then libdwarf will not keep track
of allocations so your code must do
all
\f(CWdwarf_dealloc()\fP calls
as defined below.
.P
If you call
\f(CWdwarf_set_de_alloc_flag(1)\fP
that sets/restores the setting to
its default value so from that point
all new internal allocations will be
tracked and
\f(CWdwarf_finish()\fP
can clean the new ones up.
.P
The return value of
\f(CWdwarf_set_de_alloc_flag()\fP
is the previous value of the internal flag:
One (1) is the default, meaning record allocations..
Zero (0) is the other possible value, meaning
do not record
\f(CWlibdwarf\fP
allocations.
.P
It is best to ignore this call unless you
have gigantic DWARF sections and you need
whatever percent speed improvement
from
\f(CWlibdwarf\fP
that you can get.
If you do use it
then by all means use tools such as cc --fsanitize...
or valgrind to ensure there are no leaks in your
application (at least given your test cases).
.P
The function name echos the spelling of a
\f(CWlibdwarf\fP-internal
field in
\f(CWstruct Dwarf_Debug_s\fP
named
\f(CWde_alloc_tree\fP.
.H 3 "Dwarf_Handler function"
This is an example of a valid error handler function.
A pointer to this (or another like it)
may be passed to
\f(CWdwarf_elf_init_b()\fP
or
\f(CWdwarf_init_b()\fP.
.DS
\f(CWstatic void
simple_error_handler(Dwarf_Error error, Dwarf_Ptr errarg)
{
printf("libdwarf error: %d %s\\n",
dwarf_errno(error), dwarf_errmsg(error));
exit(1);
}\fP
.DE
.P
This will only be called if an error is detected inside libdwarf
and the
Dwarf_Error
argument passed to libdwarf is NULL.
A Dwarf_Error will be created with the error number
assigned by the library and passed to the error handler.
.P
The second argument is a copy of the value passed in to
\f(CWdwarf_elf_init_b()\fP
or
\f(CWdwarf_init()\fP
as the
\f(CWerrarg()\fP argument.
Typically the init function would be passed
a pointer to an application-created struct
containing the data the application needs to
do what it wants to do in the error handler.
.P
In a language with exceptions or exception-like features
an exception could be thrown here.
Or the application could simply give up and call
\f(CWexit()\fP
as in the sample given above.
.H 3 "dwarf_elf_init_b() [deprecated 2019]"
.DS
\f(CWint dwarf_elf_init_b(
Elf * elf_file_pointer,
Dwarf_Unsigned access,
unsigned groupnumber,
Dwarf_Handler errhand,
Dwarf_Ptr errarg,
Dwarf_Debug * dbg,
Dwarf_Error *error)\fP
.DE
We recommend you change to calling
\f(CWdwarf_init_b()\fP
or
\f(CWdwarf_init_path()\fP
instead.
The
\f(CW
dwarf_elf_init()
\fP
and
\f(CW
dwarf_elf_init_b()
\fP
interfaces give no benefit
over the other interfaces
(other than allowing \f(CWdwarf_get_elf()\fP
to succeed).
.P
The function
\f(CWdwarf_elf_init_b()\fP is similar to
\f(CWdwarf_init_b()\fP
but
an open \f(CWElf *\fP pointer is passed instead of a file
descriptor so
\f(CWdwarf_get_elf()\fP
can succeed.
.P
The client is allowed to use the
\f(CWElf *\fP pointer
for its own purposes without restriction during the time the
\f(CWDwarf_Debug\fP
is open, except that the client should not \f(CWelf_end()\fP the
pointer till after
\f(CWdwarf_finish\fP is called.
.H 3 "dwarf_elf_init() [deprecated 2019]"
.DS
\f(CWint dwarf_elf_init(
Elf * elf_file_pointer,
Dwarf_Unsigned access,
Dwarf_Handler errhand,
Dwarf_Ptr errarg,
Dwarf_Debug * dbg,
Dwarf_Error *error)\fP
.DE
The function
\f(CWdwarf_elf_init()\fP is identical to
\f(CWdwarf_init[_b]()\fP
except
an open \f(CWElf *\fP pointer is passed instead of a file
descriptor so
\f(CWdwarf_get_elf()\fP
can succeed.
.P
Code using
\f(CWdwarf_elf_init[_b]()\fP
should be switched to calling
\f(CWdwarf_init_b()\fP.
.H 3 "dwarf_get_elf()"
.DS
\f(CWint dwarf_get_elf(
Dwarf_Debug dbg,
Elf ** elf,
Dwarf_Error *error)\fP
.DE
.P
The function \f(CWdwarf_get_elf()\fP
is only meaningful if a
\f(CWdwarf_elf_init[_b]()\fP
function was used to initialize the pointer
\f(CWdbg\fP.
None of the other dwarf*init*() functions here
ever use libelf, so
there is no elf pointer to return through
the pointer, so
and the call will return
\f(CWDW_DLV_NO_ENTRY\fP.
In addition,
this function is also not meaningful for an object file
that is not in the Elf format.
.P
When it returns \f(CWDW_DLV_OK\fP,
the function \f(CWdwarf_get_elf()\fP returns through the
pointer \f(CWelf\fP the \f(CWElf *\fP handle
used to access the object represented by the \f(CWDwarf_Debug\fP
descriptor \f(CWdbg\fP.
It returns \f(CWDW_DLV_ERROR\fP on error.
.H 3 "dwarf_set_tied_dbg()"
.DS
\f(CWint dwarf_set_tied_dbg(
Dwarf_Debug dbg,
Dwarf_Debug tieddbg,
Dwarf_Error *error)\fP
.DE
The function
\f(CWdwarf_set_tied_dbg()\fP
enables cross-object
access of DWARF data.
If a DWARF5 Package object
has
\f(CWDW_FORM_addrx\fP
or
\f(CWDW_FORM_GNU_addr_index\fP
or one of the other indexed forms in DWARF5
in an address attribute
one needs both the Package file
and the executable to extract the actual address with
\f(CWdwarf_formaddr()\fP.
The utility function
\f(CWdwarf_addr_form_is_indexed(form)\fP
is a handy way to know if an address form is
indexed.
One does a normal
\f(CWdwarf_elf_init_b()\fP
or
\f(CWdwarf_init()_b\fP
on each object and then tie the two together with
a call such as:
.in +2
.DS
.FG "Example2 dwarf_set_died_dbg()"
\f(CW
void example2(Dwarf_Debug dbg, Dwarf_Debug tieddbg)
{
Dwarf_Error error = 0;
int res = 0;
/* Do the dwarf_init_b() or dwarf_elf_init_b()
calls to set
dbg, tieddbg at this point. Then: */
res = dwarf_set_tied_dbg(dbg,tieddbg,&error);
if (res != DW_DLV_OK) {
/* Something went wrong*/
}
}
\fP
.DE
.in -2
When done with both dbg and tieddbg
do the normal finishing operations on both
in any order.
It is possible to undo the tieing operation with
.in +2
.FG "Example3 dwarf_set_tied_dbg() obsolete"
.DS
\f(CW
void example3(Dwarf_Debug dbg)
{
Dwarf_Error error = 0;
int res = 0;
res = dwarf_set_tied_dbg(dbg,NULL,&error);
if (res != DW_DLV_OK) {
/* Something went wrong*/
}
}
\fP
.DE
.in -2
.P
It is not necessary to undo the tieing operation
before finishing on the dbg and tieddbg.
.H 3 "dwarf_get_tied_dbg()"
.DS
\f(CWint dwarf_get_tied_dbg(
Dwarf_Debug /*dbg*/,
Dwarf_Debug * /*tieddbg_out*/,
Dwarf_Error * /*error*/)\fP
.DE
\f(CWdwarf_get_tied_dbg\fP returns
\f(CWDW_DLV_OK\fP and sets
\f(CWtieddbg_out\fP to the pointer to
the 'tied' Dwarf_Debug.
If there is no 'tied' object
\f(CWtieddbg_out\fP is set to NULL.
.P
On error it returns
\f(CWDW_DLV_ERROR\fP.
.P
It never returns
\f(CWDW_DLV_NO_ENTRY\fP.
.H 3 "dwarf_finish()"
.DS
\f(CWint dwarf_finish(
Dwarf_Debug dbg,
Dwarf_Error *error)\fP
.DE
The function
\f(CWdwarf_finish()\fP releases all \fILibdwarf\fP internal resources
associated with the descriptor \f(CWdbg\fP, and invalidates \f(CWdbg\fP.
It returns \f(CWDW_DLV_ERROR\fP if there is an error during the
finishing operation. It returns \f(CWDW_DLV_OK\fP
for a successful operation.
Because \f(CWint dwarf_init()\fP opens an Elf descriptor
on its fd and \f(CWdwarf_finish()\fP does not close that
descriptor, an app should use \f(CWdwarf_get_elf\fP
and should call \f(CWelf_end\fP with the pointer returned
through the \f(CWElf**\fP handle created by \f(CWint dwarf_init()\fP.
.H 3 "dwarf_set_stringcheck()"
.DS
\f(CWint dwarf_set_stringcheck(
int stringcheck)\fP
.DE
The function
\f(CWint dwarf_set_stringcheck()\fP sets a global flag
and returns the previous value of the global flag.
If the stringcheck global flag is zero (the default)
libdwarf does string length validity checks
(the checks do slow libdwarf down very slightly).
If the stringcheck global flag is non-zero
libdwarf does not do string length validity
checks.
The global flag is really just 8 bits long, upperbits are not noticed
or recorded.
.H 3 "dwarf_set_reloc_application()"
.DS
\f(CWint dwarf_set_reloc_application(
int apply)\fP
.DE
The function
\f(CWint dwarf_set_reloc_application()\fP sets a global flag
and returns the previous value of the global flag.
If the reloc_application global flag is non-zero (the default)
then the applicable .rela section (if one exists) will be
processed and applied to any DWARF section when it is read in.
If the reloc_application global flag is zero no such
relocation-application is attempted.
Not all
machine types (elf header e_machine)
or all relocations are supported, but then very few
relocation types apply to DWARF debug sections.
The global flag is really just 8 bits long, upperbits are not noticed
or recorded.
It seems unlikely anyone will need to call this function.
.H 3 "dwarf_record_cmdline_options()"
.DS
\f(CWint dwarf_record_cmdline_options(
Dwarf_Cmdline_Options options)\fP
.DE
The function
\f(CWint dwarf_record_cmdline_options()\fP
copies a Dwarf_Cmdline_Options structure from
consumer code to libdwarf.
The structure is defined in \f(CWlibdwarf.h\fP.
The initial version of this structure has a single field
\f(CWcheck_verbose_mode\fP which, if non-zero, tells
libdwarf to print some detailed messages to
\f(CWstdout\fP
in case
certain errors are detected.
The default for this value is FALSE (0) so the extra messages
are off by default.
.H 3 "dwarf_object_init_b()"
.DS
\f(CWint dwarf_object_init_b(
Dwarf_Obj_Access_Interface* obj,
Dwarf_Handler errhand,
Dwarf_Ptr errarg,
unsigned groupnumber,
Dwarf_Debug* dbg,
Dwarf_Error* error)\fP
.DE
The function
\f(CWint dwarf_object_init_b()\fP
enables access to non-Elf object files
by allowing the caller to
then provide
function pointers to code (user-written,
not part of libdwarf) that will
look, to libdwarf, as if libdwarf was
reading Elf.
.P
See
\f(CWint dwarf_init_b()\fP
for additional information on the arguments
passed in (the
\f(CWobj\fP argument here
is a set of function pointers
and describing how to access non-Elf
files is beyond the scope of this document.
.P
As a hint, note that the source files with
dwarf_elf_init_file_ownership() (dwarf_original_elf_init.c)
and
dwarf_elf_object_access_init() (dwarf_elf_access.c)
are the only sources that would need replacement
for a different object format.
The replacement would need to emulate certain
conventions of Elf objects, (mainly that
section index
0 is an empty section) but the rest of
libdwarf uses what these two source files set up
without knowing how to operate on Elf.
.P
Writing the functions needed to support
non-Elf will require study of Elf
and of the object format involved.
The topic is beyond the scope of
this document.
.H 3 "dwarf_object_init()"
.DS
\f(CWint dwarf_object_init(
Dwarf_Obj_Access_Interface* obj,
Dwarf_Handler errhand,
Dwarf_Ptr errarg,
Dwarf_Debug* dbg,
Dwarf_Error* error)\fP
.DE
The function
\f(CWint dwarf_object_init()\fP
is the same as
\f(CWint dwarf_object_init_b()\fP
except
\f(CWint dwarf_object_init()\fP
is missing the groupnumber argument so
DWARF5 split dwarf objects cannot be
fully handled.
.H 3 "dwarf_get_real_section_name()"
.DS
\f(CWint dwarf_get_real_section_name( Dwarf_Debug dbg,
const char * std_section_name,
const char ** actual_sec_name_out,
Dwarf_Small * marked_compressed,
Dwarf_Small * marked_zlib_compressed,
Dwarf_Small * marked_shf_compressed,
Dwarf_Unsigned * compressed_length,
Dwarf_Unsigned * uncompressed_length,
Dwarf_Error * error);
.DE
Elf sections are sometimes compressed to reduce the disk
footprint of the sections.
It's sometimes interesting to library users
what the real name was in the object file and whether it
was compressed. Libdwarf uncompresses such sections
automatically.
It's not usually necessary to know the true name or
anything about compression.
.P
\f(CW
\fP
The caller passes in a
\f(CWDwarf_Debug\fP
pointer
and a standard section name such as ".debug_info" .
On success the function returns (through the
other arguments) the true section name and a
flag which, if non-zero means the section was compressed
and a flag which, if non-zero means the section had
the Elf section flag SHF_COMPRESSED set.
The caller must ensure that the memory pointed to
by
\f(CWactual_sec_name_out\fP,
\f(CWmarked_zcompressed\fP, and
\f(CWmarked_zlib_compressed\fP,
\f(CWmarked_shf_compressed\fP,
\f(CWcompressed_length\fP,
\f(CWuncompressed_length\fP,
is zero at the point of call.
.P
The flag
\f(CW*marked_compressed\fP,
if non-zero,
means the section name started
with .zdebug (indicating compression
was done).
.P
The flag
\f(CWmarked_zlib_compressed\fP,
if non-zero means the
initial bytes of the section starte
with the ASCII characters ZLIB
and the section was compressed.
.P
The flag
\f(CWmarked_shf_compressed\fP
if non-zero means the Elf section
sh_flag SHF_COMPRESSED is set
and the section was compressed..
The flag value in an elf section
header is (1<<11) (0x800).
.P
The value
\f(CWcompressed_length\fP
is passed back through the pointer
if and only if the section is compressed
and the pointer is non-null.
.P
The value
\f(CWuncompressed_length\fP
is passed back through the pointer
if and only if the section is compressed
and the pointer is non-null.
.P
If the section name passed in is not used by libdwarf
for this object file
the function returns
\f(CWDW_DLV_NO_ENTRY\fP
.P
On error the function returns
\f(CWDW_DLV_ERROR\fP.
.P
The string pointed to by
\f(CW*actual_sec_name_out\fP
must not be free()d.
.H 3 "dwarf_package_version()"
.DS
\f(CWconst char * dwarf_package_version(void); \fP
.DE
The package version is set in config.h (from
its value in configure.ac and in CMakeLists.txt
in the source tree) at the
build time of the library.
A pointer to a static string is returned by this
function.
The format is standard ISO date format.
For example "20180718".
It's not entirely clear how this actually helps.
But there is a request for this and we provide it
as of 23 October 2019.
.H 2 "Object Type Detectors"
These are used by
\f(CWlibdwarf\fP
and may be of use generally.
They have no connection to
any Dwarf_Debug data as you see
from the arguments passed in.
.H 3 "dwarf_object_detector_path()"
.DS
\f(CWint dwarf_object_detector_path(const char *path,
char *outpath,
unsigned long outpath_len,
unsigned *ftype,
unsigned *endian,
unsigned *offsetsize,
Dwarf_Unsigned *filesize,
int * errcode);\fP
.DE
On success the function returns
\f(CWDW_DLV_OK\fP,
and returns various data through the
arguments (described just below).
This works identically across all supported
object file types.
.P
If
\f(CWDW_DLV_NO_ENTRY\fP
is returned there is no such
file and nothing else is done or returned.
.P
If
\f(CWDW_DLV_ERROR\fP is returned
a Dwarf_Error is returned through the error pointer.
and nothing else is done or returned.
.P
Now we turn to the arguments.
Pass in the name of the object file via
the
\f(CWpath\fP
argument.
.P
To
\f(CWoutpath\fP
pass in a pointer big enough to hold the passed-in
path if that were doubled plus adding 100 characters.
Then pass that length in the
\f(CWoutpath_len\fP argument.
The path will be copied to outpath.
In the case of certain MacOS dSYM
object files the final outpath
of the dSYM file (with MacOS conventional
directories added) is copied into
\f(CWoutpath\fP. Where the MacOS
local directory tree is missing
or incomplete
\f(CWoutpath\fP
will be left as a zero-lengh string.
.P
To entirely skip the MacOS special treatment
pass 0 as arguments to
\f(CWoutpath\fP
and
\f(CWoutpath_len\fP.
.P
The \f(CWftype\fP
pointer argument returns
\f(CWDW_FTYPE_ELF\fP,
\f(CWDW_FTYPE_MACH_O\fP
,
\f(CWDW_FTYPE_PE\fP
,
\f(CWDW_FTYPE_ARCHIVE\fP
or
\f(CWDW_FTYPE_UNKNOWN\fP
to the caller.
The
\f(CWDW_FTYPE_ARCHIVE\fP
value says nothing whatever
about the contents of the
archive.
.P
The \f(CWendian\fP
pointer argument returns
\f(CWDW_ENDIAN_BIG\fP,
\f(CWDW_ENDIAN_LITTLE\fP
,
\f(CWDW_ENDIAN_SAME\fP
,
\f(CWDW_ENDIAN_OPPOSITE\fP
or
\f(CWDW_ENDIAN_UNKNOWN\fP
to the caller.
.P
The \f(CWoffsetsize\fP
pointer argument returns
a size value from the object file.
If the object file uses 32-bit
offsets it returns 32, and if
64-bit offsets it returns 64.
Each object type uses such values
but the ways the value is used
varies.
.P
The \f(CWfilesize\fP
pointer argument returns
the size, in bytes, of the object file.
This is essentially useless for
\f(CWDW_FTYPE_ARCHIVE\fP
files, one thinks.
.P
The \f(CWerrcode\fP
pointer argument returns
(if and only if DW_DLV_ERROR is returned
by the function) an integer error code.
At this time there is no handy function
to turn that error code into a string.
In the libdwarf source you will find that code in
the DW_DLE_* error list.
.H 3 "dwarf_object_detector_fd()"
.DS
\f(CWint dwarf_object_detector_fd(int fd,
unsigned *ftype,
unsigned *endian,
unsigned *offsetsize,
Dwarf_Unsigned *filesize,
int * errcode);\fP
.DE
\f(CWdwarf_object_detector_fd()\fP
is the same as
\f(CWdwarf_object_detector_path()\fP
except that no path strings apply to
\f(CWdwarf_object_detector_fd()\fP.
.H 2 "Section Group Operations"
The section group data is essential information
when processing an object with COMDAT section group DWARF sections
or with both split-dwarf (.dwo sections)
and non-split dwarf sections.
.P
It relies on Elf section groups, whereas some compilers
rely instead on relocation information to identify
section groups.
These relocation-specified groupings are not understood
at this time.
.P
A standard DWARF2 or DWARF3 or DWARF4 object
(Old Standard Object, or OSO) will
not contain any of those new sections.
The DWARF4 standard, Appendix E.1 "Using Compilation Units"
offers an overview of COMDAT section groups.
\f(CWlibdwarf\fP
assigns the group number one(1) to
OSO DWARF.
Any sections that are split dwarf (section name ending in .dwo
or one of the two special DWP index sections)
are assigned group number two(2)
by libdwarf.
COMDAT section groups are assigned groups numbers 3 and higher as needed.
.P
The COMDAT section group uses are not well defined, but
popular compilations systems are using such sections.
There is no meaningful documentation
that we can find (so far) on how the COMDAT
section groups are used,
so
\f(CWlibdwarf\fP
is based on observations
of what compilers generate.
.H 3 "dwarf_sec_group_sizes()"
.DS
\f(CW int dwarf_dwarf_sec_group_sizes(
Dwarf_Debug dbg,
Dwarf_Unsigned * section_count_out,
Dwarf_Unsigned * group_count_out,
Dwarf_Unsigned * selected_group_out,
Dwarf_Unsigned * map_entry_count_out,
Dwarf_Error * error)
\fP
.DE
The function
\f(CWdwarf_sec_group_sizes()\fP
may be called on any open
\f(CWDwarf_Debug\fP.
It returns
\f(CWDW_DLV_OK\fP
on success and returns
values via the pointer arguments.
.P
Once the
\f(CWDwarf_Debug\fP
is open the group
information is set and it will not change
for the life of this
\f(CWDwarf_Debug\fP.
.P
The
\f(CW*section_count_out\fP
is set to the number of sections
in the object. Many of the sections
will be irrelevant to
\f(CWlibdwarf\fP.
.P
The
\f(CW*group_count_out\fP
is set to the number of groups
in the object (as
\f(CWlibdwarf\fP
counts them).
An OSO will have exactly one group.
A DWP object will have exactly one group.
If is more than one group consumer code
will likely want to open additional
\f(CWDwarf_Debug\fP
objects and request
relevant information to process the
DWARF contents.
An executable or a DWP object will
always have a
\f(CW*group_count_out\fP
of one(1).
An executable or a shared library
cannot have any COMDAT section groups
as the linker will have dealt with them.
.P
The
\f(CW*selected_group_out\fP
is set to the group number that
this
\f(CWDwarf_Debug\fP
will focus on.
See
\f(CWdwarf_sec_group_map()\fP
for additional details on how
\f(CW*selected_group_out\fP
is interpreted.
.P
The
\f(CW*map_entry_count_out\fP
is set to the number of
entries in the map.
See
\f(CWdwarf_sec_group_map()\fP.
.P
On failure it returns
\f(CWDW_DLV_ERROR\fP
and sets \f(CW*error\fP
.P
The initial implementation never returns
\f(CWDW_DLV_ERROR\fP
or
\f(CWDW_DLV_NO_ENTRY\fP
but callers should allow for that possibility.
.H 3 " dwarf_sec_group_map()"
.DS
\f(CW int dwarf_sec_group_map(
Dwarf_Debug dbg,
Dwarf_Unsigned map_entry_count,
Dwarf_Unsigned * group_numbers_array,
Dwarf_Unsigned * section_numbers_array,
const char ** sec_names_array,
Dwarf_Error * error)
\fP
.DE
The function
\f(CWdwarf_sec_group_map()\fP
may be called on any open
\f(CWDwarf_Debug\fP.
.P
The caller must allocate
\f(CWmap_entry_count\fP
arrays used in the
following three arguments
the and pass the appropriate
pointer into the function as well
as passing in
\f(CWmap_entry_count\fP
itself.
.P
The map entries returned cover all the
DWARF related sections in the object
though the
\f(CWselected_group\fP
value will dictate which of the sections
in the
\f(CWDwarf_Debug\fP
will actually be accessed via the usual
\f(CWlibdwarf\fP
functions.
That is, only sections in the selected group
may be directly accessed though libdwarf may
indirectly access sections in section group
one(1) so relevant details can be accessed,
such as abbreviation tables etc.
Describing the details of this access outside
the current
\f(CWselected_group\fP
goes beyond what this document covers (as of this
writing).
.P
It returns
\f(CWDW_DLV_OK\fP
on success and sets
values into the user-allocated
array elements (sorted by section number):
.in +2
.DS
\f(CW
group_numbers_array[0]... group_numbers_array[map_entry_count-1]
section_numbers_array[0]... section_numbers_array[map_entry_count-1]
sec_names_array[0]... sec_names_array[map_entry_count-1]
\fP
.DE
.in -2
.P
\f(CWgroup_numbers_array[0]\fP
for example
is set to a group number. One(1), or two(2) or if there are
COMDAT groups it will be three(3) or higher.
.P
\f(CWsection_numbers_array[0]\fP
for example
is set to a valid Elf section number
relevant to
\f(CWDWARF\fP
(each section number shown will be greater than zero).
.P
\f(CWsec_names_array[0]\fP
for example
is set to a pointer to a string containing
the Elf section name of the Elf section number in
\f(CWsections_number_array[0]\fP.
.P
On error the function will return
\f(CWDW_DLV_ERROR\fP
or
\f(CWDW_DLV_NO_ENTRY\fP
which indicates a serious problem with this object.
.P
Here is an example of use of these functions.
.in +2
.DS
\f(CW
void examplesecgroup(Dwarf_Debug dbg)
{
int res = 0;
Dwarf_Unsigned section_count = 0;
Dwarf_Unsigned group_count;
Dwarf_Unsigned selected_group = 0;
Dwarf_Unsigned group_map_entry_count = 0;
Dwarf_Unsigned *sec_nums = 0;
Dwarf_Unsigned *group_nums = 0;
const char ** sec_names = 0;
Dwarf_Error error = 0;
Dwarf_Unsigned i = 0;
res = dwarf_sec_group_sizes(dbg,§ion_count,
&group_count,&selected_group, &group_map_entry_count,
&error);
if(res != DW_DLV_OK) {
/* Something is badly wrong*/
return;
}
/* In an object without split-dwarf sections
or COMDAT sections we now have
selected_group == 1. */
sec_nums = calloc(group_map_entry_count,sizeof(Dwarf_Unsigned));
if(!sec_nums) {
/* FAIL. out of memory */
return;
}
group_nums = calloc(group_map_entry_count,sizeof(Dwarf_Unsigned));
if(!group_nums) {
free(group_nums);
/* FAIL. out of memory */
return;
}
sec_names = calloc(group_map_entry_count,sizeof(char*));
if(!sec_names) {
free(group_nums);
free(sec_nums);
/* FAIL. out of memory */
return;
}
res = dwarf_sec_group_map(dbg,group_map_entry_count,
group_nums,sec_nums,sec_names,&error);
if(res != DW_DLV_OK) {
/* FAIL. Something badly wrong. */
}
for( i = 0; i < group_map_entry_count; ++i) {
/* Now do something with
group_nums[i],sec_nums[i],sec_names[i] */
}
free(group_nums);
free(sec_nums);
/* The strings are in Elf data.
Do not free() the strings themselves.*/
free(sec_names);
}
\fP
.DE
.in -2
.H 2 "Section size operations"
.P
These operations are informative but not normally needed.
.H 3 "dwarf_get_section_max_offsets_b()"
.DS
\f(CWint dwarf_get_section_max_offsets_b(Dwarf_debug dbg,
Dwarf_Unsigned * /*debug_info_size*/,
Dwarf_Unsigned * /*debug_abbrev_size*/,
Dwarf_Unsigned * /*debug_line_size*/,
Dwarf_Unsigned * /*debug_loc_size*/,
Dwarf_Unsigned * /*debug_aranges_size*/,
Dwarf_Unsigned * /*debug_macinfo_size*/,
Dwarf_Unsigned * /*debug_pubnames_size*/,
Dwarf_Unsigned * /*debug_str_size*/,
Dwarf_Unsigned * /*debug_frame_size*/,
Dwarf_Unsigned * /*debug_ranges_size*/,
Dwarf_Unsigned * /*debug_pubtypes_size*/,
Dwarf_Unsigned * /*debug_types_size*/);
.DE
.P
The function
\f(CWdwarf_get_section_max_offsets_b()\fP an open
Dwarf_Dbg and reports on the section sizes by pushing
section size values back through the pointers.
Created in October 2011.
.H 3 "dwarf_get_section_max_offsets()"
.DS
\f(CWint dwarf_get_section_max_offsets(Dwarf_debug dbg,
Dwarf_Unsigned * /*debug_info_size*/,
Dwarf_Unsigned * /*debug_abbrev_size*/,
Dwarf_Unsigned * /*debug_line_size*/,
Dwarf_Unsigned * /*debug_loc_size*/,
Dwarf_Unsigned * /*debug_aranges_size*/,
Dwarf_Unsigned * /*debug_macinfo_size*/,
Dwarf_Unsigned * /*debug_pubnames_size*/,
Dwarf_Unsigned * /*debug_str_size*/,
Dwarf_Unsigned * /*debug_frame_size*/,
Dwarf_Unsigned * /*debug_ranges_size*/,
Dwarf_Unsigned * /*debug_pubtypes_size*/);
.DE
.P
The function is the same as \f(CWdwarf_get_section_max_offsets_b()\fP
except it is missing the \f(CWdebug_types_size()\fP argument.
Though obsolete it is still supported.
.H 2 "Printf Callbacks"
.P
This is new in August 2013.
.P
The \f(CWdwarf_print_lines()\fP function
is intended as a helper to programs like \f(CWdwarfdump\fP
and show some line internal details in a way only
the internals
of libdwarf can show them.
But using printf directly in libdwarf means the caller
has limited control of where the output appears.
So now the 'printf' output is passed back to the
caller through a callback function whose implementation
is provided by the caller.
.P
Any code calling libdwarf can ignore
the functions described in this section completely.
If the functions are ignored the messages
(if any) from libdwarf will simply not appear anywhere.
.P
The \f(CWlibdwarf.h\fP header file defines
\f(CWstruct Dwarf_Printf_Callback_Info_s\fP
and
\f(CWdwarf_register_printf_callback\fP
for those libdwarf callers wishing to implement the callback.
In this section we describe how one uses that interface.
The applications \f(CWdwarfdump\fP and
\f(CWdwarfdump2\fP are examples of how these may be used.
.H 3 "dwarf_register_printf_callback"
.DS
\f(CWstruct Dwarf_Printf_Callback_Info_s
dwarf_register_printf_callback(Dwarf_Debug dbg,
struct Dwarf_Printf_Callback_Info_s * newvalues);
.DE
.P
The \f(CWdwarf_register_printf_callback()\fP function
can only be called after the Dwarf_Debug instance
has been initialized, the call makes no sense at other times.
The function returns the current value of the structure.
If \f(CWnewvalues\fP is non-null then the passed-in
values are used to initialize the libdwarf internal
callback data (the values returned are the values
before the \f(CWnewvalues\fP are recorded).
If \f(CWnewvalues\fP is null no change is made to
the libdwarf internal callback data.
.H 3 "Dwarf_Printf_Callback_Info_s"
.DS
\f(CWstruct Dwarf_Printf_Callback_Info_s {
void * dp_user_pointer;
dwarf_printf_callback_function_type dp_fptr;
char * dp_buffer;
unsigned int dp_buffer_len;
int dp_buffer_user_provided;
void * dp_reserved;
};
.DE
.P
First we describe the fields as applicable in setting up
for a call to \f(CWdwarf_register_printf_callback()\fP.
.P
The field \f(CWdp_user_pointer\fP is remembered by libdwarf
and passed back in any call libdwarf makes to the
user's callback function.
It is otherwise ignored by libdwarf.
.P
The field \f(CWdp_fptr\fP is either NULL or a pointer to
a user-implemented function.
.P
If the field \f(CWdp_buffer_user_provided\fP is non-zero
then \f(CWdp_buffer_len\fP and \f(CWdp_buffer\fP
must be set by the user and libdwarf will use that buffer
without doing any malloc of space.
If the field \f(CWdp_buffer_user_provided\fP is zero
then the input fields \f(CWdp_buffer_len\fP and \f(CWdp_buffer\fP
are ignored by libdwarf and space is malloc'd as needed.
.P
The field \f(CWdp_reserved\fP is ignored, it is reserved for
future use.
.P
When the structure is returned by \f(CWdwarf_register_printf_callback()\fP
the values of the fields before the
\f(CWdwarf_register_printf_callback()\fP call are returned.
.H 3 "dwarf_printf_callback_function_type"
.DS
\f(CWtypedef void (* dwarf_printf_callback_function_type)(void * user_pointer,
const char * linecontent);
.DE
.P
Any application using the callbacks needs to use the function
\f(CWdwarf_register_printf_callback()\fP and supply a function matching
the above function prototype from libdwarf.h.
.H 3 "Example of printf callback use in a C++ application using libdwarf"
.DS
\f(CWstruct Dwarf_Printf_Callback_Info_s printfcallbackdata;
memset(&printfcallbackdata,0,sizeof(printfcallbackdata));
printfcallbackdata.dp_fptr = printf_callback_for_libdwarf;
dwarf_register_printf_callback(dbg,&printfcallbackdata);
Assuming the user implements something
like the following function in her application:
void
printf_callback_for_libdwarf(void *userdata,const char *data)
{
cout << data;
}
.DE
.P
It is crucial that the user's callback function copies or
prints the data immediately. Once the user callback
function returns the \f(CWdata\fP
pointer may change or become stale without warning.
.H 2 "Debugging Information Entry Delivery Operations"
These functions are concerned with accessing debugging information
entries, whether from a .debug_info, .debug_types, .debug_info.dwo,
or .debug_types.dwo .
.P
Since all such sections use similar formats, one
set of functions suffices.
.H 3 "dwarf_get_die_section_name()"
.DS
int
dwarf_get_die_section_name(Dwarf_Debug dbg,
Dwarf_Bool is_info,
const char ** sec_name,
Dwarf_Error * error);
.DE
\f(CWdwarf_get_die_section_name()\fP lets consumers
access the object section name when no specific
DIE is at hand.
This is useful for applications wanting to print
the name, but of course the object section name is not
really a part of the DWARF information.
Most applications will
probably not call this function.
It can be called at any time
after the Dwarf_Debug initialization is done.
See also \f(CWdwarf_get_die_section_name_b()\fP.
.P
The function
\f(CWdwarf_get_die_section_name()\fP operates on
the either the .debug_info[.dwo] section
(if \f(CWis_info\fP is non-zero)
or .debug_types[.dwo]
section
(if \f(CWis_info\fP is zero).
.P
If the function succeeds, \f(CW*sec_name\fP is set to
a pointer to a string with the object section name and
the function returns \f(CWDW_DLV_OK\fP.
Do not free the string whose pointer is returned.
For non-Elf objects it is possible the string pointer
returned will be NULL or will point to an empty string.
It is up to the calling application to recognize this
possibility and deal with it appropriately.
.P
If the section does not exist the function returns
DW_DLV_NO_ENTRY.
.P
If there is an internal error detected the
function returns \f(CWDW_DLV_ERROR\fP and sets the
\f(CW*error\fP pointer.
.H 3 "dwarf_get_die_section_name_b()"
.DS
int
dwarf_get_die_section_name_b(Dwarf_Die die,
const char ** sec_name,
Dwarf_Error * error);
.DE
\f(CWdwarf_get_die_section_name_b()\fP lets consumers
access the object section name when one has a DIE.
This is useful for applications wanting to print
the name, but of course the object section name is not
really a part of the DWARF information.
Most applications will
probably not call this function.
It can be called at any time
after the Dwarf_Debug initialization is done.
See also \f(CWdwarf_get_die_section_name()\fP.
.P
If the function succeeds, \f(CW*sec_name\fP is set to
a pointer to a string with the object section name and
the function returns \f(CWDW_DLV_OK\fP.
Do not free the string whose pointer is returned.
For non-Elf objects it is possible the string pointer
returned will be NULL or will point to an empty string.
It is up to the calling application to recognize this
possibility and deal with it appropriately.
.P
If the section does not exist the function returns
DW_DLV_NO_ENTRY.
.P
If there is an internal error detected the
function returns \f(CWDW_DLV_ERROR\fP and sets the
\f(CW*error\fP pointer.
.H 3 "dwarf_next_cu_header_d()"
.DS
\f(CWint dwarf_next_cu_header_d(
Dwarf_debug dbg,
Dwarf_Bool is_info,
Dwarf_Unsigned *cu_header_length,
Dwarf_Half *version_stamp,
Dwarf_Unsigned *abbrev_offset,
Dwarf_Half *address_size,
Dwarf_Half *offset_size,
Dwarf_Half *extension_size,
Dwarf_Sig8 *signature,
Dwarf_Unsigned *typeoffset
Dwarf_Unsigned *next_cu_header,
Dwarf_Half *header_cu_type,
Dwarf_Error *error);
.DE
The function
\f(CWdwarf_next_cu_header_d()\fP operates on
the either the .debug_info section
(if \f(CWis_info\fP is non-zero) or .debug_types
section
(if \f(CWis_info\fP is zero).
It returns \f(CWDW_DLV_ERROR\fP
if it fails, and
\f(CWDW_DLV_OK\fP if it succeeds.
.P
If it succeeds, \f(CW*next_cu_header\fP is set to
the offset in the .debug_info section of the next
compilation-unit header if it succeeds. On reading the last
compilation-unit header in the .debug_info section it contains
the size of the .debug_info or debug_types section.
Beginning 22 April 2019
\f(CWnext_cu_header\fP
will not be used to return the offset
if
\f(CWnext_cu_header\fP
is null.
Be cautious using a null argument
unless you know that only a suitably
recent version of libdwarf will be used.
.P
The next call to
\f(CWdwarf_next_cu_header_b()\fP returns \f(CWDW_DLV_NO_ENTRY\fP
without reading a
compilation-unit or setting \f(CW*next_cu_header\fP.
Subsequent calls to \f(CWdwarf_next_cu_header()\fP
repeat the cycle by reading the first compilation-unit and so on.
.P
The other
values returned through pointers are the values in the compilation-unit
header. If any of \f(CWcu_header_length\fP,
\f(CWversion_stamp\fP,
\f(CWabbrev_offset\fP, \f(CWaddress_size\fP,
\f(CWoffset_size\fP, \f(CWextension_size\fP,
\f(CWsignature\fP, or \f(CWtypeoffset\fP,
is \f(CWNULL\fP, the
argument is ignored (meaning it is not an error to provide a
\f(CWNULL\fP pointer for any or all of these arguments).
.P
\f(CWcu_header_length\fP returns the length in bytes of the compilation
unit header.
.P
\f(CWversion_stamp\fP returns the section version, which
would be (for .debug_info) 2 for DWARF2, 3 for DWARF3,
4 for DWARF4, or 5 for DWARF5..
.P
\f(CWabbrev_offset\fP returns the .debug_abbrev
section offset of the abbreviations
for this compilation unit.
.P
\f(CWaddress_size\fP returns the size of an address in this
compilation unit. Which is usually 4 or 8.
.P
\f(CWoffset_size\fP returns the size in bytes of
an offset for the compilation unit. The offset size
is 4 for 32bit dwarf
and 8 for 64bit dwarf.
This is the offset size in dwarf data, not
the address size inside the executable code.
The offset size can be 4 even
if embedded in a 64bit elf file (which
is normal for 64bit elf), and can be 8 even in
a 32bit elf file (which probably will never be seen
in practice).
.P
The
\f(CWextension_size\fP pointer is only relevant if
the \f(CWoffset_size\fP pointer returns 8.
The value is not normally useful but is returned
through the pointer for completeness.
The pointer \f(CWextension_size\fP returns 0
if the CU is MIPS/IRIX non-standard 64bit dwarf
(MIPS/IRIX 64bit dwarf was created years before DWARF3
defined 64bit dwarf)
and returns 4 if the dwarf uses the standard 64bit
extension (the 4 is the size in bytes of the 0xffffffff
in the initial length field
which indicates the following 8 bytes in the .debug_info section
are the real length).
See the DWARF3 or DWARF4 standard, section 7.4.
.P
The
\f(CWsignature\fP pointer is only relevant if
the CU has a type signature, and if relevant the 8 byte type
signature of the .debug_types CU header is assigned through
the pointer.
.P
The
\f(CWtypeoffset\fP pointer is only relevant
the CU has a type signature
if relevant the local offset
within the CU of the the type offset the .debug_types entry
represents is assigned through the pointer.
The
\f(CWtypeoffset\fP matters because a
DW_AT_type referencing the type unit may reference an inner type,
such as a C++ class in a C++ namespace, but the type itself
has the enclosing namespace in the .debug_type type_unit.
.P
The
\f(CWheader_cu_type\fP pointer is applicable to
all CU headers.
The value returned through the pointer is either
\f(CWDW_UT_compile\fP
\f(CWDW_UT_partial\fP
\f(CWDW_UT_type\fP
and identifies the header type of this CU.
In \f(CWDWARF4\fP a \f(CWDW_UT_type\fP
will be in \f(CW.debug_types\fP, but in
\f(CWDWARF5\fP these compilation units are in \f(CW.debug_info\fP
and the Debug Fission (ie Split Dwarf) \f(CW.debug_info.dwo\fP
sections .
.H 3 "dwarf_next_cu_header_c()"
.DS
\f(CWint dwarf_next_cu_header_c(
Dwarf_debug dbg,
Dwarf_Bool is_info,
Dwarf_Unsigned *cu_header_length,
Dwarf_Half *version_stamp,
Dwarf_Unsigned *abbrev_offset,
Dwarf_Half *address_size,
Dwarf_Half *offset_size,
Dwarf_Half *extension_size,
Dwarf_Sig8 *signature,
Dwarf_Unsigned *typeoffset
Dwarf_Unsigned *next_cu_header,
Dwarf_Error *error);
.DE
The function
\f(CWdwarf_next_cu_header_c()\fP operates on
the either the .debug_info section
(if \f(CWis_info\fP is non-zero) or .debug_types
section
(if \f(CWis_info\fP is zero).
.P
It operates exactly like
\f(CWdwarf_next_cu_header_d()\fP but
is missing the
\f(CWheader_type\fP field.
This is kept for compatibility.
All code using this should be changed to use
\f(CWdwarf_next_cu_header_d()\fP
.H 3 "dwarf_next_cu_header_b()"
.DS
\f(CWint dwarf_next_cu_header_b(
Dwarf_debug dbg,
Dwarf_Unsigned *cu_header_length,
Dwarf_Half *version_stamp,
Dwarf_Unsigned *abbrev_offset,
Dwarf_Half *address_size,
Dwarf_Half *offset_size,
Dwarf_Half *extension_size,
Dwarf_Unsigned *next_cu_header,
Dwarf_Error *error);
.DE
.P
This is obsolete as of October 2011 though supported.
.P
The function
\f(CWdwarf_next_cu_header_b()\fP operates on
the .debug_info section. It operates exactly like
\f(CWdwarf_next_cu_header_c()\fP but
is missing the
\f(CWsignature\fP, and \f(CWtypeoffset\fP
fields.
This is kept for compatibility.
All code using this should be changed to use
\f(CWdwarf_next_cu_header_c()\fP
.H 3 "dwarf_next_cu_header()"
.P
The following is the original form, missing the
\f(CWoffset_size\fP, \f(CWextension_size\fP,
\f(CWsignature\fP, and \f(CWtypeoffset\fP
fields in
\f(CWdwarf_next_cu_header_c()\fP.
This is kept for compatibility.
All code using this should be changed to use
\f(CWdwarf_next_cu_header_c()\fP
.DS
\f(CWint dwarf_next_cu_header(
Dwarf_debug dbg,
Dwarf_Unsigned *cu_header_length,
Dwarf_Half *version_stamp,
Dwarf_Unsigned *abbrev_offset,
Dwarf_Half *address_size,
Dwarf_Unsigned *next_cu_header,
Dwarf_Error *error);
.DE
.H 3 "dwarf_siblingof_b()"
.DS
\f(CWint dwarf_siblingof_b(
Dwarf_Debug dbg,
Dwarf_Die die,
Dwarf_Bool is_info,
Dwarf_Die *return_sib,
Dwarf_Error *error)\fP
.DE
The function \f(CWdwarf_siblingof_b()\fP
returns \f(CWDW_DLV_ERROR\fP and sets the \f(CWerror\fP pointer on error.
If there is no sibling it returns \f(CWDW_DLV_NO_ENTRY\fP.
When it succeeds,
\f(CWdwarf_siblingof_b()\fP returns
\f(CWDW_DLV_OK\fP and sets
\f(CW*return_sib\fP to the \f(CWDwarf_Die\fP
descriptor of the sibling of \f(CWdie\fP.
If \f(CWis_info\fP is non-zero then the \f(CWdie\fP
is assumed to refer to a .debug_info DIE.
If \f(CWis_info\fP is zero then the \f(CWdie\fP
is assumed to refer to a .debug_types DIE.
Note that the first call (the call that gets the compilation-unit
DIE in a compilation unit) passes in a NULL \f(CWdie\fP
so having the caller pass in \f(CWis_info\fP is essential.
And if \f(CWdie\fP is non-NULL it is still essential for the
call to pass in \f(CWis_info\fP set properly to reflect the
section the DIE came from.
The function
\f(CWdwarf_get_die_infotypes_flag()\fP is of interest as
it returns the proper is_info value from any non-NULL \f(CWdie\fP
pointer.
If \f(CWdie\fP is \fINULL\fP, the \f(CWDwarf_Die\fP descriptor of the
first die in the compilation-unit is returned.
This die has the
\f(CWDW_TAG_compile_unit\fP,
\f(CWDW_TAG_partial_unit\fP,
or \f(CWDW_TAG_type_unit\fP
tag.
.in +2
.FG "Example4 dwarf_siblingof()"
.DS
\f(CW
void example4(Dwarf_Debug dbg,Dwarf_Die in_die,Dwarf_Bool is_info)
{
Dwarf_Die return_sib = 0;
Dwarf_Error error = 0;
int res = 0;
/* in_die might be NULL or a valid Dwarf_Die */
res = dwarf_siblingof_b(dbg,in_die,is_info,&return_sib, &error);
if (res == DW_DLV_OK) {
/* Use return_sib here. */
dwarf_dealloc_die(return_sib);
/* This original form still works.
dwarf_dealloc(dbg, return_sib, DW_DLA_DIE);
*/
/* return_sib is no longer usable for anything, we
ensure we do not use it accidentally with: */
return_sib = 0;
}
}
\fP
.DE
.in -2
.H 3 "dwarf_siblingof()"
.DS
\f(CWint dwarf_siblingof(
Dwarf_Debug dbg,
Dwarf_Die die,
Dwarf_Die *return_sib,
Dwarf_Error *error)\fP
.DE
.P
\f(CWint dwarf_siblingof()\fP operates exactly the same as
\f(CWint dwarf_siblingof_b()\fP, but
\f(CWint dwarf_siblingof()\fP refers only to .debug_info
DIEs.
.H 3 "dwarf_child()"
.DS
\f(CWint dwarf_child(
Dwarf_Die die,
Dwarf_Die *return_kid,
Dwarf_Error *error)\fP
.DE
The function \f(CWdwarf_child()\fP
returns \f(CWDW_DLV_ERROR\fP and sets the \f(CWerror\fP die on error.
If there is no child it returns \f(CWDW_DLV_NO_ENTRY\fP.
When it succeeds,
\f(CWdwarf_child()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*return_kid\fP
to the \f(CWDwarf_Die\fP descriptor
of the first child of \f(CWdie\fP.
The function
\f(CWdwarf_siblingof()\fP can be used with the return value of
\f(CWdwarf_child()\fP to access the other children of \f(CWdie\fP.
.in +2
.FG "Example5 dwarf_child()"
.DS
\f(CW
void example5(Dwarf_Die in_die)
{
Dwarf_Die return_kid = 0;
Dwarf_Error error = 0;
int res = 0;
res = dwarf_child(in_die,&return_kid, &error);
if (res == DW_DLV_OK) {
/* Use return_kid here. */
dwarf_dealloc_die(return_kid);
/* The original form of dealloc still works
dwarf_dealloc(dbg, return_kid, DW_DLA_DIE);
*/
/* return_die is no longer usable for anything, we
ensure we do not use it accidentally with: */
return_kid = 0;
}
}
\fP
.DE
.in -2
.H 3 "dwarf_offdie_b()"
.DS
\f(CWint dwarf_offdie_b(
Dwarf_Debug dbg,
Dwarf_Off offset,
Dwarf_Bool is_info,
Dwarf_Die *return_die,
Dwarf_Error *error)\fP
.DE
The function \f(CWdwarf_offdie_b()\fP
returns \f(CWDW_DLV_ERROR\fP and sets the \f(CWerror\fP die on error.
When it succeeds,
\f(CWdwarf_offdie_b()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*return_die\fP
to the
the \f(CWDwarf_Die\fP
descriptor of the debugging information entry at \f(CWoffset\fP in
the section containing debugging information entries i.e the .debug_info
section.
A return of \f(CWDW_DLV_NO_ENTRY\fP
means that the \f(CWoffset\fP in the section is of a byte containing
all 0 bits, indicating that there
is no abbreviation code. Meaning this 'die offset' is not
the offset of a real die, but is instead an offset of a null die,
a padding die, or of some random zero byte: this should
not be returned in normal use.
.P
It is the user's
responsibility to make sure that \f(CWoffset\fP is the start of a valid
debugging information entry. The result of passing it an invalid
offset could be chaos.
.P
If \f(CWis_info\fP is non-zero the \f(CWoffset\fP must refer
to a .debug_info section offset.
If \f(CWis_info\fP zero the \f(CWoffset\fP must refer
to a .debug_types section offset.
Error returns or misleading
values may result if the
\f(CWis_info\fP flag
or the \f(CWoffset\fP value
are incorrect.
.in +2
.FG "Example6 dwarf_offdie_b()"
.DS
\f(CW
void example6(Dwarf_Debug dbg,Dwarf_Off die_offset,Dwarf_Bool is_info)
{
Dwarf_Error error = 0;
Dwarf_Die return_die = 0;
int res = 0;
res = dwarf_offdie_b(dbg,die_offset,is_info,&return_die, &error);
if (res == DW_DLV_OK) {
/* Use return_die here. */
dwarf_dealloc_die(return_die);
/* The original form still works:
dwarf_dealloc(dbg, return_die, DW_DLA_DIE);
*/
/* return_die is no longer usable for anything, we
ensure we do not use it accidentally with: */
return_die = 0;
} else {
/* res could be NO ENTRY or ERROR, so no
dealloc necessary. */
}
}
\fP
.DE
.in -2
.H 3 "dwarf_offdie()"
.DS
\f(CWint dwarf_offdie(
Dwarf_Debug dbg,
Dwarf_Off offset,
Dwarf_Die *return_die,
Dwarf_Error *error)\fP
.DE
.P
The function \f(CWdwarf_offdie()\fP is obsolete, use
\f(CWdwarf_offdie_b()\fP instead.
The function is still supported in the library, but only
references the .debug_info section.
.H 3 "dwarf_validate_die_sibling()"
.DS
\f(CWint validate_die_sibling(
Dwarf_Die sibling,
Dwarf_Off *offset)\fP
.DE
When used correctly in a depth-first walk of a DIE tree this
function validates that any DW_AT_sibling attribute gives
the same offset as the direct tree walk.
That is the only purpose of this function.
The function \f(CWdwarf_validate_die_sibling()\fP
returns \f(CWDW_DLV_OK\fP if the last die processed
in a depth-first DIE tree walk was the same offset as
generated by a call to \f(CWdwarf_siblingof()\fP.
Meaning that the DW_AT_sibling attribute value, if any, was correct.
If the conditions are not met then DW_DLV_ERROR is returned
and \f(CW*offset\fP is set to the offset
in the .debug_info section of the last DIE processed.
If the application prints the offset a knowledgeable
user may be able to figure out what the compiler did wrong.
.H 2 "Debugging Information Entry Query Operations"
These queries return specific information about debugging information
entries or a descriptor that can be used on subsequent queries when
given a \f(CWDwarf_Die\fP descriptor. Note that some operations are
specific to debugging information entries that are represented by a
\f(CWDwarf_Die\fP descriptor of a specific type.
For example, not all
debugging information entries contain an attribute having a name, so
consequently, a call to \f(CWdwarf_diename()\fP using a \f(CWDwarf_Die\fP
descriptor that does not have a name attribute will return
\f(CWDW_DLV_NO_ENTRY\fP.
This is not an error, i.e. calling a function that needs a specific
attribute is not an error for a die that does not contain that specific
attribute.
.P
There are several methods that can be used to obtain the value of an
attribute in a given die:
.AL 1
.LI
Call \f(CWdwarf_hasattr()\fP to determine if the debugging information
entry has the attribute of interest prior to issuing the query for
information about the attribute.
.LI
Supply an \f(CWerror\fP argument, and check its value after the call to
a query indicates an unsuccessful return, to determine the nature of the
problem. The \f(CWerror\fP argument will indicate whether an error occurred,
or the specific attribute needed was missing in that die.
.LI
Arrange to have an error handling function invoked upon detection of an
error (see \f(CWdwarf_init()\fP).
.LI
Call \f(CWdwarf_attrlist()\fP and iterate through the returned list of
attributes, dealing with each one as appropriate.
.LE
.P
.H 3 "dwarf_get_die_infotypes_flag()"
.DS
\f(CWDwarf_Bool dwarf_get_die_infotypes_flag(Dwarf_Die die)\fP
.DE
.P
The function
\f(CWdwarf_get_die_infotypes_flag()\fP
returns the section flag
indicating which section the DIE originates from.
If the returned value is non-zero the DIE
originates from the .debug_info section.
If the returned value is zero the DIE
originates from the .debug_types section.
.H 3 "dwarf_cu_header_basics()"
.DS
\f(CWint dwarf_cu_header_basics(Dwarf_Die die
Dwarf_Half *version,
Dwarf_Bool *is_info,
Dwarf_Bool *is_dwo,
Dwarf_Half *offset_size,
Dwarf_Half *address_size,
Dwarf_Half *extension_size,
Dwarf_Sig8 **signature,
Dwarf_Off *offset_of_length,
Dwarf_Unsigned *total_byte_length,
Dwarf_Error *error)\fP
.DE
.P
On success,
the function \f(CWcu_header_basics()\fP
various data items from the CU header
and the CU die passed in.
Any return-value
pointer may be passed in as NULL,
indicating that the value is not needed.
.P
Summing
\f(CWoffset_size\fP
and
\f(CWextention_size\fP
gives the length of the CU length field,
which is immediately followed by
the CU header.
.P
\f(CWis_dwo\fP
field will surely always be 0
as dwo/dwp .debug_info
cannot be skeleton CUs.
.P
The
\f(CWsignature\fP
value is returned
if there a signature in the DWARF5
CU header or the CU die.
.P
The
\f(CWoffset_of_length\fP
returned is the offset of the first byte
of the length field of the CU.
.P
The
\f(CWtotal_byte_Length\fP
returned is the length of data
in the CU counting from the first byte
at
\f(CWoffset_of_length\fP.
.H 3 "dwarf_tag()"
.DS
\f(CWint dwarf_tag(
Dwarf_Die die,
Dwarf_Half *tagval,
Dwarf_Error *error)\fP
.DE
The function \f(CWdwarf_tag()\fP returns the \f(CWtag\fP of \f(CWdie\fP
through the pointer \f(CWtagval\fP if it succeeds.
It returns \f(CWDW_DLV_OK\fP if it succeeds.
It returns \f(CWDW_DLV_ERROR\fP on error.
.H 3 "dwarf_dieoffset()"
.DS
\f(CWint dwarf_dieoffset(
Dwarf_Die die,
Dwarf_Off * return_offset,
Dwarf_Error *error)\fP
.DE
When it succeeds,
the function \f(CWdwarf_dieoffset()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP
to the position of \f(CWdie\fP
in the section containing debugging information entries
(the \f(CWreturn_offset\fP is a section-relative offset).
In other words,
it sets \f(CWreturn_offset\fP
to the offset of the start of the debugging information entry
described by \f(CWdie\fP in the section containing dies i.e .debug_info.
It returns \f(CWDW_DLV_ERROR\fP on error.
.H 3 "dwarf_addr_form_is_indexed()"
\f(CWdwarf_addr_form_is_indexed(form)\fP
is a utility function to make it simple to determine
if a form is one of the indexed forms (there are
several such in DWARF5).
See DWARF5 section 7.5.5 \f(CWClasses and Forms\fP
for more information.
.DS
int dwarf_addr_form_is_indexed(Dwarf_Half form);
.DE
It returns TRUE if the form is one of the
indexed address forms (such as DW_FORM_addrx1)
and FALSE otherwise.
.H 3 "dwarf_debug_addr_index_to_addr()"
.DS
int dwarf_debug_addr_index_to_addr(Dwarf_Die /*die*/,
Dwarf_Unsigned index,
Dwarf_Addr * return_addr,
Dwarf_Error * error);
.DE
Attributes with form DW_FORM_addrx, the
operation DW_OP_addrx, or
certain of the split-dwarf location list entries
give an index value to
a machine address in the .debug_addr section
(which is always in .debug_addr even when
the form/operation are in a split dwarf .dwo section).
.P
On successful return this function turns such an index
into a target address value through the pointer
\f(CWreturn_addr\fP .
.P
If there is an error this may return DW_
\f(CWDW_DLV_ERROR\fP and it will have
returned an error through \f(CW*error\fP.
.P
If there is no available .debug_addr section this
may return \f(CWDW_DLV_NO_ENTRY\fP.
.H 3 "dwarf_die_CU_offset()"
.DS
\f(CWint dwarf_die_CU_offset(
Dwarf_Die die,
Dwarf_Off *return_offset,
Dwarf_Error *error)\fP
.DE
The function \f(CWdwarf_die_CU_offset()\fP is similar to
\f(CWdwarf_dieoffset()\fP, except that it puts the offset of the DIE
represented by the \f(CWDwarf_Die\fP \f(CWdie\fP, from the
start of the compilation-unit that it belongs to rather than the start
of .debug_info (the \f(CWreturn_offset\fP is a CU-relative offset).
.H 3 "dwarf_die_offsets()"
.DS
\f(CWint dwarf_die_offsets(
Dwarf_Die die,
Dwarf_Off *global_off,
Dwarf_Off *cu_off,
Dwarf_Error *error)\fP
.DE
The function \f(CWdwarf_die_offsets()\fP is a combination of
\f(CWdwarf_dieoffset()\fP and \f(CWdwarf_die_cu_offset()\fP
in that it returns both the global .debug_info offset and
the CU-relative offset of the \f(CWdie\fP in a single call.
.H 3 "dwarf_ptr_CU_offset()"
.DS
\f(CWint dwarf_ptr_CU_offset(
Dwarf_CU_Context cu_context,
Dwarf_Byte_ptr di_ptr ,
Dwarf_Off *cu_off)\fP
.DE
Given a valid CU context pointer and a pointer into that CU
context,
the function \f(CWdwarf_ptr_CU_offset()\fP returns DW_DLV_OK
and sets \f(CW*cu_off\fP to the CU-relative (local) offset
in that CU.
.H 3 "dwarf_CU_dieoffset_given_die()"
.DS
\f(CWint dwarf_CU_dieoffset_given_die(
Dwarf_Die given_die,
Dwarf_Off *return_offset,
Dwarf_Error *error)\fP
.DE
The function \f(CWdwarf_CU_dieoffset_given_die()\fP is similar to
\f(CWdwarf_die_CU_offset()\fP, except that it puts the
global offset of the CU DIE owning \f(CWgiven_die\fP
of .debug_info (the \f(CWreturn_offset\fP is a global section offset).
.P
This is useful when processing a DIE tree and encountering
an error or other surprise in a DIE, as the \f(CWreturn_offset\fP
can be passed to \f(CWdwarf_offdie_b()\fP to return a pointer
to the CU die of the CU owning the \f(CWgiven_die\fP passed
to \f(CWdwarf_CU_dieoffset_given_die()\fP. The consumer can
extract information from the CU die and the \f(CWgiven_die\fP
(in the normal way) and print it.
An example (a snippet) of code using this function
follows. It assumes that \f(CWin_die\fP is a DIE
in .debug_info
that, for some reason, you have decided needs CU context
printed (assuming \f(CWprint_die_data\fP
does some reasonable printing).
.in +2
.FG "Example7 dwarf_CU_dieoffset_given_die()"
.DS
\f(CW
void example7(Dwarf_Debug dbg, Dwarf_Die in_die,Dwarf_Bool is_info)
{
int res = 0;
Dwarf_Off cudieoff = 0;
Dwarf_Die cudie = 0;
Dwarf_Error error = 0;
res = dwarf_CU_dieoffset_given_die(in_die,&cudieoff,&error);
if(res != DW_DLV_OK) {
/* FAIL */
return;
}
res = dwarf_offdie_b(dbg,cudieoff,is_info,&cudie,&error);
if(res != DW_DLV_OK) {
/* FAIL */
return;
}
/* do something with cu_die */
dwarf_dealloc_die(cudie);
/* The original form still works.
dwarf_dealloc(dbg,cudie, DW_DLA_DIE);
*/
}
\fPy
.DE
.in -2
.H 3 "dwarf_die_CU_offset_range()"
.DS
\f(CWint dwarf_die_CU_offset_range(
Dwarf_Die die,
Dwarf_Off *cu_global_offset,
Dwarf_Off *cu_length,
Dwarf_Error *error)\fP
.DE
The function \f(CWdwarf_die_CU_offset_range()\fP
returns the offset of the beginning of the CU and the length of the CU.
The offset and length are of the entire CU that this DIE is
a part of. It is used by dwarfdump (for example) to check
the validity of offsets.
Most applications will have no reason to call this function.
.H 3 "dwarf_diename()"
.DS
\f(CWint dwarf_diename(
Dwarf_Die die,
char ** return_name,
Dwarf_Error *error)\fP
.DE
When it succeeds,
the function \f(CWdwarf_diename()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*return_name\fP
to
a pointer to a
null-terminated string of characters that represents the
name attribute
(\f(CWDW_AT_name\fP)
of
\f(CWdie\fP.
.P
The storage pointed to by a successful return of
\f(CWdwarf_diename()\fP
should not be freed
as the text is
a string in static memory (for some error cases)
or a string residing in a DWARF data section.
.P
Up to March 2020 this document said that dwarf_dealloc
with DW_DLA_STRING
should be applied to the string returned through the
pointer.
That was always incorrect.
However, doing the dwarf_dealloc(dbg,xxx,DW_DLA_STRING)
that was previously called for does not result
in any error (dwarf_dealloc avoids freeing strings
like this).
.P
It returns \f(CWDW_DLV_NO_ENTRY\fP if
\f(CWdie\fP does not have a name attribute.
It returns \f(CWDW_DLV_ERROR\fP if
an error occurred.
.H 3 "dwarf_die_text()"
.DS
\f(CWint dwarf_die_text(
Dwarf_Die die,
Dwarf_Half attrnum,
char ** return_name,
Dwarf_Error *error)\fP
.DE
When it succeeds,
the function
\f(CWdwarf_die_text()\fP
returns
\f(CWDW_DLV_OK\fP
and sets
\f(CW*return_name\fP
to
a pointer to a
null-terminated string of characters that represents a
string-value
attribute of
\f(CWdie\fP
if an
attribute
\f(CWattrnum\fP
is present.
.P
The storage pointed to by a successful return of
\f(CWdwarf_die_text()\fP must never be freed,
the string is in the DWARF data and is
not dynamically allocated.
.P
As of March 2020 the description here has been corrected.
\f(CWdwarf_dealloc()\fP
should never have been applied to
a string returned by
\f(CWdwarf_die_text()\fP.
.P
It returns
\f(CWDW_DLV_NO_ENTRY\fP
if \f(CWdie\fP does not have the attribute
\f(CWattrnum\fP.
It returns
\f(CWDW_DLV_ERROR\fP if
an error occurred.
.H 3 "dwarf_die_abbrev_code()"
.DS
\f(CWint dwarf_die_abbrev_code( Dwarf_Die die)\fP
.DE
The function returns
the abbreviation code of the DIE.
That is, it returns the abbreviation "index"
into the abbreviation table for the compilation unit
of which the DIE is a part.
It cannot fail. No errors are possible.
The pointer \f(CWdie()\fP must not be NULL.
.H 3 "dwarf_die_abbrev_children_flag()"
.DS
\f(CWint dwarf_die_abbrev_children_flag( Dwarf_Die die,
Dwarf_Half *has_child)\fP
.DE
The function returns the has-children flag of the \f(CWdie\fP
passed in through the \f(CW*has_child\fP passed in and returns
\f(CWDW_DLV_OK\fP on success.
A non-zero value of \f(CW*has_child\fP means the \f(CWdie\fP
has children.
On failure it returns \f(CWDW_DLV_ERROR\fP.
The function was developed to let
consumer code do better error reporting
in some circumstances, it is not generally needed.
.H 3 "dwarf_die_abbrev_global_offset()"
.DS
\f(CWint dwarf_die_abbrev_global_offset(Dwarf_Die die,
Dwarf_Off * abbrev_offset,
Dwarf_Unsigned * abbrev_count,
Dwarf_Error* error);\fP
.DE
The function allows more detailed printing of abbreviation
data.
It is handy for analyzing abbreviations but is not
normally needed by applications.
The function first appears in March 2016.
.P
On success the function returns \f(CWDW_DLV_OK\fP
and sets
\f(CW*abbrev_offset\fP
to the global offset
in the
\f(CW.debug_abbrev\fP
section of the abbreviation.
It also sets
\f(CW*abbrev_count\fP
to the number of attribute/form
pairs in the abbreviation entry.
It is possible, though unusual, for the
count to be zero (meaning there is abbreviation
instance and a TAG instance which have no attributes).
.P
On failure it returns
\f(CWDW_DLV_ERROR\fP
and sets \f(CW*error\fP
.P
It should never return \f(CWDW_DLV_NO_ENTRY\fP,
but callers should allow for that possibility..
.H 3 "dwarf_get_version_of_die()"
.DS
\f(CWint dwarf_get_version_of_die(Dwarf_Die die,
Dwarf_Half *version,
Dwarf_Half *offset_size)\fP
.DE
The function returns the CU context version through \f(CW*version\fP
and the CU context offset-size through \f(CW*offset_size\fP and
returns \f(CWDW_DLV_OK\fP on success.
In case of error, the only errors possible involve
an inappropriate NULL \f(CWdie\fP pointer so no Dwarf_Debug
pointer is available. Therefore setting a Dwarf_Error would not
be very meaningful (there is no Dwarf_Debug to
attach it to). The function returns DW_DLV_ERROR on error.
The values returned through the pointers are the values
two arguments to dwarf_get_form_class() requires.
.H 3 "dwarf_attrlist()"
.DS
\f(CWint dwarf_attrlist(
Dwarf_Die die,
Dwarf_Attribute** attrbuf,
Dwarf_Signed *attrcount,
Dwarf_Error *error)\fP
.DE
When it returns \f(CWDW_DLV_OK\fP,
the function \f(CWdwarf_attrlist()\fP sets \f(CWattrbuf\fP to point
to an array of \f(CWDwarf_Attribute\fP descriptors corresponding to
each of the attributes in die, and returns the number of elements in
the array through \f(CWattrcount\fP.
\f(CWDW_DLV_NO_ENTRY\fP is returned if the count is zero (no
\f(CWattrbuf\fP is allocated in this case).
\f(CWDW_DLV_ERROR\fP is returned on error.
On a successful return from \f(CWdwarf_attrlist()\fP, each of the
\f(CWDwarf_Attribute\fP descriptors should be individually freed using
\f(CWdwarf_dealloc()\fP with the allocation type \f(CWDW_DLA_ATTR\fP,
followed by free-ing the list pointed to by \f(CW*attrbuf\fP using
\f(CWdwarf_dealloc()\fP with the allocation type \f(CWDW_DLA_LIST\fP,
when no longer of interest (see \f(CWdwarf_dealloc()\fP).
Freeing the attrlist:
.in +2
.FG "Example8 dwarf_attrlist() free"
.DS
\f(CW
void example8(Dwarf_Debug dbg, Dwarf_Die somedie)
{
Dwarf_Signed atcount = 0;
Dwarf_Attribute *atlist = 0;
Dwarf_Error error = 0;
int errv = 0;
errv = dwarf_attrlist(somedie, &atlist,&atcount, &error);
if (errv == DW_DLV_OK) {
Dwarf_Signed i = 0;
for (i = 0; i < atcount; ++i) {
/* use atlist[i] */
dwarf_dealloc_attribute(atlist[i]);
/* The original form still works.
dwarf_dealloc(dbg, atlist[i], DW_DLA_ATTR);
*/
}
dwarf_dealloc(dbg, atlist, DW_DLA_LIST);
}
}
\fP
.DE
.in -2
.P
.H 3 "dwarf_hasattr()"
.DS
\f(CWint dwarf_hasattr(
Dwarf_Die die,
Dwarf_Half attr,
Dwarf_Bool *return_bool,
Dwarf_Error *error)\fP
.DE
When it succeeds, the
function \f(CWdwarf_hasattr()\fP returns \f(CWDW_DLV_OK\fP
and sets \f(CW*return_bool\fP to \fInon-zero\fP if
\f(CWdie\fP has the attribute \f(CWattr\fP and \fIzero\fP otherwise.
If it fails, it returns \f(CWDW_DLV_ERROR\fP.
.H 3 "dwarf_attr()"
.DS
\f(CWint dwarf_attr(
Dwarf_Die die,
Dwarf_Half attr,
Dwarf_Attribute *return_attr,
Dwarf_Error *error)\fP
.DE
.P
When it returns \f(CWDW_DLV_OK\fP,
the function \f(CWdwarf_attr()\fP
sets
\f(CW*return_attr\fP to the
\f(CWDwarf_Attribute\fP
descriptor of \f(CWdie\fP having the attribute \f(CWattr\fP.
When one no longer needs the attribute call
\f(CWdwarf_dealloc_attribute(return_attr)\fP.
.P
It returns
\f(CWDW_DLV_NO_ENTRY\fP if
\f(CWattr\fP is not contained
in
\f(CWdie\fP.
.P
It returns
\f(CWDW_DLV_ERROR\fP
and sets the *error argument if an error occurred.
.H 3 "dwarf_lowpc()"
.DS
\f(CWint dwarf_lowpc(
Dwarf_Die die,
Dwarf_Addr * return_lowpc,
Dwarf_Error * error)\fP
.DE
The function \f(CWdwarf_lowpc()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*return_lowpc\fP
to the low program counter
value associated with the \f(CWdie\fP descriptor if \f(CWdie\fP
represents a debugging information entry with the
\f(CWDW_AT_low_pc\fP attribute.
It returns \f(CWDW_DLV_NO_ENTRY\fP if \f(CWdie\fP does not have this
attribute.
It returns \f(CWDW_DLV_ERROR\fP if an error occurred.
.H 3 "dwarf_highpc_b()"
.DS
\f(CWint dwarf_highpc_b(
Dwarf_Die die,
Dwarf_Addr * return_highpc,
Dwarf_Half * return_form*/,
enum Dwarf_Form_Class * return_class*/,
Dwarf_Error *error)\fP
.DE
The function \f(CWdwarf_highpc_b()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*return_highpc\fP
to the value of the \f(CWDW_AT_high_pc\fP attribute.
It also sets
\f(CW*return_form\fP
to the FORM
of the attribute.
Beginning 22 April 2019
\f(CWreturn_form\fP
will not be used to return the form class
if
\f(CWreturn_form\fP
is null.
Be cautious using a null argument
unless you know that only a suitably
recent version of libdwarf will be used.
It sets
\f(CW*return_class\fP
to the form class
of the attribute.
Beginning 22 April 2019
\f(CWreturn_class\fP
will not be used to return the form class
if
\f(CWreturn_class\fP
is null.
Be cautious using a null argument
unless you know that only a suitably
recent version of libdwarf will be used.
If the form class returned is \f(CWDW_FORM_CLASS_ADDRESS\fP
the \f(CWreturn_highpc\fP is an actual pc address (1 higher
than the address of the last pc in the address range)..
If the form class returned is \f(CWDW_FORM_CLASS_CONSTANT\fP
the \f(CWreturn_highpc\fP is an offset from the value of
the the DIE's low PC address (see DWARF4 section 2.17.2 Contiguous
Address Range).
It returns \f(CWDW_DLV_NO_ENTRY\fP if \f(CWdie\fP does not have
the \f(CWDW_AT_high_pc\fP attribute.
It returns \f(CWDW_DLV_ERROR\fP if an error occurred.
.H 3 "dwarf_highpc()"
.DS
\f(CWint dwarf_highpc(
Dwarf_Die die,
Dwarf_Addr * return_highpc,
Dwarf_Error *error)\fP
.DE
The function \f(CWdwarf_highpc()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*return_highpc\fP
the high program counter
value associated with the \f(CWdie\fP descriptor if \f(CWdie\fP
represents a debugging information entry with the
\f(CWDW_AT_high_pc attribute\fP and the form is \f(CWDW_FORM_addr\fP
(meaning the form is of class address).
.P
This function is useless for a \f(CWDW_AT_high_pc\fP
which is encoded as a constant (which was first possible in
DWARF4).
.P
It returns \f(CWDW_DLV_NO_ENTRY\fP if \f(CWdie\fP does not have this
attribute.
.P
It returns \f(CWDW_DLV_ERROR\fP if an error occurred or if the
form is not of class address.
.H 3 "dwarf_dietype_offset()"
.DS
\f(CWint dwarf_dietype_offset(Dwarf_Die /*die*/,
Dwarf_Off * /*return_off*/,
Dwarf_Error * /*error*/);\fP
.DE
On success the function
\f(CWdwarf_dietype_offset()\fP
returns
the offset referred to by
\f(CWDW_AT_type\fP
attribute of
\f(CWdie\fP.
.P
\f(CWDW_DLV_NO_ENTRY\fP
is returned if the
\f(CWdie\fP
has no
\f(CWDW_AT_type\fP
attribute.
.P
\f(CWDW_DLV_ERROR\fP
is returned if an error is
detected.
.P
This feature was introduced in February 2016.
.H 3 "dwarf_offset_list()"
.DS
\f(CWint dwarf_offset_list(Dwarf_Debug dbg,
Dwarf_Off offset,
Dwarf_Bool is_info,
Dwarf_Off ** offbuf,
Dwarf_Unsigned * offcnt,
Dwarf_Error * error);
.DE
On success The function
\f(CWdwarf_offset_list()\fP
returns
\f(CWDW_DLV_OK\fP and
sets
\f(CW*offbuf\fP to point to
an array of the offsets of the direct children
of the die
at
\f(CWoffset\fP.
It sets
\f(CW*offcnt\fP to point to
the count of entries in
the
\f(CWoffset\fP array
.P
In case of error it returns
\f(CWDW_DLV_OK\fP.
.P
It does not return
\f(CWDW_DLV_NO_ENTRY\fP
but callers should allow
for that possibility anyway.
.P
This feature was introduced in March 2016.
.P
Freeing the offset_list is done as follows.:
.in +2
.FG "Exampleoffset_list dwarf_offset_list() free"
.DS
\f(CW
void exampleoffset_list(Dwarf_Debug dbg, Dwarf_Off dieoffset,
Dwarf_Bool is_info)
{
Dwarf_Unsigned offcnt = 0;
Dwarf_Off *offbuf = 0;
Dwarf_Error error = 0;
int errv = 0;
errv = dwarf_offset_list(dbg,dieoffset, is_info,
&offbuf,&offcnt, &error);
if (errv == DW_DLV_OK) {
Dwarf_Unsigned i = 0;
for (i = 0; i < offcnt; ++i) {
/* use offbuf[i] */
}
dwarf_dealloc(dbg, offbuf, DW_DLA_LIST);
}
}
\fP
.DE
.in -2
.P
.H 3 "dwarf_bytesize()"
.DS
\f(CWDwarf_Signed dwarf_bytesize(
Dwarf_Die die,
Dwarf_Unsigned *return_size,
Dwarf_Error *error)\fP
.DE
When it succeeds,
\f(CWdwarf_bytesize()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*return_size\fP
to the number of bytes
needed to contain an instance of the aggregate debugging information
entry represented by \f(CWdie\fP.
It returns \f(CWDW_DLV_NO_ENTRY\fP if
\f(CWdie\fP does not contain the byte size attribute \f(CWDW_AT_byte_size\fP.
It returns \f(CWDW_DLV_ERROR\fP if
an error occurred.
.H 3 "dwarf_bitsize()"
.DS
\f(CWint dwarf_bitsize(
Dwarf_Die die,
Dwarf_Unsigned *return_size,
Dwarf_Error *error)\fP
.DE
When it succeeds,
\f(CWdwarf_bitsize()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*return_size\fP
to the number of
bits
occupied by the bit field value that is an attribute of the given
die.
It returns \f(CWDW_DLV_NO_ENTRY\fP if \f(CWdie\fP does not
contain the bit size attribute \f(CWDW_AT_bit_size\fP.
It returns \f(CWDW_DLV_ERROR\fP if
an error occurred.
.H 3 "dwarf_bitoffset()"
.DS
\f(CWint dwarf_bitoffset(
Dwarf_Die die,
Dwarf_Unsigned *return_size,
Dwarf_Error *error)\fP
.DE
When it succeeds,
\f(CWdwarf_bitoffset()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*return_size\fP
to the number of bits
to the left of the most significant bit of the bit field value.
This bit offset is not necessarily the net bit offset within the
structure or class , since \f(CWDW_AT_data_member_location\fP
may give a byte offset to this \f(CWDIE\fP and the bit offset
returned through the pointer
does not include the bits in the byte offset.
It returns \f(CWDW_DLV_NO_ENTRY\fP if \f(CWdie\fP does not contain the
bit offset attribute \f(CWDW_AT_bit_offset\fP.
It returns \f(CWDW_DLV_ERROR\fP if
an error occurred.
.H 3 "dwarf_srclang()"
.DS
\f(CWint dwarf_srclang(
Dwarf_Die die,
Dwarf_Unsigned *return_lang,
Dwarf_Error *error)\fP
.DE
When it succeeds,
\f(CWdwarf_srclang()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*return_lang\fP
to
a code indicating the
source language of the compilation unit represented by the descriptor
\f(CWdie\fP.
It returns \f(CWDW_DLV_NO_ENTRY\fP if \f(CWdie\fP does not
represent a source file debugging information entry (i.e. contain the
attribute \f(CWDW_AT_language\fP).
It returns \f(CWDW_DLV_ERROR\fP if
an error occurred.
.H 3 "dwarf_arrayorder()"
.DS
\f(CWint dwarf_arrayorder(
Dwarf_Die die,
Dwarf_Unsigned *return_order,
Dwarf_Error *error)\fP
.DE
When it succeeds,
\f(CWdwarf_arrayorder()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*return_order\fP
a code indicating
the ordering of the array represented by the descriptor \f(CWdie\fP.
It returns \f(CWDW_DLV_NO_ENTRY\fP if \f(CWdie\fP does not contain the
array order attribute \f(CWDW_AT_ordering\fP.
It returns \f(CWDW_DLV_ERROR\fP if
an error occurred.
.H 2 "Attribute Queries"
Based on the attributes form, these operations are concerned with
returning uninterpreted attribute data. Since it is not always
obvious from the return value of these functions if an error occurred,
one should always supply an
\f(CWerror\fP
parameter or have arranged
to have an error handling function invoked (see
\f(CWdwarf_init()\fP
)
to determine the validity of the returned value and the nature of any
errors that may have occurred.
A \f(CWDwarf_Attribute\fP descriptor describes an attribute of a
specific die. Thus, each \f(CWDwarf_Attribute\fP descriptor is
implicitly associated with a specific die.
.H 3 "dwarf_hasform()"
.DS
\f(CWint dwarf_hasform(
Dwarf_Attribute attr,
Dwarf_Half form,
Dwarf_Bool *return_hasform,
Dwarf_Error *error)\fP
.DE
The function \f(CWdwarf_hasform()\fP returns
\f(CWDW_DLV_OK\fP and and puts a
\fInon-zero\fP
value in the
\f(CW*return_hasform\fP boolean if the
attribute represented by the \f(CWDwarf_Attribute\fP descriptor
\f(CWattr\fP has the attribute form \f(CWform\fP.
If the attribute does not have that form \fIzero\fP
is put into \f(CW*return_hasform\fP.
\f(CWDW_DLV_ERROR\fP is returned on error.
.H 3 "dwarf_whatform()"
.DS
\f(CWint dwarf_whatform(
Dwarf_Attribute attr,
Dwarf_Half *return_form,
Dwarf_Error *error)\fP
.DE
When it succeeds,
\f(CWdwarf_whatform()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*return_form\fP
to the attribute form code of
the attribute represented by the \f(CWDwarf_Attribute\fP descriptor
\f(CWattr\fP.
It returns \f(CWDW_DLV_ERROR\fP on error.
An attribute using DW_FORM_indirect effectively has two forms.
This function returns the 'final' form for \f(CWDW_FORM_indirect\fP,
not the \f(CWDW_FORM_indirect\fP itself. This function is
what most applications will want to call.
.H 3 "dwarf_whatform_direct()"
.DS
\f(CWint dwarf_whatform_direct(
Dwarf_Attribute attr,
Dwarf_Half *return_form,
Dwarf_Error *error)\fP
.DE
When it succeeds,
\f(CWdwarf_whatform_direct()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*return_form\fP
to the attribute form code of
the attribute represented by the \f(CWDwarf_Attribute\fP descriptor
\f(CWattr\fP.
It returns \f(CWDW_DLV_ERROR\fP on error.
An attribute using \f(CWDW_FORM_indirect\fP effectively has two forms.
This returns the form 'directly' in the initial form field.
That is, it returns the 'initial' form of the attribute.
.P
So when the form field is \f(CWDW_FORM_indirect\fP
this call returns the \f(CWDW_FORM_indirect\fP form,
which is sometimes useful for dump utilities.
.P
It is confusing that the _direct() function returns
DW_FORM_indirect if an indirect form is involved.
Just think of this as returning the initial form the first
form value seen for the attribute, which is also the final
form unless the initial form is \f(CWDW_FORM_indirect\fP.
.H 3 "dwarf_whatattr()"
.DS
\f(CWint dwarf_whatattr(
Dwarf_Attribute attr,
Dwarf_Half *return_attr,
Dwarf_Error *error)\fP
.DE
When it succeeds,
\f(CWdwarf_whatattr()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*return_attr\fP
to the attribute code
represented by the \f(CWDwarf_Attribute\fP descriptor \f(CWattr\fP.
It returns \f(CWDW_DLV_ERROR\fP on error.
.H 3 "dwarf_formref()"
.DS
\f(CWint dwarf_formref(
Dwarf_Attribute attr,
Dwarf_Off *return_offset,
Dwarf_Error *error)\fP
.DE
When it succeeds,
\f(CWdwarf_formref()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP
to the CU-relative offset
represented by the descriptor \f(CWattr\fP if the form of the attribute
belongs to the \f(CWREFERENCE\fP class.
\f(CWattr\fP must be a CU-local reference,
not form \f(CWDW_FORM_ref_addr\fP and not \f(CWDW_FORM_sec_offset\fP .
It is an error for the form to
not belong to the \f(CWREFERENCE\fP class.
It returns \f(CWDW_DLV_ERROR\fP on error.
Beginning November 2010:
All \f(CWDW_DLV_ERROR\fP returns set \f(CW*return_offset\fP. Most
errors set \f(CW*return_offset\fP to zero, but
for error \f(CWDW_DLE_ATTR_FORM_OFFSET_BAD\fP
the function sets \f(CW*return_offset\fP to the invalid
offset (which allows the caller to print a more
detailed error message).
See also \f(CWdwarf_global_formref\fP below.
.H 3 "dwarf_global_formref()"
.DS
\f(CWint dwarf_global_formref(
Dwarf_Attribute attr,
Dwarf_Off *return_offset,
Dwarf_Error *error)\fP
.DE
When it succeeds,
\f(CWdwarf_global_formref()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP
to the section-relative offset
represented by the descriptor \f(CWattr\fP if the form of the attribute
belongs to the \f(CWREFERENCE\fP or other section-references classes.
.P
\f(CWattr\fP can be any legal
\f(CWREFERENCE\fP class form plus \f(CWDW_FORM_ref_addr\fP or
\f(CWDW_FORM_sec_offset\fP.
It is an error for the form to
not belong to one of the reference classes.
It returns \f(CWDW_DLV_ERROR\fP on error.
See also \f(CWdwarf_formref\fP above.
.P
The caller must determine which section the offset returned applies to.
The function \f(CWdwarf_get_form_class()\fP is useful to determine
the applicable section.
.P
The function converts CU relative offsets from forms
such as DW_FORM_ref4 into
global section offsets.
.H 3 "dwarf_convert_to_global_offset()"
.DS
\f(CWint dwarf_convert_to_global_offset(
Dwarf_Attribute attr,
Dwarf_Off offset,
Dwarf_Off *return_offset,
Dwarf_Error *error)\fP
.DE
When it succeeds,
\f(CWdwarf_convert_to_global_offset()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP
to the section-relative offset
represented by the cu-relative offset \f(CWoffset\fP
if the form of the attribute
belongs to the \f(CWREFERENCE\fP class.
\f(CWattr\fP must be a CU-local reference (DWARF class REFERENCE)
or form \f(CWDW_FORM_ref_addr\fP and the \f(CWattr\fP
must be directly relevant for the calculated \f(CW*return_offset\fP
to mean anything.
The function returns \f(CWDW_DLV_ERROR\fP on error.
The function is not strictly necessary but may be a
convenience for attribute printing in case of error.
.H 3 "dwarf_formaddr()"
.DS
\f(CWint dwarf_formaddr(
Dwarf_Attribute attr,
Dwarf_Addr * return_addr,
Dwarf_Error *error)\fP
.DE
When it succeeds,
\f(CWdwarf_formaddr()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*return_addr\fP
to
the address
represented by the descriptor \f(CWattr\fP if the form of the attribute
belongs to the \f(CWADDRESS\fP class.
It is an error for the form to
not belong to this class.
It returns \f(CWDW_DLV_ERROR\fP on error.
One possible error that can arise (in a .dwo object file
or a .dwp package file) is
\f(CWDW_DLE_MISSING_NEEDED_DEBUG_ADDR_SECTION\fP.
Such an error means that the .dwo or .dwp file
is missing the
\f(CW.debug_addr\fP
section.
When opening a .dwo object file or a .dwp package file
one should also open the corresponding executable
and use
\f(CWdwarf_set_tied_dbg()\fP
to associate the objects before calling dwarf_formaddr().
H 3 "dwarf_get_debug_addr_index()"
.DS
\f(CWint dwarf_get_debug_addr_index(
Dwarf_Attribute attr,
Dwarf_Unsigned * return_index,
Dwarf_Error *error)\fP
.DE
\f(CWdwarf_get_debug_addr_index()\fP
is only valid on attributes with form
\f(CWDW_FORM_GNU_addr_index\fP
or
\f(CWDW_FORM_addrx\fP.
The function makes it possible
to print the
index from a dwarf dumper program.
When it succeeds,
\f(CWdwarf_get_debug_addr_index()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*return_index\fP
to
the attribute's index (into the
\f(CW.debug_addr\fP section).
It returns \f(CWDW_DLV_ERROR\fP on error.
.H 3 "dwarf_get_debug_str_index()"
.DS
\f(CWint dwarf_get_debug_str_index(
Dwarf_Attribute attr,
Dwarf_Unsigned * return_index,
Dwarf_Error * error);\fP
.DE
.P
For an attribute with form
\f(CWDW_FORM_strx\fP
or
\f(CWDW_FORM_GNU_str_index\fP
this function retrieves the index (which refers
to a .debug_str_offsets section in this .dwo).
.P
If successful, the function
\f(CWdwarf_get_debug_str_index()\fP
returns
\f(CWDW_DLV_OK\fP
and
returns the index through the
\f(CWreturn_index()\fP pointer.
.P
If the passed in attribute does not have
this form or there is no valid compilation
unit context for the attribute the
function returns
\f(CWDW_DLV_ERROR\fP.
.P
\f(CWDW_DLV_NO_ENTRY\fP is not returned.
.H 3 "dwarf_formflag()"
.DS
\f(CWint dwarf_formflag(
Dwarf_Attribute attr,
Dwarf_Bool * return_bool,
Dwarf_Error *error)\fP
.DE
When it succeeds,
\f(CWdwarf_formflag()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*return_bool\fP
to the (one unsigned byte) flag value.
Any non-zero value means true.
A zero value means false.
Before 29 November 2012 this would only return 1 or zero
through the pointer, but that was always a strange thing to do.
The DWARF specification has always been clear that any non-zero
value means true. The function should report the value
found truthfully, and now it does.
It returns \f(CWDW_DLV_ERROR\fP on error or if the \f(CWattr\fP
does not have form flag.
.H 3 "dwarf_formudata()"
.DS
\f(CWint dwarf_formudata(
Dwarf_Attribute attr,
Dwarf_Unsigned * return_uvalue,
Dwarf_Error * error)\fP
.DE
The function
\f(CWdwarf_formudata()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*return_uvalue\fP
to
the \f(CWDwarf_Unsigned\fP
value of the attribute represented by the descriptor \f(CWattr\fP if the
form of the attribute belongs to the \f(CWCONSTANT\fP class.
It is an
error for the form to not belong to this class.
It returns \f(CWDW_DLV_ERROR\fP on error.
Never returns \f(CWDW_DLV_NO_ENTRY\fP.
For DWARF2 and DWARF3, \f(CWDW_FORM_data4\fP and \f(CWDW_FORM_data8\fP
are possibly class \f(CWCONSTANT\fP,
and for DWARF4 and later they
are definitely class \f(CWCONSTANT\fP.
.H 3 "dwarf_formsdata()"
.DS
\f(CWint dwarf_formsdata(
Dwarf_Attribute attr,
Dwarf_Signed * return_svalue,
Dwarf_Error *error)\fP
.DE
The function \f(CWdwarf_formsdata()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*return_svalue\fP
to
the \f(CWDwarf_Signed\fP
value of the attribute represented by the descriptor \f(CWattr\fP if the
form of the attribute belongs to the \f(CWCONSTANT\fP class.
It is an
error for the form to not belong to this class.
If the size of the data
attribute referenced is smaller than the size of the \f(CWDwarf_Signed\fP
type, its value is sign extended.
It returns \f(CWDW_DLV_ERROR\fP on error.
Never returns \f(CWDW_DLV_NO_ENTRY\fP.
For DWARF2 and DWARF3, \f(CWDW_FORM_data4\fP and \f(CWDW_FORM_data8\fP
are possibly class \f(CWCONSTANT\fP,
and for DWARF4 and later they
are definitely class \f(CWCONSTANT\fP.
.H 3 "dwarf_formblock()"
.DS
\f(CWint dwarf_formblock(
Dwarf_Attribute attr,
Dwarf_Block ** return_block,
Dwarf_Error * error)\fP
.DE
The function \f(CWdwarf_formblock()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*return_block\fP
to
a pointer to a
\f(CWDwarf_Block\fP structure containing the value of the attribute
represented by the descriptor \f(CWattr\fP if the form of the
attribute belongs to the \f(CWBLOCK\fP class.
It is an error
for the form to not belong to this class.
The storage pointed
to by a successful return of \f(CWdwarf_formblock()\fP should
be freed using the allocation type \f(CWDW_DLA_BLOCK\fP, when
no longer of interest (see \f(CWdwarf_dealloc()\fP).
It returns
\f(CWDW_DLV_ERROR\fP on error.
.H 3 "dwarf_formstring()"
.DS
\f(CWint dwarf_formstring(
Dwarf_Attribute attr,
char ** return_string,
Dwarf_Error *error)\fP
.DE
The function \f(CWdwarf_formstring()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*return_string\fP
to
a pointer to a
null-terminated string containing the value of the attribute
represented by the descriptor \f(CWattr\fP if the form of the
attribute belongs to the \f(CWSTRING\fP class.
It is an error
for the form to not belong to this class.
.P
The storage pointed
to by a successful return of \f(CWdwarf_formstring()\fP
should not be freed. The pointer points into
existing DWARF memory and the pointer becomes stale/invalid
after a call to \f(CWdwarf_finish\fP.
\f(CWdwarf_formstring()\fP returns \f(CWDW_DLV_ERROR\fP on error.
.H 3 "dwarf_formsig8()"
.DS
\f(CWint dwarf_formsig8(
Dwarf_Attribute attr,
Dwarf_Sig8 * return_sig8,
Dwarf_Error * error)\fP
.DE
The function \f(CWdwarf_formsig8()\fP returns
\f(CWDW_DLV_OK\fP and copies the 8 byte signature
to a \f(CWDwarf_Sig8\fP structure provided by the caller
if the form of the
attribute is of form \f(CWDW_FORM_ref_sig8\fP
( a member of the \f(CWREFERENCE\fP class).
It is an error
for the form to be anything but \f(CWDW_FORM_ref_sig8\fP.
It returns \f(CWDW_DLV_ERROR\fP on error.
.P
This form is used to refer to a type unit.
.H 3 "dwarf_formexprloc()"
.DS
\f(CWint dwarf_formexprloc(
Dwarf_Attribute attr,
Dwarf_Unsigned * return_exprlen,
Dwarf_Ptr * block_ptr,
Dwarf_Error * error)\fP
.DE
The function \f(CWdwarf_formexprloc()\fP returns
\f(CWDW_DLV_OK\fP and sets the two values thru the pointers
to the length and bytes of the DW_FORM_exprloc entry
if the form of the
attribute is of form \f(CWDW_FORM_experloc\fP.
It is an error
for the form to be anything but \f(CWDW_FORM_exprloc\fP.
It returns \f(CWDW_DLV_ERROR\fP on error.
.P
On success the value set through the
\f(CWreturn_exprlen\fP pointer is the length
of the location expression.
On success the value set through the
\f(CWblock_ptr\fP pointer is a pointer to
the bytes of the location expression itself.
.H 3 "dwarf_get_form_class()"
.DS
\f(CWenum Dwarf_Form_Class dwarf_get_form_class(
Dwarf_Half dwversion,
Dwarf_Half attrnum,
Dwarf_Half offset_size,
Dwarf_Half form)\fP
.DE
.P
The function is just for the convenience
of libdwarf clients that might wish to categorize
the FORM of a particular attribute.
The DWARF specification divides FORMs into classes
in Chapter 7 and this function figures out the correct
class for a form.
.P
The \f(CWdwversion\fP passed in shall be the dwarf version
of the compilation unit involved (2 for DWARF2, 3 for
DWARF3, 4 for DWARF 4).
The \f(CWattrnum\fP passed in shall be the attribute
number of the attribute involved (for example, \f(CWDW_AT_name\fP ).
The \f(CWoffset_size\fP passed in shall be the
length of an offset in the current compilation unit
(4 for 32bit dwarf or 8 for 64bit dwarf).
The \f(CWform\fP passed in shall be the attribute form number.
If \f(CWform\fP
\f(CWDW_FORM_indirect\fP
is passed in \f(CWDW_FORM_CLASS_UNKNOWN\fP will be returned
as this form has no defined 'class'.
.P
When it returns \f(CWDW_FORM_CLASS_UNKNOWN\fP the
function is simply saying it could not determine the
correct class given the arguments
presented. Some user-defined
attributes might have this problem.
The function \f(CWdwarf_get_version_of_die()\fP may be helpful
in filling out arguments for a call to \f(CWdwarf_get_form_class()\fP.
.H 3 "dwarf_discr_list()"
.DS
\f(CWint dwarf_discr_list(
Dwarf_Debug dbg,
Dwarf_Small * blockpointer,
Dwarf_Unsigned blocklen,
Dwarf_Dsc_Head * dsc_head_out,
Dwarf_Unsigned * dsc_array_length_out,
Dwarf_Error * error)
Dwarf_Error *error)\fP
.DE
When it succeeds,
\f(CWdwarf_discr_list()\fP
returns
\f(CWDW_DLV_OK\fP and sets
\f(CW*dsc_head_out\fP
to a pointer to the discriminant information
for the discriminant list and sets
\f(CW*dsc_array_length_out\fP
to the count of discriminant entries.
The only current applicability is
the block value of a
\f(CWDW_AT_discr_list\fP
attribute.
.P
Those values are useful for calls to
\f(CWdwarf_discr_entry_u()\fP
or
\f(CWdwarf_discr_entry_s()\fP
to get the actual discriminant values.
See the example below.
It returns \f(CWDW_DLV_NO_ENTRY\fP if
the block is empty.
It returns
\f(CWDW_DLV_ERROR\fP
if
an error occurred.
.P
When the call was successful and
the
\f(CWDwarf_Dsc_Head\fP
is no longer needed, call
\f(CWdwarf_dealloc()\fP
to free all the space
related to this.
.DS
void example_discr_list(Dwarf_Debug dbg,
Dwarf_Die die,
Dwarf_Attribute attr,
Dwarf_Half attrnum,
Dwarf_Bool isunsigned,
Dwarf_Half theform,
Dwarf_Error *err)
{
/* The example here assumes that
attribute attr is a DW_AT_discr_list.
isunsigned should be set from the signedness
of the parent of 'die' per DWARF rules for
DW_AT_discr_list. */
enum Dwarf_Form_Class fc = DW_FORM_CLASS_UNKNOWN;
Dwarf_Half version = 0;
Dwarf_Half offset_size = 0;
int wres = 0;
wres = dwarf_get_version_of_die(die,&version,&offset_size);
if (wres != DW_DLV_OK) {
/* FAIL */
return;
}
fc = dwarf_get_form_class(version,attrnum,offset_size,theform);
if (fc == DW_FORM_CLASS_BLOCK) {
int fres = 0;
Dwarf_Block *tempb = 0;
fres = dwarf_formblock(attr, &tempb, err);
if (fres == DW_DLV_OK) {
Dwarf_Dsc_Head h = 0;
Dwarf_Unsigned u = 0;
Dwarf_Unsigned arraycount = 0;
int sres = 0;
sres = dwarf_discr_list(dbg,
(Dwarf_Small *)tempb->bl_data,
tempb->bl_len,
&h,&arraycount,err);
if (sres == DW_DLV_NO_ENTRY) {
/* Nothing here. */
dwarf_dealloc(dbg, tempb, DW_DLA_BLOCK);
return;
}
if (sres == DW_DLV_ERROR) {
/* FAIL . */
dwarf_dealloc(dbg, tempb, DW_DLA_BLOCK);
return;
}
for(u = 0; u < arraycount; u++) {
int u2res = 0;
Dwarf_Half dtype = 0;
Dwarf_Signed dlow = 0;
Dwarf_Signed dhigh = 0;
Dwarf_Unsigned ulow = 0;
Dwarf_Unsigned uhigh = 0;
if (isunsigned) {
u2res = dwarf_discr_entry_u(h,u,
&dtype,&ulow,&uhigh,err);
} else {
u2res = dwarf_discr_entry_s(h,u,
&dtype,&dlow,&dhigh,err);
}
if( u2res == DW_DLV_ERROR) {
/* Something wrong */
dwarf_dealloc(dbg,h,DW_DLA_DSC_HEAD);
dwarf_dealloc(dbg, tempb, DW_DLA_BLOCK);
return;
}
if( u2res == DW_DLV_NO_ENTRY) {
/* Impossible. u < arraycount. */
dwarf_dealloc(dbg,h,DW_DLA_DSC_HEAD);
dwarf_dealloc(dbg, tempb, DW_DLA_BLOCK);
return;
}
/* Do something with dtype, and whichever
of ulow, uhigh,dlow,dhigh got set.
Probably save the values somewhere.
Simple casting of dlow to ulow (or vice versa)
will not get the right value due to the nature
of LEB values. Similarly for uhigh, dhigh.
One must use the right call.
*/
}
dwarf_dealloc(dbg,h,DW_DLA_DSC_HEAD);
dwarf_dealloc(dbg, tempb, DW_DLA_BLOCK);
}
}
}
.DE
.H 3 "dwarf_discr_entry_u()"
.DS
\f(CWint dwarf_discr_entry_u(
Dwarf_Dsc_Head dsc_head,
Dwarf_Unsigned dsc_array_index,
Dwarf_Half *dsc_type,
Dwarf_Unsigned *dsc_low,
Dwarf_Unsigned *dsc_high,
Dwarf_Error *error)\fP
.DE
When it succeeds,
\f(CWdwarf_discr_entry_u()\fP
returns
\f(CWDW_DLV_OK\fP and sets
\f(CW*dsc_type\fP,
\f(CW*dsc_low\fP,
and
\f(CW*dsc_high\fP
to the discriminant values for that index.
Valid
\f(CWdsc_array_index\fP
values
are zero to
\f(CW(dsc_array_length_out -1)\fP
from a
\f(CWdwarf_discr_list()\fP
call.
.P
If
\f(CW*dsc_type\fP is
\f(CWDW_DSC_label\fP
\f(CW*dsc_low\fP is
set to the discriminant value
and
\f(CW*dsc_high\fP is set to zero.
.P
If
\f(CW*dsc_type\fP
is
\f(CWDW_DSC_range\fP
\f(CW*dsc_low\fP
is
set to the low end of the discriminant
range and
and
\f(CW*dsc_high\fP is set to
the high end of the discriminant range.
.P
Due to the nature of the LEB numbers in
the discriminant representation in DWARF
one must call the correct one of
\f(CWdwarf_discr_entry_u()\fP
or
\f(CWdwarf_discr_entry_s()\fP
based on whether the discriminant is
signed or unsigned.
Casting an unsigned to signed is
not always going to get the right value.
.P
If
\f(CWdsc_array_index\fP
is outside the range of valid indexes
the function returns
\f(CWDW_DLV_NO_ENTRY\fP.
On error it returns
\f(CWDW_DLV_ERROR\fP
and sets
\f(CW*error\fP
to an error pointer.
.H 3 "dwarf_discr_entry_s()"
.DS
\f(CWint dwarf_discr_entry_s(
Dwarf_Dsc_Head dsc_head,
Dwarf_Unsigned dsc_array_index,
Dwarf_Half *dsc_type,
Dwarf_Signed *dsc_low,
Dwarf_Signed *dsc_high,
Dwarf_Error *error)\fP
.DE
This is identical to
\f(CWdwarf_discr_entry_u()\fP
except that the discriminant values
are signed values in this interface.
Callers must check the discriminant type
and call the correct function.
.H 2 "Location List Operations, Raw .debug_loclists"
This set of interfaces is to read the
(entire)
\f(CW.debug_loclists\fP
section without reference
to any DIE.
As such these can only present the
raw data from the file. There is no way
in these interfaces to get actual addresses.
These might be of interest if you want to
know exactly what the compiler output in
the
\f(CW.debug_loclists\fP
section.
"dwarfdump ----print-raw-loclists"
(try adding -v or -vvv)
makes these calls.
.P
Here is
an example using all the following calls.
.in +2
.FG "Example Raw Loclist"
.DS
\f(CW
int example_raw_loclist(Dwarf_Debug dbg,Dwarf_Error *error)
{
Dwarf_Unsigned count = 0;
int res = 0;
Dwarf_Unsigned i = 0;
res = dwarf_load_loclists(dbg,&count,error);
if (res != DW_DLV_OK) {
return res;
}
for(i =0 ; i < count ; ++i) {
Dwarf_Unsigned header_offset = 0;
Dwarf_Small offset_size = 0;
Dwarf_Small extension_size = 0;
unsigned version = 0; /* 5 */
Dwarf_Small address_size = 0;
Dwarf_Small segment_selector_size = 0;
Dwarf_Unsigned offset_entry_count = 0;
Dwarf_Unsigned offset_of_offset_array = 0;
Dwarf_Unsigned offset_of_first_locentry = 0;
Dwarf_Unsigned offset_past_last_loceentry = 0;
res = dwarf_get_loclist_context_basics(dbg,i,
&header_offset,&offset_size,&extension_size,
&version,&address_size,&segment_selector_size,
&offset_entry_count,&offset_of_offset_array,
&offset_of_first_locentry,
&offset_past_last_locentry,error);
if (res != DW_DLV_OK) {
return res;
}
{
Dwarf_Unsigned e = 0;
unsigned colmax = 4;
unsigned col = 0;
Dwarf_Unsigned global_offset_of_value = 0;
for ( ; e < offset_entry_count; ++e) {
Dwarf_Unsigned value = 0;
int resc = 0;
resc = dwarf_get_loclist_offset_index_value(dbg,
i,e,&value,
&global_offset_of_value,error);
if (resc != DW_DLV_OK) {
return resc;
}
/* Do something */
col++;
if (col == colmax) {
col = 0;
}
}
}
{
Dwarf_Unsigned curoffset = offset_of_first_loceentry;
Dwarf_Unsigned endoffset = offset_past_last_loceentry;
int rese = 0;
Dwarf_Unsigned ct = 0;
for ( ; curoffset < endoffset; ++ct ) {
unsigned entrylen = 0;
unsigned code = 0;
Dwarf_Unsigned v1 = 0;
Dwarf_Unsigned v2 = 0;
rese = dwarf_get_loclist_lle(dbg,i,
curoffset,endoffset,
&entrylen,
&code,&v1,&v2,error);
if (rese != DW_DLV_OK) {
return rese;
}
curoffset += entrylen;
if (curoffset > endoffset) {
return DW_DLV_ERROR;
}
}
}
}
return DW_DLV_OK;
}
\fP
.DE
.in -2
.H 3 "dwarf_load_loclists()"
.DS
\f(CWint dwarf_load_loclists(
Dwarf_Debug dbg,
Dwarf_Unsigned *loclists_count,
Dwarf_Error *error)\fP
.DE
On a successful call to
\f(CWdwarf_load_loclists()\fP
the function returns
\f(CWDW_DLV_OK\fP,
sets
\f(CW*loclists_count\fP
(if and only if
\f(CWloclists_count\fP
is non-null) to the number of distinct
section contents that exist.
A small amount of data for each Location List Table
(DWARF5 section 7.29)
is recorded in
\f(CWdbg\fP as a side effect.
Normally libdwarf will have already called this,
but if an application never requests any
\f(CW.debug_info\fP
data the section might not be loaded.
If the section is loaded this returns
very quickly and will set
\f(CW*loclists_count\fP
just as described in this paragraph.
.P
If there is no
\f(CW.debug_loclists\fP
section in the object file this function returns
\f(CWDW_DLV_NO_ENTRY\fP.
.P
If something is malformed it returns
\f(CWDW_DLV_ERROR\fP
and sets
\f(CW*error\fP
to the applicable error pointer describgin the problem.
.P
There is no dealloc call. Calling
\f(CWdwarf_finish()\fP
releases the modest amount of memory
recorded for this section as a side effect.
.P
.H 3 "dwarf_get_loclist_context_basics()"
.DS
\f(CWint dwarf_get_loclist_context_basics(Dwarf_Debug dbg,
Dwarf_Unsigned context_index,
Dwarf_Unsigned * header_offset,
Dwarf_Small * offset_size,
Dwarf_Small * extension_size,
unsigned * version, /* 5 */
Dwarf_Small * address_size,
Dwarf_Small * segment_selector_size,
Dwarf_Unsigned * offset_entry_count,
Dwarf_Unsigned * offset_of_offset_array,
Dwarf_Unsigned * offset_of_first_locentry,
Dwarf_Unsigned * offset_past_last_locentry,
Dwarf_Error * /*err*/);\fP
.DE
On success this returns
\f(CWDW_DLV_OK\fP
and returns values through the pointer arguments
(other than
\f(CWdbg\fP
or
\f(CWerror\fP)
.P
A call to
\f(CWdwarf_load_loclists()\fP
that suceeds gets you the count
of contexts
and
\f(CWdwarf_get_loclist_context_basics()\fP
for any "i >=0 and i < count"
gets you the context values relevant to
\f(CW.debug_loclists\fP.
.P
Any of the pointer-arguments for returning context values
can be passed in as 0 (in which case they will be skipped).
.P
You will want
\f(CW*offset_entry_count\fP
so you can call
\f(CWdwarf_get_loclist_offset_index_value()\fP
usefully.
.P
If the
\f(CWcontext_index\fP
passed in is out of range the function returns
\f(CWDW_DLV_NO_ENTRY\fP
.P
At the present time
\f(CWDW_DLV_ERROR\fP
is never returned.
.H 3 "dwarf_get_loclist_offset_index_value()"
.DS
\f(CWint dwarf_get_loclist_offset_index_value(Dwarf_Debug dbg,
Dwarf_Unsigned context_index,
Dwarf_Unsigned offsetentry_index,
Dwarf_Unsigned * offset_value_out,
Dwarf_Unsigned * global_offset_value_out,
Dwarf_Error *error)\fP
.DE
.P
On success
\f(CWdwarf_get_loclist_offset_index_value()\fP
returns
\f(CWDW_DLV_OK\fP,
sets
\f(CW* offset_value_out\fP
to the value in the Range List Table
offset array,
and sets
\f(CW* global_offset_value_out\fP
to the section offset (in
\f(CW.debug_addr\fP)
of the offset value.
.P
Pass in
\f(CWcontext_index\fP
exactly as the same field passed to
\f(CWdwarf_get_loclist_context_basics()\fP.
.P
Pass in
\f(CWoffset_entry_index\fP
based on the return field
\f(CWoffset_entry_count\fP
from
\f(CWdwarf_get_loclist_context_basics()\fP,
meaning for that
\f(CWcontext_index\fP
an
\f(CWoffset_entry_index\fP >=0
and <
\f(CWoffset_entry_count\fP.
.P
Pass in
\f(CWoffset_entry_count\fP
exactly as the same field passed to
\f(CWdwarf_get_loclist_context_basics()\fP.
.P
If one of the indexes passed in is out of range
\f(CWDW_DLV_NO_ENTRY\fP will
be returned and no return arguments touched.
.P
If there is some corruption of DWARF5 data
then
\f(CWDW_DLV_ERROR\fP
might be returned
and
\f(CW*error\fP
set to the error details.
.H 3 "dwarf_get_loclist_lle()"
.DS
\f(CWint dwarf_get_loclist_lle(
Dwarf_Debug dbg,
Dwarf_Unsigned contextnumber,
Dwarf_Unsigned entry_offset,
Dwarf_Unsigned endoffset,
unsigned *entrylen,
unsigned *entry_kind,
Dwarf_Unsigned *entry_operand1,
Dwarf_Unsigned *entry_operand2,
Dwarf_Unsigned *expr_ops_blocksize,
Dwarf_Unsigned *expr_ops_offset,
Dwarf_Small **expr_opsdata,
Dwarf_Error *error)\fP
.DE
On success
it returns a single
\f(CWDW_RLE*\fP
record
(see dwarf.h)
fields.
.P
\f(CWcontextnumber\fP
is the number of the current loclist context.
.P
\f(CWentry_offset\fP
is the section offset (section-global
offset) of the next record.
.P
\f(CWendoffset\fP
is one past the last entry in this
rle context.
.P
\f(CW*entrylen\fP
returns the length in the .debug_loclists section
of the particular record returned.
It's used to increment to the next record
within this loclist context.
.P
\f(CW*entrykind\fP
returns is the \f(CWDW_RLE*\fP number.
.P
Some record kinds have 1 or 0 operands,
most have two operands (the records
describing ranges).
.P
\f(CW*expr_ops_blocksize\fP
returns the size, in bytes, of the Dwarf Expression
(some operations have no Dwarf Expression
and those that do can have a zero length
blocksize.
.P
\f(CW*expr_ops_offset\fP
returns the offset (in the .debug_loclists
section) of the first byte of the Dwarf Expression.
.P
\f(CW*expr_opsdata\fP
returns a pointer to the bytes
of the Dwarf Expression.
.P
If the contextnumber is out of range
it will return
\f(CWDW_DLV_NO_ENTRY\fP.
.P
If the
\f(CW.debug_loclists\fP
section is malformed
or the
\f(CWentry_offset\fP
is incorrect
it may return
\f(CWDW_DLV_ERROR\fP.
.H 2 "Location List operations .debug_loc & .debug_loclists"
These operations apply to the .debug_loc section
in DWARF2, DWARF3, DWARF4, and DWARF5 object files.
Earlier versions still work as well as ever,
but they only deal with, at most, DWARF2,
DWARF3, and DWARF4.
.H 3 "dwarf_get_loclist_c()"
.DS
\f(CW
int dwarf_get_loclist_c (Dwarf_Attribute attr,
Dwarf_Loc_Head_c * loclist_head,
Dwarf_Unsigned * locCount,
Dwarf_Error * error);
\fP
.DE
This function returns a pointer that is, in turn,
used to make possible calls to return the details
of the location list.
.P
The incoming argument
\f(CWattr\fP
should have one of the FORMs of a location
expression or location list.
.P
On success this returns
\f(CWDW_DLV_OK\fP
and sets
\f(CW*loclist_head\fP
to a pointer used in further calls (see the example
and descriptions that follow it).
\f(CWlocCount\fP
is set to the number of entries
in the location list (or if the FORM is of a location
expression the
\f(CWlocCount\fP
will be set to one).
At this point one cannot yet tell if it was a location
list or a location expression (see .
\f(CWdwarf_get_locdesc_entry_c{}\fP).
.P
In case of error
\f(CWDW_DLV_ERROR\fP
is returned and
\f(CW*error\fP
is set to an error designation.
.P
A return of
\f(CWDW_DLV_NO_ENTRY\fP
may be possible but is a bit odd.
.DS
\f(CW
void example_loclistcv5(Dwarf_Debug dbg,Dwarf_Attribute someattr)
{
Dwarf_Unsigned lcount = 0;
Dwarf_Loc_Head_c loclist_head = 0;
Dwarf_Error error = 0;
int lres = 0;
lres = dwarf_get_loclist_c(someattr,&loclist_head,&lcount,&error);
if (lres == DW_DLV_OK) {
Dwarf_Unsigned i = 0;
/* Before any return remember to call
dwarf_loc_head_c_dealloc(loclist_head); */
for (i = 0; i < lcount; ++i) {
Dwarf_Small loclist_lkind = 0;
Dwarf_Small lle_value = 0;
Dwarf_Unsigned rawval1 = 0;
Dwarf_Unsigned rawval2 = 0;
Dwarf_Bool debug_addr_unavailable = FALSE;
Dwarf_Addr lopc = 0;
Dwarf_Addr hipc = 0;
Dwarf_Unsigned loclist_expr_op_count = 0;
Dwarf_Locdesc_c locdesc_entry = 0;
Dwarf_Unsigned expression_offset = 0;
Dwarf_Unsigned locdesc_offset = 0;
lres = dwarf_get_locdesc_entry_d(loclist_head,
i,
&lle_value,
&rawval1,&rawval2,
&debug_addr_unavailable,
&lopc,&hipc,
&loclist_expr_op_count,
&locdesc_entry,
&loclist_lkind,
&expression_offset,
&locdesc_offset,
&error);
if (lres == DW_DLV_OK) {
Dwarf_Unsigned j = 0;
int opres = 0;
Dwarf_Small op = 0;
for (j = 0; j < loclist_expr_op_count; ++j) {
Dwarf_Unsigned raw1 = 0;
Dwarf_Unsigned raw2 = 0;
Dwarf_Unsigned raw3 = 0;
Dwarf_Unsigned opd1 = 0;
Dwarf_Unsigned opd2 = 0;
Dwarf_Unsigned opd3 = 0;
Dwarf_Unsigned offsetforbranch = 0;
opres = dwarf_get_location_op_value_d(
locdesc_entry,
j,&op,
&raw1,&raw2,&raw3,
&opd1, &opd2,&opd3,&offsetforbranch,
&error);
if (opres == DW_DLV_OK) {
/* Do something with the operators.
Usually you want to use opd1,2,3
as appropriate. Calculations
involving base addresses etc
have already been incorporated
in opd1,2,3. */
} else {
dwarf_dealloc_error(dbg,error);
dwarf_loc_head_c_dealloc(loclist_head);
/*Something is wrong. */
return;
}
}
} else {
/* Something is wrong. Do something. */
dwarf_loc_head_c_dealloc(loclist_head);
dwarf_dealloc_error(dbg,error);
return;
}
}
}
/* Always call dwarf_loc_head_c_dealloc()
to free all the memory associated with loclist_head. */
if (error) {
dwarf_dealloc_error(dbg,error);
}
dwarf_loc_head_c_dealloc(loclist_head);
loclist_head = 0;
return;
}
\fP
.DE
.H 3 "dwarf_get_locdesc_entry_d()"
Earlier versions of this work with earlier
versions of DWARF. This works with all
DWARF from DWARF2 on.
.DS
\f(CW
int dwarf_get_locdesc_entry_d(Dwarf_Loc_Head_c /*loclist_head*/,
Dwarf_Unsigned index,
Dwarf_Small *lle_value_out,
Dwarf_Addr *rawval1_out,
Dwarf_Addr *rawval2_out,
Dwarf_Bool *debug_addr_unavailable,
Dwarf_Addr *lopc_out,
Dwarf_Addr *hipc_out,
Dwarf_Unsigned *loc_expr_op_count_out,
Dwarf_Locdesc_c *locentry_out,
Dwarf_Small *loclist_kind,
Dwarf_Unsigned *expression_offset_out,
Dwarf_Unsigned *locdesc_offset_out,
Dwarf_Error *error);
\fP
.DE
This function returns overall information about a
location list or location description.
Details about location operators are retrieved
by a call to
\f(CWdwarf_get_location_op_value_d()\fP
(described
below).
In case of success
\f(CWDW_DLV_OK\fP
is returned and arguments are set through
the pointers to return values to the caller.
Now we describe each argument.
.P
\f(CW*loclist_kind\fP returns
\f(CWDW_LKIND_expression\fP,
\f(CWDW_LKIND_loclist\fP,
\f(CWDW_LKIND_GNU_exp_list\fP,
or
\f(CWDW_LKIND_loclists\fP.
.P
\f(CWDW_LKIND_expression\fP means
the 'list' is really just a location
expression. The only entry
is with \f(CWindex\fP zero.
In this case
\f(CW*lle_value_out\fP
will have the value
\f(CWDW_LLE_start_end\fP.
.P
\f(CWDW_LKIND_loclist\fP,
means the list is from DWARF2, DWARF3,
or DWARF4. The
\f(CW*lle_value_out\fP
value has been
synthesized as if it were a DWARF5
expression.
.P
\f(CWDW_LKIND_GNU_exp_list\fP,
means the list is from a DWARF4 .debug_loc.dwo
object section. It is an experimental
version from before DWARF5 was published.
The
\f(CW*lle_value_out\fP
is
\f(CWDW_LLEX_start_end_entry\fP
(or one of the other DW_LLEX values).
.P
\f(CWDW_LKIND_loclists\fP
means this is a DWARF5 loclist,
so
\f(CWDW_LLE_start_end\fP
is an example of one possible
\f(CW*lle_value_out\fP
values.
In addition, if
\f(CW*debug_addr_unavailable\fP
is set it means the
\f(CW*lopc_out\fP
and
\f(CW*hipc_out\fP
could not be correctly set
(so are meaningless) because
the .debug_addr section is missing.
Very likely the .debug_addr section
is in the executable and
that file needs to be opened
and attached to the current Dwarf_Debug with
\f(CWdwarf_set_tied_dbg()\fP.
.P
\f(CW*rawval1_out\fP
returns the value of the first operand
in the location list entry.
Uninterpreted. Useful for reporting
or for those wishing to do their own
calculation of
\f(CWlopc\fP.
.P
\f(CW*rawval2_out\fP
returns the value of the second operand
in the location list entry.
Uninterpreted. Useful for reporting
or for those wishing to do their own
calculation of
\f(CWhipc\fP.
The argument
\f(CWloc_expr_op_count_out\fP
returns the number of operators in the location expression
involved (which may be zero).
.P
The argument
\f(CWlocentry_out\fP
returns an identifier used in calls to
\f(CWdwarf_get_location_op_value_d()\fP.
.P
The argument
\f(CWexpression_offset_out\fP
returns the offset (in the .debug_loc(.dso) or .debug_info(.dwo)
of the location expression itself
(possibly useful for debugging).
.P
The argument
\f(CWlocdesc_offset_out\fP
returns the offset (in the
section involved (see
\f(CWloclist_kind\fP)
of the location list entry itself
(possibly useful for debugging).
.P
In case of error
\f(CWDW_DLV_ERROR\fP
is returned and
\f(CW*error\fP
is set to an error designation.
.P
A return of
\f(CWDW_DLV_NO_ENTRY\fP
may be possible but is a bit odd.
\f(CW
\fP
.H 3 "dwarf_get_locdesc_entry_c()"
This is the same as
\f(CWdwarf_get_locdesc_entry_d()\fP
except that the
\f(CWdebug_addr_unavailable\fP
field
is missing.
Earlier versions (starting with
\f(CWdwarf_get_locdesc_entry()\fP
exist and work as well
as they ever did, but we suggest
you stop using those earlier
versions.
We suggest you switch to using
\f(CWdwarf_get_locdesc_entry_d()\fP
.DS
\f(CW
int dwarf_get_locdesc_entry_c(Dwarf_Loc_Head_c /*loclist_head*/,
Dwarf_Unsigned index,
Dwarf_Small *lle_value_out,
Dwarf_Addr *rawval1_out,
Dwarf_Addr *rawval2_out,
Dwarf_Addr *lopc_out,
Dwarf_Addr *hipc_out,
Dwarf_Unsigned *loc_expr_op_count_out,
Dwarf_Locdesc_c *locentry_out,
Dwarf_Small *loclist_kind,
Dwarf_Unsigned *expression_offset_out,
Dwarf_Unsigned *locdesc_offset_out,
Dwarf_Error *error);
\fP
.DE
.H 3 "dwarf_get_loclist_head_kind()"
.DS
\f(CW
int dwarf_get_loclist_head_kind(
Dwarf_Loclists_Head head,
unsigned int * kind,
Dwarf_Error *error)
\fP
.DE
Though one should test the return code,
at present this always returns
\f(CWDW_DLV_OK\fP,
and sets
\f(CW*kind\fP
to the
\f(CWDW_LKIND*\fP
value for this
\f(CWhead\fP.
.P
At the present time
neither
\f(CWDW_DLV_ERROR\fP
nor
\f(CWDW_DLV_NO_ENTRY\fP
is returned.
.H 3 "dwarf_get_location_op_value_d()"
.DS
\f(CW
int dwarf_get_location_op_value_d(Dwarf_Locdesc_c locdesc,
Dwarf_Unsigned index,
Dwarf_Small * atom_out,
Dwarf_Unsigned * operand1,
Dwarf_Unsigned * operand2,
Dwarf_Unsigned * operand3,
Dwarf_Unsigned * rawop1,
Dwarf_Unsigned * rawop2,
Dwarf_Unsigned * rawop3,
Dwarf_Unsigned * offset_for_branch,
Dwarf_Error* error);
\fP
.DE
On success
The function
\f(CWdwarf_get_location_op_value_d()\fP
returns
the information for the single operator
number
\f(CWindex\fP
from the location expression
\f(CWlocdesc\fP.
It sets the following values.
.P
\f(CWatom_out\fP
is set to the applicable operator code, for example
\f(CWDW_OP_reg5\fP.
.P
\f(CWoperand1\fP,
\f(CWoperand2\fP, and
\f(CWoperand3\fP are set to the
operator operands as applicable (see
DWARF documents on the operands
for each operator).
All additions of base fields, if any,
have been done already.
\f(CWoperand3\fP is new as of DWARF5.
.P
In some cases
\f(CWoperand3\fP
is actually a pointer into section data in memory
and operand2 has the length of the data at
operand3. Callers must extract the bytes and
deal with endianness issues of the extracted value.
.P
\f(CWrawop1\fP,
\f(CWrawop2\fP, and
\f(CWrawop3\fP are set to the
operator operands as applicable (see
DWARF documents on the operands
for each operator) before any
base values were added in..
As for the previous, sometimes dealing
with
\f(CWrawop3\fP means interpreting it as a pointer
and doing a dereference.
.P
More on the pointer values in Dwarf_Unsigned:
When a DWARF operand is not of a size
fixed by dwarf or whose type
is unknown, or is possibly too large for
a dwarf stack entry, libdwarf will
insert a pointer (to memory
in the dwarf data somewhere) as the operand value.
\f(CWDW_OP_implicit_value operand 2\fP,
\f(CWDW_OP_[GNU_]entry_value operand 2\fP,
and
\f(CWDW_OP_[GNU_]const_type operand 3\fP
are instances of this.
The problem with the values is that libdwarf
is unclear what the type of the value is
so we pass the problem to you, the callers!
.P
\f(CWoffset_for_branch\fP is set to the
offset (in bytes) in this expression of this
operator.
The value makes it possible for callers
to implement the operator branch
operators.
.P
In case of an error, the
function returns
\f(CWDW_DLV_ERROR\fP
and sets
\f(CW*error\fP to an error
value.
.P
\f(CWDW_DLV_NO_ENTRY\fP
is probably not a possible return value, but
please test for it anyway.
.H 3 "dwarf_loclist_from_expr_c()"
This is now obsolete, though it works as
well as ever, so if it works for your object
codes you may continue to use it.
.DS
\f(CW
int dwarf_loclist_from_expr_c(Dwarf_Debug dbg,
Dwarf_Ptr expression_in,
Dwarf_Unsigned expression_length,
Dwarf_Half address_size,
Dwarf_Half offset_size,
Dwarf_Small dwarf_version,
Dwarf_Loc_Head_c* loc_head,
Dwarf_Unsigned * listlen,
Dwarf_Error * error);
\fP
.DE
This interface is not sufficient
to work properly as it fails to pass in
data from the Compilation Unit.
The earlier versions
\f(CWdwarf_loclist_from_expr()\fP,
\f(CWdwarf_loclist_from_expr_a()\fP,
and
\f(CWdwarf_loclist_from_expr_b\fP
are all similarly deficient.
These suffice for early DWARF locations
but cannot work for every kind of
DWARF5 location list or location.
.P
Frame operators such as
DW_CFA_def_cfa_expression have a location expression
and the location_expression is accessed with
this function.
.P
On success it returns
\f(CWDW_DLV_OK\fP and sets the two return arguments
(explained a few lines later here).
.P
The
\f(CWexpression_in\fP
argument must contain a valid pointer
to location expression bytes.
The
\f(CWexpression_length\fP
argument must contain the length of
that location expression in bytes.
.P
The
\f(CWaddress_size\fP
argument must contain the size of an address
on the target machine for this expression
(normally 4 or 8).
The
\f(CWoffset_size\fP
argument must contain the size of an offset
in the expression
(normally 4, sometimes 8).
The
\f(CWversion\fP
argument must contain the dwarf_version
of the expression
(2,3,4, or 5).
.P
The returned value
\f(CW*loc_head\fP
is used to actually access the location expression
details (see the example following).
.P
The returned value
\f(CW*listlen\fP
is the number of location expressions
(ie 1) in the location list
(for uniformity of access we make it look like
a single-entry location list).
.P
On error the function returns
\f(CWDW_DLV_ERROR\fP
and sets
\f(CW*error\fP to reflect
the error.
.P
A return of
\f(CWDW_DLV_NO_ENTRY\fP
is probably impossible, but
callers should assume it is possible.
No return arguments are set in this case.
.DS
void
example_locexprc(Dwarf_Debug dbg,Dwarf_Ptr expr_bytes,
Dwarf_Unsigned expr_len,
Dwarf_Half addr_size,
Dwarf_Half offset_size,
Dwarf_Half version)
{
Dwarf_Loc_Head_c head = 0;
Dwarf_Locdesc_c locentry = 0;
int res2 = 0;
Dwarf_Unsigned lopc = 0;
Dwarf_Unsigned hipc = 0;
Dwarf_Unsigned ulistlen = 0;
Dwarf_Unsigned ulocentry_count = 0;
Dwarf_Unsigned section_offset = 0;
Dwarf_Unsigned locdesc_offset = 0;
Dwarf_Small lle_value = 0;
Dwarf_Small loclist_source = 0;
Dwarf_Unsigned i = 0;
Dwarf_Error error = 0;
res2 = dwarf_loclist_from_expr_c(dbg,
expr_bytes,expr_len,
addr_size,
offset_size,
version,
&head,
&ulistlen,
&error);
if(res2 == DW_DLV_NO_ENTRY) {
return;
}
if(res2 == DW_DLV_ERROR) {
return;
}
/* These are a location expression, not loclist.
So we just need the 0th entry. */
res2 = dwarf_get_locdesc_entry_c(head,
0, /* Data from 0th LocDesc */
&lle_value,
&lopc, &hipc,
&ulocentry_count,
&locentry,
&loclist_source,
§ion_offset,
&locdesc_offset,
&error);
if (res2 == DW_DLV_ERROR) {
dwarf_loc_head_c_dealloc(head);
return;
} else if (res2 == DW_DLV_NO_ENTRY) {
dwarf_loc_head_c_dealloc(head);
return;
}
/* ASSERT: ulistlen == 1 */
for (i = 0; i < ulocentry_count;++i) {
Dwarf_Small op = 0;
Dwarf_Unsigned opd1 = 0;
Dwarf_Unsigned opd2 = 0;
Dwarf_Unsigned opd3 = 0;
Dwarf_Unsigned offsetforbranch = 0;
res2 = dwarf_get_location_op_value_c(locentry,
i, &op,&opd1,&opd2,&opd3,&offsetforbranch,
&error);
/* Do something with the expression operator and operands */
if (res2 != DW_DLV_OK) {
dwarf_loc_head_c_dealloc(head);
return;
}
}
dwarf_loc_head_c_dealloc(head);
}
.DE
.H 3 "dwarf_loc_head_c_dealloc()"
.DS
void dwarf_loc_head_c_dealloc(Dwarf_Loc_Head_c loclist_head);
.DE
This function takes care of all the details so
one does not have to _dwarf_dealloc() the pieces
individually, though code that continues to do
the pieces individually still works.
.P
This function frees all the memory associated with
the
\f(CWloclist_head\fP.
There is no return value.
It's good practice to set
\f(CWloclist_head\fP.
to
zero immediately after the call, as the pointer
is stale at that point.
.H 3 "dwarf_loclist_n()"
.DS
\f(CWint dwarf_loclist_n(
Dwarf_Attribute attr,
Dwarf_Locdesc ***llbuf,
Dwarf_Signed *listlen,
Dwarf_Error *error)\fP
.DE
This interface cannot handle DWARF5 or Split Dwarf.
Use \f(CWdwarf_get_loclist_c()\fP and related functions
instead (as of November 2015).
The function \f(CWdwarf_loclist_n()\fP sets \f(CW*llbuf\fP to point to
an array of \f(CWDwarf_Locdesc\fP pointers corresponding to each of
the location expressions in a location list, and sets
\f(CW*listlen\fP to the number
of elements in the array and
returns \f(CWDW_DLV_OK\fP if the attribute is
appropriate.
.P
This is the preferred function for Dwarf_Locdesc as
it is the interface allowing access to an entire
loclist. (use of \f(CWdwarf_loclist_n()\fP is
suggested as the better interface, though
\f(CWdwarf_loclist()\fP is still
supported.)
.P
If the attribute is a reference to a location list
(DW_FORM_data4 or DW_FORM_data8)
the location list entries are used to fill
in all the fields of the \f(CWDwarf_Locdesc\fP(s) returned.
.P
If the attribute is a location description
(DW_FORM_block2 or DW_FORM_block4)
then some of the \f(CWDwarf_Locdesc\fP values of the single
\f(CWDwarf_Locdesc\fP record are set to 'sensible'
but arbitrary values. Specifically, ld_lopc is set to 0 and
ld_hipc is set to all-bits-on. And \f(CW*listlen\fP is set to 1.
.P
If the attribute is a reference to a location expression
(DW_FORM_locexper)
then some of the \f(CWDwarf_Locdesc\fP values of the single
\f(CWDwarf_Locdesc\fP record are set to 'sensible'
but arbitrary values. Specifically, ld_lopc is set to 0 and
ld_hipc is set to all-bits-on. And \f(CW*listlen\fP is set to 1.
.P
It returns \f(CWDW_DLV_ERROR\fP on error.
.P
\f(CWdwarf_loclist_n()\fP works on \f(CWDW_AT_location\fP,
\f(CWDW_AT_data_member_location\fP, \f(CWDW_AT_vtable_elem_location\fP,
\f(CWDW_AT_string_length\fP, \f(CWDW_AT_use_location\fP, and
\f(CWDW_AT_return_addr\fP attributes.
.P
If the attribute is \f(CWDW_AT_data_member_location\fP the value
may be of class CONSTANT. \f(CWdwarf_loclist_n()\fP is unable
to read class CONSTANT, so you need to first determine the
class using \f(CWdwarf_get_form_class()\fP and if it is
class CONSTANT call
\f(CWdwarf_formsdata()\fP or \f(CWdwarf_formudata()\fP
to get the constant value (you may need to call both as
DWARF4 does not define the signedness of the constant value).
.P
Storage allocated by a successful call of \f(CWdwarf_loclist_n()\fP should
be deallocated when no longer of interest (see \f(CWdwarf_dealloc()\fP).
The block of \f(CWDwarf_Loc\fP structs pointed to by the \f(CWld_s\fP
field of each \f(CWDwarf_Locdesc\fP structure
should be deallocated with the allocation type
\f(CWDW_DLA_LOC_BLOCK\fP.
and the \f(CWllbuf[]\fP space pointed to should be deallocated with
allocation type \f(CWDW_DLA_LOCDESC\fP.
This should be followed by deallocation of the \f(CWllbuf\fP
using the allocation type \f(CWDW_DLA_LIST\fP.
.in +2
.DS
\f(CW
void example9(Dwarf_Debug dbg,Dwarf_Attribute someattr)
{
Dwarf_Signed lcount = 0;
Dwarf_Locdesc **llbuf = 0;
Dwarf_Error error = 0;
int lres = 0;
lres = dwarf_loclist_n(someattr, &llbuf,&lcount,&error);
if (lres == DW_DLV_OK) {
Dwarf_Signed i = 0;
for (i = 0; i < lcount; ++i) {
/* Use llbuf[i]. Both Dwarf_Locdesc and the
array of Dwarf_Loc it points to are
defined in libdwarf.h: they are
not opaque structs. */
dwarf_dealloc(dbg, llbuf[i]->ld_s, DW_DLA_LOC_BLOCK);
dwarf_dealloc(dbg,llbuf[i], DW_DLA_LOCDESC);
}
dwarf_dealloc(dbg, llbuf, DW_DLA_LIST);
}
}
\fP
.DE
.in -2
.P
.H 3 "dwarf_loclist()"
.DS
\f(CWint dwarf_loclist(
Dwarf_Attribute attr,
Dwarf_Locdesc **llbuf,
Dwarf_Signed *listlen,
Dwarf_Error *error)\fP
.DE
Use \f(CWdwarf_get_loclist_c()\fP and related functions
instead (as of November 2015).
The function \f(CWdwarf_loclist()\fP sets \f(CW*llbuf\fP to point to
a \f(CWDwarf_Locdesc\fP pointer for the single location expression
it can return.
It sets
\f(CW*listlen\fP to 1.
and returns \f(CWDW_DLV_OK\fP
if the attribute is
appropriate.
.P
It is less flexible than \f(CWdwarf_loclist_n()\fP in that
\f(CWdwarf_loclist()\fP can handle a maximum of one
location expression, not a full location list.
If a location-list is present it returns only
the first location-list entry location description.
Use \f(CWdwarf_loclist_n()\fP instead.
.P
It returns \f(CWDW_DLV_ERROR\fP on error.
\f(CWdwarf_loclist()\fP works on \f(CWDW_AT_location\fP,
\f(CWDW_AT_data_member_location\fP, \f(CWDW_AT_vtable_elem_location\fP,
\f(CWDW_AT_string_length\fP, \f(CWDW_AT_use_location\fP, and
\f(CWDW_AT_return_addr\fP attributes.
.P
Storage allocated by a successful call of \f(CWdwarf_loclist()\fP should
be deallocated when no longer of interest (see \f(CWdwarf_dealloc()\fP).
The block of \f(CWDwarf_Loc\fP structs pointed to by the \f(CWld_s\fP
field of each \f(CWDwarf_Locdesc\fP structure
should be deallocated with the allocation type \f(CWDW_DLA_LOC_BLOCK\fP.
This should be followed by deallocation of the \f(CWllbuf\fP
using the allocation type \f(CWDW_DLA_LOCDESC\fP.
.in +2
.FG "Examplea dwarf_loclist()"
.DS
\f(CW
void examplea(Dwarf_Debug dbg,Dwarf_Attribute someattr)
{
Dwarf_Signed lcount = 0;
Dwarf_Locdesc *llbuf = 0;
Dwarf_Error error = 0;
int lres = 0;
lres = dwarf_loclist(someattr, &llbuf,&lcount,&error);
if (lres == DW_DLV_OK) {
/* lcount is always 1, (and has always been 1) */
/* Use llbuf here. */
dwarf_dealloc(dbg, llbuf->ld_s, DW_DLA_LOC_BLOCK);
dwarf_dealloc(dbg, llbuf, DW_DLA_LOCDESC);
}
}
\fP
.DE
.in -2
.P
.H 3 "dwarf_loclist_from_expr()"
.DS
\f(CWint dwarf_loclist_from_expr(
Dwarf_Debug dbg,
Dwarf_Ptr bytes_in,
Dwarf_Unsigned bytes_len,
Dwarf_Locdesc **llbuf,
Dwarf_Signed *listlen,
Dwarf_Error *error)\fP
.DE
Use \f(CWdwarf_loclist_from_expr_b()\fP instead.
This function is obsolete.
.P
The function \f(CWdwarf_loclist_from_expr()\fP
sets \f(CW*llbuf\fP to point to
a \f(CWDwarf_Locdesc\fP pointer for the single location expression
which is pointed to by \f(CW*bytes_in\fP (whose length is
\f(CW*bytes_len\fP).
It sets
\f(CW*listlen\fP to 1.
and returns \f(CWDW_DLV_OK\fP
if decoding is successful.
Some sources of bytes of expressions are dwarf expressions
in frame operations like \f(CWDW_CFA_def_cfa_expression\fP,
\f(CWDW_CFA_expression\fP, and \f(CWDW_CFA_val_expression\fP.
.P
Any address_size data in the location expression is assumed
to be the same size as the default address_size for the object
being read (normally 4 or 8).
.P
It returns \f(CWDW_DLV_ERROR\fP on error.
.P
Storage allocated by a successful call
of \f(CWdwarf_loclist_from_expr()\fP should
be deallocated when no longer of interest (see \f(CWdwarf_dealloc()\fP).
The block of \f(CWDwarf_Loc\fP structs pointed to by the \f(CWld_s\fP
field of each \f(CWDwarf_Locdesc\fP structure
should be deallocated with the allocation type \f(CWDW_DLA_LOC_BLOCK\fP.
This should be followed by deallocation of the \f(CWllbuf\fP
using the allocation type \f(CWDW_DLA_LOCDESC\fP.
.in +2
.FG "Exampleb dwarf_loclist_from_expr()"
.DS
\f(CW
void exampleb(Dwarf_Debug dbg,Dwarf_Ptr data, Dwarf_Unsigned len)
{
Dwarf_Signed lcount = 0;
Dwarf_Locdesc *llbuf = 0;
Dwarf_Error error = 0;
int lres = 0;
lres = dwarf_loclist_from_expr(dbg,data,len, &llbuf,&lcount,
&error);
if (lres == DW_DLV_OK) {
/* lcount is always 1 */
/* Use llbuf here.*/
dwarf_dealloc(dbg, llbuf->ld_s, DW_DLA_LOC_BLOCK);
dwarf_dealloc(dbg, llbuf, DW_DLA_LOCDESC);
}
}
\fP
.DE
.in -2
.P
.H 3 "dwarf_loclist_from_expr_b()"
.DS
\f(CWint dwarf_loclist_from_expr_a(
Dwarf_Ptr bytes_in,
Dwarf_Unsigned bytes_len,
Dwarf_Half addr_size,
Dwarf_Half offset_size,
Dwarf_Half version_stamp,
Dwarf_Locdesc **llbuf,
Dwarf_Signed *listlen,
Dwarf_Error *error)\fP
.DE
This function is obsolete.
The function \f(CWdwarf_loclist_from_expr_b()\fP
is identical to \f(CWdwarf_loclist_from_expr_a()\fP
in every way except that the caller passes an additional argument
\f(CWversion_stamp\fP containing the
version stamp (2 for DWARF2, etc) of the CU using
this location expression and an additional argument
of the offset size of the CU using this location expression.
The DW_OP_GNU_implicit_pointer operation requires this version
and offset information to be correctly processed.
.P
The \f(CWaddr_size\fP argument (from 27April2009) is needed
to correctly interpret frame information as different compilation
units can have different address sizes.
DWARF4 adds address_size to the CIE header.
.P
.H 3 "dwarf_loclist_from_expr_a()"
.DS
\f(CWint dwarf_loclist_from_expr_a(
Dwarf_Ptr bytes_in,
Dwarf_Unsigned bytes_len,
Dwarf_Half addr_size,
Dwarf_Locdesc **llbuf,
Dwarf_Signed *listlen,
Dwarf_Error *error)\fP
.DE
This function is obsolete.
Use \f(CWdwarf_loclist_from_expr_b()\fP instead.
This function is obsolete.
.P
The function \f(CWdwarf_loclist_from_expr_a()\fP
is identical to \f(CWdwarf_loclist_from_expr()\fP
in every way except that the caller passes the additional argument
\f(CWaddr_size\fP containing the address size (normally 4 or 8)
applying this location expression.
.P
The \f(CWaddr_size\fP argument (added 27April2009) is needed
to correctly interpret frame information as different compilation
units can have different address sizes.
DWARF4 adds address_size to the CIE header.
.P
.H 2 "Line Number Operations"
These functions are concerned with accessing line number entries,
mapping debugging information entry objects to their corresponding
source lines, and providing a mechanism for obtaining information
about line number entries. Although, the interface talks of "lines"
what is really meant is "statements". In case there is more than
one statement on the same line, there will be at least one descriptor
per statement, all with the same line number. If column number is
also being represented they will have the column numbers of the start
of the statements also represented.
.P
There can also be more than one Dwarf_Line per statement.
For example, if a file is preprocessed by a language translator,
this could result in translator output showing 2 or more sets of line
numbers per translated line of output.
.P
\f(CW
\fP
As of October 2015 there are two sets of overall access
and release functions.
The older set of functions is
\f(CWdwarf_srclines()\fP
with
\f(CWdwarf_srclines_dealloc()\fP.
This set does not handle line table
headers with no lines.
.P
A newer set is
\f(CWdwarf_srclines_b()\fP
with
\f(CWdwarf_srclines_from_linecontext()\fP
and
\f(CWdwarf_srclines_dealloc_b()\fP.
These functions provide for handling
both DWARF2 through DWARF5 details
and give access to line header
information even if there are no lines
in a particular compilation unit's line
table.
.P
.H 3 "Get A Set of Lines (including skeleton line tables)"
This set of functions works on any DWARF version.
DWARF2,3,4,5 and the DWARF4 based experimental
two-level line tables are all supported.
What was once done by dwarf_srclines() alone
is now done with two calls as described here.
.P
The interfaces support reading GNU two-level line tables.
The format of such tables is a topic beyond
the scope of this document.
.P
.H 3 "dwarf_srclines_b()"
This is the
.DS
\f(CWint dwarf_srclines_b(
Dwarf_Die die,
Dwarf_Unsigned *version_out,
Dwarf_Bool *is_single_table,
Dwarf_Line_Context *context_out,
Dwarf_Error *error)\fP
.DE
\f(CWdwarf_srclines_b()\fP
takes a single argument as input,
a pointer to a compilation-unit (CU) DIE.
The other arguments are used to return values
to the caller.
On success
\f(CWDW_DLV_OK\fP
is returned and values
are returned through the pointers.
If there is no line table
\f(CWDW_DLV_NO_ENTRY\fP
is returned
and no values are returned though the pointers.
If
\f(CWDW_DLV_ERROR\fP
is returned the
involved is returned through the
\f(CWerror\fP
pointer.
.P
The values returned on success are:
.P
\f(CW*version_out()\fP
is set to the version number from
the line table header for this CU.
The experimental two-level line table
value is 0xf006. Standard numbers
are 2,3,4 and 5.
.P
\f(CW*is_single_table()\fP
is set to non-zero if the line table
is an ordinary single line table.
If the line table is anything else
(either a line table header with no lines
or an experimental two-level line table)
it is set to zero.
.P
\f(CW*context_out()\fP
is set to an opaque pointer to a
\f(CWDwarf_Line_Context\fP
record
which in turn is used to get
other data from this line table.
See below.
.P
See
\f(CW*dwarf_srclines_dealloc_b()\fP
for examples showing correct use.
.H 3 "dwarf_get_line_section_name_from_die()"
.DS
\f(CWint dwarf_get_line_section_name_from_die(
Dwarf_Die die,
const char ** sec_name,
Dwarf_Error *error)\fP
.DE
\f(CW*dwarf_get_line_section_name_from_die()\fP
retrieves the object file section name of
the applicable line section.
This is useful for applications wanting to print
the name, but of course the object section name is not
really a part of the DWARF information.
Most applications will
probably not call this function.
It can be called at any time
after the Dwarf_Debug initialization is done.
.P
If the function succeeds, \f(CW*sec_name\fP is set to
a pointer to a string with the object section name and
the function returns \f(CWDW_DLV_OK\fP.
Do not free the string whose pointer is returned.
For non-Elf objects it is possible the string pointer
returned will be NULL or will point to an empty string.
It is up to the calling application to recognize this
possibility and deal with it appropriately.
.P
If the section does not exist the function returns
DW_DLV_NO_ENTRY.
.P
If there is an internal error detected the
function returns \f(CWDW_DLV_ERROR\fP and sets the
\f(CW*error\fP pointer.
.H 3 "dwarf_srclines_from_linecontext()"
.DS
\f(CWint dwarf_srclines_from_linecontext(
Dwarf_Line_Context line_context,
Dwarf_Line ** linebuf,
Dwarf_Signed *linecount,
Dwarf_Error *error)\fP
.DE
\f(CW*dwarf_srclines_from_linecontext()\fP
gives access to the line tables.
On success it returns
\f(CWDW_DLV_OK\fP
and passes back line tables
through the pointers.
.P
Though
\f(CWDW_DLV_OK\fP
will not be returned callers should
assume it is possible.
.P
On error
\f(CWDW_DLV_ERROR\fP
is returned and the error code set through
the
\f(CWerror\fP
pointer.
.P
On success:
.P
\f(CW*linebuf\fP
is set to an array of Dwarf_Line pointers.
.P
\f(CW*linecount\fP is set
to the number of pointers in the array.
.P
.H 3 "dwarf_srclines_two_levelfrom_linecontext()"
.DS
\f(CWint dwarf_srclines_from_linecontext(
Dwarf_Line_Context line_context,
Dwarf_Line ** linebuf,
Dwarf_Signed *linecount,
Dwarf_Line ** linebuf_actuals,
Dwarf_Signed *linecount_actuals,
Dwarf_Error *error)\fP
.DE
\f(CW*dwarf_srclines_two_levelfrom_linecontext()\fP
gives access to the line tables.
On success it returns
\f(CWDW_DLV_OK\fP
and passes back line tables
through the pointers.
.P
Though
\f(CWDW_DLV_OK\fP
will not be returned callers should
assume it is possible.
.P
On error
\f(CWDW_DLV_ERROR\fP
is returned and the error code set through
the
\f(CWerror\fP
pointer.
.P
On success:
.P
\f(CW*linebuf\fP
is set to an array of Dwarf_Line pointers.
.P
\f(CW*linecount\fP is set
to the number of pointers in the array.
.P
If one is not intending that the experimental two-level
line tables are of interest then pass NULL
for
\f(CW*linebuf_actuals\fP
and
\f(CW*linecount_actuals\fP.
The NULL pointers notify the library
that the second table is not to be passed back.
.P
If a line table is actually a two-level tables
\f(CW*linebuf\fP is set to point to an array of
Logicals lines.
\f(CW*linecount\fP is set to the number of Logicals.
\f(CW*linebuf_actuals\fP is set to point to an array of
Actuals lines.
\f(CW*linecount_actuals\fP is set to the number of Actuals.
.H 3 "dwarf_srclines_dealloc_b()"
.DS
\f(CWvoid dwarf_srclines_dealloc_b(
Dwarf_Line_Context line_context,
Dwarf_Error *error)\fP
.DE
This does a complete deallocation of
the memory of the
\f(CWDwarf_Line_Context\fP
and the
\f(CWDwarf_Line\fP array (or arrays)
that came from the
\f(CWDwarf_Line_Context\fP.
On return you should set any local pointers
to these buffers to NULL as a reminder
that any use of the local pointers would
be to stale memory.
.in +2
.FG "Examplec dwarf_srclines_b()"
.DS
\f(CW
void examplec(Dwarf_Die cu_die)
{
/* EXAMPLE: DWARF5 style access. */
Dwarf_Line *linebuf = 0;
Dwarf_Signed linecount = 0;
Dwarf_Line *linebuf_actuals = 0;
Dwarf_Signed linecount_actuals = 0;
Dwarf_Line_Context line_context = 0;
Dwarf_Signed linecount_total = 0;
Dwarf_Small table_count = 0;
Dwarf_Unsigned lineversion = 0;
Dwarf_Error err = 0;
int sres = 0;
/* ... */
/* we use 'return' here to signify we can do nothing more
at this point in the code. */
sres = dwarf_srclines_b(cu_die,&lineversion,
&table_count,&line_context,&err);
if (sres != DW_DLV_OK) {
/* Handle the DW_DLV_NO_ENTRY or DW_DLV_ERROR
No memory was allocated so there nothing
to dealloc. */
return;
}
if (table_count == 0) {
/* A line table with no actual lines.
This occurs in a DWARF5 or DWARF5
DW_TAG_type_unit
as such has no lines of code
but needs data for
DW_AT_decl_file attributes. */
/*...do something, see dwarf_srclines_files_count()
etc below. */
dwarf_srclines_dealloc_b(line_context);
/* All the memory is released, the line_context
and linebuf zeroed now
as a reminder they are stale. */
linebuf = 0;
line_context = 0;
} else if (table_count == 1) {
Dwarf_Signed i = 0;
Dwarf_Signed baseindex = 0;
Dwarf_Signed file_count = 0;
Dwarf_Signed endindex = 0;
/* Standard dwarf 2,3,4, or 5 line table */
/* Do something. */
/* First let us index through all the files listed
in the line table header. */
sres = dwarf_srclines_files_indexes(line_context,
&baseindex,&file_count,&endindex,&err);
if (sres != DW_DLV_OK) {
/* Something badly wrong! */
return;
}
/* Works for DWARF2,3,4 (one-based index)
and DWARF5 (zero-based index) */
for (i = baseindex; i < endindex; i++) {
Dwarf_Unsigned dirindex = 0;
Dwarf_Unsigned modtime = 0;
Dwarf_Unsigned flength = 0;
Dwarf_Form_Data16 *md5data = 0;
int vres = 0;
const char *name = 0;
vres = dwarf_srclines_files_data_b(line_context,i,
&name,&dirindex, &modtime,&flength,
&md5data,&err);
if (vres != DW_DLV_OK) {
/* something very wrong. */
return;
}
/* Do something. */
}
/* For this case where we have a line table we will likely
wish to get the line details: */
sres = dwarf_srclines_from_linecontext(line_context,
&linebuf,&linecount,
&err);
if (sres != DW_DLV_OK) {
/* Error. Clean up the context information. */
dwarf_srclines_dealloc_b(line_context);
return;
}
/* The lines are normal line table lines. */
for (i = 0; i < linecount; ++i) {
/* use linebuf[i] */
}
dwarf_srclines_dealloc_b(line_context);
/* All the memory is released, the line_context
and linebuf zeroed now as a reminder they are stale */
linebuf = 0;
line_context = 0;
linecount = 0;
} else {
Dwarf_Signed i = 0;
/* ASSERT: table_count == 2,
Experimental two-level line table. Version 0xf006
We do not define the meaning of this non-standard
set of tables here. */
/* For 'something C' (two-level line tables)
one codes something like this
Note that we do not define the meaning or use of two-level line
tables as these are experimental, not standard DWARF. */
sres = dwarf_srclines_two_level_from_linecontext(line_context,
&linebuf,&linecount,
&linebuf_actuals,&linecount_actuals,
&err);
if (sres == DW_DLV_OK) {
for (i = 0; i < linecount; ++i) {
/* use linebuf[i], these are the 'logicals' entries. */
}
for (i = 0; i < linecount_actuals; ++i) {
/* use linebuf_actuals[i], these are the actuals entries */
}
dwarf_srclines_dealloc_b(line_context);
line_context = 0;
linebuf = 0;
linecount = 0;
linebuf_actuals = 0;
linecount_actuals = 0;
} else if (sres == DW_DLV_NO_ENTRY) {
/* This should be impossible, but do something. */
/* Then Free the line_context */
dwarf_srclines_dealloc_b(line_context);
line_context = 0;
linebuf = 0;
linecount = 0;
linebuf_actuals = 0;
linecount_actuals = 0;
} else {
/* ERROR, show the error or something.
Free the line_context. */
dwarf_srclines_dealloc_b(line_context);
line_context = 0;
linebuf = 0;
linecount = 0;
linebuf_actuals = 0;
linecount_actuals = 0;
}
}
}
\fP
.DE
.in -2
.H 2 "Line Context Details (DWARF5 style)"
New in October 2015.
When a
\f(CW
Dwarf_Line_Context
\fP
has been returned by
\f(CWdwarf_srclines_b()\fP
that line context data's details can be retrieved
with the following set of calls.
.H 3 "dwarf_srclines_table_offset()"
.DS
\f(CW
int dwarf_srclines_table_offset(Dwarf_Line_Context line_context,
Dwarf_Unsigned * offset,
Dwarf_Error * error);
\fP
.DE
On success, this function returns the offset (in the object file
line section) of the actual line data (i.e. after the line
header for this compilation unit) through the
\f(CWoffset\fP
pointer.
The offset is probably only of interest when
printing detailed information about a line table header.
.P
In case of error,
\f(CWDW_DLV_ERROR\fP
is returned and the error is set through
the
\f(CWerror\fP
pointer.
\f(CWDW_DLV_NO_ENTRY\fP
will not be returned.
.H 3 "dwarf_srclines_version()"
.DS
\f(CW
int dwarf_srclines_version(Dwarf_Line_Context line_context,
Dwarf_Unsigned * version,
Dwarf_Error * error);
\fP
.DE
On success
\f(CWDW_DLV_OK\fP
is returned and the line table version number is returned
through the
\f(CWversion\fP pointer.
.P
In case of error,
\f(CWDW_DLV_ERROR\fP
is returned and the error is set through
the
\f(CWerror\fP
pointer.
\f(CWDW_DLV_NO_ENTRY\fP
will not be returned.
.H 3 "dwarf_srclines_comp_dir()"
.DS
\f(CW
int dwarf_srclines_comp_dir(Dwarf_Line_Context line_context,
const char ** compilation_directory,
Dwarf_Error * error);
\fP
.DE
On success this returns a pointer to
the compilation directory string for this
line table in
\f(CW*compilation_directory\fP.
That compilation string may be NULL or the empty
string.
The string pointer is valid until the
\f(CWline_context\fP has been deallocated.
.P
In case of error,
\f(CWDW_DLV_ERROR\fP
is returned and the error is set through
the
\f(CWerror\fP
pointer.
\f(CWDW_DLV_NO_ENTRY\fP
will not be returned.
.H 3 "dwarf_srclines_files_indexes()"
.DS
\f(CW
int dwarf_srclines_files_indexes(Dwarf_Line_Context line_context,
Dwarf_Signed * baseindex,
Dwarf_Signed * count,
Dwarf_Signed * endindex,
Dwarf_Error * error);
\fP
.DE
With DWARF5 the base file number index in the
line table changed from zero (DWARF2,3,4)
to one (DWARF5).
Which meant iterating through the valid source file
indexes became messy if one used the older
\f(CWdwarf_srclines_files_count()\fP
function (zero-based and one-based indexing
being incompatible).
See Figure "Examplec dwarf_srclines_b()"
above
for use of this function in accessing file names.
.P
The base index of files in the files list of
a line table header will be returned through
\f(CWbaseindex\fP.
.P
The number of files in the files list of
a line table header will be returned through
\f(CWcount\fP.
.P
The end index of files in the files list of
a line table header will be returned through
\f(CWendindex\fP.
.P
In case of error,
\f(CWDW_DLV_ERROR\fP
is returned and the error is set through
the
\f(CWerror\fP
pointer.
\f(CWDW_DLV_NO_ENTRY\fP
will not be returned.
.H 3 "dwarf_srclines_files_count()"
.DS
\f(CW
int dwarf_srclines_files_count(Dwarf_Line_Context line_context,
Dwarf_Signed * count,
Dwarf_Error * error);
\fP
.DE
On success, the number of files in the files list of
a line table header will be returned through
\f(CWcount\fP.
.P
In case of error,
\f(CWDW_DLV_ERROR\fP
is returned and the error is set through
the
\f(CWerror\fP
pointer.
\f(CWDW_DLV_NO_ENTRY\fP
will not be returned.
.H 3 "dwarf_srclines_files_data_b()"
This supplants
\f(CWdwarf_srclines_files_data()\fP
as of March 2018
to allow access to the md5 value in DWARF5.
The function
\f(CWdwarf_srclines_files_data()\fP
continues to be supported.
.DS
\f(CW
int dwarf_srclines_files_data_b(Dwarf_Line_Context line_context,
Dwarf_Signed index,
const char ** name,
Dwarf_Unsigned * directory_index,
Dwarf_Unsigned * last_mod_time,
Dwarf_Unsigned * file_length,
Dwarf_Form_Data16 ** md5_value,
Dwarf_Error * error);
\fP
.DE
On success, data about a single file in
the files list will be returned through the pointers.
See DWARF documentation for the meaning of these
fields.
\f(CWcount\fP.
Valid
\f(CWindex\fP.
values are 1 through
\f(CWcount\fP,
reflecting the way the table is defined by DWARF2,3,4.
For a dwarf5 line table index values 0...count-1 are legal.
This is certainly awkward.
.P
If
\f(CWmd5_value\fP
is non-null it is used to pass a back
a pointer to a
\f(CWDwarf_Form_Data16\fP md5 value if
the md5 value is present. Otherwise
a zero value is passed back to indicate there
was no such field.
The 16-byte value pointed to is inside
the line_context, so if you want to keep
the value you should probably copy it
to storage you control.
.P
This returns the raw files data from the
line table header.
.P
In case of error,
\f(CWDW_DLV_ERROR\fP
is returned and the error is set through
the
\f(CWerror\fP
pointer.
\f(CWDW_DLV_NO_ENTRY\fP
will not be returned.
.H 3 "dwarf_srclines_files_data()"
This interface was created in October 2015.
It cannot return the DWARF5 MD5 value.
See the newer dwarf_srclines_files_data_b().
.DS
\f(CW
int dwarf_srclines_files_data(Dwarf_Line_Context line_context,
Dwarf_Signed index,
const char ** name,
Dwarf_Unsigned * directory_index,
Dwarf_Unsigned * last_mod_time,
Dwarf_Unsigned * file_length,
Dwarf_Error * error);
\fP
.DE
On success, data about a single file in
the files list will be returned through the pointers.
See DWARF documentation for the meaning of these
fields.
\f(CWcount\fP.
Valid
\f(CWindex\fP.
values are 1 through
\f(CWcount\fP,
reflecting the way the table is defined by DWARF2,3,4.
For a dwarf5 line table index values 0...count-1 are legal.
This is certainly awkward.
.P
This returns the raw files data from the
line table header.
.P
In case of error,
\f(CWDW_DLV_ERROR\fP
is returned and the error is set through
the
\f(CWerror\fP
pointer.
\f(CWDW_DLV_NO_ENTRY\fP
will not be returned.
.H 3 "dwarf_srclines_include_dir_count()"
.DS
\f(CW
int dwarf_srclines_include_dir_count(Dwarf_Line_Context line_context,
Dwarf_Signed * count,
Dwarf_Error * error);
\fP
.DE
On success, the number of files in the includes list of
a line table header will be returned through
\f(CWcount\fP.
.P
Valid
\f(CWindex\fP.
values are 1 through
\f(CWcount\fP,
reflecting the way the table is defined by DWARF 2,3 and 4.
For a dwarf5 line table index values 0...count-1 are legal.
This is certainly awkward.
.P
In case of error,
\f(CWDW_DLV_ERROR\fP
is returned and the error is set through
the
\f(CWerror\fP
pointer.
\f(CWDW_DLV_NO_ENTRY\fP
will not be returned.
.H 3 "dwarf_srclines_include_dir_data()"
.DS
\f(CW
int dwarf_srclines_include_dir_data(Dwarf_Line_Context line_context,
Dwarf_Signed index,
const char ** name,
Dwarf_Error * error);
\fP
.DE
On success, data about a single file in
the include files list will be returned through the pointers.
See DWARF documentation for the meaning of these
fields.
.P
Valid
\f(CWindex\fP.
values are 1 through
\f(CWcount\fP,
reflecting the way the table is defined by DWARF.
.P
In case of error,
\f(CWDW_DLV_ERROR\fP
is returned and the error is set through
the
\f(CWerror\fP
pointer.
\f(CWDW_DLV_NO_ENTRY\fP
will not be returned.
.H 3 "dwarf_srclines_subprog_count()"
\f(CW
int dwarf_srclines_subprog_count(Dwarf_Line_Context line_context,
Dwarf_Signed * count,
Dwarf_Error * error);
\fP
This is only useful with experimental two-level line tables.
.H 3 "dwarf_srclines_subprog_data()"
\f(CW
int dwarf_srclines_subprog_data(Dwarf_Line_Context line_context,
Dwarf_Signed index,
const char ** name,
Dwarf_Unsigned * decl_file,
Dwarf_Unsigned * decl_line,
Dwarf_Error * error);
\fP
This is only useful with experimental two-level line tables.
.H 2 "Get A Set of Lines (DWARF2,3,4 style)"
The function returns information about every source line for a
particular compilation-unit.
The compilation-unit is specified
by the corresponding die.
It does not support line tables with no lines very well
nor does it support experimental two-level linetables.
.H 3 "dwarf_srclines()"
.DS
\f(CWint dwarf_srclines(
Dwarf_Die die,
Dwarf_Line **linebuf,
Dwarf_Signed *linecount,
Dwarf_Error *error)\fP
.DE
This function is not useful for DWARF5 skeleton line tables nor
for two-level line tables.
It works for DWARF2,3,4,5 ordinary single line tables.
The function \f(CWdwarf_srclines()\fP places all line number descriptors
for a single compilation unit into a single block, sets \f(CW*linebuf\fP
to point to that block,
sets \f(CW*linecount\fP to the number of descriptors in this block
and returns \f(CWDW_DLV_OK\fP.
.in +2
.P
To get a more detailed view of the contents of a dwarf line
table header see \f(CWdwarf_srclines_b()\fP and
the routines that use the Dwarf_Line_Context
information, such as \f(CWdwarf_srcfiles_comp_dir()\fP,
\f(CWdwarf_srclines_files_count()\fP,
\f(CWdwarf_srclines_include_dir_count()\fP
and similar functions.
.in -2
.P
The compilation-unit is indicated by the given \f(CWdie\fP which must be
a compilation-unit die.
It returns \f(CWDW_DLV_ERROR\fP on error.
On
successful return, line number information
should be freed using \f(CWdwarf_srclines_dealloc()\fP
when no longer of interest.
.P
.in +2
.FG "Exampled dwarf_srclines()"
.DS
\f(CW
void exampled(Dwarf_Debug dbg,Dwarf_Die somedie)
{
Dwarf_Signed count = 0;
Dwarf_Line *linebuf = 0;
Dwarf_Signed i = 0;
Dwarf_Error error = 0;
int sres = 0;
sres = dwarf_srclines(somedie, &linebuf,&count, &error);
if (sres == DW_DLV_OK) {
for (i = 0; i < count; ++i) {
/* use linebuf[i] */
}
dwarf_srclines_dealloc(dbg, linebuf, count);
}
}
\fP
.DE
.in -2
.P
An alternative using \f(CWdwarf_dealloc()\fP directly
is no longer (as of 2015) described here. It works as well
as ever, but it has been obsolete since 2005.
still works, but does not completely free all data allocated.
The \f(CWdwarf_srclines_dealloc()\fP routine was created
to fix the problem of incomplete deallocation.
.H 2 "Get the set of Source File Names"
The function returns the names of the source files that have contributed
to the compilation-unit represented by the given DIE. Only the source
files named in the statement program prologue (which
in current DWARF standards is referred to as the Line
Table Header) are returned.
.H 3 dwarf_srcfiles()
This works for for all line tables.
However indexing is different
in DWARF5 than in other versions of dwarf.
To understand the DWARF5 version
look at the following
which explains a contradiction in the DWARF5
document and how libdwarf (and at least some
compilers) resolve it.
Join the next two strings together with no spaces
to recreate the web reference.
.P
If the applicable file name in the line
table Statement Program Prolog
does not start with a '/' character
the string in \f(CWDW_AT_comp_dir\fP
(if applicable and present)
and the applicable
directory name from the line Statement Program Prolog
is prepended to the
file name in the line table Statement Program Prolog
to make a full path.
.P
For all versions of dwarf this function
and dwarf_linesrc() prepend the value
of DW_AT_co prepend the value
of DW_AT_comp_dir to the name created
from the line table header file names and directory
names if the line table header name(s) are not
full paths.mp_dir to the name created
from the line table header file names and directory
names if the line table header name(s) are not
full paths.
.P
http://wiki.dwarfstd.org/index.php?title
=DWARF5_Line_Table_File_Numbers
.P
It may help understand the file tables
and dwarf_srcfiles() to
use \f(CWdwarfdump\fP.
The
\f(CWdwarfdump\fP
utility program now
will print the dwarf_srcfiles() values
in addition to the compilation unit
DIE and the line table header details
(and much more)
if one does "dwarfdump -vvv -i -l <objfilename>"
or "dwarfdump -vvv -a <objfilename>"
for example.
Since the output can be large, with your editor
focus on lines beginning with "COMPILE_UNIT"
(do not type the quotes) to quickly get to the
CU die and the line table for that CU as those
tend to be far apart in the output.
.P
DWARF5:
\f(CWDW_MACRO_start_file\fP,
\f(CWDW_LNS_set_file\fP,
\f(CWDW_AT_decl_file\fP,
\f(CWDW_AT_call_file\fP,
and the line table state machine
file numbers begin at zero. To index srcfiles
use the values directly with no subtraction.
.P
DWARF2-4 and experimental line table:
\f(CWDW_MACINFO_start_file\fP,
\f(CWDW_LNS_set_file\fP,
\f(CWDW_AT_decl_file\fP,
and line table state machine
file numbers begin at one.
In all these the value of 0 means
there is no source file or source file name.
To index the srcfiles array
subtract one from the
\f(CWDW_AT_decl_file\fP (etc)
file number.
.P
.DS
\f(CWint dwarf_srcfiles(
Dwarf_Die die,
char ***srcfiles,
Dwarf_Signed *srccount,
Dwarf_Error *error)\fP
.DE
When it succeeds
\f(CWdwarf_srcfiles()\fP returns
\f(CWDW_DLV_OK\fP
and puts
the number of source
files named in the statement program prologue indicated by the given
\f(CWdie\fP
into \f(CW*srccount\fP.
Source files defined in the statement program are ignored.
The given \f(CWdie\fP should have the tag
\f(CWDW_TAG_compile_unit\fP,
\f(CWDW_TAG_partial_unit\fP,
or
\f(CWDW_TAG_type_unit\fP
.
The location pointed to by \f(CWsrcfiles\fP is set to point to a list
of pointers to null-terminated strings that name the source
files.
.P
On a successful return from \f(CWdwarf_srcfiles()\fP each of the
strings returned should be individually freed using
\f(CWdwarf_dealloc()\fP
with the allocation type
\f(CWDW_DLA_STRING\fP when no longer of
interest.
This should be followed by free-ing the list using
\f(CWdwarf_dealloc()\fP with the allocation type \f(CWDW_DLA_LIST\fP.
It returns
\f(CWDW_DLV_ERROR\fP on error.
It returns
\f(CWDW_DLV_NO_ENTRY\fP
if there is no
corresponding statement program (i.e.,
if there is no line information).
.P
.in +2
.FG "Exampled dwarf_srcfiles()"
.DS
\f(CW
void examplee(Dwarf_Debug dbg,Dwarf_Die somedie)
{
Dwarf_Signed count = 0;
char **srcfiles = 0;
Dwarf_Signed i = 0;
Dwarf_Error error = 0;
int res = 0;
res = dwarf_srcfiles(somedie, &srcfiles,&count,&error);
if (res == DW_DLV_OK) {
for (i = 0; i < count; ++i) {
/* use srcfiles[i] */
dwarf_dealloc(dbg, srcfiles[i], DW_DLA_STRING);
}
dwarf_dealloc(dbg, srcfiles, DW_DLA_LIST);
}
}
\fP
.DE
.in -2
.H 2 "Get Information About a Single Line Table Line"
The following functions can be used on the \f(CWDwarf_Line\fP descriptors
returned by
\f(CWdwarf_srclines()\fP
or
\f(CWdwarf_srclines_from_linecontext()\fP
to obtain information about the
source lines.
.H 3 "dwarf_linebeginstatement()"
.DS
\f(CWint dwarf_linebeginstatement(
Dwarf_Line line,
Dwarf_Bool *return_bool,
Dwarf_Error *error)\fP
.DE
The function \f(CWdwarf_linebeginstatement()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*return_bool\fP
to
\fInon-zero\fP
(if \f(CWline\fP represents a line number entry that is marked as
beginning a statement).
or
\fIzero\fP ((if \f(CWline\fP represents a line number entry
that is not marked as beginning a statement).
It returns \f(CWDW_DLV_ERROR\fP on error.
It never returns \f(CWDW_DLV_NO_ENTRY\fP.
.P
.H 3 "dwarf_lineendsequence()"
.DS
\f(CWint dwarf_lineendsequence(
Dwarf_Line line,
Dwarf_Bool *return_bool,
Dwarf_Error *error)\fP
.DE
The function \f(CWdwarf_lineendsequence()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*return_bool\fP
\fInon-zero\fP
(in which case
\f(CWline\fP represents a line number entry that is marked as
ending a text sequence)
or
\fIzero\fP (in which case
\f(CWline\fP represents a line number entry
that is not marked as ending a text sequence).
A line number entry that is marked as
ending a text sequence is an entry with an address
one beyond the highest address used by the current
sequence of line table entries (that is, the table entry is
a DW_LNE_end_sequence entry (see the DWARF specification)).
.P
The function \f(CWdwarf_lineendsequence()\fP
returns \f(CWDW_DLV_ERROR\fP on error.
It never returns \f(CWDW_DLV_NO_ENTRY\fP.
.P
.H 3 "dwarf_lineno()"
.DS
\f(CWint dwarf_lineno(
Dwarf_Line line,
Dwarf_Unsigned * returned_lineno,
Dwarf_Error * error)\fP
.DE
The function \f(CWdwarf_lineno()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*return_lineno\fP to
the source statement line
number corresponding to the descriptor \f(CWline\fP.
It returns \f(CWDW_DLV_ERROR\fP on error.
It never returns \f(CWDW_DLV_NO_ENTRY\fP.
.P
.H 3 "dwarf_line_srcfileno()"
.DS
\f(CWint dwarf_line_srcfileno(
Dwarf_Line line,
Dwarf_Unsigned * returned_fileno,
Dwarf_Error * error)\fP
.DE
The function \f(CWdwarf_line_srcfileno()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*returned_fileno\fP to
the source statement line
number corresponding to the descriptor \f(CWfile number\fP.
.P
DWARF2-4 and experimental:
When the number returned through \f(CW*returned_fileno\fP is zero it means
the file name is unknown (see the DWARF2/3 line table specification).
When the number returned through \f(CW*returned_fileno\fP is non-zero
it is a file number:
subtract 1 from this file number
to get an
index into the array of strings returned by \f(CWdwarf_srcfiles()\fP
(verify the resulting index is in range for the array of strings
before indexing into the array of strings).
The file number may exceed the size of
the array of strings returned by \f(CWdwarf_srcfiles()\fP
because \f(CWdwarf_srcfiles()\fP does not return files names defined with
the \f(CWDW_DLE_define_file\fP operator.
.P
DWARF5:
To index into the array of strings returned by
\f(CWdwarf_srcfiles()\fP
use the number returned through \f(CW*returned_fileno\fP.
.P
The function \f(CWdwarf_line_srcfileno()\fP returns \f(CWDW_DLV_ERROR\fP on error.
It never returns \f(CWDW_DLV_NO_ENTRY\fP.
.P
.H 3 "dwarf_lineaddr()"
.DS
\f(CWint dwarf_lineaddr(
Dwarf_Line line,
Dwarf_Addr *return_lineaddr,
Dwarf_Error *error)\fP
.DE
The function \f(CWdwarf_lineaddr()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*return_lineaddr\fP to
the address associated
with the descriptor \f(CWline\fP.
It returns \f(CWDW_DLV_ERROR\fP on error.
It never returns \f(CWDW_DLV_NO_ENTRY\fP.
.P
.H 3 "dwarf_lineoff()"
.DS
\f(CWint dwarf_lineoff(
Dwarf_Line line,
Dwarf_Signed * return_lineoff,
Dwarf_Error *error)\fP
.DE
The function \f(CWdwarf_lineoff()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*return_lineoff\fP to
the column number at which
the statement represented by \f(CWline\fP begins.
.P
It sets \f(CWreturn_lineoff\fP to zero
if the column number of the statement is not represented
(meaning the producer library call was given zero
as the column number). Zero is the correct value meaning "left edge"
as defined in the DWARF2/3/4 specication (section 6.2.2).
.P
Before December 2011 zero was not returned through
the \f(CWreturn_lineoff\fP pointer, -1 was returned through the pointer.
The reason for this oddity is unclear, lost in history.
But there is no good reason for -1.
.P
The type of \f(CWreturn_lineoff\fP is a pointer-to-signed, but there
is no good reason for the value to be signed, the DWARF specification
does not deal with negative column numbers. However, changing the
declaration would cause compilation errors for little benefit, so
the pointer-to-signed is left unchanged.
.P
On error it returns \f(CWDW_DLV_ERROR\fP.
It never returns \f(CWDW_DLV_NO_ENTRY\fP.
.H 3 "dwarf_lineoff_b()"
.DS
\f(CWint dwarf_lineoff_b(
Dwarf_Line line,
Dwarf_Unsigned * return_lineoff,
Dwarf_Error *error)\fP
.DE
The function
\f(CWdwarf_lineoff_b()\fP
returns
exactly the same as
\f(CWdwarf_lineoff()\fP
except the line offset returned
through
\f(CWreturn_lineoff()\fP
is an unsigned value.
The signed return offset never made much sense
but was harmless since line lengths are limited
by most language standards.
.H 3 "dwarf_linesrc()"
.DS
\f(CWint dwarf_linesrc(
Dwarf_Line line,
char ** return_linesrc,
Dwarf_Error *error)\fP
.DE
The function \f(CWdwarf_linesrc()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*return_linesrc\fP to
a pointer to a
null-terminated string of characters that represents the name of the
source-file where \f(CWline\fP occurs.
It returns \f(CWDW_DLV_ERROR\fP on
error.
.P
If the applicable file name in the line table Statement Program Prolog
does not start with a '/' character
the string in \f(CWDW_AT_comp_dir\fP (if applicable and present)
or the applicable
directory name from the line Statement Program Prolog
is prepended to the
file name in the line table Statement Program Prolog
to make a full path.
.P
The storage pointed to by a successful return of
\f(CWdwarf_linesrc()\fP should be freed using
\f(CWdwarf_dealloc()\fP with
the allocation type
\f(CWDW_DLA_STRING\fP when no longer of interest.
It never returns \f(CWDW_DLV_NO_ENTRY\fP.
.H 3 "dwarf_lineblock()"
.DS
\f(CWint dwarf_lineblock(
Dwarf_Line line,
Dwarf_Bool *return_bool,
Dwarf_Error *error)\fP
.DE
The function
\f(CWdwarf_lineblock()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*return_linesrc\fP to
non-zero (i.e. true)(if the line is marked as
beginning a basic block)
or zero (i.e. false) (if the line is marked as not
beginning a basic block).
It returns \f(CWDW_DLV_ERROR\fP on error.
It never returns \f(CWDW_DLV_NO_ENTRY\fP.
.H 3 "dwarf_is_addr_set()"
.DS
\f(CWint dwarf_line_is_addr_set(
Dwarf_Line line,
Dwarf_Bool *return_bool,
Dwarf_Error *error)\fP
.DE
The function
\f(CWdwarf_line_is_addr_set()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*return_bool\fP to
non-zero (i.e. true)(if the line is marked as
being a DW_LNE_set_address operation)
or zero (i.e. false) (if the line is marked as not
being a DW_LNE_set_address operation).
It returns \f(CWDW_DLV_ERROR\fP on error.
It never returns \f(CWDW_DLV_NO_ENTRY\fP.
This is intended to allow consumers to do a more useful job
printing and analyzing DWARF data, it is not strictly
necessary.
.H 3 "dwarf_prologue_end_etc()"
.DS
\f(CWint dwarf_prologue_end_etc(Dwarf_Line line,
Dwarf_Bool * prologue_end,
Dwarf_Bool * epilogue_begin,
Dwarf_Unsigned * isa,
Dwarf_Unsigned * discriminator,
Dwarf_Error * error)\fP
.DE
The function
\f(CWdwarf_prologue_end_etc()\fP returns
\f(CWDW_DLV_OK\fP and sets the returned fields to
values currently set.
While it is pretty safe to assume that the
\f(CWisa\fP
and
\f(CWdiscriminator\fP
values returned are very small integers, there is
no restriction in the standard.
It returns \f(CWDW_DLV_ERROR\fP on error.
It never returns \f(CWDW_DLV_NO_ENTRY\fP.
This function is new in December 2011.
.H 2 "Accelerated Access By Name operations"
These operations operate on the .debug_pubnames section
as well as all the other sections with this
specific format and purpose:
.debug_pubtypes,
.debug_typenames,
.debug_varnames,
.debug_funcnames,
and .debug_weaknames.
The first in the list is generic DWARF 2,3,4.
The second in the list is generic DWARF 3,4.
The rest are SGI specific and rarely used.
.P
The interface types are Dwarf_Global
Dwarf_Type,Dwarf_Weak,Dwarf_Func, and Dwarf_Var.
Only Dwarf_Global is a real type. The others
are opaque pointers with no actual
definition or instantiation and can be converted
to Dwarf_Global with a simple cast.
.P
In hindsight it would have been simpler to
write a single set of interfaces for Accelerated
Access By Name.
.H 3 "Fine Tuning Accelerated Access"
By default the various dwarf_get*() functions
here return an array of pointers to opaque records
with a .debug_info DIE offset and a string
(the fields are accessible by function calls).
While the actual .debug_pubnames (etc) section
contains CU-local DIE offsets for the named
things the accelerated access functions below
return a .debug_info (or .debug_types)
global section offset.
.P
.H 4 "dwarf_return_empty_pubnames"
New March 2019. Mostly special for dwarfdump.
If called with a flag value of one (1)
it tells libdwarf, for any pubnames(etc)
section list returned to add to the list
an entry with a global-DIE-offset of zero (0)
for any section Compilation Unit entry with no pubnames(etc)
name( ie, an empty list for the Compilation Unit).
.P
If called with a value of zero(0) (zero is the default
set by any
\f(CWdwarf_init*()\fP
call) it causes such empty lists to be omitted from
the array of pointers returned, which
is the standard behavior of libdwarf since libdwarf
was first written.
.P
Since zero is never a valid DIE offset in .debug_info
(or .debug_types) consumers requesting such
can detect the special Dwarf_Global entries.
.P
For example, calling
\f(CW dwarf_global_name_offsets()\fP
on one of the special global records
sets
\f(CW*die_offset\fP
to 0,
\f(CW*return_name\fP
to a pointer to an empty string,
and
\f(CW*cu_offset\fP
to the offset of the compilation
unit die in the .debug_info
(or .debug_types if applicable) section.
.DS
\f(CWint dwarf_return_empty_pubnames(Dwarf_Debug dbg,
int flag ,
Dwarf_Error* error)\fP
.DE
Callers should pass in one (1) or zero(0), no other value.
On success it returns DW_DLV_OK.
On failure it returns DW_DLV_ERROR;
.P
The assumption is that programs calling this with
value one (1) will be calling
dwarf_get_globals_header()
to retrieve the relevant pubnames(etc)
section Compilation Unit
header.
.H 4 "dwarf_get_globals_header"
New February 2019.
For more complete dwarfdump printing.
For each CU represented in .debug_pubnames, etc,
there is a .debug_pubnames header. For any given
Dwarf_Global this returns the content of the applicable
header.
.P
This allows dwarfdump, or any DWARF dumper,
to print pubnames(etc) specific CU header
data.
.DS
\f(CWint dwarf_get_globals_header(Dwarf_Global global,
Dwarf_Off * offset_pub_header,
Dwarf_Unsigned * offset_size,
Dwarf_Unsigned * length_pub,
Dwarf_Unsigned * version,
Dwarf_Unsigned * header_info_offset,
Dwarf_Unsigned * info_length,
Dwarf_Error* error)\fP
.DE
On success it returns DW_DLV_OK and
it returns the header data (and calculated values)
though the pointers.
Casting Dwarf_Type (etc) to Dwarf_Global
for a call to this function allows this to
be used for any of these accelerated-access
types.
.H 3 "Accelerated Access Pubnames"
.H 4 "dwarf_get_globals()"
This is .debug_pubnames and is standard DWARF2, DWARF3, and DWARF4.
.DS
\f(CWint dwarf_get_globals(
Dwarf_Debug dbg,
Dwarf_Global **globals,
Dwarf_Signed * return_count,
Dwarf_Error *error)\fP
.DE
The function \f(CWdwarf_get_globals()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*return_count\fP to
the count of pubnames
represented in the section containing pubnames i.e. .debug_pubnames.
It also stores at \f(CW*globals\fP, a pointer
to a list of \f(CWDwarf_Global\fP descriptors, one for each of the
pubnames in the .debug_pubnames section.
The returned results are for the entire section.
It returns \f(CWDW_DLV_ERROR\fP on error.
It returns \f(CWDW_DLV_NO_ENTRY\fP if the .debug_pubnames
section does not exist.
.P
On a successful return from
\f(CWdwarf_get_globals()\fP, the \f(CWDwarf_Global\fP
descriptors should be
freed using \f(CWdwarf_globals_dealloc()\fP.
\f(CWdwarf_globals_dealloc()\fP is new as of July 15, 2005
and is the preferred approach to freeing this memory..
.P
Global names refer exclusively to names and offsets
in the .debug_info section.
See section 6.1.1 "Lookup by Name" in the dwarf standard.
.in +2
.FG "Exampled dwarf_get_globals()"
.DS
\f(CW
void examplef(Dwarf_Debug dbg)
{
Dwarf_Signed count = 0;
Dwarf_Global *globs = 0;
Dwarf_Signed i = 0;
Dwarf_Error error = 0;
int res = 0;
res = dwarf_get_globals(dbg, &globs,&count, &error);
if (res == DW_DLV_OK) {
for (i = 0; i < count; ++i) {
/* use globs[i] */
}
dwarf_globals_dealloc(dbg, globs, count);
}
}
\fP
.DE
.in -2
.P
The following code is deprecated as of July 15, 2005 as it does not
free all relevant memory.
This approach still works as well as it ever did.
On a successful return from
\f(CWdwarf_get_globals()\fP, the \f(CWDwarf_Global\fP
descriptors should be individually
freed using \f(CWdwarf_dealloc()\fP with the allocation type
\f(CWDW_DLA_GLOBAL_CONTEXT\fP,
(or
\f(CWDW_DLA_GLOBAL\fP, an older name, supported for compatibility)
followed by the deallocation of the list itself
with the allocation type \f(CWDW_DLA_LIST\fP when the descriptors are
no longer of interest.
.in +2
.DS
\f(CW
Dwarf_Signed cnt;
Dwarf_Global *globs;
int res;
res = dwarf_get_globals(dbg, &globs,&cnt, &error);
if (res == DW_DLV_OK) {
/* OBSOLETE: DO NOT USE to deallocate*/
for (i = 0; i < cnt; ++i) {
/* use globs[i] */
dwarf_dealloc(dbg, globs[i], DW_DLA_GLOBAL_CONTEXT);
}
dwarf_dealloc(dbg, globs, DW_DLA_LIST);
}
\fP
.DE
.in -2
.H 4 "dwarf_globname()"
.DS
\f(CWint dwarf_globname(
Dwarf_Global global,
char ** return_name,
Dwarf_Error *error)\fP
.DE
The function \f(CWdwarf_globname()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*return_name\fP to
a pointer to a
null-terminated string that names the pubname represented by the
\f(CWDwarf_Global\fP descriptor, \f(CWglobal\fP.
It returns \f(CWDW_DLV_ERROR\fP on error.
On a successful return from this function, the string should
be freed using \f(CWdwarf_dealloc()\fP, with the allocation type
\f(CWDW_DLA_STRING\fP when no longer of interest.
It never returns \f(CWDW_DLV_NO_ENTRY\fP.
.H 4 "dwarf_global_die_offset()"
.DS
\f(CWint dwarf_global_die_offset(
Dwarf_Global global,
Dwarf_Off *return_offset,
Dwarf_Error *error)\fP
.DE
The function \f(CWdwarf_global_die_offset()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP to
the offset in
the section containing DIEs, i.e. .debug_info, of the DIE representing
the pubname that is described by the \f(CWDwarf_Global\fP descriptor,
\f(CWglob\fP.
It returns \f(CWDW_DLV_ERROR\fP on error.
It never returns \f(CWDW_DLV_NO_ENTRY\fP.
.H 4 "dwarf_global_cu_offset()"
.DS
\f(CWint dwarf_global_cu_offset(
Dwarf_Global global,
Dwarf_Off *return_offset,
Dwarf_Error *error)\fP
.DE
The function \f(CWdwarf_global_cu_offset()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP to
the offset in
the section containing DIEs, i.e. .debug_info, of the compilation-unit
header of the compilation-unit that contains the pubname described
by the \f(CWDwarf_Global\fP descriptor, \f(CWglobal\fP.
It returns \f(CWDW_DLV_ERROR\fP on error.
It never returns \f(CWDW_DLV_NO_ENTRY\fP.
.H 4 "dwarf_get_cu_die_offset_given_cu_header_offset()"
.DS
\f(CWint dwarf_get_cu_die_offset_given_cu_header_offset_b(
Dwarf_Debug dbg,
Dwarf_Off in_cu_header_offset,
Dwarf_Bool is_info,
Dwarf_Off * out_cu_die_offset,
Dwarf_Error *error)\fP
.DE
The function \f(CWdwarf_get_cu_die_offset_given_cu_header_offset()\fP
returns
\f(CWDW_DLV_OK\fP and sets \f(CW*out_cu_die_offset\fP to
the offset of the compilation-unit DIE given the
offset \f(CWin_cu_header_offset\fP of a compilation-unit header.
It returns \f(CWDW_DLV_ERROR\fP on error.
It never returns \f(CWDW_DLV_NO_ENTRY\fP.
.P
If \f(CWis_info\fP is non-zero the \f(CWin_cu_header_offset\fP must refer
to a .debug_info section offset.
If \f(CWis_info\fP zero the \f(CWin_cu_header_offset\fP must refer
to a .debug_types section offset.
Chaos may result if the \f(CWis_info\fP flag is incorrect.
This effectively turns a compilation-unit-header offset
into a compilation-unit DIE offset (by adding the
size of the applicable CU header).
This function is also sometimes useful with the
\f(CWdwarf_weak_cu_offset()\fP,
\f(CWdwarf_func_cu_offset()\fP,
\f(CWdwarf_type_cu_offset()\fP,
and
\f(CWint dwarf_var_cu_offset()\fP
functions, though for those functions the data is
only in .debug_info by definition.
.H 4 "dwarf_get_cu_die_offset_given_cu_header_offset()"
.DS
\f(CWint dwarf_get_cu_die_offset_given_cu_header_offset(
Dwarf_Debug dbg,
Dwarf_Off in_cu_header_offset,
Dwarf_Off * out_cu_die_offset,
Dwarf_Error *error)\fP
.DE
This function is superseded by
\f(CWdwarf_get_cu_die_offset_given_cu_header_offset_b()\fP,
a function which is still supported thought it refers only
to the .debug_info section.
.P
\f(CWdwarf_get_cu_die_offset_given_cu_header_offset()\fP
added Rev 1.45, June, 2001.
.P
This function was declared as 'optional' in libdwarf.h
on IRIX systems so the _MIPS_SYMBOL_PRESENT
predicate could be used at run time to determine if the version of
libdwarf linked into an application has this function.
.H 4 "dwarf_global_name_offsets()"
.DS
\f(CWint dwarf_global_name_offsets(
Dwarf_Global global,
char **return_name,
Dwarf_Off *die_offset,
Dwarf_Off *cu_die_offset,
Dwarf_Error *error)\fP
.DE
The function \f(CWdwarf_global_name_offsets()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*return_name\fP to
a pointer to
a null-terminated string that gives the name of the pubname
described by the \f(CWDwarf_Global\fP descriptor \f(CWglobal\fP.
It returns \f(CWDW_DLV_ERROR\fP on error.
It never returns \f(CWDW_DLV_NO_ENTRY\fP.
It also returns in the locations
pointed to by \f(CWdie_offset\fP, and \f(CWcu_offset\fP,
the global offset of the DIE representing the pubname,
and
the offset of the DIE representing the compilation-unit
containing the
pubname, respectively.
On a
successful return from \f(CWdwarf_global_name_offsets()\fP the storage
pointed to by \f(CWreturn_name\fP
should be freed using \f(CWdwarf_dealloc()\fP,
with the allocation type \f(CWDW_DLA_STRING\fP when no longer of interest.
.P
If a portion of .debug_pubnames ( or .debug_types etc)
represents a compilation unit with no names there
is a .debug_pubnames header there with no content.
In that case a single Dwarf_Global record is
created with the value of *die_offset zero
and the name-pointer returned points to the empty string.
A zero is never a valid DIE offset, so zero always
means this is an uninteresting (Dwarf_Global).
.H 3 "Accelerated Access Pubtypes"
Section ".debug_pubtypes" is in DWARF3 and DWARF4.
.P
These functions operate on the .debug_pubtypes section of the debugging
information. The .debug_pubtypes section contains the names of file-scope
user-defined types, the offsets of the \f(CWDIE\fPs that represent the
definitions of those types, and the offsets of the compilation-units
that contain the definitions of those types.
.H 4 "dwarf_get_pubtypes()"
This is standard DWARF3 and DWARF4.
.DS
\f(CWint dwarf_get_pubtypes(
Dwarf_Debug dbg,
Dwarf_Type **types,
Dwarf_Signed *typecount,
Dwarf_Error *error)\fP
.DE
The function \f(CWdwarf_get_pubtypes()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*typecount\fP to
the count of user-defined
type names represented in the section containing user-defined type names,
i.e. .debug_pubtypes.
It also stores at \f(CW*types\fP,
a pointer to a list of \f(CWDwarf_Type\fP descriptors, one for each of the
user-defined type names in the .debug_pubtypes section.
The returned results are for the entire section.
It returns \f(CWDW_DLV_NOCOUNT\fP on error.
It returns \f(CWDW_DLV_NO_ENTRY\fP if
the .debug_pubtypes section does not exist.
.P
On a successful
return from \f(CWdwarf_get_pubtypes()\fP,
the \f(CWDwarf_Type\fP descriptors should be
freed using \f(CWdwarf_types_dealloc()\fP.
\f(CWdwarf_types_dealloc()\fP is used for both
\f(CWdwarf_get_pubtypes()\fP and \f(CWdwarf_get_types()\fP
as the data types are the same.
.P
Global type names refer exclusively to names and offsets
in the .debug_info section.
See section 6.1.1 "Lookup by Name" in the dwarf standard.
.in +2
.FG "Exampled dwarf_get_pubtypes()"
.DS
\f(CW
Avoid exampleg(Dwarf_Debug dbg)
{
Dwarf_Error error = 0;
Dwarf_Signed count = 0;
Dwarf_Type *types = 0;
Dwarf_Signed i = 0;
int res = 0;
res = dwarf_get_pubtypes(dbg, &types,&count, &error);
if (res == DW_DLV_OK) {
for (i = 0; i < count; ++i) {
/* use types[i] */
}
dwarf_types_dealloc(dbg, types, count);
}
}
\fP
.DE
.in -2
.H 4 "dwarf_pubtypename()"
.DS
\f(CWint dwarf_pubtypename(
Dwarf_Type type,
char **return_name,
Dwarf_Error *error)\fP
.DE
The function \f(CWdwarf_pubtypename()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*return_name\fP to
a pointer to a
null-terminated string that names the user-defined type represented by the
\f(CWDwarf_Type\fP descriptor, \f(CWtype\fP.
It returns \f(CWDW_DLV_ERROR\fP on error.
It never returns \f(CWDW_DLV_NO_ENTRY\fP.
On a successful return from this function, the string should
be freed using \f(CWdwarf_dealloc()\fP, with the allocation type
\f(CWDW_DLA_STRING\fP when no longer of interest.
.H 4 "dwarf_pubtype_type_die_offset()"
.DS
\f(CWint dwarf_pubtype_type_die_offset(
Dwarf_Type type,
Dwarf_Off *return_offset,
Dwarf_Error *error)\fP
.DE
The function \f(CWdwarf_pubtype_type_die_offset()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP to
the offset in
the section containing DIEs, i.e. .debug_info, of the DIE representing
the user-defined type that is described by the \f(CWDwarf_Type\fP
descriptor, \f(CWtype\fP.
It returns \f(CWDW_DLV_ERROR\fP on error.
It never returns \f(CWDW_DLV_NO_ENTRY\fP.
.H 4 "dwarf_pubtype_cu_offset()"
.DS
\f(CWint dwarf_pubtype_cu_offset(
Dwarf_Type type,
Dwarf_Off *return_offset,
Dwarf_Error *error)\fP
.DE
The function \f(CWdwarf_pubtype_cu_offset()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP to
the offset in
the section containing DIEs, i.e. .debug_info, of the compilation-unit
header of the compilation-unit that contains the user-defined type
described by the \f(CWDwarf_Type\fP descriptor, \f(CWtype\fP.
It returns \f(CWDW_DLV_ERROR\fP on error.
It never returns \f(CWDW_DLV_NO_ENTRY\fP.
.H 4 "dwarf_pubtype_name_offsets()"
.DS
\f(CWint dwarf_pubtype_name_offsets(
Dwarf_Type type,
char ** returned_name,
Dwarf_Off * die_offset,
Dwarf_Off * cu_offset,
Dwarf_Error *error)\fP
.DE
The function \f(CWdwarf_pubtype_name_offsets()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*returned_name\fP to
a pointer to
a null-terminated string that gives the name of the user-defined
type described by the \f(CWDwarf_Type\fP descriptor \f(CWtype\fP.
It also returns in the locations
pointed to by \f(CWdie_offset\fP, and \f(CWcu_offset\fP, the offsets
of the DIE representing the
user-defined type, and the DIE
representing the compilation-unit containing the
user-defined type, respectively.
It returns \f(CWDW_DLV_ERROR\fP on error.
It never returns \f(CWDW_DLV_NO_ENTRY\fP.
On a successful return from \f(CWdwarf_pubtype_name_offsets()\fP
the storage pointed to by \f(CWreturned_name\fP should
be freed using
\f(CWdwarf_dealloc()\fP, with the allocation type \f(CWDW_DLA_STRING\fP
when no longer of interest.
.H 3 "Accelerated Access Weaknames"
This section is SGI specific and is not part of standard DWARF.
.P
These functions operate on the .debug_varnames section of the debugging
information. The .debug_varnames section contains the names of file-scope
static variables, the offsets of the \f(CWDIE\fPs that represent the
definitions of those variables, and the offsets of the compilation-units
that contain the definitions of those variables.
.P
These operations operate on the .debug_weaknames section of the debugging
information.
.H 4 "dwarf_get_weaks()"
.DS
\f(CWint dwarf_get_weaks(
Dwarf_Debug dbg,
Dwarf_Weak **weaks,
Dwarf_Signed *weak_count,
Dwarf_Error *error)\fP
.DE
The function \f(CWdwarf_get_weaks()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*weak_count\fP to
the count of weak names
represented in the section containing weak names i.e. .debug_weaknames.
It returns \f(CWDW_DLV_ERROR\fP on error.
It returns \f(CWDW_DLV_NO_ENTRY\fP if the section does not exist.
It also stores in \f(CW*weaks\fP, a pointer to
a list of \f(CWDwarf_Weak\fP descriptors, one for each of the weak names
in the .debug_weaknames section.
The returned results are for the entire section.
.P
On a successful return from this function,
the \f(CWDwarf_Weak\fP descriptors should be freed using
\f(CWdwarf_weaks_dealloc()\fP when the data is no longer of
interest. \f(CWdwarf_weaks_dealloc()\fPis new as of July 15, 2005.
.in +2
.FG "Exampleh dwarf_get_weaks()"
.DS
\f(CW
void exampleh(Dwarf_Debug dbg)
{
Dwarf_Error error = 0;
Dwarf_Signed count = 0;
Dwarf_Weak *weaks = 0;
Dwarf_Signed i = 0;
int res = 0;
res = dwarf_get_weaks(dbg, &weaks, &count, &error);
if (res == DW_DLV_OK) {
for (i = 0; i < count; ++i) {
/* use weaks[i] */
}
dwarf_weaks_dealloc(dbg, weaks, count);
}
}
\fP
.DE
.in -2
.P
The following code is deprecated as of July 15, 2005 as it does not
free all relevant memory.
This approach still works as well as it ever did.
On a successful return from \f(CWdwarf_get_weaks()\fP
the \f(CWDwarf_Weak\fP descriptors should be individually freed using
\f(CWdwarf_dealloc()\fP with the allocation type
\f(CWDW_DLA_WEAK_CONTEXT\fP,
(or
\f(CWDW_DLA_WEAK\fP, an older name, supported for compatibility)
followed by the deallocation of the list itself with the allocation type
\f(CWDW_DLA_LIST\fP when the descriptors are no longer of interest.
.in +2
.FG "Examplei dwarf_get_weaks() obsolete"
.DS
\f(CW
void examplei(Dwarf_Debug dbg)
{
Dwarf_Error error = 0;
Dwarf_Signed count = 0;
Dwarf_Weak *weaks = 0;
Dwarf_Signed i = 0;
int res = 0;
/* Obsolete, see exampleh instead */
res = dwarf_get_weaks(dbg, &weaks, &count, &error);
if (res == DW_DLV_OK) {
/* OBSOLETE: do not use dealloc for this.
See above */
for (i = 0; i < count; ++i) {
/* use weaks[i] */
dwarf_dealloc(dbg, weaks[i], DW_DLA_WEAK);
}
dwarf_dealloc(dbg, weaks, DW_DLA_LIST);
}
}
\fP
.DE
.in -2
.H 4 "dwarf_weakname()"
.DS
\f(CWint dwarf_weakname(
Dwarf_Weak weak,
char ** return_name,
Dwarf_Error *error)\fP
.DE
The function \f(CWdwarf_weakname()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*return_name\fP to
a pointer to a null-terminated
string that names the weak name represented by the
\f(CWDwarf_Weak\fP descriptor, \f(CWweak\fP.
It returns \f(CWDW_DLV_ERROR\fP on error.
It never returns \f(CWDW_DLV_NO_ENTRY\fP.
On a successful return from this function, the string should
be freed using \f(CWdwarf_dealloc()\fP, with the allocation type
\f(CWDW_DLA_STRING\fP when no longer of interest.
.DS
\f(CWint dwarf_weak_die_offset(
Dwarf_Weak weak,
Dwarf_Off *return_offset,
Dwarf_Error *error)\fP
.DE
The function \f(CWdwarf_weak_die_offset()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP to the offset in
the section containing DIEs, i.e. .debug_info, of the DIE representing
the weak name that is described by the \f(CWDwarf_Weak\fP descriptor,
\f(CWweak\fP.
It returns \f(CWDW_DLV_ERROR\fP on error.
It never returns \f(CWDW_DLV_NO_ENTRY\fP.
.H 4 "dwarf_weak_cu_offset()"
.DS
\f(CWint dwarf_weak_cu_offset(
Dwarf_Weak weak,
Dwarf_Off *return_offset,
Dwarf_Error *error)\fP
.DE
The function \f(CWdwarf_weak_cu_offset()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP to the offset in
the section containing DIEs, i.e. .debug_info, of the compilation-unit
header of the compilation-unit that contains the weak name described
by the \f(CWDwarf_Weak\fP descriptor, \f(CWweak\fP.
It returns \f(CWDW_DLV_ERROR\fP on error.
It never returns \f(CWDW_DLV_NO_ENTRY\fP.
.H 4 "dwarf_weak_name_offsets()"
.DS
\f(CWint dwarf_weak_name_offsets(
Dwarf_Weak weak,
char ** weak_name,
Dwarf_Off *die_offset,
Dwarf_Off *cu_offset,
Dwarf_Error *error)\fP
.DE
The function \f(CWdwarf_weak_name_offsets()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*weak_name\fP to
a pointer to
a null-terminated string that gives the name of the weak name
described by the \f(CWDwarf_Weak\fP descriptor \f(CWweak\fP.
It also returns in the locations
pointed to by \f(CWdie_offset\fP, and \f(CWcu_offset\fP, the offsets
of the DIE representing the
weakname, and the DIE
representing the compilation-unit containing the
weakname, respectively.
It returns \f(CWDW_DLV_ERROR\fP on error.
It never returns \f(CWDW_DLV_NO_ENTRY\fP.
On a
successful return from \f(CWdwarf_weak_name_offsets()\fP the storage
pointed to by \f(CWweak_name\fP
should be freed using \f(CWdwarf_dealloc()\fP,
with the allocation type \f(CWDW_DLA_STRING\fP when no longer of interest.
.H 3 "Accelerated Access Funcnames"
This section is SGI specific and is not part of standard DWARF.
.P
These function operate on the .debug_funcnames section of the debugging
information. The .debug_funcnames section contains the names of static
functions defined in the object, the offsets of the \f(CWDIE\fPs that
represent the definitions of the corresponding functions, and the offsets
of the start of the compilation-units that contain the definitions of
those functions.
.H 4 "dwarf_get_funcs()"
.DS
\f(CWint dwarf_get_funcs(
Dwarf_Debug dbg,
Dwarf_Func **funcs,
Dwarf_Signed *func_count,
Dwarf_Error *error)\fP
.DE
The function \f(CWdwarf_get_funcs()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*func_count\fP to
the count of static
function names represented in the section containing static function
names, i.e. .debug_funcnames.
It also
stores, at \f(CW*funcs\fP, a pointer to a list of \f(CWDwarf_Func\fP
descriptors, one for each of the static functions in the .debug_funcnames
section.
The returned results are for the entire section.
It returns \f(CWDW_DLV_ERROR\fP on error.
It returns \f(CWDW_DLV_NO_ENTRY\fP
if the .debug_funcnames section does not exist.
.P
On a successful return from \f(CWdwarf_get_funcs()\fP,
the \f(CWDwarf_Func\fP
descriptors should be freed using \f(CWdwarf_funcs_dealloc()\fP.
\f(CWdwarf_funcs_dealloc()\fP is new as of July 15, 2005.
.in +2
.FG "Examplej dwarf_get_funcs()"
.DS
\f(CW
void examplej(Dwarf_Debug dbg)
{
Dwarf_Error error = 0;
Dwarf_Signed count = 0;
Dwarf_Func *funcs = 0;
Dwarf_Signed i = 0;
int fres = 0;
fres = dwarf_get_funcs(dbg, &funcs, &count, &error);
if (fres == DW_DLV_OK) {
for (i = 0; i < count; ++i) {
/* use funcs[i] */
}
dwarf_funcs_dealloc(dbg, funcs, count);
}
}
\fP
.DE
.in -2
.P
The following code is deprecated as of July 15, 2005 as it does not
free all relevant memory.
This approach still works as well as it ever did.
On a successful return from \f(CWdwarf_get_funcs()\fP,
the \f(CWDwarf_Func\fP
descriptors should be individually freed using \f(CWdwarf_dealloc()\fP
with the allocation type
\f(CWDW_DLA_FUNC_CONTEXT\fP,
(or
\f(CWDW_DLA_FUNC\fP, an older name, supported for compatibility)
followed by the deallocation
of the list itself with the allocation type \f(CWDW_DLA_LIST\fP when
the descriptors are no longer of interest.
.in +2
.FG "Examplek dwarf_get_funcs() obsolete"
.DS
\f(CW
void examplek(Dwarf_Debug dbg)
{
Dwarf_Error error = 0;
Dwarf_Func *funcs = 0;
Dwarf_Signed count = 0;
Dwarf_Signed i = 0;
int fres = 0;
fres = dwarf_get_funcs(dbg, &funcs,&count, &error);
if (fres == DW_DLV_OK) {
/* OBSOLETE: see dwarf_funcs_dealloc() above */
for (i = 0; i < count; ++i) {
/* use funcs[i] */
dwarf_dealloc(dbg, funcs[i], DW_DLA_FUNC);
}
dwarf_dealloc(dbg, funcs, DW_DLA_LIST);
}
}
\fP
.DE
.in -2
.H 4 "dwarf_funcname()"
.DS
\f(CWint dwarf_funcname(
Dwarf_Func func,
char ** return_name,
Dwarf_Error *error)\fP
.DE
The function \f(CWdwarf_funcname()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*return_name\fP to
a pointer to a
null-terminated string that names the static function represented by the
\f(CWDwarf_Func\fP descriptor, \f(CWfunc\fP.
It returns \f(CWDW_DLV_ERROR\fP on error.
It never returns \f(CWDW_DLV_NO_ENTRY\fP.
On a successful return from this function, the string should
be freed using \f(CWdwarf_dealloc()\fP, with the allocation type
\f(CWDW_DLA_STRING\fP when no longer of interest.
.H 4 "dwarf_func_die_offset()"
.DS
\f(CWint dwarf_func_die_offset(
Dwarf_Func func,
Dwarf_Off *return_offset,
Dwarf_Error *error)\fP
.DE
The function \f(CWdwarf_func_die_offset()\fP, returns
\f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP to
the offset in
the section containing DIEs, i.e. .debug_info, of the DIE representing
the static function that is described by the \f(CWDwarf_Func\fP
descriptor, \f(CWfunc\fP.
It returns \f(CWDW_DLV_ERROR\fP on error.
It never returns \f(CWDW_DLV_NO_ENTRY\fP.
.H 4 "dwarf_func_cu_offset()"
.DS
\f(CWint dwarf_func_cu_offset(
Dwarf_Func func,
Dwarf_Off *return_offset,
Dwarf_Error *error)\fP
.DE
The function \f(CWdwarf_func_cu_offset()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP to
the offset in
the section containing DIEs, i.e. .debug_info, of the compilation-unit
header of the
compilation-unit that contains the static function
described by the \f(CWDwarf_Func\fP descriptor, \f(CWfunc\fP.
It returns \f(CWDW_DLV_ERROR\fP on error.
It never returns \f(CWDW_DLV_NO_ENTRY\fP.
.H 4 "dwarf_func_name_offsets()"
.DS
\f(CWint dwarf_func_name_offsets(
Dwarf_Func func,
char **func_name,
Dwarf_Off *die_offset,
Dwarf_Off *cu_offset,
Dwarf_Error *error)\fP
.DE
The function \f(CWdwarf_func_name_offsets()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*func_name\fP to
a pointer to
a null-terminated string that gives the name of the static
function described by the
\f(CWDwarf_Func\fP descriptor \f(CWfunc\fP.
It also returns in the locations
pointed to by \f(CWdie_offset\fP, and
\f(CWcu_offset\fP, the offsets
of the DIE representing the
static function, and the DIE
representing the compilation-unit containing the
static function, respectively.
It returns \f(CWDW_DLV_ERROR\fP on error.
It never returns \f(CWDW_DLV_NO_ENTRY\fP.
On a successful return from \f(CWdwarf_func_name_offsets()\fP
the storage pointed to by
\f(CWfunc_name\fP should be freed using
\f(CWdwarf_dealloc()\fP, with the
allocation type \f(CWDW_DLA_STRING\fP
when no longer of interest.
.H 3 "Accelerated Access Typenames"
Section "debug_typenames" is SGI specific
and is not part of standard DWARF.
(However, an identical section is part of DWARF version 3
named ".debug_pubtypes", see \f(CWdwarf_get_pubtypes()\fP above.)
.P
These functions operate on
the .debug_typenames section of the debugging
information.
The .debug_typenames section contains the names of file-scope
user-defined types, the offsets of the
\f(CWDIE\fPs that represent the
definitions of those types, and the offsets
of the compilation-units
that contain the definitions of those types.
.H 4 "dwarf_get_types()"
.DS
\f(CWint dwarf_get_types(
Dwarf_Debug dbg,
Dwarf_Type **types,
Dwarf_Signed *typecount,
Dwarf_Error *error)\fP
.DE
The function \f(CWdwarf_get_types()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*typecount\fP to
the count of user-defined
type names represented in the section containing user-defined type names,
i.e. .debug_typenames.
It also stores at \f(CW*types\fP,
a pointer to a list of \f(CWDwarf_Type\fP descriptors, one for each of the
user-defined type names in the .debug_typenames section.
The returned results are for the entire section.
It returns \f(CWDW_DLV_NOCOUNT\fP on error.
It returns \f(CWDW_DLV_NO_ENTRY\fP if
the .debug_typenames section does not exist.
.P
On a successful
return from \f(CWdwarf_get_types()\fP,
the \f(CWDwarf_Type\fP descriptors should be
freed using \f(CWdwarf_types_dealloc()\fP.
\f(CWdwarf_types_dealloc()\fP is new as of July 15, 2005
and frees all memory allocated by \f(CWdwarf_get_types()\fP.
.in +2
.FG "Examplel dwarf_get_types()"
.DS
\f(CW
void examplel(Dwarf_Debug dbg)
{
Dwarf_Error error = 0;
Dwarf_Signed count = 0;
Dwarf_Type *types = 0;
Dwarf_Signed i = 0;
int res = 0;
res = dwarf_get_types(dbg, &types,&count, &error);
if (res == DW_DLV_OK) {
for (i = 0; i < count; ++i) {
/* use types[i] */
}
dwarf_types_dealloc(dbg, types, count);
}
}
\fP
.DE
.in -2
.P
The following code is deprecated as of July 15, 2005 as it does not
free all relevant memory.
This approach still works as well as it ever did.
On a successful
return from \f(CWdwarf_get_types()\fP,
the \f(CWDwarf_Type\fP descriptors should be
individually freed using \f(CWdwarf_dealloc()\fP with the allocation type
\f(CWDW_DLA_TYPENAME_CONTEXT\fP,
(or
\f(CWDW_DLA_TYPENAME\fP, an older name, supported for compatibility)
followed by the deallocation of the list itself
with the allocation type \f(CWDW_DLA_LIST\fP when the descriptors are no
longer of interest.
.in +2
.FG "Examplel dwarf_get_types() obsolete"
.DS
\f(CW
void examplem(Dwarf_Debug dbg)
{
Dwarf_Error error = 0;
Dwarf_Signed count = 0;
Dwarf_Type *types = 0;
Dwarf_Signed i = 0;
int res = 0;
/* OBSOLETE: see dwarf_types_dealloc() above */
res = dwarf_get_types(dbg, &types,&count, &error);
if (res == DW_DLV_OK) {
for (i = 0; i < count; ++i) {
/* use types[i] */
dwarf_dealloc(dbg, types[i], DW_DLA_TYPENAME);
}
dwarf_dealloc(dbg, types, DW_DLA_LIST);
}
}
\fP
.DE
.in -2
.H 4 "dwarf_typename()"
.DS
\f(CWint dwarf_typename(
Dwarf_Type type,
char **return_name,
Dwarf_Error *error)\fP
.DE
The function \f(CWdwarf_typename()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*return_name\fP to
a pointer to a
null-terminated string that names the user-defined type represented by the
\f(CWDwarf_Type\fP descriptor, \f(CWtype\fP.
It returns \f(CWDW_DLV_ERROR\fP on error.
It never returns \f(CWDW_DLV_NO_ENTRY\fP.
On a successful return from this function, the string should
be freed using \f(CWdwarf_dealloc()\fP, with the allocation type
\f(CWDW_DLA_STRING\fP when no longer of interest.
.H 4 "dwarf_type_die_offset()"
.DS
\f(CWint dwarf_type_die_offset(
Dwarf_Type type,
Dwarf_Off *return_offset,
Dwarf_Error *error)\fP
.DE
The function \f(CWdwarf_type_die_offset()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP to
the offset in
the section containing DIEs, i.e. .debug_info, of the DIE representing
the user-defined type that is described by the \f(CWDwarf_Type\fP
descriptor, \f(CWtype\fP.
It returns \f(CWDW_DLV_ERROR\fP on error.
It never returns \f(CWDW_DLV_NO_ENTRY\fP.
.H 4 "dwarf_type_cu_offset()"
.DS
\f(CWint dwarf_type_cu_offset(
Dwarf_Type type,
Dwarf_Off *return_offset,
Dwarf_Error *error)\fP
.DE
The function \f(CWdwarf_type_cu_offset()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP to
the offset in
the section containing DIEs, i.e. .debug_info, of the compilation-unit
header of the compilation-unit that contains the user-defined type
described by the \f(CWDwarf_Type\fP descriptor, \f(CWtype\fP.
It returns \f(CWDW_DLV_ERROR\fP on error.
It never returns \f(CWDW_DLV_NO_ENTRY\fP.
.H 4 "dwarf_type_name_offsets()"
.DS
\f(CWint dwarf_type_name_offsets(
Dwarf_Type type,
char ** returned_name,
Dwarf_Off * die_offset,
Dwarf_Off * cu_offset,
Dwarf_Error *error)\fP
.DE
The function \f(CWdwarf_type_name_offsets()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*returned_name\fP to
a pointer to
a null-terminated string that gives the name of the user-defined
type described by the \f(CWDwarf_Type\fP descriptor \f(CWtype\fP.
It also returns in the locations
pointed to by \f(CWdie_offset\fP, and \f(CWcu_offset\fP, the offsets
of the DIE representing the
user-defined type, and the DIE
representing the compilation-unit containing the
user-defined type, respectively.
It returns \f(CWDW_DLV_ERROR\fP on error.
It never returns \f(CWDW_DLV_NO_ENTRY\fP.
On a successful return from \f(CWdwarf_type_name_offsets()\fP
the storage pointed to by \f(CWreturned_name\fP should
be freed using
\f(CWdwarf_dealloc()\fP, with the allocation type \f(CWDW_DLA_STRING\fP
when no longer of interest.
.H 3 "Accelerated Access varnames"
This section is SGI specific and is not part of standard DWARF.
.P
These functions operate on the .debug_varnames section of the debugging
information. The .debug_varnames section contains the names of file-scope
static variables, the offsets of the \f(CWDIE\fPs that represent the
definitions of those variables, and the offsets of the compilation-units
that contain the definitions of those variables.
.H 4 "dwarf_get_vars()"
.DS
\f(CWint dwarf_get_vars(
Dwarf_Debug dbg,
Dwarf_Var **vars,
Dwarf_Signed *var_count,
Dwarf_Error *error)\fP
.DE
The function \f(CWdwarf_get_vars()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*var_count\fP to
the count of file-scope
static variable names represented in the section containing file-scope
static variable names, i.e. .debug_varnames.
It also stores, at \f(CW*vars\fP, a pointer to a list of
\f(CWDwarf_Var\fP descriptors, one for each of the file-scope static
variable names in the .debug_varnames section.
The returned results are for the entire section.
It returns \f(CWDW_DLV_ERROR\fP on error.
It returns \f(CWDW_DLV_NO_ENTRY\fP if the .debug_varnames section does
not exist.
.P
The following is new as of July 15, 2005.
On a successful return
from \f(CWdwarf_get_vars()\fP, the \f(CWDwarf_Var\fP descriptors should be
freed using \f(CWdwarf_vars_dealloc()\fP.
.in +2
.FG "Examplen dwarf_get_vars()"
.DS
\f(CW
void examplen(Dwarf_Debug dbg)
{
Dwarf_Error error = 0;
Dwarf_Signed count = 0;
Dwarf_Var *vars = 0;
Dwarf_Signed i = 0;
int res = 0;
res = dwarf_get_vars(dbg, &vars,&count,&error);
if (res == DW_DLV_OK) {
for (i = 0; i < count; ++i) {
/* use vars[i] */
}
dwarf_vars_dealloc(dbg, vars, count);
}
}
\fP
.DE
.in -2
.P
The following code is deprecated as of July 15, 2005 as it does not
free all relevant memory.
This approach still works as well as it ever did.
On a successful return
from \f(CWdwarf_get_vars()\fP, the \f(CWDwarf_Var\fP descriptors should be individually
freed using \f(CWdwarf_dealloc()\fP with the allocation type
\f(CWDW_DLA_VAR_CONTEXT\fP,
(or
\f(CWDW_DLA_VAR\fP, an older name, supported for compatibility)
followed by the deallocation of the list itself with
the allocation type \f(CWDW_DLA_LIST\fP when the descriptors are no
longer of interest.
.in +2
.FG "Exampleo dwarf_get_vars() obsolete"
.DS
\f(CW
void exampleo(Dwarf_Debug dbg)
{
Dwarf_Error error = 0;
Dwarf_Signed count = 0;
Dwarf_Var *vars = 0;
Dwarf_Signed i = 0;
int res = 0;
res = dwarf_get_vars(dbg, &vars,&count,&error);
if (res == DW_DLV_OK) {
/* DO NOT USE: see dwarf_vars_dealloc() above */
for (i = 0; i < count; ++i) {
/* use vars[i] */
dwarf_dealloc(dbg, vars[i], DW_DLA_VAR);
}
dwarf_dealloc(dbg, vars, DW_DLA_LIST);
}
}
\fP
.DE
.in -2
.H 4 "dwarf_varname()"
.DS
\f(CWint dwarf_varname(
Dwarf_Var var,
char ** returned_name,
Dwarf_Error *error)\fP
.DE
The function \f(CWdwarf_varname()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*returned_name\fP to
a pointer to a
null-terminated string that names the file-scope static variable represented
by the \f(CWDwarf_Var\fP descriptor, \f(CWvar\fP.
It returns \f(CWDW_DLV_ERROR\fP on error.
It never returns \f(CWDW_DLV_NO_ENTRY\fP.
On a successful return from this function, the string should
be freed using \f(CWdwarf_dealloc()\fP, with the allocation type
\f(CWDW_DLA_STRING\fP when no longer of interest.
.H 4 "dwarf_var_die_offset()"
.DS
\f(CWint dwarf_var_die_offset(
Dwarf_Var var,
Dwarf_Off *returned_offset,
Dwarf_Error *error)\fP
.DE
The function \f(CWdwarf_var_die_offset()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*returned_offset\fP to
the offset in
the section containing DIEs, i.e. .debug_info, of the DIE representing
the file-scope static variable that is described by the \f(CWDwarf_Var\fP
descriptor, \f(CWvar\fP.
It returns \f(CWDW_DLV_ERROR\fP on error.
It never returns \f(CWDW_DLV_NO_ENTRY\fP.
.H 4 "dwarf_var_cu_offset()"
.DS
\f(CWint dwarf_var_cu_offset(
Dwarf_Var var,
Dwarf_Off *returned_offset,
Dwarf_Error *error)\fP
.DE
The function \f(CWdwarf_var_cu_offset()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*returned_offset\fP to
the offset in
the section containing DIEs, i.e. .debug_info, of the compilation-unit
header of the compilation-unit that contains the file-scope static
variable described by the \f(CWDwarf_Var\fP descriptor, \f(CWvar\fP.
It returns \f(CWDW_DLV_ERROR\fP on error.
It never returns \f(CWDW_DLV_NO_ENTRY\fP.
.H 4 "dwarf_var_name_offsets()"
.DS
\f(CWint dwarf_var_name_offsets(
Dwarf_Var var,
char **returned_name,
Dwarf_Off *die_offset,
Dwarf_Off *cu_offset,
Dwarf_Error *error)\fP
.DE
The function \f(CWdwarf_var_name_offsets()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*returned_name\fP to
a pointer to
a null-terminated string that gives the name of the file-scope
static variable described by the \f(CWDwarf_Var\fP descriptor \f(CWvar\fP.
It also returns in the locations
pointed to by \f(CWdie_offset\fP, and \f(CWcu_offset\fP, the offsets
of the DIE representing the
representing the compilation-unit containing the
file-scope static variable, respectively.
It returns \f(CWDW_DLV_ERROR\fP on error.
It never returns \f(CWDW_DLV_NO_ENTRY\fP.
On a successful return from
\f(CWdwarf_var_name_offsets()\fP the storage pointed to by
\f(CWreturned_name\fP
should be freed using \f(CWdwarf_dealloc()\fP, with the allocation
type
\f(CWDW_DLA_STRING\fP
when no longer of interest.
.H 2 "Names Fast Access (DWARF5) .debug_names"
The section
\f(CW.debug_names\fP
section is new in DWARF5 so a new set
of functions is defined to access this section.
This section replaces
\f(CW.debug_pubnames\fP
and
\f(CW.debug_pubtypes\fP
as those older sections were not found to be
useful in practice.
See also
\f(CWNames Fast Access .debug_gnu_pubnames\fP
.H 3 "dwarf_debugnames_header()"
.DS
\f(CWint dwarf_debugnames_header(
Dwarf_Debug dbg,
Dwarf_Dnames_Head * dn_out,
Dwarf_Unsigned * dn_index_count_out,
Dwarf_Error *error)\fP
.DE
.P
The function
\f(CWdwarf_debugnames_header()\fP
allocates an opaque data structure used
in all the other debugnames calls.
.P
Many of the function calls here let one
extract the entire content of the section,
which is useful if one wishes to dump the
section or to use its data to create one's
own internal data structures.
.P
To free space allocated when one has finished
with these data structures, call
.DS
Debug_Dnames_Head dn /* Assume set somehow */;
...
dwarf_dealloc(dbg,dn,DW_DLA_DNAMES_HEAD);
.DE
which will free up all data
allocated for
\f(CWdwarf_debugnames_header()\fP.
.P
On success the function returns
\f(CWDW_DLV_OK\fP
and returns a pointer
to the Head structure through
\f(CWdn_out\fP.
.P
It also returns the count of debugnames
entry in the debugnames index
through the
\f(CWdn_index_count_out\fP
value.
.P
It returns
\f(CWDW_DLV_NO_ENTRY\fP
if there is no
\f(CW.debug_names\fP
section.
.P
It returns
\f(CWDW_DLV_ERROR\fP
if there is an internal
error such as data corruption
in the section.
.H 3 " dwarf_debugnames_sizes()"
.DS
\f(CW int dwarf_debugnames_sizes(Dwarf_Dnames_Head dn,
Dwarf_Unsigned index_number,
Dwarf_Unsigned * section_offsets,
Dwarf_Unsigned * version,
Dwarf_Unsigned * offset_size,
/* The counts are entry counts, not byte sizes. */
Dwarf_Unsigned * comp_unit_count,
Dwarf_Unsigned * local_type_unit_count,
Dwarf_Unsigned * foreign_type_unit_count,
Dwarf_Unsigned * bucket_count,
Dwarf_Unsigned * name_count,
/* The following are counted in bytes */
Dwarf_Unsigned * indextable_overall_length,
Dwarf_Unsigned * abbrev_table_size,
Dwarf_Unsigned * entry_pool_size,
Dwarf_Unsigned * augmentation_string_size,
Dwarf_Error * error*/)\fP
.DE
.P
Given a properly created
head
\f(CWdn\fP
this
Allows access to fields a
\f(CW.debug_names\fP
\f(CWDWARF5\fP
header record
\f(CWindex_number\fP.
.P
We will not describe the fields in detail
here.
See the
\f(CWDWARF5\fP
standard and
\f(CWdwarfdump\fP
for the motivation of this function.
.H 3 " dwarf_debugnames_cu_entry()"
.DS
\f(CW int dwarf_debugnames_cu_entry(
Dwarf_Dnames_Head dn,
Dwarf_Unsigned index_number,
Dwarf_Unsigned offset_number,
Dwarf_Unsigned * offset_count,
Dwarf_Unsigned * offset,
Dwarf_Error * error)\fP
.DE
Given a properly created
head
\f(CWdn\fP
this
Allows access to fields in
cu entry
\f(CWindex_number\fP
from
a
\f(CW.debug_names\fP
\f(CWDWARF5\fP
Compilation Unit
entry.
.P
We will not describe the fields in detail
here.
See the
\f(CWDWARF5\fP
standard and
\f(CWdwarfdump\fP
for the motivation of this function.
.H 3 " dwarf_debugnames_local_tu_entry()"
.DS
\f(CW int dwarf_debugnames_local_tu_entry(
Dwarf_Dnames_Head dn,
Dwarf_Unsigned index_number,
Dwarf_Unsigned offset_number,
Dwarf_Unsigned * offset_count,
Dwarf_Unsigned * offset,
Dwarf_Error * error)
\fP
.DE
.P
The same as
\f(CWdwarf_debugnames_cu_entry()\fP
but referencing type unit fields.
.H 3 " dwarf_debugnames_foreign_tu_entry()"
.DS
\f(CW int dwarf_debugnames_foreign_tu_entry(
Dwarf_Dnames_Head dn,
Dwarf_Unsigned index_number,
Dwarf_Unsigned sig_number,
Dwarf_Unsigned * sig_minimum,
Dwarf_Unsigned * sig_count,
Dwarf_Sig8 * signature,
Dwarf_Error * error)
\fP
.DE
Allows retrieving the data
for foreign type-unit entries.
.H 3 " dwarf_debugnames_bucket()"
.DS
\f(CW int dwarf_debugnames_bucket(
Dwarf_Dnames_Head dn,
Dwarf_Unsigned index_number,
Dwarf_Unsigned bucket_number,
Dwarf_Unsigned * bucket_count,
Dwarf_Unsigned * index_of_name_entry,
Dwarf_Error * error)
\fP
.DE
Allows retrieving the data
for hash buckets.
.H 3 " dwarf_debugnames_name()"
.DS
\f(CW int dwarf_debugnames_bucket(
Dwarf_Dnames_Head dn,
Dwarf_Unsigned index_number,
Dwarf_Unsigned name_entry,
Dwarf_Unsigned * names_count,
Dwarf_Sig8 * signature,
Dwarf_Unsigned * offset_to_debug_str,
Dwarf_Unsigned * offset_in_entrypool,
Dwarf_Error * error)
\fP
.DE
Allows retrieving the data
about names and signatures.
.H 3" dwarf_debugnames_abbrev_by_index()"
.DS
\f(CW int dwarf_debugnames_abbrev_by_index(
Dwarf_Dnames_Head dn,
Dwarf_Unsigned index_number,
Dwarf_Unsigned abbrev_entry,
Dwarf_Unsigned * abbrev_code,
Dwarf_Unsigned * tag,
Dwarf_Unsigned * number_of_abbrev,
Dwarf_Unsigned * number_of_attr_form_entries,
Dwarf_Error * error)
\fP
.DE
Allows retrieving the abbreviations
from a portion of the
section by index.
.H 3 " dwarf_debugnames_abbrev_by_code()"
.DS
\f(CW int dwarf_debugnames_abbrev_by_code(
Dwarf_Dnames_Head dn,
Dwarf_Unsigned index_number,
Dwarf_Unsigned abbrev_code,
Dwarf_Unsigned * tag,
Dwarf_Unsigned * index_of_abbrev,
Dwarf_Unsigned * index_of_attr_form_entries,
Dwarf_Error * error)
\fP
.DE
Allows retrieving the abbreviations
from a portion of the
section by abbrev-code.
.H 3 " dwarf_debugnames_form_by_index()"
.DS
\f(CW int dwarf_debugnames_form_by_index(
Dwarf_Dnames_Head dn,
Dwarf_Unsigned index_number,
Dwarf_Unsigned abbrev_entry_index,
Dwarf_Unsigned abbrev_form_index,
Dwarf_Unsigned * name_attr_index,
Dwarf_Unsigned * form,
Dwarf_Unsigned * number_of_attr_form_entries,
Dwarf_Error * error)
\fP
.DE
Allows retrieving the abbreviations
forms
from a portion of the
section by index.
.H 3 " dwarf_debugnames_entrypool()"
.DS
\f(CW int dwarf_debugnames_entrypool(
Dwarf_Dnames_Head dn,
Dwarf_Unsigned index_number,
Dwarf_Unsigned offset_in_entrypool,
Dwarf_Unsigned * abbrev_code,
Dwarf_Unsigned * tag,
Dwarf_Unsigned * value_count,
Dwarf_Unsigned * index_of_abbrev,
Dwarf_Unsigned * offset_of_initial_value,
Dwarf_Error * error)
\fP
.DE
Allows retrieving the
data from a portion of the entrypool
by index and offset.
.H 3 " dwarf_debugnames_entrypool_values()"
.DS
\f(CW int dwarf_debugnames_entrypool_values(
Dwarf_Dnames_Head dn,
Dwarf_Unsigned index_number,
Dwarf_Unsigned index_of_abbrev,
Dwarf_Unsigned offset_in_entrypool_of_values,
Dwarf_Unsigned * array_dw_idx_number,
Dwarf_Unsigned * array_form,
Dwarf_Unsigned * array_of_offsets,
Dwarf_Sig8 * array_of_signatures,
Dwarf_Error * error)
\fP
.DE
Allows retrieving detailed
data from a portion of the entrypool
by index and offset.
.H 2 "Names Fast Access .debug_gnu_pubnames"
The sections
\f(CW.debug_gnu_pubnames\fP
and
\f(CW.debug_gnu_pubtypes\fP
are non-standard sections emitted by
gcc and clang with DWARF5.
Typically they will be in the skeleton
executable and the split dwarf section
\f(CW.debug_info.dwo\fP
will have the actual
DWARF the offsets refer to,
These sections would normally be read
once by a program wanting them and
filed in an internal format and
then the program would do the cleanup
\f(CWdwarf_gnu_index_dealloc()\fP.
.P
Each section is divided into what
we term blocks here and within
each block there is an array of entries.
The functions below enable access.
.H 3 "dwarf_get_gnu_index_head()"
.DS
\f(CWint dwarf_get_gnu_index_head(
Dwarf_Debug dbg,
/* The following arg false to select gnu_pubtypes */
Dwarf_Bool for_gdb_pubnames ,
Dwarf_Gnu_Index_Head * head,
Dwarf_Unsigned * index_block_count,
Dwarf_Error * error); \fP
.DE
This creates an open header to use
in subsequent data access.
Free the memory associated with this
by calling
\f(CWdwarf_gnu_index_dealloc(head)\fP.
\f(CW
\fP
.P
The field
\f(CWindex_block_count\fP
is set through the pointer to the
number of blocks in the section.
Call
\f(CWdwarf_get_gnu_index_block()\fP
and pass in valid block number
(zero thrugh index_block_count-1)
to get
block information.
.P
If the section does not exist or is empty
it returns
\f(CWDW_DLV_NO_ENTRY\fP
and does nothing else.
.P
If there is data corruption
or some serious error it returns
\f(CWDW_DLV_ERROR\fP
and sets the error pointer with
information about the error.
\f(CW
\fP
.H 3 "dwarf_gnu_index_dealloc()"
.DS
\f(CWvoid dwarf_gnu_index_dealloc(
Dwarf_Gnu_Index_Head index_head);
.DE
This frees all data associated with the section.
.H 3 "dwarf_get_gnu_index_block()"
.DS
\f(CWint dwarf_get_gnu_index_block(
Dwarf_Gnu_Index_Head head,
Dwarf_Unsigned blocknumber,
Dwarf_Unsigned * block_length,
Dwarf_Half * version ,
Dwarf_Unsigned * offset_into_debug_info,
Dwarf_Unsigned * size_of_debug_info_area,
Dwarf_Unsigned * count_of_index_entries,
Dwarf_Error * error); \fP
.DE
On success this returns
\f(CWDW_DLV_OK\fP
and fills in the various fields through
the pointers.
If the pointer to a field is null
the function ignores that field.
.P
The field
\f(CWblock_length\fP
has the byte length of the block (with its entries).
.P
The field
\f(CWversion\fP
has the version number.
Currently it must be 2.
.P
The field
\f(CWoffsetinto_debug_info\fP
is the offset (in some .debug_info
or .debug_info.owo section) of
a Compilation Unit Header.
.P
The field
\f(CWsize_of_debug_info_area\fP
is the size of the referenced
compilation unit.
.P
The field
\f(CWcount_of_index_entries\fP
is the number of entries
attached to the block.
See \f(CWdwarf_get_gnu_index_block_entry()\fP.
.P
If the block number is outside the valid range
(zero through
\f(CWindex_block_count\fP -1)
it returns
\f(CWDW_DLV_NO_ENTRY\fP
and does nothing.
.P
If there is data corruption
or some serious error it returns
\f(CWDW_DLV_ERROR\fP
and sets the error pointer with
information about the error.
.H 3 "dwarf_get_gnu_index_block_entry()"
.DS
\f(CWint dwarf_get_gnu_index_block_entry(
Dwarf_Gnu_Index_Head head,
Dwarf_Unsigned blocknumber,
Dwarf_Unsigned entrynumber,
Dwarf_Unsigned * offset_in_debug_info
const char ** name,
unsigned char * flagbyte,
unsigned char * staticorglobal,
unsigned char * typeofentry,
Dwarf_Error * error); \fP
.DE
If either
\f(CWblocknumber\fP
or
\f(CWentrynumber\fP
is outside the range of valid values
it returns
\f(CWDW_DLV_NO_ENTRY\fP
and does nothing.
.P
On success it returns
\f(CWDW_DLV_OK\fP
and sets information about each entry
through the pointers.
Any pointers pased in as NULL are ignored.
.P
The field
\f(CWoffset_in_debug_info\fP
has the offset of DIE in
a .debug_info section.
.P
The field
\f(CWname\fP
has a pointer to the name of the variable
or function that the DIE refers to.
.P
The field
\f(CWflagbyte\fP
has the entire 8 bits
of a byte that has two useful fields.
The next two fields are those useful fields.
.P
The field
\f(CWstaticorglobal\fP
has an integer 0
if the DIE involved describes
a global (externally-visble)
name.
It has an integer 1
if the name refers to a static (file-local)
DIE.
.P
The field
\f(CWtypeofentry\fP
has a small integer describing the type.
Zero means the type is "none".
One means the type is "type".
Two means the type is "variable".
Three means the type is "function".
Four means the type is "other".
Any other value has, apparently,
no assigned meaning.
.P
If there is data corruption
or some serious error it returns
\f(CWDW_DLV_ERROR\fP
and sets the error pointer with
information about the error.
.H 2 "Macro Information Operations (DWARF4, DWARF5)"
This section refers to DWARF4 and later
macro information from the .debug_macro
section (for DWARF 4 some producers
generated .debug_macro before its formal
standardization in DWARF 5).
While standard operations are supported there
is as yet no support for implementation-defined
extensions.
Once someone has defined such things it will
make sense to design an interface for extensions.
.H 3 "Getting access"
The opaque struct pointer Dwarf_Macro_Context
is allocated by either
\f(CWdwarf_get_macro_context()\fP
or
\f(CWdwarf_get_macro_context_by_offset()\fP
and once the context is no longer needed
one frees up all its storage by
\f(CWdwarf_dealloc_macro_context()\fP.
.H 4 "dwarf_get_macro_context()"
.DS
\f(CWint dwarf_get_macro_context(Dwarf_Die die,
Dwarf_Unsigned * version_out,
Dwarf_Macro_Context * macro_context,
Dwarf_Unsigned * macro_unit_offset_out,
Dwarf_Unsigned * macro_ops_count_out,
Dwarf_Unsigned * macro_ops_data_length_out,
Dwarf_Error * error);\fP
.DE
Given a Compilation Unit (CU) die,
on success
\f(CWdwarf_get_macro_context()\fP
opens a
\f(CWDwarf_Macro_Context\fP
and returns a pointer to it and some data from the
macro unit for that CU.
The \f(CWDwarf_Macro_Context\fP
is used to get at the details of the macros.
.P
The value
\f(CWversion_out\fP
is set to the DWARF version number of the macro data.
Version 5 means DWARF5 version information. Version 4
means the DWARF5 format macro data is present as an
extension of DWARF4.
.P
The value
\f(CWmacro_unit_offset_out\fP
is set to the offset in the .debug_macro section
of the first byte of macro data for this CU.
.P
The value
\f(CWmacro_ops_count_out\fP
is set to the number of macro entries in the macro data
data for this CU.
The count includes the final zero entry (which is not
really a macro, it is a terminator, a zero byte ending
the macro unit).
.P
The value
\f(CWmacro_ops_data_length_out\fP
is set to the number of bytes of data in the macro unit,
including the macro unit header.
.P
If
\f(CWDW_DLV_NO_ENTRY\fP
is returned the CU has no macro data attribute or
there is no .debug_macro section present.
.P
On error
\f(CWDW_DLV_ERROR\fP
is returned and
the error details are returned through the pointer
\f(CWerror\fP.
.H 4 "dwarf_get_macro_context_by_offset()"
.DS
\f(CWint dwarf_get_macro_context_by_offset(Dwarf_Die die,
Dwarf_Unsigned offset,
Dwarf_Unsigned * version_out,
Dwarf_Macro_Context * macro_context,
Dwarf_Unsigned * macro_ops_count_out,
Dwarf_Unsigned * macro_ops_total_byte_len,
Dwarf_Error * error);\fP
.DE
Given a Compilation Unit (CU) die and
the offset of an imported macro unit
\f(CWdwarf_get_macro_context_by_offset()\fP
opens a
\f(CWDwarf_Macro_Context\fP
and returns a pointer to it and some data from the
macro unit for that CU on success.
.P
On success
the function produces the same output values as
\f(CWdwarf_get_macro_context()\fP
except there is no offset returned (
the caller provides it).
.P
If
\f(CWDW_DLV_NO_ENTRY\fP
is returned there is no .debug_macro section present.
.P
On error
\f(CWDW_DLV_ERROR\fP
is returned and
the error details are returned through the pointer
\f(CWerror\fP.
.H 4 "dwarf_dealloc_macro_context()"
.DS
\f(CWvoid dwarf_dealloc_macro_context(Dwarf_Macro_Context macro_context);\fP
.DE
The function
\f(CWdwarf_dealloc_macro_context()\fP
cleans up memory allocated by a successful
call to
\f(CWdwarf_get_macro_context()\fP
or
\f(CWdwarf_get_macro_context_by_offset()\fP.
.in +2
.FG "Examplep5 dwarf_dealloc_macro_context()"
.DS
\f(CW
/* This builds an list or some other data structure
(not defined) to give an import somewhere to list
the import offset and then later to enquire
if the list has unexamined offsets.
A candidate set of hypothetical functions that
callers would write:
has_unchecked_import_in_list()
get_next_import_from_list()
mark_this_offset_as_examined(macro_unit_offset);
add_offset_to_list(offset);
*/
void examplep5(Dwarf_Debug dbg, Dwarf_Die cu_die)
{
int lres = 0;
Dwarf_Unsigned version = 0;
Dwarf_Macro_Context macro_context = 0;
Dwarf_Unsigned macro_unit_offset = 0;
Dwarf_Unsigned number_of_ops = 0;
Dwarf_Unsigned ops_total_byte_len = 0;
Dwarf_Bool is_primary = TRUE;
unsigned k = 0;
Dwarf_Error err = 0;
for(;;) {
if (is_primary) {
lres = dwarf_get_macro_context(cu_die,
&version,¯o_context,
¯o_unit_offset,
&number_of_ops,
&ops_total_byte_len,
&err);
is_primary = FALSE;
} else {
if (has_unchecked_import_in_list()) {
macro_unit_offset = get_next_import_from_list();
} else {
/* We are done */
break;
}
lres = dwarf_get_macro_context_by_offset(cu_die,
macro_unit_offset,
&version,
¯o_context,
&number_of_ops,
&ops_total_byte_len,
&err);
mark_this_offset_as_examined(macro_unit_offset);
}
if (lres == DW_DLV_ERROR) {
/* Something is wrong. */
return;
}
if (lres == DW_DLV_NO_ENTRY) {
/* We are done. */
break;
}
/* lres == DW_DLV_OK) */
for (k = 0; k < number_of_ops; ++k) {
Dwarf_Unsigned section_offset = 0;
Dwarf_Half macro_operator = 0;
Dwarf_Half forms_count = 0;
const Dwarf_Small *formcode_array = 0;
Dwarf_Unsigned line_number = 0;
Dwarf_Unsigned index = 0;
Dwarf_Unsigned offset =0;
const char * macro_string =0;
int lres = 0;
lres = dwarf_get_macro_op(macro_context,
k, §ion_offset,¯o_operator,
&forms_count, &formcode_array,&err);
if (lres != DW_DLV_OK) {
print_error(dbg,
"ERROR from dwarf_get_macro_op()",
lres,err);
dwarf_dealloc_macro_context(macro_context);
return;
}
switch(macro_operator) {
case 0:
/* Nothing to do. This
sigifies it is the end-marker,
standing in for the 0 byte
at the end of his macro group. */
break;
case DW_MACRO_end_file:
/* Do something */
break;
case DW_MACRO_define:
case DW_MACRO_undef:
case DW_MACRO_define_strp:
case DW_MACRO_undef_strp:
case DW_MACRO_define_strx:
case DW_MACRO_undef_strx:
case DW_MACRO_define_sup:
case DW_MACRO_undef_sup: {
lres = dwarf_get_macro_defundef(macro_context,
k,
&line_number,
&index,
&offset,
&forms_count,
¯o_string,
&err);
if (lres != DW_DLV_OK) {
print_error(dbg,
"ERROR from sup dwarf_get_macro_defundef()",
lres,err);
dwarf_dealloc_macro_context(macro_context);
return;
}
/* do something */
}
break;
case DW_MACRO_start_file: {
lres = dwarf_get_macro_startend_file(macro_context,
k,&line_number,
&index,
¯o_string,&err);
if (lres != DW_DLV_OK) {
print_error(dbg,
"ERROR from dwarf_get_macro_startend_file()(sup)",
lres,err);
dwarf_dealloc_macro_context(macro_context);
return;
}
/* do something */
}
break;
case DW_MACRO_import: {
lres = dwarf_get_macro_import(macro_context,
k,&offset,&err);
if (lres != DW_DLV_OK) {
print_error(dbg,
"ERROR from dwarf_get_macro_import()(sup)",
lres,err);
dwarf_dealloc_macro_context(macro_context);
return;
}
add_offset_to_list(offset);
}
break;
case DW_MACRO_import_sup: {
lres = dwarf_get_macro_import(macro_context,
k,&offset,&err);
if (lres != DW_DLV_OK) {
print_error(dbg,
"ERROR from dwarf_get_macro_import()(sup)",
lres,err);
dwarf_dealloc_macro_context(macro_context);
return;
}
/* do something */
}
break;
}
}
dwarf_dealloc_macro_context(macro_context);
macro_context = 0;
}
}
\fP
.DE
.in -2
.H 3 "Getting Macro Unit Header Data"
.H 4 "dwarf_macro_context_head()"
.DS
\f(CWint dwarf_macro_context_head(Dwarf_Macro_Context macro_context,
Dwarf_Half * version,
Dwarf_Unsigned * mac_offset,
Dwarf_Unsigned * mac_len,
Dwarf_Unsigned * mac_header_len,
unsigned * flags,
Dwarf_Bool * has_line_offset,
Dwarf_Unsigned * line_offset,
Dwarf_Bool * has_offset_size_64,
Dwarf_Bool * has_operands_table,
Dwarf_Half * opcode_count,
Dwarf_Error * error); \fP
.DE
Given a
\f(CWDwarf_Macro_Context\fP
pointer this function returns the basic fields
of a macro unit header (Macro Information Header)
on success.
.P
The value
\f(CWversion\fP
is set to the DWARF version number of the macro unit header.
Version 5 means DWARF5 version information. Version 4
means the DWARF5 format macro data is present as an
extension of DWARF4.
.P
The value
\f(CWmac_offset\fP
is set to the offset in the .debug_macro section
of the first byte of macro data for this CU.
.P
The value
\f(CWmac_len\fP
is set to the number of bytes of data in the macro unit,
including the macro unit header.
.P
The value
\f(CWmac_header_len\fP
is set to the number of bytes in the macro unit header
(not a field that is generally useful).
.P
The value
\f(CWflags\fP
is set to the value of the
\f(CWflags\fP
field of the macro unit header.
.P
The value
\f(CWhas_line_offset\fP
is set to non-zero if the
\f(CWdebug_line_offset_flag\fP
bit is set in the
\f(CWflags\fP
field of the macro unit header.
If
\f(CWhas_line_offset\fP
is set then
\f(CWline_offset\fP
is set to the value of the
\f(CWdebug_line_offset\fP
field in the macro unit header.
If
\f(CWhas_line_offset\fP
is not set there is no
\f(CWdebug_line_offset\fP
field present in the
macro unit header.
.P
The value
\f(CWhas_offset_size_64\fP
is set non-zero if the
\f(CWoffset_size_flag\fP
bit is set in the
\f(CWflags\fP
field of the macro unit header and in this
case offset fields in this macro unit are
64 bits.
If
\f(CWhas_offset_size_64\fP
is not set then
offset fields in this macro unit are
32 bits.
.P
The value
\f(CWhas_operands_table\fP
is set to non-zero if the
\f(CWopcod_operands_table_flag\fP
bit is set in the
\f(CWflags\fP
field of the macro unit header.
.P
If
\f(CWhas_operands_table\fP
is set non-zero then
The value
\f(CWopcode_count\fP
is set to the number of opcodes
in the macro unit header
\f(CWopcode_operands_table\fP.
See
\f(CWdwarf_get_macro_op()\fP.
.P
\f(CWDW_DLV_NO_ENTRY\fP
is not returned.
.P
On error
\f(CWDW_DLV_ERROR\fP
is returned and
the error details are returned through the pointer
\f(CWerror\fP.
.H 4 "dwarf_macro_operands_table()"
.DS
\f(CWint dwarf_macro_operands_table(Dwarf_Macro_Context macro_context,
Dwarf_Half index, /* 0 to opcode_count -1 */
Dwarf_Half * opcode_number,
Dwarf_Half * operand_count,
const Dwarf_Small ** operand_array,
Dwarf_Error * error); \fP
.DE
\f(CWdwarf_macro_operands_table()\fP
is used to index through the operands table
in a macro unit header if the operands
table exists in the macro unit header.
The operands table provides the mechanism
for implementations to add extensions
to the macro operations while allowing
clients to skip macro operations the
client code does not recognize.
.P
The
\f(CWmacro_context\fP
field passed in identifies the macro unit involved.
The
\f(CWindex\fP
field passed in identifies which macro operand to
look at. Valid index values are
zero through
the
\f(CWopcode_count\fP-1
(returned by
\f(CWdwarf_macro_context_head()\fP).
.P
The
\f(CWopcode_number\fP
value returned through the pointer is
the the macro operation code.
The operation code could be one of the
standard codes or if there are user extensions
there would be an extension code in the
\f(CWDW_MACRO_lo_user\fP
to
\f(CWDW_MACRO_hi_user\fP
range.
.P
The
\f(CWoperand_count\fP
returned
is the number of form codes in the form codes
array of unsigned bytes
\f(CWoperand_array\fP.
.P
\f(CWDW_DLV_NO_ENTRY\fP
is not returned.
.P
On error
\f(CWDW_DLV_ERROR\fP
is returned and
the error details are returned through the pointer
\f(CWerror\fP.
.H 3 "Getting Individual Macro Operations Data"
.H 4 "dwarf_get_macro_op()"
.DS
\f(CWint dwarf_get_macro_op(Dwarf_Macro_Context macro_context,
Dwarf_Unsigned op_number,
Dwarf_Unsigned * op_start_section_offset,
Dwarf_Half * macro_operator,
Dwarf_Half * forms_count,
const Dwarf_Small ** formcode_array,
Dwarf_Error * error);\fP
.DE
Use
\f(CWdwarf_get_macro_op()\fP
to access the macro operations of this macro unit.
.P
The
\f(CWmacro_context\fP
field passed in identifies the macro unit involved.
The
\f(CWop_number\fP
field passed in identifies which macro operand to
look at. Valid index values are
zero through
\f(CWmacro_ops_count_out\fP-1
(field returned by
\f(CWdwarf_get_macro_context()\fP
or
\f(CWdwarf_get_macro_context_by_offset()\fP)
.P
On success the function returns values
through the pointers.
.P
If
\f(CWmacro_operator\fP
returned is zero that means this
is a placeholder for the null byte
at the end of this array of macros.
The other pointer values returned
are also zero in this case.
.P
The
\f(CWop_start_section_offset\fP
returned is useful for debugging
but otherwise is not normally useful.
It is the byte offset of the beginning
of this macro operator's data.
.P
The
\f(CWmacro_operator\fP
returned is one of the defined
macro operations such as
\f(CWDW_MACRO_define\fP.
This is the field you will use to
choose what call to use to get the
data for a macro operator.
For example, for
\f(CWDW_MACRO_undef\fP
one would call
\f(CWdwarf_get_macro_defundef()\fP
(see below)
to get the details about the undefine.
.P
The
\f(CWforms_count\fP
returned is useful for debugging
but otherwise is not normally useful.
It is the number of bytes of form numbers
in the
\f(CWformcode_array\fP
of this macro operator's applicable forms.
.P
\f(CWDW_DLV_NO_ENTRY\fP
is not returned.
.P
On error
\f(CWDW_DLV_ERROR\fP
is returned and
the error details are returned through the pointer
\f(CWerror\fP.
.H 4 "dwarf_get_macro_defundef()"
.DS
\f(CWint dwarf_get_macro_defundef(Dwarf_Macro_Context macro_context,
Dwarf_Unsigned op_number,
Dwarf_Unsigned * line_number,
Dwarf_Unsigned * index,
Dwarf_Unsigned * offset,
Dwarf_Half * forms_count,
const char ** macro_string,
Dwarf_Error * error);\fP
.DE
Call
\f(CWdwarf_get_macro_defundef\fP for
any of the macro define/undefine operators.
Which fields are set through the pointers
depends on the particular operator.
.P
The
\f(CWmacro_context\fP
field passed in identifies the macro unit involved.
The
\f(CWop_number\fP
field passed in identifies which macro operand to
look at. Valid index values are
zero through
\f(CWmacro_ops_count_out\fP-1
(field returned by
\f(CWdwarf_get_macro_context()\fP
or
\f(CWdwarf_get_macro_context_by_offset()\fP).
.P
The
\f(CWline_number\fP
field is set with the source line number of the macro.
.P
The
\f(CWindex\fP
field only set meaningfully if the macro operator is
\f(CWDW_MACRO_define_strx\fP
or
\f(CWDW_MACRO_undef_strx\fP.
If set it is an index into an array of offsets in the .debug_str_offsets
section.
.P
The
\f(CWoffset\fP
field only set meaningfully if the macro operator is
\f(CWDW_MACRO_define_strx\fP,
\f(CWDW_MACRO_undef_strx\fP
\f(CWDW_MACRO_define_strp\fP,
or
\f(CWDW_MACRO_undef_strp\fP
If set it is an offset of a string in the .debug_str section.
.P
The
\f(CWforms_count\fP
is set to the number of forms
that apply to the macro operator.
.P
The
\f(CWmacro_string\fP
pointer is used to return a pointer to
the macro string.
If the actual string cannot be found
(as when section with the string is in
a different object, see
\f(CWset_tied_dbg()\fP)
the string returned may be
"<:No string available>"
or
"<.debug_str_offsets not available>"
(without the quotes).
.P
The function returns
\f(CWDW_DLV_NO_ENTRY\fP
if the macro operation is not
one of the define/undef
operations.
.P
On error
\f(CWDW_DLV_ERROR\fP
is returned and
the error details are returned through the pointer
\f(CWerror\fP.
.H 4 "dwarf_get_macro_startend_file()"
.DS
\f(CWint dwarf_get_macro_startend_file(Dwarf_Macro_Context macro_context,
Dwarf_Unsigned op_number,
Dwarf_Unsigned * line_number,
Dwarf_Unsigned * name_index_to_line_tab,
const char ** src_file_name,
Dwarf_Error * error);\fP
.DE
Call
\f(CWdwarf_get_macro_startend_file\fP for
operators
\f(CWDW_MACRO_start_file\fP
or
\f(CWDW_MACRO_end_file\fP.
.P
The
\f(CWmacro_context\fP
field passed in identifies the macro unit involved.
.P
The
\f(CWop_number\fP
field passed in identifies which macro operand to
look at. Valid index values are
zero through
\f(CWmacro_ops_count_out\fP-1
(field returned by
\f(CWdwarf_get_macro_context()\fP
or
\f(CWdwarf_get_macro_context_by_offset()\fP)
.P
For
\f(CWDW_MACRO_end_file\fP
none of the following fields are set
on successful return, they are only
set for.
\f(CWDW_MACRO_start_file\fP
.P
The
\f(CWline_number\fP
field is set with the source line number of the macro.
.P
.P
The
\f(CWname_index_to_line_tab\fP
field is set with the index into the
file name table of the line table section.
For DWARF2, DWARF3, DWARF4 line tables
the index value assumes DWARF2 line table header rules
(identical to DWARF3, DWARF4 line table header rules).
For DWARF5
the index value assumes DWARF5 line table header rules.
The
\f(CWsrc_file_name\fP
is set with the source file name.
If the index seems wrong or
the line table is unavailable
the name returned is "<no-source-file-name-available>");
.P
The function returns
\f(CWDW_DLV_NO_ENTRY\fP
if the macro operation is not
one of the start/end
operations.
.P
On error
\f(CWDW_DLV_ERROR\fP
is returned and
the error details are returned through the pointer
\f(CWerror\fP.
.H 4 "dwarf_get_macro_import()"
.DS
\f(CWint dwarf_get_macro_import(Dwarf_Macro_Context macro_context,
Dwarf_Unsigned op_number,
Dwarf_Unsigned * target_offset,
Dwarf_Error * error);\fP
.DE
Call
\f(CWdwarf_get_macro_import\fP for
operators
\f(CWDW_MACRO_import\fP
or
\f(CWDW_MACRO_import_sup\fP.
.P
The
\f(CWmacro_context\fP
field passed in identifies the macro unit involved.
The
\f(CWop_number\fP
field passed in identifies which macro operand to
look at. Valid index values are
zero through
\f(CWmacro_ops_count_out\fP-1
(field returned by
\f(CWdwarf_get_macro_context()\fP
or
\f(CWdwarf_get_macro_context_by_offset()\fP)
.P
On success the
\f(CWtarget_offset\fP
field is set to the
offset in the referenced section.
For DW_MACRO_import the referenced section is
the same section as the macro operation referenced here.
For DW_MACRO_import_sup the referenced section is
in a supplementary object.
.P
The function returns
\f(CWDW_DLV_NO_ENTRY\fP
if the macro operation is not
one of the import
operations.
.P
On error
\f(CWDW_DLV_ERROR\fP
is returned and
the error details are returned through the pointer
\f(CWerror\fP.
.H 2 "Macro Information Operations (DWARF2, DWARF3, DWARF4)"
This section refers to DWARF2,DWARF3,and DWARF4
macro information from the .debug_macinfo
section. These do not apply to DWARF5
macro data.
.H 3 "General Macro Operations"
.H 4 "dwarf_find_macro_value_start()"
.DS
\f(CWchar *dwarf_find_macro_value_start(char * macro_string);\fP
.DE
Given a macro string in the standard form defined in the DWARF
document ("name <space> value" or "name(args)<space>value")
this returns a pointer to the first byte of the macro value.
It does not alter the string pointed to by macro_string or copy
the string: it returns a pointer into the string whose
address was passed in.
.H 3 "Debugger Interface Macro Operations"
Macro information is accessed from the .debug_info section via the
DW_AT_macro_info attribute (whose value is an offset into .debug_macinfo).
.P
No Functions yet defined.
.H 3 "Low Level Macro Information Operations"
.H 4 "dwarf_get_macro_details()"
.DS
\f(CWint dwarf_get_macro_details(Dwarf_Debug /*dbg*/,
Dwarf_Off macro_offset,
Dwarf_Unsigned maximum_count,
Dwarf_Signed * entry_count,
Dwarf_Macro_Details ** details,
Dwarf_Error * err);\fP
.DE
\f(CWdwarf_get_macro_details()\fP
returns
\f(CWDW_DLV_OK\fP and sets
\f(CWentry_count\fP to the number of \f(CWdetails\fP records
returned through the \f(CWdetails\fP pointer.
The data returned through \f(CWdetails\fP should be freed
by a call to \f(CWdwarf_dealloc()\fP with the allocation type
\f(CWDW_DLA_STRING\fP.
If \f(CWDW_DLV_OK\fP is returned, the \f(CWentry_count\fP will
be at least 1, since
a compilation unit with macro information but no macros will
have at least one macro data byte of 0.
.P
\f(CWdwarf_get_macro_details()\fP
begins at the \f(CWmacro_offset\fP offset you supply
and ends at the end of a compilation unit or at \f(CWmaximum_count\fP
detail records (whichever comes first).
If \f(CWmaximum_count\fP is 0, it is treated as if it were the maximum
possible unsigned integer.
.P
\f(CWdwarf_get_macro_details()\fP
attempts to set \f(CWdmd_fileindex\fP to the correct file in every
\f(CWdetails\fP record. If it is unable to do so (or whenever
the current file index is unknown, it sets \f(CWdmd_fileindex\fP
to -1.
.P
\f(CWdwarf_get_macro_details()\fP returns \f(CWDW_DLV_ERROR\fP on error.
It returns \f(CWDW_DLV_NO_ENTRY\fP if there is no more
macro information at that \f(CWmacro_offset\fP. If \f(CWmacro_offset\fP
is passed in as 0, a \f(CWDW_DLV_NO_ENTRY\fP return means there is
no macro information.
.P
.in +2
.FG "Examplep2 dwarf_get_macro_details()"
.DS
\f(CW
void examplep2(Dwarf_Debug dbg, Dwarf_Off cur_off)
{
Dwarf_Error error = 0;
Dwarf_Signed count = 0;
Dwarf_Macro_Details *maclist = 0;
Dwarf_Signed i = 0;
Dwarf_Unsigned max = 500000; /* sanity limit */
int errv = 0;
/* Given an offset from a compilation unit,
start at that offset (from DW_AT_macroinfo)
and get its macro details. */
errv = dwarf_get_macro_details(dbg, cur_off,max,
&count,&maclist,&error);
if (errv == DW_DLV_OK) {
for (i = 0; i < count; ++i) {
Dwarf_Macro_Details * mentry = maclist +i;
/* example of use */
Dwarf_Signed lineno = mentry->dmd_lineno;
functionusingsigned(lineno);
}
dwarf_dealloc(dbg, maclist, DW_DLA_STRING);
}
/* Loop through all the compilation units macro info from zero.
This is not guaranteed to work because DWARF does not
guarantee every byte in the section is meaningful:
there can be garbage between the macro info
for CUs. But this loop will sometimes work.
*/
cur_off = 0;
while((errv = dwarf_get_macro_details(dbg, cur_off,max,
&count,&maclist,&error))== DW_DLV_OK) {
for (i = 0; i < count; ++i) {
Dwarf_Macro_Details * mentry = maclist +i;
/* example of use */
Dwarf_Signed lineno = mentry->dmd_lineno;
functionusingsigned(lineno);
}
cur_off = maclist[count-1].dmd_offset + 1;
dwarf_dealloc(dbg, maclist, DW_DLA_STRING);
}
}
\fP
.DE
.in -2
.H 2 "Low Level Frame Operations"
These functions provide information about stack frames to be
used to perform stack traces. The information is an abstraction
of a table with a row per instruction and a column per register
and a column for the canonical frame address (CFA, which corresponds
to the notion of a frame pointer),
as well as a column for the return address.
.P
From 1993-2006 the interface we'll here refer to as DWARF2
made the CFA be a column in the matrix, but left
DW_FRAME_UNDEFINED_VAL, and DW_FRAME_SAME_VAL out of the matrix
(giving them high numbers). As of the DWARF3 interfaces
introduced in this document in April 2006, there are *two*
interfaces (the original set and a new set).
Several frame functions work transparently for either set, we
will focus on the ones that are not equally suitable
now.
.P
The original DWARF2 interface set still exists
(dwarf_get_fde_info_for_reg(),
dwarf_get_fde_info_for_cfa_reg(), and dwarf_get_fde_info_for_all_regs())
and works adequately for MIPS/IRIX DWARF2 and ABI/ISA sets
that are sufficiently similar to MIPS.
These functions not a good choice for non-MIPS architectures nor
were they a good design for MIPS either.
It's better to switch entirely to the new functions mentioned
in the next paragraph.
This DWARF2 interface set assumes and uses DW_FRAME_CFA_COL
and that is assumed when libdwarf is configured with --enable-oldframecol .
.P
A new DWARF3 interface set of dwarf_get_fde_info_for_reg3(),
dwarf_get_fde_info_for_cfa_reg3(), dwarf_get_fde_info_for_all_regs3(),
dwarf_set_frame_rule_table_size()
dwarf_set_frame_cfa_value(),
dwarf_set_frame_same_value(),
dwarf_set_frame_undefined_value(), and
dwarf_set_frame_rule_initial_value()
is more flexible
and will work for many more architectures.
It is also entirely suitable for use with DWARF2 and DWARF4.
The setting of the 'frame cfa column number'
defaults to DW_FRAME_CFA_COL3
and it can be set at runtime with dwarf_set_frame_cfa_value().
.P
Mixing use of the DWARF2 interface set with use
of the new DWARF3 interface set
on a single open Dwarf_Debug instance is a mistake.
Do not do it.
.P
We will pretend, from here on unless otherwise
specified, that
DW_FRAME_CFA_COL3, DW_FRAME_UNDEFINED_VAL,
and DW_FRAME_SAME_VAL are the synthetic column numbers.
These columns may be user-chosen by calls of
dwarf_set_frame_cfa_value()
dwarf_set_frame_undefined_value(), and
dwarf_set_frame_same_value() respectively.
.P
Each cell in the table contains one of the following:
.AL
.LI
A register + offset(a)(b)
.LI
A register(c)(d)
.LI
A marker (DW_FRAME_UNDEFINED_VAL) meaning \fIregister value undefined\fP
.LI
A marker (DW_FRAME_SAME_VAL) meaning
\fIregister value same as in caller\fP
.LE
.P
(a old DWARF2 interface) When the column is DW_FRAME_CFA_COL:
the register
number is a real hardware register, not a reference
to DW_FRAME_CFA_COL, not DW_FRAME_UNDEFINED_VAL,
and not DW_FRAME_SAME_VAL.
The CFA rule value should be the stack pointer
plus offset 0 when no other value makes sense.
A value of DW_FRAME_SAME_VAL would
be semi-logical, but since the CFA is not a real register,
not really correct.
A value of DW_FRAME_UNDEFINED_VAL would imply
the CFA is undefined --
this seems to be a useless notion, as
the CFA is a means to finding real registers,
so those real registers should be marked DW_FRAME_UNDEFINED_VAL,
and the CFA column content (whatever register it
specifies) becomes unreferenced by anything.
.P
(a new April 2006 DWARF2/3 interface): The CFA is
separately accessible and not part of the table.
The 'rule number' for the CFA is a number outside the table.
So the CFA is a marker, not a register number.
See DW_FRAME_CFA_COL3 in libdwarf.h and
dwarf_get_fde_info_for_cfa_reg3() and
dwarf_set_frame_rule_cfa_value().
.P
(b) When the column is not DW_FRAME_CFA_COL3, the 'register'
will and must be DW_FRAME_CFA_COL3(COL), implying that
to get the final location for the column one must add
the offset here plus the DW_FRAME_CFA_COL3 rule value.
.P
(c) When the column is DW_FRAME_CFA_COL3, then the 'register'
number is (must be) a real hardware register .
(This paragraph does not apply to the April 2006 new interface).
If it were DW_FRAME_UNDEFINED_VAL or DW_FRAME_SAME_VAL
it would be a marker, not a register number.
.P
(d) When the column is not DW_FRAME_CFA_COL3, the register
may be a hardware register.
It will not be DW_FRAME_CFA_COL3.
.P
There is no 'column' for DW_FRAME_UNDEFINED_VAL or DW_FRAME_SAME_VAL.
Nor for DW_FRAME_CFA_COL3.
Figure \n(aX
is machine dependent and represents MIPS CPU register
assignments. The DW_FRAME_CFA_COL define in dwarf.h
is historical and really belongs
in libdwarf.h, not dwarf.h.
.DS
.TS
center box, tab(:);
lfB lfB lfB
l c l.
NAME:value:PURPOSE
_
DW_FRAME_CFA_COL:0:column used for CFA
DW_FRAME_REG1:1:integer register 1
DW_FRAME_REG2:2:integer register 2
---::obvious names and values here
DW_FRAME_REG30:30:integer register 30
DW_FRAME_REG31:31:integer register 31
DW_FRAME_FREG0:32:floating point register 0
DW_FRAME_FREG1:33:floating point register 1
---::obvious names and values here
DW_FRAME_FREG30:62:floating point register 30
DW_FRAME_FREG31:63:floating point register 31
DW_FRAME_RA_COL:64:column recording ra
DW_FRAME_UNDEFINED_VAL:1034:register val undefined
DW_FRAME_SAME_VAL:1035:register same as in caller
.TE
.FG "Frame Information Rule Assignments MIPS"
.DE
.P
The following table shows SGI/MIPS specific
special cell values: these values mean
that the cell has the value \fIundefined\fP or \fIsame value\fP
respectively, rather than containing a \fIregister\fP or
\fIregister+offset\fP.
It assumes DW_FRAME_CFA_COL is a table rule, which
is not readily accomplished or even sensible for some architectures.
.P
.DS
.TS
center box, tab(:);
lfB lfB lfB
l c l.
NAME:value:PURPOSE
_
DW_FRAME_UNDEFINED_VAL:1034:means undefined value.
::Not a column or register value
DW_FRAME_SAME_VAL:1035:means 'same value' as
::caller had. Not a column or
::register value
DW_FRAME_CFA_COL:0:means register zero is
::usurped by the CFA column.
::
.TE
.FG "Frame Information Special Values any architecture"
.DE
.P
The following table shows more general special cell values.
These values mean
that the cell register-number refers to the \fIcfa-register\fP or
\fIundefined-value\fP or \fIsame-value\fP
respectively, rather than referring to a \fIregister in the table\fP.
The generality arises from making DW_FRAME_CFA_COL3 be
outside the set of registers and making the cfa rule accessible
from outside the rule-table.
.P
.DS
.TS
center box, tab(:);
lfB lfB lfB
l c l.
NAME:value:PURPOSE
_
DW_FRAME_UNDEFINED_VAL:1034:means undefined
::value. Not a column or register value
DW_FRAME_SAME_VAL:1035:means 'same value' as
::caller had. Not a column or
::register value
DW_FRAME_CFA_COL3:1436:means 'cfa register'
::is referred to, not a real register, not
::a column, but the cfa (the cfa does have
::a value, but in the DWARF3 libdwarf interface
::it does not have a 'real register number').
.TE
.DE
.P
.H 3 "dwarf_get_frame_section_name()"
.DS
\f(CWint dwarf_get_frame_section_name(Dwarf_Debug dbg,
const char ** sec_name,
Dwarf_Error *error)\fP
.DE
\f(CWdwarf_get_string_section_name()\fP lets consumers
access the object string section name.
This is useful for applications wanting to print
the name, but of course the object section name is not
really a part of the DWARF information.
Most applications will
probably not call this function.
It can be called at any time
after the Dwarf_Debug initialization is done.
See also \f(CWdwarf_get_frame_section_name_eh_gnu()\fP.
.P
The function
\f(CWdwarf_get_frame_section_name()\fP operates on
the the .debug_frame section.
.P
If the function succeeds, \f(CW*sec_name\fP is set to
a pointer to a string with the object section name and
the function returns \f(CWDW_DLV_OK\fP.
Do not free the string whose pointer is returned.
For non-Elf objects it is possible the string pointer
returned will be NULL or will point to an empty string.
It is up to the calling application to recognize this
possibility and deal with it appropriately.
.P
If the section does not exist the function returns
DW_DLV_NO_ENTRY.
.P
If there is an internal error detected the
function returns \f(CWDW_DLV_ERROR\fP and sets the
\f(CW*error\fP pointer.
.H 3 "dwarf_get_frame_section_name_eh_gnu()"
.DS
\f(CWint dwarf_get_frame_section_name_eh_gnu(Dwarf_Debug dbg
const char ** sec_name,
Dwarf_Error *error)\fP
.DE
\f(CWdwarf_get_frame_section_name_eh_gnu()\fP lets consumers
access the object string section name.
This is useful for applications wanting to print
the name, but of course the object section name is not
really a part of the DWARF information.
Most applications will
probably not call this function.
It can be called at any time
after the Dwarf_Debug initialization is done.
See also \f(CWdwarf_get_frame_section_name()\fP.
.P
The function
\f(CWdwarf_get_frame_section_name_eh_ghu()\fP operates on
the the .eh_frame section.
.P
If the function succeeds, \f(CW*sec_name\fP is set to
a pointer to a string with the object section name and
the function returns \f(CWDW_DLV_OK\fP.
Do not free the string whose pointer is returned.
For non-Elf objects it is possible the string pointer
returned will be NULL or will point to an empty string.
It is up to the calling application to recognize this
possibility and deal with it appropriately.
.P
If the section does not exist the function returns
DW_DLV_NO_ENTRY.
.P
If there is an internal error detected the
function returns \f(CWDW_DLV_ERROR\fP and sets the
\f(CW*error\fP pointer.
.H 3 "dwarf_get_fde_list()"
.DS
\f(CWint dwarf_get_fde_list(
Dwarf_Debug dbg,
Dwarf_Cie **cie_data,
Dwarf_Signed *cie_element_count,
Dwarf_Fde **fde_data,
Dwarf_Signed *fde_element_count,
Dwarf_Error *error);\fP
.DE
\f(CWdwarf_get_fde_list()\fP stores a pointer to a list of
\f(CWDwarf_Cie\fP descriptors in \f(CW*cie_data\fP, and the
count of the number of descriptors in \f(CW*cie_element_count\fP.
There is a descriptor for each CIE in the .debug_frame section.
Similarly, it stores a pointer to a list of \f(CWDwarf_Fde\fP
descriptors in \f(CW*fde_data\fP, and the count of the number
of descriptors in \f(CW*fde_element_count\fP. There is one
descriptor per FDE in the .debug_frame section.
\f(CWdwarf_get_fde_list()\fP returns \f(CWDW_DLV_ERROR\fP on error.
It returns \f(CWDW_DLV_NO_ENTRY\fP if it cannot find frame entries.
It returns \f(CWDW_DLV_OK\fP on a successful return.
.P
On successful return, structures pointed to by a
descriptor should be freed using \f(CWdwarf_fde_cie_list_dealloc()\fP.
This dealloc approach is new as of July 15, 2005.
.in +2
.FG "Exampleq dwarf_get_fde_list()"
.DS
\f(CW
void exampleq(Dwarf_Debug dbg)
{
Dwarf_Cie *cie_data = 0;
Dwarf_Signed cie_count = 0;
Dwarf_Fde *fde_data = 0;
Dwarf_Signed fde_count = 0;
Dwarf_Error error = 0;
int fres = 0;
fres = dwarf_get_fde_list(dbg,&cie_data,&cie_count,
&fde_data,&fde_count,&error);
if (fres == DW_DLV_OK) {
dwarf_fde_cie_list_dealloc(dbg, cie_data, cie_count,
fde_data,fde_count);
}
}
\fP
.DE
.in -2
.P
The following code is deprecated as of July 15, 2005 as it does not
free all relevant memory.
This approach still works as well as it ever did.
.in +2
.FG "Exampleqb dwarf_get_fde_list() obsolete"
.DS
\f(CW
/* OBSOLETE EXAMPLE */
void exampleqb(Dwarf_Debug dbg)
{
Dwarf_Cie *cie_data = 0;
Dwarf_Signed cie_count = 0;
Dwarf_Fde *fde_data = 0;
Dwarf_Signed fde_count = 0;
Dwarf_Error error = 0;
Dwarf_Signed i = 0;
int fres = 0;
fres = dwarf_get_fde_list(dbg,&cie_data,&cie_count,
&fde_data,&fde_count,&error);
if (fres == DW_DLV_OK) {
for (i = 0; i < cie_count; ++i) {
/* use cie[i] */
dwarf_dealloc(dbg, cie_data[i], DW_DLA_CIE);
}
for (i = 0; i < fde_count; ++i) {
/* use fde[i] */
dwarf_dealloc(dbg, fde_data[i], DW_DLA_FDE);
}
dwarf_dealloc(dbg, cie_data, DW_DLA_LIST);
dwarf_dealloc(dbg, fde_data, DW_DLA_LIST);
}
}
\fP
.DE
.in -2
.P
.H 3 "dwarf_get_fde_list_eh()"
.DS
\f(CWint dwarf_get_fde_list_eh(
Dwarf_Debug dbg,
Dwarf_Cie **cie_data,
Dwarf_Signed *cie_element_count,
Dwarf_Fde **fde_data,
Dwarf_Signed *fde_element_count,
Dwarf_Error *error);\fP
.DE
\f(CWdwarf_get_fde_list_eh()\fP is identical to
\f(CWdwarf_get_fde_list()\fP except that
\f(CWdwarf_get_fde_list_eh()\fP reads the GNU gcc
section named .eh_frame (C++ exception handling information).
\f(CWdwarf_get_fde_list_eh()\fP stores a pointer to a list of
\f(CWDwarf_Cie\fP descriptors in \f(CW*cie_data\fP, and the
count of the number of descriptors in \f(CW*cie_element_count\fP.
There is a descriptor for each CIE in the .debug_frame section.
Similarly, it stores a pointer to a list of \f(CWDwarf_Fde\fP
descriptors in \f(CW*fde_data\fP, and the count of the number
of descriptors in \f(CW*fde_element_count\fP. There is one
descriptor per FDE in the .debug_frame section.
\f(CWdwarf_get_fde_list()\fP returns \f(CWDW_DLV_ERROR\fP on error.
It returns \f(CWDW_DLV_NO_ENTRY\fP if it cannot find
exception handling entries.
It returns \f(CWDW_DLV_OK\fP on a successful return.
.P
On successful return, structures pointed to by a
descriptor should be freed using \f(CWdwarf_fde_cie_list_dealloc()\fP.
This dealloc approach is new as of July 15, 2005.
.in +2
.FG "Exampler dwarf_get_fde_list_eh()"
.DS
\f(CW
void exampler(Dwarf_Debug dbg,Dwarf_Addr mypcval)
{
/* Given a pc value
for a function find the FDE and CIE data for
the function.
Example shows basic access to FDE/CIE plus
one way to access details given a PC value.
dwarf_get_fde_n() allows accessing all FDE/CIE
data so one could build up an application-specific
table of information if that is more useful. */
Dwarf_Signed count = 0;
Dwarf_Cie *cie_data = 0;
Dwarf_Signed cie_count = 0;
Dwarf_Fde *fde_data = 0;
Dwarf_Signed fde_count = 0;
Dwarf_Error error = 0;
int fres = 0;
fres = dwarf_get_fde_list_eh(dbg,&cie_data,&cie_count,
&fde_data,&fde_count,&error);
if (fres == DW_DLV_OK) {
Dwarf_Fde myfde = 0;
Dwarf_Addr low_pc = 0;
Dwarf_Addr high_pc = 0;
fres = dwarf_get_fde_at_pc(fde_data,mypcval,
&myfde,&low_pc,&high_pc,
&error);
if (fres == DW_DLV_OK) {
Dwarf_Cie mycie = 0;
fres = dwarf_get_cie_of_fde(myfde,&mycie,&error);
if (fres == DW_DLV_OK) {
/* Now we can access a range of information
about the fde and cie applicable. */
}
}
dwarf_fde_cie_list_dealloc(dbg, cie_data, cie_count,
fde_data,fde_count);
}
/* ERROR or NO ENTRY. Do something */
}
\fP
.DE
.in -2
.P
.H 3 "dwarf_get_cie_of_fde()"
.DS
\f(CWint dwarf_get_cie_of_fde(Dwarf_Fde fde,
Dwarf_Cie *cie_returned,
Dwarf_Error *error);\fP
.DE
\f(CWdwarf_get_cie_of_fde()\fP stores a \f(CWDwarf_Cie\fP
into the \f(CWDwarf_Cie\fP that \f(CWcie_returned\fP points at.
If one has called
\f(CWdwarf_get_fde_list()\fP
must avoid dwarf_dealloc-ing the FDEs and the CIEs for those FDEs
individually (see its documentation here).
Failing to observe this restriction will cause the FDE(s) not
dealloc'd to become invalid: an FDE contains (hidden in it)
a CIE pointer which will be be invalid (stale, pointing to freed memory)
if the CIE is dealloc'd.
The invalid CIE pointer internal to the FDE cannot be detected
as invalid by libdwarf.
If one later passes an FDE with a stale internal CIE pointer
to one of the routines taking an FDE as input the result will
be failure of the call (returning DW_DLV_ERROR) at best and
it is possible a coredump or worse will happen (eventually).
\f(CWdwarf_get_cie_of_fde()\fP returns
\f(CWDW_DLV_OK\fP if it is successful (it will be
unless fde is the NULL pointer).
It returns \f(CWDW_DLV_ERROR\fP if the fde is invalid (NULL).
.P
Each \f(CWDwarf_Fde\fP descriptor describes information about the
frame for a particular subroutine or function.
\f(CWint dwarf_get_fde_for_die\fP is SGI/MIPS specific.
.H 3 "dwarf_get_fde_for_die()"
.DS
\f(CWint dwarf_get_fde_for_die(
Dwarf_Debug dbg,
Dwarf_Die die,
Dwarf_Fde * return_fde,
Dwarf_Error *error)\fP
.DE
When it succeeds,
\f(CWdwarf_get_fde_for_die()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*return_fde\fP
to
a \f(CWDwarf_Fde\fP
descriptor representing frame information for the given \f(CWdie\fP. It
looks for the \f(CWDW_AT_MIPS_fde\fP attribute in the given \f(CWdie\fP.
If it finds it, is uses the value of the attribute as the offset in
the .debug_frame section where the FDE begins.
If there is no \f(CWDW_AT_MIPS_fde\fP it returns \f(CWDW_DLV_NO_ENTRY\fP.
If there is an error it returns \f(CWDW_DLV_ERROR\fP.
.H 3 "dwarf_get_fde_range()"
.DS
\f(CWint dwarf_get_fde_range(
Dwarf_Fde fde,
Dwarf_Addr *low_pc,
Dwarf_Unsigned *func_length,
Dwarf_Ptr *fde_bytes,
Dwarf_Unsigned *fde_byte_length,
Dwarf_Off *cie_offset,
Dwarf_Signed *cie_index,
Dwarf_Off *fde_offset,
Dwarf_Error *error);\fP
.DE
On success,
\f(CWdwarf_get_fde_range()\fP returns
\f(CWDW_DLV_OK\fP.
The location pointed to by \f(CWlow_pc\fP is set to the low pc value for
this function.
The location pointed to by \f(CWfunc_length\fP is
set to the length of the function in bytes.
This is essentially the
length of the text section for the function.
The location pointed
to by \f(CWfde_bytes\fP is set to the address where the FDE begins
in the .debug_frame section.
The location pointed to by
\f(CWfde_byte_length\fP is set to the length in bytes of the portion
of .debug_frame for this FDE.
This is the same as the value returned
by \f(CWdwarf_get_fde_range\fP.
The location pointed to by
\f(CWcie_offset\fP is set to the offset in the .debug_frame section
of the CIE used by this FDE.
The location pointed to by \f(CWcie_index\fP
is set to the index of the CIE used by this FDE.
The index is the
index of the CIE in the list pointed to by \f(CWcie_data\fP as set
by the function \f(CWdwarf_get_fde_list()\fP.
However, if the function
\f(CWdwarf_get_fde_for_die()\fP was used to obtain the given \f(CWfde\fP,
this index may not be correct.
The location pointed to by
\f(CWfde_offset\fP is set to the offset of the start of this FDE in
the .debug_frame section.
\f(CWdwarf_get_fde_range()\fP returns \f(CWDW_DLV_ERROR\fP on error.
.H 3 "dwarf_get_cie_info()"
.DS
\f(CWint dwarf_get_cie_info(
Dwarf_Cie cie,
Dwarf_Unsigned *bytes_in_cie,
Dwarf_Small *version,
char **augmenter,
Dwarf_Unsigned *code_alignment_factor,
Dwarf_Signed *data_alignment_factor,
Dwarf_Half *return_address_register_rule,
Dwarf_Ptr *initial_instructions,
Dwarf_Unsigned *initial_instructions_length,
Dwarf_Error *error);\fP
.DE
\f(CWdwarf_get_cie_info()\fP is primarily for Internal-level Interface
consumers.
If successful,
it returns
\f(CWDW_DLV_OK\fP and sets \f(CW*bytes_in_cie\fP to
the number of bytes in the portion of the
frames section for the CIE represented by the given \f(CWDwarf_Cie\fP
descriptor, \f(CWcie\fP.
The other fields are directly taken from
the cie and returned, via the pointers to the caller.
It returns \f(CWDW_DLV_ERROR\fP on error.
.H 3 "dwarf_get_cie_index()"
.DS
\f(CWint dwarf_get_cie_index(
Dwarf_Cie cie,
Dwarf_Signed *cie_index,
Dwarf_Error *error);\fP
.DE
On success,
\f(CWdwarf_get_cie_index()\fP returns
\f(CWDW_DLV_OK\fP.
On error this function returns \f(CWDW_DLV_ERROR\fP.
The location pointed to by \f(CWcie_index\fP
is set to the index of the CIE of this FDE.
The index is the
index of the CIE in the list pointed to by \f(CWcie_data\fP as set
by the function \f(CWdwarf_get_fde_list()\fP.
So one must have used \f(CWdwarf_get_fde_list()\fP or
\f(CWdwarf_get_fde_list_eh()\fP to get
a cie list before this is meaningful.
This function is occasionally useful, but is
little used.
.H 3 "dwarf_get_fde_instr_bytes()"
.DS
\f(CWint dwarf_get_fde_instr_bytes(
Dwarf_Fde fde,
Dwarf_Ptr *outinstrs,
Dwarf_Unsigned *outlen,
Dwarf_Error *error);\fP
.DE
\f(CWdwarf_get_fde_instr_bytes()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*outinstrs\fP to
a pointer to a set of bytes which are the
actual frame instructions for this fde.
It also sets \f(CW*outlen\fP to the length, in
bytes, of the frame instructions.
It returns \f(CWDW_DLV_ERROR\fP on error.
It never returns \f(CWDW_DLV_NO_ENTRY\fP.
The intent is to allow low-level consumers like a dwarf-dumper
to print the bytes in some fashion.
The memory pointed to by \f(CWoutinstrs\fP
must not be changed and there
is nothing to free.
.H 3 "dwarf_get_fde_info_for_reg()"
This interface is suitable for DWARF2 but is not
sufficient for DWARF3. See
\f(CWint dwarf_get_fde_info_for_reg3\fP.
.DS
\f(CWint dwarf_get_fde_info_for_reg(
Dwarf_Fde fde,
Dwarf_Half table_column,
Dwarf_Addr pc_requested,
Dwarf_Signed *offset_relevant,
Dwarf_Signed *register_num,
Dwarf_Signed *offset,
Dwarf_Addr *row_pc,
Dwarf_Error *error);\fP
.DE
\f(CWdwarf_get_fde_info_for_reg()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*offset_relevant\fP to
non-zero if the offset is relevant for the
row specified by \f(CWpc_requested\fP and column specified by
\f(CWtable_column\fP, for the FDE specified by \f(CWfde\fP.
The
intent is to return the rule for the given pc value and register.
The location pointed to by \f(CWregister_num\fP is set to the register
value for the rule.
The location pointed to by \f(CWoffset\fP
is set to the offset value for the rule.
If offset is not relevant for this rule, \f(CW*offset_relevant\fP is
set to zero.
Since more than one pc
value will have rows with identical entries, the user may want to
know the earliest pc value after which the rules for all the columns
remained unchanged.
Recall that in the virtual table that the frame information
represents there may be one or more table rows with identical data
(each such table row at a different pc value).
Given a \f(CWpc_requested\fP which refers to a pc in such a group
of identical rows,
the location pointed to by \f(CWrow_pc\fP is set
to the lowest pc value
within the group of identical rows.
The value put in \f(CW*register_num\fP any of the
\f(CWDW_FRAME_*\fP table columns values specified in \f(CWlibdwarf.h\fP
or \f(CWdwarf.h\fP.
\f(CWdwarf_get_fde_info_for_reg\fP returns \f(CWDW_DLV_ERROR\fP if there is an error.
It is usable with either
\f(CWdwarf_get_fde_n()\fP or \f(CWdwarf_get_fde_at_pc()\fP.
\f(CWdwarf_get_fde_info_for_reg()\fP is tailored to MIPS, please use
\f(CWdwarf_get_fde_info_for_reg3()\fP instead for all architectures.
.H 3 "dwarf_get_fde_info_for_all_regs()"
.DS
\f(CWint dwarf_get_fde_info_for_all_regs(
Dwarf_Fde fde,
Dwarf_Addr pc_requested,
Dwarf_Regtable *reg_table,
Dwarf_Addr *row_pc,
Dwarf_Error *error);\fP
.DE
\f(CWdwarf_get_fde_info_for_all_regs()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*reg_table\fP for the row specified by
\f(CWpc_requested\fP for the FDE specified by \f(CWfde\fP.
.P
The intent is
to return the rules for decoding all the registers, given a pc value.
\f(CWreg_table\fP is an array of rules, one for each register specified in
\f(CWdwarf.h\fP. The rule for each register contains three items -
\f(CWdw_regnum\fP which denotes the register value for that rule,
\f(CWdw_offset\fP which denotes the offset value for that rule and
\f(CWdw_offset_relevant\fP which is set to zero if offset is not relevant
for that rule. See \f(CWdwarf_get_fde_info_for_reg()\fP for a description
of \f(CWrow_pc\fP.
.P
\f(CWdwarf_get_fde_info_for_all_regs\fP returns \f(CWDW_DLV_ERROR\fP if there is an error.
.P
\f(CWint dwarf_get_fde_info_for_all_regs\fP is tailored to SGI/MIPS,
please use dwarf_get_fde_info_for_all_regs3() instead for all architectures.
.H 3 "dwarf_fde_section_offset()"
.DS
\f(CWint dwarf_fde_section_offset(
Dwarf_Debug /*dbg*/,
Dwarf_Fde /*in_fde*/,
Dwarf_Off * /*fde_off*/,
Dwarf_Off * /*cie_off*/,
Dwarf_Error *error);\fP
.DE
On success
\f(CWdwarf_fde_section_offset()\fP returns
the .dwarf_line section offset of the fde passed in
and also the offset of its CIE.
.P
It returns \f(CWDW_DLV_ERROR\fP if there is an error.
.P
It returns \f(CWDW_DLV_ERROR\fP if there is an error.
.P
It is intended to be used by applications like dwarfdump
when such want to print the offsets of CIEs and FDEs.
.H 3 "dwarf_cie_section_offset()"
.DS
\f(CWint dwarf_cie_section_offset(
Dwarf_Debug /*dbg*/,
Dwarf_Cie /*in_cie*/,
Dwarf_Off * /*cie_off*/,
Dwarf_Error * /*err*/);
Dwarf_Error *error);\fP
.DE
On success
\f(CWdwarf_cie_section_offset()\fP returns
the .dwarf_line section offset of the cie passed in.
.P
It returns \f(CWDW_DLV_ERROR\fP if there is an error.
.P
It is intended to be used by applications like dwarfdump
when such want to print the offsets of CIEs.
.H 3 "dwarf_set_frame_rule_table_size()"
.P
This allows consumers to set the size of the (internal to libdwarf)
rule table when using the 'reg3' interfaces (these interfaces
are strongly preferred over the older 'reg' interfaces).
It should be at least as large as the
number of real registers in the ABI which is to be read in
for the dwarf_get_fde_info_for_reg3() or
dwarf_get_fde_info_for_all_regs3()
functions to work properly.
The frame rule table size must be less than the marker values
DW_FRAME_UNDEFINED_VAL, DW_FRAME_SAME_VAL, DW_FRAME_CFA_COL3
(dwarf_set_frame_rule_undefined_value()
dwarf_set_frame_same_value()
dwarf_set_frame_cfa_value()
effectively set these markers so
the frame rule table size can actually be any value regardless
of the macro values in libdwarf.h as long as the table size
does not overlap these markers).
.P
.DS
\f(CWDwarf_Half
dwarf_set_frame_rule_table_size(Dwarf_Debug dbg,
Dwarf_Half value);\fP
.DE
\f(CWdwarf_set_frame_rule_table_size()\fP sets the
value \f(CWvalue\fP as the size of libdwarf-internal
rules tables of \f(CWdbg\fP.
.P
The function returns
the previous value of the rules table size setting (taken from the
\f(CWdbg\fP structure).
.H 3 "dwarf_set_frame_rule_initial_value()"
This allows consumers to set the initial value
for rows in the frame tables. By default it
is taken from libdwarf.h and is DW_FRAME_REG_INITIAL_VALUE
(which itself is either DW_FRAME_SAME_VAL or DW_FRAME_UNDEFINED_VAL).
The MIPS/IRIX default is DW_FRAME_SAME_VAL.
Consumer code should set this appropriately and for
many architectures (but probably not MIPS) DW_FRAME_UNDEFINED_VAL is an
appropriate setting.
Note: an earlier spelling of dwarf_set_frame_rule_inital_value()
is still supported as an interface, but please change to use
the new correctly spelled name.
.DS
\f(CWDwarf_Half
dwarf_set_frame_rule_initial_value(Dwarf_Debug dbg,
Dwarf_Half value);\fP
.DE
\f(CWdwarf_set_frame_rule_initial_value()\fP sets the
value \f(CWvalue\fP as the initial value for this \f(CWdbg\fP
when initializing rules tables.
.P
The function returns
the previous value of initial value (taken from the
\f(CWdbg\fP structure).
.H 3 "dwarf_set_frame_cfa_value()"
This allows consumers to set the number of the CFA register
for rows in the frame tables. By default it
is taken from libdwarf.h and is \f(CWDW_FRAME_CFA_COL\fP.
Consumer code should set this appropriately and for
nearly all architectures \f(CWDW_FRAME_CFA_COL3\fP is an
appropriate setting.
.DS
\f(CWDwarf_Half
dwarf_set_frame_rule_cfa_value(Dwarf_Debug dbg,
Dwarf_Half value);\fP
.DE
\f(CWdwarf_set_frame_rule_cfa_value()\fP sets the
value \f(CWvalue\fP as the number of the cfa 'register rule'
for this \f(CWdbg\fP
when initializing rules tables.
.P
The function returns
the previous value of the pseudo-register (taken from the
\f(CWdbg\fP structure).
.H 3 "dwarf_set_frame_same_value()"
This allows consumers to set the number of the pseudo-register
when DW_CFA_same_value is the operation. By default it
is taken from libdwarf.h and is \f(CWDW_FRAME_SAME_VAL\fP.
Consumer code should set this appropriately, though for
many architectures \f(CWDW_FRAME_SAME_VAL\fP is an
appropriate setting.
.DS
\f(CWDwarf_Half
dwarf_set_frame_rule_same_value(Dwarf_Debug dbg,
Dwarf_Half value);\fP
.DE
\f(CWdwarf_set_frame_rule_same_value()\fP sets the
value \f(CWvalue\fP as the number of the register
that is the pseudo-register set by the DW_CFA_same_value
frame operation.
.P
The function returns
the previous value of the pseudo-register (taken from the
\f(CWdbg\fP structure).
.H 3 "dwarf_set_frame_undefined_value()"
This allows consumers to set the number of the pseudo-register
when DW_CFA_undefined_value is the operation. By default it
is taken from libdwarf.h and is \f(CWDW_FRAME_UNDEFINED_VAL\fP.
Consumer code should set this appropriately, though for
many architectures \f(CWDW_FRAME_UNDEFINED_VAL\fP is an
appropriate setting.
.DS
\f(CWDwarf_Half
dwarf_set_frame_rule_undefined_value(Dwarf_Debug dbg,
Dwarf_Half value);\fP
.DE
\f(CWdwarf_set_frame_rule_undefined_value()\fP sets the
value \f(CWvalue\fP as the number of the register
that is the pseudo-register set by the DW_CFA_undefined_value
frame operation.
.P
The function returns
the previous value of the pseudo-register (taken from the
\f(CWdbg\fP structure).
.H 3 "dwarf_set_default_address_size()"
This allows consumers to set a default address size.
When one has an object where the
default address_size does not match the frame address
size where there is no debug_info available to get a
frame-specific address-size, this function is useful.
For example, if an Elf64 object has a .debug_frame whose
real address_size is 4 (32 bits). This a very rare
situation.
.DS
\f(CWDwarf_Small
dwarf_set_default_address_size(Dwarf_Debug dbg,
Dwarf_Small value);\fP
.DE
\f(CWdwarf_set_default_address_size()\fP sets the
value \f(CWvalue\fP as the default address size for
this activation of the reader, but only if \f(CWvalue\fP
is greater than zero (otherwise the default address size
is not changed).
.P
The function returns
the previous value of the default address size (taken from the
\f(CWdbg\fP structure).
.H 3 "dwarf_get_fde_info_for_reg3()"
This interface is suitable for DWARF2 and later.
It returns the values for a particular real register
(Not for the CFA virtual register,
see dwarf_get_fde_info_for_cfa_reg3()
below).
If the application is going to retrieve the value for more
than a few \f(CWtable_column\fP values at this \f(CWpc_requested\fP
(by calling this function multiple times)
it is much more efficient to
call dwarf_get_fde_info_for_all_regs3() (in spite
of the additional setup that requires of the caller).
.DS
\f(CWint dwarf_get_fde_info_for_reg3(
Dwarf_Fde fde,
Dwarf_Half table_column,
Dwarf_Addr pc_requested,
Dwarf_Small *value_type,
Dwarf_Signed *offset_relevant,
Dwarf_Signed *register_num,
Dwarf_Signed *offset_or_block_len,
Dwarf_Ptr *block_ptr,
Dwarf_Addr *row_pc,
Dwarf_Error *error);\fP
.DE
See also the nearly identical function
\f(CWdwarf_get_fde_info_for_reg3_b()\fP.
.P
\f(CWdwarf_get_fde_info_for_reg3()\fP returns
\f(CWDW_DLV_OK\fP on success.
It sets \f(CW*value_type\fP
to one of DW_EXPR_OFFSET (0),
DW_EXPR_VAL_OFFSET(1), DW_EXPR_EXPRESSION(2) or
DW_EXPR_VAL_EXPRESSION(3).
On call, \f(CWtable_column\fP must be set to the
register number of a real register. Not
the cfa 'register' or DW_FRAME_SAME_VALUE or
DW_FRAME_UNDEFINED_VALUE.
if \f(CW*value_type\fP has the value DW_EXPR_OFFSET (0) then:
.in +4
.P
It sets \f(CW*offset_relevant\fP to
non-zero if the offset is relevant for the
row specified by \f(CWpc_requested\fP and column specified by
\f(CWtable_column\fP or, for the FDE specified by \f(CWfde\fP.
In this case the \f(CW*register_num\fP will be set
to DW_FRAME_CFA_COL3 (. This is an offset(N) rule
as specified in the DWARF3/2 documents.
.P
Adding the value of \f(CW*offset_or_block_len\fP
to the value of the CFA register gives the address
of a location holding the previous value of
register \f(CWtable_column\fP.
.P
If offset is not relevant for this rule, \f(CW*offset_relevant\fP is
set to zero. \f(CW*register_num\fP will be set
to the number of the real register holding the value of
the \f(CWtable_column\fP register.
This is the register(R) rule as specified in DWARF3/2 documents.
.P
The
intent is to return the rule for the given pc value and register.
The location pointed to by \f(CWregister_num\fP is set to the register
value for the rule.
The location pointed to by \f(CWoffset\fP
is set to the offset value for the rule.
Since more than one pc
value will have rows with identical entries, the user may want to
know the earliest pc value after which the rules for all the columns
remained unchanged.
Recall that in the virtual table that the frame information
represents there may be one or more table rows with identical data
(each such table row at a different pc value).
Given a \f(CWpc_requested\fP which refers to a pc in such a group
of identical rows,
the location pointed to by \f(CWrow_pc\fP is set
to the lowest pc value
within the group of identical rows.
.in -4
.P
If \f(CW*value_type\fP has the value DW_EXPR_VAL_OFFSET (1) then:
.in +4
This will be a val_offset(N) rule as specified in the
DWARF3/2 documents so \f(CW*offset_relevant\fP will
be non zero.
The calculation is identical to the DW_EXPR_OFFSET (0)
calculation with \f(CW*offset_relevant\fP non-zero,
but the value resulting is the actual \f(CWtable_column\fP
value (rather than the address where the value may be found).
.in -4
.P
If \f(CW*value_type\fP has the value DW_EXPR_EXPRESSION (1) then:
.in +4
\f(CW*offset_or_block_len\fP
is set to the length in bytes of a block of memory
with a DWARF expression in the block.
\f(CW*block_ptr\fP is set to point at the block of memory.
The consumer code should evaluate the block as
a DWARF-expression. The result is the address where
the previous value of the register may be found.
This is a DWARF3/2 expression(E) rule.
.in -4
.P
If \f(CW*value_type\fP has the value DW_EXPR_VAL_EXPRESSION (1) then:
.in +4
The calculation is exactly as for DW_EXPR_EXPRESSION (1)
but the result of the DWARF-expression evaluation is
the value of the \f(CWtable_column\fP (not
the address of the value).
This is a DWARF3/2 val_expression(E) rule.
.in -4
\f(CWdwarf_get_fde_info_for_reg\fP
returns \f(CWDW_DLV_ERROR\fP if there is an error and
if there is an error only the \f(CWerror\fP pointer is set, none
of the other output arguments are touched.
It is usable with either
\f(CWdwarf_get_fde_n()\fP or \f(CWdwarf_get_fde_at_pc()\fP.
.H 3 "dwarf_get_fde_info_for_reg3_b()"
This interface is suitable for DWARF2 and later.
It returns the values for a particular real register
(Not for the CFA virtual register,
see dwarf_get_fde_info_for_cfa_reg3_b()
below).
If the application is going to retrieve the value for more
than a few \f(CWtable_column\fP values at this \f(CWpc_requested\fP
(by calling this function multiple times)
it is much more efficient to
call dwarf_get_fde_info_for_all_regs3() (in spite
of the additional setup that requires of the caller).
.DS
\f(CWint dwarf_get_fde_info_for_reg3_b(
Dwarf_Fde fde,
Dwarf_Half table_column,
Dwarf_Addr pc_requested,
Dwarf_Small *value_type,
Dwarf_Signed *offset_relevant,
Dwarf_Signed *register_num,
Dwarf_Signed *offset_or_block_len,
Dwarf_Ptr *block_ptr,
Dwarf_Addr *row_pc,
Dwarf_Bool *has_more_rows,
Dwarf_Addr *subsequent_pc,
Dwarf_Error *error);\fP
.DE
.P
This is identical to
\f(CWdwarf_get_fde_info_for_reg3()\fP
except for the new arguments
\f(CWhas_more_rows\fP
and
\f(CWsubsequent_pc\fP
which allow the caller to
know if there are more rows in the frame table
and what the next pc value in the frame table
for this fde is.
The two new arguments may be passed in as NULL
if their values are not needed by the caller.
.H 3 "dwarf_get_fde_info_for_cfa_reg3()"
.DS
\f(CWint dwarf_get_fde_info_for_cfa_reg3(Dwarf_Fde fde,
Dwarf_Addr pc_requested,
Dwarf_Small * value_type,
Dwarf_Signed* offset_relevant,
Dwarf_Signed* register_num,
Dwarf_Signed* offset_or_block_len,
Dwarf_Ptr * block_ptr ,
Dwarf_Addr * row_pc_out,
Dwarf_Error * error)\fP
.DE
.P
This is identical to
\f(CWdwarf_get_fde_info_for_reg3()\fP
except the returned values are for the CFA rule.
So register number
\f(CW*register_num\fP
will be set
to a real register, not one of the pseudo registers
(which are usually
DW_FRAME_CFA_COL3, DW_FRAME_SAME_VALUE, or
DW_FRAME_UNDEFINED_VALUE).
.P
Applications like dwarfdump
which access the register rules for every pc
value in a function may find the following
function a slight performance improvement
if the new arguments are used appropriately.
See \f(CWdwarfdump\fP for an example of use.
.H 3 "dwarf_get_fde_info_for_cfa_reg3_b()"
.DS
\f(CWint dwarf_get_fde_info_for_cfa_reg3_b(Dwarf_Fde fde,
Dwarf_Addr pc_requested,
Dwarf_Small * value_type,
Dwarf_Signed* offset_relevant,
Dwarf_Signed* register_num,
Dwarf_Signed* offset_or_block_len,
Dwarf_Ptr * block_ptr ,
Dwarf_Addr * row_pc_out,
Dwarf_Bool * has_more_rows,
Dwarf_Addr * subsequent_pc,
Dwarf_Error * error)\fP
.DE
.P
This is identical to
\f(CWdwarf_get_fde_info_for_cfa_reg3()\fP
except for the new arguments
\f(CWhas_more_rows\fP
and
\f(CWsubsequent_pc\fP
which allow the caller to
know if there are more rows in the frame table
and what the next pc value is.
The two new arguments may be passed in as NULL
if their values are not needed by the caller.
.P
For a tool just wanting the frame information for a single
pc_value this interface is no more useful or
efficient than
\f(CWdwarf_get_fde_info_for_cfa_reg3()\fP.
.P
The essential difference is that when using
\f(CWdwarf_get_fde_info_for_cfa_reg3()\fP
for all pc values for a function the caller
has no idea what is the next pc value that might
have new frame data and iterating through
pc values (calling
\f(CWdwarf_get_fde_info_for_cfa_reg3()\fP on each)
is a waste of cpu cycles.
With
\f(CWdwarf_get_fde_info_for_cfa_reg3_b()\fP
the
\f(CWhas_more_rows\fP
and
\f(CWsubsequent_pc\fP
arguments let the caller know whether there
are further rows and if so at what pc value.
.P
If
\f(CWhas_more_rows\fP
is non-null
then 1 is returned through the pointer
if, for the
\f(CWpc_requested\fP
there is frame data for addresses after
\f(CWpc_requested\fP
in the frame.
And if there are no more rows in the frame data then
0 is set through the
\f(CWhas_more_rows\fP pointer.
.P
If
\f(CWsubsequent_pc\fP
is non-null
then the pc-value which has the next
frame operator is returned through the
pointer. If no more rows are present
zero is returned through the pointer, but
please use
\f(CWhas_more_rows\fP
to determine if there are more rows.
.H 3 "dwarf_get_fde_info_for_all_regs3()"
.DS
\f(CWint dwarf_get_fde_info_for_all_regs3(
Dwarf_Fde fde,
Dwarf_Addr pc_requested,
Dwarf_Regtable3 *reg_table,
Dwarf_Addr *row_pc,
Dwarf_Error *error)\fP
.DE
\f(CWdwarf_get_fde_info_for_all_regs3()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*reg_table\fP
for the row specified by
\f(CWpc_requested\fP for the FDE specified by \f(CWfde\fP.
The intent is
to return the rules for decoding all the registers, given a pc
value.
\f(CWreg_table\fP is an array of rules, the
array size specified by the caller.
plus a rule for the CFA.
The rule for the cfa returned in \f(CW*reg_table\fP
defines the CFA value at \f(CWpc_requested\fP
The rule for each
register contains several values that enable
the consumer to determine the previous value
of the register (see the earlier documentation of Dwarf_Regtable3).
\f(CWdwarf_get_fde_info_for_reg3()\fP and
the Dwarf_Regtable3 documentation above for a description of
the values for each row.
\f(CWdwarf_get_fde_info_for_all_regs3\fP returns \f(CWDW_DLV_ERROR\fP if there is an error.
It is up to the caller to allocate space for
\f(CW*reg_table\fP and initialize it properly.
.H 3 "dwarf_get_fde_n()"
.DS
\f(CWint dwarf_get_fde_n(
Dwarf_Fde *fde_data,
Dwarf_Unsigned fde_index,
Dwarf_Fde *returned_fde
Dwarf_Error *error)\fP
.DE
\f(CWdwarf_get_fde_n()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CWreturned_fde\fP to
the \f(CWDwarf_Fde\fP descriptor whose
index is \f(CWfde_index\fP in the table of \f(CWDwarf_Fde\fP descriptors
pointed to by \fPfde_data\fP.
The index starts with 0.
The table pointed to by fde_data is required to contain
at least one entry. If the table has no entries at all
the error checks may refer to uninitialized memory.
Returns \f(CWDW_DLV_NO_ENTRY\fP if the index does not
exist in the table of \f(CWDwarf_Fde\fP
descriptors.
Returns \f(CWDW_DLV_ERROR\fP if there is an error.
This function cannot be used unless
the block of \f(CWDwarf_Fde\fP descriptors has been created by a call to
\f(CWdwarf_get_fde_list()\fP.
.H 3 "dwarf_get_fde_at_pc()"
.DS
\f(CWint dwarf_get_fde_at_pc(
Dwarf_Fde *fde_data,
Dwarf_Addr pc_of_interest,
Dwarf_Fde *returned_fde,
Dwarf_Addr *lopc,
Dwarf_Addr *hipc,
Dwarf_Error *error)\fP
.DE
\f(CWdwarf_get_fde_at_pc()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CWreturned_fde\fP to
a \f(CWDwarf_Fde\fP descriptor
for a function which contains the pc value specified by \f(CWpc_of_interest\fP.
In addition, it sets the locations pointed to
by \f(CWlopc\fP and \f(CWhipc\fP to the low address and the high address
covered by this FDE, respectively.
The table pointed to by fde_data is required to contain
at least one entry. If the table has no entries at all
the error checks may refer to uninitialized memory.
It returns \f(CWDW_DLV_ERROR\fP on error.
It returns \f(CWDW_DLV_NO_ENTRY\fP
if \f(CWpc_of_interest\fP is not in any of the
FDEs represented by the block of \f(CWDwarf_Fde\fP descriptors pointed
to by \f(CWfde_data\fP.
This function cannot be used unless
the block of \f(CWDwarf_Fde\fP descriptors has been created by a call to
\f(CWdwarf_get_fde_list()\fP.
.H 3 "dwarf_expand_frame_instructions()"
.DS
\f(CWint dwarf_expand_frame_instructions(
Dwarf_Cie cie,
Dwarf_Ptr instruction,
Dwarf_Unsigned i_length,
Dwarf_Frame_Op **returned_op_list,
Dwarf_Signed * returned_op_count,
Dwarf_Error *error);\fP
.DE
\f(CWdwarf_expand_frame_instructions()\fP is a High-level interface
function which expands a frame instruction byte stream into an
array of \f(CWDwarf_Frame_Op\fP structures.
To indicate success, it returns \f(CWDW_DLV_OK\fP.
The address where
the byte stream begins is specified by \f(CWinstruction\fP, and
the length of the byte stream is specified by \f(CWi_length\fP.
The location pointed to by \f(CWreturned_op_list\fP is set to
point to a table of
\f(CWreturned_op_count\fP
pointers to \f(CWDwarf_Frame_Op\fP which
contain the frame instructions in the byte stream.
It returns \f(CWDW_DLV_ERROR\fP on error.
It never returns \f(CWDW_DLV_NO_ENTRY\fP.
After a successful return, the
array of structures should be freed using
\f(CWdwarf_dealloc()\fP with the allocation type \f(CWDW_DLA_FRAME_BLOCK\fP
(when they are no longer of interest).
.P
Not all CIEs have the same address-size, so it is crucial
that a CIE pointer to the frame's CIE be passed in.
.in +2
.FG "Examples dwarf_expand_frame_instructions()"
.DS
\f(CW
void examples(Dwarf_Debug dbg,Dwarf_Cie cie,
Dwarf_Ptr instruction,Dwarf_Unsigned len)
{
Dwarf_Signed count = 0;
Dwarf_Frame_Op *frameops = 0;
Dwarf_Error error = 0;
int res = 0;
res = dwarf_expand_frame_instructions(cie,instruction,len,
&frameops,&count, &error);
if (res == DW_DLV_OK) {
Dwarf_Signed i = 0;
for (i = 0; i < count; ++i) {
/* use frameops[i] */
}
dwarf_dealloc(dbg, frameops, DW_DLA_FRAME_BLOCK);
}
}
\fP
.DE
.in -2
.H 3 "dwarf_get_fde_exception_info()"
.DS
\f(CWint dwarf_get_fde_exception_info(
Dwarf_Fde fde,
Dwarf_Signed * offset_into_exception_tables,
Dwarf_Error * error);
.DE
\f(CWdwarf_get_fde_exception_info()\fP is an IRIX specific
function which returns an exception table signed offset
through \f(CWoffset_into_exception_tables\fP.
The function never returns \f(CWDW_DLV_NO_ENTRY\fP.
If \f(CWDW_DLV_NO_ENTRY\fP is NULL the function returns
\f(CWDW_DLV_ERROR\fP.
For non-IRIX objects the offset returned will always be zero.
For non-C++ objects the offset returned will always be zero.
The meaning of the offset and the content of the tables
is not defined in this document.
The applicable CIE augmentation string (see above)
determines whether the value returned has meaning.
.H 2 "Location Expression Evaluation"
An "interpreter" which evaluates a location expression
is required in any debugger. There is no interface defined
here at this time.
.P
One problem with defining an interface is that operations are
machine dependent: they depend on the interpretation of
register numbers and the methods of getting values from the
environment the expression is applied to.
.P
It would be desirable to specify an interface.
.H 3 "Location List Internal-level Interface"
.H 4 "dwarf_get_loclist_entry()"
.DS
\f(CWint dwarf_get_loclist_entry(
Dwarf_Debug dbg,
Dwarf_Unsigned offset,
Dwarf_Addr *hipc_offset,
Dwarf_Addr *lopc_offset,
Dwarf_Ptr *data,
Dwarf_Unsigned *entry_len,
Dwarf_Unsigned *next_entry,
Dwarf_Error *error)\fP
.DE
This function is ill suited to use with
21st century DWARF as there is just not
enough data provided in the interface.
Do not use this interface.
Use
\f(CWdwarf_get_locdesc_entry_c()\fP
instead.
.P
The function reads
a location list entry starting at \f(CWoffset\fP and returns
through pointers (when successful)
the high pc \f(CWhipc_offset\fP, low pc
\f(CWlopc_offset\fP, a pointer to the location description data
\f(CWdata\fP, the length of the location description data
\f(CWentry_len\fP, and the offset of the next location description
entry \f(CWnext_entry\fP.
.P
This function will often work correctly (meaning with most
objects compiled for DWARF3 or DWARF3)
but will not work correctly (and can crash
an application calling it) if either
some location list applies to a compilation unit with
an address_size different from the overall address_size
of the object file being read or if the .debug_loc section
being read has random padding bytes between loclists.
Neither of these characteristics necessarily represents
a bug in the compiler/linker toolset that produced the
object file being read. The DWARF standard
allows both characteristics.
.P
\f(CWdwarf_dwarf_get_loclist_entry()\fP returns
\f(CWDW_DLV_OK\fP if successful.
\f(CWDW_DLV_NO_ENTRY\fP is returned when the offset passed
in is beyond the end of the .debug_loc section (expected if
you start at offset zero and proceed through all the entries).
\f(CWDW_DLV_ERROR\fP is returned on error.
.P
The \f(CWhipc_offset\fP,
low pc \f(CWlopc_offset\fP are offsets from the beginning of the
current procedure, not genuine pc values.
.P
The example of use has been deleted.
Do not use this function.
.H 2 "Abbreviations access"
These are Internal-level Interface functions.
Debuggers can ignore this.
.H 3 "dwarf_get_abbrev()"
.DS
\f(CWint dwarf_get_abbrev(
Dwarf_Debug dbg,
Dwarf_Unsigned offset,
Dwarf_Abbrev *returned_abbrev,
Dwarf_Unsigned *length,
Dwarf_Unsigned *attr_count,
Dwarf_Error *error)\fP
.DE
The function \f(CWdwarf_get_abbrev()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*returned_abbrev\fP to
\f(CWDwarf_Abbrev\fP,
a descriptor for the abbreviation
that begins
at offset
\f(CW*offset\fP in the abbreviations
section (i.e .debug_abbrev) on success.
The user is responsible for making sure that
a valid abbreviation begins at
\f(CWoffset\fP in the abbreviations section.
The location pointed to by
\f(CWlength\fP
is set to the length in bytes of the
abbreviation set in the abbreviations
section.
The location pointed to by
\f(CWattr_count\fP is set to the
number of attributes in the abbreviation.
An abbreviation entry with a
length of 1 is the 0 byte of the last
abbreviation entry of a compilation
unit.
.P
\f(CWdwarf_get_abbrev()\fP returns
\f(CWDW_DLV_NO_ENTRY\fP if the .debug_abbrev
section is missing or if the offset passed
in is past the end of the section.
.P
\f(CWdwarf_get_abbrev()\fP returns
\f(CWDW_DLV_ERROR\fP on error.
If the call succeeds, the storage pointed to
by \f(CW*returned_abbrev\fP
should be freed, using
\f(CWdwarf_dealloc()\fP with the
allocation type
\f(CWDW_DLA_ABBREV\fP
when no longer needed.
.H 3 "dwarf_get_abbrev_tag()"
.DS
\f(CWint dwarf_get_abbrev_tag(
Dwarf_Abbrev abbrev,
Dwarf_Half *return_tag,
Dwarf_Error *error);\fP
.DE
If successful,
\f(CWdwarf_get_abbrev_tag()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*return_tag\fP to
the \fItag\fP of
the given abbreviation.
It returns \f(CWDW_DLV_ERROR\fP on error.
It never returns \f(CWDW_DLV_NO_ENTRY\fP.
.H 3 "dwarf_get_abbrev_code()"
.DS
\f(CWint dwarf_get_abbrev_code(
Dwarf_Abbrev abbrev,
Dwarf_Unsigned *return_code,
Dwarf_Error *error);\fP
.DE
If successful,
\f(CWdwarf_get_abbrev_code()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*return_code\fP to
the abbreviation code of
the given abbreviation.
It returns \f(CWDW_DLV_ERROR\fP on error.
It never returns \f(CWDW_DLV_NO_ENTRY\fP.
.H 3 "dwarf_get_abbrev_children_flag()"
.DS
\f(CWint dwarf_get_abbrev_children_flag(
Dwarf_Abbrev abbrev,
Dwarf_Signed *returned_flag,
Dwarf_Error *error)\fP
.DE
The function \f(CWdwarf_get_abbrev_children_flag()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CWreturned_flag\fP to
\f(CWDW_children_no\fP (if the given abbreviation indicates that
a die with that abbreviation has no children) or
\f(CWDW_children_yes\fP (if the given abbreviation indicates that
a die with that abbreviation has a child).
It returns \f(CWDW_DLV_ERROR\fP on error.
.H 3 "dwarf_get_abbrev_entry_b()"
.DS
\f(CWint dwarf_get_abbrev_entry_b(Dwarf_Abbrev abbrev,
Dwarf_Unsigned index,
Dwarf_Bool filter_outliers,
Dwarf_Unsigned * returned_attr_num,
Dwarf_Unsigned * returned_form,
Dwarf_Signed * returned_implicit_const,
Dwarf_Off * offset,
Dwarf_Error * error)\fP
.DE
\f(CWdwarf_get_abbrev_entry_b()\fP
is new in August 2019.
It should be used in place of
\f(CWdwarf_get_abbrev_entry()\fP
as
\f(CWdwarf_get_abbrev_entry()\fP
cannot return the DWARF5 implicit const value
and and
\f(CWdwarf_get_abbrev_entry()\fP
can hide some instances of corrupt
uleb abbreviation values.
.P
While the
\f(CWreturned_attr_num\fP
and
and \f(CWreturned_form\fP
are only correct if they each fit in
a
\f(CWDwarf_Half\fP
value, we return larger values in
certain cases (see next paragraph).
.P
If
\f(CWfilter_outliers\fP
is passed in zero then
erroneous
\f(CWreturned_attr_num\fP
or
and \f(CWreturned_form\fP
are returned whether their
values are sensible or not
and
\f(CWDW_DLV_OK\fP
is the returned value.
This is useful
for dwarfdump as dwarfdump checks abbreviation
values quite thoroughly and reports errors
in detail (dwarfdump -kb).
.P
If
\f(CWfilter_outliers\fP
is passed in non-zero then
\f(CWDW_DLV_OK\fP
is returned
only if
\f(CWreturned_attr_num\fP
and
and \f(CWreturned_form\fP
are both legitimate values.
.P
If successful,
\f(CWdwarf_get_abbrev_entry_b()\fP returns
\f(CWDW_DLV_OK\fP and sets
\f(CW*attr_num\fP to the attribute code of
the attribute
whose index is specified by
\f(CWindex\fP in the given abbreviation.
.P
The index starts at 0.
.P
The location pointed to by
\f(CWreturned_attr_num\fP is set
to the attribute number (example:
\f(CWDW_AT_name\fP).
The location pointed to by
\f(CWreturned_form\fP is set
to the form of the attribute (example:
\f(CWDW_FORM_string\fP).
The location pointed to by
\f(CWreturned_implicit_const\fP
is set to the implicit const value
if and only if the FORM returned
is
\f(CWDW_FORM_implicit_const\fP
The location pointed to by
\f(CWoffset\fP
is set to the byte offset of the attribute
in the abbreviations section.
.P
The function returns
\f(CWDW_DLV_NO_ENTRY\fP if the
index specified is outside
the range of attributes in this abbreviation.
.P
The function returns
\f(CWDW_DLV_ERROR\fP on error and sets
\f(CW*error\fP to an error value instance.
.H 3 "dwarf_get_abbrev_entry()"
.DS
\f(CWint dwarf_get_abbrev_entry(
Dwarf_Abbrev abbrev,
Dwarf_Signed index,
Dwarf_Half *attr_num,
Dwarf_Signed *form,
Dwarf_Off *offset,
Dwarf_Error *error)\fP
.DE
.P
This function cannot return DW_FORM_implicit_const
const values.
When convenient all callers should switch to using
the
\f(CWdwarf_get_abbrev_entry_b()\fP
function.
.P
If successful,
\f(CWdwarf_get_abbrev_entry()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*attr_num\fP to the attribute code of
the attribute
whose index is specified by \f(CWindex\fP in the given abbreviation.
The index starts at 0.
The location pointed to by \f(CWform\fP is set
to the form of the attribute.
The location pointed to by \f(CWoffset\fP
is set to the byte offset of the attribute in the abbreviations section.
.P
It returns
\f(CWDW_DLV_NO_ENTRY\fP if the index specified is outside
the range of attributes in this abbreviation.
.P
It returns
\f(CWDW_DLV_ERROR\fP on error.
.H 2 "String Section Operations"
The .debug_str section contains only strings. Debuggers need
never use this interface: it is only for debugging problems with
the string section itself.
.H 3 "dwarf_get_string_section_name()"
.DS
\f(CWint dwarf_get_string_section_name(Dwarf_Debug dbg,
const char ** sec_name,
Dwarf_Error *error)\fP
.DE
\f(CWdwarf_get_string_section_name()\fP lets consumers
access the object string section name.
This is useful for applications wanting to print
the name, but of course the object section name is not
really a part of the DWARF information.
Most applications will
probably not call this function.
It can be called at any time
after the Dwarf_Debug initialization is done.
See also \f(CWdwarf_get_die_section_name_b()\fP.
.P
The function
\f(CWdwarf_get_string_section_name()\fP operates on
the the .debug_string[.dwo] section.
.P
If the function succeeds, \f(CW*sec_name\fP is set to
a pointer to a string with the object section name and
the function returns \f(CWDW_DLV_OK\fP.
Do not free the string whose pointer is returned.
For non-Elf objects it is possible the string pointer
returned will be NULL or will point to an empty string.
It is up to the calling application to recognize this
possibility and deal with it appropriately.
.P
If the section does not exist the function returns
DW_DLV_NO_ENTRY.
.P
If there is an internal error detected the
function returns \f(CWDW_DLV_ERROR\fP and sets the
\f(CW*error\fP pointer.
.H 3 "dwarf_get_str()"
.DS
\f(CWint dwarf_get_str(
Dwarf_Debug dbg,
Dwarf_Off offset,
char **string,
Dwarf_Signed *returned_str_len,
Dwarf_Error *error)\fP
.DE
The function \f(CWdwarf_get_str()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*returned_str_len\fP to
the length of
the string, not counting the null terminator, that begins at the offset
specified by \f(CWoffset\fP in the .debug_str section.
The location
pointed to by \f(CWstring\fP is set to a pointer to this string.
The next string in the .debug_str
section begins at the previous \f(CWoffset\fP + 1 + \f(CW*returned_str_len\fP.
A zero-length string is NOT the end of the section.
If there is no .debug_str section, \f(CWDW_DLV_NO_ENTRY\fP is returned.
If there is an error, \f(CWDW_DLV_ERROR\fP is returned.
If we are at the end of the section (that is, \f(CWoffset\fP
is one past the end of the section) \f(CWDW_DLV_NO_ENTRY\fP is returned.
If the \f(CWoffset\fP is some other too-large value then
\f(CWDW_DLV_ERROR\fP is returned.
.H 2 "String Offsets Section Operations"
The .debug_str_offsets section contains only
table arrays (with headers) and Debuggers should never
need to use this interface.
The normal string access functions use the section tables
transparently.
The functions here are only intended
to allow dwarfdump (or the like) print the section
completely and to help compiler developers look
for bugs in the section.
.in +2
.FG "examplestringoffsets dwarf_open_str_offsets_table_access() etc"
.DS
\f(CW
void examplestringoffsets(Dwarf_Debug dbg)
{
int res = 0;
Dwarf_Str_Offsets_Table sot = 0;
Dwarf_Unsigned wasted_byte_count = 0;
Dwarf_Unsigned table_count = 0;
Dwarf_Error error = 0;
res = dwarf_open_str_offsets_table_access(dbg, &sot,&error);
if(res == DW_DLV_NO_ENTRY) {
/* No such table */
return;
}
if(res == DW_DLV_ERROR) {
/* Something is very wrong. Print the error? */
return;
}
for(;;) {
Dwarf_Unsigned unit_length =0;
Dwarf_Unsigned unit_length_offset =0;
Dwarf_Unsigned table_start_offset =0;
Dwarf_Half entry_size = 0;
Dwarf_Half version =0;
Dwarf_Half padding =0;
Dwarf_Unsigned table_value_count =0;
Dwarf_Unsigned i = 0;
Dwarf_Unsigned table_entry_value = 0;
res = dwarf_next_str_offsets_table(sot,
&unit_length, &unit_length_offset,
&table_start_offset,
&entry_size,&version,&padding,
&table_value_count,&error);
if (res == DW_DLV_NO_ENTRY) {
/* We have dealt with all tables */
break;
}
if (res == DW_DLV_ERROR) {
/* Something badly wrong. Do something. */
return;
}
/* One could call dwarf_str_offsets_statistics to
get the wasted bytes so far, but we do not do that
in this example. */
/* Possibly print the various table-related values
returned just above. */
for (i=0; i < table_value_count; ++i) {
res = dwarf_str_offsets_value_by_index(sot,i,
&table_entry_value,&error);
if (res != DW_DLV_OK) {
/* Something is badly wrong. Do something. */
return;
}
/* Do something with the table_entry_value
at this index. Maybe just print it.
It is an offset in .debug_str. */
}
}
res = dwarf_str_offsets_statistics(sot,&wasted_byte_count,
&table_count,&error);
if (res == DW_DLV_OK) {
/* The wasted byte count is set. Print it or something.
One hopes zero bytes are wasted.
Print the table count if one is interested. */
}
res = dwarf_close_str_offsets_table_access(sot,&error);
/* There is little point in checking the return value
as little can be done about any error. */
sot = 0;
}
\fP
.DE
.in -2
.H 3 "dwarf_open_str_offsets_table_access()"
.DS
\f(CWint dwarf_open_str_offsets_table_access(
Dwarf_Debug dbg,
Dwarf_Str_Offsets_Table * table_data,
Dwarf_Error * error);\fP
.DE
\f(CWdwarf_open_str_offsets_table_access()\fP
creates an opaque struct and returns a pointer to
it on success. That struct pointer is used
in all subsequent operations on the table.
Through the function
\f(CWdwarf_next_str_offsets_table()\fP
the caller can iterate through each of the
per-CU offset tables.
.P
If there is no such section, or if the section
is empty the function returns DW_DLV_NO_ENTRY.
.P
If there is an error (such as out-of-memory)
the function returns DW_DLV_ERROR and sets
an error value through the
\f(CWerror\fP
pointer.
.H 3 "dwarf_close_str_offsets_table_access()"
.DS
\f(CWint
dwarf_close_str_offsets_table_access(
Dwarf_Str_Offsets_Table table_data,
Dwarf_Error * error);\fP
.DE
On success,
\f(CWdwarf_close_str_offsets_table_access()\fP
frees any allocated data associated with the
struct pointed to by
\f(CWtable_data\fP
and returns DW_DLV_OK.
It is up to the caller to set the
\f(CWtable_data\fP
pointer to NULL if desired. The pointer
is unusable at that point and any other
calls to libdwarf using that pointer will fail.
.P
It returns DW_DLV_OK on error.
Any error suggests there is memory corruption
or an error in the call.
Something serious happened.
.P
It never returns DW_DLV_NO_ENTRY, but if it did
there would be nothing the caller could do anyway..
.P
If one forgets to call this function
the memory allocated will be freed automatically
by to call to
\f(CWdwarf_finish()\fP,
as is true of all other data allocated by libdwarf.
.H 3 "dwarf_next_str_offsets_table()"
.DS
\f(CWint dwarf_next_str_offsets_table(
Dwarf_Str_Offsets_Table table,
Dwarf_Unsigned *unit_length_out,
Dwarf_Unsigned *unit_length_offset_out,
Dwarf_Unsigned *table_start_offset_out,
Dwarf_Half *entry_size_out,
Dwarf_Half *version_out,
Dwarf_Half *padding_out,
Dwarf_Unsigned *table_value_count_out,
Dwarf_Error * error);\fP
.DE
Each call to
\f(CWdwarf_next_str_offsets_table()\fP
returns the next String Offsets table
in the .debug_str_offsets section.
Typically there would be one such table
for each CU in .debug_info[.dwo] contributing
to .debug_str_offsets.
The
\f(CWtable\fP
contains (internally, hidden) the section offset
of the next table.
.P
On success it returns DW_DLV_OK and
sets various fields representing data about
the current table (fields described below).
.P
If there are no more tables it returns
DW_DLV_NO_ENTRY.
.P
On error it returns DW_DLV_ERROR and passes back
error details through the
\f(CWerror\fP
pointer.
.P
The returned values are intended to let the caller
understand the table header and the table in detail.
These pointers are only used if the call returned
DW_DLV_OK.
.P
\f(CWunit_length_out\fP
is set to the unit_length of
a String Offsets Table Header.
Which means it gives the length,
in bytes, of the data following
the length value that belongs
to this table.
.P
\f(CWunit_length_offset_out\fP
is set to the section offset of
the table header.
.P
\f(CWtable_start_offset_out\fP
is set to the section offset of
the array of offsets in this table.
.P
\f(CWentry_size_out\fP
is set to the size of a table entry.
Which is 4 for 32-bit offsets
in this table
and 8 for 64-bit offsets in this table.
.P
\f(CWversion_out\fP
is set to the version number in the
table header.
The only current valid value is 5.
.P
\f(CWpadding_out\fP
is set to the 16-bit padding value
in the table header.
In a correct table header the value is zero.
.P
\f(CWtable_value_count_out\fP
is set to the number of entries in
the array of offsets in this table.
Each entry is
\f(CWentry_size_out\fP
bytes long.
Use this value in calling
\f(CWdwarf_str_offsets_value_by_index()\fP.
.H 3 "dwarf_str_offsets_value_by_index()"
.DS
\f(CWint dwarf_str_offsets_value_by_index(
Dwarf_Str_Offsets_Table sot,
Dwarf_Unsigned index,
Dwarf_Unsigned *stroffset,
Dwarf_Error *error);\fP
.DE
On success,
\f(CWdwarf_str_offsets_value_by_index()\fP
returns DW_DLV_OK and sets
the offset from the array of string
offsets in the current table at the input
\f(CWindex\fP.
.P
Valid index values are zero through
\f(CWtable_value_count_out - 1\fP
.P
A function is used instead of simply
letting callers use pointers
as libdwarf correctly handles
endianness differences
(between the system running libdwarf
and the object file being inspected)
so offsets
can be reported properly.
.P
DW_DLV_ERROR is returned on error.
.P
DW_DLV_NO_ENTRY is never returned.
.H 3 "dwarf_str_offsets_statistics()"
.DS
\f(CWint dwarf_str_offsets_statistics(
Dwarf_Str_Offsets_Table table_data,
Dwarf_Unsigned * wasted_byte_count,
Dwarf_Unsigned * table_count,
Dwarf_Error * error);\fP
.DE
Normally called after all tables have been inspected to
return (through a pointer)
the count of apparently-wasted bytes in the section.
It can be called at any point that the
\f(CWDwarf_Str_Offsets_Table\fP
pointer is valid.
.P
On error it returns DW_DLV_ERROR and sets
an error value through the pointer.
.P
DW_DLV_NO_ENTRY is never returned.
.P
On success it returns DW_DLV_OK
and sets values through the two pointers.
Calling just after each table is accessed by
\f(CWdwarf_next_str_offsets_table()\fP
will reveal the sum of all wasted bytes at
that point in iterating through the section.
.P
\f(CWtable_count\fP
is the count of table headers encountered so far.
.P
By wasted bytes we mean bytes in between tables.
libdwarf has no idea whether any
apparently-valid table data
is in fact useless.
.H 2 "Address Range Operations"
These functions provide information about address ranges.
The content is in the
\f(CW.debug_aranges\fP
section.
Address
ranges map ranges of pc values to the corresponding compilation-unit
die that covers the address range.
In the DWARF2,3,4 Standards this is described under
"Accelerated Access" "Lookup by Address".
.H 3 "dwarf_get_aranges_section_name()"
.DS
\f(CWint dwarf_get_aranges_section_name(Dwarf_Debug dbg,
const char ** sec_name,
Dwarf_Error *error)\fP
.DE
\f(CW*dwarf_get_aranges_section_name()\fP
retrieves the object file section name of
the applicable aranges section.
This is useful for applications wanting to print
the name, but of course the object section name is not
really a part of the DWARF information.
Most applications will
probably not call this function.
It can be called at any time
after the Dwarf_Debug initialization is done.
.P
If the function succeeds, \f(CW*sec_name\fP is set to
a pointer to a string with the object section name and
the function returns \f(CWDW_DLV_OK\fP.
Do not free the string whose pointer is returned.
For non-Elf objects it is possible the string pointer
returned will be NULL or will point to an empty string.
It is up to the calling application to recognize this
possibility and deal with it appropriately.
.P
If the section does not exist the function returns
DW_DLV_NO_ENTRY.
.P
If there is an internal error detected the
function returns \f(CWDW_DLV_ERROR\fP and sets the
\f(CW*error\fP pointer.
.H 3 "dwarf_get_aranges()"
.DS
\f(CWint dwarf_get_aranges(
Dwarf_Debug dbg,
Dwarf_Arange **aranges,
Dwarf_Signed * returned_arange_count,
Dwarf_Error *error)\fP
.DE
The function \f(CWdwarf_get_aranges()\fP returns
\f(CWDW_DLV_OK\fP and sets \f(CW*returned_arange_count\fP to
the count of the
number of address ranges in the .debug_aranges section
(for all compilation units).
It sets
\f(CW*aranges\fP to point to a block of \f(CWDwarf_Arange\fP
descriptors, one for each address range.
It returns \f(CWDW_DLV_ERROR\fP on error.
It returns \f(CWDW_DLV_NO_ENTRY\fP if there is no .debug_aranges
section.
.P
This not only reads all the ranges, it also reads
the per-compilation-unit headers in .debug_aranges
and verifies they make sense.
.in +2
.FG "Exampleu dwarf_get_aranges()"
.DS
\f(CW
void exampleu(Dwarf_Debug dbg)
{
Dwarf_Signed count = 0;
Dwarf_Arange *arang = 0;
int res = 0;
Dwarf_Error error = 0;
res = dwarf_get_aranges(dbg, &arang,&count, &error);
if (res == DW_DLV_OK) {
Dwarf_Signed i = 0;
for (i = 0; i < count; ++i) {
/* use arang[i] */
dwarf_dealloc(dbg, arang[i], DW_DLA_ARANGE);
}
dwarf_dealloc(dbg, arang, DW_DLA_LIST);
}
}
\fP
.DE
.in -2
.H 3 "dwarf_get_arange()"
.DS
\f(CWint dwarf_get_arange(
Dwarf_Arange *aranges,
Dwarf_Unsigned arange_count,
Dwarf_Addr address,
Dwarf_Arange *returned_arange,
Dwarf_Error *error);\fP
.DE
The function \f(CWdwarf_get_arange()\fP takes as input a pointer
to a block of \f(CWDwarf_Arange\fP pointers, and a count of the
number of descriptors in the block.
It then searches for the
descriptor that covers the given \f(CWaddress\fP.
If it finds
one, it returns
\f(CWDW_DLV_OK\fP and sets \f(CW*returned_arange\fP to
the descriptor.
It returns \f(CWDW_DLV_ERROR\fP on error.
It returns \f(CWDW_DLV_NO_ENTRY\fP if there is no .debug_aranges
entry covering that address.
.P
.H 3 "dwarf_get_cu_die_offset()"
.DS
\f(CWint dwarf_get_cu_die_offset(
Dwarf_Arange arange,
Dwarf_Off *returned_cu_die_offset,
Dwarf_Error *error);\fP
.DE
The function \f(CWdwarf_get_cu_die_offset()\fP takes a
\f(CWDwarf_Arange\fP descriptor as input, and
if successful returns
\f(CWDW_DLV_OK\fP and sets \f(CW*returned_cu_die_offset\fP to
the offset
in the .debug_info section of the compilation-unit DIE for the
compilation-unit represented by the given address range.
It returns \f(CWDW_DLV_ERROR\fP on error.
.H 3 "dwarf_get_arange_cu_header_offset()"
.DS
\f(CWint dwarf_get_arange_cu_header_offset(
Dwarf_Arange arange,
Dwarf_Off *returned_cu_header_offset,
Dwarf_Error *error)\fP
.DE
The function \f(CWdwarf_get_arange_cu_header_offset()\fP takes a
\f(CWDwarf_Arange\fP descriptor as input, and
if successful returns
\f(CWDW_DLV_OK\fP and sets \f(CW*returned_cu_header_offset\fP to
the offset
in the .debug_info section of the compilation-unit header for the
compilation-unit represented by the given address range.
It returns \f(CWDW_DLV_ERROR\fP on error.
This function added Rev 1.45, June, 2001.
This function is declared as 'optional' in libdwarf.h
on IRIX systems so the _MIPS_SYMBOL_PRESENT
predicate may be used at run time to determine if the version of
libdwarf linked into an application has this function.
.H 3 "dwarf_get_arange_info_b()"
.DS
\f(CWint dwarf_get_arange_info_b(
Dwarf_Arange arange,
Dwarf_Unsigned *segment,
Dwarf_Unsigned *segment_entry_size;
Dwarf_Addr *start,
Dwarf_Unsigned *length,
Dwarf_Off *cu_die_offset,
Dwarf_Error *error)\fP
.DE
The function
\f(CWdwarf_get_arange_info_b()\fP
returns
\f(CWDW_DLV_OK\fP
and
returns detailed information on the address range
through the pointers.
.P
\f(CWsegment\fP
is the segment number for segmented
addresss spaces and it is only meaningful
if
\f(CWsegment_entry_size\fP
is non-zero.
.P
It puts
the starting value of the address range
in the location pointed
to by
\f(CWstart\fP,
and
the length of the address range in the location
pointed to by
\f(CWlength\fP.
.P
It sets
the
\f(CWcu_die_offset\fP.
in the
\f(CW.debug_info\fP,
section
of the compilation-unit DIE for the
compilation-unit represented by the
address range.
.P
It returns \f(CWDW_DLV_ERROR\fP on error.
and sets
\f(CWerror\fP,
.H 3 "dwarf_get_arange_info()"
.DS
\f(CWint dwarf_get_arange_info(
Dwarf_Arange arange,
Dwarf_Addr *start,
Dwarf_Unsigned *length,
Dwarf_Off *cu_die_offset,
Dwarf_Error *error)\fP
.DE
This is the same as
\f(CWdwarf_get_arange_info_b()\fP
except that this earlier function does not
have a way to return the segment information.
.H 2 "General Low Level Operations"
This function is low-level and intended for use only
by programs such as dwarf-dumpers.
.H 3 "dwarf_get_offset_size()"
.DS
\f(CWint dwarf_get_offset_size(Dwarf_Debug dbg,
Dwarf_Half *offset_size,
Dwarf_Error *error)\fP
.DE
The function \f(CWdwarf_get_offset_size()\fP
returns \f(CWDW_DLV_OK\fP on success and sets
the \f(CW*offset_size\fP
to the size in bytes of an offset.
In case of error, it returns \f(CWDW_DLV_ERROR\fP
and does not set \f(CW*offset_size\fP.
The offset size returned is the overall address size,
which can be misleading if different compilation
units have different address sizes.
Many ABIs have only a single address size per
executable, but differing address sizes are
becoming more common.
.H 3 "dwarf_get_address_size()"
.DS
\f(CWint dwarf_get_address_size(Dwarf_Debug dbg,
Dwarf_Half *addr_size,
Dwarf_Error *error)\fP
.DE
The function \f(CWdwarf_get_address_size()\fP
returns \f(CWDW_DLV_OK\fP on success and sets
the \f(CW*addr_size\fP
to the size in bytes of an address.
In case of error, it returns \f(CWDW_DLV_ERROR\fP
and does not set \f(CW*addr_size\fP.
The address size returned is the overall address size,
which can be misleading if different compilation
units have different address sizes.
Many ABIs have only a single address size per
executable, but differing address sizes are
becoming more common.
Use \f(CWdwarf_get_die_address_size()\fP
instead whenever possible.
.H 3 "dwarf_get_die_address_size()"
.DS
\f(CWint dwarf_get_die_address_size(Dwarf_Die die,
Dwarf_Half *addr_size,
Dwarf_Error *error)\fP
.DE
The function \f(CWdwarf_get_die_address_size()\fP
returns \f(CWDW_DLV_OK\fP on success and sets
the \f(CW*addr_size\fP
to the size in bytes of an address.
In case of error, it returns \f(CWDW_DLV_ERROR\fP
and does not set \f(CW*addr_size\fP.
The address size returned is the address size
of the compilation unit owning the \f(CWdie\fP
This is the preferred way to get address size when the
\f(CWDwarf_Die\fP is known.
.H 2 "Ranges Operations DWARF5 (.debug_rnglists)"
These functions provide information about the address ranges
indicated by a \f(CWDW_AT_ranges\fP attribute
of a DIE. The ranges are recorded
in the \f(CW.debug_rnglists\fP section.
.P
The section
requires that each group of ranges
has a header and the compilation unit
may have a
\f(CWDW_AT_ranges_base\fP
attribute that must be added to
the \f(CWDW_AT_ranges\fP attribute value
to get the true ranges offset.
.P
(A compiler generating
\f(CWDW_AT_ranges_base\fP
will add a relocation for that attribute value
but will not have to make the
\f(CWDW_AT_ranges\fP
attributes relocatable and will thus save space
in the object (ie, .o) file
and save link time.)
.P
See DWARF5 Section 2.17.3 Non-Contiguous Address Ranges
and Section 7.28 Range List Table.
.P
Section 7.28 describes the header fields for a Range List
Table. There will usually be many such tables, in some
sequence, in the .debug_rnglists section.
Here we call each header
\f(CWDwarf_Rnglists_Head\fP
(a pointer to an opaque struct).
.H 3 "Getting rnglists data for a DIE"
This set of interfaces provides access
to the DWARF5 .debug_rnglists entries
for a particular DIE.
.
Here is an example using the functions described below:
.in +2
.DS
.FG "Example .debug_rnglist for attribute"
\f(CW
int example_rnglist_for_attribute(Dwarf_Attribute attr,
Dwarf_Unsigned attrvalue,Dwarf_Error *error)
{
/* attrvalue must be the DW_AT_ranges
DW_FORM_rnglistx or DW_FORM_sec_offset value
extracted from attr. */
int res = 0;
Dwarf_Half theform = 0;
Dwarf_Unsigned entries_count;
Dwarf_Unsigned global_offset_of_rle_set;
Dwarf_Rnglists_Head rnglhead = 0;
Dwarf_Unsigned i = 0;
res = dwarf_rnglists_get_rle_head(attr,
theform,
attrvalue,
&rnglhead,
&entries_count,
&global_offset_of_rle_set,
error);
if (res != DW_DLV_OK) {
return res;
}
for (i = 0; i < entries_count; ++i) {
unsigned entrylen = 0;
unsigned code = 0;
Dwarf_Unsigned rawlowpc = 0;
Dwarf_Unsigned rawhighpc = 0;
Dwarf_Unsigned lowpc = 0;
Dwarf_Unsigned highpc = 0;
Dwarf_Bool debug_addr_unavailable = FALSE;
/* Actual addresses are most likely what one
wants to know, not the lengths/offsets
recorded in .debug_rnglists. */
res = dwarf_get_rnglists_entry_fields_a(rnglhead,
i,&entrylen,&code,
&rawlowpc,&rawhighpc,
&debug_addr_unavailable,
&lowpc,&highpc,error);
if (res != DW_DLV_OK) {
dwarf_dealloc_rnglists_head(rnglhead);
return res;
}
if (code == DW_RLE_end_of_list) {
/* we are done */
break;
}
if (code == DW_RLE_base_addressx ||
code == DW_RLE_base_address) {
/* We do not need to use these, they
have been accounted for already. */
continue;
}
if (debug_addr_unavailable) {
/* lowpc and highpc are not real addresses */
continue;
}
/* Here do something with lowpc and highpc, these
are real addresses */
}
dwarf_dealloc_rnglists_head(rnglhead);
return DW_DLV_OK;
}
\fP
.DE
.in -2
.H 4 "dwarf_rnglists_get_rle_head()"
This function is used to enable
access to the specific set of rnglist entries
applying to a specific
\f(CWDW_AT_rangees\fP
attribute.
.DS
\f(CWint dwarf_rnglists_get_rle_head( Dwarf_Attribute attr,
Dwarf_Half theform,
Dwarf_Unsigned attr_val,
Dwarf_Rnglists_Head *head_out,
Dwarf_Unsigned *entries_count_out,
Dwarf_Unsigned *global_offset_of_rle_set,
Dwarf_Error *error); \fP
.DE
.P
Given a
\f(CWDW_AT_ranges\fP
\f(CWDwarf_Attribute\fP, the FORM
from that attribute, and the value of the
the attribute (which might be an index from
\f(CWDW_FORM_rnglistx\fP
or a section offset from
\f(CWDW_FORM_sec_offset\fP
the function determines which
\f(CWDwarf_Rnglists_Head\fP
applies and returns the pointer on
success (meaning it returned .
\f(CWDW_DLV_OK\fP).
And on sucess it also returns the global
offset of a set of rnglist entries
within that particular Dwarf_Rnglists_Head
(not needed except to show it to users)
as well as the count of entries in that set
(which is crucial to iterate through
the rnglist entries applicable).
.P
If not successful none of the pointers
\f(CWhead_out\fP,
\f(CWentries_count_out\fP,
\f(CWglobal_offset\fP
will not be touched by the function.
.P
If there is some problem with the section it
will return
\f(CWDW_DLV_ERROR\fP and return
the error informatio through.
\f(CW*error\fP.
.P
There is, currently, no situation in which
it will return
\f(CWDW_DLV_NO_ENTRY\fP.
.P
See
\f(CWdwarf_dealloc_rnglists_head()\fP
below to release the storage allocated
by a successful call here.
.H 4 "dwarf_get_rnglist_head_basics()"
.DS
int dwarf_get_rnglist_head_basics(
Dwarf_Rnglists_Head head,
Dwarf_Unsigned * rle_count,
Dwarf_Unsigned * rle_version,
Dwarf_Unsigned * rnglists_index_returned,
Dwarf_Unsigned * bytes_total_in_rle,
unsigned * offset_size,
unsigned * address_size,
unsigned * segment_selector_size,
Dwarf_Unsigned * overall_offset_of_this_context,
Dwarf_Unsigned * total_length_of_this_context,
Dwarf_Bool * rnglists_base_present,
Dwarf_Unsigned * rnglists_base,
Dwarf_Bool * rnglists_base_address_present,
Dwarf_Unsigned * rnglists_base_address,
Dwarf_Bool * rnglists_debug_addr_base_present,
Dwarf_Unsigned * rnglists_debug_addr_base,
Dwarf_Error *error)
.DE
The function
\f(CWdwarf_get_rnglist_head_basics()\fP
allows caller to print or display the fields
of the Dwarf_Rnglists_Head that might be
of interest for understanding the section data
for that
\f(CWDwarf_Rnglists_Head\fP.
.P
It is not needed to access the rangelist data.
It currently returns only \f(CWDW_DLV_OK\fP.
\f(CW
\fP
.H 4 "dwarf_get_rnglists_entry_fields_a()"
.DS
\f(CWint dwarf_get_rnglists_entry_fields_a(
Dwarf_Rnglists_Head head,
Dwarf_Unsigned entrynum,
unsigned *entrylen,
unsigned *code,
Dwarf_Unsigned *raw1,
Dwarf_Unsigned *raw2,
Dwarf_Bool *debug_addr_unavailable,
Dwarf_Unsigned *cooked1,
Dwarf_Unsigned *cooked2,
Dwarf_Error *err)\fP
.DE
This is the function to access the
rnglist entries for this
\f(CWDwarf_Rnglists_Head\fP
\f(CWCall this with\fP
\f(CWentrynum\fP
in the normal iteration
"i = 0; i < entries_count; ++i"
where
\f(CWentries_count\fP
was returned by
\f(CWdwarf_rnglists_get_rle_head()\fP
through a pointer.
.P
On success
\f(CWDW_DLV_OK\fP
is returned
and the following fields are set through
the pointers.
.P
The
\f(CWentrylen\fP
value returned is the length, in bytes,
of the single entry's length.
.P
The
\f(CWcode\fP
value returned is the type of entry,
\f(CWDW_RLE_startx_endx\fP
(see
\f(CWdwarf.h\fP).
.P
The
\f(CWraw1\fP
and
\f(CWraw2\fP
values returned are the actual values
in the rangelist entry (address, length,
or index depending).
For basename entries both
values are set to the single value in the entry
(an address or index).
For end of list entries neither value is set.
.P
If
\f(CWdebug_addr_unavailable\fP
is returns non-zero then
the
\f(CWcooked1\fP
and
\f(CWcooked2\fP
values are not set usefully
and should be ignored.
The issue arises because with dwp/dwo
object files the
\f(CW.debug_addr\fP
section will be in the executable
and if the
\f(CWdwarf_set_tied_dbg()\fP
function was not called to enable access
to .debug_addr the 'cooked' fields cannot
be calculated.
.P
The
\f(CWcooked1\fP
\f(CWcooked2\fP
values returned are the actual
addresses in the rangelist entry,
after any necessary translation of
indexes and offsets and lengths.
For non-basename entries these
two values are the start and end addresses
of the rnglist entry.
If and only if
\f(CWdebug_addr_unavailable\fP
returns zero.
For basename entries these
two values are both the basename address.
For end-of-list
entries neither value means anything.
.P
If the
\f(CWentrynum\fP
is out of range,
\f(CWDW_DLV_NO_ENTRY\fP
is returned.
.P
At present
\f(CWDW_DLV_ERROR\fP
is never returned, but callers
should not assume that will aways be true.
.H 4 "dwarf_get_rnglists_entry_fields()"
.DS
\f(CWint dwarf_get_rnglists_entry_fields(
Dwarf_Rnglists_Head head,
Dwarf_Unsigned entrynum,
unsigned *entrylen,
unsigned *code,
Dwarf_Unsigned *raw1,
Dwarf_Unsigned *raw2,
Dwarf_Unsigned *cooked1,
Dwarf_Unsigned *cooked2,
Dwarf_Error *err)\fP
.DE
This the same as
\f(CWdwarf_get_rnglists_entry_fields_a()\fP
except this is missing the
\f(CWdebug_addr_unavailable\fP
argument so it's impossible for callers to know
that the cooked values are not calculated.
Do not use this function.
.H 4 "dwarf_dealloc_rnglists_head()"
.DS
\f(CWint dwarf_dealloc_rnglists_head(Dwarf_Rnglists_Head /*head*/);
.DE
This frees the storage allocated by the
\f(CWdwarf_rnglists_get_rle_head()\fP
call that created the \f(CWDwarf_Rnglists_Head\fP pointer.
.P
It only returns DW_DLV_OK.
.H 3 "Getting raw .debug_rnglists entries"
This set of interfaces is to read the
(entire)
\f(CW.debug_rnglists\fP
section without reference
to any DIE.
As such these can only present the
raw data from the file. There is no way
in these interfaces to get actual addresses.
These might be of interest if you want to
know exactly what the compiler output in
the
\f(CW.debug_rnglists\fP
section.
"dwarfdump ----print-raw-rnglists"
(try adding -v or -vvv)
makes these calls.
.P
Here is
an example using all the following calls.
example_rngl
.in +2
.FG "Examplev dwarf_get_ranges_a()"
.DS
\f(CW
int example_raw_rnglist(Dwarf_Debug dbg,Dwarf_Error *error)
{
Dwarf_Unsigned count = 0;
int res = 0;
Dwarf_Unsigned i = 0;
res = dwarf_load_rnglists(dbg,&count,error);
if (res != DW_DLV_OK) {
return res;
}
for(i =0 ; i < count ; ++i) {
Dwarf_Unsigned header_offset = 0;
Dwarf_Small offset_size = 0;
Dwarf_Small extension_size = 0;
unsigned version = 0; /* 5 */
Dwarf_Small address_size = 0;
Dwarf_Small segment_selector_size = 0;
Dwarf_Unsigned offset_entry_count = 0;
Dwarf_Unsigned offset_of_offset_array = 0;
Dwarf_Unsigned offset_of_first_rangeentry = 0;
Dwarf_Unsigned offset_past_last_rangeentry = 0;
res = dwarf_get_rnglist_context_basics(dbg,i,
&header_offset,&offset_size,&extension_size,
&version,&address_size,&segment_selector_size,
&offset_entry_count,&offset_of_offset_array,
&offset_of_first_rangeentry,
&offset_past_last_rangeentry,error);
if (res != DW_DLV_OK) {
return res;
}
{
Dwarf_Unsigned e = 0;
unsigned colmax = 4;
unsigned col = 0;
Dwarf_Unsigned global_offset_of_value = 0;
for ( ; e < offset_entry_count; ++e) {
Dwarf_Unsigned value = 0;
int resc = 0;
resc = dwarf_get_rnglist_offset_index_value(dbg,
i,e,&value,
&global_offset_of_value,error);
if (resc != DW_DLV_OK) {
return resc;
}
/* Do something */
col++;
if (col == colmax) {
col = 0;
}
}
}
{
Dwarf_Unsigned curoffset = offset_of_first_rangeentry;
Dwarf_Unsigned endoffset = offset_past_last_rangeentry;
int rese = 0;
Dwarf_Unsigned ct = 0;
for ( ; curoffset < endoffset; ++ct ) {
unsigned entrylen = 0;
unsigned code = 0;
Dwarf_Unsigned v1 = 0;
Dwarf_Unsigned v2 = 0;
rese = dwarf_get_rnglist_rle(dbg,i,
curoffset,endoffset,
&entrylen,
&code,&v1,&v2,error);
if (rese != DW_DLV_OK) {
return rese;
}
curoffset += entrylen;
if (curoffset > endoffset) {
return DW_DLV_ERROR;
}
}
}
}
return DW_DLV_OK;
}
\fP
.DE
.in -2
.H 4 "dwarf_load_rnglists()"
.DS
\f(CWint dwarf_load_rnglists(
Dwarf_Debug dbg,
Dwarf_Unsigned *rnglists_count,
Dwarf_Error *error)\fP
.DE
On a successful call to
\f(CWdwarf_load_rnglists()\fP
the function returns
\f(CWDW_DLV_OK\fP,
sets
\f(CW*rnglists_count\fP
(if and only if
\f(CWrnglists_count\fP
is non-null) to the number of distinct
section contents that exist.
A small amount of data for each Range Line Table
is recorded in
\f(CWdbg\fP as a side effect.
Normally libdwarf will have already called this,
but if an application never requests any
\f(CW.debug_info\fP
data the section might not be loaded.
If the section is loaded this returns
very quickly and will set
\f(CW*rnglists_count\fP
just as described in this paragraph.
.P
If there is no
\f(CW.debug_rnglists\fP
section in the object file this function returns
\f(CWDW_DLV_NO_ENTRY\fP.
.P
If something is malformed it returns
\f(CWDW_DLV_ERROR\fP
and sets
\f(CW*error\fP
to the applicable error pointer describgin the problem.
.P
There is no dealloc call. Calling
\f(CWdwarf_finish()\fP
releases the modest amount of memory
recorded for this section as a side effect.
.P
.H 4 "dwarf_get_rnglist_context_basics()"
.DS
\f(CWint dwarf_get_rnglist_context_basics(Dwarf_Debug dbg,
Dwarf_Unsigned context_index,
Dwarf_Unsigned * header_offset,
Dwarf_Small * offset_size,
Dwarf_Small * extension_size,
unsigned * version, /* 5 */
Dwarf_Small * address_size,
Dwarf_Small * segment_selector_size,
Dwarf_Unsigned * offset_entry_count,
Dwarf_Unsigned * offset_of_offset_array,
Dwarf_Unsigned * offset_of_first_rangeentry,
Dwarf_Unsigned * offset_past_last_rangeentry,
Dwarf_Error * /*err*/);\fP
.DE
On success this returns
\f(CWDW_DLV_OK\fP
and returns values through the pointer arguments
(other than
\f(CWdbg\fP
or
\f(CWerror\fP)
.P
A call to
\f(CWdwarf_load_rnglists()\fP
that suceeds gets you the count
of contexts
and
\f(CWdwarf_get_rnglist_context_basics()\fP
for any "i >=0 and i < count"
gets you the context values relevant to
\f(CW.debug_rnglists\fP.
.P
Any of the pointer-arguments for returning context values
can be passed in as 0 (in which case they will be skipped).
.P
You will want
\f(CW*offset_entry_count\fP
so you can call
\f(CWdwarf_get_rnglist_offset_index_value()\fP
usefully.
.P
If the
\f(CWcontext_index\fP
passed in is out of range the function returns
\f(CWDW_DLV_NO_ENTRY\fP
.P
At the present time
\f(CWDW_DLV_ERROR\fP
is never returned.
.H 4 "dwarf_get_rnglist_offset_index_value()"
.DS
\f(CWint dwarf_get_rnglist_offset_index_value(Dwarf_Debug dbg,
Dwarf_Unsigned context_index,
Dwarf_Unsigned offsetentry_index,
Dwarf_Unsigned * offset_value_out,
Dwarf_Unsigned * global_offset_value_out,
Dwarf_Error *error)\fP
.DE
.P
On success
\f(CWdwarf_get_rnglist_offset_index_value()\fP
returns
\f(CWDW_DLV_OK\fP,
sets
\f(CW* offset_value_out\fP
to the value in the Range List Table
offset array,
and sets
\f(CW* global_offset_value_out\fP
to the section offset (in
\f(CW.debug_addr\fP)
of the offset value.
.P
Pass in
\f(CWcontext_index\fP
exactly as the same field passed to
\f(CWdwarf_get_rnglist_context_basics()\fP.
.P
Pass in
\f(CWoffset_entry_index\fP
based on the return field
\f(CWoffset_entry_count\fP
from
\f(CWdwarf_get_rnglist_context_basics()\fP,
meaning for that
\f(CWcontext_index\fP
an
\f(CWoffset_entry_index\fP >=0
and <
\f(CWoffset_entry_count\fP.
.P
Pass in
\f(CWoffset_entry_count\fP
exactly as the same field passed to
\f(CWdwarf_get_rnglist_context_basics()\fP.
.P
If one of the indexes passed in is out of range
\f(CWDW_DLV_NO_ENTRY\fP will
be returned and no return arguments touched.
.P
If there is some corruption of DWARF5 data
then
\f(CWDW_DLV_ERROR\fP
might be returned
and
\f(CW*error\fP
set to the error details.
.H 4 "dwarf_get_rnglist_rle()"
.DS
\f(CWint dwarf_get_rnglist_rle(
Dwarf_Debug dbg,
Dwarf_Unsigned contextnumber,
Dwarf_Unsigned entry_offset,
Dwarf_Unsigned endoffset,
unsigned *entrylen,
unsigned *entry_kind,
Dwarf_Unsigned *entry_operand1,
Dwarf_Unsigned *entry_operand2,
Dwarf_Error *error)\fP
.DE
On success
it returns a single
\f(CWDW_RLE*\fP
record
(see dwarf.h)
fields.
.P
\f(CWcontextnumber\fP
is the number of the current rnglist context.
.P
\f(CWentry_offset\fP
is the section offset (section-global
offset) of the next record.
.P
\f(CWendoffset\fP
is one past the last entry in this
rle context.
.P
\f(CW*entrylen\fP
returns the length in the .debug_rnglists section
of the particular record returned.
It's used to increment to the next record
within this rnglist context.
.P
\f(CW*entrykind\fP
returns is the \f(CWDW_RLE*\fP number.
.P
Some record kinds have 1 or 0 operands,
most have two operands (the records
describing ranges).
.P
If the contextnumber is out of range
it will return
\f(CWDW_DLV_NO_ENTRY\fP.
.P
If the
\f(CW.debug_rnglists\fP
section is malformed
or the
\f(CWentry_offset\fP
is incorrect
it may return
\f(CWDW_DLV_ERROR\fP.
.H 2 "Ranges Operations DWARF3,4 (.debug_ranges)"
These functions provide information about the address ranges
indicated by a \f(CWDW_AT_ranges\fP attribute (the ranges are recorded
in the \f(CW.debug_ranges\fP section) of a DIE.
These functions apply to
DWARF3 and
DWARF4.
Each call of \f(CWdwarf_get_ranges_a()\fP
or \f(CWdwarf_get_ranges()\fP
returns a an array
of Dwarf_Ranges structs, each of which represents a single ranges
entry. The struct is defined in \f(CWlibdwarf.h\fP.
.P
New in DWARF3,
for DWARF3, and DWARF4 the section contains
just ranges.
The ranges are referenced by
\f(CWDW_AT_ranges\fP
attributes in various DIEs.
.P
For DWARF5 the section
requires that each group of ranges
has a header and the compilation unit
may have a
\f(CWDW_AT_ranges_base\fP
attribute that must be added to
the \f(CWDW_AT_ranges\fP attribute value
to get the true ranges offset.
.P
(A compiler generating
\f(CWDW_AT_ranges_base\fP
will add a relocation for that attribute value
but will not have to make the
\f(CWDW_AT_ranges\fP
attributes relocatable and will thus save space
in the object (ie, .o) file
and link time.)
.H 3 "dwarf_get_ranges_section_name()"
.DS
\f(CWint dwarf_get_ranges_section_name(Dwarf_Debug dbg,
const char ** sec_name,
Dwarf_Error *error)\fP
.DE
\f(CW*dwarf_get_ranges_section_name()\fP
retrieves the object file section name of
the applicable ranges section.
This is useful for applications wanting to print
the name, but of course the object section name is not
really a part of the DWARF information.
Most applications will
probably not call this function.
It can be called at any time
after the Dwarf_Debug initialization is done.
.P
If the function succeeds, \f(CW*sec_name\fP is set to
a pointer to a string with the object section name and
the function returns \f(CWDW_DLV_OK\fP.
Do not free the string whose pointer is returned.
For non-Elf objects it is possible the string pointer
returned will be NULL or will point to an empty string.
It is up to the calling application to recognize this
possibility and deal with it appropriately.
.P
If the section does not exist the function returns
DW_DLV_NO_ENTRY.
.P
If there is an internal error detected the
function returns \f(CWDW_DLV_ERROR\fP and sets the
\f(CW*error\fP pointer.
.H 3 "dwarf_get_ranges()"
This is the original call and it will work fine when
all compilation units have the same address_size.
There is no \f(CWdie\fP argument to this original
version of the function.
Other arguments (and deallocation) match the use
of
\f(CWdwarf_get_ranges_b()\fP and
\f(CWdwarf_get_ranges_a()\fP.
.H 3 "dwarf_get_ranges_a()"
This is the same as
\f(CWdwarf_get_ranges_b()\fP
except it is missing the
\f(CWfinaloffset\fP
pointer argument, so when
reading DWARF4 split-dwarf
GNU extension DIEs
it's not possible to know the final
offset of the ranges, but few
applications will care..
.DS
\f(CWint dwarf_get_ranges_a(
Dwarf_Debug dbg,
Dwarf_Off offset,
Dwarf_Die die,
Dwarf_Ranges **ranges,
Dwarf_Signed * returned_ranges_count,
Dwarf_Unsigned * returned_byte_count,
Dwarf_Error *error)\fP
.DE
.P
Though missing
\f(CWfinaloffset\fP
this function works properly and
is usable on and DWARF2,3,4 objects.
.H 3 "dwarf_get_ranges_b()"
.DS
\f(CWint dwarf_get_ranges_b(
Dwarf_Debug dbg,
Dwarf_Off offset,
Dwarf_Die die,
Dwarf_Off *finaloffset,
Dwarf_Ranges **ranges,
Dwarf_Signed * returned_ranges_count,
Dwarf_Unsigned * returned_byte_count,
Dwarf_Error *error)\fP
.DE
The function
\f(CWdwarf_get_ranges_b()\fP returns
\f(CWDW_DLV_OK\fP and sets
\f(CW*returned_ranges_count\fP to
the count of the
number of address ranges in the group of ranges
in the .debug_ranges section where the
\f(CWDW_AT_ranges\fP attribute gives offset
\f(CWoffset\fP.
This function is new as of 10 September 2020.
.P
DWARF4 GNU split-dwarf extension ONLY:
With a .dwp object and the tied (executable,a.out)
involved the actual .debug_ranges
offset is determined from the
DW_AT_GNU_ranges_base from the tied file and
the offset from
\f(CWDW_AT_ranges\fP in the .dwp object and
returned through the
\f(CWfinaloffset\fP pointer.
If \f(CWfinaloffset\fP pointer is null the
function ignores it.
.P
If there is no use of the GNU split-dwarf
extension to DWARF4 the
\f(CWfinaloffset\fP value returned is identical to
the \f(CWoffset\fP passed in.
If the pointer is null it is ignored by the function.
.P
This function is normally used when one has
a DIE
with the
\f(CWDW_AT_ranges\fP
attribute (whose value is the offset needed).
The ranges thus apply to the DIE involved.
.P
See also
\f(CWdwarf_get_aranges()\fP,
.P
The
\f(CWoffset\fP argument should be the value of
a \f(CWDW_AT_ranges\fP
attribute of a Debugging Information Entry.
The
\f(CWdie\fP
argument should be the value of
a
\f(CWDwarf_Die\fP pointer of a
\f(CWDwarf_Die\fP with
the attribute containing
this range set offset.
Because each compilation unit
has its own address_size field this argument is necessary to
to correctly read ranges.
(Most executables have the
same address_size in every compilation unit, but
some ABIs allow multiple address sized in an executable).
If a NULL pointer is passed in libdwarf assumes
a single address_size is appropriate for all ranges records.
On success,
The call sets
\f(CW*ranges\fP to point to a block of
\f(CWDwarf_Ranges\fP
structs, one for each address range.
If the
\f(CW*returned_byte_count\fP pointer is passed as non-NULL
the number of bytes that the returned ranges
were taken from is returned through the pointer
(for example if the returned_ranges_count is 2
and the pointer-size
is 4, then returned_byte_count will be 8).
If the
\f(CW*returned_byte_count\fP pointer is passed as NULL
the parameter is ignored.
The
\f(CW*returned_byte_count\fP is only of use to certain
dumper applications, most applications will not use it.
The
\f(CWfinaloffset\fP pointer is only of use to certain
dumper applications, and if null is passed the function
ignores the argument.
.P
On error the function returns
\f(CWDW_DLV_ERROR\fP.
.P
It returns
\f(CWDW_DLV_NO_ENTRY\fP if there is no
\f(CW.debug_ranges\fP
section or if
\f(CWoffset\fP is past the end of the
\f(CW.debug_ranges\fP section.
.in +2
.FG "Examplev dwarf_get_ranges_b()"
.DS
\f(CW
void examplev(Dwarf_Debug dbg,Dwarf_Unsigned offset,Dwarf_Die die)
{
Dwarf_Signed count = 0;
Dwarf_Ranges *ranges = 0;
Dwarf_Unsigned bytes = 0;
Dwarf_Error error = 0;
Dwarf_Off finaloffset = 0;
int res = 0;
res = dwarf_get_ranges_b(dbg,offset,die,
&finaloffset, &ranges,&count,&bytes,&error);
if (res == DW_DLV_OK) {
Dwarf_Signed i;
for( i = 0; i < count; ++i ) {
Dwarf_Ranges *cur = ranges+i;
/* Use cur. */
functionusingrange(cur);
}
dwarf_ranges_dealloc(dbg,ranges,count);
}
}
\fP
.DE
.in -2
.H 3 "dwarf_ranges_dealloc()"
.DS
\f(CWint dwarf_ranges_dealloc(
Dwarf_Debug dbg,
Dwarf_Ranges *ranges,
Dwarf_Signed range_count,
);\fP
.DE
The function \f(CWdwarf_ranges_dealloc()\fP takes as input a pointer
to a block of \f(CWDwarf_Ranges\fP array and the
number of structures in the block.
It frees all the data in the array of structures.
.H 2 "Gdb Index operations"
These functions get access to the fast lookup tables
defined by gdb and gcc and stored in the
\f(CW.gdb_index\fP
section.
The section is of sufficient complexity that a number of function
interfaces are needed.
For additional information see
"https://sourceware.org/gdb/onlinedocs/gdb/"
"Index-Section-Format.html#Index-Section-Format".
(We split the url to two pieces so it can fit
on the printed page
join the pieces to make a usable url).
.H 3 "dwarf_gdbindex_header()"
.DS
int dwarf_gdbindex_header(Dwarf_Debug dbg,
Dwarf_Gdbindex * gdbindexptr,
Dwarf_Unsigned * version,
Dwarf_Unsigned * cu_list_offset,
Dwarf_Unsigned * types_cu_list_offset,
Dwarf_Unsigned * address_area_offset,
Dwarf_Unsigned * symbol_table_offset,
Dwarf_Unsigned * constant_pool_offset,
Dwarf_Unsigned * section_size,
Dwarf_Unsigned * unused_reserved,
const char ** section_name,
Dwarf_Error * error);
.DE
The function \f(CWdwarf_gdbindex_header()\fP takes as input a pointer
to a Dwarf_Debug structure and returns fields through
various pointers.
.P
If the function returns DW_DLV_NO_ENTRY
there is no .gdb_index section and none of the return-pointer argument
values are set.
.P
If the function returns DW_DLV_ERROR \f(CWerror\fP is set
to indicate the specific error, but no other return-pointer
arguments are touched.
.P
If successful, the function returns DW_DLV_OK and other values are set.
The other values are set as follows:
.P
The field \f(CW*gdbindexptr\fP is set to an opaque
pointer to a libdwarf_internal structure used as an argument
to other .gdbindex functions below.
.P
The remaining fields are set to values that are
mostly of interest to a pretty-printer application.
See the detailed layout specification for specifics.
The values returned are recorded in the
Dwarf_Gdbindex opaque structure for the other gdbindex
functions documented below.
.P
The field \f(CW*version\fP is set to the version
of the gdb index header (2)..
.P
The field \f(CW*cu_list_offset\fP is set to
the offset (in the .gdb_index section) of the
cu-list.
.P
The field \f(CW*types_cu_list_offset\fP is set to
the offset (in the .gdb_index section) of the
types-list.
.P
The field \f(CW*address_area_offset\fP is set to
the offset (in the .gdb_index section) of the
address area.
.P
The field \f(CW*symbol_table_offset\fP is set to
the offset (in the .gdb_index section) of the
symbol table.
.P
The field \f(CW*constant_pool_offset\fP is set to
the offset (in the .gdb_index section) of the
constant pool.
.P
The field \f(CW*section_size\fP is set to
the length of the .gdb_index section.
.P
The field \f(CW*unused_reserved\fP is set to
zero.
.P
The field \f(CW*section_name\fP is set to
the Elf object file section name (.gdb_index).
If a non-Elf object file has such a section
the value set might be NULL or might point to
an empty string (NUL terminated), so
code to account for NULL or empty.
.P
The field \f(CW*error\fP is not set.
.P
Here we show a use of the set of cu_list
functions (using all the functions in one
example makes it rather too long).
.in +2
.FG "Examplew dwarf_get_gdbindex_header()"
.DS
\f(CW
void examplew(Dwarf_Debug dbg
{
Dwarf_Gdbindex gindexptr = 0;
Dwarf_Unsigned version = 0;
Dwarf_Unsigned cu_list_offset = 0;
Dwarf_Unsigned types_cu_list_offset = 0;
Dwarf_Unsigned address_area_offset = 0;
Dwarf_Unsigned symbol_table_offset = 0;
Dwarf_Unsigned constant_pool_offset = 0;
Dwarf_Unsigned section_size = 0;
Dwarf_Unsigned reserved = 0;
Dwarf_Error error = 0;
const char * section_name = 0;
int res = 0;
res = dwarf_gdbindex_header(dbg,&gindexptr,
&version,&cu_list_offset, &types_cu_list_offset,
&address_area_offset,&symbol_table_offset,
&constant_pool_offset, §ion_size,
&reserved,§ion_name,&error);
if (res == DW_DLV_NO_ENTRY) {
return;
} else if (res == DW_DLV_ERROR) {
return;
}
{
/* do something with the data */
Dwarf_Unsigned length = 0;
Dwarf_Unsigned typeslength = 0;
Dwarf_Unsigned i = 0;
res = dwarf_gdbindex_culist_array(gindexptr,
&length,&error);
/* Example actions. */
if (res == DW_DLV_OK) {
for(i = 0; i < length; ++i) {
Dwarf_Unsigned cuoffset = 0;
res = dwarf_gdbindex_culist_entry(gindexptr,
i,&cuoffset,&culength,&error);
if (res == DW_DLV_OK) {
/* Do something with cuoffset, culength */
}
}
}
res = dwarf_gdbindex_types_culist_array(gindexptr,
&typeslength,&error);
if (res == DW_DLV_OK) {
for(i = 0; i < typeslength; ++i) {
Dwarf_Unsigned cuoffset = 0;
Dwarf_Unsigned tuoffset = 0;
Dwarf_Unsigned culength = 0;
Dwarf_Unsigned type_signature = 0;
res = dwarf_gdbindex_types_culist_entry(gindexptr,
i,&cuoffset,&tuoffset,&type_signature,&error);
if (res == DW_DLV_OK) {
/* Do something with cuoffset etc. */
}
}
}
dwarf_gdbindex_free(gindexptr);
}
}
\fP
.DE
.in -2
.H 3 "dwarf_gdbindex_culist_array()"
.DS
int dwarf_gdbindex_culist_array(Dwarf_Gdbindex gdbindexptr,
Dwarf_Unsigned * list_length,
Dwarf_Error * error);
.DE
The function \f(CWdwarf_gdbindex_culist_array()\fP takes as input
valid Dwarf_Gdbindex pointer.
.P
While currently only DW_DLV_OK is returned one should
test for DW_DLV_NO_ENTRY and DW_DLV_ERROR and do something
sensible if either is returned.
.P
If successful, the function
returns DW_DLV_OK
and returns the number
of entries in the culist through the\f(CWlist_length\fP
pointer.
.H 3 "dwarf_gdbindex_culist_entry()"
.DS
int dwarf_gdbindex_culist_entry(Dwarf_Gdbindex gdbindexptr,
Dwarf_Unsigned entryindex,
Dwarf_Unsigned * cu_offset,
Dwarf_Unsigned * cu_length,
Dwarf_Error * error);
.DE
The function \f(CWdwarf_gdbindex_culist_entry()\fP takes as input
valid Dwarf_Gdbindex pointer and an index into the culist array.
Valid indexes are 0 through \f(CWlist_length -1\fP .
.P
If it returns DW_DLV_NO_ENTRY there is a coding error.
If it returns DW_DLV_ERROR there is an error of some kind
and the error is indicated by
the vale returned through the \f(CWerror\fP pointer.
.P
On success it returns DW_DLV_OK and returns
the \f(CWcu_offset\fP (the section global offset of the CU
in .debug_info))
and \f(CWcu_length\fP (the length of the CU
in .debug_info) values through the pointers.
.H 3 "dwarf_gdbindex_types_culist_array()"
.DS
int dwarf_gdbindex_types_culist_array(Dwarf_Gdbindex /*gdbindexptr*/,
Dwarf_Unsigned * /*types_list_length*/,
Dwarf_Error * /*error*/);
.DE
The function \f(CWdwarf_gdbindex_types_culist_array()\fP takes as input
valid Dwarf_Gdbindex pointer.
.P
While currently only DW_DLV_OK is returned one should
test for DW_DLV_NO_ENTRY and DW_DLV_ERROR and do something
sensible if either is returned.
.P
If successful, the function
returns DW_DLV_OK
and returns the number
of entries in the types culist through the\f(CWlist_length\fP
.P
.H 3 "dwarf_gdbindex_types_culist_entry()"
.DS
int dwarf_gdbindex_types_culist_entry(
Dwarf_Gdbindex gdbindexptr,
Dwarf_Unsigned entryindex,
Dwarf_Unsigned * cu_offset,
Dwarf_Unsigned * tu_offset,
Dwarf_Unsigned * type_signature,
Dwarf_Error * error);
.DE
The function \f(CWdwarf_gdbindex_types_culist_entry()\fP takes as input
valid Dwarf_Gdbindex pointer and an index into the types culist array.
Valid indexes are 0 through \f(CWtypes_list_length -1\fP .
.P
If it returns DW_DLV_NO_ENTRY there is a coding error.
If it returns DW_DLV_ERROR there is an error of some kind.
and the error is indicated by
the value returned through the \f(CWerror\fP pointer.
.P
On success it returns DW_DLV_OK and returns
the \f(CWtu_offset\fP (the section global offset of the CU
in .debug_types))
and \f(CWtu_length\fP (the length of the CU
in .debug_types) values through the pointers.
It also returns the type signature (a 64bit value) through
the \f(CWtype_signature\fP pointer.
.H 3 "dwarf_gdbindex_addressarea()"
.DS
int dwarf_gdbindex_addressarea(Dwarf_Gdbindex /*gdbindexptr*/,
Dwarf_Unsigned * /*addressarea_list_length*/,
Dwarf_Error * /*error*/);
.DE
The function \f(CWdwarf_addressarea()\fP takes as input
valid Dwarf_Gdbindex pointer and returns
the length of the address area through \f(CWaddressarea_list_length\fP.
.P
If it returns DW_DLV_NO_ENTRY there is a coding error.
If it returns DW_DLV_ERROR there is an error of some kind.
and the error is indicated by
the value returned through the \f(CWerror\fP pointer.
.P
If successful, the function
returns DW_DLV_OK
and returns the number
of entries in the address area through the
\f(CWaddressarea_list_length\fP pointer.
.H 3 "dwarf_gdbindex_addressarea_entry()"
.DS
int dwarf_gdbindex_addressarea_entry(
Dwarf_Gdbindex gdbindexptr,
Dwarf_Unsigned entryindex,
Dwarf_Unsigned * low_address,
Dwarf_Unsigned * high_address,
Dwarf_Unsigned * cu_index,
Dwarf_Error * error);
.DE
The function \f(CWdwarf_addressarea_entry()\fP takes as input
valid Dwarf_Gdbindex pointer
and an index into the address area (valid indexes are
zero through \f(CWaddressarea_list_length - 1\fP.
.P
If it returns DW_DLV_NO_ENTRY there is a coding error.
If it returns DW_DLV_ERROR there is an error of some kind.
and the error is indicated by
the value returned through the \f(CWerror\fP pointer.
.P
If successful, the function
returns DW_DLV_OK
and returns
The
\f(CWlow_address\fP
\f(CWhigh_address\fP
and
\f(CWcu_index\fP
through the pointers.
.P
Given an open Dwarf_Gdbindex one uses the function as follows:
.P
.DS
.FG "Examplewgdbindex dwarf_gdbindex_addressarea()"
\f(CW
void examplewgdbindex(Dwarf_Gdbindex gdbindex)
{
Dwarf_Unsigned list_len = 0;
Dwarf_Unsigned i = 0;
int res = 0;
Dwarf_Error err = 0;
res = dwarf_gdbindex_addressarea(gdbindex, &list_len,&err);
if (res != DW_DLV_OK) {
/* Something wrong, ignore the addressarea */
}
/* Iterate through the address area. */
for( i = 0; i < list_len; i++) {
Dwarf_Unsigned lowpc = 0;
Dwarf_Unsigned highpc = 0;
Dwarf_Unsigned cu_index = 0;
res = dwarf_gdbindex_addressarea_entry(gdbindex,i,
&lowpc,&highpc,
&cu_index,
&err);
if (res != DW_DLV_OK) {
/* Something wrong, ignore the addressarea */
return;
}
/* We have a valid address area entry, do something
with it. */
}
}
\fP
.DE
.H 3 "dwarf_gdbindex_symboltable_array()"
.DS
int dwarf_gdbindex_symboltable_array(Dwarf_Gdbindex gdbindexptr,
Dwarf_Unsigned * symtab_list_length,
Dwarf_Error * error);
.DE
One can look at the symboltable as a two-level table (with
The outer level indexes through symbol names and the inner level
indexes through all the compilation units that
define that symbol (each symbol having a different number
of compilation units, this is not a simple rectangular table).
.P
The function \f(CWdwarf_gdbindex_symboltable_array()\fP takes as input
valid Dwarf_Gdbindex pointer.
.P
If it returns DW_DLV_NO_ENTRY there is a coding error.
If it returns DW_DLV_ERROR there is an error of some kind.
and the error is indicated by
the value returned through the \f(CWerror\fP pointer.
.P
If successful, the function
returns DW_DLV_OK
and returns
The \f(CWsymtab_list_length\fP through the pointer.
.P
Given a valid Dwarf_Gdbindex pointer, one can access the entire
symbol table as follows (using 'return' here to indicate
we are giving up due to a problem while keeping the
example code fairly short):
.DS
.FG "Examplex dwarf_gdbindex_symboltable_array()"
\f(CW
void examplex(Dwarf_Gdbindex gdbindex)
{
Dwarf_Unsigned symtab_list_length = 0;
Dwarf_Unsigned i = 0;
Dwarf_Error err = 0;
int res = 0;
res = dwarf_gdbindex_symboltable_array(gdbindex,
&symtab_list_length,&err);
if (res != DW_DLV_OK) {
return;
}
for( i = 0; i < symtab_list_length; i++) {
Dwarf_Unsigned symnameoffset = 0;
Dwarf_Unsigned cuvecoffset = 0;
Dwarf_Unsigned cuvec_len = 0;
Dwarf_Unsigned ii = 0;
const char *name = 0;
res = dwarf_gdbindex_symboltable_entry(gdbindex,i,
&symnameoffset,&cuvecoffset,
&err);
if (res != DW_DLV_OK) {
return;
}
res = dwarf_gdbindex_string_by_offset(gdbindex,
symnameoffset,&name,&err);
if(res != DW_DLV_OK) {
return;
}
res = dwarf_gdbindex_cuvector_length(gdbindex,
cuvecoffset,&cuvec_len,&err);
if( res != DW_DLV_OK) {
return;
}
for(ii = 0; ii < cuvec_len; ++ii ) {
Dwarf_Unsigned attributes = 0;
Dwarf_Unsigned cu_index = 0;
Dwarf_Unsigned reserved1 = 0;
Dwarf_Unsigned symbol_kind = 0;
Dwarf_Unsigned is_static = 0;
res = dwarf_gdbindex_cuvector_inner_attributes(
gdbindex,cuvecoffset,ii,
&attributes,&err);
if( res != DW_DLV_OK) {
return;
}
/* 'attributes' is a value with various internal
fields so we expand the fields. */
res = dwarf_gdbindex_cuvector_instance_expand_value(gdbindex,
attributes, &cu_index,&reserved1,&symbol_kind, &is_static,
&err);
if( res != DW_DLV_OK) {
return;
}
/* Do something with the attributes. */
}
}
}
\fP
.DE
.H 3 "dwarf_gdbindex_symboltable_entry()"
.DS
int dwarf_gdbindex_symboltable_entry(
Dwarf_Gdbindex gdbindexptr,
Dwarf_Unsigned entryindex,
Dwarf_Unsigned * string_offset,
Dwarf_Unsigned * cu_vector_offset,
Dwarf_Error * error);
.DE
.P
The function \f(CWdwarf_gdbindex_symboltable_entry()\fP takes as input
valid Dwarf_Gdbindex pointer and
an entry index(valid index values being zero through
\f(CWsymtab_list_length -1\fP).
.P
If it returns DW_DLV_NO_ENTRY there is a coding error.
If it returns DW_DLV_ERROR there is an error of some kind.
and the error is indicated by
the value returned through the \f(CWerror\fP pointer.
.P
If successful, the function
returns DW_DLV_OK
and returns
The \f(CWstring_offset\fP
and \f(CWcu_vector_offset\fP through the pointers.
See the example above which uses this function.
.H 3 "dwarf_gdbindex_cuvector_length()"
.DS
int dwarf_gdbindex_cuvector_length(
Dwarf_Gdbindex gdbindex,
Dwarf_Unsigned cuvector_offset,
Dwarf_Unsigned * innercount,
Dwarf_Error * error);
.DE
The function \f(CWdwarf_gdbindex_cuvector_length()\fP takes as input
valid Dwarf_Gdbindex pointer and
an a cu vector offset.
.P
If it returns DW_DLV_NO_ENTRY there is a coding error.
If it returns DW_DLV_ERROR there is an error of some kind.
and the error is indicated by
the value returned through the \f(CWerror\fP pointer.
.P
If successful, the function
returns DW_DLV_OK
and returns
the \f(CWinner_count\fP through the pointer.
The \f(CWinner_count\fP is the number of
compilation unit vectors for this array of vectors.
See the example above which uses this function.
.H 3 "dwarf_gdbindex_cuvector_inner_attributes()"
.DS
int dwarf_gdbindex_cuvector_inner_attributes(
Dwarf_Gdbindex gdbindex,
Dwarf_Unsigned cuvector_offset,
Dwarf_Unsigned innerindex,
/* The attr_value is a field of bits. For expanded version
use dwarf_gdbindex_cuvector_expand_value() */
Dwarf_Unsigned * attr_value,
Dwarf_Error * error);
.DE
The function \f(CWdwarf_gdbindex_cuvector_inner_attributes()\fP takes as input
valid Dwarf_Gdbindex pointer and
an a cu vector offset and a \f(CWinner_index\fP (valid
\f(CWinner_index\fP values are zero through \f(CWinner_count - 1\fP.
.P
If it returns DW_DLV_NO_ENTRY there is a coding error.
If it returns DW_DLV_ERROR there is an error of some kind.
and the error is indicated by
the value returned through the \f(CWerror\fP pointer.
.P
If successful, the function
returns DW_DLV_OK
and returns
The \f(CWattr_value\fP through the pointer.
The \f(CWattr_value\fP is actually composed of several fields,
see the next function which expands the value.
See the example above which uses this function.
.H 3 "dwarf_gdbindex_cuvector_instance_expand_value()"
.DS
int dwarf_gdbindex_cuvector_instance_expand_value(
Dwarf_Gdbindex gdbindex,
Dwarf_Unsigned attr_value,
Dwarf_Unsigned * cu_index,
Dwarf_Unsigned * reserved1,
Dwarf_Unsigned * symbol_kind,
Dwarf_Unsigned * is_static,
Dwarf_Error * error);
.DE
The function \f(CWdwarf_gdbindex_cuvector_instance_expand_value()\fP
takes as input
valid Dwarf_Gdbindex pointer and
an \f(CWattr_value\fP.
.P
If it returns DW_DLV_NO_ENTRY there is a coding error.
If it returns DW_DLV_ERROR there is an error of some kind.
and the error is indicated by
the value returned through the \f(CWerror\fP pointer.
.P
If successful, the function
returns DW_DLV_OK
and returns the following values through the pointers:
The \f(CWcu_index\fP field is the index in the applicable
CU list of a compilation unit. For the purpose of
indexing the CU list and the types CU list form a single
array so the \f(CWcu_index\fP can be indicating either list.
The \f(CWsymbol_kind\fP field is a small integer with the symbol kind(
zero is reserved, one is a type, 2 is a variable or enum value, etc).
The \f(CWreserved1\fP field should have the value zero
and is the value of a bit field defined as reserved for future use.
The \f(CWis_static\fP field is zero if the CU indexed is global
and one if the CU indexed is static.
See the example above which uses this function.
.H 3 "dwarf_gdbindex_string_by_offset()"
.DS
\f(CWint dwarf_gdbindex_string_by_offset(
Dwarf_Gdbindex gdbindexptr,
Dwarf_Unsigned stringoffset,
const char ** string_ptr,
Dwarf_Error * error);\fP
.DE
The function \f(CWdwarf_gdbindex_string_by_offset()\fP
takes as input
valid Dwarf_Gdbindex pointer and
a \f(CWstringoffset\fP
If it returns
\f(CWDW_DLV_NO_ENTRY\fP there is a coding error.
If it returns
\f(CWDW_DLV_ERROR\fP there is an error of some kind.
and the error is indicated by
the value returned through the \f(CWerror\fP pointer.
.P
If it succeeds, the call returns a pointer to a string
from the 'constant pool' through the \f(CWstring_ptr\fP.
The string pointed to must never be free()d.
.P
See the example above which uses this function.
.H 2 "GNU linking (.gnu_debuglink, .note.gnu.build-id) operations"
This section deals with the way GNU tools
allow creation of DWARF separated from the
executable file involved.
See
https://sourceware.org/gdb/onlinedocs/gdb/Separate-Debug-Files.html
for more information.
The function here is new in September 2019, revised
in October 2020.
An example of use follows the description
of arguments.
.P
These functions are concerned with finding
DWARF data in a companion file.
There is no Split-Dwarf involved,
this is a different way of splitting
DWARF out of an executable or
shared object..
It never applies to simple .o object files,
only to executable objects (or shared
libraries).
.H 3 "dwarf_gnu_debuglink()"
.DS
\f(CWint dwarf_gnu_debuglink(Dwarf_Debug dbg,
char **debuglink_path_returned,
unsigned char **crc_returned,
char **debuglink_fullpath_returned,
unsigned *buildid_type returned,
char **builid_returned,
unsigned *builid_length_returned,
char ***paths_returned,
unsigned *paths_count_returned,
Dwarf_Error* error);\fP
.DE
This returns
\f(CWDW_DLV_NO_ENTRY\fP
if there is neither a \f(CW.gnu_debuglink\fP object-file section
nor a \f(CW.note.gnu.build-id\fP section in the object file.
.P
If there is an error it returns
\f(CWDW_DLV_ERROR\fP
and sets
\f(CW*error\fP to point to the error value.
.P
On success it returns
\f(CWDW_DLV_OK\fP and
sets the fields through the pointers as described below.
Two fields must be free()d to avoid a memory leak.
None of the other fields should be freed.
.P
If there is a
\f(CW.gnu_debuglink\fP
section the first four fields will be set.
.P
\f(CW*debuglink_path_returned\fP
points to the null-terminated string
in the section.
Do not free this.
The bytes are in the object itself
and the pointer is invalid once
dwarf_finish() is run on the dbg.
.P
\f(CW*crc_returned\fP points
to a 4-byte CRC value. The
bytes pointed to are not a string.
.P
\f(CW*debuglink_fullpath_returned\fP
points to a full pathname derived from
the
\f(CW*debuglink_fullpath_returned\fP
string.
And then
\f(CW*debuglink_fullpath_strlen\fP
is set to the length of
\f(CW*debuglink_fullpath_returned\fP
just as
\f(CWstrlen()\fP would count the length.
Callers must free()
\f(CW*debuglink_fullpath_returned\fP.
.P
If there is a
\f(CW.note.gnu.build-id\fP
section the buildid fields will be set
through the pointers.
.P
\f(CW*buildid_type_returned\fP will be set to
the value 3.
.P
\f(CW*buildid_owner_name_returned\fP will be set to
point to the null-terminated string which will
be "GNU".
Do not free() this.
The bytes are in the object itself
and the pointer is invalid once
dwarf_finish() is run on the dbg.
.P
\f(CW*buildid_returned\fP will be set to
point to the group of bytes
of length
\f(CW*buildid_length_returned\fP.
This is not a string and is not null-terminated.
It is normally a 20-byte field to be used
in its ascii-hex form.
Do not free() this.
The bytes are in the object itself
and the pointer is invalid once
dwarf_finish() is run on the dbg.
.P
If \f(CW*paths_returned\fP
is passed as NULL then no paths
calculation will be made and
\f(CW*paths_count_returned\fP
is not referenced by libdwarf.
.P
If \f(CW*paths_returned\fP
is
passed in non-NULL then
\f(CW*paths_returned\fP
and
\f(CW*paths_count_returned\fP
provide an array of pointers-to-strings
(with the actual strings following
the array) and the count of the
pointers in the array.
When the strings are no longer needed
free()
\f(CW*paths_returned\fP.
The number of paths returned will depend
on which (of the two) sections exist and on
how many global paths have been set
by
\f(CWdwarf_add_debuglink_global_path()\fP.
and defined by the rules described in the
web page mentioned above.
The default global path is "/usr/lib/debug"
and that is set by libdwarf as
\f(CWpaths_returned[0]\fP.
.P
An example of calling this function follows
.DS
.FG "Example debuglink ()"
\f(CWvoid exampledebuglink(Dwarf_Debug dbg)
{
int res = 0;
char *debuglink_path = 0;
unsigned char *crc = 0;
char *debuglink_fullpath = 0;
unsigned debuglink_fullpath_strlen = 0;
unsigned buildid_type = 0;
char * buildidowner_name = 0;
unsigned char *buildid_itself = 0;
unsigned buildid_length = 0;
char ** paths = 0;
unsigned paths_count = 0;
Dwarf_Error error = 0;
unsigned i = 0;
/* This is just an example if one knows
of another place full-DWARF objects
may be. "/usr/lib/debug" is automatically
set. */
res = dwarf_add_debuglink_global_path(dbg,
"/some/path/debug",&error);
if (res != DW_DLV_OK) {
/* Something is wrong, but we'll ignore
that. */
}
res = dwarf_gnu_debuglink(dbg,
&debuglink_path,
&crc,
&debuglink_fullpath,
&debuglink_fullpath_strlen,
&buildid_type,
&buildidowner_name,
&buildid_itself,
&buildid_length,
&paths,
&paths_count,
&error);
if (res == DW_DLV_ERROR) {
/* Do something with the error */
return;
}
if (res == DW_DLV_NO_ENTRY) {
/* No such sections as .note.gnu.build-id
or .gnu_debuglink */
return;
}
if (debuglink_fullpath_strlen) {
printf("debuglink path: %s\\n",debuglink_path);
printf("crc length : %u crc: ",4);
for (i = 0; i < 4;++i ) {
printf("%02x",crc[i]);
}
printf("\\n");
printf("debuglink fullpath: %s\\n",debuglink_fullpath);
}
if(buildid_length) {
printf("buildid type : %u\\n",buildid_type);
printf("Buildid owner : %s\\n",buildidowner_name);
printf("buildid byte count: %u\\n",buildid_length);
printf(" ");
/* buildid_length should be 20. */
for (i = 0; i < buildid_length;++i) {
printf("%02x",buildid_itself[i]);
}
printf("\\n");
}
printf("Possible paths count %u\\n",paths_count);
for ( ; i < paths_count; ++i ){
printf("%2u: %s\\n",i,paths[i]);
}
free(debuglink_fullpath);
free(paths);
return;
}
\fP
.DE
.H 3 "dwarf_add_debuglink_global_path()"
.DS
\f(CWint dwarf_add_debuglink_global_path(Dwarf_Debug dbg,
const char * path,
Dwarf_Error* error);\fP
.DE
This is unlikely to return
\f(CWDW_DLV_ERROR\fP
unless one passes in a NULL instead of an open
\f(CWDwarf_Debug\fP.
It cannot return
\f(CWDW_DLV_NO_ENTRY\fP.
.P
On success it returns
\f(CWDW_DLV_OK\fP
after adding the path
to the global list recorded in the
\f(CWDwarf_Debug\fP.
.H 3 "dwarf_crc32()"
.DS
\f(CWint dwarf_crc32(Dwarf_Debug dbg,
unsigned char * crc_buf,
Dwarf_Error* error);
\fP
.DE
The caller must pass the address of
a 4 byte array of unsigned char in
\f(CWcrc_buf\fP.
And the Dwarf_Debug must have
been opened with
\f(CWdwarf_init_path()\fP
to be useful.
If the executable is named
\f(CWexecutable\fP
the file containing most of
the
f(CWDWARF\fP
data would often be
\f(CWexecutable.debug\fP.
This is normally called
from libdwarf code
on opening
\f(CWexecutable\fP
and
\f(CWlibdwarf\fP
may call this function on
\f(CWexecutable.debug\fP.
Library users could would likely
never call it.
.P
On success it returns
\f(CWDW_DLV_OK\fP
and sets the 4 bytes
pointed to by
\f(CWcrc_buf\fP
to the calculated CRC value.
.P
If it returns
\f(CWDW_DLV_NO_ENTRY\fP
or
\f(CWDW_DLV_ERROR\fP
somethine went wrong and
\f(CWcrc_buf\fP
is not touched.
.P
The function was added October 2020.
.H 3 "dwarf_basic_crc32()"
.DS
\f(CWunsigned int dwarf_crc32(const unsigned char *buf,
int len,
unsigned int init);
\fP
.DE
This computes the crc on
\f(CWbuf\fP
of length
\f(CWlen\fP with initial
value
\f(CWinit\fP.
See libdwarf source
for the details of calling this.
It is not likely useful for
library uses to call this directly.
.P
The function was added October 2020.
.H 2 "DWARF5 .debug_sup section access"
The .debug_sup section is new in DWARF5
and this function returns all the data
in that section.
The section enables splitting off some
DWARF5 information to a separate file,
enabling a debugger to find the file,
and ensuring the file found actually matches.
See the DWARF5 standard.
.H 3 "dwarf_get_debug_sup()"
.DS
\f(CWint dwarf_get_debug_sup(Dwarf_Debug dbg,
Dwarf_Half * version,
Dwarf_Small * is_supplementary,
char ** filename,
Dwarf_Unsigned * checksum_len,
Dwarf_Small ** checksum,
Dwarf_Error* error);\fP
.DE
On success it returns
\f(CWDW_DLV_OK\fP
and sets values through the
pointer fields (other than
\f(CWerror\fP).
If any of the pointer fields
are NULL those pointers are ignored.
There is nothing resulting from
this call to free or dealloc.
.P
The pointer values are as follows:
.P
\f(CWversion\fP is defined to be 2,
and any other value is an error
(libdwarf does not indicate an error).
.P
\f(CWis_supplementary\fP is a flag
and only 0 or 1 should be present.
and any other value is an error, though
libdwarf does not indicate an error.
.P
\f(CWfilename\fP
is a null-terminated string.
.P
\f(CWchecksum_len\fP
is the length, in bytes, of the
data \f(CWchecksum\fP points to.
.P
If there is no .debug_sup section or
if that is empty
\f(CWDW_DLV_NO_ENTRY\fP
is returned.
.P
On error (for example, if a field runs
off the end of the section due to data corruption)
\f(CWDW_DLV_ERROR\fP is returned
and
\f(CW*error\fP returns the error information
as is standard in libdwarf.
.H 2 "Debug Fission (.debug_tu_index, .debug_cu_index) operations"
We name things "xu" as these sections have the same format
so we let "x" stand for either section.
The DWARF5 standard refers to Split Dwarf while
libdwarf tends to refer to this as "Fission".
.P
These functions get access to the index functions needed
to access and print the contents of an object file
which is an aggregate of .dwo objects.
These sections are implemented in gcc/gdb and are
DWARF5.
The idea is that much debug information can be separated
off into individual .dwo Elf objects and then aggregated
simply into a single .dwp object so the executable need not
have the complete debug information in it at runtime
yet allow good debugging.
.P
For additional information, see
"https://gcc.gnu.org/wiki/DebugFissionDWP",
"https://gcc.gnu.org/wiki/DebugFission",
and
"http://www.bayarea.net/~cary/dwarf/Accelerated%20Access%20Diagram.png"
and as of 17 February 2017, the DWARF5 standard.
.P
There are FORM access functions related
to Debug Fission (Split Dwarf).
See
\f(CWdwarf_formaddr()\fP
and
\f(CWdwarf_get_debug_addr_index()\fP
and
\f(CWdwarf_get_debug_str_index()\fP.
.P
The FORM with the hash value (for a reference
to a type unit ) is
\f(CWDW_FORM_ref_sig8\fP.
.P
In a compilation unit of Debug Fission object
(or a .dwp Package FIle)
\f(CWDW_AT_dwo_id\fP
the hash is expected to be
\f(CWDW_FORM_data8\fP.
.P
The \f(CWDWARF5\fP standard defines the hash as an 8 byte value
which we could use \f(CWDwarf_Unsigned\fP.
Instead (and mostly for type safety) we define
the value as a structure whose type name is
\f(CWDwarf_Sig8\fP.
.P
To look up a name in the hash (to find
which CU(s) it exists in).
use
\f(CWdwarf_get_debugfission_for_key()fP,
defined below.
.P
The second group of interfaces here
beginning with
\f(CWdwarf_get_xu_index_header()\fP
are useful if one wants to print
a .debug_tu_index or .debug_cu_index section.
.P
To access DIE, macro, etc information
the support is built into DIE, Macro, etc operations
so applications usually won't need to use these
operations at all.
.H 3 "Dwarf_Debug_Fission_Per_CU"
.DS
#define DW_FISSION_SECT_COUNT 12
struct Dwarf_Debug_Fission_Per_CU_s {
/* Do not free the string. It contains "cu" or "tu". */
/* If this is not set (ie, not a CU/TU in DWP Package File)
then pcu_type will be NULL. */
const char * pcu_type;
/* pcu_index is the index (range 1 to N )
into the tu/cu table of offsets and the table
of sizes. 1 to N as the zero index is reserved
for special purposes. Not a value one
actually needs. */
Dwarf_Unsigned pcu_index;
Dwarf_Sig8 pcu_hash; /* 8 byte */
/* [0] has offset and size 0.
[1]-[8] are DW_SECT_* indexes and the
values are the offset and size
of the respective section contribution
of a single .dwo object. When pcu_size[n] is
zero the corresponding section is not present. */
Dwarf_Unsigned pcu_offset[DW_FISSION_SECT_COUNT];
Dwarf_Unsigned pcu_size[DW_FISSION_SECT_COUNT];
Dwarf_Unsigned unused1;
Dwarf_Unsigned unused2;
};
.DE
.P
The structure is used to return data to callers with
the data from either .debug_tu_index or .debug_cu_index
that is applicable to a single compilation unit or type unit.
.P
Callers to the applicable functions (see below)
should allocate the structure and zero all the
bytes in it. The structure has a few
fields that are presently unused. These
are reserved for future use since it is
impossible to alter the structure without
breaking binary compatibility.
.H 3 "dwarf_die_from_hash_signature()"
.DS
int dwarf_die_from_hash_signature(Dwarf_Debug dbg,
Dwarf_Sig8 * hash_sig,
const char * sig_type,
Dwarf_Die* returned_die,
Dwarf_Error* error);
.DE
The function
\f(CWdwarf_die_from_hash_signature()\fP
is the most direct way to go from
the hash data from a
\f(CWDW_FORM_ref_sig8\fP
or
a
\f(CWDW_AT_dwo_id\fP (form
\f(CWDW_FORM_data8\fP)
to a DIE from a .dwp package file
or a .dwo object file ( .dwo access
not supported yet).
.P
The caller passes in
\f(CWdbg\fP which should be
\f(CWDwarf_Debug\fP open/initialized
on a .dwp package file (or a .dwo object file).
.P
The caller also passes in
\f(CWhash_sig\fP, a pointer to the
hash signature for which the caller
wishes to find a DIE.
.P
The caller also passes in
\f(CWsig_type\fP which must
contain either "tu" (identifying
the hash referring to a type unit)
or "cu" (identifying the hash as referring
to a compilation unit).
.P
On success the function returns
\f(CWDW_DLV_OK\fP and sets
\f(CW*returned_die\fP to be a
pointer to a valid DIE for the
compilation unit or type unit.
If the type is "tu" the DIE returned
is the specific type DIE that the
hash refers to.
If the type is "cu" the DIE returned
is the compilation unit DIE of the
compilation unit referred to.
.P
When appropriate the caller should
free the space of the returned DIE
by a call something like
.DS
dwarf_dealloc(dbg,die,DW_DLA_DIE);
.DE
.P
If there is no DWP Package File section
or the hash cannot be found
the function returns
\f(CWDW_DLV_NO_ENTRY\fP and leaves \f(CWreturned_die\fP
untouched. Only .dwo objects and .dwp package files
have the package file index sections.
.P
If there is an error of some sort
the function returns
\f(CWDW_DLV_ERROR\fP, leaves \f(CWreturned_die\fP
untouched, and sets \f(CW*error\fP to indicate
the precise error encountered.
.P
.H 3 "dwarf_get_debugfission_for_die()"
.DS
int dwarf_get_debugfission_for_die(Dwarf_Die die,
Dwarf_Debug_Fission_Per_CU * percu_out,
Dwarf_Error * error);
.DE
The function
\f(CWdwarf_get_debugfission_for_die()\fP
returns the debug fission for the compilation
unit the DIE is a part of.
Any DIE in the compilation (or type) unit
will get the same result.
.P
On a call to this function ensure the pointed-to
space is fully initialized.
.P
On success the function returns
\f(CWDW_DLV_OK\fP and fills in the
fields of \f(CW*percu_out\fP for which
it has data.
.P
If there is no DWP Package File section
the function returns
\f(CWDW_DLV_NO_ENTRY\fP and leaves \f(CW*percu_out\fP
untouched. Only .dwp package files
have the package file index sections.
.P
If there is an error of some sort
the function returns
\f(CWDW_DLV_ERROR\fP, leaves \f(CW*percu_out\fP
untouched, and sets \f(CW*error\fP to indicate
the precise error encountered.
.H 3 "dwarf_get_debugfission_for_key()"
.DS
int dwarf_get_debugfission_for_key(Dwarf_Debug dbg,
Dwarf_Sig8 * key,
const char * key_type ,
Dwarf_Debug_Fission_Per_CU * percu_out,
Dwarf_Error * error);
.DE
The function
\f(CWdwarf_get_debugfission_for_key()\fP
returns the debug fission data
for the
compilation unit in a .dwp package file.
.P
If there is no DWP Package File section
the function returns
\f(CWDW_DLV_NO_ENTRY\fP and leaves \f(CW*percu_out\fP
untouched. Only .dwp package files
have the package file index sections.
.P
If there is an error of some sort
the function returns
\f(CWDW_DLV_ERROR\fP, leaves \f(CW*percu_out\fP
untouched, and sets \f(CW*error\fP to indicate
the precise error encountered.
.H 3 "dwarf_get_xu_index_header()"
.DS
int dwarf_get_xu_index_header(Dwarf_Debug dbg,
const char * section_type, /* "tu" or "cu" */
Dwarf_Xu_Index_Header * xuhdr,
Dwarf_Unsigned * version_number,
Dwarf_Unsigned * offsets_count /* L*/,
Dwarf_Unsigned * units_count /* N*/,
Dwarf_Unsigned * hash_slots_count /* M*/,
const char ** sect_name,
Dwarf_Error * err);
.DE
The function \f(CWdwarf_get_xu_index_header()\fP
takes as input a
valid Dwarf_Debug pointer and
an \f(CWsection_type\fP value, which must one of the
strings \f(CWtu\fP or \f(CWcu\fP.
.P
It returns DW_DLV_NO_ENTRY if the section requested
is not in the object file.
.P
It returns DW_DLV_ERROR there is an error of some kind.
and the error is indicated by
the value returned through the \f(CWerror\fP pointer.
.P
If successful, the function
returns DW_DLV_OK
and returns the following values through the pointers:
.P
The \f(CWxuhdr\fP field is a pointer usable in
other operations (see below).
.P
The \f(CWversion_number\fP field is a the index version
number.
For gcc before DWARF5 the version number is 2.
For DWARF5 the version number is 5.
.P
The \f(CWoffsets_count\fP field is a the number
of columns in the table of section offsets.
Sometimes known as \f(CWL\fP.
.P
The \f(CWunits_count\fP field is a the number
of compilation units or type units in the index.
Sometimes known as \f(CWN\fP.
.P
The \f(CWhash_slots_count\fP field is a the number
of slots in the hash table.
Sometimes known as \f(CWM\fP.
.P
The \f(CWsect_name\fP field is the name
of the section in the object file.
Because non-Elf objects may not use section names
callers must recognize that the sect_name may be
set to NULL (zero) or to point to the empty string
and this is not considered an error.
.P
An example of initializing and disposing
of a \f(CWDwarf_Xu_Index_Header\fP follows.
.DS
.FG "Exampley dwarf_get_xu_index_header()"
\f(CW
void exampley(Dwarf_Debug dbg, const char *type)
{
/* type is "tu" or "cu" */
int res = 0;
Dwarf_Xu_Index_Header xuhdr = 0;
Dwarf_Unsigned version_number = 0;
Dwarf_Unsigned offsets_count = 0; /*L */
Dwarf_Unsigned units_count = 0; /* M */
Dwarf_Unsigned hash_slots_count = 0; /* N */
Dwarf_Error err = 0;
const char * section_name = 0;
res = dwarf_get_xu_index_header(dbg,
type,
&xuhdr,
&version_number,
&offsets_count,
&units_count,
&hash_slots_count,
§ion_name,
&err);
if (res == DW_DLV_NO_ENTRY) {
/* No such section. */
return;
}
if (res == DW_DLV_ERROR) {
/* Something wrong. */
return;
}
/* Do something with the xuhdr here . */
dwarf_xu_header_free(xuhdr);
}
\fP
.DE
.H 3 "dwarf_get_xu_index_section_type()"
.DS
int dwarf_get_xu_index_section_type(
Dwarf_Xu_Index_Header xuhdr,
const char ** typename,
const char ** sectionname,
Dwarf_Error * error);
.DE
The function \f(CWdwarf_get_xu_section_type()\fP
takes as input a
valid \f(CWDwarf_Xu_Index_Header\fP.
It is only useful when one already as an
open \f(CWxuhdr\fP but one does not know if
this is a type unit or compilation unit index section.
.P
If it returns DW_DLV_NO_ENTRY something is wrong
(should never happen).
If it returns DW_DLV_ERROR something is wrong and
the \f(CWerror\fP field is set to indicate a specific error.
.P
If successful, the function returns DW_DLV_OK
and sets the following arguments through the pointers:
.P
\f(CWtypename\fP is set to the string \f(CWtu\fP
or \f(CWcu\fP to indicate the index is of a type unit
or a compilation unit, respectively.
.P
\f(CWsectionname\fP is set to name of the object
file section.
Because non-Elf objects may not use section names
callers must recognize that the sect_name may be
set to NULL (zero) or to point to the empty string
and this is not considered an error.
.P
Neither string should be free()d.
.H 3 "dwarf_get_xu_header_free()"
.DS
void dwarf_xu_header_free(Dwarf_Xu_Index_Header xuhdr);
.DE
The function \f(CWdwarf_get_xu_header_free()\fP
takes as input a valid \f(CWDwarf_Xu_Index_Header\fP
and frees all the special data allocated for this
access type. Once called, any pointers returned
by use of the \f(CWxuhdr\fP should be considered
stale and unusable.
.H 3 "dwarf_get_xu_hash_entry()"
.DS
int dwarf_get_xu_hash_entry(
Dwarf_Xu_Index_Header xuhdr,
Dwarf_Unsigned index,
Dwarf_Sig8 * hash_value,
Dwarf_Unsigned * index_to_sections,
Dwarf_Error * error);
.DE
The function \f(CWdwarf_get_xu_hash_entry()\fP
takes as input a valid \f(CWDwarf_Xu_Index_Header\fP
and an \f(CWindex\fP of a hash slot entry
(valid hash slot index values are zero (0) through
\f(CWhash_slots_count -1\fP (M-1)).
.P
If it returns DW_DLV_NO_ENTRY something is wrong
.P
If it returns DW_DLV_ERROR something is wrong and
the \f(CWerror\fP field is set to indicate a specific error.
.P
If successful, the function returns DW_DLV_OK
and sets the following arguments through the pointers:
.P
\f(CWhash_value\fP is set to the 64bit hash of of the symbol name.
.P
\f(CWindex_to_sections\fP is set to the index into offset-size tables
of this hash entry.
.P
If both \f(CWhash_value\fP and \f(CWindex_to_sections\fP are
zero (0)
then the hash slot is unused.
\f(CWindex_to_sections\fP is used in calls to
the function \f(CWdwarf_get_xu_section_offset()\fP
as the \f(CWrow_index\fP.
.P
An example of use follows.
.DS
.FG "Examplez dwarf_get_xu_hash_entry()"
\f(CW
void examplez( Dwarf_Xu_Index_Header xuhdr,
Dwarf_Unsigned hash_slots_count)
{
/* hash_slots_count returned by
dwarf_get_xu_index_header(), see above. */
static Dwarf_Sig8 zerohashval;
Dwarf_Error err = 0;
Dwarf_Unsigned h = 0;
for( h = 0; h < hash_slots_count; h++) {
Dwarf_Sig8 hashval;
Dwarf_Unsigned index = 0;
int res = 0;
res = dwarf_get_xu_hash_entry(xuhdr,h,
&hashval,&index,&err);
if (res == DW_DLV_ERROR) {
/* Oops. hash_slots_count wrong. */
return;
} else if (res == DW_DLV_NO_ENTRY) {
/* Impossible */
return;
} else if (!memcmp(&hashval,&zerohashval,
sizeof(Dwarf_Sig8))
&& index == 0 ) {
/* An unused hash slot */
continue;
}
/* Here, hashval and index (a row index into
offsets and lengths) are valid.
But the row to be passed into
various functions here is index-1. */
}
}
\fP
.DE
.H 3 "dwarf_get_xu_section_names()"
.DS
int dwarf_get_xu_section_names(
Dwarf_Xu_Index_Header xuhdr,
Dwarf_Unsigned column_index,
Dwarf_Unsigned* number,
const char ** name,
Dwarf_Error * err);
.DE
The function \f(CWdwarf_get_xu_section_names()\fP
takes as input a valid \f(CWDwarf_Xu_Index_Header\fP
and a \f(CWcolumn_index\fP of a hash slot entry
(valid column_index values are zero (0) through
\f(CWoffsets_count -1\fP (L-1)).
.P
If it returns DW_DLV_NO_ENTRY something is wrong
.P
If it returns DW_DLV_ERROR something is wrong and
the \f(CWerror\fP field is set to indicate a specific error.
.P
If successful, the function returns DW_DLV_OK
and sets the following arguments through the pointers:
.P
\f(CWnumber\fP is set to a number identifying which section
this column applies to. For example, if the value is
\f(CWDW_SECT_INFO\fP
(1) the column came from a .debug_info.dwo section.
See the table of \f(CWDW_SECT_\fP identifiers and
assigned numbers in DWARF5.
.P
\f(CWname\fP is set to the applicable spelling of the
section identifier, for example \f(CWDW_SECT_INFO\fP.
.H 3 "dwarf_get_xu_section_offset()"
.DS
int dwarf_get_xu_section_offset(
Dwarf_Xu_Index_Header xuhdr,
Dwarf_Unsigned row_index,
Dwarf_Unsigned column_index,
Dwarf_Unsigned* sec_offset,
Dwarf_Unsigned* sec_size,
Dwarf_Error * error);
.DE
The function \f(CWdwarf_get_xu_section_offset()\fP
takes as input a valid \f(CWDwarf_Xu_Index_Header\fP
and a \f(CWrow_index\fP
(see \f(CWdwarf_get_xu_hash_entry()\fP above)
and a \f(CWcolumn_index\fP.
.P
Valid row_index values are zero (0) through
\f(CWunits_count-1\fP (N) but one uses
\f(CWdwarf_get_xu_hash_entry()\fP
(above) to get
row index and it returns a 1-origin index as
that is what the DWARF5 standard specifies.
Since a zero index from
\f(CWdwarf_get_xu_hash_entry()\fP
means this is not an actual entry such must be skipped.
.P
Hence it makes (some) sense to subtract one
making a zero-origin as that is the sense of
all but the first row of the offsets table.
.P
Valid column_index values are zero (0) through
\f(CWoffsets_count -1\fP (L-1).
.P
If it returns DW_DLV_NO_ENTRY something is wrong.
.P
If it returns DW_DLV_ERROR something is wrong and
the \f(CWerror\fP field is set to indicate a specific error.
.P
If successful, the function returns DW_DLV_OK
and sets the following arguments through the pointers:
.P
\f(CWsec_offset\fP, (\f(CWbase offset\fP) is set to
the base offset of the initial compilation-unit-header
section taken from a .dwo object.
The base offset is the data
from a single section of a .dwo object.
.P
\f(CWsec_size\fP is set to
the length of the original section taken from
a .dwo object.
This is the length in the applicable
section in the .dwp over which the base offset applies.
.P
An example of use of
\f(CWdwarf_get_xu_section_names()\fP
and
\f(CWdwarf_get_xu_section_offset()\fP
follows.
.DS
.FG "Exampleza dwarf_get_xu_section_names()"
\f(CW
void exampleza(Dwarf_Xu_Index_Header xuhdr,
Dwarf_Unsigned offsets_count, Dwarf_Unsigned index )
{
Dwarf_Error err = 0;
Dwarf_Unsigned col = 0;
/* We use 'offsets_count' returned by
a dwarf_get_xu_index_header() call.
We use 'index' returned by a
dwarf_get_xu_hash_entry() call. */
for (col = 0; col < offsets_count; col++) {
Dwarf_Unsigned off = 0;
Dwarf_Unsigned len = 0;
const char * name = 0;
Dwarf_Unsigned num = 0;
int res = 0;
res = dwarf_get_xu_section_names(xuhdr,
col,&num,&name,&err);
if (res != DW_DLV_OK) {
break;
}
res = dwarf_get_xu_section_offset(xuhdr,
index-1,col,&off,&len,&err);
if (res != DW_DLV_OK) {
break;
}
/* Here we have the DW_SECT_ name and number
and the base offset and length of the
section data applicable to the hash
that got us here.
Use the values.*/
}
}
.DE
.H 2 "TAG ATTR etc names as strings"
These functions turn a value into a string.
So applications wanting the string "DW_TAG_compile_unit"
given the value 0x11 (the value defined for this TAG) can do so easily.
The general form is
.in +2
.DS
\f(CWint dwarf_get_<something>_name(
unsigned value,
char **s_out,
);\fP
.DE
.in -2
If the \f(CWvalue\fP passed in is known, the function
returns \f(CWDW_DLV_OK\fP and places a pointer to the appropriate string
into \f(CW*s_out\fP. The string is in static storage
and applications must never free the string.
If the \f(CWvalue\fP is not known, \f(CWDW_DLV_NO_ENTRY\fP is returned
and \f(CW*s_out\fP is not set. \f(CWDW_DLV_ERROR\fP is never returned.
\f(CWLibdwarf\fP generates these functions at libdwarf build time
by reading dwarf.h.
All these follow this pattern rigidly, so the details of each
are not repeated for each function.
The choice of 'unsigned' for the value type argument (the code value)
argument is somewhat arbitrary, 'int' could have been used.
The library simply assumes the value passed in is applicable.
So, for example,
passing a TAG value code to \f(CWdwarf_get_ACCESS_name()\fP
is a coding error which libdwarf will process as if it was
an accessibility code value.
Examples of bad and good usage are:
.in +2
.DS
.FG "Examplezb dwarf_get_TAG_name()"
\f(CW
void examplezb(void)
{
const char * out = 0;
int res = 0;
/* The following is wrong, do not do it! */
res = dwarf_get_ACCESS_name(DW_TAG_entry_point,&out);
/* Nothing one does here with 'res' or 'out'
is meaningful. */
/* The following is meaningful.*/
res = dwarf_get_TAG_name(DW_TAG_entry_point,&out);
if( res == DW_DLV_OK) {
/* Here 'out' is a pointer one can use which
points to the string "DW_TAG_entry_point". */
} else {
/* Here 'out' has not been touched, it is
uninitialized. Do not use it. */
}
}
\fP
.DE
.in -2
.H 3 "dwarf_get_ACCESS_name()"
Returns an accessibility code name through the \f(CWs_out\fP pointer.
.H 3 "dwarf_get_AT_name()"
Returns an attribute code name through the \f(CWs_out\fP pointer.
.H 3 "dwarf_get_ATE_name()"
Returns a base type encoding name through the \f(CWs_out\fP pointer.
.H 3 "dwarf_get_ADDR_name()"
Returns an address type encoding name through the \f(CWs_out\fP pointer.
As of this writing only \f(CWDW_ADDR_none\fP is defined in \f(CWdwarf.h\fP.
.H 3 "dwarf_get_ATCF_name()"
Returns a SUN code flag encoding name through the \f(CWs_out\fP pointer.
This code flag is entirely a DWARF extension.
.H 3 "dwarf_get_CHILDREN_name()"
Returns a child determination name (which
is seen in the abbreviations section data) through the \f(CWs_out\fP pointer.
The only value this recognizes for a 'yes' value is 1.
As a flag value this is not quite correct (any non-zero value means
yes) but dealing with this is left up to client code (normally
compilers really do emit a value of 1 for a flag).
.H 3 "dwarf_get_children_name()"
Returns a child determination name through the \f(CWs_out\fP pointer,
though this version is really a libdwarf artifact.
The standard function is \f(CWdwarf_get_CHILDREN_name()\fP
which appears just above.
As a flag value this is not quite correct (any non-zero value means
yes) but dealing with this is left up to client code (normally
compilers really do emit a value of 1 for a flag).
.H 3 "dwarf_get_CC_name()"
Returns a calling convention case code name through the \f(CWs_out\fP pointer.
.H 3 "dwarf_get_CFA_name()"
Returns a call frame information instruction
name through the \f(CWs_out\fP pointer.
.H 3 "dwarf_get_DS_name()"
Returns a decimal sign code name through the \f(CWs_out\fP pointer.
.H 3 "dwarf_get_DSC_name()"
Returns a discriminant descriptor code name through the \f(CWs_out\fP pointer.
.H 3 "dwarf_get_EH_name()"
Returns a GNU exception header
code name through the \f(CWs_out\fP pointer.
.H 3 "dwarf_get_END_name()"
Returns an endian code name through the \f(CWs_out\fP pointer.
.H 3 "dwarf_get_FORM_name()"
Returns an form code name through the \f(CWs_out\fP pointer.
.H 3 "dwarf_get_FRAME_name()"
Returns a frame code name through the \f(CWs_out\fP pointer.
These are dependent on the particular ABI, so unless the
\f(CWdwarf.h\fP used to generate libdwarf matches your ABI
these names are unlikely to be very useful and certainly
won't be entirely appropriate.
.H 3 "dwarf_get_ID_name()"
Returns an identifier case code name through the \f(CWs_out\fP pointer.
.H 3 "dwarf_get_INL_name()"
Returns an inline code name through the \f(CWs_out\fP pointer.
.H 3 "dwarf_get_LANG_name()"
Returns a language code name through the \f(CWs_out\fP pointer.
.H 3 "dwarf_get_LLE_name()"
Returns a split-dwarf loclist code name through the \f(CWs_out\fP pointer.
.H 3 "dwarf_get_LNE_name()"
Returns a line table extended
opcode code name through the \f(CWs_out\fP pointer.
.H 3 "dwarf_get_LNS_name()"
Returns a line table standard
opcode code name through the \f(CWs_out\fP pointer.
.H 3 "dwarf_get_MACINFO_name()"
Returns a macro information macinfo
code name through the \f(CWs_out\fP pointer.
.H 3 "dwarf_get_MACRO_name()"
Returns a DWARF5 macro information macro
code name through the \f(CWs_out\fP pointer.
.H 3 "dwarf_get_OP_name()"
Returns a DWARF expression operation
code name through the \f(CWs_out\fP pointer.
.H 3 "dwarf_get_ORD_name()"
Returns an array ordering code name through the \f(CWs_out\fP pointer.
.H 3 "dwarf_get_TAG_name()"
Returns a TAG name through the \f(CWs_out\fP pointer.
.H 3 "dwarf_get_VIRTUALITY_name()"
Returns a virtuality code name through the \f(CWs_out\fP pointer.
.H 3 "dwarf_get_VIS_name()"
Returns a visibility code name through the \f(CWs_out\fP pointer.
.H 2 "Section Operations"
In checking DWARF in linkonce sections for correctness
it has been found useful to have certain section-oriented
operations when processing object files.
Normally these operations are not needed or useful
in a fully-linked executable or shared library.
While the code is written with Elf sections in mind,
it is quite possible to process non-Elf objects
with code that implements certain function pointers
(see \f(CWstruct Dwarf_Obj_Access_interface_s\fP).
So far no one with such non-elf code has come forward
to open-source it.
.H 3 "dwarf_get_section_count()"
.DS
\f(CWint dwarf_get_section_count(
Dwarf_Debug dbg) \fP
.DE
.P
Returns a count of the number of object sections found.
.P
If there is an incomplete or damaged dbg passed in
this can return -1;
.H 3 "dwarf_get_section_info_by_name()"
.DS
\f(CWint dwarf_get_section_info_by_name(
const char *section_name,
Dwarf_Addr *section_addr,
Dwarf_Unsigned *section_size,
Dwarf_Error *error)\fP
.DE
The function \f(CWdwarf_get_section_info_by_name()\fP
returns \f(CWDW_DLV_OK\fP if the section given by \f(CWsection_name\fP
was seen by libdwarf.
On success it sets \f(CW*section_addr\fP to the virtual address
assigned to the section by the linker or compiler and \f(CW*section_size\fP
to the size of the object section.
It returns DW_DLV_ERROR on error.
.H 3 "dwarf_get_section_info_by_index()"
.DS
\f(CWint dwarf_get_section_info_by_index(
int section_index,
const char **section_name,
Dwarf_Addr *section_addr,
Dwarf_Unsigned *section_size,
Dwarf_Error *error)\fP
.DE
The function \f(CWdwarf_get_section_info_by_index()\fP
returns \f(CWDW_DLV_OK\fP if the section given by
\f(CWsection_index\fP
was seen by libdwarf.
\f(CW*section_addr\fP to the virtual address
assigned to the section by the linker or compiler
and \f(CW*section_size\fP
to the size of the object section.
No free or deallocate of information returned should be done by
callers.
.H 2 "Utility Operations"
These functions aid in the management of errors encountered when using
functions in the \fIlibdwarf\fP library and releasing memory allocated
as a result of a \fIlibdwarf\fP operation.
.P
For clients that wish to encode LEB numbers two
interfaces are provided to the producer code's
internal LEB function.
.H 3 "dwarf_errno()"
.DS
\f(CWDwarf_Unsigned dwarf_errno(
Dwarf_Error error)\fP
.DE
The function
\f(CWdwarf_errno()\fP returns the error number corresponding
to the error specified by
\f(CWerror\fP.
.H 3 "dwarf_errmsg()"
.DS
\f(CWconst char* dwarf_errmsg(
Dwarf_Error error)\fP
.DE
The function \f(CWdwarf_errmsg()\fP returns a pointer to a
null-terminated error message string
corresponding to the error specified by
\f(CWerror\fP.
The string
should not be deallocated using \f(CWdwarf_dealloc()\fP.
The string should be considered to be a temporary string.
That is, the returned pointer may become stale if you do
libdwarf calls on the
\f(CWDwarf_Debug\fP
instance
other than
\f(CWdwarf_errmsg()\fP
or
\f(CWdwarf_errno()\fP.
So copy the errmsg string ( or print
it) but do not depend on the pointer remaining valid
past other libdwarf calls to the
\f(CWDwarf_Debug\fP instance that detected an error.
.H 3 "dwarf_errmsg_by_number()"
.DS
\f(CWconst char* dwarf_errmsg_by_number(
Dwarf_Unside errcode)\fP
.DE
The function
\f(CWdwarf_errmsg_by_number()\fP returns a pointer to a
null-terminated error message string
corresponding to the error number specified by
\f(CWerrcode\fP.
The string
should not be deallocated or freed.
If the
\f(CWerrcode\fP
is too large for the table of static error strings
a string reflecting that fact is returned.
.P
For some places in the code a
\f(CWDwarf_Error()\fP
is inconvenient and this function
lets dwarfdump report better information
in those cases.
Function new December 19, 2018.
.H 3 "dwarf_get_endian_copy_function()"
.DS
\f(CWvoid (*dwarf_get_endian_copy_function(Dwarf_Debug /*dbg*/))
(void *, const void * /*src*/, unsigned long /*srclen*/)\fP
.DE
When reader client code wants to extract endian-dependent
integers from dwarf and the existing interfaces won't do
that (for example in printing frame instructions as
done by dwarfdump)
\f(CWdwarf_get_endian_copy_function\fP
helps by returning the proper copy function
needed, the one libdwarf itself uses.
The client code needs a bit of glue to finish the job,
as demonstrated by the ASNAR macro in
dwarfdump/print_frames.c
.P
On success this returns a pointer to the correct copy function.
.P
On failure it returns the null pointer.
It's up to the client code to decide how to deal
with the situation.
In no reasonable case will the null pointer be returned.
.P
New December 2018.
.H 3 "dwarf_get_harmless_error_list()"
.DS
\f(CWint dwarf_get_harmless_error_list(Dwarf_Debug dbg,
unsigned count,
const char ** errmsg_ptrs_array,
unsigned * newerr_count);\fP
.DE
The harmless errors are not denoted by error returns from
the other libdwarf functions. Instead, this function
returns strings of any harmless errors that have been
seen in the current object. Clients never need call this, but
if a client wishes to report any such errors it may call.
Only a fixed number of harmless errors are recorded. It
is a circular list, so if more than the current maximum
is encountered older harmless error messages are lost.
The caller passes in a pointer to an array of pointer-to-char
as the argument \f(CWerrmsg_ptrs_array\fP. The caller
must provide this array, libdwarf does not provide it.
The caller need not initialize the array elements.
The caller passes in the number of elements of the array of
pointer-to-char thru \f(CWcount\fP. Since the
If there are no unreported harmless errors the function
returns \f(CWDW_DLV_NO_ENTRY\fP and the function arguments
are ignored.
Otherwise the function returns \f(CWDW_DLV_OK\fP
and uses the arguments.
\f(CWlibdwarf\fP assigns error strings to the errmsg_ptrs_array.
The MININUM(count-1, number of messages recorded) pointers are assigned
to the array. The array is terminated with a NULL pointer.
(That is, one array entry is reserved for a NULL pointer).
So if \f(CWcount\fP is 5 up to 4 strings may be returned through
the array, and one array entry is set to NULL.
Because the list is circular and messages may have been dropped
the function also returns the actual error count of harmless
errors encountered through \f(CWnewerr_count\fP
(unless the argument is NULL, in which case it is ignored).
Each call to this function resets the circular error buffer and
the error count.
So think of this call as reporting harmless errors since the
last call to it.
The pointers returned through \f(CWerrmsg_ptrs_array\fP
are only valid till the next call to libdwarf.
Do not save the pointers, they become invalid. Copy the strings
if you wish to save them.
Calling this function neither allocates any space in memory nor
frees any space in memory.
.H 3 "dwarf_insert_harmless_error()"
.DS
void dwarf_insert_harmless_error(Dwarf_Debug dbg,
char * newerror);
.DE
This function is used to test
\f(CWdwarf_get_harmless_error_list\fP. It simply adds
a harmless error string.
There is little reason client code should use this function.
It exists so that the harmless error functions can be
easily tested for correctness and leaks.
.H 3 "dwarf_set_harmless_error_list_size()"
.DS
\f(CWunsigned dwarf_set_harmless_error_list_size(Dwarf_Debug dbg,
unsigned maxcount)\fP
.DE
\f(CWdwarf_set_harmless_error_list_size\fP returns the
number of harmless error strings the library is currently
set to hold.
If \f(CWmaxcount\fP is non-zero the library changes the
maximum it will record to be \f(CWmaxcount\fP.
It is extremely unwise to make \f(CWmaxcount\fP large because
\f(CWlibdwarf\fP allocates space for \f(CWmaxcount\fP
strings immediately.
.P
The set of errors
enumerated in Figure \n(aX below were defined in Dwarf 1.
These errors are not used by the \f(CWlibdwarf\fP implementation
for Dwarf 2 or later.
.DS
.TS
center box, tab(:);
lfB lfB
l l.
SYMBOLIC NAME:DESCRIPTION
_
DW_DLE_NE:No error (0)
DW_DLE_VMM:Version of DWARF information newer
:than libdwarf
DW_DLE_MAP:Memory map failure
DW_DLE_LEE:Propagation of libelf error
DW_DLE_NDS:No debug section
DW_DLE_NLS:No line section
DW_DLE_ID:Requested information not associated
:with descriptor
DW_DLE_IOF:I/O failure
DW_DLE_MAF:Memory allocation failure
DW_DLE_IA:Invalid argument
DW_DLE_MDE:Mangled debugging entry
DW_DLE_MLE:Mangled line number entry
DW_DLE_FNO:File descriptor does not refer
:to an open file
DW_DLE_FNR:File is not a regular file
DW_DLE_FWA:File is opened with wrong access
DW_DLE_NOB:File is not an object file
DW_DLE_MOF:Mangled object file header
DW_DLE_EOLL:End of location list entries
DW_DLE_NOLL:No location list section
DW_DLE_BADOFF:Invalid offset
DW_DLE_EOS:End of section
DW_DLE_ATRUNC:Abbreviations section appears
:truncated
DW_DLE_BADBITC:Address size passed to
:dwarf bad
.TE
.FG "Dwarf Error Codes"
.DE
The set of errors returned by \f(CWLibdwarf\fP functions
is listed below.
The list does lengthen: the ones listed
here are far from a complete list.
Some of the errors are SGI specific.
See libdwarf/dwarf_errmsg_list.h
for the complete list.
.DS
.TS
center box, tab(:);
lfB lfB
l.
SYMBOLIC NAME (description not shown here)
_
DW_DLE_DBG_ALLOC
DW_DLE_FSTAT_ERROR
DW_DLE_FSTAT_MODE_ERROR
DW_DLE_INIT_ACCESS_WRONG
DW_DLE_ELF_BEGIN_ERROR
DW_DLE_ELF_GETEHDR_ERROR
DW_DLE_ELF_GETSHDR_ERROR
DW_DLE_ELF_STRPTR_ERROR
DW_DLE_DEBUG_INFO_DUPLICATE
DW_DLE_DEBUG_INFO_NULL
DW_DLE_DEBUG_ABBREV_DUPLICATE
DW_DLE_DEBUG_ABBREV_NULL
DW_DLE_DEBUG_ARANGES_DUPLICATE
DW_DLE_DEBUG_ARANGES_NULL
DW_DLE_DEBUG_LINE_DUPLICATE
DW_DLE_DEBUG_LINE_NULL
DW_DLE_DEBUG_LOC_DUPLICATE
DW_DLE_DEBUG_LOC_NULL
DW_DLE_DEBUG_MACINFO_DUPLICATE
DW_DLE_DEBUG_MACINFO_NULL
DW_DLE_DEBUG_PUBNAMES_DUPLICATE
DW_DLE_DEBUG_PUBNAMES_NULL
DW_DLE_DEBUG_STR_DUPLICATE
DW_DLE_DEBUG_STR_NULL
DW_DLE_CU_LENGTH_ERROR
DW_DLE_VERSION_STAMP_ERROR
DW_DLE_ABBREV_OFFSET_ERROR
DW_DLE_ADDRESS_SIZE_ERROR
DW_DLE_DEBUG_INFO_PTR_NULL
DW_DLE_DIE_NULL
DW_DLE_STRING_OFFSET_BAD
DW_DLE_DEBUG_LINE_LENGTH_BAD
DW_DLE_LINE_PROLOG_LENGTH_BAD
DW_DLE_LINE_NUM_OPERANDS_BAD
DW_DLE_LINE_SET_ADDR_ERROR
.TE
.FG "Dwarf 2 and later Error Codes"
.DE
This list of errors is not complete;
additional errors have been added.
Some of the above errors may be unused.
Errors may not have the same meaning in different releases.
Since most error codes are returned from only one place
(or a very small number of places) in the source
it is normally very useful to simply search the
\f(CWlibdwarf\fP source to find
out where a particular error code is generated.
See
\f(CWlibdwarf/dwarf_errmsg_list.h\fP
for the complete message set with short descriptions.
.H 3 "dwarf_dealloc()"
.DS
\f(CWvoid dwarf_dealloc(
Dwarf_Debug dbg,
void* space,
Dwarf_Unsigned type)\fP
.DE
The function \f(CWdwarf_dealloc\fP frees the dynamic storage pointed
to by \f(CWspace\fP, and allocated to the given \f(CWDwarf_Debug\fP.
The argument
\f(CWtype\fP is an integer code that specifies the allocation
type of the region pointed to by the \f(CWspace\fP. Refer to section
4 for details on \fIlibdwarf\fP memory management.
.H 3 "dwarf_encode_leb128()"
.DS
int dwarf_encode_leb128(Dwarf_Unsigned val,
int * nbytes,
char * space,
int splen);
.DE
The function \f(CWdwarf_encode_leb128\fP
encodes the value \f(CWval\fP
in the caller-provided buffer that \f(CWspace\fP
points to. The caller-provided buffer must
be at least \f(CWsplen\fP bytes long.
The function returns \f(CWDW_DLV_OK\fP
if the encoding succeeds.
If \f(CWsplen\fP is too small to encode the
value, \f(CWDW_DLV_ERROR\fP will
be returned.
If the call succeeds,
the number of bytes of \f(CWspace\fP that are used
in the encoding are returned through the pointer \f(CWnbytes\fP
.H 3 "dwarf_encode_signed_leb128()"
.DS
int dwarf_encode_signed_leb128(Dwarf_Signed val,
int * nbytes,
char * space,
int splen);
.DE
The function \f(CWdwarf_encode_signed_leb128\fP
is the same as \f(CWdwarf_encode_leb128\fP except that
the argument
\f(CWval\fP
is signed.
.H 2 "Finding Memory Leaks"
\f(CW
\fP
If you are using
\f(CWdwarf_set_de_alloc_flag(0)\fP
to turn off the garbage collection
\f(CWdwarfinish()\fP
does and you find memory leaks there
are a couple specific tools provided
that may ease the process of tracking down
the errors you have made.
.P
This chapter is new as of 26 March 2020.
.H 3 "Compiling libdwarf -DDEBUG=1"
.P
The first tool is to build libdwarf with
options
\f(CW-g -O0 -DDEBUG=1\fP.
The -O0 is simply to help a debugger,
valgrind or other too identify source lines accurately.
The
\f(CW-DDEBUG=1\fP
Turns on printf statements in
dwarf_alloc.c
and
dwarf_error.c
that emit lines like
.DS
libdwarfdetector ALLOC ret 0x... size
libdwarfdetector DEALLOC ret 0x... size
libdwarfdetector ALLOC creating error string
libdwarfdetector DEALLOC Now destruct error string
.DE
at each point of particular interest.
.P
The first two relate to actually malloc/free.
The ret 0x... will be a hex address of
the pointer yuur code is presented for allocations
inside libdwarf.
.P
The second two relate to allocation/free
of a string in Dwarf_Error record
when an error record with variable
descriptive error information is being built/freed.
.P
.H 3 "Making use of the output of -DDEBUG=1"
A small Python 3 program (alloctrack.py) in the libdwarf
regressiontests on SourceForge.net
will read through a file with libdwarfdetector
lines and report on mismatches in the alloc/dealloc
counts for each memory-blob libdwarf created.
All other lines are skipped.
.P
This has been found very useful.
.P
Since the regression tests are large
and you won't otherwise need them
a copy of alloctrack.py follows so
you need not clone the test code.
.DS
\f(CW
#!/usr/bin/env python3
# Copyright 2020 David Anderson
# This Python code is hereby placed into the public domain
# for use by anyone for any purpose.
# Useful for finding the needle of
# a single leaking allocation
# in the haystack of all the libdwarfdetector
# lines libdwarf can emit if compiled -DDEBUG=1
import sys
import os
def trackallocs(fi,valdict):
line = 0
while True:
line = int(line)+1
try:
recf = fi.readline()
except EOFError:
break
if len(recf) < 1:
# eof
break
rec = recf.strip()
if rec.find("ALLOC") != -1:
if rec.find("libdwarfdetector ALLOC ret 0x") != -1:
wds = rec.split()
off = wds[3]
if off in valdict:
(allo,deallo) = valdict[off]
if int(allo) == 0:
r = (1,deallo)
valdict[off] = r
else:
print("Duplicate use of ",off,"line",line)
r =(int(allo)+1,deallo)
valdict[off] = r
else:
allo = 1
deallo = 0
r=(allo,deallo)
valdict[off] = r
continue
if rec.find("libdwarfdetector DEALLOC ret 0x") != -1:
wds = rec.split()
off = wds[3]
if off in valdict:
(allo,deallo) = valdict[off]
if int(deallo) == 0:
r = (allo,1)
valdict[off] = r
else:
print("Duplicate use of ",off,"line",line)
r = (allo,int(deallo)+1)
valdict[off] = r
else:
allo = 0
deallo = 1
r=(allo,deallo)
valdict[off] = r
continue
if __name__ == '__main__':
if len(sys.argv) > 1:
fname = sys.argv[1]
try:
file = open(fname,"r")
except IOError as message:
print("File could not be opened: ", fname, " ", message)
sys.exit(1)
else:
file = sys.stdin
vals = {}
trackallocs(file,vals)
for s in vals:
(allo,deallo) = vals[s]
if int(allo) != int(deallo):
print("Mismatch on ",s," a vs d: ",allo,deallo)
if int(allo) > 1:
print("Reuse of ",s," a vs d: ",allo,deallo)
\fP
.DE
.SK
.S
.TC 1 1 4
.CS
|