https://github.com/llvmbot created https://github.com/llvm/llvm-project/pull/223248
Backport 60bd2e1942b80287c8b4fbe5b0d1b0cd6bfe96ae Requested by: @amy-kwan >From 72a7c1b0d48f388073b203aab946d7ba8cc99a80 Mon Sep 17 00:00:00 2001 From: Amy Kwan <[email protected]> Date: Tue, 18 Aug 2026 23:46:45 -0400 Subject: [PATCH] [llvm-nm][GOFF] Support symbol types and sizes (#207119) 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. (cherry picked from commit 60bd2e1942b80287c8b4fbe5b0d1b0cd6bfe96ae) --- .../llvm-nm/GOFF/symbol-types-and-sizes.ll | 39 +++++++++++++++++++ llvm/tools/llvm-nm/llvm-nm.cpp | 24 ++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 llvm/test/tools/llvm-nm/GOFF/symbol-types-and-sizes.ll 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..44837c6e0886e --- /dev/null +++ b/llvm/test/tools/llvm-nm/GOFF/symbol-types-and-sizes.ll @@ -0,0 +1,39 @@ +; REQUIRES: systemz-registered-target + +; RUN: llc -mtriple=s390x-ibm-zos -filetype=obj %s -o %t.o +; RUN: llvm-nm --no-sort --print-size %t.o | FileCheck %s + +target triple = "s390x-ibm-zos" + +@GlobalData = global i32 42, align 4 +@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 +} + +; The functions within this test are label definitions (LD). The function entry +; point is typically created as a label within a container, and these label +; symbols do not have an explicit size set, hence why 0 is the expected size +; for the below functions. + +; CHECK-DAG: {{^[0-9A-Fa-f]+}} 0000000000000004 D GlobalData +; CHECK-DAG: {{^[0-9A-Fa-f]+}} 0000000000000004 d LocalData +; CHECK-DAG: {{^[0-9A-Fa-f]+}} 0000000000000000 T GlobalFunc +; CHECK-DAG: {{^[0-9A-Fa-f]+}} 0000000000000000 t LocalFunc +; CHECK-DAG: {{^[0-9A-Fa-f]+}} 0000000000000000 T UseExternFunc +; CHECK-DAG: U ExternFunc diff --git a/llvm/tools/llvm-nm/llvm-nm.cpp b/llvm/tools/llvm-nm/llvm-nm.cpp index 4e3472154063a..4f3f833a50a5f 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,25 @@ static char getSymbolNMTypeChar(COFFImportFile &Obj) { return '?'; } +static char getSymbolNMTypeChar(GOFFObjectFile &, basic_symbol_iterator I) { + GOFFSymbolRef Ref(*I); + Expected<SymbolRef::Type> Type = Ref.getSymbolGOFFType(); + // TODO: Add a test using yaml2obj once GOFF ESD record support is + // available in yaml2obj. + if (!Type) { + consumeError(Type.takeError()); + return '?'; + } + switch (*Type) { + case SymbolRef::ST_Data: + return 'd'; + case SymbolRef::ST_Function: + return 't'; + default: + llvm_unreachable("GOFFObjectFile::getSymbolType returned unexpected type"); + } +} + static char getSymbolNMTypeChar(MachOObjectFile &Obj, basic_symbol_iterator I) { DataRefImpl Symb = I->getRawDataRefImpl(); uint8_t NType = Obj.is64Bit() ? Obj.getSymbol64TableEntry(Symb).n_type @@ -1173,6 +1193,8 @@ static char getNMSectionTagAndName(SymbolicFile &Obj, basic_symbol_iterator I, Ret = getSymbolNMTypeChar(*ELF, I); if (ELFSymbolRef(*I).getBinding() == ELF::STB_GNU_UNIQUE) return Ret; + } else if (GOFFObjectFile *GOFF = dyn_cast<GOFFObjectFile>(&Obj)) { + Ret = getSymbolNMTypeChar(*GOFF, I); } else llvm_unreachable("unknown binary format"); @@ -1852,6 +1874,8 @@ 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)) _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
