mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-27 15:41:46 +00:00
[XCOFF] make related SD symbols as isFunction (#69553)
This will help tools like llvm-symbolizer recognizes more functions.
This commit is contained in:
parent
3bbed4ee26
commit
abc405858d
@ -853,6 +853,9 @@ public:
|
||||
xcoff_symbol_iterator(const basic_symbol_iterator &B)
|
||||
: symbol_iterator(B) {}
|
||||
|
||||
xcoff_symbol_iterator(const XCOFFSymbolRef *Symbol)
|
||||
: symbol_iterator(*Symbol) {}
|
||||
|
||||
const XCOFFSymbolRef *operator->() const {
|
||||
return static_cast<const XCOFFSymbolRef *>(symbol_iterator::operator->());
|
||||
}
|
||||
|
@ -1242,21 +1242,57 @@ Expected<bool> XCOFFSymbolRef::isFunction() const {
|
||||
|
||||
const XCOFFCsectAuxRef CsectAuxRef = ExpCsectAuxEnt.get();
|
||||
|
||||
// A function definition should be a label definition.
|
||||
// FIXME: This is not necessarily the case when -ffunction-sections is
|
||||
// enabled.
|
||||
if (!CsectAuxRef.isLabel())
|
||||
if (CsectAuxRef.getStorageMappingClass() != XCOFF::XMC_PR &&
|
||||
CsectAuxRef.getStorageMappingClass() != XCOFF::XMC_GL)
|
||||
return false;
|
||||
|
||||
if (CsectAuxRef.getStorageMappingClass() != XCOFF::XMC_PR)
|
||||
// A function definition should not be a common type symbol or an external
|
||||
// symbol.
|
||||
if (CsectAuxRef.getSymbolType() == XCOFF::XTY_CM ||
|
||||
CsectAuxRef.getSymbolType() == XCOFF::XTY_ER)
|
||||
return false;
|
||||
|
||||
const int16_t SectNum = getSectionNumber();
|
||||
Expected<DataRefImpl> SI = getObject()->getSectionByNum(SectNum);
|
||||
if (!SI)
|
||||
return SI.takeError();
|
||||
// If the next symbol is an XTY_LD type symbol with the same address, this
|
||||
// XTY_SD symbol is not a function. Otherwise this is a function symbol for
|
||||
// -ffunction-sections.
|
||||
if (CsectAuxRef.getSymbolType() == XCOFF::XTY_SD) {
|
||||
// If this is a csect with size 0, it won't be a function definition.
|
||||
// This is used to work around the fact that LLVM always generates below
|
||||
// symbol for -ffunction-sections:
|
||||
// m 0x00000000 .text 1 unamex **No Symbol**
|
||||
// a4 0x00000000 0 0 SD PR 0 0
|
||||
// FIXME: remove or replace this meaningless symbol.
|
||||
if (getSize() == 0)
|
||||
return false;
|
||||
|
||||
return (getObject()->getSectionFlags(SI.get()) & XCOFF::STYP_TEXT);
|
||||
xcoff_symbol_iterator NextIt(this);
|
||||
// If this is the last main symbol table entry, there won't be an XTY_LD
|
||||
// type symbol below.
|
||||
if (++NextIt == getObject()->symbol_end())
|
||||
return true;
|
||||
|
||||
if (cantFail(getAddress()) != cantFail(NextIt->getAddress()))
|
||||
return true;
|
||||
|
||||
// Check next symbol is XTY_LD. If so, this symbol is not a function.
|
||||
Expected<XCOFFCsectAuxRef> NextCsectAuxEnt = NextIt->getXCOFFCsectAuxRef();
|
||||
if (!NextCsectAuxEnt)
|
||||
return NextCsectAuxEnt.takeError();
|
||||
|
||||
if (NextCsectAuxEnt.get().getSymbolType() == XCOFF::XTY_LD)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (CsectAuxRef.getSymbolType() == XCOFF::XTY_LD)
|
||||
return true;
|
||||
|
||||
return createError(
|
||||
"symbol csect aux entry with index " +
|
||||
Twine(getObject()->getSymbolIndex(CsectAuxRef.getEntryAddress())) +
|
||||
" has invalid symbol type " +
|
||||
Twine::utohexstr(CsectAuxRef.getSymbolType()));
|
||||
}
|
||||
|
||||
bool XCOFFSymbolRef::isCsectSymbol() const {
|
||||
|
@ -17,13 +17,13 @@ entry:
|
||||
ret i32 2
|
||||
}
|
||||
|
||||
; CHECKFS32: 00000000 l .text 00000000 (idx: {{[[:digit:]]*}}) [PR]
|
||||
; CHECKFS32-NEXT: 00000000 g .text {{([[:xdigit:]]{8})}} (idx: {{[[:digit:]]*}}) .text[PR]
|
||||
; CHECKFS32-NEXT: {{([[:xdigit:]]{8})}} g .text {{([[:xdigit:]]{8})}} (idx: {{[[:digit:]]*}}) .text2[PR]
|
||||
; CHECKFS32: 00000000 l .text 00000000 (idx: {{[[:digit:]]*}}) [PR]
|
||||
; CHECKFS32-NEXT: 00000000 g F .text {{([[:xdigit:]]{8})}} (idx: {{[[:digit:]]*}}) .text[PR]
|
||||
; CHECKFS32-NEXT: {{([[:xdigit:]]{8})}} g F .text {{([[:xdigit:]]{8})}} (idx: {{[[:digit:]]*}}) .text2[PR]
|
||||
|
||||
; CHECKFS64: 0000000000000000 l .text 0000000000000000
|
||||
; CHECKFS64-NEXT: 0000000000000000 g .text {{([[:xdigit:]]{16})}} (idx: {{[[:digit:]]*}}) .text[PR]
|
||||
; CHECKFS64-NEXT: {{([[:xdigit:]]{16})}} g .text {{([[:xdigit:]]{16})}} (idx: {{[[:digit:]]*}}) .text2[PR]
|
||||
; CHECKFS64: 0000000000000000 l .text 0000000000000000
|
||||
; CHECKFS64-NEXT: 0000000000000000 g F .text {{([[:xdigit:]]{16})}} (idx: {{[[:digit:]]*}}) .text[PR]
|
||||
; CHECKFS64-NEXT: {{([[:xdigit:]]{16})}} g F .text {{([[:xdigit:]]{16})}} (idx: {{[[:digit:]]*}}) .text2[PR]
|
||||
|
||||
; CHECK32: 00000000 l .text {{([[:xdigit:]]{8})}} (idx: {{[[:digit:]]*}}) [PR]
|
||||
; CHECK32-NEXT: {{([[:xdigit:]]{8})}} g F .text (csect: (idx: {{[[:digit:]]*}}) [PR]) 00000000 (idx: {{[[:digit:]]*}}) .text
|
||||
|
@ -117,9 +117,9 @@ entry:
|
||||
; XCOFF32-NEXT: 00000000 l .text 00000000 (idx: 5) [PR]
|
||||
; XCOFF32-NEXT: 00000000 g .text 00000019 (idx: 7) .foo[PR]
|
||||
; XCOFF32-NEXT: 00000000 g F .text (csect: (idx: 7) .foo[PR]) 00000000 (idx: 9) .alias_foo
|
||||
; XCOFF32-NEXT: 00000020 g .text 00000020 .hidden (idx: 11) .hidden_foo[PR]
|
||||
; XCOFF32-NEXT: 00000040 g .text 00000059 (idx: 13) .bar[PR]
|
||||
; XCOFF32-NEXT: 000000c0 l .text 0000002a (idx: 15) .static_overalign_foo[PR]
|
||||
; XCOFF32-NEXT: 00000020 g F .text 00000020 .hidden (idx: 11) .hidden_foo[PR]
|
||||
; XCOFF32-NEXT: 00000040 g F .text 00000059 (idx: 13) .bar[PR]
|
||||
; XCOFF32-NEXT: 000000c0 l F .text 0000002a (idx: 15) .static_overalign_foo[PR]
|
||||
; XCOFF32-NEXT: 000000ec g O .data 0000000c (idx: 17) foo[DS]
|
||||
; XCOFF32-NEXT: 000000ec g O .data (csect: (idx: 17) foo[DS]) 00000000 (idx: 19) alias_foo
|
||||
; XCOFF32-NEXT: 000000f8 g O .data 0000000c .hidden (idx: 21) hidden_foo[DS]
|
||||
@ -152,9 +152,9 @@ entry:
|
||||
; XCOFF64-NEXT: 0000000000000000 l .text 0000000000000000 (idx: 5) [PR]
|
||||
; XCOFF64-NEXT: 0000000000000000 g .text 0000000000000019 (idx: 7) .foo[PR]
|
||||
; XCOFF64-NEXT: 0000000000000000 g F .text (csect: (idx: 7) .foo[PR]) 0000000000000000 (idx: 9) .alias_foo
|
||||
; XCOFF64-NEXT: 0000000000000020 g .text 0000000000000020 .hidden (idx: 11) .hidden_foo[PR]
|
||||
; XCOFF64-NEXT: 0000000000000040 g .text 0000000000000059 (idx: 13) .bar[PR]
|
||||
; XCOFF64-NEXT: 00000000000000c0 l .text 000000000000002a (idx: 15) .static_overalign_foo[PR]
|
||||
; XCOFF64-NEXT: 0000000000000020 g F .text 0000000000000020 .hidden (idx: 11) .hidden_foo[PR]
|
||||
; XCOFF64-NEXT: 0000000000000040 g F .text 0000000000000059 (idx: 13) .bar[PR]
|
||||
; XCOFF64-NEXT: 00000000000000c0 l F .text 000000000000002a (idx: 15) .static_overalign_foo[PR]
|
||||
; XCOFF64-NEXT: 00000000000000f0 g O .data 0000000000000018 (idx: 17) foo[DS]
|
||||
; XCOFF64-NEXT: 00000000000000f0 g O .data (csect: (idx: 17) foo[DS]) 0000000000000000 (idx: 19) alias_foo
|
||||
; XCOFF64-NEXT: 0000000000000108 g O .data 0000000000000018 .hidden (idx: 21) hidden_foo[DS]
|
||||
|
@ -0,0 +1,33 @@
|
||||
## Check that llvm-objdump --syms reports an error when
|
||||
## the symbol type in the csect aux entry of a symbol is not valid.
|
||||
|
||||
## Check XCOFF32
|
||||
# RUN: yaml2obj -DMAGICNUMBER=0x1DF %s -o %t1
|
||||
# RUN: not llvm-objdump --syms %t1 2>&1 | FileCheck %s -DOBJ=%t1
|
||||
|
||||
## Check XCOFF64
|
||||
# RUN: yaml2obj -DMAGICNUMBER=0x1F7 %s -o %t2
|
||||
# RUN: not llvm-objdump --syms %t2 2>&1 | FileCheck %s -DOBJ=%t2
|
||||
|
||||
# CHECK: error: '[[OBJ]]': symbol csect aux entry with index 2 has invalid symbol type 5
|
||||
|
||||
--- !XCOFF
|
||||
FileHeader:
|
||||
MagicNumber: [[MAGICNUMBER]]
|
||||
Sections:
|
||||
- Name: .text
|
||||
Flags: [ STYP_TEXT ]
|
||||
Symbols:
|
||||
- Name: .file
|
||||
Section: N_DEBUG
|
||||
NumberOfAuxEntries: 0
|
||||
Type: 0x0
|
||||
StorageClass: C_FILE
|
||||
- Name: test
|
||||
Section: .text
|
||||
NumberOfAuxEntries: 1
|
||||
StorageClass: C_EXT
|
||||
AuxEntries:
|
||||
- Type: AUX_CSECT
|
||||
SymbolAlignmentAndType: 5
|
||||
StorageMappingClass: XMC_PR
|
@ -16,10 +16,10 @@ entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK: ??
|
||||
; CHECK: .foo
|
||||
; CHECK: ??:0:0
|
||||
; CHECK-EMPTY:
|
||||
|
||||
; CHECK: ??
|
||||
; CHECK: .foo1
|
||||
; CHECK: ??:0:0
|
||||
; CHECK-EMPTY:
|
||||
|
Loading…
Reference in New Issue
Block a user