[clang] [llvm] [InstallAPI] Report exports discovered in binary but not in interface (PR #86025)
Cyndy Ishida via llvm-commits
llvm-commits at lists.llvm.org
Wed Mar 20 15:51:10 PDT 2024
https://github.com/cyndyishida updated https://github.com/llvm/llvm-project/pull/86025
>From 9c75bb6dac672fedef114618500cd8600501f8aa Mon Sep 17 00:00:00 2001
From: Cyndy Ishida <cyndy_ishida at apple.com>
Date: Wed, 20 Mar 2024 15:50:01 -0700
Subject: [PATCH] [InstallAPI] Report exports discovered in binary but not in
interface
This patch completes the classes of errors installapi can detect.
---
.../clang/Basic/DiagnosticInstallAPIKinds.td | 1 +
.../include/clang/InstallAPI/DylibVerifier.h | 13 +-
clang/lib/InstallAPI/DylibVerifier.cpp | 160 +++++++++-
clang/test/InstallAPI/diagnostics-cpp.test | 3 +
.../mismatching-objc-class-symbols.test | 269 ++++++++++++++++
clang/test/InstallAPI/symbol-flags.test | 290 ++++++++++++++++++
.../clang-installapi/ClangInstallAPI.cpp | 2 +-
llvm/lib/TextAPI/BinaryReader/DylibReader.cpp | 7 +-
8 files changed, 724 insertions(+), 21 deletions(-)
create mode 100644 clang/test/InstallAPI/mismatching-objc-class-symbols.test
create mode 100644 clang/test/InstallAPI/symbol-flags.test
diff --git a/clang/include/clang/Basic/DiagnosticInstallAPIKinds.td b/clang/include/clang/Basic/DiagnosticInstallAPIKinds.td
index f99a5fca64cb46..a7b62891100a84 100644
--- a/clang/include/clang/Basic/DiagnosticInstallAPIKinds.td
+++ b/clang/include/clang/Basic/DiagnosticInstallAPIKinds.td
@@ -26,6 +26,7 @@ def warn_library_hidden_symbol : Warning<"declaration has external linkage, but
def warn_header_hidden_symbol : Warning<"symbol exported in dynamic library, but marked hidden in declaration '%0'">, InGroup<InstallAPIViolation>;
def err_header_hidden_symbol : Error<"symbol exported in dynamic library, but marked hidden in declaration '%0'">;
def err_header_symbol_missing : Error<"no declaration found for exported symbol '%0' in dynamic library">;
+def warn_header_symbol_missing : Warning<"no declaration was found for exported symbol '%0' in dynamic library">;
def warn_header_availability_mismatch : Warning<"declaration '%0' is marked %select{available|unavailable}1,"
" but symbol is %select{not |}2exported in dynamic library">, InGroup<InstallAPIViolation>;
def err_header_availability_mismatch : Error<"declaration '%0' is marked %select{available|unavailable}1,"
diff --git a/clang/include/clang/InstallAPI/DylibVerifier.h b/clang/include/clang/InstallAPI/DylibVerifier.h
index bbfa8711313e47..49de24763f1f93 100644
--- a/clang/include/clang/InstallAPI/DylibVerifier.h
+++ b/clang/include/clang/InstallAPI/DylibVerifier.h
@@ -28,7 +28,7 @@ enum class VerificationMode {
/// lifetime of InstallAPI.
/// As declarations are collected during AST traversal, they are
/// compared as symbols against what is available in the binary dylib.
-class DylibVerifier {
+class DylibVerifier : llvm::MachO::RecordVisitor {
private:
struct SymbolContext;
@@ -72,6 +72,9 @@ class DylibVerifier {
Result verify(ObjCIVarRecord *R, const FrontendAttrs *FA,
const StringRef SuperClass);
+ // Scan through dylib slices and report any remaining missing exports.
+ Result verifyRemainingSymbols();
+
/// Initialize target for verification.
void setTarget(const Target &T);
@@ -128,6 +131,14 @@ class DylibVerifier {
/// Find matching dylib slice for target triple that is being parsed.
void assignSlice(const Target &T);
+ /// Shared implementation for verifying exported symbols in dylib.
+ void visitSymbolInDylib(const Record &R, SymbolContext &SymCtx);
+
+ void visitGlobal(const GlobalRecord &R) override;
+ void visitObjCInterface(const ObjCInterfaceRecord &R) override;
+ void visitObjCCategory(const ObjCCategoryRecord &R) override;
+ void visitObjCIVar(const ObjCIVarRecord &R, const StringRef Super);
+
/// Gather annotations for symbol for error reporting.
std::string getAnnotatedName(const Record *R, SymbolContext &SymCtx,
bool ValidSourceLoc = true);
diff --git a/clang/lib/InstallAPI/DylibVerifier.cpp b/clang/lib/InstallAPI/DylibVerifier.cpp
index 24e0d0addf2f46..2f71cd1a8044f8 100644
--- a/clang/lib/InstallAPI/DylibVerifier.cpp
+++ b/clang/lib/InstallAPI/DylibVerifier.cpp
@@ -66,17 +66,15 @@ std::string DylibVerifier::getAnnotatedName(const Record *R,
Annotation += "(tlv) ";
// Check if symbol represents only part of a @interface declaration.
- const bool IsAnnotatedObjCClass =
- ((SymCtx.ObjCIFKind != ObjCIFSymbolKind::None) &&
- (SymCtx.ObjCIFKind <= ObjCIFSymbolKind::EHType));
-
- if (IsAnnotatedObjCClass) {
- if (SymCtx.ObjCIFKind == ObjCIFSymbolKind::EHType)
- Annotation += "Exception Type of ";
- if (SymCtx.ObjCIFKind == ObjCIFSymbolKind::MetaClass)
- Annotation += "Metaclass of ";
- if (SymCtx.ObjCIFKind == ObjCIFSymbolKind::Class)
- Annotation += "Class of ";
+ switch (SymCtx.ObjCIFKind) {
+ default:
+ break;
+ case ObjCIFSymbolKind::EHType:
+ return Annotation + "Exception Type of " + PrettyName;
+ case ObjCIFSymbolKind::MetaClass:
+ return Annotation + "Metaclass of " + PrettyName;
+ case ObjCIFSymbolKind::Class:
+ return Annotation + "Class of " + PrettyName;
}
// Only print symbol type prefix or leading "_" if there is no source location
@@ -90,9 +88,6 @@ std::string DylibVerifier::getAnnotatedName(const Record *R,
return Annotation + PrettyName;
}
- if (IsAnnotatedObjCClass)
- return Annotation + PrettyName;
-
switch (SymCtx.Kind) {
case EncodeKind::GlobalSymbol:
return Annotation + PrettyName;
@@ -332,9 +327,9 @@ bool DylibVerifier::compareSymbolFlags(const Record *R, SymbolContext &SymCtx,
}
if (!DR->isThreadLocalValue() && R->isThreadLocalValue()) {
Ctx.emitDiag([&]() {
- SymCtx.FA->D->getLocation(),
- Ctx.Diag->Report(diag::err_header_symbol_flags_mismatch)
- << getAnnotatedName(DR, SymCtx) << R->isThreadLocalValue();
+ Ctx.Diag->Report(SymCtx.FA->D->getLocation(),
+ diag::err_header_symbol_flags_mismatch)
+ << getAnnotatedName(R, SymCtx) << R->isThreadLocalValue();
});
return false;
}
@@ -520,5 +515,136 @@ void DylibVerifier::VerifierContext::emitDiag(
Report();
}
+// The existence of weak-defined RTTI can not always be inferred from the
+// header files because they can be generated as part of an implementation
+// file.
+// InstallAPI doesn't warn about weak-defined RTTI, because this doesn't affect
+// linking and so can be ignored in text files.
+static bool shouldIgnoreCpp(StringRef Name, bool IsWeakDef) {
+ return (IsWeakDef &&
+ (Name.starts_with("__ZTI") || Name.starts_with("__ZTS")));
+}
+void DylibVerifier::visitSymbolInDylib(const Record &R, SymbolContext &SymCtx) {
+ if (R.isUndefined()) {
+ updateState(Result::Valid);
+ return;
+ }
+ if (R.isInternal()) {
+ updateState(Result::Valid);
+ return;
+ }
+
+ const StringRef SymbolName(SymCtx.SymbolName);
+ // Allow zippered symbols with potentially mismatching availability
+ // between macOS and macCatalyst in the final text file.
+ if (const Symbol *Sym = Exports->findSymbol(SymCtx.Kind, SymCtx.SymbolName,
+ SymCtx.ObjCIFKind)) {
+ if (Sym->hasArchitecture(Ctx.Target.Arch)) {
+ updateState(Result::Ignore);
+ return;
+ }
+ }
+
+ if (shouldIgnoreCpp(SymbolName, R.isWeakDefined())) {
+ updateState(Result::Valid);
+ return;
+ }
+
+ // All checks at the point classify as some kind of violation that should be
+ // reported.
+ if (SymbolName.starts_with("$ld$")) {
+ Ctx.emitDiag([&]() {
+ Ctx.Diag->Report(diag::err_header_symbol_missing)
+ << getAnnotatedName(&R, SymCtx, /*ValidSourceLoc=*/false);
+ });
+ updateState(Result::Invalid);
+ return;
+ }
+
+ if (Mode == VerificationMode::Pedantic) {
+ Ctx.emitDiag([&]() {
+ Ctx.Diag->Report(diag::err_header_symbol_missing)
+ << getAnnotatedName(&R, SymCtx, /*ValidSourceLoc=*/false);
+ });
+ updateState(Result::Invalid);
+ return;
+ }
+
+ if (Mode == VerificationMode::ErrorsAndWarnings) {
+ Ctx.emitDiag([&]() {
+ Ctx.Diag->Report(diag::warn_header_symbol_missing)
+ << getAnnotatedName(&R, SymCtx, /*ValidSourceLoc=*/false);
+ });
+ updateState(Result::Ignore);
+ return;
+ }
+
+ updateState(Result::Ignore);
+ return;
+}
+
+void DylibVerifier::visitGlobal(const GlobalRecord &R) {
+ if (R.isVerified())
+ return;
+ SymbolContext SymCtx;
+ SimpleSymbol Sym = parseSymbol(R.getName());
+ SymCtx.SymbolName = Sym.Name;
+ SymCtx.Kind = Sym.Kind;
+ visitSymbolInDylib(R, SymCtx);
+}
+
+void DylibVerifier::visitObjCIVar(const ObjCIVarRecord &R,
+ const StringRef Super) {
+ if (R.isVerified())
+ return;
+ SymbolContext SymCtx;
+ SymCtx.SymbolName = ObjCIVarRecord::createScopedName(Super, R.getName());
+ SymCtx.Kind = EncodeKind::ObjectiveCInstanceVariable;
+ visitSymbolInDylib(R, SymCtx);
+}
+
+void DylibVerifier::visitObjCInterface(const ObjCInterfaceRecord &R) {
+ if (R.isVerified())
+ return;
+ SymbolContext SymCtx;
+ SymCtx.SymbolName = R.getName();
+ SymCtx.ObjCIFKind = assignObjCIFSymbolKind(&R);
+ if (SymCtx.ObjCIFKind > ObjCIFSymbolKind::EHType) {
+ if (R.hasExceptionAttribute()) {
+ SymCtx.Kind = EncodeKind::ObjectiveCClassEHType;
+ visitSymbolInDylib(R, SymCtx);
+ }
+ SymCtx.Kind = EncodeKind::ObjectiveCClass;
+ visitSymbolInDylib(R, SymCtx);
+ } else {
+ SymCtx.Kind = R.hasExceptionAttribute() ? EncodeKind::ObjectiveCClassEHType
+ : EncodeKind::ObjectiveCClass;
+ visitSymbolInDylib(R, SymCtx);
+ }
+
+ for (const ObjCIVarRecord *IV : R.getObjCIVars())
+ visitObjCIVar(*IV, R.getName());
+}
+
+void DylibVerifier::visitObjCCategory(const ObjCCategoryRecord &R) {
+ for (const ObjCIVarRecord *IV : R.getObjCIVars())
+ visitObjCIVar(*IV, R.getSuperClassName());
+}
+
+DylibVerifier::Result DylibVerifier::verifyRemainingSymbols() {
+ if (getState() == Result::NoVerify)
+ return Result::NoVerify;
+ assert(!Dylib.empty() && "No binary to verify against");
+
+ Ctx.DiscoveredFirstError = false;
+ Ctx.PrintArch = true;
+ for (std::shared_ptr<RecordsSlice> Slice : Dylib) {
+ Ctx.Target = Slice->getTarget();
+ Ctx.DylibSlice = Slice.get();
+ Slice->visit(*this);
+ }
+ return getState();
+}
+
} // namespace installapi
} // namespace clang
diff --git a/clang/test/InstallAPI/diagnostics-cpp.test b/clang/test/InstallAPI/diagnostics-cpp.test
index 65888653750722..f0ff7ddfbb3bbe 100644
--- a/clang/test/InstallAPI/diagnostics-cpp.test
+++ b/clang/test/InstallAPI/diagnostics-cpp.test
@@ -21,6 +21,9 @@ CHECK-NEXT: CPP.h:5:7: error: declaration has external linkage, but symbol has i
CHECK-NEXT: CPP.h:6:7: error: dynamic library symbol '(weak-def) Bar::init()' is weak defined, but its declaration is not
CHECK-NEXT: int init();
CHECK-NEXT: ^
+CHECK-NEXT: warning: violations found for arm64
+CHECK-NEXT: error: no declaration found for exported symbol 'int foo<unsigned int>(unsigned int)' in dyn
+amic library
//--- inputs.json.in
{
diff --git a/clang/test/InstallAPI/mismatching-objc-class-symbols.test b/clang/test/InstallAPI/mismatching-objc-class-symbols.test
new file mode 100644
index 00000000000000..3b4acf1035ace3
--- /dev/null
+++ b/clang/test/InstallAPI/mismatching-objc-class-symbols.test
@@ -0,0 +1,269 @@
+; RUN: rm -rf %t
+; RUN: split-file %s %t
+; RUN: sed -e "s|DSTROOT|%/t|g" %t/inputs.json.in > %t/inputs.json
+; RUN: yaml2obj %t/swift-objc-class.yaml -o %t/libswift-objc.dylib
+
+// Try out dylib that only has 1 symbol for a ObjCClass, with no declarations in header.
+; RUN: clang-installapi -target arm64-apple-macos14 -dynamiclib \
+; RUN: -install_name tmp.dylib --verify-against=%t/libswift-objc.dylib \
+; RUN: -I%t/usr/include %t/inputs.json -o %t/missing.tbd \
+; RUN: --verify-mode=ErrorsAndWarnings 2>&1 | FileCheck --check-prefix MISSING_DECL %s
+; RUN: llvm-readtapi --compare %t/missing.tbd %t/missing-expected.tbd
+
+// Try out a dylib that only has 1 symbol for a ObjCClass,
+// but a complete ObjCClass decl in header.
+; RUN: clang-installapi -target arm64-apple-macos14 -dynamiclib \
+; RUN: -install_name tmp.dylib --verify-against=%t/libswift-objc.dylib \
+; RUN: -I%t/usr/include %t/inputs.json -o %t/mismatching.tbd \
+; RUN: --verify-mode=Pedantic -DFULL_DECL 2>&1 | FileCheck --check-prefix MISMATCH_DECL %s
+; RUN: llvm-readtapi -compare %t/mismatching.tbd %t/mismatching-expected.tbd
+
+// Try out a dylib that only has 1 symbol for a ObjCClass, but is represented in header.
+; RUN: clang-installapi -target arm64-apple-macos14 \
+; RUN: -install_name tmp.dylib --verify-against=%t/libswift-objc.dylib \
+; RUN: -I%t/usr/include %t/inputs.json -o %t/matching.tbd \
+; RUN: --verify-mode=Pedantic \
+; RUN: -DHAS_META_DECL 2>&1 | FileCheck --allow-empty %s
+
+; MISSING_DECL: violations found for arm64
+; MISSING_DECL-NEXT: warning: no declaration was found for exported symbol 'Metaclass of Suggestion' in dynamic library
+
+; MISMATCH_DECL: violations found for arm64-apple-macos14
+; MISMATCH_DECL: warning: declaration has external linkage, but dynamic library doesn't have symbol 'Class of Suggestion'
+
+; CHECK-NOT: error
+; CHECK-NOT: warning
+
+
+;--- usr/include/mismatch.h
+#if HAS_META_DECL
+int metaclass __asm("_OBJC_METACLASS_$_Suggestion");
+#endif
+
+#if FULL_DECL
+ at interface Suggestion
+ at end
+#endif
+
+;--- inputs.json.in
+{
+ "headers": [ {
+ "path" : "DSTROOT/usr/include/mismatch.h",
+ "type" : "public"
+ }
+ ],
+ "version": "3"
+}
+
+;--- missing-expected.tbd
+--- !tapi-tbd
+tbd-version: 4
+targets: [ arm64-macos ]
+flags: [ not_app_extension_safe ]
+install-name: tmp.dylib
+current-version: 0
+compatibility-version: 0
+...
+
+;--- mismatching-expected.tbd
+--- !tapi-tbd
+tbd-version: 4
+targets: [ arm64-macos ]
+flags: [ not_app_extension_safe ]
+install-name: tmp.dylib
+current-version: 0
+compatibility-version: 0
+exports:
+ - targets: [ arm64-macos ]
+ objc-classes: [ Suggestion ]
+...
+
+;--- swift-objc-class.yaml
+--- !mach-o
+FileHeader:
+ magic: 0xFEEDFACF
+ cputype: 0x100000C
+ cpusubtype: 0x0
+ filetype: 0x6
+ ncmds: 13
+ sizeofcmds: 752
+ flags: 0x100085
+ reserved: 0x0
+LoadCommands:
+ - cmd: LC_SEGMENT_64
+ cmdsize: 232
+ segname: __TEXT
+ vmaddr: 0
+ vmsize: 16384
+ fileoff: 0
+ filesize: 16384
+ maxprot: 5
+ initprot: 5
+ nsects: 2
+ flags: 0
+ Sections:
+ - sectname: __text
+ segname: __TEXT
+ addr: 0x330
+ size: 0
+ offset: 0x330
+ align: 0
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x80000000
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ content: ''
+ - sectname: __const
+ segname: __TEXT
+ addr: 0x330
+ size: 1
+ offset: 0x330
+ align: 0
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x0
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ content: '61'
+ - cmd: LC_SEGMENT_64
+ cmdsize: 72
+ segname: __LINKEDIT
+ vmaddr: 16384
+ vmsize: 416
+ fileoff: 16384
+ filesize: 416
+ maxprot: 1
+ initprot: 1
+ nsects: 0
+ flags: 0
+ - cmd: LC_DYLD_INFO_ONLY
+ cmdsize: 48
+ rebase_off: 0
+ rebase_size: 0
+ bind_off: 0
+ bind_size: 0
+ weak_bind_off: 0
+ weak_bind_size: 0
+ lazy_bind_off: 0
+ lazy_bind_size: 0
+ export_off: 16384
+ export_size: 40
+ - cmd: LC_SYMTAB
+ cmdsize: 24
+ symoff: 16432
+ nsyms: 2
+ stroff: 16464
+ strsize: 48
+ - cmd: LC_DYSYMTAB
+ cmdsize: 80
+ ilocalsym: 0
+ nlocalsym: 0
+ iextdefsym: 0
+ nextdefsym: 1
+ iundefsym: 1
+ nundefsym: 1
+ tocoff: 0
+ ntoc: 0
+ modtaboff: 0
+ nmodtab: 0
+ extrefsymoff: 0
+ nextrefsyms: 0
+ indirectsymoff: 0
+ nindirectsyms: 0
+ extreloff: 0
+ nextrel: 0
+ locreloff: 0
+ nlocrel: 0
+ - cmd: LC_ID_DYLIB
+ cmdsize: 40
+ dylib:
+ name: 24
+ timestamp: 0
+ current_version: 0
+ compatibility_version: 0
+ Content: tmp.dylib
+ ZeroPadBytes: 7
+ - cmd: LC_UUID
+ cmdsize: 24
+ uuid: 4C4C4443-5555-3144-A142-97179769CBE0
+ - cmd: LC_BUILD_VERSION
+ cmdsize: 32
+ platform: 1
+ minos: 917504
+ sdk: 983040
+ ntools: 1
+ Tools:
+ - tool: 4
+ version: 1245184
+ - cmd: LC_LOAD_DYLIB
+ cmdsize: 96
+ dylib:
+ name: 24
+ timestamp: 0
+ current_version: 197656576
+ compatibility_version: 19660800
+ Content: '/System/Library/Frameworks/Foundation.framework/Versions/C/Foundation'
+ ZeroPadBytes: 3
+ - cmd: LC_LOAD_DYLIB
+ cmdsize: 56
+ dylib:
+ name: 24
+ timestamp: 0
+ current_version: 88473600
+ compatibility_version: 65536
+ Content: '/usr/lib/libSystem.B.dylib'
+ ZeroPadBytes: 6
+ - cmd: LC_FUNCTION_STARTS
+ cmdsize: 16
+ dataoff: 16424
+ datasize: 8
+ - cmd: LC_DATA_IN_CODE
+ cmdsize: 16
+ dataoff: 16432
+ datasize: 0
+ - cmd: LC_CODE_SIGNATURE
+ cmdsize: 16
+ dataoff: 16512
+ datasize: 288
+LinkEditData:
+ ExportTrie:
+ TerminalSize: 0
+ NodeOffset: 0
+ Name: ''
+ Flags: 0x0
+ Address: 0x0
+ Other: 0x0
+ ImportName: ''
+ Children:
+ - TerminalSize: 3
+ NodeOffset: 32
+ Name: '_OBJC_METACLASS_$_Suggestion'
+ Flags: 0x0
+ Address: 0x330
+ Other: 0x0
+ ImportName: ''
+ NameList:
+ - n_strx: 2
+ n_type: 0xF
+ n_sect: 2
+ n_desc: 0
+ n_value: 816
+ - n_strx: 31
+ n_type: 0x1
+ n_sect: 0
+ n_desc: 512
+ n_value: 0
+ StringTable:
+ - ' '
+ - '_OBJC_METACLASS_$_Suggestion'
+ - dyld_stub_binder
+ FunctionStarts: [ 0x330 ]
+...
+// Generated from:
+// xcrun -sdk macosx clang tmp.c -dynamiclib -install_name tmp.dylib
+// tmp.c:
+// __attribute__((visibility("default")))
+// const char Meta __asm("_OBJC_METACLASS_$_Suggestion") = 'a';
diff --git a/clang/test/InstallAPI/symbol-flags.test b/clang/test/InstallAPI/symbol-flags.test
new file mode 100644
index 00000000000000..3f68afd17e3b20
--- /dev/null
+++ b/clang/test/InstallAPI/symbol-flags.test
@@ -0,0 +1,290 @@
+; RUN: rm -rf %t
+; RUN: split-file %s %t
+; RUN: sed -e "s|DSTROOT|%/t|g" %t/inputs.json.in > %t/inputs.json
+
+; RUN: yaml2obj %t/flags.yaml -o %t/SymbolFlags
+
+; RUN: not clang-installapi -x c++ --target=arm64-apple-macos13 \
+; RUN: -install_name /System/Library/Frameworks/SymbolFlags.framework/Versions/A/SymbolFlags \
+; RUN: -current_version 1 -compatibility_version 1 \
+; RUN: %t/inputs.json -o output.tbd \
+; RUN: --verify-against=%t/SymbolFlags \
+; RUN: --verify-mode=ErrorsOnly 2>&1 | FileCheck %s
+
+; CHECK: project.h:2:21: error: declaration '(tlv) val' is thread local, but symbol is not in dynamic library
+; CHECK-NEXT: extern __thread int val;
+; CHECK: project.h:3:13: error: dynamic library symbol '(weak-def) __Z12my_weak_funcv' is weak defined, but its declaration is not
+; CHECK-NEXT: extern void my_weak_func();
+
+;--- project.h
+extern void my_func();
+extern __thread int val;
+extern void my_weak_func();
+
+;--- inputs.json.in
+{
+ "headers": [ {
+ "path" : "DSTROOT/project.h",
+ "type" : "project"
+ }
+ ],
+ "version": "3"
+}
+
+;--- flags.yaml
+--- !mach-o
+FileHeader:
+ magic: 0xFEEDFACF
+ cputype: 0x100000C
+ cpusubtype: 0x0
+ filetype: 0x6
+ ncmds: 14
+ sizeofcmds: 912
+ flags: 0x118085
+ reserved: 0x0
+LoadCommands:
+ - cmd: LC_SEGMENT_64
+ cmdsize: 232
+ segname: __TEXT
+ vmaddr: 0
+ vmsize: 16384
+ fileoff: 0
+ filesize: 16384
+ maxprot: 5
+ initprot: 5
+ nsects: 2
+ flags: 0
+ Sections:
+ - sectname: __text
+ segname: __TEXT
+ addr: 0xFB0
+ size: 8
+ offset: 0xFB0
+ align: 2
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x80000400
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ content: C0035FD6C0035FD6
+ - sectname: __unwind_info
+ segname: __TEXT
+ addr: 0xFB8
+ size: 4152
+ offset: 0xFB8
+ align: 2
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x0
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ content: 010000001C000000010000002000000000000000200000000200000000000002B00F00003800000038000000B80F00000000000038000000030000000C0001001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+ - cmd: LC_SEGMENT_64
+ cmdsize: 152
+ segname: __DATA
+ vmaddr: 16384
+ vmsize: 16384
+ fileoff: 16384
+ filesize: 0
+ maxprot: 3
+ initprot: 3
+ nsects: 1
+ flags: 0
+ Sections:
+ - sectname: __common
+ segname: __DATA
+ addr: 0x4000
+ size: 4
+ offset: 0x0
+ align: 2
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x1
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ - cmd: LC_SEGMENT_64
+ cmdsize: 72
+ segname: __LINKEDIT
+ vmaddr: 32768
+ vmsize: 480
+ fileoff: 16384
+ filesize: 480
+ maxprot: 1
+ initprot: 1
+ nsects: 0
+ flags: 0
+ - cmd: LC_DYLD_INFO_ONLY
+ cmdsize: 48
+ rebase_off: 0
+ rebase_size: 0
+ bind_off: 0
+ bind_size: 0
+ weak_bind_off: 0
+ weak_bind_size: 0
+ lazy_bind_off: 0
+ lazy_bind_size: 0
+ export_off: 16384
+ export_size: 64
+ - cmd: LC_SYMTAB
+ cmdsize: 24
+ symoff: 16456
+ nsyms: 4
+ stroff: 16520
+ strsize: 56
+ - cmd: LC_DYSYMTAB
+ cmdsize: 80
+ ilocalsym: 0
+ nlocalsym: 0
+ iextdefsym: 0
+ nextdefsym: 3
+ iundefsym: 3
+ nundefsym: 1
+ tocoff: 0
+ ntoc: 0
+ modtaboff: 0
+ nmodtab: 0
+ extrefsymoff: 0
+ nextrefsyms: 0
+ indirectsymoff: 0
+ nindirectsyms: 0
+ extreloff: 0
+ nextrel: 0
+ locreloff: 0
+ nlocrel: 0
+ - cmd: LC_ID_DYLIB
+ cmdsize: 96
+ dylib:
+ name: 24
+ timestamp: 0
+ current_version: 65536
+ compatibility_version: 65536
+ Content: '/System/Library/Frameworks/SymbolFlags.framework/Versions/A/SymbolFlags'
+ ZeroPadBytes: 1
+ - cmd: LC_UUID
+ cmdsize: 24
+ uuid: 4C4C4436-5555-3144-A1AF-5D3063ACFC99
+ - cmd: LC_BUILD_VERSION
+ cmdsize: 32
+ platform: 1
+ minos: 851968
+ sdk: 983040
+ ntools: 1
+ Tools:
+ - tool: 4
+ version: 1245184
+ - cmd: LC_LOAD_DYLIB
+ cmdsize: 48
+ dylib:
+ name: 24
+ timestamp: 0
+ current_version: 117985024
+ compatibility_version: 65536
+ Content: '/usr/lib/libc++.1.dylib'
+ ZeroPadBytes: 1
+ - cmd: LC_LOAD_DYLIB
+ cmdsize: 56
+ dylib:
+ name: 24
+ timestamp: 0
+ current_version: 88473600
+ compatibility_version: 65536
+ Content: '/usr/lib/libSystem.B.dylib'
+ ZeroPadBytes: 6
+ - cmd: LC_FUNCTION_STARTS
+ cmdsize: 16
+ dataoff: 16448
+ datasize: 8
+ - cmd: LC_DATA_IN_CODE
+ cmdsize: 16
+ dataoff: 16456
+ datasize: 0
+ - cmd: LC_CODE_SIGNATURE
+ cmdsize: 16
+ dataoff: 16576
+ datasize: 288
+LinkEditData:
+ ExportTrie:
+ TerminalSize: 0
+ NodeOffset: 0
+ Name: ''
+ Flags: 0x0
+ Address: 0x0
+ Other: 0x0
+ ImportName: ''
+ Children:
+ - TerminalSize: 0
+ NodeOffset: 5
+ Name: _
+ Flags: 0x0
+ Address: 0x0
+ Other: 0x0
+ ImportName: ''
+ Children:
+ - TerminalSize: 4
+ NodeOffset: 16
+ Name: val
+ Flags: 0x0
+ Address: 0x4000
+ Other: 0x0
+ ImportName: ''
+ - TerminalSize: 0
+ NodeOffset: 22
+ Name: _Z
+ Flags: 0x0
+ Address: 0x0
+ Other: 0x0
+ ImportName: ''
+ Children:
+ - TerminalSize: 3
+ NodeOffset: 52
+ Name: 7my_funcv
+ Flags: 0x0
+ Address: 0xFB0
+ Other: 0x0
+ ImportName: ''
+ - TerminalSize: 3
+ NodeOffset: 57
+ Name: 12my_weak_funcv
+ Flags: 0x4
+ Address: 0xFB4
+ Other: 0x0
+ ImportName: ''
+ NameList:
+ - n_strx: 2
+ n_type: 0xF
+ n_sect: 1
+ n_desc: 0
+ n_value: 4016
+ - n_strx: 15
+ n_type: 0xF
+ n_sect: 1
+ n_desc: 128
+ n_value: 4020
+ - n_strx: 34
+ n_type: 0xF
+ n_sect: 3
+ n_desc: 0
+ n_value: 16384
+ - n_strx: 39
+ n_type: 0x1
+ n_sect: 0
+ n_desc: 512
+ n_value: 0
+ StringTable:
+ - ' '
+ - __Z7my_funcv
+ - __Z12my_weak_funcv
+ - _val
+ - dyld_stub_binder
+ FunctionStarts: [ 0xFB0, 0xFB4 ]
+...
+
+/// Generated from:
+// clang++ -mtargetos=macosx13 -arch arm64 flags.cpp
+// flags.cpp:
+// __attribute__((visibility("default"))) void my_func() {}
+// __attribute__((weak)) void my_weak_func() {}
+// int val = 0;
diff --git a/clang/tools/clang-installapi/ClangInstallAPI.cpp b/clang/tools/clang-installapi/ClangInstallAPI.cpp
index 54e82d78d4d228..13061cfa36eeb0 100644
--- a/clang/tools/clang-installapi/ClangInstallAPI.cpp
+++ b/clang/tools/clang-installapi/ClangInstallAPI.cpp
@@ -123,7 +123,7 @@ static bool run(ArrayRef<const char *> Args, const char *ProgName) {
}
}
- if (Ctx.Verifier->getState() == DylibVerifier::Result::Invalid)
+ if (Ctx.Verifier->verifyRemainingSymbols() == DylibVerifier::Result::Invalid)
return EXIT_FAILURE;
// After symbols have been collected, prepare to write output.
diff --git a/llvm/lib/TextAPI/BinaryReader/DylibReader.cpp b/llvm/lib/TextAPI/BinaryReader/DylibReader.cpp
index 0694d8f28df6bd..2e36d4a8b98ce0 100644
--- a/llvm/lib/TextAPI/BinaryReader/DylibReader.cpp
+++ b/llvm/lib/TextAPI/BinaryReader/DylibReader.cpp
@@ -293,8 +293,11 @@ static Error readSymbols(MachOObjectFile *Obj, RecordsSlice &Slice,
RecordLinkage Linkage = RecordLinkage::Unknown;
SymbolFlags RecordFlags = SymbolFlags::None;
- if (Opt.Undefineds && (Flags & SymbolRef::SF_Undefined)) {
- Linkage = RecordLinkage::Undefined;
+ if (Flags & SymbolRef::SF_Undefined) {
+ if (Opt.Undefineds)
+ Linkage = RecordLinkage::Undefined;
+ else
+ continue;
if (Flags & SymbolRef::SF_Weak)
RecordFlags |= SymbolFlags::WeakReferenced;
} else if (Flags & SymbolRef::SF_Exported) {
More information about the llvm-commits
mailing list