Skip to content

Commit 8971b99

Browse files
committed
[llvm-objdump/llvm-readobj/obj2yaml/yaml2obj] Support STO_RISCV_VARIANT_CC and DT_RISCV_VARIANT_CC
STO_RISCV_VARIANT_CC marks that a symbol uses a non-standard calling convention or the vector calling convention. See riscv-non-isa/riscv-elf-psabi-doc#190 Differential Revision: https://reviews.llvm.org/D107949
1 parent e49c0c5 commit 8971b99

File tree

10 files changed

+201
-1
lines changed

10 files changed

+201
-1
lines changed

llvm/include/llvm/BinaryFormat/DynamicTags.def

+12
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@
3131
#define PPC64_DYNAMIC_TAG_DEFINED
3232
#endif
3333

34+
#ifndef RISCV_DYNAMIC_TAG
35+
#define RISCV_DYNAMIC_TAG(name, value) DYNAMIC_TAG(name, value)
36+
#define RISCV_DYNAMIC_TAG_DEFINED
37+
#endif
38+
3439
#ifndef DYNAMIC_TAG_MARKER
3540
#define DYNAMIC_TAG_MARKER(name, value) DYNAMIC_TAG(name, value)
3641
#define DYNAMIC_TAG_MARKER_DEFINED
@@ -213,6 +218,9 @@ PPC_DYNAMIC_TAG(PPC_OPT, 0x70000001) // Has TLS optimization.
213218
PPC64_DYNAMIC_TAG(PPC64_GLINK, 0x70000000) // Address of 32 bytes before the
214219
// first glink lazy resolver stub.
215220

221+
// RISC-V specific dynamic array tags.
222+
RISCV_DYNAMIC_TAG(RISCV_VARIANT_CC, 0x70000001)
223+
216224
// Sun machine-independent extensions.
217225
DYNAMIC_TAG(AUXILIARY, 0x7FFFFFFD) // Shared object to load before self
218226
DYNAMIC_TAG(USED, 0x7FFFFFFE) // Same as DT_NEEDED
@@ -243,3 +251,7 @@ DYNAMIC_TAG(FILTER, 0x7FFFFFFF) // Shared object to get values from
243251
#undef PPC64_DYNAMIC_TAG
244252
#undef PPC64_DYNAMIC_TAG_DEFINED
245253
#endif
254+
#ifdef RISCV_DYNAMIC_TAG_DEFINED
255+
#undef RISCV_DYNAMIC_TAG
256+
#undef RISCV_DYNAMIC_TAG_DEFINED
257+
#endif

llvm/include/llvm/BinaryFormat/ELF.h

+6
Original file line numberDiff line numberDiff line change
@@ -660,6 +660,12 @@ enum {
660660
#include "ELFRelocs/RISCV.def"
661661
};
662662

