@@ -1300,28 +1300,28 @@ calls. This descriptor results in the following DWARF tag:
1300
1300
Debugging information format
1301
1301
============================
1302
1302
1303
- Debugging Information Extension for Objective C Properties
1303
+ Debugging Information Extension for Objective- C Properties
1304
1304
----------------------------------------------------------
1305
1305
1306
1306
Introduction
1307
1307
^^^^^^^^^^^^
1308
1308
1309
- Objective C provides a simpler way to declare and define accessor methods using
1309
+ Objective- C provides a simpler way to declare and define accessor methods using
1310
1310
declared properties. The language provides features to declare a property and
1311
1311
to let compiler synthesize accessor methods.
1312
1312
1313
- The debugger lets developer inspect Objective C interfaces and their instance
1313
+ The debugger lets developer inspect Objective- C interfaces and their instance
1314
1314
variables and class variables. However, the debugger does not know anything
1315
- about the properties defined in Objective C interfaces. The debugger consumes
1315
+ about the properties defined in Objective- C interfaces. The debugger consumes
1316
1316
information generated by compiler in DWARF format. The format does not support
1317
- encoding of Objective C properties. This proposal describes DWARF extensions to
1318
- encode Objective C properties, which the debugger can use to let developers
1319
- inspect Objective C properties.
1317
+ encoding of Objective- C properties. This proposal describes DWARF extensions to
1318
+ encode Objective- C properties, which the debugger can use to let developers
1319
+ inspect Objective- C properties.
1320
1320
1321
1321
Proposal
1322
1322
^^^^^^^^
1323
1323
1324
- Objective C properties exist separately from class members. A property can be
1324
+ Objective- C properties exist separately from class members. A property can be
1325
1325
defined only by "setter" and "getter" selectors, and be calculated anew on each
1326
1326
access. Or a property can just be a direct access to some declared ivar.
1327
1327
Finally it can have an ivar "automatically synthesized" for it by the compiler,
@@ -1624,24 +1624,24 @@ The BUCKETS are an array of offsets to DATA for each hash:
1624
1624
1625
1625
So for ``bucket[3] `` in the example above, we have an offset into the table
1626
1626
0x000034f0 which points to a chain of entries for the bucket. Each bucket must
1627
- contain a next pointer, full 32 bit hash value, the string itself, and the data
1627
+ contain a next pointer, full 32- bit hash value, the string itself, and the data
1628
1628
for the current string value.
1629
1629
1630
1630
.. code-block :: none
1631
1631
1632
1632
.------------.
1633
1633
0x000034f0: | 0x00003500 | next pointer
1634
- | 0x12345678 | 32 bit hash
1634
+ | 0x12345678 | 32- bit hash
1635
1635
| "erase" | string value
1636
1636
| data[n] | HashData for this bucket
1637
1637
|------------|
1638
1638
0x00003500: | 0x00003550 | next pointer
1639
- | 0x29273623 | 32 bit hash
1639
+ | 0x29273623 | 32- bit hash
1640
1640
| "dump" | string value
1641
1641
| data[n] | HashData for this bucket
1642
1642
|------------|
1643
1643
0x00003550: | 0x00000000 | next pointer
1644
- | 0x82638293 | 32 bit hash
1644
+ | 0x82638293 | 32- bit hash
1645
1645
| "main" | string value
1646
1646
| data[n] | HashData for this bucket
1647
1647
`------------'
@@ -1650,17 +1650,17 @@ The problem with this layout for debuggers is that we need to optimize for the
1650
1650
negative lookup case where the symbol we're searching for is not present. So
1651
1651
if we were to lookup "``printf ``" in the table above, we would make a 32-bit
1652
1652
hash for "``printf ``", it might match ``bucket[3] ``. We would need to go to
1653
- the offset 0x000034f0 and start looking to see if our 32 bit hash matches. To
1653
+ the offset 0x000034f0 and start looking to see if our 32- bit hash matches. To
1654
1654
do so, we need to read the next pointer, then read the hash, compare it, and
1655
1655
skip to the next bucket. Each time we are skipping many bytes in memory and
1656
- touching new pages just to do the compare on the full 32 bit hash. All of
1656
+ touching new pages just to do the compare on the full 32- bit hash. All of
1657
1657
these accesses then tell us that we didn't have a match.
1658
1658
1659
1659
Name Hash Tables
1660
1660
""""""""""""""""
1661
1661
1662
1662
To solve the issues mentioned above we have structured the hash tables a bit
1663
- differently: a header, buckets, an array of all unique 32 bit hash values,
1663
+ differently: a header, buckets, an array of all unique 32- bit hash values,
1664
1664
followed by an array of hash value data offsets, one for each hash value, then
1665
1665
the data for all hash values:
1666
1666
@@ -1679,11 +1679,11 @@ the data for all hash values:
1679
1679
`-------------'
1680
1680
1681
1681
The ``BUCKETS `` in the name tables are an index into the ``HASHES `` array. By
1682
- making all of the full 32 bit hash values contiguous in memory, we allow
1682
+ making all of the full 32- bit hash values contiguous in memory, we allow
1683
1683
ourselves to efficiently check for a match while touching as little memory as
1684
- possible. Most often checking the 32 bit hash values is as far as the lookup
1684
+ possible. Most often checking the 32- bit hash values is as far as the lookup
1685
1685
goes. If it does match, it usually is a match with no collisions. So for a
1686
- table with "``n_buckets ``" buckets, and "``n_hashes ``" unique 32 bit hash
1686
+ table with "``n_buckets ``" buckets, and "``n_hashes ``" unique 32- bit hash
1687
1687
values, we can clarify the contents of the ``BUCKETS ``, ``HASHES `` and
1688
1688
``OFFSETS `` as:
1689
1689
@@ -1698,11 +1698,11 @@ values, we can clarify the contents of the ``BUCKETS``, ``HASHES`` and
1698
1698
| HEADER.header_data_len | uint32_t
1699
1699
| HEADER_DATA | HeaderData
1700
1700
|-------------------------|
1701
- | BUCKETS | uint32_t[n_buckets] // 32 bit hash indexes
1701
+ | BUCKETS | uint32_t[n_buckets] // 32- bit hash indexes
1702
1702
|-------------------------|
1703
- | HASHES | uint32_t[n_hashes] // 32 bit hash values
1703
+ | HASHES | uint32_t[n_hashes] // 32- bit hash values
1704
1704
|-------------------------|
1705
- | OFFSETS | uint32_t[n_hashes] // 32 bit offsets to hash value data
1705
+ | OFFSETS | uint32_t[n_hashes] // 32- bit offsets to hash value data
1706
1706
|-------------------------|
1707
1707
| ALL HASH DATA |
1708
1708
`-------------------------'
@@ -1761,26 +1761,26 @@ with:
1761
1761
| |
1762
1762
|------------|
1763
1763
0x000034f0: | 0x00001203 | .debug_str ("erase")
1764
- | 0x00000004 | A 32 bit array count - number of HashData with name "erase"
1764
+ | 0x00000004 | A 32- bit array count - number of HashData with name "erase"
1765
1765
| 0x........ | HashData[0]
1766
1766
| 0x........ | HashData[1]
1767
1767
| 0x........ | HashData[2]
1768
1768
| 0x........ | HashData[3]
1769
1769
| 0x00000000 | String offset into .debug_str (terminate data for hash)
1770
1770
|------------|
1771
1771
0x00003500: | 0x00001203 | String offset into .debug_str ("collision")
1772
- | 0x00000002 | A 32 bit array count - number of HashData with name "collision"
1772
+ | 0x00000002 | A 32- bit array count - number of HashData with name "collision"
1773
1773
| 0x........ | HashData[0]
1774
1774
| 0x........ | HashData[1]
1775
1775
| 0x00001203 | String offset into .debug_str ("dump")
1776
- | 0x00000003 | A 32 bit array count - number of HashData with name "dump"
1776
+ | 0x00000003 | A 32- bit array count - number of HashData with name "dump"
1777
1777
| 0x........ | HashData[0]
1778
1778
| 0x........ | HashData[1]
1779
1779
| 0x........ | HashData[2]
1780
1780
| 0x00000000 | String offset into .debug_str (terminate data for hash)
1781
1781
|------------|
1782
1782
0x00003550: | 0x00001203 | String offset into .debug_str ("main")
1783
- | 0x00000009 | A 32 bit array count - number of HashData with name "main"
1783
+ | 0x00000009 | A 32- bit array count - number of HashData with name "main"
1784
1784
| 0x........ | HashData[0]
1785
1785
| 0x........ | HashData[1]
1786
1786
| 0x........ | HashData[2]
@@ -1795,13 +1795,13 @@ with:
1795
1795
1796
1796
So we still have all of the same data, we just organize it more efficiently for
1797
1797
debugger lookup. If we repeat the same "``printf ``" lookup from above, we
1798
- would hash "``printf ``" and find it matches ``BUCKETS[3] `` by taking the 32 bit
1798
+ would hash "``printf ``" and find it matches ``BUCKETS[3] `` by taking the 32- bit
1799
1799
hash value and modulo it by ``n_buckets ``. ``BUCKETS[3] `` contains "6" which
1800
1800
is the index into the ``HASHES `` table. We would then compare any consecutive
1801
- 32 bit hashes values in the ``HASHES `` array as long as the hashes would be in
1801
+ 32- bit hashes values in the ``HASHES `` array as long as the hashes would be in
1802
1802
``BUCKETS[3] ``. We do this by verifying that each subsequent hash value modulo
1803
1803
``n_buckets `` is still 3. In the case of a failed lookup we would access the
1804
- memory for ``BUCKETS[3] ``, and then compare a few consecutive 32 bit hashes
1804
+ memory for ``BUCKETS[3] ``, and then compare a few consecutive 32- bit hashes
1805
1805
before we know that we have no match. We don't end up marching through
1806
1806
multiple words of memory and we really keep the number of processor data cache
1807
1807
lines being accessed as small as possible.
@@ -1842,10 +1842,10 @@ header is:
1842
1842
HeaderData header_data; // Implementation specific header data
1843
1843
};
1844
1844
1845
- The header starts with a 32 bit "``magic ``" value which must be ``'HASH' ``
1845
+ The header starts with a 32- bit "``magic ``" value which must be ``'HASH' ``
1846
1846
encoded as an ASCII integer. This allows the detection of the start of the
1847
1847
hash table and also allows the table's byte order to be determined so the table
1848
- can be correctly extracted. The "``magic ``" value is followed by a 16 bit
1848
+ can be correctly extracted. The "``magic ``" value is followed by a 16- bit
1849
1849
``version `` number which allows the table to be revised and modified in the
1850
1850
future. The current version number is 1. ``hash_function `` is a ``uint16_t ``
1851
1851
enumeration that specifies which hash function was used to produce this table.
@@ -1858,8 +1858,8 @@ The current values for the hash function enumerations include:
1858
1858
eHashFunctionDJB = 0u, // Daniel J Bernstein hash function
1859
1859
};
1860
1860
1861
- ``bucket_count `` is a 32 bit unsigned integer that represents how many buckets
1862
- are in the ``BUCKETS `` array. ``hashes_count `` is the number of unique 32 bit
1861
+ ``bucket_count `` is a 32- bit unsigned integer that represents how many buckets
1862
+ are in the ``BUCKETS `` array. ``hashes_count `` is the number of unique 32- bit
1863
1863
hash values that are in the ``HASHES `` array, and is the same number of offsets
1864
1864
are contained in the ``OFFSETS `` array. ``header_data_len `` specifies the size
1865
1865
in bytes of the ``HeaderData `` that is filled in by specialized versions of
@@ -1875,12 +1875,12 @@ The header is followed by the buckets, hashes, offsets, and hash value data.
1875
1875
struct FixedTable
1876
1876
{
1877
1877
uint32_t buckets[Header.bucket_count]; // An array of hash indexes into the "hashes[]" array below
1878
- uint32_t hashes [Header.hashes_count]; // Every unique 32 bit hash for the entire table is in this table
1878
+ uint32_t hashes [Header.hashes_count]; // Every unique 32- bit hash for the entire table is in this table
1879
1879
uint32_t offsets[Header.hashes_count]; // An offset that corresponds to each item in the "hashes[]" array above
1880
1880
};
1881
1881
1882
- ``buckets `` is an array of 32 bit indexes into the ``hashes `` array. The
1883
- ``hashes `` array contains all of the 32 bit hash values for all names in the
1882
+ ``buckets `` is an array of 32- bit indexes into the ``hashes `` array. The
1883
+ ``hashes `` array contains all of the 32- bit hash values for all names in the
1884
1884
hash table. Each hash in the ``hashes `` table has an offset in the ``offsets ``
1885
1885
array that points to the data for the hash value.
1886
1886
@@ -1967,13 +1967,13 @@ array to be:
1967
1967
HeaderData.atoms[0].form = DW_FORM_data4;
1968
1968
1969
1969
This defines the contents to be the DIE offset (eAtomTypeDIEOffset) that is
1970
- encoded as a 32 bit value (DW_FORM_data4). This allows a single name to have
1970
+ encoded as a 32- bit value (DW_FORM_data4). This allows a single name to have
1971
1971
multiple matching DIEs in a single file, which could come up with an inlined
1972
1972
function for instance. Future tables could include more information about the
1973
1973
DIE such as flags indicating if the DIE is a function, method, block,
1974
1974
or inlined.
1975
1975
1976
- The KeyType for the DWARF table is a 32 bit string table offset into the
1976
+ The KeyType for the DWARF table is a 32- bit string table offset into the
1977
1977
".debug_str" table. The ".debug_str" is the string table for the DWARF which
1978
1978
may already contain copies of all of the strings. This helps make sure, with
1979
1979
help from the compiler, that we reuse the strings between all of the DWARF
@@ -1982,7 +1982,7 @@ compiler generate all strings as DW_FORM_strp in the debug info, is that
1982
1982
DWARF parsing can be made much faster.
1983
1983
1984
1984
After a lookup is made, we get an offset into the hash data. The hash data
1985
- needs to be able to deal with 32 bit hash collisions, so the chunk of data
1985
+ needs to be able to deal with 32- bit hash collisions, so the chunk of data
1986
1986
at the offset in the hash data consists of a triple:
1987
1987
1988
1988
.. code-block :: c
@@ -1992,7 +1992,7 @@ at the offset in the hash data consists of a triple:
1992
1992
HashData[hash_data_count]
1993
1993
1994
1994
If "str_offset" is zero, then the bucket contents are done. 99.9% of the
1995
- hash data chunks contain a single item (no 32 bit hash collision):
1995
+ hash data chunks contain a single item (no 32- bit hash collision):
1996
1996
1997
1997
.. code-block :: none
1998
1998
@@ -2025,7 +2025,7 @@ If there are collisions, you will have multiple valid string offsets:
2025
2025
`------------'
2026
2026
2027
2027
Current testing with real world C++ binaries has shown that there is around 1
2028
- 32 bit hash collision per 100,000 name entries.
2028
+ 32- bit hash collision per 100,000 name entries.
2029
2029
2030
2030
Contents
2031
2031
^^^^^^^^
0 commit comments