[llvm] [llvm][object][GOFF] refine Global flag conditions (PR #211632)
David Tenty via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 7 09:55:01 PDT 2026
https://github.com/daltenty updated https://github.com/llvm/llvm-project/pull/211632
>From 85ff941be5a22ad775623d9a2de8dd3dee063338 Mon Sep 17 00:00:00 2001
From: David Tenty <daltenty at ibm.com>
Date: Thu, 23 Jul 2026 00:15:56 -0400
Subject: [PATCH 01/12] [llvm][object][GOFF] refine Global flag conditions
---
llvm/lib/Object/GOFFObjectFile.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/Object/GOFFObjectFile.cpp b/llvm/lib/Object/GOFFObjectFile.cpp
index 057d3fc208c9b..59b94208b38d5 100644
--- a/llvm/lib/Object/GOFFObjectFile.cpp
+++ b/llvm/lib/Object/GOFFObjectFile.cpp
@@ -279,7 +279,8 @@ Expected<uint32_t> GOFFObjectFile::getSymbolFlags(DataRefImpl Symb) const {
GOFF::ESDBindingScope BindingScope;
ESDRecord::getBindingScope(Record, BindingScope);
- if (BindingScope != GOFF::ESD_BSC_Section) {
+ if (BindingScope != GOFF::ESD_BSC_Section &&
+ BindingScope != GOFF::ESD_BSC_Module) {
Expected<StringRef> Name = getSymbolName(Symb);
if (Name && *Name != " ") { // Blank name is local.
Flags |= SymbolRef::SF_Global;
>From d82a9483ca5c6f3e075d924111dcea412a8fccd4 Mon Sep 17 00:00:00 2001
From: David Tenty <daltenty at ibm.com>
Date: Thu, 23 Jul 2026 13:48:07 -0400
Subject: [PATCH 02/12] Add test
---
llvm/unittests/Object/GOFFObjectFileTest.cpp | 139 +++++++++++++++++++
1 file changed, 139 insertions(+)
diff --git a/llvm/unittests/Object/GOFFObjectFileTest.cpp b/llvm/unittests/Object/GOFFObjectFileTest.cpp
index 09fa1c2f63938..dc8a4f30119ec 100644
--- a/llvm/unittests/Object/GOFFObjectFileTest.cpp
+++ b/llvm/unittests/Object/GOFFObjectFileTest.cpp
@@ -633,3 +633,142 @@ TEST_F(GOFFObjectFileTest, TXTConstruct) {
StringRef Contents = SectionContent.get();
EXPECT_EQ(Contents, "\x12\x34\x56\x78\x9a\xbc\xde\xf0");
}
+
+TEST(GOFFObjectFileTest, GlobalSymbols) {
+ char GOFFData[GOFF::RecordLength * 12] = {0x00};
+
+ // HDR record.
+ GOFFData[0] = (char)0x03;
+ GOFFData[1] = (char)0xF0;
+
+ // ESD record 1: type SD
+ GOFFData[GOFF::RecordLength] = (char)0x03;
+ GOFFData[GOFF::RecordLength + 3] = (char)0x00; // Type: SD
+ GOFFData[GOFF::RecordLength + 7] = (char)0x01; // ESDID.
+ GOFFData[GOFF::RecordLength + 71] = (char)0x01; // Size of symbol name.
+ GOFFData[GOFF::RecordLength + 72] = (char)0xC1; // Symbol name is A.
+
+ // ESD record 2: type ED
+ GOFFData[GOFF::RecordLength * 2] = (char)0x03;
+ GOFFData[GOFF::RecordLength * 2 + 3] = (char)0x01; // Type: ED
+ GOFFData[GOFF::RecordLength * 2 + 7] = (char)0x02; // ESDID.
+ GOFFData[GOFF::RecordLength * 2 + 11] = (char)0x01; // Parent ESDID.
+ GOFFData[GOFF::RecordLength * 2 + 71] = (char)0x01; // Size of symbol name.
+ GOFFData[GOFF::RecordLength * 2 + 72] = (char)0xC2; // Symbol name is B.
+
+ // ESD record 3: type LD
+ GOFFData[GOFF::RecordLength * 3] = (char)0x03;
+ GOFFData[GOFF::RecordLength * 3 + 3] = (char)0x02; // Type: LD
+ GOFFData[GOFF::RecordLength * 3 + 7] = (char)0x03; // ESDID.
+ GOFFData[GOFF::RecordLength * 3 + 11] = (char)0x02; // Parent ESDID.
+ GOFFData[GOFF::RecordLength * 3 + 71] = (char)0x01; // Size of symbol name.
+ GOFFData[GOFF::RecordLength * 3 + 72] = (char)0xC3; // Symbol name is C.
+
+ // ESD record 4: type PR
+ GOFFData[GOFF::RecordLength * 4] = (char)0x03;
+ GOFFData[GOFF::RecordLength * 4 + 3] = (char)0x03; // Type: PR
+ GOFFData[GOFF::RecordLength * 4 + 7] = (char)0x04; // ESDID.
+ GOFFData[GOFF::RecordLength * 4 + 11] = (char)0x02; // Parent ESDID.
+ GOFFData[GOFF::RecordLength * 4 + 71] = (char)0x01; // Size of symbol name.
+ GOFFData[GOFF::RecordLength * 4 + 72] = (char)0xC4; // Symbol name is D.
+
+ // ESD record 5: type ErWx
+ GOFFData[GOFF::RecordLength * 5] = (char)0x03;
+ GOFFData[GOFF::RecordLength * 5 + 3] = (char)0x04; // Type: ErWx
+ GOFFData[GOFF::RecordLength * 5 + 7] = (char)0x05; // ESDID.
+ GOFFData[GOFF::RecordLength * 5 + 71] = (char)0x01; // Size of symbol name.
+ GOFFData[GOFF::RecordLength * 5 + 72] = (char)0xC5; // Symbol name is E.
+
+ // ESD record 6: type LD + Section binding scope
+ GOFFData[GOFF::RecordLength * 6] = (char)0x03;
+ GOFFData[GOFF::RecordLength * 6 + 3] = (char)0x02; // Type: LD
+ GOFFData[GOFF::RecordLength * 6 + 7] = (char)0x06; // ESDID.
+ GOFFData[GOFF::RecordLength * 6 + 11] = (char)0x02; // Parent ESDID.
+ GOFFData[GOFF::RecordLength * 6 + 65] = (char)0x01; // Binding Scope: Section.
+ GOFFData[GOFF::RecordLength * 6 + 71] = (char)0x01; // Size of symbol name.
+ GOFFData[GOFF::RecordLength * 6 + 72] = (char)0xC6; // Symbol name is F.
+
+ // ESD record 7: type LD + Module binding scope
+ GOFFData[GOFF::RecordLength * 7] = (char)0x03;
+ GOFFData[GOFF::RecordLength * 7 + 3] = (char)0x02; // Type: LD
+ GOFFData[GOFF::RecordLength * 7 + 7] = (char)0x07; // ESDID.
+ GOFFData[GOFF::RecordLength * 7 + 11] = (char)0x02; // Parent ESDID.
+ GOFFData[GOFF::RecordLength * 7 + 65] = (char)0x02; // Binding Scope: Module.
+ GOFFData[GOFF::RecordLength * 7 + 71] = (char)0x01; // Size of symbol name.
+ GOFFData[GOFF::RecordLength * 7 + 72] = (char)0xC7; // Symbol name is G.
+
+ // ESD record 8: type LD + Library binding scope
+ GOFFData[GOFF::RecordLength * 8] = (char)0x03;
+ GOFFData[GOFF::RecordLength * 8 + 3] = (char)0x02; // Type: LD
+ GOFFData[GOFF::RecordLength * 8 + 7] = (char)0x08; // ESDID.
+ GOFFData[GOFF::RecordLength * 8 + 11] = (char)0x02; // Parent ESDID.
+ GOFFData[GOFF::RecordLength * 8 + 65] = (char)0x03; // Binding Scope: Library.
+ GOFFData[GOFF::RecordLength * 8 + 71] = (char)0x01; // Size of symbol name.
+ GOFFData[GOFF::RecordLength * 8 + 72] = (char)0xC8; // Symbol name is H.
+
+ // ESD record 9: type LD + Import-Export binding scope
+ GOFFData[GOFF::RecordLength * 9] = (char)0x03;
+ GOFFData[GOFF::RecordLength * 9 + 3] = (char)0x02; // Type: LD
+ GOFFData[GOFF::RecordLength * 9 + 7] = (char)0x09; // ESDID.
+ GOFFData[GOFF::RecordLength * 9 + 11] = (char)0x02; // Parent ESDID.
+ GOFFData[GOFF::RecordLength * 9 + 65] = (char)0x04; // Binding Scope: ImportExport.
+ GOFFData[GOFF::RecordLength * 9 + 71] = (char)0x01; // Size of symbol name.
+ GOFFData[GOFF::RecordLength * 9 + 72] = (char)0xC9; // Symbol name is I.
+
+ // ESD record 10: type LD + blank name
+ GOFFData[GOFF::RecordLength * 10] = (char)0x03;
+ GOFFData[GOFF::RecordLength * 10 + 3] = (char)0x02; // Type: LD
+ GOFFData[GOFF::RecordLength * 10 + 7] = (char)0x0A; // ESDID.
+ GOFFData[GOFF::RecordLength * 10 + 11] = (char)0x02; // Parent ESDID.
+ GOFFData[GOFF::RecordLength * 10 + 71] = (char)0x01; // Size of symbol name.
+ GOFFData[GOFF::RecordLength * 10 + 72] = (char)0x40; // Symbol name is ' '.
+
+ // END record.
+ GOFFData[GOFF::RecordLength * 11] = (char)0x03;
+ GOFFData[GOFF::RecordLength * 11 + 1] = (char)0x40;
+
+ StringRef Data(GOFFData, GOFF::RecordLength * 12);
+
+ Expected<std::unique_ptr<ObjectFile>> GOFFObjOrErr =
+ object::ObjectFile::createGOFFObjectFile(
+ MemoryBufferRef(Data, "dummyGOFF"));
+
+ ASSERT_THAT_EXPECTED(GOFFObjOrErr, Succeeded());
+
+ GOFFObjectFile *GOFFObj = dyn_cast<GOFFObjectFile>((*GOFFObjOrErr).get());
+
+
+ auto SymbolRange = GOFFObj->symbols();
+ auto Symbol = SymbolRange.begin();
+ auto ValidateGlobal = [&](StringRef Name, bool IsGlobal) {
+ ASSERT_TRUE(Symbol != SymbolRange.end());
+
+ // Check Name.
+ Expected<StringRef> SymbolNameOrErr = GOFFObj->getSymbolName(*Symbol);
+ ASSERT_THAT_EXPECTED(SymbolNameOrErr, Succeeded());
+ StringRef SymbolName = SymbolNameOrErr.get();
+ EXPECT_EQ(SymbolName, Name);
+
+ // Check flags.
+ Expected<uint32_t> SymbolFlagsOrErr = Symbol->getFlags();
+ ASSERT_THAT_EXPECTED(SymbolFlagsOrErr, Succeeded());
+ uint32_t SymbolFlags = SymbolFlagsOrErr.get();
+ if (IsGlobal){
+ EXPECT_TRUE(SymbolFlags & SymbolRef::SF_Global);
+ } else {
+ EXPECT_FALSE(SymbolFlags & SymbolRef::SF_Global);
+ }
+
+ ++Symbol;
+ };
+
+ // ESD records 'A' and 'B' shouldn't be considered symbols.
+ ValidateGlobal("C", true);
+ ValidateGlobal("D", true);
+ ValidateGlobal("E", true);
+ ValidateGlobal("F", false);
+ ValidateGlobal("G", false);
+ ValidateGlobal("H", true);
+ ValidateGlobal("I", true);
+ ValidateGlobal(" ", false);
+}
>From f61f2826df894fa0aa3d30bf3f43d54703a6374c Mon Sep 17 00:00:00 2001
From: David Tenty <daltenty at ibm.com>
Date: Fri, 24 Jul 2026 10:44:22 -0400
Subject: [PATCH 03/12] clang-format
---
llvm/unittests/Object/GOFFObjectFileTest.cpp | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/llvm/unittests/Object/GOFFObjectFileTest.cpp b/llvm/unittests/Object/GOFFObjectFileTest.cpp
index dc8a4f30119ec..538fbfc22eb0b 100644
--- a/llvm/unittests/Object/GOFFObjectFileTest.cpp
+++ b/llvm/unittests/Object/GOFFObjectFileTest.cpp
@@ -706,16 +706,17 @@ TEST(GOFFObjectFileTest, GlobalSymbols) {
GOFFData[GOFF::RecordLength * 8 + 71] = (char)0x01; // Size of symbol name.
GOFFData[GOFF::RecordLength * 8 + 72] = (char)0xC8; // Symbol name is H.
- // ESD record 9: type LD + Import-Export binding scope
+ // ESD record 9: type LD + Import-Export binding scope
GOFFData[GOFF::RecordLength * 9] = (char)0x03;
GOFFData[GOFF::RecordLength * 9 + 3] = (char)0x02; // Type: LD
GOFFData[GOFF::RecordLength * 9 + 7] = (char)0x09; // ESDID.
GOFFData[GOFF::RecordLength * 9 + 11] = (char)0x02; // Parent ESDID.
- GOFFData[GOFF::RecordLength * 9 + 65] = (char)0x04; // Binding Scope: ImportExport.
+ GOFFData[GOFF::RecordLength * 9 + 65] =
+ (char)0x04; // Binding Scope: ImportExport.
GOFFData[GOFF::RecordLength * 9 + 71] = (char)0x01; // Size of symbol name.
GOFFData[GOFF::RecordLength * 9 + 72] = (char)0xC9; // Symbol name is I.
- // ESD record 10: type LD + blank name
+ // ESD record 10: type LD + blank name
GOFFData[GOFF::RecordLength * 10] = (char)0x03;
GOFFData[GOFF::RecordLength * 10 + 3] = (char)0x02; // Type: LD
GOFFData[GOFF::RecordLength * 10 + 7] = (char)0x0A; // ESDID.
@@ -737,7 +738,6 @@ TEST(GOFFObjectFileTest, GlobalSymbols) {
GOFFObjectFile *GOFFObj = dyn_cast<GOFFObjectFile>((*GOFFObjOrErr).get());
-
auto SymbolRange = GOFFObj->symbols();
auto Symbol = SymbolRange.begin();
auto ValidateGlobal = [&](StringRef Name, bool IsGlobal) {
@@ -753,7 +753,7 @@ TEST(GOFFObjectFileTest, GlobalSymbols) {
Expected<uint32_t> SymbolFlagsOrErr = Symbol->getFlags();
ASSERT_THAT_EXPECTED(SymbolFlagsOrErr, Succeeded());
uint32_t SymbolFlags = SymbolFlagsOrErr.get();
- if (IsGlobal){
+ if (IsGlobal) {
EXPECT_TRUE(SymbolFlags & SymbolRef::SF_Global);
} else {
EXPECT_FALSE(SymbolFlags & SymbolRef::SF_Global);
>From 11630d3fe7ad929173854a1bfc9d9bac2ebfc61e Mon Sep 17 00:00:00 2001
From: David Tenty <daltenty at ibm.com>
Date: Fri, 24 Jul 2026 16:42:18 -0400
Subject: [PATCH 04/12] Update cast
---
llvm/unittests/Object/GOFFObjectFileTest.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/unittests/Object/GOFFObjectFileTest.cpp b/llvm/unittests/Object/GOFFObjectFileTest.cpp
index 538fbfc22eb0b..62fdbe58de6d1 100644
--- a/llvm/unittests/Object/GOFFObjectFileTest.cpp
+++ b/llvm/unittests/Object/GOFFObjectFileTest.cpp
@@ -736,7 +736,7 @@ TEST(GOFFObjectFileTest, GlobalSymbols) {
ASSERT_THAT_EXPECTED(GOFFObjOrErr, Succeeded());
- GOFFObjectFile *GOFFObj = dyn_cast<GOFFObjectFile>((*GOFFObjOrErr).get());
+ GOFFObjectFile *GOFFObj = static_cast<GOFFObjectFile*>((*GOFFObjOrErr).get());
auto SymbolRange = GOFFObj->symbols();
auto Symbol = SymbolRange.begin();
>From 876ccacdee43a6100786ff958c88128924e67088 Mon Sep 17 00:00:00 2001
From: David Tenty <daltenty at ibm.com>
Date: Wed, 5 Aug 2026 17:11:08 -0400
Subject: [PATCH 05/12] Adopt new record helpers
---
llvm/unittests/Object/GOFFObjectFileTest.cpp | 101 +++++--------------
1 file changed, 25 insertions(+), 76 deletions(-)
diff --git a/llvm/unittests/Object/GOFFObjectFileTest.cpp b/llvm/unittests/Object/GOFFObjectFileTest.cpp
index 62fdbe58de6d1..9b8c74103f941 100644
--- a/llvm/unittests/Object/GOFFObjectFileTest.cpp
+++ b/llvm/unittests/Object/GOFFObjectFileTest.cpp
@@ -634,101 +634,49 @@ TEST_F(GOFFObjectFileTest, TXTConstruct) {
EXPECT_EQ(Contents, "\x12\x34\x56\x78\x9a\xbc\xde\xf0");
}
-TEST(GOFFObjectFileTest, GlobalSymbols) {
- char GOFFData[GOFF::RecordLength * 12] = {0x00};
-
+TEST_F(GOFFObjectFileTest, GlobalSymbols) {
// HDR record.
- GOFFData[0] = (char)0x03;
- GOFFData[1] = (char)0xF0;
+ addHdrRecord();
// ESD record 1: type SD
- GOFFData[GOFF::RecordLength] = (char)0x03;
- GOFFData[GOFF::RecordLength + 3] = (char)0x00; // Type: SD
- GOFFData[GOFF::RecordLength + 7] = (char)0x01; // ESDID.
- GOFFData[GOFF::RecordLength + 71] = (char)0x01; // Size of symbol name.
- GOFFData[GOFF::RecordLength + 72] = (char)0xC1; // Symbol name is A.
+ addEsdRecord(0x00, 0x01, {0xC1}); // A
// ESD record 2: type ED
- GOFFData[GOFF::RecordLength * 2] = (char)0x03;
- GOFFData[GOFF::RecordLength * 2 + 3] = (char)0x01; // Type: ED
- GOFFData[GOFF::RecordLength * 2 + 7] = (char)0x02; // ESDID.
- GOFFData[GOFF::RecordLength * 2 + 11] = (char)0x01; // Parent ESDID.
- GOFFData[GOFF::RecordLength * 2 + 71] = (char)0x01; // Size of symbol name.
- GOFFData[GOFF::RecordLength * 2 + 72] = (char)0xC2; // Symbol name is B.
-
- // ESD record 3: type LD
- GOFFData[GOFF::RecordLength * 3] = (char)0x03;
- GOFFData[GOFF::RecordLength * 3 + 3] = (char)0x02; // Type: LD
- GOFFData[GOFF::RecordLength * 3 + 7] = (char)0x03; // ESDID.
- GOFFData[GOFF::RecordLength * 3 + 11] = (char)0x02; // Parent ESDID.
- GOFFData[GOFF::RecordLength * 3 + 71] = (char)0x01; // Size of symbol name.
- GOFFData[GOFF::RecordLength * 3 + 72] = (char)0xC3; // Symbol name is C.
+ addEsdRecord(0x01, 0x02, {0xC2}, 0x01); // B, parent=1
+
+ // ESD record 3: type LD (default binding scope = global)
+ addEsdRecord(0x02, 0x03, {0xC3}, 0x02); // C, parent=2
// ESD record 4: type PR
- GOFFData[GOFF::RecordLength * 4] = (char)0x03;
- GOFFData[GOFF::RecordLength * 4 + 3] = (char)0x03; // Type: PR
- GOFFData[GOFF::RecordLength * 4 + 7] = (char)0x04; // ESDID.
- GOFFData[GOFF::RecordLength * 4 + 11] = (char)0x02; // Parent ESDID.
- GOFFData[GOFF::RecordLength * 4 + 71] = (char)0x01; // Size of symbol name.
- GOFFData[GOFF::RecordLength * 4 + 72] = (char)0xC4; // Symbol name is D.
+ addEsdRecord(0x03, 0x04, {0xC4}, 0x02); // D, parent=2
// ESD record 5: type ErWx
- GOFFData[GOFF::RecordLength * 5] = (char)0x03;
- GOFFData[GOFF::RecordLength * 5 + 3] = (char)0x04; // Type: ErWx
- GOFFData[GOFF::RecordLength * 5 + 7] = (char)0x05; // ESDID.
- GOFFData[GOFF::RecordLength * 5 + 71] = (char)0x01; // Size of symbol name.
- GOFFData[GOFF::RecordLength * 5 + 72] = (char)0xC5; // Symbol name is E.
-
- // ESD record 6: type LD + Section binding scope
- GOFFData[GOFF::RecordLength * 6] = (char)0x03;
- GOFFData[GOFF::RecordLength * 6 + 3] = (char)0x02; // Type: LD
- GOFFData[GOFF::RecordLength * 6 + 7] = (char)0x06; // ESDID.
- GOFFData[GOFF::RecordLength * 6 + 11] = (char)0x02; // Parent ESDID.
- GOFFData[GOFF::RecordLength * 6 + 65] = (char)0x01; // Binding Scope: Section.
- GOFFData[GOFF::RecordLength * 6 + 71] = (char)0x01; // Size of symbol name.
- GOFFData[GOFF::RecordLength * 6 + 72] = (char)0xC6; // Symbol name is F.
+ addEsdRecord(0x04, 0x05, {0xC5}); // E
+
+ // ESD record 6: type LD + Section binding scope (BindingScope=1 -> lower
+ // nibble of BehavioralAttributes[5])
+ addEsdRecord(0x02, 0x06, {0xC6}, 0x02, 0x00, 0x00, 0x00,
+ {0, 0, 0, 0, 0, 0x01, 0, 0, 0, 0}); // F, parent=2
// ESD record 7: type LD + Module binding scope
- GOFFData[GOFF::RecordLength * 7] = (char)0x03;
- GOFFData[GOFF::RecordLength * 7 + 3] = (char)0x02; // Type: LD
- GOFFData[GOFF::RecordLength * 7 + 7] = (char)0x07; // ESDID.
- GOFFData[GOFF::RecordLength * 7 + 11] = (char)0x02; // Parent ESDID.
- GOFFData[GOFF::RecordLength * 7 + 65] = (char)0x02; // Binding Scope: Module.
- GOFFData[GOFF::RecordLength * 7 + 71] = (char)0x01; // Size of symbol name.
- GOFFData[GOFF::RecordLength * 7 + 72] = (char)0xC7; // Symbol name is G.
+ addEsdRecord(0x02, 0x07, {0xC7}, 0x02, 0x00, 0x00, 0x00,
+ {0, 0, 0, 0, 0, 0x02, 0, 0, 0, 0}); // G, parent=2
// ESD record 8: type LD + Library binding scope
- GOFFData[GOFF::RecordLength * 8] = (char)0x03;
- GOFFData[GOFF::RecordLength * 8 + 3] = (char)0x02; // Type: LD
- GOFFData[GOFF::RecordLength * 8 + 7] = (char)0x08; // ESDID.
- GOFFData[GOFF::RecordLength * 8 + 11] = (char)0x02; // Parent ESDID.
- GOFFData[GOFF::RecordLength * 8 + 65] = (char)0x03; // Binding Scope: Library.
- GOFFData[GOFF::RecordLength * 8 + 71] = (char)0x01; // Size of symbol name.
- GOFFData[GOFF::RecordLength * 8 + 72] = (char)0xC8; // Symbol name is H.
+ addEsdRecord(0x02, 0x08, {0xC8}, 0x02, 0x00, 0x00, 0x00,
+ {0, 0, 0, 0, 0, 0x03, 0, 0, 0, 0}); // H, parent=2
// ESD record 9: type LD + Import-Export binding scope
- GOFFData[GOFF::RecordLength * 9] = (char)0x03;
- GOFFData[GOFF::RecordLength * 9 + 3] = (char)0x02; // Type: LD
- GOFFData[GOFF::RecordLength * 9 + 7] = (char)0x09; // ESDID.
- GOFFData[GOFF::RecordLength * 9 + 11] = (char)0x02; // Parent ESDID.
- GOFFData[GOFF::RecordLength * 9 + 65] =
- (char)0x04; // Binding Scope: ImportExport.
- GOFFData[GOFF::RecordLength * 9 + 71] = (char)0x01; // Size of symbol name.
- GOFFData[GOFF::RecordLength * 9 + 72] = (char)0xC9; // Symbol name is I.
+ addEsdRecord(0x02, 0x09, {0xC9}, 0x02, 0x00, 0x00, 0x00,
+ {0, 0, 0, 0, 0, 0x04, 0, 0, 0, 0}); // I, parent=2
// ESD record 10: type LD + blank name
- GOFFData[GOFF::RecordLength * 10] = (char)0x03;
- GOFFData[GOFF::RecordLength * 10 + 3] = (char)0x02; // Type: LD
- GOFFData[GOFF::RecordLength * 10 + 7] = (char)0x0A; // ESDID.
- GOFFData[GOFF::RecordLength * 10 + 11] = (char)0x02; // Parent ESDID.
- GOFFData[GOFF::RecordLength * 10 + 71] = (char)0x01; // Size of symbol name.
- GOFFData[GOFF::RecordLength * 10 + 72] = (char)0x40; // Symbol name is ' '.
+ addEsdRecord(0x02, 0x0A, {0x40}, 0x02); // ' ', parent=2
// END record.
- GOFFData[GOFF::RecordLength * 11] = (char)0x03;
- GOFFData[GOFF::RecordLength * 11 + 1] = (char)0x40;
+ addEndRecord();
- StringRef Data(GOFFData, GOFF::RecordLength * 12);
+ StringRef Data(GOFFData.data(), GOFFData.size());
Expected<std::unique_ptr<ObjectFile>> GOFFObjOrErr =
object::ObjectFile::createGOFFObjectFile(
@@ -736,7 +684,8 @@ TEST(GOFFObjectFileTest, GlobalSymbols) {
ASSERT_THAT_EXPECTED(GOFFObjOrErr, Succeeded());
- GOFFObjectFile *GOFFObj = static_cast<GOFFObjectFile*>((*GOFFObjOrErr).get());
+ GOFFObjectFile *GOFFObj =
+ static_cast<GOFFObjectFile *>((*GOFFObjOrErr).get());
auto SymbolRange = GOFFObj->symbols();
auto Symbol = SymbolRange.begin();
>From 4c9195e17af0fc6d54cec77d643c5c540e83e897 Mon Sep 17 00:00:00 2001
From: David Tenty <daltenty at ibm.com>
Date: Wed, 5 Aug 2026 17:15:44 -0400
Subject: [PATCH 06/12] Add FIXME for missing ESD records
---
llvm/unittests/Object/GOFFObjectFileTest.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/unittests/Object/GOFFObjectFileTest.cpp b/llvm/unittests/Object/GOFFObjectFileTest.cpp
index 9b8c74103f941..02124b2b2a176 100644
--- a/llvm/unittests/Object/GOFFObjectFileTest.cpp
+++ b/llvm/unittests/Object/GOFFObjectFileTest.cpp
@@ -711,7 +711,7 @@ TEST_F(GOFFObjectFileTest, GlobalSymbols) {
++Symbol;
};
- // ESD records 'A' and 'B' shouldn't be considered symbols.
+ // FIXME: ESD records 'A' and 'B' should be considered symbols, but aren't returned iteration.
ValidateGlobal("C", true);
ValidateGlobal("D", true);
ValidateGlobal("E", true);
>From 82c2ec152720034d77cddbd2131132ff7f834d04 Mon Sep 17 00:00:00 2001
From: David Tenty <daltenty at ibm.com>
Date: Wed, 5 Aug 2026 17:25:18 -0400
Subject: [PATCH 07/12] Add explicit type checks
---
llvm/lib/Object/GOFFObjectFile.cpp | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/Object/GOFFObjectFile.cpp b/llvm/lib/Object/GOFFObjectFile.cpp
index 59b94208b38d5..d00ad71105fd5 100644
--- a/llvm/lib/Object/GOFFObjectFile.cpp
+++ b/llvm/lib/Object/GOFFObjectFile.cpp
@@ -279,7 +279,12 @@ Expected<uint32_t> GOFFObjectFile::getSymbolFlags(DataRefImpl Symb) const {
GOFF::ESDBindingScope BindingScope;
ESDRecord::getBindingScope(Record, BindingScope);
- if (BindingScope != GOFF::ESD_BSC_Section &&
+ GOFF::ESDSymbolType Type;
+ ESDRecord::getSymbolType(Record, Type);
+
+ if (Type != GOFF::ESD_ST_SectionDefinition &&
+ Type != GOFF::ESD_ST_ElementDefinition &&
+ BindingScope != GOFF::ESD_BSC_Section &&
BindingScope != GOFF::ESD_BSC_Module) {
Expected<StringRef> Name = getSymbolName(Symb);
if (Name && *Name != " ") { // Blank name is local.
>From 6205ea4f65e83bb33b873b502ac6fafbacedc029 Mon Sep 17 00:00:00 2001
From: David Tenty <daltenty at ibm.com>
Date: Wed, 5 Aug 2026 17:32:21 -0400
Subject: [PATCH 08/12] clang-format
---
llvm/unittests/Object/GOFFObjectFileTest.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/llvm/unittests/Object/GOFFObjectFileTest.cpp b/llvm/unittests/Object/GOFFObjectFileTest.cpp
index 02124b2b2a176..142666a6da077 100644
--- a/llvm/unittests/Object/GOFFObjectFileTest.cpp
+++ b/llvm/unittests/Object/GOFFObjectFileTest.cpp
@@ -711,7 +711,8 @@ TEST_F(GOFFObjectFileTest, GlobalSymbols) {
++Symbol;
};
- // FIXME: ESD records 'A' and 'B' should be considered symbols, but aren't returned iteration.
+ // FIXME: ESD records 'A' and 'B' should be considered symbols, but aren't
+ // returned iteration.
ValidateGlobal("C", true);
ValidateGlobal("D", true);
ValidateGlobal("E", true);
>From 18b36ec707a81707927181558beb3be5a714d2bd Mon Sep 17 00:00:00 2001
From: David Tenty <daltenty.dev at gmail.com>
Date: Thu, 6 Aug 2026 13:13:31 -0400
Subject: [PATCH 09/12] Fix comment
---
llvm/unittests/Object/GOFFObjectFileTest.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/llvm/unittests/Object/GOFFObjectFileTest.cpp b/llvm/unittests/Object/GOFFObjectFileTest.cpp
index 142666a6da077..acb8511be9851 100644
--- a/llvm/unittests/Object/GOFFObjectFileTest.cpp
+++ b/llvm/unittests/Object/GOFFObjectFileTest.cpp
@@ -711,8 +711,8 @@ TEST_F(GOFFObjectFileTest, GlobalSymbols) {
++Symbol;
};
- // FIXME: ESD records 'A' and 'B' should be considered symbols, but aren't
- // returned iteration.
+ // FIXME: ESD records 'A' and 'B' should be considered symbols, but are
+ // currently skipped by the iterators.
ValidateGlobal("C", true);
ValidateGlobal("D", true);
ValidateGlobal("E", true);
>From cd1908cd5c1dcd6f89a11a5cd1cade4a7ffc67a1 Mon Sep 17 00:00:00 2001
From: David Tenty <daltenty at ibm.com>
Date: Thu, 6 Aug 2026 21:09:47 -0400
Subject: [PATCH 10/12] Address comments
---
llvm/unittests/Object/GOFFObjectFileTest.cpp | 11 +++--------
1 file changed, 3 insertions(+), 8 deletions(-)
diff --git a/llvm/unittests/Object/GOFFObjectFileTest.cpp b/llvm/unittests/Object/GOFFObjectFileTest.cpp
index acb8511be9851..996cf8de703f5 100644
--- a/llvm/unittests/Object/GOFFObjectFileTest.cpp
+++ b/llvm/unittests/Object/GOFFObjectFileTest.cpp
@@ -687,7 +687,7 @@ TEST_F(GOFFObjectFileTest, GlobalSymbols) {
GOFFObjectFile *GOFFObj =
static_cast<GOFFObjectFile *>((*GOFFObjOrErr).get());
- auto SymbolRange = GOFFObj->symbols();
+ object::GOFFObjectFile::symbol_iterator_range SymbolRange = GOFFObj->symbols();
auto Symbol = SymbolRange.begin();
auto ValidateGlobal = [&](StringRef Name, bool IsGlobal) {
ASSERT_TRUE(Symbol != SymbolRange.end());
@@ -695,18 +695,13 @@ TEST_F(GOFFObjectFileTest, GlobalSymbols) {
// Check Name.
Expected<StringRef> SymbolNameOrErr = GOFFObj->getSymbolName(*Symbol);
ASSERT_THAT_EXPECTED(SymbolNameOrErr, Succeeded());
- StringRef SymbolName = SymbolNameOrErr.get();
- EXPECT_EQ(SymbolName, Name);
+ EXPECT_EQ(*SymbolNameOrErr, Name);
// Check flags.
Expected<uint32_t> SymbolFlagsOrErr = Symbol->getFlags();
ASSERT_THAT_EXPECTED(SymbolFlagsOrErr, Succeeded());
uint32_t SymbolFlags = SymbolFlagsOrErr.get();
- if (IsGlobal) {
- EXPECT_TRUE(SymbolFlags & SymbolRef::SF_Global);
- } else {
- EXPECT_FALSE(SymbolFlags & SymbolRef::SF_Global);
- }
+ EXPECT_EQ((SymbolFlags & SymbolRef::SF_Global) != 0, IsGlobal);
++Symbol;
};
>From 0150a0cefa25186da52d5d346cbeb63139159eb3 Mon Sep 17 00:00:00 2001
From: David Tenty <daltenty at ibm.com>
Date: Thu, 6 Aug 2026 21:40:27 -0400
Subject: [PATCH 11/12] clang-format
---
llvm/unittests/Object/GOFFObjectFileTest.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/llvm/unittests/Object/GOFFObjectFileTest.cpp b/llvm/unittests/Object/GOFFObjectFileTest.cpp
index 996cf8de703f5..1982222fc34e4 100644
--- a/llvm/unittests/Object/GOFFObjectFileTest.cpp
+++ b/llvm/unittests/Object/GOFFObjectFileTest.cpp
@@ -687,7 +687,8 @@ TEST_F(GOFFObjectFileTest, GlobalSymbols) {
GOFFObjectFile *GOFFObj =
static_cast<GOFFObjectFile *>((*GOFFObjOrErr).get());
- object::GOFFObjectFile::symbol_iterator_range SymbolRange = GOFFObj->symbols();
+ object::GOFFObjectFile::symbol_iterator_range SymbolRange =
+ GOFFObj->symbols();
auto Symbol = SymbolRange.begin();
auto ValidateGlobal = [&](StringRef Name, bool IsGlobal) {
ASSERT_TRUE(Symbol != SymbolRange.end());
>From aab44562560adbb8a04bc7b61126556814de9b41 Mon Sep 17 00:00:00 2001
From: David Tenty <daltenty at ibm.com>
Date: Fri, 7 Aug 2026 12:54:38 -0400
Subject: [PATCH 12/12] Address remaining nit
---
llvm/unittests/Object/GOFFObjectFileTest.cpp | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/llvm/unittests/Object/GOFFObjectFileTest.cpp b/llvm/unittests/Object/GOFFObjectFileTest.cpp
index 1982222fc34e4..89096a87618cc 100644
--- a/llvm/unittests/Object/GOFFObjectFileTest.cpp
+++ b/llvm/unittests/Object/GOFFObjectFileTest.cpp
@@ -701,8 +701,7 @@ TEST_F(GOFFObjectFileTest, GlobalSymbols) {
// Check flags.
Expected<uint32_t> SymbolFlagsOrErr = Symbol->getFlags();
ASSERT_THAT_EXPECTED(SymbolFlagsOrErr, Succeeded());
- uint32_t SymbolFlags = SymbolFlagsOrErr.get();
- EXPECT_EQ((SymbolFlags & SymbolRef::SF_Global) != 0, IsGlobal);
+ EXPECT_EQ((*SymbolFlagsOrErr & SymbolRef::SF_Global) != 0, IsGlobal);
++Symbol;
};
More information about the llvm-commits
mailing list