Skip to content

Commit b781312

Browse files
committed
objdump prioritize actual symbols over dummy symbols during resolution
1 parent 846d055 commit b781312

File tree

5 files changed

+76
-21
lines changed

5 files changed

+76
-21
lines changed

llvm/include/llvm/MC/MCDisassembler/MCDisassembler.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,14 @@ struct SymbolInfoTy {
3434
uint8_t Type;
3535
// Used by ELF to describe a mapping symbol that is usually not displayed.
3636
bool IsMappingSymbol;
37+
bool IsDummy = false;
3738

3839
private:
3940
bool IsXCOFF;
4041
bool HasType;
4142

4243
public:
44+
SymbolInfoTy() = default;
4345
SymbolInfoTy(std::optional<XCOFF::StorageMappingClass> Smc, uint64_t Addr,
4446
StringRef Name, std::optional<uint32_t> Idx, bool Label)
4547
: Addr(Addr), Name(Name), XCOFFSymInfo{Smc, Idx, Label}, Type(0),

llvm/test/tools/llvm-objdump/X86/disassemble-same-section-addr.test

Lines changed: 47 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,33 +5,33 @@
55
## to reproduce the original failure.
66

77
## Two empty sections, one with symbol in, one without.
8-
# RUN: yaml2obj %s --docnum=1 -o %t1 -D SIZE1=0 -D SIZE2=0 -D SECTION=.second -D INDEX=SHN_ABS
8+
# RUN: yaml2obj %s --docnum=1 -o %t1 -D SIZE1=0 -D SIZE2=0 -D SECTION=.second -D INDEX=SHN_ABS -D VALUE=0x5
99
# RUN: llvm-objdump -d %t1 | FileCheck %s --check-prefix=TARGET
10-
# RUN: yaml2obj %s --docnum=1 -o %t2 -D SIZE1=0 -D SIZE2=0 -D SECTION=.first -D INDEX=SHN_ABS
10+
# RUN: yaml2obj %s --docnum=1 -o %t2 -D SIZE1=0 -D SIZE2=0 -D SECTION=.first -D INDEX=SHN_ABS -D VALUE=0x5
1111
# RUN: llvm-objdump -d %t2 | FileCheck %s --check-prefix=TARGET
1212

1313
## Two sections, one empty with symbol, other non-empty, without symbol.
14-
# RUN: yaml2obj %s --docnum=1 -o %t3 -D SIZE1=1 -D SIZE2=0 -D SECTION=.second -D INDEX=SHN_ABS
14+
# RUN: yaml2obj %s --docnum=1 -o %t3 -D SIZE1=1 -D SIZE2=0 -D SECTION=.second -D INDEX=SHN_ABS -D VALUE=0x5
1515
# RUN: llvm-objdump -d %t3 | FileCheck %s --check-prefix=TARGET
16-
# RUN: yaml2obj %s --docnum=1 -o %t4 -D SIZE1=0 -D SIZE2=1 -D SECTION=.first -D INDEX=SHN_ABS
16+
# RUN: yaml2obj %s --docnum=1 -o %t4 -D SIZE1=0 -D SIZE2=1 -D SECTION=.first -D INDEX=SHN_ABS -D VALUE=0x5
1717
# RUN: llvm-objdump -d %t4 | FileCheck %s --check-prefix=TARGET
1818

19-
## Fall back to absolute symbol if no symbol found in candidate sections.
20-
# RUN: yaml2obj %s --docnum=1 -o %t5 -D SIZE1=1 -D SIZE2=0 -D SECTION=.caller -D INDEX=SHN_ABS
19+
## Fall back to absolute symbols before dummy symbols if no symbols in candidate sections.
20+
# RUN: yaml2obj %s --docnum=1 -o %t5 -D SIZE1=1 -D SIZE2=0 -D SECTION=.caller -D INDEX=SHN_ABS -D VALUE=0x6
2121
# RUN: llvm-objdump -d %t5 | FileCheck %s --check-prefix=ABSOLUTE
2222

2323
## Show that other symbols with reserved st_shndx values are treated as absolute
24-
## symbols.
25-
# RUN: yaml2obj %s --docnum=1 -o %t6 -D SIZE1=1 -D SIZE2=0 -D SECTION=.caller -D INDEX=SHN_LOPROC
24+
# RUN: yaml2obj %s --docnum=1 -o %t6 -D SIZE1=1 -D SIZE2=0 -D SECTION=.caller -D INDEX=SHN_LOPROC -D VALUE=0x6
2625
# RUN: llvm-objdump -d %t6 | FileCheck %s --check-prefix=ABSOLUTE
2726

28-
## Print no target if no symbol in section/absolute symbol found.
27+
## Print dummy symbol if available and if no symbol in section/absolute symbol found.
2928
# RUN: llvm-objcopy %t5 %t7 -N other
30-
# RUN: llvm-objdump -d %t7 | FileCheck %s --check-prefix=FAIL
29+
# RUN: llvm-objdump -d %t7 | FileCheck %s --check-prefix=DUMMY
3130

3231
# TARGET: callq 0x5 <target>
3332
# ABSOLUTE: callq 0x5 <other+0x5>
3433
# FAIL: callq 0x5{{$}}
34+
# DUMMY: callq 0x5 <.caller+0x5>
3535

3636
--- !ELF
3737
FileHeader:
@@ -58,7 +58,7 @@ Sections:
5858
Symbols:
5959
- Name: target
6060
Section: [[SECTION]]
61-
Value: 0x5
61+
Value: [[VALUE]]
6262
- Name: other
6363
Index: [[INDEX]]
6464
Value: 0x0
@@ -112,3 +112,39 @@ Symbols:
112112
- Name: second
113113
Section: .second
114114
Value: [[SYMVAL2]]
115+
116+
## Fall back to symbols in earlier sections if no symbols in target section
117+
# RUN: yaml2obj %s --docnum=2 -o %t12 -D SIZE1=2 -D SIZE2=0 -D SYMVAL1=0x1 -D SYMVAL2=0x5 -D SYMSEC1=.caller
118+
# RUN: llvm-objdump -d %t12 | FileCheck %s --check-prefix=PREVSECSYM
119+
120+
# PREVSECSYM: callq 0x5 <first+0x4>
121+
122+
--- !ELF
123+
FileHeader:
124+
Class: ELFCLASS64
125+
Data: ELFDATA2LSB
126+
Type: ET_EXEC
127+
Machine: EM_X86_64
128+
Sections:
129+
- Name: .caller
130+
Type: SHT_PROGBITS
131+
Flags: [SHF_ALLOC, SHF_EXECINSTR]
132+
Address: 0x0
133+
- Name: .first
134+
Type: SHT_PROGBITS
135+
Flags: [SHF_ALLOC, SHF_EXECINSTR]
136+
Address: 0x3
137+
Content: e800000000 ## Call instruction to next address.
138+
Size: [[SIZE1]]
139+
- Name: .second
140+
Type: SHT_PROGBITS
141+
Flags: [SHF_ALLOC, SHF_EXECINSTR]
142+
Address: 0x5
143+
Size: [[SIZE2]]
144+
Symbols:
145+
- Name: first
146+
Section: [[SYMSEC1]]
147+
Value: [[SYMVAL1]]
148+
- Name: second
149+
Section: .second
150+
Value: [[SYMVAL2]]

llvm/test/tools/llvm-objdump/X86/elf-disassemble-symbol-references.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ Symbols:
5858
# REL: Disassembly of section .text1:
5959
# REL-EMPTY:
6060
# REL-NEXT: 0000000000000000 <.text1>:
61-
# REL-NEXT: 0: e8 00 00 00 00 callq 0x5 <.text1+0x5>
61+
# REL-NEXT: 0: e8 00 00 00 00 callq 0x5 <sym3+0x5>
6262
# REL-EMPTY:
6363
# REL-NEXT: Disassembly of section .text2:
6464
# REL-EMPTY:
@@ -68,7 +68,7 @@ Symbols:
6868
# REL-NEXT: Disassembly of section .text3:
6969
# REL-EMPTY:
7070
# REL-NEXT: 0000000000000000 <.text3>:
71-
# REL-NEXT: 0: e8 00 00 00 00 callq 0x5 <.text3+0x5>
71+
# REL-NEXT: 0: e8 00 00 00 00 callq 0x5 <sym3+0x5>
7272

7373
--- !ELF
7474
FileHeader:

llvm/test/tools/llvm-objdump/X86/section-filter-relocs.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
# DISASM: Disassembly of section .text:
1111
# DISASM-EMPTY:
1212
# DISASM-NEXT: 0000000000000400 <.text>:
13-
# DISASM-NEXT: 400: e8 00 00 00 00 callq 0x405 <.text+0x5>
13+
# DISASM-NEXT: 400: e8 00 00 00 00 callq 0x405 <foo+0x405>
1414
# RELOC-NEXT: 00000401: R_X86_64_PC32 foo+0x1
1515
# RELOC-NEXT: 00000401: R_X86_64_GOT32 foo
1616
# DISASM: Disassembly of section .rodata:

llvm/tools/llvm-objdump/llvm-objdump.cpp

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
#include "llvm/Object/MachOUniversal.h"
6262
#include "llvm/Object/ObjectFile.h"
6363
#include "llvm/Object/OffloadBinary.h"
64+
#include "llvm/Object/SymbolicFile.h"
6465
#include "llvm/Object/Wasm.h"
6566
#include "llvm/Option/Arg.h"
6667
#include "llvm/Option/ArgList.h"
@@ -85,8 +86,10 @@
8586
#include <cctype>
8687
#include <cstring>
8788
#include <optional>
89+
#include <queue>
8890
#include <set>
8991
#include <system_error>
92+
#include <unistd.h>
9093
#include <unordered_map>
9194
#include <utility>
9295

@@ -1436,11 +1439,15 @@ SymbolInfoTy objdump::createSymbolInfo(const ObjectFile &Obj,
14361439
static SymbolInfoTy createDummySymbolInfo(const ObjectFile &Obj,
14371440
const uint64_t Addr, StringRef &Name,
14381441
uint8_t Type) {
1442+
SymbolInfoTy Ret;
14391443
if (Obj.isXCOFF() && (SymbolDescription || TracebackTable))
1440-
return SymbolInfoTy(std::nullopt, Addr, Name, std::nullopt, false);
1441-
if (Obj.isWasm())
1442-
return SymbolInfoTy(Addr, Name, wasm::WASM_SYMBOL_TYPE_SECTION);
1443-
return SymbolInfoTy(Addr, Name, Type);
1444+
Ret = SymbolInfoTy(std::nullopt, Addr, Name, std::nullopt, false);
1445+
else if (Obj.isWasm())
1446+
Ret = SymbolInfoTy(Addr, Name, wasm::WASM_SYMBOL_TYPE_SECTION);
1447+
else
1448+
Ret = SymbolInfoTy(Addr, Name, Type);
1449+
Ret.IsDummy = true;
1450+
return Ret;
14441451
}
14451452

14461453
static void collectBBAddrMapLabels(
@@ -2366,11 +2373,10 @@ disassembleObject(ObjectFile &Obj, const ObjectFile &DbgObj,
23662373
while (It != SectionAddresses.begin()) {
23672374
--It;
23682375
if (It->first != TargetSecAddr) {
2369-
if (!FoundSymbols) {
2376+
if (!FoundSymbols)
23702377
TargetSecAddr = It->first;
2371-
} else {
2378+
else
23722379
break;
2373-
}
23742380
}
23752381
TargetSectionSymbols.push_back(&AllSymbols[It->second]);
23762382
if (!AllSymbols[It->second].empty())
@@ -2387,13 +2393,18 @@ disassembleObject(ObjectFile &Obj, const ObjectFile &DbgObj,
23872393
// using the nearest preceding absolute symbol (if any), if there
23882394
// are no other valid symbols.
23892395
const SymbolInfoTy *TargetSym = nullptr;
2396+
std::queue<const SymbolInfoTy *> DummySymbols;
23902397
for (const SectionSymbolsTy *TargetSymbols :
23912398
TargetSectionSymbols) {
23922399
auto It = llvm::partition_point(
23932400
*TargetSymbols,
23942401
[=](const SymbolInfoTy &O) { return O.Addr <= Target; });
23952402
while (It != TargetSymbols->begin()) {
23962403
--It;
2404+
if (It->IsDummy) {
2405+
DummySymbols.push(&(*It));
2406+
continue;
2407+
}
23972408
// Skip mapping symbols to avoid possible ambiguity as they
23982409
// do not allow uniquely identifying the target address.
23992410
if (!It->IsMappingSymbol) {
@@ -2404,6 +2415,12 @@ disassembleObject(ObjectFile &Obj, const ObjectFile &DbgObj,
24042415
if (TargetSym)
24052416
break;
24062417
}
2418+
while (!DummySymbols.empty() && !TargetSym) {
2419+
const SymbolInfoTy *Sym = DummySymbols.front();
2420+
if (!Sym->IsMappingSymbol)
2421+
TargetSym = Sym;
2422+
DummySymbols.pop();
2423+
}
24072424

24082425
// Branch and instruction targets are printed just after the instructions.
24092426
// Print the labels corresponding to the target if there's any.

0 commit comments

Comments
 (0)