@@ -209,22 +209,13 @@ type Symbol struct {
209
209
Name string
210
210
Info , Other byte
211
211
212
- // VersionScope describes the version in which the symbol is defined.
213
- // This is only set for the dynamic symbol table.
214
- // When no symbol versioning information is available,
215
- // this is VersionScopeNone.
216
- VersionScope SymbolVersionScope
217
- // VersionIndex is the version index.
218
- // This is only set if VersionScope is VersionScopeSpecific or
219
- // VersionScopeHidden. This is only set for the dynamic symbol table.
220
- // This index will match either [DynamicVersion.Index]
221
- // in the slice returned by [File.DynamicVersions],
222
- // or [DynamicVersiondep.Index] in the Needs field
223
- // of the elements of the slice returned by [File.DynamicVersionNeeds].
224
- // In general, a defined symbol will have an index referring
225
- // to DynamicVersions, and an undefined symbol will have an index
226
- // referring to some version in DynamicVersionNeeds.
227
- VersionIndex int16
212
+ // HasVersion reports whether the symbol has any version information.
213
+ // This will only be true for the dynamic symbol table.
214
+ HasVersion bool
215
+ // VersionIndex is the symbol's version index.
216
+ // Use the methods of the [VersionIndex] type to access it.
217
+ // This field is only meaningful if HasVersion is true.
218
+ VersionIndex VersionIndex
228
219
229
220
Section SectionIndex
230
221
Value , Size uint64
@@ -678,7 +669,6 @@ func (f *File) getSymbols32(typ SectionType) ([]Symbol, []byte, error) {
678
669
symbols [i ].Name = str
679
670
symbols [i ].Info = sym .Info
680
671
symbols [i ].Other = sym .Other
681
- symbols [i ].VersionIndex = - 1
682
672
symbols [i ].Section = SectionIndex (sym .Shndx )
683
673
symbols [i ].Value = uint64 (sym .Value )
684
674
symbols [i ].Size = uint64 (sym .Size )
@@ -726,7 +716,6 @@ func (f *File) getSymbols64(typ SectionType) ([]Symbol, []byte, error) {
726
716
symbols [i ].Name = str
727
717
symbols [i ].Info = sym .Info
728
718
symbols [i ].Other = sym .Other
729
- symbols [i ].VersionIndex = - 1
730
719
symbols [i ].Section = SectionIndex (sym .Shndx )
731
720
symbols [i ].Value = sym .Value
732
721
symbols [i ].Size = sym .Size
@@ -1473,7 +1462,7 @@ func (f *File) DynamicSymbols() ([]Symbol, error) {
1473
1462
}
1474
1463
if hasVersions {
1475
1464
for i := range sym {
1476
- sym [i ].VersionIndex , sym [i ].Version , sym [i ].Library , sym [i ].VersionScope = f .gnuVersion (i )
1465
+ sym [i ].HasVersion , sym [i ].VersionIndex , sym [i ].Version , sym [i ].Library = f .gnuVersion (i )
1477
1466
}
1478
1467
}
1479
1468
return sym , nil
@@ -1502,23 +1491,37 @@ func (f *File) ImportedSymbols() ([]ImportedSymbol, error) {
1502
1491
if ST_BIND (s .Info ) == STB_GLOBAL && s .Section == SHN_UNDEF {
1503
1492
all = append (all , ImportedSymbol {Name : s .Name })
1504
1493
sym := & all [len (all )- 1 ]
1505
- _ , sym .Version , sym .Library , _ = f .gnuVersion (i )
1494
+ _ , _ , sym .Version , sym .Library = f .gnuVersion (i )
1506
1495
}
1507
1496
}
1508
1497
return all , nil
1509
1498
}
1510
1499
1511
- // SymbolVersionScope describes the version in which a [Symbol] is defined.
1512
- // This is only used for the dynamic symbol table.
1513
- type SymbolVersionScope byte
1500
+ // VersionIndex is the type of a [Symbol] version index.
1501
+ type VersionIndex uint16
1514
1502
1515
- const (
1516
- VersionScopeNone SymbolVersionScope = iota // no symbol version available
1517
- VersionScopeLocal // symbol has local scope
1518
- VersionScopeGlobal // symbol has global scope and is in the base version
1519
- VersionScopeSpecific // symbol has global scope and is in the version given by VersionIndex
1520
- VersionScopeHidden // symbol is in the version given by VersionIndex, and is hidden
1521
- )
1503
+ // IsHidden reports whether the symbol is hidden within the version.
1504
+ // This means that the symbol can only be seen by specifying the exact version.
1505
+ func (vi VersionIndex ) IsHidden () bool {
1506
+ return vi & 0x8000 != 0
1507
+ }
1508
+
1509
+ // Index returns the version index.
1510
+ // If this is the value 0, it means that the symbol is local,
1511
+ // and is not visible externally.
1512
+ // If this is the value 1, it means that the symbol is in the base version,
1513
+ // and has no specific version; it may or may not match a
1514
+ // [DynamicVersion.Index] in the slice returned by [File.DynamicVersions].
1515
+ // Other values will match either [DynamicVersion.Index]
1516
+ // in the slice returned by [File.DynamicVersions],
1517
+ // or [DynamicVersionDep.Index] in the Needs field
1518
+ // of the elements of the slice returned by [File.DynamicVersionNeeds].
1519
+ // In general, a defined symbol will have an index referring
1520
+ // to DynamicVersions, and an undefined symbol will have an index
1521
+ // referring to some version in DynamicVersionNeeds.
1522
+ func (vi VersionIndex ) Index () uint16 {
1523
+ return uint16 (vi & 0x7fff )
1524
+ }
1522
1525
1523
1526
// DynamicVersion is a version defined by a dynamic object.
1524
1527
// This describes entries in the ELF SHT_GNU_verdef section.
@@ -1752,45 +1755,38 @@ func (f *File) gnuVersionInit(str []byte) (bool, error) {
1752
1755
1753
1756
// gnuVersion adds Library and Version information to sym,
1754
1757
// which came from offset i of the symbol table.
1755
- func (f * File ) gnuVersion (i int ) (versionIndex int16 , version string , library string , versionFlags SymbolVersionScope ) {
1758
+ func (f * File ) gnuVersion (i int ) (hasVersion bool , versionIndex VersionIndex , version string , library string ) {
1756
1759
// Each entry is two bytes; skip undef entry at beginning.
1757
1760
i = (i + 1 ) * 2
1758
1761
if i >= len (f .gnuVersym ) {
1759
- return - 1 , "" , "" , VersionScopeNone
1762
+ return false , 0 , "" , ""
1760
1763
}
1761
1764
s := f .gnuVersym [i :]
1762
1765
if len (s ) < 2 {
1763
- return - 1 , "" , "" , VersionScopeNone
1764
- }
1765
- j := int32 (f .ByteOrder .Uint16 (s ))
1766
- ndx := int16 (j & 0x7fff )
1767
-
1768
- if j == 0 {
1769
- return ndx , "" , "" , VersionScopeLocal
1770
- } else if j == 1 {
1771
- return ndx , "" , "" , VersionScopeGlobal
1766
+ return false , 0 , "" , ""
1772
1767
}
1768
+ vi := VersionIndex (f .ByteOrder .Uint16 (s ))
1769
+ ndx := vi .Index ()
1773
1770
1774
- scope := VersionScopeSpecific
1775
- if j & 0x8000 != 0 {
1776
- scope = VersionScopeHidden
1771
+ if ndx == 0 || ndx == 1 {
1772
+ return true , vi , "" , ""
1777
1773
}
1778
1774
1779
1775
for _ , v := range f .dynVerNeeds {
1780
1776
for _ , n := range v .Needs {
1781
- if uint16 ( ndx ) == n .Index {
1782
- return ndx , n .Dep , v .Name , scope
1777
+ if ndx == n .Index {
1778
+ return true , vi , n .Dep , v .Name
1783
1779
}
1784
1780
}
1785
1781
}
1786
1782
1787
1783
for _ , v := range f .dynVers {
1788
- if uint16 ( ndx ) == v .Index {
1789
- return ndx , v .Name , "" , scope
1784
+ if ndx == v .Index {
1785
+ return true , vi , v .Name , ""
1790
1786
}
1791
1787
}
1792
1788
1793
- return - 1 , "" , "" , VersionScopeNone
1789
+ return false , 0 , "" , ""
1794
1790
}
1795
1791
1796
1792
// ImportedLibraries returns the names of all libraries
0 commit comments