[llvm] [llvm-nm][GOFF] Support symbol types and sizes (PR #207119)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 1 22:05:48 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-binary-utilities
Author: Amy Kwan (amy-kwan)
<details>
<summary>Changes</summary>
Add GOFF-specific handling in llvm-nm for symbol types and sizes. GOFF symbols are now classified using their GOFF type, allowing llvm-nm to distinguish global/local data and text symbol,s as well as undefined symbols.
This addition to llvm-nm is also useful to display the symbol table of GOFF object and archives.
---
Full diff: https://github.com/llvm/llvm-project/pull/207119.diff
2 Files Affected:
- (added) llvm/test/tools/llvm-nm/GOFF/symbol-types-and-sizes.ll (+42)
- (modified) llvm/tools/llvm-nm/llvm-nm.cpp (+43-1)
``````````diff
diff --git a/llvm/test/tools/llvm-nm/GOFF/symbol-types-and-sizes.ll b/llvm/test/tools/llvm-nm/GOFF/symbol-types-and-sizes.ll
new file mode 100644
index 0000000000000..405520a961a67
--- /dev/null
+++ b/llvm/test/tools/llvm-nm/GOFF/symbol-types-and-sizes.ll
@@ -0,0 +1,42 @@
+; REQUIRES: systemz-registered-target
+; REQUIRES: target=s390x{{.*}}
+
+; RUN: llc -mtriple=s390x-ibm-zos -filetype=obj %s -o %t.o
+; RUN: llvm-nm --no-sort %t.o | FileCheck %s --check-prefix=TYPES
+; RUN: llvm-nm --no-sort --print-size --defined-only %t.o | FileCheck %s --check-prefix=SIZES
+
+target triple = "s390x-ibm-zos"
+
+ at GlobalData = global i32 42, align 4
+ at LocalData = internal global i32 7, align 4
+
+declare void @ExternFunc()
+
+define void @GlobalFunc() {
+entry:
+ ret void
+}
+
+define internal void @LocalFunc() {
+entry:
+ ret void
+}
+
+define void @UseExternFunc() {
+entry:
+ call void @ExternFunc()
+ ret void
+}
+
+; TYPES-DAG: {{^[0-9A-Fa-f]+}} D GlobalData
+; TYPES-DAG: {{^[0-9A-Fa-f]+}} d LocalData
+; TYPES-DAG: {{^[0-9A-Fa-f]+}} T GlobalFunc
+; TYPES-DAG: {{^[0-9A-Fa-f]+}} t LocalFunc
+; TYPES-DAG: {{^[0-9A-Fa-f]+}} T UseExternFunc
+; TYPES-DAG: {{^ *}}U ExternFunc
+
+; SIZES-DAG: {{^[0-9A-Fa-f]+}} {{0*4}} D GlobalData
+; SIZES-DAG: {{^[0-9A-Fa-f]+}} {{0*4}} d LocalData
+; SIZES-DAG: {{^[0-9A-Fa-f]+}} {{[0-9A-Fa-f]+}} T GlobalFunc
+; SIZES-DAG: {{^[0-9A-Fa-f]+}} {{[0-9A-Fa-f]+}} t LocalFunc
+; SIZES-DAG: {{^[0-9A-Fa-f]+}} {{[0-9A-Fa-f]+}} T UseExternFunc
diff --git a/llvm/tools/llvm-nm/llvm-nm.cpp b/llvm/tools/llvm-nm/llvm-nm.cpp
index 4e3472154063a..2979fc4a0bcb3 100644
--- a/llvm/tools/llvm-nm/llvm-nm.cpp
+++ b/llvm/tools/llvm-nm/llvm-nm.cpp
@@ -28,6 +28,7 @@
#include "llvm/Object/COFF.h"
#include "llvm/Object/COFFImportFile.h"
#include "llvm/Object/ELFObjectFile.h"
+#include "llvm/Object/GOFFObjectFile.h"
#include "llvm/Object/IRObjectFile.h"
#include "llvm/Object/MachO.h"
#include "llvm/Object/MachOUniversal.h"
@@ -1013,6 +1014,42 @@ static char getSymbolNMTypeChar(COFFImportFile &Obj) {
return '?';
}
+static char getSymbolNMTypeChar(GOFFObjectFile &Obj, basic_symbol_iterator I) {
+ symbol_iterator SymI(I);
+ Expected<section_iterator> SecIOrErr = SymI->getSection();
+ if (!SecIOrErr) {
+ consumeError(SecIOrErr.takeError());
+ return '?';
+ }
+
+ GOFFSymbolRef Ref(*I);
+ Expected<uint32_t> Flags = Ref.getSymbolGOFFFlags();
+ Expected<SymbolRef::Type> Type = Ref.getSymbolGOFFType();
+
+ if (!Type || !Flags) {
+ return '?';
+ }
+
+ switch (*Type) {
+ case SymbolRef::ST_Unknown:
+ return 'U';
+ case SymbolRef::ST_Data: {
+ if (*Flags & SymbolRef::SF_Global)
+ return 'D';
+ return 'd';
+ }
+ case SymbolRef::ST_Debug:
+ return 'g';
+ case SymbolRef::ST_Function: {
+ if (*Flags & SymbolRef::SF_Global)
+ return 'T';
+ return 't';
+ }
+ default:
+ return 'o';
+ }
+}
+
static char getSymbolNMTypeChar(MachOObjectFile &Obj, basic_symbol_iterator I) {
DataRefImpl Symb = I->getRawDataRefImpl();
uint8_t NType = Obj.is64Bit() ? Obj.getSymbol64TableEntry(Symb).n_type
@@ -1173,7 +1210,9 @@ static char getNMSectionTagAndName(SymbolicFile &Obj, basic_symbol_iterator I,
Ret = getSymbolNMTypeChar(*ELF, I);
if (ELFSymbolRef(*I).getBinding() == ELF::STB_GNU_UNIQUE)
return Ret;
- } else
+ } else if (GOFFObjectFile *GOFF = dyn_cast<GOFFObjectFile>(&Obj))
+ Ret = getSymbolNMTypeChar(*GOFF, I);
+ else
llvm_unreachable("unknown binary format");
if (!(Symflags & object::SymbolRef::SF_Global))
@@ -1852,6 +1891,9 @@ static bool getSymbolNamesFromObject(SymbolicFile &Obj,
S.Address = 0;
if (isa<ELFObjectFileBase>(&Obj))
S.Size = ELFSymbolRef(Sym).getSize();
+ else if (isa<GOFFObjectFile>(&Obj)) {
+ S.Size = GOFFSymbolRef(Sym).getSize();
+ }
if (const XCOFFObjectFile *XCOFFObj =
dyn_cast<const XCOFFObjectFile>(&Obj))
``````````
</details>
https://github.com/llvm/llvm-project/pull/207119
More information about the llvm-commits
mailing list