aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorgii Rymar <grimar@accesssoftek.com>2021-01-18 16:13:45 +0300
committerGeorgii Rymar <grimar@accesssoftek.com>2021-01-26 12:16:38 +0300
commitdb92d47cf70ebc846f7fac3bb52e281076421def (patch)
tree21b0a86424bb87310f84bffe6ef8bfdeb7797696
parent68dbd1aefe5a5ae6bb59009f497ead130385d964 (diff)
downloadllvm-db92d47cf70ebc846f7fac3bb52e281076421def.zip
llvm-db92d47cf70ebc846f7fac3bb52e281076421def.tar.gz
llvm-db92d47cf70ebc846f7fac3bb52e281076421def.tar.bz2
[llvm-nm][ELF] - Use @@ prefix when printing default versions.
llvm-readelf prints default versions with `@@` prefix. This patch does the same for llvm-nm. Differential revision: https://reviews.llvm.org/D94912
-rw-r--r--llvm/test/tools/llvm-nm/dynamic.test70
-rw-r--r--llvm/tools/llvm-nm/llvm-nm.cpp34
2 files changed, 73 insertions, 31 deletions
diff --git a/llvm/test/tools/llvm-nm/dynamic.test b/llvm/test/tools/llvm-nm/dynamic.test
index 9d91aac..732da61 100644
--- a/llvm/test/tools/llvm-nm/dynamic.test
+++ b/llvm/test/tools/llvm-nm/dynamic.test
@@ -62,17 +62,26 @@ Sections:
Size: 0
## Check we print symbol versions, when they are available.
-
-# RUN: yaml2obj --docnum=4 %s -o %t4.o
-# RUN: llvm-nm --dynamic %t4.o 2>&1 | \
-# RUN: FileCheck %s -DFILE=%t4.o --check-prefix=VERSIONED-SYMS
-
-# VERSIONED-SYMS: U globalversym
-# VERSIONED-SYMS-NEXT: U localversym
-# VERSIONED-SYMS-NEXT: U version2sym@v2
-# VERSIONED-SYMS-NEXT: U version3sym@v3hidden
-# VERSIONED-SYMS-NEXT: U version4sym@v4
-# VERSIONED-SYMS-NEXT: U version5sym@v5hidden
+## A default version is one that is contained in the version table (SHT_GNU_versym)
+## and only available for defined symbols. Check we use the "@@" prefix to print it.
+
+# RUN: yaml2obj --docnum=4 %s -o %t4-undef.o
+# RUN: llvm-nm --dynamic %t4-undef.o 2>&1 | \
+# RUN: FileCheck %s -DFILE=%t4-undef.o -DTYPE=U \
+# RUN: --check-prefixes=VERSIONED-SYMS,VERSIONED-UNDEF-SYMS
+
+# RUN: yaml2obj --docnum=4 -DINDEX=0x1 %s -o %t4-def.o
+# RUN: llvm-nm --dynamic %t4-def.o 2>&1 | \
+# RUN: FileCheck %s -DFILE=%t4-def.o -DTYPE=r \
+# RUN: --check-prefixes=VERSIONED-SYMS,VERSIONED-DEF-SYMS
+
+# VERSIONED-SYMS: [[TYPE]] globalversym
+# VERSIONED-SYMS-NEXT: [[TYPE]] localversym
+# VERSIONED-UNDEF-SYMS-NEXT: [[TYPE]] version2sym@v2
+# VERSIONED-DEF-SYMS-NEXT: [[TYPE]] version2sym@@v2
+# VERSIONED-SYMS-NEXT: [[TYPE]] version3sym@v3hidden
+# VERSIONED-SYMS-NEXT: [[TYPE]] version4sym@v4
+# VERSIONED-SYMS-NEXT: [[TYPE]] version5sym@v5hidden
--- !ELF
FileHeader:
@@ -120,13 +129,22 @@ Sections:
Hash: 0
Flags: 0
Other: 5
+ - Name: .dynsym
+ Type: SHT_DYNSYM
+ EntSize: [[ENTSIZE=<none>]]
DynamicSymbols:
- - Name: localversym
- - Name: globalversym
- - Name: version2sym
- - Name: version3sym
- - Name: version4sym
- - Name: version5sym
+ - Name: localversym
+ Index: [[INDEX=<none>]]
+ - Name: globalversym
+ Index: [[INDEX=<none>]]
+ - Name: version2sym
+ Index: [[INDEX=<none>]]
+ - Name: version3sym
+ Index: [[INDEX=<none>]]
+ - Name: version4sym
+ Index: [[INDEX=<none>]]
+ - Name: version5sym
+ Index: [[INDEX=<none>]]
## In the following cases we check we report warnings when unable to read symbol version.
## Check that we still print unversioned symbol names.
@@ -137,7 +155,7 @@ DynamicSymbols:
# RUN: yaml2obj --docnum=4 -DVERDEFOFFSET=0xffffffff %s -o %t4-broken-verdef.o
# RUN: llvm-nm --dynamic %t4-broken-verdef.o 2>&1 | \
-# RUN: FileCheck %s -DFILE=%t4-broken-verdef.o --check-prefixes=VERSION-ERR,VERSION-ERR1
+# RUN: FileCheck %s --check-prefixes=VERSION-ERR,VERSION-ERR1
# VERSION-ERR1: warning: unable to read symbol versions: cannot read content of SHT_GNU_verdef section with index 2: section [index 2] has a sh_offset (0xffffffff) + sh_size (0x38) that is greater than the file size (0x438)
# VERSION-ERR2: warning: unable to read symbol versions: unable to read an entry with index 1 from SHT_GNU_versym section with index 1: section [index 1] has an invalid sh_size (255) which is not a multiple of its sh_entsize (2)
@@ -155,11 +173,21 @@ DynamicSymbols:
# RUN: yaml2obj --docnum=4 -DVERSYMSIZE=0xff %s -o %t4-broken-versym.o
# RUN: llvm-nm --dynamic %t4-broken-versym.o 2>&1 | \
-# RUN: FileCheck %s -DFILE=%t4-broken-versym.o --check-prefixes=VERSION-ERR,VERSION-ERR2
+# RUN: FileCheck %s --check-prefixes=VERSION-ERR,VERSION-ERR2
-## Case 3: check we report a warning when we are unable to get a vesrion for a SHT_GNU_versym section entry.
+## Case 3: check we report a warning when we are unable to get a version for a SHT_GNU_versym section entry.
## In this case the SHT_GNU_versym section refers to a version index 255 which is missing.
# RUN: yaml2obj --docnum=4 -DVERSYMENTRY=0xff %s -o %t4-broken-index.o
# RUN: llvm-nm --dynamic %t4-broken-index.o 2>&1 | \
-# RUN: FileCheck %s -DFILE=%t4-broken-index.o --check-prefixes=VERSION-ERR,VERSION-ERR3
+# RUN: FileCheck %s --check-prefixes=VERSION-ERR,VERSION-ERR3
+
+## Case 4: check we report a warning when we are unable to get symbol flags.
+## In this case the dynamic symbol table has a wrong sh_entsize and we can't read a symbol.
+
+# RUN: yaml2obj --docnum=4 -DENTSIZE=0xff %s -o %t4-broken-dynsym.o
+# RUN: not llvm-nm --dynamic %t4-broken-dynsym.o 2>&1 | \
+# RUN: FileCheck %s -DFILE=%t4-broken-dynsym.o --check-prefix=VERSION-ERR4
+
+# VERSION-ERR4: warning: unable to read symbol versions: unable to read flags for symbol with index 1: section [index 4] has invalid sh_entsize: expected 24, but got 255
+# VERSION-ERR4: error: [[FILE]] section [index 4] has invalid sh_entsize: expected 24, but got 255
diff --git a/llvm/tools/llvm-nm/llvm-nm.cpp b/llvm/tools/llvm-nm/llvm-nm.cpp
index 16ceb1e..e3f2c7a 100644
--- a/llvm/tools/llvm-nm/llvm-nm.cpp
+++ b/llvm/tools/llvm-nm/llvm-nm.cpp
@@ -1686,8 +1686,15 @@ static void dumpSymbolsFromDLInfoMachO(MachOObjectFile &MachO) {
}
}
+namespace {
+struct SymbolVersion {
+ std::string Name;
+ bool IsDefault;
+};
+}; // namespace
+
template <class ELFT>
-static Expected<std::vector<std::string>>
+static Expected<std::vector<SymbolVersion>>
readSymbolVersionsELF(const ELFFile<ELFT> &Obj, StringRef FileName,
ELFObjectFileBase::elf_symbol_iterator_range Symbols) {
using Elf_Shdr = typename ELFT::Shdr;
@@ -1707,14 +1714,14 @@ readSymbolVersionsELF(const ELFFile<ELFT> &Obj, StringRef FileName,
}
if (!SymVerSec)
- return std::vector<std::string>{};
+ return std::vector<SymbolVersion>{};
Expected<SmallVector<Optional<VersionEntry>, 0>> MapOrErr =
Obj.loadVersionMap(SymVerNeedSec, SymVerDefSec);
if (!MapOrErr)
return MapOrErr.takeError();
- std::vector<std::string> Ret;
+ std::vector<SymbolVersion> Ret;
size_t I = 0;
for (auto It = Symbols.begin(), E = Symbols.end(); It != E; ++It) {
++I;
@@ -1725,21 +1732,27 @@ readSymbolVersionsELF(const ELFFile<ELFT> &Obj, StringRef FileName,
" from " + describe(Obj, *SymVerSec) + ": " +
toString(VerEntryOrErr.takeError()));
+ Expected<uint32_t> FlagsOrErr = It->getFlags();
+ if (!FlagsOrErr)
+ return createError("unable to read flags for symbol with index " +
+ Twine(I) + ": " + toString(FlagsOrErr.takeError()));
+
bool IsDefault;
Expected<StringRef> VerOrErr = Obj.getSymbolVersionByIndex(
- (*VerEntryOrErr)->vs_index, IsDefault, *MapOrErr, /*IsSymHidden=*/None);
+ (*VerEntryOrErr)->vs_index, IsDefault, *MapOrErr,
+ (*FlagsOrErr) & SymbolRef::SF_Undefined);
if (!VerOrErr)
return createError("unable to get a version for entry " + Twine(I) +
" of " + describe(Obj, *SymVerSec) + ": " +
toString(VerOrErr.takeError()));
- Ret.push_back((*VerOrErr).str());
+ Ret.push_back({(*VerOrErr).str(), IsDefault});
}
return Ret;
}
-static Expected<std::vector<std::string>>
+static Expected<std::vector<SymbolVersion>>
readSymbolVersionsELF(const ELFObjectFileBase &Obj,
ELFObjectFileBase::elf_symbol_iterator_range Symbols) {
if (const auto *ELF = dyn_cast<ELF32LEObjectFile>(&Obj))
@@ -1756,7 +1769,7 @@ static void dumpSymbolNamesFromObject(SymbolicFile &Obj, bool printName,
StringRef ArchiveName = {},
StringRef ArchitectureName = {}) {
auto Symbols = Obj.symbols();
- std::vector<std::string> SymbolVersions;
+ std::vector<SymbolVersion> SymbolVersions;
if (DynamicSyms) {
const auto *E = dyn_cast<ELFObjectFileBase>(&Obj);
if (!E) {
@@ -1765,7 +1778,7 @@ static void dumpSymbolNamesFromObject(SymbolicFile &Obj, bool printName,
}
Symbols = E->getDynamicSymbolIterators();
- if (Expected<std::vector<std::string>> VersionsOrErr =
+ if (Expected<std::vector<SymbolVersion>> VersionsOrErr =
readSymbolVersionsELF(*E, Symbols))
SymbolVersions = std::move(*VersionsOrErr);
else
@@ -1827,8 +1840,9 @@ static void dumpSymbolNamesFromObject(SymbolicFile &Obj, bool printName,
} else
error(std::move(E), Obj.getFileName());
}
- if (!SymbolVersions.empty() && !SymbolVersions[I].empty())
- S.Name += "@" + SymbolVersions[I];
+ if (!SymbolVersions.empty() && !SymbolVersions[I].Name.empty())
+ S.Name +=
+ (SymbolVersions[I].IsDefault ? "@@" : "@") + SymbolVersions[I].Name;
S.Sym = Sym;
SymbolList.push_back(S);