diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp --- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp +++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp @@ -2258,6 +2258,8 @@ symbol_size_valid, // Symbol size is valid has_suffix, // Contains linker annotations? flags); // Symbol flags. + if (symbol.getBinding() == STB_WEAK) + dc_symbol.SetIsWeak(true); symtab->AddSymbol(dc_symbol); } return i; diff --git a/lldb/source/Symbol/Symtab.cpp b/lldb/source/Symbol/Symtab.cpp --- a/lldb/source/Symbol/Symtab.cpp +++ b/lldb/source/Symbol/Symtab.cpp @@ -928,7 +928,53 @@ } } + // For each matching address range choose the most global symbol. + // Rewrite 'data' of all the less global symbols, Sort() below will + // discard those entries. + size_t b_ix; + for (size_t a_ix = 0; a_ix < num_entries; a_ix = b_ix) { + FileRangeToIndexMap::Entry &a = m_file_addr_to_index.GetEntryRef(a_ix); + for (b_ix = a_ix + 1; b_ix < num_entries; ++b_ix) { + FileRangeToIndexMap::Entry &b = + m_file_addr_to_index.GetEntryRef(b_ix); + if (a.GetRangeBase() != b.GetRangeBase() || + a.GetByteSize() != b.GetByteSize()) + break; + } + if (b_ix == a_ix + 1) + continue; + int val_max = -1; + FileRangeToIndexMap::Entry::DataType val_max_data; + for (size_t scan_ix = a_ix; scan_ix < b_ix; ++scan_ix) { + FileRangeToIndexMap::Entry &scan = + m_file_addr_to_index.GetEntryRef(scan_ix); + const Symbol &scan_symbol = *SymbolAtIndex(scan.data); + // Store to 'val' how much preferred is this symbol. + int val; + if (scan_symbol.IsExternal()) + val = 3; + else if (scan_symbol.IsWeak()) + val = 2; + else if (scan_symbol.IsDebug()) + val = 0; + else + val = 1; + if (val > val_max) { + val_max = val; + val_max_data = scan.data; + } + } + // Set 'data' of the most preferred symbol to all symbols with the same + // address range. + for (size_t set_ix = a_ix; set_ix < b_ix; ++set_ix) { + FileRangeToIndexMap::Entry &set = + m_file_addr_to_index.GetEntryRef(set_ix); + set.data = val_max_data; + } + } + // Sort again in case the range size changes the ordering + // Also discard duplicate 'data' from the selection above. m_file_addr_to_index.Sort(); } } diff --git a/lldb/test/Shell/SymbolFile/Inputs/symbol-binding.s b/lldb/test/Shell/SymbolFile/Inputs/symbol-binding.s new file mode 100644 --- /dev/null +++ b/lldb/test/Shell/SymbolFile/Inputs/symbol-binding.s @@ -0,0 +1,22 @@ + .text + .byte 0 +sizeless: +sizeful: + .byte 0 + .byte 0 +sizeend: + .size sizeful, sizeend - sizeful + .byte 0 +global: +globalX: + .globl globalX + .byte 0 +weak: +weakW: + .weak weakW + .byte 0 +bothW: + .weak bothW +bothX: + .globl bothX + .byte 0 diff --git a/lldb/test/Shell/SymbolFile/symbol-binding.test b/lldb/test/Shell/SymbolFile/symbol-binding.test new file mode 100644 --- /dev/null +++ b/lldb/test/Shell/SymbolFile/symbol-binding.test @@ -0,0 +1,22 @@ +# Some targets do not have the .size directive. +# RUN: %clang -target x86_64-unknown-unknown-elf %S/Inputs/symbol-binding.s -c -o %t.o +# RUN: %lldb %t.o -s %s -o quit | FileCheck %s + +image lookup --address 4 +# CHECK: Summary: symbol-binding.test.tmp.o`globalX +image lookup --address 5 +# CHECK: Summary: symbol-binding.test.tmp.o`weakW +image lookup --address 6 +# CHECK: Summary: symbol-binding.test.tmp.o`bothX +image dump symtab +# CHECK: Index UserID DSX Type File Address/Value Load Address Size Flags Name +# CHECK-NEXT:------- ------ --- --------------- ------------------ ------------------ ------------------ ---------- ---------------------------------- +# CHECK-NEXT:[ 0] 1 Code 0x0000000000000004 0x0000000000000001 0x00000000 global +# CHECK-NEXT:[ 1] 2 Code 0x0000000000000003 0x0000000000000001 0x00000000 sizeend +# CHECK-NEXT:[ 2] 3 Code 0x0000000000000001 0x0000000000000002 0x00000000 sizeful +# CHECK-NEXT:[ 3] 4 Code 0x0000000000000001 0x0000000000000002 0x00000000 sizeless +# CHECK-NEXT:[ 4] 5 Code 0x0000000000000005 0x0000000000000001 0x00000000 weak +# CHECK-NEXT:[ 5] 6 Code 0x0000000000000006 0x0000000000000001 0x00000020 bothW +# CHECK-NEXT:[ 6] 7 X Code 0x0000000000000006 0x0000000000000001 0x00000010 bothX +# CHECK-NEXT:[ 7] 8 X Code 0x0000000000000004 0x0000000000000001 0x00000010 globalX +# CHECK-NEXT:[ 8] 9 Code 0x0000000000000005 0x0000000000000001 0x00000020 weakW