# OBJ-NEXT: Size: 4
# OBJ-NEXT: Binding: Global (0x1)
# OBJ-NEXT: Type: Object (0x1)
-# OBJ-NEXT: Other: 1
+# OBJ-NEXT: Other [ (0x1)
+# OBJ-NEXT: STV_INTERNAL
+# OBJ-NEXT: ]
# OBJ-NEXT: Section: .data (0x1)
# OBJ-NEXT: }
# OBJ-NEXT: Symbol {
# OBJ-NEXT: Size: 4
# OBJ-NEXT: Binding: Global (0x1)
# OBJ-NEXT: Type: Object (0x1)
-# OBJ-NEXT: Other: 2
+# OBJ-NEXT: Other [ (0x2)
+# OBJ-NEXT: STV_HIDDEN
+# OBJ-NEXT: ]
# OBJ-NEXT: Section: .data (0x1)
# OBJ-NEXT: }
# OBJ-NEXT: Symbol {
# OBJ-NEXT: Size: 4
# OBJ-NEXT: Binding: Global (0x1)
# OBJ-NEXT: Type: Object (0x1)
-# OBJ-NEXT: Other: 163
+# OBJ-NEXT: Other [ (0xA3)
+# OBJ-NEXT: STO_MIPS_MICROMIPS
+# OBJ-NEXT: STO_MIPS_PIC
+# OBJ-NEXT: STV_PROTECTED
+# OBJ-NEXT: ]
# OBJ-NEXT: Section: .data (0x1)
# OBJ-NEXT: }
--- /dev/null
+RUN: llvm-readobj -symbols %p/Inputs/st-other.obj.elf-mips \
+RUN: | FileCheck -check-prefix=MREG %s
+RUN: llvm-readobj -symbols %p/Inputs/st-other.obj.elf-mips16 \
+RUN: | FileCheck -check-prefix=M16 %s
+
+MREG: Name: foo
+MREG-NEXT: Value: 0x0
+MREG-NEXT: Size: 0
+MREG-NEXT: Binding: Global
+MREG-NEXT: Type: None
+MREG-NEXT: Other [ (0x29)
+MREG-NEXT: STO_MIPS_PIC (0x20)
+MREG-NEXT: STO_MIPS_PLT (0x8)
+MREG-NEXT: STV_INTERNAL (0x1)
+MREG-NEXT: ]
+
+M16: Name: foo
+M16-NEXT: Value: 0x0
+M16-NEXT: Size: 0
+M16-NEXT: Binding: Global
+M16-NEXT: Type: None
+M16-NEXT: Other [ (0xF1)
+M16-NEXT: STO_MIPS_MIPS16 (0xF0)
+M16-NEXT: STV_INTERNAL (0x1)
+M16-NEXT: ]
LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_64R6)
};
+static const EnumEntry<unsigned> ElfSymOtherFlags[] = {
+ LLVM_READOBJ_ENUM_ENT(ELF, STV_INTERNAL),
+ LLVM_READOBJ_ENUM_ENT(ELF, STV_HIDDEN),
+ LLVM_READOBJ_ENUM_ENT(ELF, STV_PROTECTED)
+};
+
+static const EnumEntry<unsigned> ElfMipsSymOtherFlags[] = {
+ LLVM_READOBJ_ENUM_ENT(ELF, STO_MIPS_OPTIONAL),
+ LLVM_READOBJ_ENUM_ENT(ELF, STO_MIPS_PLT),
+ LLVM_READOBJ_ENUM_ENT(ELF, STO_MIPS_PIC),
+ LLVM_READOBJ_ENUM_ENT(ELF, STO_MIPS_MICROMIPS)
+};
+
+static const EnumEntry<unsigned> ElfMips16SymOtherFlags[] = {
+ LLVM_READOBJ_ENUM_ENT(ELF, STO_MIPS_OPTIONAL),
+ LLVM_READOBJ_ENUM_ENT(ELF, STO_MIPS_PLT),
+ LLVM_READOBJ_ENUM_ENT(ELF, STO_MIPS_MIPS16)
+};
+
template <typename ELFT>
ELFDumper<ELFT>::ELFDumper(const ELFFile<ELFT> *Obj, StreamWriter &Writer)
: ObjDumper(Writer), Obj(Obj) {
W.printEnum("Type", SymbolType, makeArrayRef(AMDGPUSymbolTypes));
else
W.printEnum("Type", SymbolType, makeArrayRef(ElfSymbolTypes));
- W.printNumber("Other", Symbol->st_other);
+ if (Symbol->st_other == 0)
+ // Usually st_other flag is zero. Do not pollute the output
+ // by flags enumeration in that case.
+ W.printNumber("Other", 0);
+ else {
+ std::vector<EnumEntry<unsigned>> SymOtherFlags(std::begin(ElfSymOtherFlags),
+ std::end(ElfSymOtherFlags));
+ if (Obj->getHeader()->e_machine == EM_MIPS) {
+ // Someones in their infinite wisdom decided to make STO_MIPS_MIPS16
+ // flag overlapped with other ST_MIPS_xxx flags. So consider both
+ // cases separately.
+ if ((Symbol->st_other & STO_MIPS_MIPS16) == STO_MIPS_MIPS16)
+ SymOtherFlags.insert(SymOtherFlags.end(),
+ std::begin(ElfMips16SymOtherFlags),
+ std::end(ElfMips16SymOtherFlags));
+ else
+ SymOtherFlags.insert(SymOtherFlags.end(),
+ std::begin(ElfMipsSymOtherFlags),
+ std::end(ElfMipsSymOtherFlags));
+ }
+ W.printFlags("Other", Symbol->st_other, makeArrayRef(SymOtherFlags), 0x3u);
+ }
W.printHex("Section", SectionName, SectionIndex);
}