diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2023-04-14 21:41:27 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2023-06-22 18:20:56 +0000 |
| commit | bdd1243df58e60e85101c09001d9812a789b6bc4 (patch) | |
| tree | a1ce621c7301dd47ba2ddc3b8eaa63b441389481 /contrib/llvm-project/llvm/tools/llvm-readobj | |
| parent | 781624ca2d054430052c828ba8d2c2eaf2d733e7 (diff) | |
| parent | e3b557809604d036af6e00c60f012c2025b59a5e (diff) | |
Diffstat (limited to 'contrib/llvm-project/llvm/tools/llvm-readobj')
14 files changed, 847 insertions, 317 deletions
diff --git a/contrib/llvm-project/llvm/tools/llvm-readobj/ARMEHABIPrinter.h b/contrib/llvm-project/llvm/tools/llvm-readobj/ARMEHABIPrinter.h index d641b172eb91..5f3cc7dcbfd8 100644 --- a/contrib/llvm-project/llvm/tools/llvm-readobj/ARMEHABIPrinter.h +++ b/contrib/llvm-project/llvm/tools/llvm-readobj/ARMEHABIPrinter.h @@ -91,7 +91,7 @@ inline ArrayRef<OpcodeDecoder::RingEntry> OpcodeDecoder::ring() { {0xf8, 0xd0, &OpcodeDecoder::Decode_11010nnn}, {0xc0, 0xc0, &OpcodeDecoder::Decode_11xxxyyy}, }; - return makeArrayRef(Ring); + return ArrayRef(Ring); } inline void OpcodeDecoder::Decode_00xxxxxx(const uint8_t *Opcodes, @@ -341,8 +341,9 @@ class PrinterContext { return Location + Place; } - ErrorOr<StringRef> FunctionAtAddress(uint64_t Address, - Optional<unsigned> SectionIndex) const; + ErrorOr<StringRef> + FunctionAtAddress(uint64_t Address, + std::optional<unsigned> SectionIndex) const; const Elf_Shdr *FindExceptionTable(unsigned IndexTableIndex, off_t IndexTableOffset) const; @@ -363,9 +364,8 @@ template <typename ET> const size_t PrinterContext<ET>::IndexTableEntrySize = 8; template <typename ET> -ErrorOr<StringRef> -PrinterContext<ET>::FunctionAtAddress(uint64_t Address, - Optional<unsigned> SectionIndex) const { +ErrorOr<StringRef> PrinterContext<ET>::FunctionAtAddress( + uint64_t Address, std::optional<unsigned> SectionIndex) const { if (!Symtab) return inconvertibleErrorCode(); auto StrTableOrErr = ELF.getStringTableForSymtab(*Symtab); @@ -501,8 +501,8 @@ void PrinterContext<ET>::PrintExceptionTable(const Elf_Shdr &EHT, ? PREL31(Word, EHT.sh_addr) : PREL31(Word, EHT.sh_addr + TableEntryOffset); SW.printHex("PersonalityRoutineAddress", Address); - Optional<unsigned> SecIndex = - IsRelocatable ? Optional<unsigned>(EHT.sh_link) : None; + std::optional<unsigned> SecIndex = + IsRelocatable ? std::optional<unsigned>(EHT.sh_link) : std::nullopt; if (ErrorOr<StringRef> Name = FunctionAtAddress(Address, SecIndex)) SW.printString("PersonalityRoutineName", *Name); } @@ -574,8 +574,8 @@ void PrinterContext<ET>::PrintIndexTable(unsigned SectionIndex, // their code sections via the sh_link field. For a non-relocatable ELF file // the sh_link field is not reliable, because we have one .ARM.exidx section // normally, but might have many code sections. - Optional<unsigned> SecIndex = - IsRelocatable ? Optional<unsigned>(IT->sh_link) : None; + std::optional<unsigned> SecIndex = + IsRelocatable ? std::optional<unsigned>(IT->sh_link) : std::nullopt; if (ErrorOr<StringRef> Name = FunctionAtAddress(Address, SecIndex)) SW.printString("FunctionName", *Name); diff --git a/contrib/llvm-project/llvm/tools/llvm-readobj/ARMWinEHPrinter.cpp b/contrib/llvm-project/llvm/tools/llvm-readobj/ARMWinEHPrinter.cpp index b7cbf353c43f..ef77d4b2fd22 100644 --- a/contrib/llvm-project/llvm/tools/llvm-readobj/ARMWinEHPrinter.cpp +++ b/contrib/llvm-project/llvm/tools/llvm-readobj/ARMWinEHPrinter.cpp @@ -143,35 +143,36 @@ const Decoder::RingEntry Decoder::Ring[] = { { 0xff, 0xff, 1, &Decoder::opcode_11111111 }, // UOP_END }; - // Unwind opcodes for ARM64. // https://docs.microsoft.com/en-us/cpp/build/arm64-exception-handling const Decoder::RingEntry Decoder::Ring64[] = { - { 0xe0, 0x00, 1, &Decoder::opcode_alloc_s }, - { 0xe0, 0x20, 1, &Decoder::opcode_save_r19r20_x }, - { 0xc0, 0x40, 1, &Decoder::opcode_save_fplr }, - { 0xc0, 0x80, 1, &Decoder::opcode_save_fplr_x }, - { 0xf8, 0xc0, 2, &Decoder::opcode_alloc_m }, - { 0xfc, 0xc8, 2, &Decoder::opcode_save_regp }, - { 0xfc, 0xcc, 2, &Decoder::opcode_save_regp_x }, - { 0xfc, 0xd0, 2, &Decoder::opcode_save_reg }, - { 0xfe, 0xd4, 2, &Decoder::opcode_save_reg_x }, - { 0xfe, 0xd6, 2, &Decoder::opcode_save_lrpair }, - { 0xfe, 0xd8, 2, &Decoder::opcode_save_fregp }, - { 0xfe, 0xda, 2, &Decoder::opcode_save_fregp_x }, - { 0xfe, 0xdc, 2, &Decoder::opcode_save_freg }, - { 0xff, 0xde, 2, &Decoder::opcode_save_freg_x }, - { 0xff, 0xe0, 4, &Decoder::opcode_alloc_l }, - { 0xff, 0xe1, 1, &Decoder::opcode_setfp }, - { 0xff, 0xe2, 2, &Decoder::opcode_addfp }, - { 0xff, 0xe3, 1, &Decoder::opcode_nop }, - { 0xff, 0xe4, 1, &Decoder::opcode_end }, - { 0xff, 0xe5, 1, &Decoder::opcode_end_c }, - { 0xff, 0xe6, 1, &Decoder::opcode_save_next }, - { 0xff, 0xe8, 1, &Decoder::opcode_trap_frame }, - { 0xff, 0xe9, 1, &Decoder::opcode_machine_frame }, - { 0xff, 0xea, 1, &Decoder::opcode_context }, - { 0xff, 0xec, 1, &Decoder::opcode_clear_unwound_to_call }, + {0xe0, 0x00, 1, &Decoder::opcode_alloc_s}, + {0xe0, 0x20, 1, &Decoder::opcode_save_r19r20_x}, + {0xc0, 0x40, 1, &Decoder::opcode_save_fplr}, + {0xc0, 0x80, 1, &Decoder::opcode_save_fplr_x}, + {0xf8, 0xc0, 2, &Decoder::opcode_alloc_m}, + {0xfc, 0xc8, 2, &Decoder::opcode_save_regp}, + {0xfc, 0xcc, 2, &Decoder::opcode_save_regp_x}, + {0xfc, 0xd0, 2, &Decoder::opcode_save_reg}, + {0xfe, 0xd4, 2, &Decoder::opcode_save_reg_x}, + {0xfe, 0xd6, 2, &Decoder::opcode_save_lrpair}, + {0xfe, 0xd8, 2, &Decoder::opcode_save_fregp}, + {0xfe, 0xda, 2, &Decoder::opcode_save_fregp_x}, + {0xfe, 0xdc, 2, &Decoder::opcode_save_freg}, + {0xff, 0xde, 2, &Decoder::opcode_save_freg_x}, + {0xff, 0xe0, 4, &Decoder::opcode_alloc_l}, + {0xff, 0xe1, 1, &Decoder::opcode_setfp}, + {0xff, 0xe2, 2, &Decoder::opcode_addfp}, + {0xff, 0xe3, 1, &Decoder::opcode_nop}, + {0xff, 0xe4, 1, &Decoder::opcode_end}, + {0xff, 0xe5, 1, &Decoder::opcode_end_c}, + {0xff, 0xe6, 1, &Decoder::opcode_save_next}, + {0xff, 0xe7, 3, &Decoder::opcode_save_any_reg}, + {0xff, 0xe8, 1, &Decoder::opcode_trap_frame}, + {0xff, 0xe9, 1, &Decoder::opcode_machine_frame}, + {0xff, 0xea, 1, &Decoder::opcode_context}, + {0xff, 0xec, 1, &Decoder::opcode_clear_unwound_to_call}, + {0xff, 0xfc, 1, &Decoder::opcode_pac_sign_lr}, }; static void printRange(raw_ostream &OS, ListSeparator &LS, unsigned First, @@ -855,7 +856,7 @@ bool Decoder::opcode_end_c(const uint8_t *OC, unsigned &Offset, unsigned Length, bool Prologue) { SW.startLine() << format("0x%02x ; end_c\n", OC[Offset]); ++Offset; - return true; + return false; } bool Decoder::opcode_save_next(const uint8_t *OC, unsigned &Offset, @@ -869,6 +870,83 @@ bool Decoder::opcode_save_next(const uint8_t *OC, unsigned &Offset, return false; } +bool Decoder::opcode_save_any_reg(const uint8_t *OC, unsigned &Offset, + unsigned Length, bool Prologue) { + // Whether the instruction has writeback + bool Writeback = (OC[Offset + 1] & 0x20) == 0x20; + // Whether the instruction is paired. (Paired instructions are required + // to save/restore adjacent registers.) + bool Paired = (OC[Offset + 1] & 0x40) == 0x40; + // The kind of register saved: + // - 0 is an x register + // - 1 is the low half of a q register + // - 2 is a whole q register + int RegKind = (OC[Offset + 2] & 0xC0) >> 6; + // Encoded register name (0 -> x0/q0, 1 -> x1/q1, etc.) + int Reg = OC[Offset + 1] & 0x1F; + // Encoded stack offset of load/store instruction; decoding varies by mode. + int StackOffset = OC[Offset + 2] & 0x3F; + if (Writeback) + StackOffset++; + if (!Writeback && !Paired && RegKind != 2) + StackOffset *= 8; + else + StackOffset *= 16; + + SW.startLine() << format("0x%02x%02x%02x ; ", OC[Offset], + OC[Offset + 1], OC[Offset + 2]); + + // Verify the encoding is in a form we understand. The high bit of the first + // byte, and mode 3 for the register kind are apparently reserved. The + // encoded register must refer to a valid register. + int MaxReg = 0x1F; + if (Paired) + --MaxReg; + if (RegKind == 0) + --MaxReg; + if ((OC[Offset + 1] & 0x80) == 0x80 || RegKind == 3 || Reg > MaxReg) { + SW.getOStream() << "invalid save_any_reg encoding\n"; + Offset += 3; + return false; + } + + if (Paired) { + if (Prologue) + SW.getOStream() << "stp "; + else + SW.getOStream() << "ldp "; + } else { + if (Prologue) + SW.getOStream() << "str "; + else + SW.getOStream() << "ldr "; + } + + char RegChar = 'x'; + if (RegKind == 1) { + RegChar = 'd'; + } else if (RegKind == 2) { + RegChar = 'q'; + } + + if (Paired) + SW.getOStream() << format("%c%d, %c%d, ", RegChar, Reg, RegChar, Reg + 1); + else + SW.getOStream() << format("%c%d, ", RegChar, Reg); + + if (Writeback) { + if (Prologue) + SW.getOStream() << format("[sp, #-%d]!\n", StackOffset); + else + SW.getOStream() << format("[sp], #%d\n", StackOffset); + } else { + SW.getOStream() << format("[sp, #%d]\n", StackOffset); + } + + Offset += 3; + return false; +} + bool Decoder::opcode_trap_frame(const uint8_t *OC, unsigned &Offset, unsigned Length, bool Prologue) { SW.startLine() << format("0x%02x ; trap frame\n", OC[Offset]); @@ -899,6 +977,16 @@ bool Decoder::opcode_clear_unwound_to_call(const uint8_t *OC, unsigned &Offset, return false; } +bool Decoder::opcode_pac_sign_lr(const uint8_t *OC, unsigned &Offset, + unsigned Length, bool Prologue) { + if (Prologue) + SW.startLine() << format("0x%02x ; pacibsp\n", OC[Offset]); + else + SW.startLine() << format("0x%02x ; autibsp\n", OC[Offset]); + ++Offset; + return false; +} + void Decoder::decodeOpcodes(ArrayRef<uint8_t> Opcodes, unsigned Offset, bool Prologue) { assert((!Prologue || Offset == 0) && "prologue should always use offset 0"); @@ -906,8 +994,8 @@ void Decoder::decodeOpcodes(ArrayRef<uint8_t> Opcodes, unsigned Offset, bool Terminated = false; for (unsigned OI = Offset, OE = Opcodes.size(); !Terminated && OI < OE; ) { for (unsigned DI = 0;; ++DI) { - if ((isAArch64 && (DI >= array_lengthof(Ring64))) || - (!isAArch64 && (DI >= array_lengthof(Ring)))) { + if ((isAArch64 && (DI >= std::size(Ring64))) || + (!isAArch64 && (DI >= std::size(Ring)))) { SW.startLine() << format("0x%02x ; Bad opcode!\n", Opcodes.data()[OI]); ++OI; @@ -1160,7 +1248,7 @@ bool Decoder::dumpPackedEntry(const object::COFFObjectFile &COFF, } if (RF.C()) { // Count the number of registers pushed below R11 - int FpOffset = 4 * countPopulation(GPRMask & ((1U << 11) - 1)); + int FpOffset = 4 * llvm::popcount(GPRMask & ((1U << 11) - 1)); if (FpOffset) SW.startLine() << "add.w r11, sp, #" << FpOffset << "\n"; else @@ -1256,7 +1344,7 @@ bool Decoder::dumpPackedARM64Entry(const object::COFFObjectFile &COFF, int SavSZ = (IntSZ + FpSZ + 8 * 8 * RF.H() + 0xf) & ~0xf; int LocSZ = (RF.FrameSize() << 4) - SavSZ; - if (RF.CR() == 3) { + if (RF.CR() == 2 || RF.CR() == 3) { SW.startLine() << "mov x29, sp\n"; if (LocSZ <= 512) { SW.startLine() << format("stp x29, lr, [sp, #-%d]!\n", LocSZ); @@ -1267,7 +1355,7 @@ bool Decoder::dumpPackedARM64Entry(const object::COFFObjectFile &COFF, if (LocSZ > 4080) { SW.startLine() << format("sub sp, sp, #%d\n", LocSZ - 4080); SW.startLine() << "sub sp, sp, #4080\n"; - } else if ((RF.CR() != 3 && LocSZ > 0) || LocSZ > 512) { + } else if ((RF.CR() != 3 && RF.CR() != 2 && LocSZ > 0) || LocSZ > 512) { SW.startLine() << format("sub sp, sp, #%d\n", LocSZ); } if (RF.H()) { @@ -1329,6 +1417,11 @@ bool Decoder::dumpPackedARM64Entry(const object::COFFObjectFile &COFF, 19 + 2 * I + 1, 16 * I); } } + // CR=2 is yet undocumented, see + // https://github.com/MicrosoftDocs/cpp-docs/pull/4202 for upstream + // progress on getting it documented. + if (RF.CR() == 2) + SW.startLine() << "pacibsp\n"; SW.startLine() << "end\n"; return true; diff --git a/contrib/llvm-project/llvm/tools/llvm-readobj/ARMWinEHPrinter.h b/contrib/llvm-project/llvm/tools/llvm-readobj/ARMWinEHPrinter.h index ceaa866ff215..0ffebe5834c4 100644 --- a/contrib/llvm-project/llvm/tools/llvm-readobj/ARMWinEHPrinter.h +++ b/contrib/llvm-project/llvm/tools/llvm-readobj/ARMWinEHPrinter.h @@ -121,6 +121,8 @@ class Decoder { bool Prologue); bool opcode_save_next(const uint8_t *Opcodes, unsigned &Offset, unsigned Length, bool Prologue); + bool opcode_save_any_reg(const uint8_t *Opcodes, unsigned &Offset, + unsigned Length, bool Prologue); bool opcode_trap_frame(const uint8_t *Opcodes, unsigned &Offset, unsigned Length, bool Prologue); bool opcode_machine_frame(const uint8_t *Opcodes, unsigned &Offset, @@ -129,6 +131,8 @@ class Decoder { bool Prologue); bool opcode_clear_unwound_to_call(const uint8_t *Opcodes, unsigned &Offset, unsigned Length, bool Prologue); + bool opcode_pac_sign_lr(const uint8_t *Opcodes, unsigned &Offset, + unsigned Length, bool Prologue); void decodeOpcodes(ArrayRef<uint8_t> Opcodes, unsigned Offset, bool Prologue); diff --git a/contrib/llvm-project/llvm/tools/llvm-readobj/COFFDumper.cpp b/contrib/llvm-project/llvm/tools/llvm-readobj/COFFDumper.cpp index caeb49af24be..5279e5853cc5 100644 --- a/contrib/llvm-project/llvm/tools/llvm-readobj/COFFDumper.cpp +++ b/contrib/llvm-project/llvm/tools/llvm-readobj/COFFDumper.cpp @@ -193,7 +193,6 @@ private: CPUType CompilationCPUType = CPUType::X64; ScopedPrinter &Writer; - BinaryByteStream TypeContents; LazyRandomTypeCollection Types; }; @@ -344,6 +343,7 @@ const EnumEntry<COFF::MachineTypes> ImageFileMachineType[] = { LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_AMD64 ), LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_ARM ), LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_ARM64 ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_ARM64EC ), LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_ARMNT ), LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_EBC ), LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_I386 ), @@ -578,6 +578,52 @@ const EnumEntry<uint8_t> FileChecksumKindNames[] = { LLVM_READOBJ_ENUM_CLASS_ENT(FileChecksumKind, SHA256), }; +const EnumEntry<uint32_t> PELoadConfigGuardFlags[] = { + LLVM_READOBJ_ENUM_CLASS_ENT(COFF::GuardFlags, CF_INSTRUMENTED), + LLVM_READOBJ_ENUM_CLASS_ENT(COFF::GuardFlags, CFW_INSTRUMENTED), + LLVM_READOBJ_ENUM_CLASS_ENT(COFF::GuardFlags, CF_FUNCTION_TABLE_PRESENT), + LLVM_READOBJ_ENUM_CLASS_ENT(COFF::GuardFlags, SECURITY_COOKIE_UNUSED), + LLVM_READOBJ_ENUM_CLASS_ENT(COFF::GuardFlags, PROTECT_DELAYLOAD_IAT), + LLVM_READOBJ_ENUM_CLASS_ENT(COFF::GuardFlags, + DELAYLOAD_IAT_IN_ITS_OWN_SECTION), + LLVM_READOBJ_ENUM_CLASS_ENT(COFF::GuardFlags, + CF_EXPORT_SUPPRESSION_INFO_PRESENT), + LLVM_READOBJ_ENUM_CLASS_ENT(COFF::GuardFlags, CF_ENABLE_EXPORT_SUPPRESSION), + LLVM_READOBJ_ENUM_CLASS_ENT(COFF::GuardFlags, CF_LONGJUMP_TABLE_PRESENT), + LLVM_READOBJ_ENUM_CLASS_ENT(COFF::GuardFlags, + EH_CONTINUATION_TABLE_PRESENT), + LLVM_READOBJ_ENUM_CLASS_ENT(COFF::GuardFlags, + CF_FUNCTION_TABLE_SIZE_5BYTES), + LLVM_READOBJ_ENUM_CLASS_ENT(COFF::GuardFlags, + CF_FUNCTION_TABLE_SIZE_6BYTES), + LLVM_READOBJ_ENUM_CLASS_ENT(COFF::GuardFlags, + CF_FUNCTION_TABLE_SIZE_7BYTES), + LLVM_READOBJ_ENUM_CLASS_ENT(COFF::GuardFlags, + CF_FUNCTION_TABLE_SIZE_8BYTES), + LLVM_READOBJ_ENUM_CLASS_ENT(COFF::GuardFlags, + CF_FUNCTION_TABLE_SIZE_9BYTES), + LLVM_READOBJ_ENUM_CLASS_ENT(COFF::GuardFlags, + CF_FUNCTION_TABLE_SIZE_10BYTES), + LLVM_READOBJ_ENUM_CLASS_ENT(COFF::GuardFlags, + CF_FUNCTION_TABLE_SIZE_11BYTES), + LLVM_READOBJ_ENUM_CLASS_ENT(COFF::GuardFlags, + CF_FUNCTION_TABLE_SIZE_12BYTES), + LLVM_READOBJ_ENUM_CLASS_ENT(COFF::GuardFlags, + CF_FUNCTION_TABLE_SIZE_13BYTES), + LLVM_READOBJ_ENUM_CLASS_ENT(COFF::GuardFlags, + CF_FUNCTION_TABLE_SIZE_14BYTES), + LLVM_READOBJ_ENUM_CLASS_ENT(COFF::GuardFlags, + CF_FUNCTION_TABLE_SIZE_15BYTES), + LLVM_READOBJ_ENUM_CLASS_ENT(COFF::GuardFlags, + CF_FUNCTION_TABLE_SIZE_16BYTES), + LLVM_READOBJ_ENUM_CLASS_ENT(COFF::GuardFlags, + CF_FUNCTION_TABLE_SIZE_17BYTES), + LLVM_READOBJ_ENUM_CLASS_ENT(COFF::GuardFlags, + CF_FUNCTION_TABLE_SIZE_18BYTES), + LLVM_READOBJ_ENUM_CLASS_ENT(COFF::GuardFlags, + CF_FUNCTION_TABLE_SIZE_19BYTES), +}; + template <typename T> static std::error_code getSymbolAuxData(const COFFObjectFile *Obj, COFFSymbolRef Symbol, @@ -621,16 +667,15 @@ void COFFDumper::printFileHeaders() { { DictScope D(W, "ImageFileHeader"); - W.printEnum ("Machine", Obj->getMachine(), - makeArrayRef(ImageFileMachineType)); + W.printEnum("Machine", Obj->getMachine(), ArrayRef(ImageFileMachineType)); W.printNumber("SectionCount", Obj->getNumberOfSections()); W.printHex ("TimeDateStamp", FormattedTime, Obj->getTimeDateStamp()); W.printHex ("PointerToSymbolTable", Obj->getPointerToSymbolTable()); W.printNumber("SymbolCount", Obj->getNumberOfSymbols()); W.printNumber("StringTableSize", Obj->getStringTableSize()); W.printNumber("OptionalHeaderSize", Obj->getSizeOfOptionalHeader()); - W.printFlags ("Characteristics", Obj->getCharacteristics(), - makeArrayRef(ImageFileCharacteristics)); + W.printFlags("Characteristics", Obj->getCharacteristics(), + ArrayRef(ImageFileCharacteristics)); } // Print PE header. This header does not exist if this is an object file and @@ -691,9 +736,10 @@ void COFFDumper::printPEHeader(const PEHeader *Hdr) { W.printNumber("MinorSubsystemVersion", Hdr->MinorSubsystemVersion); W.printNumber("SizeOfImage", Hdr->SizeOfImage); W.printNumber("SizeOfHeaders", Hdr->SizeOfHeaders); - W.printEnum ("Subsystem", Hdr->Subsystem, makeArrayRef(PEWindowsSubsystem)); - W.printFlags ("Characteristics", Hdr->DLLCharacteristics, - makeArrayRef(PEDLLCharacteristics)); + W.printHex ("CheckSum", Hdr->CheckSum); + W.printEnum("Subsystem", Hdr->Subsystem, ArrayRef(PEWindowsSubsystem)); + W.printFlags("Characteristics", Hdr->DLLCharacteristics, + ArrayRef(PEDLLCharacteristics)); W.printNumber("SizeOfStackReserve", Hdr->SizeOfStackReserve); W.printNumber("SizeOfStackCommit", Hdr->SizeOfStackCommit); W.printNumber("SizeOfHeapReserve", Hdr->SizeOfHeapReserve); @@ -710,7 +756,7 @@ void COFFDumper::printPEHeader(const PEHeader *Hdr) { }; for (uint32_t i = 0; i < Hdr->NumberOfRvaAndSize; ++i) - if (i < sizeof(directory) / sizeof(char *)) + if (i < std::size(directory)) printDataDirectory(i, directory[i]); else printDataDirectory(i, "Unknown"); @@ -728,7 +774,7 @@ void COFFDumper::printCOFFDebugDirectory() { W.printHex("TimeDateStamp", FormattedTime, D.TimeDateStamp); W.printHex("MajorVersion", D.MajorVersion); W.printHex("MinorVersion", D.MinorVersion); - W.printEnum("Type", D.Type, makeArrayRef(ImageDebugType)); + W.printEnum("Type", D.Type, ArrayRef(ImageDebugType)); W.printHex("SizeOfData", D.SizeOfData); W.printHex("AddressOfRawData", D.AddressOfRawData); W.printHex("PointerToRawData", D.PointerToRawData); @@ -745,7 +791,7 @@ void COFFDumper::printCOFFDebugDirectory() { DictScope PDBScope(W, "PDBInfo"); W.printHex("PDBSignature", DebugInfo->Signature.CVSignature); if (DebugInfo->Signature.CVSignature == OMF::Signature::PDB70) { - W.printBinary("PDBGUID", makeArrayRef(DebugInfo->PDB70.Signature)); + W.printBinary("PDBGUID", ArrayRef(DebugInfo->PDB70.Signature)); W.printNumber("PDBAge", DebugInfo->PDB70.Age); W.printString("PDBFileName", PDBFileName); } @@ -761,7 +807,7 @@ void COFFDumper::printCOFFDebugDirectory() { // but that might change in the future uint16_t Characteristics = RawData[0]; W.printFlags("ExtendedCharacteristics", Characteristics, - makeArrayRef(PEExtendedDLLCharacteristics)); + ArrayRef(PEExtendedDLLCharacteristics)); } W.printBinaryBlock("RawData", RawData); } @@ -807,11 +853,18 @@ void COFFDumper::printCOFFLoadConfig() { if (Tables.GuardFidTableVA) { ListScope LS(W, "GuardFidTable"); - if (Tables.GuardFlags & uint32_t(coff_guard_flags::FidTableHasFlags)) - printRVATable(Tables.GuardFidTableVA, Tables.GuardFidTableCount, 5, + if (uint32_t Size = + Tables.GuardFlags & + uint32_t(COFF::GuardFlags::CF_FUNCTION_TABLE_SIZE_MASK)) { + // The size mask gives the number of extra bytes in addition to the 4-byte + // RVA of each entry in the table. As of writing only a 1-byte extra flag + // has been defined. + Size = (Size >> 28) + 4; + printRVATable(Tables.GuardFidTableVA, Tables.GuardFidTableCount, Size, PrintGuardFlags); - else + } else { printRVATable(Tables.GuardFidTableVA, Tables.GuardFidTableCount, 4); + } } if (Tables.GuardIatTableVA) { @@ -881,7 +934,8 @@ void COFFDumper::printCOFFLoadConfig(const T *Conf, LoadConfigTables &Tables) { W.printHex("GuardCFCheckDispatch", Conf->GuardCFCheckDispatch); W.printHex("GuardCFFunctionTable", Conf->GuardCFFunctionTable); W.printNumber("GuardCFFunctionCount", Conf->GuardCFFunctionCount); - W.printHex("GuardFlags", Conf->GuardFlags); + W.printFlags("GuardFlags", Conf->GuardFlags, ArrayRef(PELoadConfigGuardFlags), + (uint32_t)COFF::GuardFlags::CF_FUNCTION_TABLE_SIZE_MASK); Tables.GuardFidTableVA = Conf->GuardCFFunctionTable; Tables.GuardFidTableCount = Conf->GuardCFFunctionCount; @@ -1026,7 +1080,7 @@ void COFFDumper::printCodeViewSymbolSection(StringRef SectionName, W.printHex("IgnoredSubsectionKind", SubType); SubType &= ~SubsectionIgnoreFlag; } - W.printEnum("SubSectionType", SubType, makeArrayRef(SubSectionTypes)); + W.printEnum("SubSectionType", SubType, ArrayRef(SubSectionTypes)); W.printHex("SubSectionSize", SubSectionSize); // Get the contents of the subsection. @@ -1123,7 +1177,7 @@ void COFFDumper::printCodeViewSymbolSection(StringRef SectionName, W.printHex("MaxStackSize", FD.MaxStackSize); W.printHex("PrologSize", FD.PrologSize); W.printHex("SavedRegsSize", FD.SavedRegsSize); - W.printFlags("Flags", FD.Flags, makeArrayRef(FrameDataFlags)); + W.printFlags("Flags", FD.Flags, ArrayRef(FrameDataFlags)); // The FrameFunc string is a small RPN program. It can be broken up into // statements that end in the '=' operator, which assigns the value on @@ -1241,7 +1295,7 @@ void COFFDumper::printCodeViewFileChecksums(StringRef Subsection) { W.printHex("Filename", Filename, FC.FileNameOffset); W.printHex("ChecksumSize", FC.Checksum.size()); W.printEnum("ChecksumKind", uint8_t(FC.Kind), - makeArrayRef(FileChecksumKindNames)); + ArrayRef(FileChecksumKindNames)); W.printBinary("ChecksumBytes", FC.Checksum); } @@ -1316,17 +1370,17 @@ void COFFDumper::mergeCodeViewTypes(MergingTypeTableBuilder &CVIDs, Obj->getFileName()); } SmallVector<TypeIndex, 128> SourceToDest; - Optional<uint32_t> PCHSignature; + std::optional<PCHMergerInfo> PCHInfo; if (GHash) { std::vector<GloballyHashedType> Hashes = GloballyHashedType::hashTypes(Types); if (Error E = mergeTypeAndIdRecords(GlobalCVIDs, GlobalCVTypes, SourceToDest, - Types, Hashes, PCHSignature)) + Types, Hashes, PCHInfo)) return reportError(std::move(E), Obj->getFileName()); } else { if (Error E = mergeTypeAndIdRecords(CVIDs, CVTypes, SourceToDest, Types, - PCHSignature)) + PCHInfo)) return reportError(std::move(E), Obj->getFileName()); } } @@ -1380,9 +1434,9 @@ void COFFDumper::printSectionHeaders() { W.printHex ("PointerToLineNumbers", Section->PointerToLinenumbers); W.printNumber("RelocationCount", Section->NumberOfRelocations); W.printNumber("LineNumberCount", Section->NumberOfLinenumbers); - W.printFlags ("Characteristics", Section->Characteristics, - makeArrayRef(ImageSectionCharacteristics), - COFF::SectionCharacteristics(0x00F00000)); + W.printFlags("Characteristics", Section->Characteristics, + ArrayRef(ImageSectionCharacteristics), + COFF::SectionCharacteristics(0x00F00000)); if (opts::SectionRelocations) { ListScope D(W, "Relocations"); @@ -1518,11 +1572,10 @@ void COFFDumper::printSymbol(const SymbolRef &Sym) { W.printString("Name", SymbolName); W.printNumber("Value", Symbol.getValue()); W.printNumber("Section", SectionName, Symbol.getSectionNumber()); - W.printEnum ("BaseType", Symbol.getBaseType(), makeArrayRef(ImageSymType)); - W.printEnum ("ComplexType", Symbol.getComplexType(), - makeArrayRef(ImageSymDType)); - W.printEnum ("StorageClass", Symbol.getStorageClass(), - makeArrayRef(ImageSymClass)); + W.printEnum("BaseType", Symbol.getBaseType(), ArrayRef(ImageSymType)); + W.printEnum("ComplexType", Symbol.getComplexType(), ArrayRef(ImageSymDType)); + W.printEnum("StorageClass", Symbol.getStorageClass(), + ArrayRef(ImageSymClass)); W.printNumber("AuxSymbolCount", Symbol.getNumberOfAuxSymbols()); for (uint8_t I = 0; I < Symbol.getNumberOfAuxSymbols(); ++I) { @@ -1544,8 +1597,8 @@ void COFFDumper::printSymbol(const SymbolRef &Sym) { DictScope AS(W, "AuxWeakExternal"); W.printNumber("Linked", getSymbolName(Aux->TagIndex), Aux->TagIndex); - W.printEnum ("Search", Aux->Characteristics, - makeArrayRef(WeakExternalCharacteristics)); + W.printEnum("Search", Aux->Characteristics, + ArrayRef(WeakExternalCharacteristics)); } else if (Symbol.isFileRecord()) { const char *FileName; @@ -1570,7 +1623,7 @@ void COFFDumper::printSymbol(const SymbolRef &Sym) { W.printNumber("LineNumberCount", Aux->NumberOfLinenumbers); W.printHex("Checksum", Aux->CheckSum); W.printNumber("Number", AuxNumber); - W.printEnum("Selection", Aux->Selection, makeArrayRef(ImageCOMDATSelect)); + W.printEnum("Selection", Aux->Selection, ArrayRef(ImageCOMDATSelect)); if (Section && Section->Characteristics & COFF::IMAGE_SCN_LNK_COMDAT && Aux->Selection == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) { @@ -1616,16 +1669,17 @@ void COFFDumper::printUnwindInfo() { break; } case COFF::IMAGE_FILE_MACHINE_ARM64: + case COFF::IMAGE_FILE_MACHINE_ARM64EC: case COFF::IMAGE_FILE_MACHINE_ARMNT: { - ARM::WinEH::Decoder Decoder(W, Obj->getMachine() == - COFF::IMAGE_FILE_MACHINE_ARM64); + ARM::WinEH::Decoder Decoder(W, Obj->getMachine() != + COFF::IMAGE_FILE_MACHINE_ARMNT); // TODO Propagate the error. consumeError(Decoder.dumpProcedureData(*Obj)); break; } default: W.printEnum("unsupported Image Machine", Obj->getMachine(), - makeArrayRef(ImageFileMachineType)); + ArrayRef(ImageFileMachineType)); break; } } @@ -1733,18 +1787,29 @@ void COFFDumper::printCOFFExports() { DictScope Export(W, "Export"); StringRef Name; - uint32_t Ordinal, RVA; + uint32_t Ordinal; + bool IsForwarder; if (Error E = Exp.getSymbolName(Name)) reportError(std::move(E), Obj->getFileName()); if (Error E = Exp.getOrdinal(Ordinal)) reportError(std::move(E), Obj->getFileName()); - if (Error E = Exp.getExportRVA(RVA)) + if (Error E = Exp.isForwarder(IsForwarder)) reportError(std::move(E), Obj->getFileName()); W.printNumber("Ordinal", Ordinal); W.printString("Name", Name); - W.printHex("RVA", RVA); + StringRef ForwardTo; + if (IsForwarder) { + if (Error E = Exp.getForwardTo(ForwardTo)) + reportError(std::move(E), Obj->getFileName()); + W.printString("ForwardedTo", ForwardTo); + } else { + uint32_t RVA; + if (Error E = Exp.getExportRVA(RVA)) + reportError(std::move(E), Obj->getFileName()); + W.printHex("RVA", RVA); + } } } @@ -1862,7 +1927,7 @@ void COFFDumper::printResourceDirectoryTable( std::copy(RawEntryNameString.begin(), RawEntryNameString.end(), EndianCorrectedNameString.begin() + 1); EndianCorrectedNameString[0] = UNI_UTF16_BYTE_ORDER_MARK_SWAPPED; - RawEntryNameString = makeArrayRef(EndianCorrectedNameString); + RawEntryNameString = ArrayRef(EndianCorrectedNameString); } std::string EntryNameString; if (!llvm::convertUTF16ToUTF8String(RawEntryNameString, EntryNameString)) @@ -2074,6 +2139,6 @@ void COFFDumper::printCOFFTLSDirectory( W.printHex("AddressOfCallBacks", TlsTable->AddressOfCallBacks); W.printHex("SizeOfZeroFill", TlsTable->SizeOfZeroFill); W.printFlags("Characteristics", TlsTable->Characteristics, - makeArrayRef(ImageSectionCharacteristics), + ArrayRef(ImageSectionCharacteristics), COFF::SectionCharacteristics(COFF::IMAGE_SCN_ALIGN_MASK)); } diff --git a/contrib/llvm-project/llvm/tools/llvm-readobj/DwarfCFIEHPrinter.h b/contrib/llvm-project/llvm/tools/llvm-readobj/DwarfCFIEHPrinter.h index 5dc947e024b9..365a5985e48d 100644 --- a/contrib/llvm-project/llvm/tools/llvm-readobj/DwarfCFIEHPrinter.h +++ b/contrib/llvm-project/llvm/tools/llvm-readobj/DwarfCFIEHPrinter.h @@ -226,8 +226,9 @@ void PrinterContext<ELFT>::printEHFrame(const Elf_Shdr *EHFrameShdr) const { W.getOStream() << "\n"; W.startLine() << "Program:\n"; W.indent(); - Entry.cfis().dump(W.getOStream(), DIDumpOptions(), nullptr, - W.getIndentLevel()); + auto DumpOpts = DIDumpOptions(); + DumpOpts.IsEH = true; + Entry.cfis().dump(W.getOStream(), DumpOpts, W.getIndentLevel()); W.unindent(); W.unindent(); W.getOStream() << "\n"; diff --git a/contrib/llvm-project/llvm/tools/llvm-readobj/ELFDumper.cpp b/contrib/llvm-project/llvm/tools/llvm-readobj/ELFDumper.cpp index ba7bae96ade3..45fff0cc4a76 100644 --- a/contrib/llvm-project/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/contrib/llvm-project/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -21,7 +21,6 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/MapVector.h" -#include "llvm/ADT/Optional.h" #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallString.h" @@ -67,6 +66,7 @@ #include <cstdlib> #include <iterator> #include <memory> +#include <optional> #include <string> #include <system_error> #include <vector> @@ -201,7 +201,7 @@ public: uint32_t Symbol; typename ELFT::uint Offset; typename ELFT::uint Info; - Optional<int64_t> Addend; + std::optional<int64_t> Addend; }; template <class ELFT> class MipsGOTParser; @@ -289,7 +289,7 @@ protected: bool NonVisibilityBitsUsed) const {}; virtual void printSymbol(const Elf_Sym &Symbol, unsigned SymIndex, DataRegion<Elf_Word> ShndxTable, - Optional<StringRef> StrTable, bool IsDynamic, + std::optional<StringRef> StrTable, bool IsDynamic, bool NonVisibilityBitsUsed) const = 0; virtual void printMipsABIFlags() = 0; @@ -305,13 +305,12 @@ protected: // Returns the function symbol index for the given address. Matches the // symbol's section with FunctionSec when specified. - // Returns None if no function symbol can be found for the address or in case - // it is not defined in the specified section. - SmallVector<uint32_t> - getSymbolIndexesForFunctionAddress(uint64_t SymValue, - Optional<const Elf_Shdr *> FunctionSec); + // Returns std::nullopt if no function symbol can be found for the address or + // in case it is not defined in the specified section. + SmallVector<uint32_t> getSymbolIndexesForFunctionAddress( + uint64_t SymValue, std::optional<const Elf_Shdr *> FunctionSec); bool printFunctionStackSize(uint64_t SymValue, - Optional<const Elf_Shdr *> FunctionSec, + std::optional<const Elf_Shdr *> FunctionSec, const Elf_Shdr &StackSizeSec, DataExtractor Data, uint64_t *Offset); void printStackSize(const Relocation<ELFT> &R, const Elf_Shdr &RelocSec, @@ -355,13 +354,13 @@ protected: Expected<StringRef> getSymbolVersion(const Elf_Sym &Sym, bool &IsDefault) const; - Expected<SmallVector<Optional<VersionEntry>, 0> *> getVersionMap() const; + Expected<SmallVector<std::optional<VersionEntry>, 0> *> getVersionMap() const; DynRegionInfo DynRelRegion; DynRegionInfo DynRelaRegion; DynRegionInfo DynRelrRegion; DynRegionInfo DynPLTRelRegion; - Optional<DynRegionInfo> DynSymRegion; + std::optional<DynRegionInfo> DynSymRegion; DynRegionInfo DynSymTabShndxRegion; DynRegionInfo DynamicTable; StringRef DynamicStringTable; @@ -371,8 +370,8 @@ protected: const Elf_Shdr *DotDynsymSec = nullptr; const Elf_Shdr *DotAddrsigSec = nullptr; DenseMap<const Elf_Shdr *, ArrayRef<Elf_Word>> ShndxTables; - Optional<uint64_t> SONameOffset; - Optional<DenseMap<uint64_t, std::vector<uint32_t>>> AddressToIndexMap; + std::optional<uint64_t> SONameOffset; + std::optional<DenseMap<uint64_t, std::vector<uint32_t>>> AddressToIndexMap; const Elf_Shdr *SymbolVersionSection = nullptr; // .gnu.version const Elf_Shdr *SymbolVersionNeedSection = nullptr; // .gnu.version_r @@ -380,7 +379,7 @@ protected: std::string getFullSymbolName(const Elf_Sym &Symbol, unsigned SymIndex, DataRegion<Elf_Word> ShndxTable, - Optional<StringRef> StrTable, + std::optional<StringRef> StrTable, bool IsDynamic) const; Expected<unsigned> getSymbolSectionIndex(const Elf_Sym &Symbol, unsigned SymIndex, @@ -399,7 +398,7 @@ protected: ArrayRef<Elf_Word> getShndxTable(const Elf_Shdr *Symtab) const; private: - mutable SmallVector<Optional<VersionEntry>, 0> VersionMap; + mutable SmallVector<std::optional<VersionEntry>, 0> VersionMap; }; template <class ELFT> @@ -493,7 +492,7 @@ ELFDumper<ELFT>::getVersionTable(const Elf_Shdr &Sec, ArrayRef<Elf_Sym> *SymTab, template <class ELFT> void ELFDumper<ELFT>::printSymbolsHelper(bool IsDynamic) const { - Optional<StringRef> StrTable; + std::optional<StringRef> StrTable; size_t Entries = 0; Elf_Sym_Range Syms(nullptr, nullptr); const Elf_Shdr *SymtabSec = IsDynamic ? DotDynsymSec : DotSymtabSec; @@ -635,7 +634,7 @@ private: const RelSymbol<ELFT> &RelSym) override; void printSymbol(const Elf_Sym &Symbol, unsigned SymIndex, DataRegion<Elf_Word> ShndxTable, - Optional<StringRef> StrTable, bool IsDynamic, + std::optional<StringRef> StrTable, bool IsDynamic, bool NonVisibilityBitsUsed) const override; void printDynamicRelocHeader(unsigned Type, StringRef Name, const DynRegionInfo &Reg) override; @@ -692,7 +691,7 @@ private: DataRegion<Elf_Word> ShndxTable) const; void printSymbol(const Elf_Sym &Symbol, unsigned SymIndex, DataRegion<Elf_Word> ShndxTable, - Optional<StringRef> StrTable, bool IsDynamic, + std::optional<StringRef> StrTable, bool IsDynamic, bool /*NonVisibilityBitsUsed*/) const override; void printProgramHeaders() override; void printSectionMapping() override {} @@ -759,14 +758,14 @@ std::unique_ptr<ObjDumper> createELFDumper(const object::ELFObjectFileBase &Obj, } // end namespace llvm template <class ELFT> -Expected<SmallVector<Optional<VersionEntry>, 0> *> +Expected<SmallVector<std::optional<VersionEntry>, 0> *> ELFDumper<ELFT>::getVersionMap() const { // If the VersionMap has already been loaded or if there is no dynamic symtab // or version table, there is nothing to do. if (!VersionMap.empty() || !DynSymRegion || !SymbolVersionSection) return &VersionMap; - Expected<SmallVector<Optional<VersionEntry>, 0>> MapOrErr = + Expected<SmallVector<std::optional<VersionEntry>, 0>> MapOrErr = Obj.loadVersionMap(SymbolVersionNeedSection, SymbolVersionDefSection); if (MapOrErr) VersionMap = *MapOrErr; @@ -804,7 +803,7 @@ Expected<StringRef> ELFDumper<ELFT>::getSymbolVersion(const Elf_Sym &Sym, return ""; } - Expected<SmallVector<Optional<VersionEntry>, 0> *> MapOrErr = + Expected<SmallVector<std::optional<VersionEntry>, 0> *> MapOrErr = getVersionMap(); if (!MapOrErr) return MapOrErr.takeError(); @@ -881,11 +880,9 @@ std::string ELFDumper<ELFT>::getStaticSymbolName(uint32_t Index) const { } template <typename ELFT> -std::string ELFDumper<ELFT>::getFullSymbolName(const Elf_Sym &Symbol, - unsigned SymIndex, - DataRegion<Elf_Word> ShndxTable, - Optional<StringRef> StrTable, - bool IsDynamic) const { +std::string ELFDumper<ELFT>::getFullSymbolName( + const Elf_Sym &Symbol, unsigned SymIndex, DataRegion<Elf_Word> ShndxTable, + std::optional<StringRef> StrTable, bool IsDynamic) const { if (!StrTable) return "<?>"; @@ -940,7 +937,8 @@ ELFDumper<ELFT>::getSymbolSectionIndex(const Elf_Sym &Symbol, unsigned SymIndex, if (Ndx != SHN_UNDEF && Ndx < SHN_LORESERVE) return Ndx; - auto CreateErr = [&](const Twine &Name, Optional<unsigned> Offset = None) { + auto CreateErr = [&](const Twine &Name, + std::optional<unsigned> Offset = std::nullopt) { std::string Desc; if (Offset) Desc = (Name + "+0x" + Twine::utohexstr(*Offset)).str(); @@ -1411,6 +1409,7 @@ static StringRef segmentTypeToString(unsigned Arch, unsigned Type) { LLVM_READOBJ_ENUM_CASE(ELF, PT_GNU_RELRO); LLVM_READOBJ_ENUM_CASE(ELF, PT_GNU_PROPERTY); + LLVM_READOBJ_ENUM_CASE(ELF, PT_OPENBSD_MUTABLE); LLVM_READOBJ_ENUM_CASE(ELF, PT_OPENBSD_RANDOMIZE); LLVM_READOBJ_ENUM_CASE(ELF, PT_OPENBSD_WXNEEDED); LLVM_READOBJ_ENUM_CASE(ELF, PT_OPENBSD_BOOTDATA); @@ -1649,14 +1648,18 @@ const EnumEntry<unsigned> ElfHeaderAVRFlags[] = { }; const EnumEntry<unsigned> ElfHeaderLoongArchFlags[] = { - ENUM_ENT(EF_LOONGARCH_BASE_ABI_ILP32S, "ILP32, SOFT-FLOAT"), - ENUM_ENT(EF_LOONGARCH_BASE_ABI_ILP32F, "ILP32, SINGLE-FLOAT"), - ENUM_ENT(EF_LOONGARCH_BASE_ABI_ILP32D, "ILP32, DOUBLE-FLOAT"), - ENUM_ENT(EF_LOONGARCH_BASE_ABI_LP64S, "LP64, SOFT-FLOAT"), - ENUM_ENT(EF_LOONGARCH_BASE_ABI_LP64F, "LP64, SINGLE-FLOAT"), - ENUM_ENT(EF_LOONGARCH_BASE_ABI_LP64D, "LP64, DOUBLE-FLOAT"), + ENUM_ENT(EF_LOONGARCH_ABI_SOFT_FLOAT, "SOFT-FLOAT"), + ENUM_ENT(EF_LOONGARCH_ABI_SINGLE_FLOAT, "SINGLE-FLOAT"), + ENUM_ENT(EF_LOONGARCH_ABI_DOUBLE_FLOAT, "DOUBLE-FLOAT"), + ENUM_ENT(EF_LOONGARCH_OBJABI_V0, "OBJ-v0"), + ENUM_ENT(EF_LOONGARCH_OBJABI_V1, "OBJ-v1"), }; +static const EnumEntry<unsigned> ElfHeaderXtensaFlags[] = { + LLVM_READOBJ_ENUM_ENT(ELF, EF_XTENSA_MACH_NONE), + LLVM_READOBJ_ENUM_ENT(ELF, EF_XTENSA_XT_INSN), + LLVM_READOBJ_ENUM_ENT(ELF, EF_XTENSA_XT_LIT) +}; const EnumEntry<unsigned> ElfSymOtherFlags[] = { LLVM_READOBJ_ENUM_ENT(ELF, STV_INTERNAL), @@ -1946,7 +1949,7 @@ template <typename ELFT> void ELFDumper<ELFT>::parseDynamicTable() { const char *StringTableBegin = nullptr; uint64_t StringTableSize = 0; - Optional<DynRegionInfo> DynSymFromTable; + std::optional<DynRegionInfo> DynSymFromTable; for (const Elf_Dyn &Dyn : dynamic_table()) { switch (Dyn.d_tag) { case ELF::DT_HASH: @@ -2314,7 +2317,7 @@ std::string ELFDumper<ELFT>::getDynamicEntry(uint64_t Type, case DT_MIPS_XHASH: return FormatHexValue(Value); case DT_MIPS_FLAGS: - return FormatFlags(Value, makeArrayRef(ElfDynamicDTMipsFlags)); + return FormatFlags(Value, ArrayRef(ElfDynamicDTMipsFlags)); default: break; } @@ -2329,7 +2332,7 @@ std::string ELFDumper<ELFT>::getDynamicEntry(uint64_t Type, return "REL"; if (Value == DT_RELA) return "RELA"; - LLVM_FALLTHROUGH; + [[fallthrough]]; case DT_PLTGOT: case DT_HASH: case DT_STRTAB: @@ -2387,9 +2390,9 @@ std::string ELFDumper<ELFT>::getDynamicEntry(uint64_t Type, .str(); } case DT_FLAGS: - return FormatFlags(Value, makeArrayRef(ElfDynamicDTFlags)); + return FormatFlags(Value, ArrayRef(ElfDynamicDTFlags)); case DT_FLAGS_1: - return FormatFlags(Value, makeArrayRef(ElfDynamicDTFlags1)); + return FormatFlags(Value, ArrayRef(ElfDynamicDTFlags1)); default: return FormatHexValue(Value); } @@ -2551,7 +2554,7 @@ template <typename ELFT> void ELFDumper<ELFT>::printHashTable() { template <class ELFT> static Expected<ArrayRef<typename ELFT::Word>> -getGnuHashTableChains(Optional<DynRegionInfo> DynSymRegion, +getGnuHashTableChains(std::optional<DynRegionInfo> DynSymRegion, const typename ELFT::GnuHash *GnuHashTable) { if (!DynSymRegion) return createError("no dynamic symbol table found"); @@ -2796,9 +2799,9 @@ Error MipsGOTParser<ELFT>::findGOT(Elf_Dyn_Range DynTable, } // Lookup dynamic table tags which define the GOT layout. - Optional<uint64_t> DtPltGot; - Optional<uint64_t> DtLocalGotNum; - Optional<uint64_t> DtGotSym; + std::optional<uint64_t> DtPltGot; + std::optional<uint64_t> DtLocalGotNum; + std::optional<uint64_t> DtGotSym; for (const auto &Entry : DynTable) { switch (Entry.getTag()) { case ELF::DT_PLTGOT: @@ -2849,8 +2852,8 @@ Error MipsGOTParser<ELFT>::findGOT(Elf_Dyn_Range DynTable, template <class ELFT> Error MipsGOTParser<ELFT>::findPLT(Elf_Dyn_Range DynTable) { // Lookup dynamic table tags which define the PLT layout. - Optional<uint64_t> DtMipsPltGot; - Optional<uint64_t> DtJmpRel; + std::optional<uint64_t> DtMipsPltGot; + std::optional<uint64_t> DtJmpRel; for (const auto &Entry : DynTable) { switch (Entry.getTag()) { case ELF::DT_MIPS_PLTGOT: @@ -3294,7 +3297,7 @@ static const EnumEntry<unsigned> *getObjectFileEnumEntry(unsigned Type) { auto It = llvm::find_if(ElfObjectFileType, [&](const EnumEntry<unsigned> &E) { return E.Value == Type; }); - if (It != makeArrayRef(ElfObjectFileType).end()) + if (It != ArrayRef(ElfObjectFileType).end()) return It; return nullptr; } @@ -3317,9 +3320,9 @@ template <class ELFT> void GNUELFDumper<ELFT>::printFileHeaders() { for (int i = 0; i < ELF::EI_NIDENT; i++) OS << format(" %02x", static_cast<int>(e.e_ident[i])); OS << "\n"; - Str = enumToString(e.e_ident[ELF::EI_CLASS], makeArrayRef(ElfClass)); + Str = enumToString(e.e_ident[ELF::EI_CLASS], ArrayRef(ElfClass)); printFields(OS, "Class:", Str); - Str = enumToString(e.e_ident[ELF::EI_DATA], makeArrayRef(ElfDataEncoding)); + Str = enumToString(e.e_ident[ELF::EI_DATA], ArrayRef(ElfDataEncoding)); printFields(OS, "Data:", Str); OS.PadToColumn(2u); OS << "Version:"; @@ -3328,7 +3331,7 @@ template <class ELFT> void GNUELFDumper<ELFT>::printFileHeaders() { if (e.e_version == ELF::EV_CURRENT) OS << " (current)"; OS << "\n"; - Str = enumToString(e.e_ident[ELF::EI_OSABI], makeArrayRef(ElfOSABI)); + Str = enumToString(e.e_ident[ELF::EI_OSABI], ArrayRef(ElfOSABI)); printFields(OS, "OS/ABI:", Str); printFields(OS, "ABI Version:", std::to_string(e.e_ident[ELF::EI_ABIVERSION])); @@ -3345,7 +3348,7 @@ template <class ELFT> void GNUELFDumper<ELFT>::printFileHeaders() { } printFields(OS, "Type:", Str); - Str = enumToString(e.e_machine, makeArrayRef(ElfMachineType)); + Str = enumToString(e.e_machine, ArrayRef(ElfMachineType)); printFields(OS, "Machine:", Str); Str = "0x" + utohexstr(e.e_version); printFields(OS, "Version:", Str); @@ -3357,18 +3360,21 @@ template <class ELFT> void GNUELFDumper<ELFT>::printFileHeaders() { printFields(OS, "Start of section headers:", Str); std::string ElfFlags; if (e.e_machine == EM_MIPS) - ElfFlags = - printFlags(e.e_flags, makeArrayRef(ElfHeaderMipsFlags), - unsigned(ELF::EF_MIPS_ARCH), unsigned(ELF::EF_MIPS_ABI), - unsigned(ELF::EF_MIPS_MACH)); + ElfFlags = printFlags( + e.e_flags, ArrayRef(ElfHeaderMipsFlags), unsigned(ELF::EF_MIPS_ARCH), + unsigned(ELF::EF_MIPS_ABI), unsigned(ELF::EF_MIPS_MACH)); else if (e.e_machine == EM_RISCV) - ElfFlags = printFlags(e.e_flags, makeArrayRef(ElfHeaderRISCVFlags)); + ElfFlags = printFlags(e.e_flags, ArrayRef(ElfHeaderRISCVFlags)); else if (e.e_machine == EM_AVR) - ElfFlags = printFlags(e.e_flags, makeArrayRef(ElfHeaderAVRFlags), + ElfFlags = printFlags(e.e_flags, ArrayRef(ElfHeaderAVRFlags), unsigned(ELF::EF_AVR_ARCH_MASK)); else if (e.e_machine == EM_LOONGARCH) - ElfFlags = printFlags(e.e_flags, makeArrayRef(ElfHeaderLoongArchFlags), - unsigned(ELF::EF_LOONGARCH_BASE_ABI_MASK)); + ElfFlags = printFlags(e.e_flags, ArrayRef(ElfHeaderLoongArchFlags), + unsigned(ELF::EF_LOONGARCH_ABI_MODIFIER_MASK), + unsigned(ELF::EF_LOONGARCH_OBJABI_MASK)); + else if (e.e_machine == EM_XTENSA) + ElfFlags = printFlags(e.e_flags, ArrayRef(ElfHeaderXtensaFlags), + unsigned(ELF::EF_XTENSA_MACH)); Str = "0x" + utohexstr(e.e_flags); if (!ElfFlags.empty()) Str = Str + ", " + ElfFlags; @@ -3537,7 +3543,7 @@ void GNUELFDumper<ELFT>::printRelRelaReloc(const Relocation<ELFT> &R, printField(F); std::string Addend; - if (Optional<int64_t> A = R.Addend) { + if (std::optional<int64_t> A = R.Addend) { int64_t RelAddend = *A; if (!RelSym.Name.empty()) { if (RelAddend < 0) { @@ -3693,8 +3699,16 @@ static void printSectionDescription(formatted_raw_ostream &OS, } template <class ELFT> void GNUELFDumper<ELFT>::printSectionHeaders() { - unsigned Bias = ELFT::Is64Bits ? 0 : 8; ArrayRef<Elf_Shdr> Sections = cantFail(this->Obj.sections()); + if (Sections.empty()) { + OS << "\nThere are no sections in this file.\n"; + Expected<StringRef> SecStrTableOrErr = + this->Obj.getSectionStringTable(Sections, this->WarningHandler); + if (!SecStrTableOrErr) + this->reportUniqueWarning(SecStrTableOrErr.takeError()); + return; + } + unsigned Bias = ELFT::Is64Bits ? 0 : 8; OS << "There are " << to_string(Sections.size()) << " section headers, starting at offset " << "0x" << utohexstr(this->Obj.getHeader().e_shoff, /*LowerCase=*/true) << ":\n\n"; @@ -3825,7 +3839,7 @@ GNUELFDumper<ELFT>::getSymbolSectionNdx(const Elf_Sym &Symbol, template <class ELFT> void GNUELFDumper<ELFT>::printSymbol(const Elf_Sym &Symbol, unsigned SymIndex, DataRegion<Elf_Word> ShndxTable, - Optional<StringRef> StrTable, + std::optional<StringRef> StrTable, bool IsDynamic, bool NonVisibilityBitsUsed) const { unsigned Bias = ELFT::Is64Bits ? 8 : 0; @@ -3839,14 +3853,14 @@ void GNUELFDumper<ELFT>::printSymbol(const Elf_Sym &Symbol, unsigned SymIndex, unsigned char SymbolType = Symbol.getType(); if (this->Obj.getHeader().e_machine == ELF::EM_AMDGPU && SymbolType >= ELF::STT_LOOS && SymbolType < ELF::STT_HIOS) - Fields[3].Str = enumToString(SymbolType, makeArrayRef(AMDGPUSymbolTypes)); + Fields[3].Str = enumToString(SymbolType, ArrayRef(AMDGPUSymbolTypes)); else - Fields[3].Str = enumToString(SymbolType, makeArrayRef(ElfSymbolTypes)); + Fields[3].Str = enumToString(SymbolType, ArrayRef(ElfSymbolTypes)); Fields[4].Str = - enumToString(Symbol.getBinding(), makeArrayRef(ElfSymbolBindings)); + enumToString(Symbol.getBinding(), ArrayRef(ElfSymbolBindings)); Fields[5].Str = - enumToString(Symbol.getVisibility(), makeArrayRef(ElfSymbolVisibilities)); + enumToString(Symbol.getVisibility(), ArrayRef(ElfSymbolVisibilities)); if (Symbol.st_other & ~0x3) { if (this->Obj.getHeader().e_machine == ELF::EM_AARCH64) { @@ -3902,14 +3916,14 @@ void GNUELFDumper<ELFT>::printHashedSymbol(const Elf_Sym *Symbol, unsigned char SymbolType = Symbol->getType(); if (this->Obj.getHeader().e_machine == ELF::EM_AMDGPU && SymbolType >= ELF::STT_LOOS && SymbolType < ELF::STT_HIOS) - Fields[4].Str = enumToString(SymbolType, makeArrayRef(AMDGPUSymbolTypes)); + Fields[4].Str = enumToString(SymbolType, ArrayRef(AMDGPUSymbolTypes)); else - Fields[4].Str = enumToString(SymbolType, makeArrayRef(ElfSymbolTypes)); + Fields[4].Str = enumToString(SymbolType, ArrayRef(ElfSymbolTypes)); Fields[5].Str = - enumToString(Symbol->getBinding(), makeArrayRef(ElfSymbolBindings)); - Fields[6].Str = enumToString(Symbol->getVisibility(), - makeArrayRef(ElfSymbolVisibilities)); + enumToString(Symbol->getBinding(), ArrayRef(ElfSymbolBindings)); + Fields[6].Str = + enumToString(Symbol->getVisibility(), ArrayRef(ElfSymbolVisibilities)); Fields[7].Str = getSymbolSectionNdx(*Symbol, SymIndex, ShndxTable); Fields[8].Str = this->getFullSymbolName(*Symbol, SymIndex, ShndxTable, StrTable, true); @@ -4074,6 +4088,14 @@ template <class ELFT> void GNUELFDumper<ELFT>::printHashSymbols() { template <class ELFT> void GNUELFDumper<ELFT>::printSectionDetails() { ArrayRef<Elf_Shdr> Sections = cantFail(this->Obj.sections()); + if (Sections.empty()) { + OS << "\nThere are no sections in this file.\n"; + Expected<StringRef> SecStrTableOrErr = + this->Obj.getSectionStringTable(Sections, this->WarningHandler); + if (!SecStrTableOrErr) + this->reportUniqueWarning(SecStrTableOrErr.takeError()); + return; + } OS << "There are " << to_string(Sections.size()) << " section headers, starting at offset " << "0x" << utohexstr(this->Obj.getHeader().e_shoff, /*LowerCase=*/true) << ":\n\n"; @@ -4171,6 +4193,30 @@ template <class ELFT> void GNUELFDumper<ELFT>::printSectionDetails() { OS << "\n"; ++SectionIndex; + + if (!(S.sh_flags & SHF_COMPRESSED)) + continue; + Expected<ArrayRef<uint8_t>> Data = this->Obj.getSectionContents(S); + if (!Data || Data->size() < sizeof(Elf_Chdr)) { + consumeError(Data.takeError()); + reportWarning(createError("SHF_COMPRESSED section '" + Name + + "' does not have an Elf_Chdr header"), + this->FileName); + OS.indent(7); + OS << "[<corrupt>]"; + } else { + OS.indent(7); + auto *Chdr = reinterpret_cast<const Elf_Chdr *>(Data->data()); + if (Chdr->ch_type == ELFCOMPRESS_ZLIB) + OS << "ZLIB"; + else if (Chdr->ch_type == ELFCOMPRESS_ZSTD) + OS << "ZSTD"; + else + OS << format("[<unknown>: 0x%x]", unsigned(Chdr->ch_type)); + OS << ", " << format_hex_no_prefix(Chdr->ch_size, ELFT::Is64Bits ? 16 : 8) + << ", " << Chdr->ch_addralign; + } + OS << '\n'; } } @@ -4257,12 +4303,21 @@ static bool checkPTDynamic(const typename ELFT::Phdr &Phdr, template <class ELFT> void GNUELFDumper<ELFT>::printProgramHeaders( bool PrintProgramHeaders, cl::boolOrDefault PrintSectionMapping) { - if (PrintProgramHeaders) - printProgramHeaders(); + const bool ShouldPrintSectionMapping = (PrintSectionMapping != cl::BOU_FALSE); + // Exit early if no program header or section mapping details were requested. + if (!PrintProgramHeaders && !ShouldPrintSectionMapping) + return; + + if (PrintProgramHeaders) { + const Elf_Ehdr &Header = this->Obj.getHeader(); + if (Header.e_phnum == 0) { + OS << "\nThere are no program headers in this file.\n"; + } else { + printProgramHeaders(); + } + } - // Display the section mapping along with the program headers, unless - // -section-mapping is explicitly set to false. - if (PrintSectionMapping != cl::BOU_FALSE) + if (ShouldPrintSectionMapping) printSectionMapping(); } @@ -4272,7 +4327,7 @@ template <class ELFT> void GNUELFDumper<ELFT>::printProgramHeaders() { Field Fields[8] = {2, 17, 26, 37 + Bias, 48 + Bias, 56 + Bias, 64 + Bias, 68 + Bias}; OS << "\nElf file type is " - << enumToString(Header.e_type, makeArrayRef(ElfObjectFileType)) << "\n" + << enumToString(Header.e_type, ArrayRef(ElfObjectFileType)) << "\n" << "Entry point " << format_hex(Header.e_entry, 3) << "\n" << "There are " << Header.e_phnum << " program headers," << " starting at offset " << Header.e_phoff << "\n\n" @@ -4565,8 +4620,8 @@ void GNUELFDumper<ELFT>::printVersionSymbolSection(const Elf_Shdr *Sec) { return; } - SmallVector<Optional<VersionEntry>, 0> *VersionMap = nullptr; - if (Expected<SmallVector<Optional<VersionEntry>, 0> *> MapOrErr = + SmallVector<std::optional<VersionEntry>, 0> *VersionMap = nullptr; + if (Expected<SmallVector<std::optional<VersionEntry>, 0> *> MapOrErr = this->getVersionMap()) VersionMap = *MapOrErr; else @@ -4588,7 +4643,7 @@ void GNUELFDumper<ELFT>::printVersionSymbolSection(const Elf_Shdr *Sec) { bool IsDefault; Expected<StringRef> NameOrErr = this->Obj.getSymbolVersionByIndex( - Ndx, IsDefault, *VersionMap, /*IsSymHidden=*/None); + Ndx, IsDefault, *VersionMap, /*IsSymHidden=*/std::nullopt); if (!NameOrErr) { this->reportUniqueWarning("unable to get a version for entry " + Twine(I) + " of " + this->describe(*Sec) + @@ -5039,7 +5094,7 @@ template <typename ELFT> static GNUAbiTag getGNUAbiTag(ArrayRef<uint8_t> Desc) { "Linux", "Hurd", "Solaris", "FreeBSD", "NetBSD", "Syllable", "NaCl", }; StringRef OSName = "Unknown"; - if (Words[0] < array_lengthof(OSNames)) + if (Words[0] < std::size(OSNames)) OSName = OSNames[Words[0]]; uint32_t Major = Words[1], Minor = Words[2], Patch = Words[3]; std::string str; @@ -5178,14 +5233,14 @@ struct FreeBSDNote { }; template <typename ELFT> -static Optional<FreeBSDNote> +static std::optional<FreeBSDNote> getFreeBSDNote(uint32_t NoteType, ArrayRef<uint8_t> Desc, bool IsCore) { if (IsCore) - return None; // No pretty-printing yet. + return std::nullopt; // No pretty-printing yet. switch (NoteType) { case ELF::NT_FREEBSD_ABI_TAG: if (Desc.size() != 4) - return None; + return std::nullopt; return FreeBSDNote{ "ABI tag", utostr(support::endian::read32<ELFT::TargetEndianness>(Desc.data()))}; @@ -5193,12 +5248,12 @@ getFreeBSDNote(uint32_t NoteType, ArrayRef<uint8_t> Desc, bool IsCore) { return FreeBSDNote{"Arch tag", toStringRef(Desc).str()}; case ELF::NT_FREEBSD_FEATURE_CTL: { if (Desc.size() != 4) - return None; + return std::nullopt; unsigned Value = support::endian::read32<ELFT::TargetEndianness>(Desc.data()); std::string FlagsStr; raw_string_ostream OS(FlagsStr); - printFlags(Value, makeArrayRef(FreeBSDFeatureCtlFlags), OS); + printFlags(Value, ArrayRef(FreeBSDFeatureCtlFlags), OS); if (OS.str().empty()) OS << "0x" << utohexstr(Value); else @@ -5206,7 +5261,7 @@ getFreeBSDNote(uint32_t NoteType, ArrayRef<uint8_t> Desc, bool IsCore) { return FreeBSDNote{"Feature flags", OS.str()}; } default: - return None; + return std::nullopt; } } @@ -5628,7 +5683,7 @@ StringRef getNoteTypeName(const typename ELFT::Note &Note, unsigned ELFType) { template <class ELFT> static void printNotesHelper( const ELFDumper<ELFT> &Dumper, - llvm::function_ref<void(Optional<StringRef>, typename ELFT::Off, + llvm::function_ref<void(std::optional<StringRef>, typename ELFT::Off, typename ELFT::Addr)> StartNotesFn, llvm::function_ref<Error(const typename ELFT::Note &, bool)> ProcessNoteFn, @@ -5641,7 +5696,7 @@ static void printNotesHelper( for (const typename ELFT::Shdr &S : Sections) { if (S.sh_type != SHT_NOTE) continue; - StartNotesFn(expectedToOptional(Obj.getSectionName(S)), S.sh_offset, + StartNotesFn(expectedToStdOptional(Obj.getSectionName(S)), S.sh_offset, S.sh_size); Error Err = Error::success(); size_t I = 0; @@ -5673,7 +5728,7 @@ static void printNotesHelper( const typename ELFT::Phdr &P = (*PhdrsOrErr)[I]; if (P.p_type != PT_NOTE) continue; - StartNotesFn(/*SecName=*/None, P.p_offset, P.p_filesz); + StartNotesFn(/*SecName=*/std::nullopt, P.p_offset, P.p_filesz); Error Err = Error::success(); size_t Index = 0; for (const typename ELFT::Note Note : Obj.notes(P, Err)) { @@ -5694,7 +5749,7 @@ static void printNotesHelper( template <class ELFT> void GNUELFDumper<ELFT>::printNotes() { bool IsFirstHeader = true; - auto PrintHeader = [&](Optional<StringRef> SecName, + auto PrintHeader = [&](std::optional<StringRef> SecName, const typename ELFT::Off Offset, const typename ELFT::Addr Size) { // Print a newline between notes sections to match GNU readelf. @@ -5737,7 +5792,7 @@ template <class ELFT> void GNUELFDumper<ELFT>::printNotes() { if (printGNUNote<ELFT>(OS, Type, Descriptor)) return Error::success(); } else if (Name == "FreeBSD") { - if (Optional<FreeBSDNote> N = + if (std::optional<FreeBSDNote> N = getFreeBSDNote<ELFT>(Type, Descriptor, IsCore)) { OS << " " << N->Type << ": " << N->Value << '\n'; return Error::success(); @@ -5950,7 +6005,7 @@ template <class ELFT> void GNUELFDumper<ELFT>::printDependentLibs() { template <class ELFT> SmallVector<uint32_t> ELFDumper<ELFT>::getSymbolIndexesForFunctionAddress( - uint64_t SymValue, Optional<const Elf_Shdr *> FunctionSec) { + uint64_t SymValue, std::optional<const Elf_Shdr *> FunctionSec) { SmallVector<uint32_t> SymbolIndexes; if (!this->AddressToIndexMap) { // Populate the address to index map upon the first invocation of this @@ -6016,7 +6071,7 @@ SmallVector<uint32_t> ELFDumper<ELFT>::getSymbolIndexesForFunctionAddress( template <class ELFT> bool ELFDumper<ELFT>::printFunctionStackSize( - uint64_t SymValue, Optional<const Elf_Shdr *> FunctionSec, + uint64_t SymValue, std::optional<const Elf_Shdr *> FunctionSec, const Elf_Shdr &StackSizeSec, DataExtractor Data, uint64_t *Offset) { SmallVector<uint32_t> FuncSymIndexes = this->getSymbolIndexesForFunctionAddress(SymValue, FunctionSec); @@ -6134,8 +6189,8 @@ void ELFDumper<ELFT>::printNonRelocatableStackSizes( break; } uint64_t SymValue = Data.getAddress(&Offset); - if (!printFunctionStackSize(SymValue, /*FunctionSec=*/None, Sec, Data, - &Offset)) + if (!printFunctionStackSize(SymValue, /*FunctionSec=*/std::nullopt, Sec, + Data, &Offset)) break; } } @@ -6322,7 +6377,7 @@ void GNUELFDumper<ELFT>::printMipsGOT(const MipsGOTParser<ELFT> &Parser) { OS.PadToColumn(31 + 2 * Bias); OS << to_string(format_hex_no_prefix(Sym.st_value, 8 + Bias)); OS.PadToColumn(40 + 3 * Bias); - OS << enumToString(Sym.getType(), makeArrayRef(ElfSymbolTypes)); + OS << enumToString(Sym.getType(), ArrayRef(ElfSymbolTypes)); OS.PadToColumn(48 + 3 * Bias); OS << getSymbolSectionNdx(Sym, &Sym - this->dynamic_symbols().begin(), ShndxTable); @@ -6376,7 +6431,7 @@ void GNUELFDumper<ELFT>::printMipsPLT(const MipsGOTParser<ELFT> &Parser) { OS.PadToColumn(20 + 2 * Bias); OS << to_string(format_hex_no_prefix(Sym.st_value, 8 + Bias)); OS.PadToColumn(29 + 3 * Bias); - OS << enumToString(Sym.getType(), makeArrayRef(ElfSymbolTypes)); + OS << enumToString(Sym.getType(), ArrayRef(ElfSymbolTypes)); OS.PadToColumn(37 + 3 * Bias); OS << getSymbolSectionNdx(Sym, &Sym - this->dynamic_symbols().begin(), ShndxTable); @@ -6423,15 +6478,15 @@ template <class ELFT> void GNUELFDumper<ELFT>::printMipsABIFlags() { OS << "GPR size: " << getMipsRegisterSize(Flags->gpr_size) << "\n"; OS << "CPR1 size: " << getMipsRegisterSize(Flags->cpr1_size) << "\n"; OS << "CPR2 size: " << getMipsRegisterSize(Flags->cpr2_size) << "\n"; - OS << "FP ABI: " - << enumToString(Flags->fp_abi, makeArrayRef(ElfMipsFpABIType)) << "\n"; + OS << "FP ABI: " << enumToString(Flags->fp_abi, ArrayRef(ElfMipsFpABIType)) + << "\n"; OS << "ISA Extension: " - << enumToString(Flags->isa_ext, makeArrayRef(ElfMipsISAExtType)) << "\n"; + << enumToString(Flags->isa_ext, ArrayRef(ElfMipsISAExtType)) << "\n"; if (Flags->ases == 0) OS << "ASEs: None\n"; else // FIXME: Print each flag on a separate line. - OS << "ASEs: " << printFlags(Flags->ases, makeArrayRef(ElfMipsASEFlags)) + OS << "ASEs: " << printFlags(Flags->ases, ArrayRef(ElfMipsASEFlags)) << "\n"; OS << "FLAGS 1: " << format_hex_no_prefix(Flags->flags1, 8, false) << "\n"; OS << "FLAGS 2: " << format_hex_no_prefix(Flags->flags2, 8, false) << "\n"; @@ -6444,30 +6499,32 @@ template <class ELFT> void LLVMELFDumper<ELFT>::printFileHeaders() { DictScope D(W, "ElfHeader"); { DictScope D(W, "Ident"); - W.printBinary("Magic", makeArrayRef(E.e_ident).slice(ELF::EI_MAG0, 4)); - W.printEnum("Class", E.e_ident[ELF::EI_CLASS], makeArrayRef(ElfClass)); + W.printBinary("Magic", + ArrayRef<unsigned char>(E.e_ident).slice(ELF::EI_MAG0, 4)); + W.printEnum("Class", E.e_ident[ELF::EI_CLASS], ArrayRef(ElfClass)); W.printEnum("DataEncoding", E.e_ident[ELF::EI_DATA], - makeArrayRef(ElfDataEncoding)); + ArrayRef(ElfDataEncoding)); W.printNumber("FileVersion", E.e_ident[ELF::EI_VERSION]); - auto OSABI = makeArrayRef(ElfOSABI); + auto OSABI = ArrayRef(ElfOSABI); if (E.e_ident[ELF::EI_OSABI] >= ELF::ELFOSABI_FIRST_ARCH && E.e_ident[ELF::EI_OSABI] <= ELF::ELFOSABI_LAST_ARCH) { switch (E.e_machine) { case ELF::EM_AMDGPU: - OSABI = makeArrayRef(AMDGPUElfOSABI); + OSABI = ArrayRef(AMDGPUElfOSABI); break; case ELF::EM_ARM: - OSABI = makeArrayRef(ARMElfOSABI); + OSABI = ArrayRef(ARMElfOSABI); break; case ELF::EM_TI_C6000: - OSABI = makeArrayRef(C6000ElfOSABI); + OSABI = ArrayRef(C6000ElfOSABI); break; } } W.printEnum("OS/ABI", E.e_ident[ELF::EI_OSABI], OSABI); W.printNumber("ABIVersion", E.e_ident[ELF::EI_ABIVERSION]); - W.printBinary("Unused", makeArrayRef(E.e_ident).slice(ELF::EI_PAD)); + W.printBinary("Unused", + ArrayRef<unsigned char>(E.e_ident).slice(ELF::EI_PAD)); } std::string TypeStr; @@ -6483,13 +6540,13 @@ template <class ELFT> void LLVMELFDumper<ELFT>::printFileHeaders() { } W.printString("Type", TypeStr + " (0x" + utohexstr(E.e_type) + ")"); - W.printEnum("Machine", E.e_machine, makeArrayRef(ElfMachineType)); + W.printEnum("Machine", E.e_machine, ArrayRef(ElfMachineType)); W.printNumber("Version", E.e_version); W.printHex("Entry", E.e_entry); W.printHex("ProgramHeaderOffset", E.e_phoff); W.printHex("SectionHeaderOffset", E.e_shoff); if (E.e_machine == EM_MIPS) - W.printFlags("Flags", E.e_flags, makeArrayRef(ElfHeaderMipsFlags), + W.printFlags("Flags", E.e_flags, ArrayRef(ElfHeaderMipsFlags), unsigned(ELF::EF_MIPS_ARCH), unsigned(ELF::EF_MIPS_ABI), unsigned(ELF::EF_MIPS_MACH)); else if (E.e_machine == EM_AMDGPU) { @@ -6499,29 +6556,33 @@ template <class ELFT> void LLVMELFDumper<ELFT>::printFileHeaders() { break; case 0: // ELFOSABI_AMDGPU_PAL, ELFOSABI_AMDGPU_MESA3D support *_V3 flags. - LLVM_FALLTHROUGH; + [[fallthrough]]; case ELF::ELFABIVERSION_AMDGPU_HSA_V3: W.printFlags("Flags", E.e_flags, - makeArrayRef(ElfHeaderAMDGPUFlagsABIVersion3), + ArrayRef(ElfHeaderAMDGPUFlagsABIVersion3), unsigned(ELF::EF_AMDGPU_MACH)); break; case ELF::ELFABIVERSION_AMDGPU_HSA_V4: case ELF::ELFABIVERSION_AMDGPU_HSA_V5: W.printFlags("Flags", E.e_flags, - makeArrayRef(ElfHeaderAMDGPUFlagsABIVersion4), + ArrayRef(ElfHeaderAMDGPUFlagsABIVersion4), unsigned(ELF::EF_AMDGPU_MACH), unsigned(ELF::EF_AMDGPU_FEATURE_XNACK_V4), unsigned(ELF::EF_AMDGPU_FEATURE_SRAMECC_V4)); break; } } else if (E.e_machine == EM_RISCV) - W.printFlags("Flags", E.e_flags, makeArrayRef(ElfHeaderRISCVFlags)); + W.printFlags("Flags", E.e_flags, ArrayRef(ElfHeaderRISCVFlags)); else if (E.e_machine == EM_AVR) - W.printFlags("Flags", E.e_flags, makeArrayRef(ElfHeaderAVRFlags), + W.printFlags("Flags", E.e_flags, ArrayRef(ElfHeaderAVRFlags), unsigned(ELF::EF_AVR_ARCH_MASK)); else if (E.e_machine == EM_LOONGARCH) - W.printFlags("Flags", E.e_flags, makeArrayRef(ElfHeaderLoongArchFlags), - unsigned(ELF::EF_LOONGARCH_BASE_ABI_MASK)); + W.printFlags("Flags", E.e_flags, ArrayRef(ElfHeaderLoongArchFlags), + unsigned(ELF::EF_LOONGARCH_ABI_MODIFIER_MASK), + unsigned(ELF::EF_LOONGARCH_OBJABI_MASK)); + else if (E.e_machine == EM_XTENSA) + W.printFlags("Flags", E.e_flags, ArrayRef(ElfHeaderXtensaFlags), + unsigned(ELF::EF_XTENSA_MACH)); else W.printFlags("Flags", E.e_flags); W.printNumber("HeaderSize", E.e_ehsize); @@ -6627,7 +6688,7 @@ template <class ELFT> void LLVMELFDumper<ELFT>::printSectionHeaders() { object::getELFSectionTypeName(this->Obj.getHeader().e_machine, Sec.sh_type), Sec.sh_type); - W.printFlags("Flags", Sec.sh_flags, makeArrayRef(FlagsList)); + W.printFlags("Flags", Sec.sh_flags, ArrayRef(FlagsList)); W.printHex("Address", Sec.sh_addr); W.printHex("Offset", Sec.sh_offset); W.printNumber("Size", Sec.sh_size); @@ -6676,7 +6737,7 @@ template <class ELFT> void LLVMELFDumper<ELFT>::printSymbolSection( const Elf_Sym &Symbol, unsigned SymIndex, DataRegion<Elf_Word> ShndxTable) const { - auto GetSectionSpecialType = [&]() -> Optional<StringRef> { + auto GetSectionSpecialType = [&]() -> std::optional<StringRef> { if (Symbol.isUndefined()) return StringRef("Undefined"); if (Symbol.isProcessorSpecific()) @@ -6689,10 +6750,10 @@ void LLVMELFDumper<ELFT>::printSymbolSection( return StringRef("Common"); if (Symbol.isReserved() && Symbol.st_shndx != SHN_XINDEX) return StringRef("Reserved"); - return None; + return std::nullopt; }; - if (Optional<StringRef> Type = GetSectionSpecialType()) { + if (std::optional<StringRef> Type = GetSectionSpecialType()) { W.printHex("Section", *Type, Symbol.st_shndx); return; } @@ -6726,7 +6787,7 @@ void LLVMELFDumper<ELFT>::printSymbolSection( template <class ELFT> void LLVMELFDumper<ELFT>::printSymbol(const Elf_Sym &Symbol, unsigned SymIndex, DataRegion<Elf_Word> ShndxTable, - Optional<StringRef> StrTable, + std::optional<StringRef> StrTable, bool IsDynamic, bool /*NonVisibilityBitsUsed*/) const { std::string FullSymbolName = this->getFullSymbolName( @@ -6737,12 +6798,12 @@ void LLVMELFDumper<ELFT>::printSymbol(const Elf_Sym &Symbol, unsigned SymIndex, W.printNumber("Name", FullSymbolName, Symbol.st_name); W.printHex("Value", Symbol.st_value); W.printNumber("Size", Symbol.st_size); - W.printEnum("Binding", Symbol.getBinding(), makeArrayRef(ElfSymbolBindings)); + W.printEnum("Binding", Symbol.getBinding(), ArrayRef(ElfSymbolBindings)); if (this->Obj.getHeader().e_machine == ELF::EM_AMDGPU && SymbolType >= ELF::STT_LOOS && SymbolType < ELF::STT_HIOS) - W.printEnum("Type", SymbolType, makeArrayRef(AMDGPUSymbolTypes)); + W.printEnum("Type", SymbolType, ArrayRef(AMDGPUSymbolTypes)); else - W.printEnum("Type", SymbolType, makeArrayRef(ElfSymbolTypes)); + W.printEnum("Type", SymbolType, ArrayRef(ElfSymbolTypes)); if (Symbol.st_other == 0) // Usually st_other flag is zero. Do not pollute the output // by flags enumeration in that case. @@ -6771,7 +6832,7 @@ void LLVMELFDumper<ELFT>::printSymbol(const Elf_Sym &Symbol, unsigned SymIndex, std::begin(ElfRISCVSymOtherFlags), std::end(ElfRISCVSymOtherFlags)); } - W.printFlags("Other", Symbol.st_other, makeArrayRef(SymOtherFlags), 0x3u); + W.printFlags("Other", Symbol.st_other, ArrayRef(SymOtherFlags), 0x3u); } printSymbolSection(Symbol, SymIndex, ShndxTable); } @@ -6854,7 +6915,7 @@ template <class ELFT> void LLVMELFDumper<ELFT>::printProgramHeaders() { W.printHex("PhysicalAddress", Phdr.p_paddr); W.printNumber("FileSize", Phdr.p_filesz); W.printNumber("MemSize", Phdr.p_memsz); - W.printFlags("Flags", Phdr.p_flags, makeArrayRef(ElfSegmentFlags)); + W.printFlags("Flags", Phdr.p_flags, ArrayRef(ElfSegmentFlags)); W.printNumber("Alignment", Phdr.p_align); } } @@ -6908,7 +6969,7 @@ void LLVMELFDumper<ELFT>::printVersionDefinitionSection(const Elf_Shdr *Sec) { for (const VerDef &D : *V) { DictScope Def(W, "Definition"); W.printNumber("Version", D.Version); - W.printFlags("Flags", D.Flags, makeArrayRef(SymVersionFlags)); + W.printFlags("Flags", D.Flags, ArrayRef(SymVersionFlags)); W.printNumber("Index", D.Ndx); W.printNumber("Hash", D.Hash); W.printString("Name", D.Name.c_str()); @@ -6941,7 +7002,7 @@ void LLVMELFDumper<ELFT>::printVersionDependencySection(const Elf_Shdr *Sec) { for (const VernAux &Aux : VN.AuxV) { DictScope Entry(W, "Entry"); W.printNumber("Hash", Aux.Hash); - W.printFlags("Flags", Aux.Flags, makeArrayRef(SymVersionFlags)); + W.printFlags("Flags", Aux.Flags, ArrayRef(SymVersionFlags)); W.printNumber("Index", Aux.Other); W.printString("Name", Aux.Name.c_str()); } @@ -7053,7 +7114,7 @@ template <class ELFT> void LLVMELFDumper<ELFT>::printBBAddrMaps() { Sec.sh_type != SHT_LLVM_BB_ADDR_MAP_V0) { continue; } - Optional<const Elf_Shdr *> FunctionSec = None; + std::optional<const Elf_Shdr *> FunctionSec; if (IsRelocatable) FunctionSec = unwrapOrError(this->FileName, this->Obj.getSection(Sec.sh_link)); @@ -7082,6 +7143,7 @@ template <class ELFT> void LLVMELFDumper<ELFT>::printBBAddrMaps() { ListScope L(W, "BB entries"); for (const BBAddrMap::BBEntry &BBE : AM.BBEntries) { DictScope L(W); + W.printNumber("ID", BBE.ID); W.printHex("Offset", BBE.Offset); W.printHex("Size", BBE.Size); W.printBoolean("HasReturn", BBE.HasReturn); @@ -7189,7 +7251,7 @@ template <class ELFT> void LLVMELFDumper<ELFT>::printNotes() { ListScope L(W, "Notes"); std::unique_ptr<DictScope> NoteScope; - auto StartNotes = [&](Optional<StringRef> SecName, + auto StartNotes = [&](std::optional<StringRef> SecName, const typename ELFT::Off Offset, const typename ELFT::Addr Size) { NoteScope = std::make_unique<DictScope>(W, "NoteSection"); @@ -7224,7 +7286,7 @@ template <class ELFT> void LLVMELFDumper<ELFT>::printNotes() { if (printGNUNoteLLVMStyle<ELFT>(Type, Descriptor, W)) return Error::success(); } else if (Name == "FreeBSD") { - if (Optional<FreeBSDNote> N = + if (std::optional<FreeBSDNote> N = getFreeBSDNote<ELFT>(Type, Descriptor, IsCore)) { W.printString(N->Type, N->Value); return Error::success(); @@ -7381,7 +7443,7 @@ void LLVMELFDumper<ELFT>::printMipsGOT(const MipsGOTParser<ELFT> &Parser) { const Elf_Sym &Sym = *Parser.getGotSym(&E); W.printHex("Value", Sym.st_value); - W.printEnum("Type", Sym.getType(), makeArrayRef(ElfSymbolTypes)); + W.printEnum("Type", Sym.getType(), ArrayRef(ElfSymbolTypes)); const unsigned SymIndex = &Sym - this->dynamic_symbols().begin(); DataRegion<Elf_Word> ShndxTable( @@ -7431,7 +7493,7 @@ void LLVMELFDumper<ELFT>::printMipsPLT(const MipsGOTParser<ELFT> &Parser) { const Elf_Sym &Sym = *Parser.getPltSym(&E); W.printHex("Value", Sym.st_value); - W.printEnum("Type", Sym.getType(), makeArrayRef(ElfSymbolTypes)); + W.printEnum("Type", Sym.getType(), ArrayRef(ElfSymbolTypes)); printSymbolSection(Sym, &Sym - this->dynamic_symbols().begin(), ShndxTable); @@ -7468,13 +7530,13 @@ template <class ELFT> void LLVMELFDumper<ELFT>::printMipsABIFlags() { else OS << format("MIPS%ur%u", Flags->isa_level, Flags->isa_rev); OS << "\n"; - W.printEnum("ISA Extension", Flags->isa_ext, makeArrayRef(ElfMipsISAExtType)); - W.printFlags("ASEs", Flags->ases, makeArrayRef(ElfMipsASEFlags)); - W.printEnum("FP ABI", Flags->fp_abi, makeArrayRef(ElfMipsFpABIType)); + W.printEnum("ISA Extension", Flags->isa_ext, ArrayRef(ElfMipsISAExtType)); + W.printFlags("ASEs", Flags->ases, ArrayRef(ElfMipsASEFlags)); + W.printEnum("FP ABI", Flags->fp_abi, ArrayRef(ElfMipsFpABIType)); W.printNumber("GPR size", getMipsRegisterSize(Flags->gpr_size)); W.printNumber("CPR1 size", getMipsRegisterSize(Flags->cpr1_size)); W.printNumber("CPR2 size", getMipsRegisterSize(Flags->cpr2_size)); - W.printFlags("Flags 1", Flags->flags1, makeArrayRef(ElfMipsFlags1)); + W.printFlags("Flags 1", Flags->flags1, ArrayRef(ElfMipsFlags1)); W.printHex("Flags 2", Flags->flags2); } @@ -7482,7 +7544,7 @@ template <class ELFT> void JSONELFDumper<ELFT>::printFileSummary(StringRef FileStr, ObjectFile &Obj, ArrayRef<std::string> InputFilenames, const Archive *A) { - FileScope = std::make_unique<DictScope>(this->W, FileStr); + FileScope = std::make_unique<DictScope>(this->W); DictScope D(this->W, "FileSummary"); this->W.printString("File", FileStr); this->W.printString("Format", Obj.getFileFormatName()); diff --git a/contrib/llvm-project/llvm/tools/llvm-readobj/MachODumper.cpp b/contrib/llvm-project/llvm/tools/llvm-readobj/MachODumper.cpp index 4931ab575bb2..5b385019486c 100644 --- a/contrib/llvm-project/llvm/tools/llvm-readobj/MachODumper.cpp +++ b/contrib/llvm-project/llvm/tools/llvm-readobj/MachODumper.cpp @@ -13,7 +13,6 @@ #include "ObjDumper.h" #include "StackMapPrinter.h" #include "llvm-readobj.h" -#include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Object/MachO.h" @@ -61,9 +60,9 @@ private: uint8_t getSymbolType(const SymbolRef &Symbol) const; void printSymbols() override; - void printSymbols(Optional<SymbolComparator> SymComp) override; + void printSymbols(std::optional<SymbolComparator> SymComp) override; void printDynamicSymbols() override; - void printDynamicSymbols(Optional<SymbolComparator> SymComp) override; + void printDynamicSymbols(std::optional<SymbolComparator> SymComp) override; void printSymbol(const SymbolRef &Symbol, ScopedPrinter &W); void printSymbol(const SymbolRef &Symbol); @@ -432,36 +431,36 @@ void MachODumper::printFileHeaders() { template<class MachHeader> void MachODumper::printFileHeaders(const MachHeader &Header) { - W.printEnum("Magic", Header.magic, makeArrayRef(MachOMagics)); - W.printEnum("CpuType", Header.cputype, makeArrayRef(MachOHeaderCpuTypes)); + W.printEnum("Magic", Header.magic, ArrayRef(MachOMagics)); + W.printEnum("CpuType", Header.cputype, ArrayRef(MachOHeaderCpuTypes)); uint32_t subtype = Header.cpusubtype & ~MachO::CPU_SUBTYPE_MASK; switch (Header.cputype) { case MachO::CPU_TYPE_X86: - W.printEnum("CpuSubType", subtype, makeArrayRef(MachOHeaderCpuSubtypesX86)); + W.printEnum("CpuSubType", subtype, ArrayRef(MachOHeaderCpuSubtypesX86)); break; case MachO::CPU_TYPE_X86_64: - W.printEnum("CpuSubType", subtype, makeArrayRef(MachOHeaderCpuSubtypesX64)); + W.printEnum("CpuSubType", subtype, ArrayRef(MachOHeaderCpuSubtypesX64)); break; case MachO::CPU_TYPE_ARM: - W.printEnum("CpuSubType", subtype, makeArrayRef(MachOHeaderCpuSubtypesARM)); + W.printEnum("CpuSubType", subtype, ArrayRef(MachOHeaderCpuSubtypesARM)); break; case MachO::CPU_TYPE_POWERPC: - W.printEnum("CpuSubType", subtype, makeArrayRef(MachOHeaderCpuSubtypesPPC)); + W.printEnum("CpuSubType", subtype, ArrayRef(MachOHeaderCpuSubtypesPPC)); break; case MachO::CPU_TYPE_SPARC: - W.printEnum("CpuSubType", subtype, makeArrayRef(MachOHeaderCpuSubtypesSPARC)); + W.printEnum("CpuSubType", subtype, ArrayRef(MachOHeaderCpuSubtypesSPARC)); break; case MachO::CPU_TYPE_ARM64: - W.printEnum("CpuSubType", subtype, makeArrayRef(MachOHeaderCpuSubtypesARM64)); + W.printEnum("CpuSubType", subtype, ArrayRef(MachOHeaderCpuSubtypesARM64)); break; case MachO::CPU_TYPE_POWERPC64: default: W.printHex("CpuSubtype", subtype); } - W.printEnum("FileType", Header.filetype, makeArrayRef(MachOHeaderFileTypes)); + W.printEnum("FileType", Header.filetype, ArrayRef(MachOHeaderFileTypes)); W.printNumber("NumOfLoadCommands", Header.ncmds); W.printNumber("SizeOfLoadCommands", Header.sizeofcmds); - W.printFlags("Flags", Header.flags, makeArrayRef(MachOHeaderFlags)); + W.printFlags("Flags", Header.flags, ArrayRef(MachOHeaderFlags)); } void MachODumper::printSectionHeaders() { return printSectionHeaders(Obj); } @@ -491,10 +490,9 @@ void MachODumper::printSectionHeaders(const MachOObjectFile *Obj) { W.printNumber("Alignment", MOSection.Alignment); W.printHex("RelocationOffset", MOSection.RelocationTableOffset); W.printNumber("RelocationCount", MOSection.NumRelocationTableEntries); - W.printEnum("Type", MOSection.Flags & 0xFF, - makeArrayRef(MachOSectionTypes)); + W.printEnum("Type", MOSection.Flags & 0xFF, ArrayRef(MachOSectionTypes)); W.printFlags("Attributes", MOSection.Flags >> 8, - makeArrayRef(MachOSectionAttributes)); + ArrayRef(MachOSectionAttributes)); W.printHex("Reserved1", MOSection.Reserved1); W.printHex("Reserved2", MOSection.Reserved2); if (Obj->is64Bit()) @@ -634,9 +632,9 @@ bool MachODumper::compareSymbolsByType(SymbolRef LHS, SymbolRef RHS) const { return getSymbolType(LHS) < getSymbolType(RHS); } -void MachODumper::printSymbols() { printSymbols(None); } +void MachODumper::printSymbols() { printSymbols(std::nullopt); } -void MachODumper::printSymbols(Optional<SymbolComparator> SymComp) { +void MachODumper::printSymbols(std::optional<SymbolComparator> SymComp) { ListScope Group(W, "Symbols"); if (SymComp) { auto SymbolRange = Obj->symbols(); @@ -655,7 +653,7 @@ void MachODumper::printSymbols(Optional<SymbolComparator> SymComp) { void MachODumper::printDynamicSymbols() { ListScope Group(W, "DynamicSymbols"); } -void MachODumper::printDynamicSymbols(Optional<SymbolComparator> SymComp) { +void MachODumper::printDynamicSymbols(std::optional<SymbolComparator> SymComp) { ListScope Group(W, "DynamicSymbols"); } @@ -695,13 +693,13 @@ void MachODumper::printSymbol(const SymbolRef &Symbol, ScopedPrinter &W) { if (MOSymbol.Type & MachO::N_EXT) W.startLine() << "Extern\n"; W.printEnum("Type", uint8_t(MOSymbol.Type & MachO::N_TYPE), - makeArrayRef(MachOSymbolTypes)); + ArrayRef(MachOSymbolTypes)); } W.printHex("Section", SectionName, MOSymbol.SectionIndex); W.printEnum("RefType", static_cast<uint16_t>(MOSymbol.Flags & 0x7), - makeArrayRef(MachOSymbolRefTypes)); + ArrayRef(MachOSymbolRefTypes)); W.printFlags("Flags", static_cast<uint16_t>(MOSymbol.Flags & ~0x7), - makeArrayRef(MachOSymbolFlags)); + ArrayRef(MachOSymbolFlags)); W.printHex("Value", MOSymbol.Value); } diff --git a/contrib/llvm-project/llvm/tools/llvm-readobj/ObjDumper.h b/contrib/llvm-project/llvm/tools/llvm-readobj/ObjDumper.h index 292efd2ae350..258d87240984 100644 --- a/contrib/llvm-project/llvm/tools/llvm-readobj/ObjDumper.h +++ b/contrib/llvm-project/llvm/tools/llvm-readobj/ObjDumper.h @@ -13,7 +13,6 @@ #include <memory> #include <system_error> -#include "llvm/ADT/Optional.h" #include "llvm/ADT/STLFunctionalExtras.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringMap.h" @@ -85,7 +84,7 @@ public: printDynamicSymbols(); } virtual void printSymbols(bool PrintSymbols, bool PrintDynamicSymbols, - llvm::Optional<SymbolComparator> SymComp) { + std::optional<SymbolComparator> SymComp) { if (SymComp) { if (PrintSymbols) printSymbols(SymComp); @@ -155,8 +154,12 @@ public: llvm::codeview::GlobalTypeTableBuilder &GlobalCVTypes, bool GHash) {} - // Only implement for XCOFF + // Only implemented for XCOFF. + virtual void printStringTable() {} virtual void printAuxiliaryHeader() {} + virtual void printExceptionSection() {} + virtual void printLoaderSection(bool PrintHeader, bool PrintSymbols, + bool PrintRelocations) {} // Only implemented for MachO. virtual void printMachODataInCode() { } @@ -166,9 +169,6 @@ public: virtual void printMachOIndirectSymbols() { } virtual void printMachOLinkerOptions() { } - // Currently only implemented for XCOFF. - virtual void printStringTable() { } - virtual void printStackMap() const = 0; void printAsStringList(StringRef StringContent, size_t StringDataOffset = 0); @@ -187,9 +187,9 @@ protected: private: virtual void printSymbols() {} - virtual void printSymbols(llvm::Optional<SymbolComparator> Comp) {} + virtual void printSymbols(std::optional<SymbolComparator> Comp) {} virtual void printDynamicSymbols() {} - virtual void printDynamicSymbols(llvm::Optional<SymbolComparator> Comp) {} + virtual void printDynamicSymbols(std::optional<SymbolComparator> Comp) {} virtual void printProgramHeaders() {} virtual void printSectionMapping() {} diff --git a/contrib/llvm-project/llvm/tools/llvm-readobj/Opts.td b/contrib/llvm-project/llvm/tools/llvm-readobj/Opts.td index 4687fc71245f..4f7b12f95a60 100644 --- a/contrib/llvm-project/llvm/tools/llvm-readobj/Opts.td +++ b/contrib/llvm-project/llvm/tools/llvm-readobj/Opts.td @@ -88,6 +88,10 @@ def coff_tls_directory : FF<"coff-tls-directory", "Display TLS directory">, Grou // XCOFF specific options. def grp_xcoff : OptionGroup<"kind">, HelpText<"OPTIONS (XCOFF specific)">; def auxiliary_header : FF<"auxiliary-header" , "Display the auxiliary header">, Group<grp_xcoff>; +def exception_section : FF<"exception-section" , "Display the exception section entries">, Group<grp_xcoff>; +def loader_section_header : FF<"loader-section-header" , "Display the loader section header">, Group<grp_xcoff>; +def loader_section_symbols : FF<"loader-section-symbols" , "Display the loader section symbol table">, Group<grp_xcoff>; +def loader_section_relocations : FF<"loader-section-relocations" , "Display the loader section relocation entries">, Group<grp_xcoff>; def help : FF<"help", "Display this help">; def version : FF<"version", "Display the version">; diff --git a/contrib/llvm-project/llvm/tools/llvm-readobj/WasmDumper.cpp b/contrib/llvm-project/llvm/tools/llvm-readobj/WasmDumper.cpp index cf80a2d13d2d..e6f0ac7ba762 100644 --- a/contrib/llvm-project/llvm/tools/llvm-readobj/WasmDumper.cpp +++ b/contrib/llvm-project/llvm/tools/llvm-readobj/WasmDumper.cpp @@ -156,7 +156,7 @@ void WasmDumper::printSectionHeaders() { for (const SectionRef &Section : Obj->sections()) { const WasmSection &WasmSec = Obj->getWasmSection(Section); DictScope SectionD(W, "Section"); - W.printEnum("Type", WasmSec.Type, makeArrayRef(WasmSectionTypes)); + W.printEnum("Type", WasmSec.Type, ArrayRef(WasmSectionTypes)); W.printNumber("Size", static_cast<uint64_t>(WasmSec.Content.size())); W.printNumber("Offset", WasmSec.Offset); switch (WasmSec.Type) { @@ -221,8 +221,8 @@ void WasmDumper::printSymbol(const SymbolRef &Sym) { DictScope D(W, "Symbol"); WasmSymbol Symbol = Obj->getWasmSymbol(Sym.getRawDataRefImpl()); W.printString("Name", Symbol.Info.Name); - W.printEnum("Type", Symbol.Info.Kind, makeArrayRef(WasmSymbolTypes)); - W.printFlags("Flags", Symbol.Info.Flags, makeArrayRef(WasmSymbolFlags)); + W.printEnum("Type", Symbol.Info.Kind, ArrayRef(WasmSymbolTypes)); + W.printFlags("Flags", Symbol.Info.Flags, ArrayRef(WasmSymbolFlags)); if (Symbol.Info.Flags & wasm::WASM_SYMBOL_UNDEFINED) { if (Symbol.Info.ImportName) { diff --git a/contrib/llvm-project/llvm/tools/llvm-readobj/Win64EHDumper.cpp b/contrib/llvm-project/llvm/tools/llvm-readobj/Win64EHDumper.cpp index da964d3132e7..2896f20336c5 100644 --- a/contrib/llvm-project/llvm/tools/llvm-readobj/Win64EHDumper.cpp +++ b/contrib/llvm-project/llvm/tools/llvm-readobj/Win64EHDumper.cpp @@ -315,11 +315,11 @@ void Dumper::printUnwindInfo(const Context &Ctx, const coff_section *Section, off_t Offset, const UnwindInfo &UI) { DictScope UIS(SW, "UnwindInfo"); SW.printNumber("Version", UI.getVersion()); - SW.printFlags("Flags", UI.getFlags(), makeArrayRef(UnwindFlags)); + SW.printFlags("Flags", UI.getFlags(), ArrayRef(UnwindFlags)); SW.printNumber("PrologSize", UI.PrologSize); if (UI.getFrameRegister()) { SW.printEnum("FrameRegister", UI.getFrameRegister(), - makeArrayRef(UnwindOpInfo)); + ArrayRef(UnwindOpInfo)); SW.printHex("FrameOffset", UI.getFrameOffset()); } else { SW.printString("FrameRegister", StringRef("-")); @@ -337,7 +337,7 @@ void Dumper::printUnwindInfo(const Context &Ctx, const coff_section *Section, return; } - printUnwindCode(UI, makeArrayRef(UCI, UCE)); + printUnwindCode(UI, ArrayRef(UCI, UCE)); UCI = UCI + UsedSlots - 1; } } diff --git a/contrib/llvm-project/llvm/tools/llvm-readobj/XCOFFDumper.cpp b/contrib/llvm-project/llvm/tools/llvm-readobj/XCOFFDumper.cpp index ccae66f20127..56f672b3c5aa 100644 --- a/contrib/llvm-project/llvm/tools/llvm-readobj/XCOFFDumper.cpp +++ b/contrib/llvm-project/llvm/tools/llvm-readobj/XCOFFDumper.cpp @@ -39,6 +39,9 @@ public: void printStackMap() const override; void printNeededLibraries() override; void printStringTable() override; + void printExceptionSection() override; + void printLoaderSection(bool PrintHeader, bool PrintSymbols, + bool PrintRelocations) override; ScopedPrinter &getScopedPrinter() const { return W; } @@ -46,6 +49,9 @@ private: template <typename T> void printSectionHeaders(ArrayRef<T> Sections); template <typename T> void printGenericSectionHeader(T &Sec) const; template <typename T> void printOverflowSectionHeader(T &Sec) const; + template <typename T> + void printExceptionSectionEntry(const T &ExceptionSectEnt) const; + template <typename T> void printExceptionSectionEntries() const; template <typename T> const T *getAuxEntPtr(uintptr_t AuxAddress); void printFileAuxEnt(const XCOFFFileAuxEnt *AuxEntPtr); void printCsectAuxEnt(XCOFFCsectAuxRef AuxEntRef); @@ -62,7 +68,20 @@ private: void printRelocations(ArrayRef<Shdr> Sections); void printAuxiliaryHeader(const XCOFFAuxiliaryHeader32 *AuxHeader); void printAuxiliaryHeader(const XCOFFAuxiliaryHeader64 *AuxHeader); + void printLoaderSectionHeader(uintptr_t LoaderSectAddr); + void printLoaderSectionSymbols(uintptr_t LoaderSectAddr); + template <typename LoaderSectionSymbolEntry, typename LoaderSectionHeader> + void printLoaderSectionSymbolsHelper(uintptr_t LoaderSectAddr); + template <typename LoadSectionRelocTy> + void printLoaderSectionRelocationEntry(LoadSectionRelocTy *LoaderSecRelEntPtr, + StringRef SymbolName); + void printLoaderSectionRelocationEntries(uintptr_t LoaderSectAddr); + template <typename LoaderSectionHeader, typename LoaderSectionSymbolEntry, + typename LoaderSectionRelocationEntry> + void printLoaderSectionRelocationEntriesHelper(uintptr_t LoaderSectAddr); + const XCOFFObjectFile &Obj; + const static int32_t FirstSymIdxOfLoaderSec = 3; }; } // anonymous namespace @@ -129,11 +148,127 @@ void XCOFFDumper::printSectionHeaders() { printSectionHeaders(Obj.sections32()); } -void XCOFFDumper::printRelocations() { +void XCOFFDumper::printLoaderSection(bool PrintHeader, bool PrintSymbols, + bool PrintRelocations) { + DictScope DS(W, "Loader Section"); + Expected<uintptr_t> LoaderSectionAddrOrError = + Obj.getSectionFileOffsetToRawData(XCOFF::STYP_LOADER); + if (!LoaderSectionAddrOrError) { + reportUniqueWarning(LoaderSectionAddrOrError.takeError()); + return; + } + uintptr_t LoaderSectionAddr = LoaderSectionAddrOrError.get(); + + if (LoaderSectionAddr == 0) + return; + + W.indent(); + if (PrintHeader) + printLoaderSectionHeader(LoaderSectionAddr); + + if (PrintSymbols) + printLoaderSectionSymbols(LoaderSectionAddr); + + if (PrintRelocations) + printLoaderSectionRelocationEntries(LoaderSectionAddr); + + W.unindent(); +} + +void XCOFFDumper::printLoaderSectionHeader(uintptr_t LoaderSectionAddr) { + DictScope DS(W, "Loader Section Header"); + + auto PrintLoadSecHeaderCommon = [&](const auto *LDHeader) { + W.printNumber("Version", LDHeader->Version); + W.printNumber("NumberOfSymbolEntries", LDHeader->NumberOfSymTabEnt); + W.printNumber("NumberOfRelocationEntries", LDHeader->NumberOfRelTabEnt); + W.printNumber("LengthOfImportFileIDStringTable", + LDHeader->LengthOfImpidStrTbl); + W.printNumber("NumberOfImportFileIDs", LDHeader->NumberOfImpid); + W.printHex("OffsetToImportFileIDs", LDHeader->OffsetToImpid); + W.printNumber("LengthOfStringTable", LDHeader->LengthOfStrTbl); + W.printHex("OffsetToStringTable", LDHeader->OffsetToStrTbl); + }; + + if (Obj.is64Bit()) { + const LoaderSectionHeader64 *LoaderSec64 = + reinterpret_cast<const LoaderSectionHeader64 *>(LoaderSectionAddr); + PrintLoadSecHeaderCommon(LoaderSec64); + W.printHex("OffsetToSymbolTable", LoaderSec64->OffsetToSymTbl); + W.printHex("OffsetToRelocationEntries", LoaderSec64->OffsetToRelEnt); + } else { + const LoaderSectionHeader32 *LoaderSec32 = + reinterpret_cast<const LoaderSectionHeader32 *>(LoaderSectionAddr); + PrintLoadSecHeaderCommon(LoaderSec32); + } +} + +const EnumEntry<XCOFF::StorageClass> SymStorageClass[] = { +#define ECase(X) \ + { #X, XCOFF::X } + ECase(C_NULL), ECase(C_AUTO), ECase(C_EXT), ECase(C_STAT), + ECase(C_REG), ECase(C_EXTDEF), ECase(C_LABEL), ECase(C_ULABEL), + ECase(C_MOS), ECase(C_ARG), ECase(C_STRTAG), ECase(C_MOU), + ECase(C_UNTAG), ECase(C_TPDEF), ECase(C_USTATIC), ECase(C_ENTAG), + ECase(C_MOE), ECase(C_REGPARM), ECase(C_FIELD), ECase(C_BLOCK), + ECase(C_FCN), ECase(C_EOS), ECase(C_FILE), ECase(C_LINE), + ECase(C_ALIAS), ECase(C_HIDDEN), ECase(C_HIDEXT), ECase(C_BINCL), + ECase(C_EINCL), ECase(C_INFO), ECase(C_WEAKEXT), ECase(C_DWARF), + ECase(C_GSYM), ECase(C_LSYM), ECase(C_PSYM), ECase(C_RSYM), + ECase(C_RPSYM), ECase(C_STSYM), ECase(C_TCSYM), ECase(C_BCOMM), + ECase(C_ECOML), ECase(C_ECOMM), ECase(C_DECL), ECase(C_ENTRY), + ECase(C_FUN), ECase(C_BSTAT), ECase(C_ESTAT), ECase(C_GTLS), + ECase(C_STTLS), ECase(C_EFCN) +#undef ECase +}; + +template <typename LoaderSectionSymbolEntry, typename LoaderSectionHeader> +void XCOFFDumper::printLoaderSectionSymbolsHelper(uintptr_t LoaderSectionAddr) { + const LoaderSectionHeader *LoadSecHeader = + reinterpret_cast<const LoaderSectionHeader *>(LoaderSectionAddr); + const LoaderSectionSymbolEntry *LoadSecSymEntPtr = + reinterpret_cast<LoaderSectionSymbolEntry *>( + LoaderSectionAddr + uintptr_t(LoadSecHeader->getOffsetToSymTbl())); + + for (uint32_t i = 0; i < LoadSecHeader->NumberOfSymTabEnt; + ++i, ++LoadSecSymEntPtr) { + if (Error E = Binary::checkOffset( + Obj.getMemoryBufferRef(), + LoaderSectionAddr + uintptr_t(LoadSecHeader->getOffsetToSymTbl()) + + (i * sizeof(LoaderSectionSymbolEntry)), + sizeof(LoaderSectionSymbolEntry))) { + reportUniqueWarning(std::move(E)); + return; + } + + Expected<StringRef> SymbolNameOrErr = + LoadSecSymEntPtr->getSymbolName(LoadSecHeader); + if (!SymbolNameOrErr) { + reportUniqueWarning(SymbolNameOrErr.takeError()); + return; + } + + DictScope DS(W, "Symbol"); + W.printString("Name", SymbolNameOrErr.get()); + W.printHex("Virtual Address", LoadSecSymEntPtr->Value); + W.printNumber("SectionNum", LoadSecSymEntPtr->SectionNumber); + W.printHex("SymbolType", LoadSecSymEntPtr->SymbolType); + W.printEnum("StorageClass", + static_cast<uint8_t>(LoadSecSymEntPtr->StorageClass), + ArrayRef(SymStorageClass)); + W.printHex("ImportFileID", LoadSecSymEntPtr->ImportFileID); + W.printNumber("ParameterTypeCheck", LoadSecSymEntPtr->ParameterTypeCheck); + } +} + +void XCOFFDumper::printLoaderSectionSymbols(uintptr_t LoaderSectionAddr) { + DictScope DS(W, "Loader Section Symbols"); if (Obj.is64Bit()) - printRelocations<XCOFFSectionHeader64, XCOFFRelocation64>(Obj.sections64()); + printLoaderSectionSymbolsHelper<LoaderSectionSymbolEntry64, + LoaderSectionHeader64>(LoaderSectionAddr); else - printRelocations<XCOFFSectionHeader32, XCOFFRelocation32>(Obj.sections32()); + printLoaderSectionSymbolsHelper<LoaderSectionSymbolEntry32, + LoaderSectionHeader32>(LoaderSectionAddr); } const EnumEntry<XCOFF::RelocationType> RelocationTypeNameclass[] = { @@ -148,6 +283,176 @@ const EnumEntry<XCOFF::RelocationType> RelocationTypeNameclass[] = { #undef ECase }; +// From the XCOFF specification: there are five implicit external symbols, one +// each for the .text, .data, .bss, .tdata, and .tbss sections. These symbols +// are referenced from the relocation table entries using symbol table index +// values 0, 1, 2, -1, and -2, respectively. +static const char *getImplicitLoaderSectionSymName(int SymIndx) { + switch (SymIndx) { + default: + return "Unkown Symbol Name"; + case -2: + return ".tbss"; + case -1: + return ".tdata"; + case 0: + return ".text"; + case 1: + return ".data"; + case 2: + return ".bss"; + } +} + +template <typename LoadSectionRelocTy> +void XCOFFDumper::printLoaderSectionRelocationEntry( + LoadSectionRelocTy *LoaderSecRelEntPtr, StringRef SymbolName) { + uint16_t Type = LoaderSecRelEntPtr->Type; + if (opts::ExpandRelocs) { + DictScope DS(W, "Relocation"); + auto IsRelocationSigned = [](uint8_t Info) { + return Info & XCOFF::XR_SIGN_INDICATOR_MASK; + }; + auto IsFixupIndicated = [](uint8_t Info) { + return Info & XCOFF::XR_FIXUP_INDICATOR_MASK; + }; + auto GetRelocatedLength = [](uint8_t Info) { + // The relocation encodes the bit length being relocated minus 1. Add + // back + // the 1 to get the actual length being relocated. + return (Info & XCOFF::XR_BIASED_LENGTH_MASK) + 1; + }; + + uint8_t Info = Type >> 8; + W.printHex("Virtual Address", LoaderSecRelEntPtr->VirtualAddr); + W.printNumber("Symbol", SymbolName, LoaderSecRelEntPtr->SymbolIndex); + W.printString("IsSigned", IsRelocationSigned(Info) ? "Yes" : "No"); + W.printNumber("FixupBitValue", IsFixupIndicated(Info) ? 1 : 0); + W.printNumber("Length", GetRelocatedLength(Info)); + W.printEnum("Type", static_cast<uint8_t>(Type), + ArrayRef(RelocationTypeNameclass)); + W.printNumber("SectionNumber", LoaderSecRelEntPtr->SectionNum); + } else { + W.startLine() << format_hex(LoaderSecRelEntPtr->VirtualAddr, + Obj.is64Bit() ? 18 : 10) + << " " << format_hex(Type, 6) << " (" + << XCOFF::getRelocationTypeString( + static_cast<XCOFF::RelocationType>(Type)) + << ")" << format_decimal(LoaderSecRelEntPtr->SectionNum, 8) + << " " << SymbolName << " (" + << LoaderSecRelEntPtr->SymbolIndex << ")\n"; + } +} + +template <typename LoaderSectionHeader, typename LoaderSectionSymbolEntry, + typename LoaderSectionRelocationEntry> +void XCOFFDumper::printLoaderSectionRelocationEntriesHelper( + uintptr_t LoaderSectionAddr) { + const LoaderSectionHeader *LoaderSec = + reinterpret_cast<const LoaderSectionHeader *>(LoaderSectionAddr); + const LoaderSectionRelocationEntry *LoaderSecRelEntPtr = + reinterpret_cast<const LoaderSectionRelocationEntry *>( + LoaderSectionAddr + uintptr_t(LoaderSec->getOffsetToRelEnt())); + + if (!opts::ExpandRelocs) + W.startLine() << center_justify("Vaddr", Obj.is64Bit() ? 18 : 10) + << center_justify("Type", 15) << right_justify("SecNum", 8) + << center_justify("SymbolName (Index) ", 24) << "\n"; + + for (uint32_t i = 0; i < LoaderSec->NumberOfRelTabEnt; + ++i, ++LoaderSecRelEntPtr) { + StringRef SymbolName; + if (LoaderSecRelEntPtr->SymbolIndex >= FirstSymIdxOfLoaderSec) { + // Because there are implicit symbol index values (-2, -1, 0, 1, 2), + // LoaderSecRelEnt.SymbolIndex - FirstSymIdxOfLoaderSec will get the + // real symbol from the symbol table. + const uint64_t SymOffset = + (LoaderSecRelEntPtr->SymbolIndex - FirstSymIdxOfLoaderSec) * + sizeof(LoaderSectionSymbolEntry); + const LoaderSectionSymbolEntry *LoaderSecRelSymEntPtr = + reinterpret_cast<LoaderSectionSymbolEntry *>( + LoaderSectionAddr + uintptr_t(LoaderSec->getOffsetToSymTbl()) + + SymOffset); + + Expected<StringRef> SymbolNameOrErr = + LoaderSecRelSymEntPtr->getSymbolName(LoaderSec); + if (!SymbolNameOrErr) { + reportUniqueWarning(SymbolNameOrErr.takeError()); + return; + } + SymbolName = SymbolNameOrErr.get(); + } else + SymbolName = + getImplicitLoaderSectionSymName(LoaderSecRelEntPtr->SymbolIndex); + + printLoaderSectionRelocationEntry(LoaderSecRelEntPtr, SymbolName); + } +} + +void XCOFFDumper::printLoaderSectionRelocationEntries( + uintptr_t LoaderSectionAddr) { + DictScope DS(W, "Loader Section Relocations"); + + if (Obj.is64Bit()) + printLoaderSectionRelocationEntriesHelper<LoaderSectionHeader64, + LoaderSectionSymbolEntry64, + LoaderSectionRelocationEntry64>( + LoaderSectionAddr); + else + printLoaderSectionRelocationEntriesHelper<LoaderSectionHeader32, + LoaderSectionSymbolEntry32, + LoaderSectionRelocationEntry32>( + LoaderSectionAddr); +} + +template <typename T> +void XCOFFDumper::printExceptionSectionEntry(const T &ExceptionSectEnt) const { + if (ExceptionSectEnt.getReason()) + W.printHex("Trap Instr Addr", ExceptionSectEnt.getTrapInstAddr()); + else { + uint32_t SymIdx = ExceptionSectEnt.getSymbolIndex(); + Expected<StringRef> ErrOrSymbolName = Obj.getSymbolNameByIndex(SymIdx); + if (Error E = ErrOrSymbolName.takeError()) { + reportUniqueWarning(std::move(E)); + return; + } + StringRef SymName = *ErrOrSymbolName; + + W.printNumber("Symbol", SymName, SymIdx); + } + W.printNumber("LangID", ExceptionSectEnt.getLangID()); + W.printNumber("Reason", ExceptionSectEnt.getReason()); +} + +template <typename T> void XCOFFDumper::printExceptionSectionEntries() const { + Expected<ArrayRef<T>> ExceptSectEntsOrErr = Obj.getExceptionEntries<T>(); + if (Error E = ExceptSectEntsOrErr.takeError()) { + reportUniqueWarning(std::move(E)); + return; + } + ArrayRef<T> ExceptSectEnts = *ExceptSectEntsOrErr; + + DictScope DS(W, "Exception section"); + if (ExceptSectEnts.empty()) + return; + for (auto &Ent : ExceptSectEnts) + printExceptionSectionEntry(Ent); +} + +void XCOFFDumper::printExceptionSection() { + if (Obj.is64Bit()) + printExceptionSectionEntries<ExceptionSectionEntry64>(); + else + printExceptionSectionEntries<ExceptionSectionEntry32>(); +} + +void XCOFFDumper::printRelocations() { + if (Obj.is64Bit()) + printRelocations<XCOFFSectionHeader64, XCOFFRelocation64>(Obj.sections64()); + else + printRelocations<XCOFFSectionHeader32, XCOFFRelocation32>(Obj.sections32()); +} + template <typename RelTy> void XCOFFDumper::printRelocation(RelTy Reloc) { Expected<StringRef> ErrOrSymbolName = Obj.getSymbolNameByIndex(Reloc.SymbolIndex); @@ -164,8 +469,7 @@ template <typename RelTy> void XCOFFDumper::printRelocation(RelTy Reloc) { W.printString("IsSigned", Reloc.isRelocationSigned() ? "Yes" : "No"); W.printNumber("FixupBitValue", Reloc.isFixupIndicated() ? 1 : 0); W.printNumber("Length", Reloc.getRelocatedLength()); - W.printEnum("Type", (uint8_t)Reloc.Type, - makeArrayRef(RelocationTypeNameclass)); + W.printEnum("Type", (uint8_t)Reloc.Type, ArrayRef(RelocationTypeNameclass)); } else { raw_ostream &OS = W.startLine(); OS << W.hex(Reloc.VirtualAddress) << " " << RelocName << " " << SymbolName @@ -230,10 +534,10 @@ void XCOFFDumper::printFileAuxEnt(const XCOFFFileAuxEnt *AuxEntPtr) { Obj.getSymbolIndex(reinterpret_cast<uintptr_t>(AuxEntPtr))); W.printString("Name", FileName); W.printEnum("Type", static_cast<uint8_t>(AuxEntPtr->Type), - makeArrayRef(FileStringType)); + ArrayRef(FileStringType)); if (Obj.is64Bit()) { W.printEnum("Auxiliary Type", static_cast<uint8_t>(AuxEntPtr->AuxType), - makeArrayRef(SymAuxType)); + ArrayRef(SymAuxType)); } } @@ -271,14 +575,14 @@ void XCOFFDumper::printCsectAuxEnt(XCOFFCsectAuxRef AuxEntRef) { // Print out symbol alignment and type. W.printNumber("SymbolAlignmentLog2", AuxEntRef.getAlignmentLog2()); W.printEnum("SymbolType", AuxEntRef.getSymbolType(), - makeArrayRef(CsectSymbolTypeClass)); + ArrayRef(CsectSymbolTypeClass)); W.printEnum("StorageMappingClass", static_cast<uint8_t>(AuxEntRef.getStorageMappingClass()), - makeArrayRef(CsectStorageMappingClass)); + ArrayRef(CsectStorageMappingClass)); if (Obj.is64Bit()) { W.printEnum("Auxiliary Type", static_cast<uint8_t>(XCOFF::AUX_CSECT), - makeArrayRef(SymAuxType)); + ArrayRef(SymAuxType)); } else { W.printHex("StabInfoIndex", AuxEntRef.getStabInfoIndex32()); W.printHex("StabSectNum", AuxEntRef.getStabSectNum32()); @@ -310,7 +614,7 @@ void XCOFFDumper::printExceptionAuxEnt(const XCOFFExceptionAuxEnt *AuxEntPtr) { W.printHex("SizeOfFunction", AuxEntPtr->SizeOfFunction); W.printNumber("SymbolIndexOfNextBeyond", AuxEntPtr->SymIdxOfNextBeyond); W.printEnum("Auxiliary Type", static_cast<uint8_t>(AuxEntPtr->AuxType), - makeArrayRef(SymAuxType)); + ArrayRef(SymAuxType)); } void XCOFFDumper::printFunctionAuxEnt(const XCOFFFunctionAuxEnt32 *AuxEntPtr) { @@ -335,7 +639,7 @@ void XCOFFDumper::printFunctionAuxEnt(const XCOFFFunctionAuxEnt64 *AuxEntPtr) { W.printHex("PointerToLineNum", AuxEntPtr->PtrToLineNum); W.printNumber("SymbolIndexOfNextBeyond", AuxEntPtr->SymIdxOfNextBeyond); W.printEnum("Auxiliary Type", static_cast<uint8_t>(AuxEntPtr->AuxType), - makeArrayRef(SymAuxType)); + ArrayRef(SymAuxType)); } void XCOFFDumper::printBlockAuxEnt(const XCOFFBlockAuxEnt32 *AuxEntPtr) { @@ -356,7 +660,7 @@ void XCOFFDumper::printBlockAuxEnt(const XCOFFBlockAuxEnt64 *AuxEntPtr) { Obj.getSymbolIndex(reinterpret_cast<uintptr_t>(AuxEntPtr))); W.printHex("LineNumber", AuxEntPtr->LineNum); W.printEnum("Auxiliary Type", static_cast<uint8_t>(AuxEntPtr->AuxType), - makeArrayRef(SymAuxType)); + ArrayRef(SymAuxType)); } template <typename T> @@ -368,28 +672,9 @@ void XCOFFDumper::printSectAuxEntForDWARF(const T *AuxEntPtr) { W.printNumber("NumberOfRelocEntries", AuxEntPtr->NumberOfRelocEnt); if (Obj.is64Bit()) W.printEnum("Auxiliary Type", static_cast<uint8_t>(XCOFF::AUX_SECT), - makeArrayRef(SymAuxType)); + ArrayRef(SymAuxType)); } -const EnumEntry<XCOFF::StorageClass> SymStorageClass[] = { -#define ECase(X) \ - { #X, XCOFF::X } - ECase(C_NULL), ECase(C_AUTO), ECase(C_EXT), ECase(C_STAT), - ECase(C_REG), ECase(C_EXTDEF), ECase(C_LABEL), ECase(C_ULABEL), - ECase(C_MOS), ECase(C_ARG), ECase(C_STRTAG), ECase(C_MOU), - ECase(C_UNTAG), ECase(C_TPDEF), ECase(C_USTATIC), ECase(C_ENTAG), - ECase(C_MOE), ECase(C_REGPARM), ECase(C_FIELD), ECase(C_BLOCK), - ECase(C_FCN), ECase(C_EOS), ECase(C_FILE), ECase(C_LINE), - ECase(C_ALIAS), ECase(C_HIDDEN), ECase(C_HIDEXT), ECase(C_BINCL), - ECase(C_EINCL), ECase(C_INFO), ECase(C_WEAKEXT), ECase(C_DWARF), - ECase(C_GSYM), ECase(C_LSYM), ECase(C_PSYM), ECase(C_RSYM), - ECase(C_RPSYM), ECase(C_STSYM), ECase(C_TCSYM), ECase(C_BCOMM), - ECase(C_ECOML), ECase(C_ECOMM), ECase(C_DECL), ECase(C_ENTRY), - ECase(C_FUN), ECase(C_BSTAT), ECase(C_ESTAT), ECase(C_GTLS), - ECase(C_STTLS), ECase(C_EFCN) -#undef ECase -}; - static StringRef GetSymbolValueName(XCOFF::StorageClass SC) { switch (SC) { case XCOFF::C_EXT: @@ -447,7 +732,7 @@ static void printUnexpectedRawAuxEnt(ScopedPrinter &W, uintptr_t AuxAddress) { ArrayRef<uint8_t>( reinterpret_cast<const uint8_t *>(AuxAddress), XCOFF::SymbolTableEntrySize), - None, XCOFF::SymbolTableEntrySize) + std::nullopt, XCOFF::SymbolTableEntrySize) << "\n"; } @@ -475,14 +760,14 @@ void XCOFFDumper::printSymbol(const SymbolRef &S) { W.printString("Section", SectionName); if (SymbolClass == XCOFF::C_FILE) { W.printEnum("Source Language ID", SymbolEntRef.getLanguageIdForCFile(), - makeArrayRef(CFileLangIdClass)); + ArrayRef(CFileLangIdClass)); W.printEnum("CPU Version ID", SymbolEntRef.getCPUTypeIddForCFile(), - makeArrayRef(CFileCpuIdClass)); + ArrayRef(CFileCpuIdClass)); } else W.printHex("Type", SymbolEntRef.getSymbolType()); W.printEnum("StorageClass", static_cast<uint8_t>(SymbolClass), - makeArrayRef(SymStorageClass)); + ArrayRef(SymStorageClass)); W.printNumber("NumberOfAuxEntries", NumberOfAuxEntries); if (NumberOfAuxEntries == 0) @@ -492,7 +777,7 @@ void XCOFFDumper::printSymbol(const SymbolRef &S) { if (NumberOfAuxEntries > 1) reportUniqueWarning("the " + enumToString(static_cast<uint8_t>(SymbolClass), - makeArrayRef(SymStorageClass)) + + ArrayRef(SymStorageClass)) + " symbol at index " + Twine(SymbolIdx) + " should not have more than 1 " "auxiliary entry"); @@ -519,22 +804,13 @@ void XCOFFDumper::printSymbol(const SymbolRef &S) { case XCOFF::C_EXT: case XCOFF::C_WEAKEXT: case XCOFF::C_HIDEXT: { - if (!SymbolEntRef.isFunction() && NumberOfAuxEntries > 1) - reportUniqueWarning("the non-function " + - enumToString(static_cast<uint8_t>(SymbolClass), - makeArrayRef(SymStorageClass)) + - " symbol at index " + Twine(SymbolIdx) + - " should have only 1 auxiliary entry, i.e. the CSECT " - "auxiliary entry"); - // For 32-bit objects, print the function auxiliary symbol table entry. The // last one must be a CSECT auxiliary entry. // For 64-bit objects, both a function auxiliary entry and an exception // auxiliary entry may appear, print them in the loop and skip printing the // CSECT auxiliary entry, which will be printed outside the loop. for (int I = 1; I <= NumberOfAuxEntries; I++) { - if ((I == NumberOfAuxEntries && !Obj.is64Bit()) || - !SymbolEntRef.isFunction()) + if (I == NumberOfAuxEntries && !Obj.is64Bit()) break; uintptr_t AuxAddress = XCOFFObjectFile::getAdvancedSymbolEntryAddress( @@ -921,7 +1197,7 @@ void XCOFFDumper::printSectionHeaders(ArrayRef<T> Sections) { if (Sec.isReservedSectionType()) W.printHex("Flags", "Reserved", SectionType); else - W.printEnum("Type", SectionType, makeArrayRef(SectionTypeFlagsNames)); + W.printEnum("Type", SectionType, ArrayRef(SectionTypeFlagsNames)); } if (opts::SectionRelocations) diff --git a/contrib/llvm-project/llvm/tools/llvm-readobj/llvm-readobj.cpp b/contrib/llvm-project/llvm/tools/llvm-readobj/llvm-readobj.cpp index e1ebbeb41f28..a11de35fcd76 100644 --- a/contrib/llvm-project/llvm/tools/llvm-readobj/llvm-readobj.cpp +++ b/contrib/llvm-project/llvm/tools/llvm-readobj/llvm-readobj.cpp @@ -21,7 +21,6 @@ #include "llvm-readobj.h" #include "ObjDumper.h" #include "WindowsResourceDumper.h" -#include "llvm/ADT/Optional.h" #include "llvm/DebugInfo/CodeView/GlobalTypeTableBuilder.h" #include "llvm/DebugInfo/CodeView/MergingTypeTableBuilder.h" #include "llvm/MC/TargetRegistry.h" @@ -62,11 +61,14 @@ enum ID { #undef OPTION }; -#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE; +#define PREFIX(NAME, VALUE) \ + static constexpr StringLiteral NAME##_init[] = VALUE; \ + static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \ + std::size(NAME##_init) - 1); #include "Opts.inc" #undef PREFIX -const opt::OptTable::Info InfoTable[] = { +static constexpr opt::OptTable::Info InfoTable[] = { #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ HELPTEXT, METAVAR, VALUES) \ { \ @@ -78,9 +80,11 @@ const opt::OptTable::Info InfoTable[] = { #undef OPTION }; -class ReadobjOptTable : public opt::OptTable { +class ReadobjOptTable : public opt::GenericOptTable { public: - ReadobjOptTable() : OptTable(InfoTable) { setGroupedShortOptions(true); } + ReadobjOptTable() : opt::GenericOptTable(InfoTable) { + setGroupedShortOptions(true); + } }; enum OutputFormatTy { bsd, sysv, posix, darwin, just_symbols }; @@ -162,6 +166,10 @@ static bool COFFTLSDirectory; // XCOFF specific options. static bool XCOFFAuxiliaryHeader; +static bool XCOFFLoaderSectionHeader; +static bool XCOFFLoaderSectionSymbol; +static bool XCOFFLoaderSectionRelocation; +static bool XCOFFExceptionSection; OutputStyleTy Output = OutputStyleTy::LLVM; static std::vector<std::string> InputFilenames; @@ -302,6 +310,11 @@ static void parseOptions(const opt::InputArgList &Args) { // XCOFF specific options. opts::XCOFFAuxiliaryHeader = Args.hasArg(OPT_auxiliary_header); + opts::XCOFFLoaderSectionHeader = Args.hasArg(OPT_loader_section_header); + opts::XCOFFLoaderSectionSymbol = Args.hasArg(OPT_loader_section_symbols); + opts::XCOFFLoaderSectionRelocation = + Args.hasArg(OPT_loader_section_relocations); + opts::XCOFFExceptionSection = Args.hasArg(OPT_exception_section); opts::InputFilenames = Args.getAllArgValues(OPT_INPUT); } @@ -357,7 +370,7 @@ static void dumpObject(ObjectFile &Obj, ScopedPrinter &Writer, toString(std::move(ContentErr)); ObjDumper *Dumper; - Optional<SymbolComparator> SymComp; + std::optional<SymbolComparator> SymComp; Expected<std::unique_ptr<ObjDumper>> DumperOrErr = createDumper(Obj, Writer); if (!DumperOrErr) reportError(DumperOrErr.takeError(), FileStr); @@ -395,6 +408,8 @@ static void dumpObject(ObjectFile &Obj, ScopedPrinter &Writer, if (opts::FileHeaders) Dumper->printFileHeaders(); + // Auxiliary header in XOCFF is right after the file header, so print the data + // here. if (Obj.isXCOFF() && opts::XCOFFAuxiliaryHeader) Dumper->printAuxiliaryHeader(); @@ -502,6 +517,18 @@ static void dumpObject(ObjectFile &Obj, ScopedPrinter &Writer, if (opts::CGProfile) Dumper->printCGProfile(); } + + if (Obj.isXCOFF()) { + if (opts::XCOFFLoaderSectionHeader || opts::XCOFFLoaderSectionSymbol || + opts::XCOFFLoaderSectionRelocation) + Dumper->printLoaderSection(opts::XCOFFLoaderSectionHeader, + opts::XCOFFLoaderSectionSymbol, + opts::XCOFFLoaderSectionRelocation); + + if (opts::XCOFFExceptionSection) + Dumper->printExceptionSection(); + } + if (opts::PrintStackMap) Dumper->printStackMap(); if (opts::PrintStackSizes) @@ -605,7 +632,7 @@ std::unique_ptr<ScopedPrinter> createWriter() { return std::make_unique<ScopedPrinter>(fouts()); } -int main(int argc, char *argv[]) { +int llvm_readobj_main(int argc, char **argv) { InitLLVM X(argc, argv); BumpPtrAllocator A; StringSaver Saver(A); diff --git a/contrib/llvm-project/llvm/tools/llvm-readobj/llvm-readobj.h b/contrib/llvm-project/llvm/tools/llvm-readobj/llvm-readobj.h index 989cd0aba6c0..5a9fe28d883e 100644 --- a/contrib/llvm-project/llvm/tools/llvm-readobj/llvm-readobj.h +++ b/contrib/llvm-project/llvm/tools/llvm-readobj/llvm-readobj.h @@ -50,6 +50,6 @@ extern OutputStyleTy Output; { #enum, ns::enum } #define LLVM_READOBJ_ENUM_CLASS_ENT(enum_class, enum) \ - { #enum, std::underlying_type<enum_class>::type(enum_class::enum) } + { #enum, std::underlying_type_t<enum_class>(enum_class::enum) } #endif |
