diff --git a/llvm/test/tools/llvm-objcopy/MachO/Inputs/strip-all.yaml b/llvm/test/tools/llvm-objcopy/MachO/Inputs/strip-all.yaml --- a/llvm/test/tools/llvm-objcopy/MachO/Inputs/strip-all.yaml +++ b/llvm/test/tools/llvm-objcopy/MachO/Inputs/strip-all.yaml @@ -262,11 +262,13 @@ n_sect: 3 n_desc: 0 n_value: 4294971392 + ## A local undefined SymDebugTable entry followed by - n_strx: 175 n_type: 0x20 n_sect: 0 n_desc: 0 n_value: 0 + ## a defined SymDebugTable entry. - n_strx: 1 n_type: 0x64 n_sect: 1 diff --git a/llvm/test/tools/llvm-objcopy/MachO/strip-all.test b/llvm/test/tools/llvm-objcopy/MachO/strip-all.test --- a/llvm/test/tools/llvm-objcopy/MachO/strip-all.test +++ b/llvm/test/tools/llvm-objcopy/MachO/strip-all.test @@ -3,6 +3,10 @@ # RUN: yaml2obj %p/Inputs/strip-all.yaml > %t.exec # RUN: yaml2obj %p/Inputs/strip-all-with-dwarf.yaml > %t.dwarf +## Check that the symbol list satisfies the order: local / defined external / +## undefined external, otherwise llvm-objcopy will fail. +# RUN: llvm-objcopy %t.exec /dev/null + # RUN: llvm-objcopy --strip-all %t.exec %t.exec.stripped # RUN: llvm-readobj --sections --relocations --symbols %t.exec.stripped \ # RUN: | FileCheck --check-prefixes=COMMON,EXEC %s diff --git a/llvm/tools/llvm-objcopy/MachO/MachOLayoutBuilder.cpp b/llvm/tools/llvm-objcopy/MachO/MachOLayoutBuilder.cpp --- a/llvm/tools/llvm-objcopy/MachO/MachOLayoutBuilder.cpp +++ b/llvm/tools/llvm-objcopy/MachO/MachOLayoutBuilder.cpp @@ -64,9 +64,11 @@ assert(std::is_sorted(O.SymTable.Symbols.begin(), O.SymTable.Symbols.end(), [](const std::unique_ptr &A, const std::unique_ptr &B) { - return (A->isLocalSymbol() && !B->isLocalSymbol()) || - (!A->isUndefinedSymbol() && - B->isUndefinedSymbol()); + bool AL = A->isLocalSymbol(), BL = B->isLocalSymbol(); + if (AL != BL) + return AL; + return !AL && !A->isUndefinedSymbol() && + B->isUndefinedSymbol(); }) && "Symbols are not sorted by their types.");