663+
enum {
664+
// Symbol may follow different calling convention than the standard calling
665+
// convention.
666+
STO_RISCV_VARIANT_CC = 0x80
667+
};
668+
663669
// ELF Relocation types for S390/zSeries
664670
enum {
665671
#include "ELFRelocs/SystemZ.def"

llvm/lib/Object/ELF.cpp

+10
Original file line numberDiff line numberDiff line change
@@ -492,6 +492,14 @@ std::string ELFFile<ELFT>::getDynamicTagAsString(unsigned Arch,
492492
#undef PPC64_DYNAMIC_TAG
493493
}
494494
break;
495+
496+
case ELF::EM_RISCV:
497+
switch (Type) {
498+
#define RISCV_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)
499+
#include "llvm/BinaryFormat/DynamicTags.def"
500+
#undef RISCV_DYNAMIC_TAG
501+
}
502+
break;
495503
}
496504
#undef DYNAMIC_TAG
497505
switch (Type) {
@@ -501,6 +509,7 @@ std::string ELFFile<ELFT>::getDynamicTagAsString(unsigned Arch,
501509
#define HEXAGON_DYNAMIC_TAG(name, value)
502510
#define PPC_DYNAMIC_TAG(name, value)
503511
#define PPC64_DYNAMIC_TAG(name, value)
512+
#define RISCV_DYNAMIC_TAG(name, value)
504513
// Also ignore marker tags such as DT_HIOS (maps to DT_VERNEEDNUM), etc.
505514
#define DYNAMIC_TAG_MARKER(name, value)
506515
#define DYNAMIC_TAG(name, value) case value: return #name;
@@ -511,6 +520,7 @@ std::string ELFFile<ELFT>::getDynamicTagAsString(unsigned Arch,
511520
#undef HEXAGON_DYNAMIC_TAG
512521
#undef PPC_DYNAMIC_TAG
513522
#undef PPC64_DYNAMIC_TAG
523+
#undef RISCV_DYNAMIC_TAG
514524
#undef DYNAMIC_TAG_MARKER
515525
#undef DYNAMIC_STRINGIFY_ENUM
516526
default:

llvm/lib/ObjectYAML/ELFYAML.cpp

+9
Original file line numberDiff line numberDiff line change
@@ -890,6 +890,13 @@ void ScalarEnumerationTraits<ELFYAML::ELF_DYNTAG>::enumeration(
890890
#undef PPC64_DYNAMIC_TAG
891891
#define PPC64_DYNAMIC_TAG(name, value)
892892
break;
893+
case ELF::EM_RISCV:
894+
#undef RISCV_DYNAMIC_TAG
895+
#define RISCV_DYNAMIC_TAG(name, value) DYNAMIC_TAG(name, value)
896+
#include "llvm/BinaryFormat/DynamicTags.def"
897+
#undef RISCV_DYNAMIC_TAG
898+
#define RISCV_DYNAMIC_TAG(name, value)
899+
break;
893900
default:
894901
#include "llvm/BinaryFormat/DynamicTags.def"
895902
break;
@@ -1168,6 +1175,8 @@ struct NormalizedOther {
11681175

11691176
if (EMachine == ELF::EM_AARCH64)
11701177
Map["STO_AARCH64_VARIANT_PCS"] = ELF::STO_AARCH64_VARIANT_PCS;
1178+
if (EMachine == ELF::EM_RISCV)
1179+
Map["STO_RISCV_VARIANT_CC"] = ELF::STO_RISCV_VARIANT_CC;
11711180
return Map;
11721181
}
11731182

llvm/test/tools/llvm-objdump/ELF/dynamic-section-machine-specific.test

+29
Original file line numberDiff line numberDiff line change
@@ -289,3 +289,32 @@ ProgramHeaders:
289289
- Type: PT_DYNAMIC
290290
FirstSec: .dynamic
291291
LastSec: .dynamic
292+
293+
## Case 6: Test that RISC-V machine-specific tags can be dumped.
294+
# RUN: yaml2obj --docnum=6 %s -o %t.rv
295+
# RUN: llvm-objdump -p %t.rv | FileCheck %s --check-prefix=RISCV
296+
297+
# RISCV: Dynamic Section:
298+
# RISCV-NEXT: RISCV_VARIANT_CC 0x0000000000000001
299+
300+
--- !ELF
301+
FileHeader:
302+
Class: ELFCLASS64
303+
Data: ELFDATA2LSB
304+
Type: ET_EXEC
305+
Machine: EM_RISCV
306+
Sections:
307+
- Name: .dynamic
308+
Type: SHT_DYNAMIC
309+
Entries:
310+
- Tag: DT_RISCV_VARIANT_CC
311+
Value: 1
312+
- Tag: DT_NULL
313+
Value: 0
314+
ProgramHeaders:
315+
- Type: PT_LOAD
316+
FirstSec: .dynamic
317+
LastSec: .dynamic
318+
- Type: PT_DYNAMIC
319+
FirstSec: .dynamic
320+
LastSec: .dynamic
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
## Check that we are able to dump RISC-V STO_* flags correctly when dumping symbols.
2+
3+
# RUN: yaml2obj %s -o %t.o
4+
# RUN: llvm-readobj -s %t.o | FileCheck %s --check-prefix=LLVM
5+
# RUN: llvm-readelf -s %t.o | FileCheck %s --check-prefix=GNU
6+
7+
# LLVM: Name: foo1
8+
# LLVM: Other [ (0x80)
9+
# LLVM-NEXT: STO_RISCV_VARIANT_CC (0x80)
10+
# LLVM-NEXT: ]
11+
# LLVM: Name: foo2
12+
# LLVM: Other [ (0xC0)
13+
# LLVM-NEXT: STO_RISCV_VARIANT_CC (0x80)
14+
# LLVM-NEXT: ]
15+
# LLVM: Name: foo3
16+
# LLVM: Other [ (0x83)
17+
# LLVM-NEXT: STO_RISCV_VARIANT_CC (0x80)
18+
# LLVM-NEXT: STV_PROTECTED (0x3)
19+
# LLVM-NEXT: ]
20+
21+
# GNU: Symbol table '.symtab' contains 4 entries:
22+
# GNU: 1: 0000000000000000 0 NOTYPE LOCAL DEFAULT [VARIANT_CC] UND foo1
23+
# GNU-NEXT: 2: 0000000000000000 0 NOTYPE LOCAL DEFAULT [VARIANT_CC | 40] UND foo2
24+
# GNU-NEXT: 3: 0000000000000000 0 NOTYPE LOCAL PROTECTED [VARIANT_CC] UND foo3
25+
26+
--- !ELF
27+
FileHeader:
28+
Class: ELFCLASS64
29+
Data: ELFDATA2LSB
30+
Type: ET_REL
31+
Machine: EM_RISCV
32+
Symbols:
33+
- Name: foo1
34+
Other: [ STO_RISCV_VARIANT_CC ]
35+
- Name: foo2
36+
Other: [ STO_RISCV_VARIANT_CC, 0x40 ]
37+
- Name: foo3
38+
Other: [ STO_RISCV_VARIANT_CC, STV_PROTECTED ]

llvm/test/tools/llvm-readobj/ELF/dynamic-tags-machine-specific.test

+38
Original file line numberDiff line numberDiff line change
@@ -391,3 +391,41 @@ ProgramHeaders:
391391
- Type: PT_DYNAMIC
392392
FirstSec: .dynamic
393393
LastSec: .dynamic
394+
395+
## Case 6: Test that RISC-V machine-specific tags can be dumped.
396+
# RUN: yaml2obj --docnum=6 %s -o %t.rv
397+
# RUN: llvm-readobj --dynamic-table %t.rv | FileCheck %s --check-prefix=LLVM-RISCV
398+
# RUN: llvm-readelf --dynamic-table %t.rv | FileCheck %s --check-prefix=GNU-RISCV
399+
400+
# LLVM-RISCV: DynamicSection [ (2 entries)
401+
# LLVM-RISCV-NEXT: Tag Type Name/Value
402+
# LLVM-RISCV-NEXT: 0x0000000070000001 RISCV_VARIANT_CC 0x1
403+
# LLVM-RISCV-NEXT: 0x0000000000000000 NULL 0x0
404+
# LLVM-RISCV-NEXT: ]
405+
406+
# GNU-RISCV: Dynamic section at offset {{.*}} contains 2 entries:
407+
# GNU-RISCV-NEXT: Tag Type Name/Value
408+
# GNU-RISCV-NEXT: 0x0000000070000001 (RISCV_VARIANT_CC) 0x1
409+
# GNU-RISCV-NEXT: 0x0000000000000000 (NULL) 0x0
410+
411+
--- !ELF
412+
FileHeader:
413+
Class: ELFCLASS64
414+
Data: ELFDATA2LSB
415+
Type: ET_EXEC
416+
Machine: EM_RISCV
417+
Sections:
418+
- Name: .dynamic
419+
Type: SHT_DYNAMIC
420+
Entries:
421+
- Tag: DT_RISCV_VARIANT_CC
422+
Value: 1
423+
- Tag: DT_NULL
424+
Value: 0
425+
ProgramHeaders:
426+
- Type: PT_LOAD
427+
FirstSec: .dynamic
428+
LastSec: .dynamic
429+
- Type: PT_DYNAMIC
430+
FirstSec: .dynamic
431+
LastSec: .dynamic

llvm/test/tools/obj2yaml/ELF/dynamic-section-arch-tags.yaml

+21-1
Original file line numberDiff line numberDiff line change
@@ -297,12 +297,32 @@ Sections:
297297
- Tag: DT_AARCH64_PAC_PLT
298298
Value: 0x0000000000000000
299299

300+
## Check we can handle RISC-V specific tags.
301+
# RUN: yaml2obj --docnum=6 %s -o %t6
302+
# RUN: obj2yaml %t6 | FileCheck %s --check-prefix=RISCV
303+
304+
# RISCV: - Tag: DT_RISCV_VARIANT_CC
305+
# RISCV-NEXT: Value: 0x0
306+
307+
--- !ELF
308+
FileHeader:
309+
Class: ELFCLASS64
310+
Data: ELFDATA2LSB
311+
Type: ET_REL
312+
Machine: EM_RISCV
313+
Sections:
314+
- Name: .dynamic
315+
Type: SHT_DYNAMIC
316+
Entries:
317+
- Tag: DT_RISCV_VARIANT_CC
318+
Value: 0x0000000000000000
319+
300320
## Check we can't use a tag from a different architecture,
301321
## even if it has the same numeric value as a valid tag.
302322
## Here for EM_PPC64 we are trying to use DT_HEXAGON_SYMSZ
303323
## instead of DT_PPC64_GLINK. They both have value of 0x70000000.
304324

305-
# RUN: not yaml2obj --docnum=6 %s 2>&1 | FileCheck %s --check-prefix=ERR
325+
# RUN: not yaml2obj --docnum=7 %s 2>&1 | FileCheck %s --check-prefix=ERR
306326
# ERR: error: invalid hex64 number
307327
# ERR-NEXT: - Tag: DT_HEXAGON_SYMSZ
308328

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
## Check RISC-V st_other extension support.
2+
3+
# RUN: yaml2obj %s -o %t
4+
# RUN: obj2yaml %t | FileCheck %s
5+
6+
# CHECK: Symbols:
7+
# CHECK: - Name: foo1
8+
# CHECK: Other: [ STO_RISCV_VARIANT_CC ]
9+
# CHECK: - Name: foo2
10+
# CHECK: Other: [ STO_RISCV_VARIANT_CC, 64 ]
11+
12+
--- !ELF
13+
FileHeader:
14+
Class: ELFCLASS64
15+
Data: ELFDATA2LSB
16+
Type: ET_REL
17+
Machine: EM_RISCV
18+
Symbols:
19+
- Name: foo1
20+
Other: [ STO_RISCV_VARIANT_CC ]
21+
- Name: foo2
22+
Other: [ STO_RISCV_VARIANT_CC, 0x40 ]

llvm/tools/llvm-readobj/ELFDumper.cpp

+16
Original file line numberDiff line numberDiff line change
@@ -1616,6 +1616,9 @@ static const EnumEntry<unsigned> ElfMips16SymOtherFlags[] = {
16161616
LLVM_READOBJ_ENUM_ENT(ELF, STO_MIPS_MIPS16)
16171617
};
16181618

1619+
static const EnumEntry<unsigned> ElfRISCVSymOtherFlags[] = {
1620+
LLVM_READOBJ_ENUM_ENT(ELF, STO_RISCV_VARIANT_CC)};
1621+
16191622
static const char *getElfMipsOptionsOdkType(unsigned Odk) {
16201623
switch (Odk) {
16211624
LLVM_READOBJ_ENUM_CASE(ELF, ODK_NULL);
@@ -3773,6 +3776,15 @@ void GNUELFDumper<ELFT>::printSymbol(const Elf_Sym &Symbol, unsigned SymIndex,
37733776
Fields[5].Str.append(" | " + to_hexString(Other, false));
37743777
Fields[5].Str.append("]");
37753778
}
3779+
} else if (this->Obj.getHeader().e_machine == ELF::EM_RISCV) {
3780+
uint8_t Other = Symbol.st_other & ~0x3;
3781+
if (Other & STO_RISCV_VARIANT_CC) {
3782+
Other &= ~STO_RISCV_VARIANT_CC;
3783+
Fields[5].Str += " [VARIANT_CC";
3784+
if (Other != 0)
3785+
Fields[5].Str.append(" | " + to_hexString(Other, false));
3786+
Fields[5].Str.append("]");
3787+
}
37763788
} else {
37773789
Fields[5].Str +=
37783790
" [<other: " + to_string(format_hex(Symbol.st_other, 2)) + ">]";
@@ -6577,6 +6589,10 @@ void LLVMELFDumper<ELFT>::printSymbol(const Elf_Sym &Symbol, unsigned SymIndex,
65776589
SymOtherFlags.insert(SymOtherFlags.end(),
65786590
std::begin(ElfAArch64SymOtherFlags),
65796591
std::end(ElfAArch64SymOtherFlags));
6592+
} else if (this->Obj.getHeader().e_machine == EM_RISCV) {
6593+
SymOtherFlags.insert(SymOtherFlags.end(),
6594+
std::begin(ElfRISCVSymOtherFlags),
6595+
std::end(ElfRISCVSymOtherFlags));
65806596
}
65816597
W.printFlags("Other", Symbol.st_other, makeArrayRef(SymOtherFlags), 0x3u);
65826598
}

0 commit comments

Comments
 (0)