Index: llvm/test/tools/obj2yaml/elf-output-indentation.yaml =================================================================== --- /dev/null +++ llvm/test/tools/obj2yaml/elf-output-indentation.yaml @@ -0,0 +1,77 @@ +## obj2yaml tries to optimize indentations between keys and +## values to make an output nicer. +## In this test we demonstrate the output produced. + +# RUN: yaml2obj %s -o %t +# RUN: obj2yaml %t | FileCheck %s --strict-whitespace --match-full-lines + +# CHECK:--- !ELF +# CHECK-NEXT:FileHeader: +# CHECK-NEXT: Class: ELFCLASS64 +# CHECK-NEXT: Data: ELFDATA2LSB +# CHECK-NEXT: Type: ET_REL +# CHECK-NEXT: Machine: EM_X86_64 +# CHECK-NEXT:Sections: +# CHECK-NEXT: - Name: .text +# CHECK-NEXT: Type: SHT_PROGBITS +# CHECK-NEXT: - Name: .data +# CHECK-NEXT: Type: SHT_PROGBITS +# CHECK-NEXT: AddressAlign: 0x0000000000000001 +# CHECK-NEXT: - Name: .rela.text +# CHECK-NEXT: Type: SHT_RELA +# CHECK-NEXT: Link: .symtab +# CHECK-NEXT: EntSize: 0x0000000000000018 +# CHECK-NEXT: Info: .text +# CHECK-NEXT: Relocations: +# CHECK-NEXT: - Offset: 0x0000000000000000 +# CHECK-NEXT: Type: R_X86_64_PC32 +# CHECK-NEXT: - Name: .rela.text2 +# CHECK-NEXT: Type: SHT_RELA +# CHECK-NEXT: Link: .symtab +# CHECK-NEXT: EntSize: 0x0000000000000018 +# CHECK-NEXT:Symbols: [] +# CHECK-NEXT:DynamicSymbols: +# CHECK-NEXT: - Name: dynamic +# CHECK-NEXT: Binding: STB_GLOBAL +# CHECK-NEXT: Value: 0x0000000012345678 +# CHECK-NEXT: - Name: both +# CHECK-NEXT:... + +## Use an arbitrary YAML with different fields. + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: .text + Type: SHT_PROGBITS + - Name: .data + Type: SHT_PROGBITS + AddressAlign: 0x1 + - Name: .rela.text + Type: SHT_RELA + Link: .symtab + EntSize: 0x0000000000000018 + Info: .text + Relocations: + - Offset: 0x0000000000000000 + Type: R_X86_64_PC32 + - Name: .rela.text2 + Type: SHT_RELA + Link: .symtab + EntSize: 0x0000000000000018 + Relocations: [] +ProgramHeaders: + - Type: PT_LOAD + VAddr: 0x100 + Sections: + - Section: .text +Symbols: [] +DynamicSymbols: + - Name: dynamic + Binding: STB_GLOBAL + Value: 0x0000000012345678 + - Name: both Index: llvm/tools/obj2yaml/obj2yaml.cpp =================================================================== --- llvm/tools/obj2yaml/obj2yaml.cpp +++ llvm/tools/obj2yaml/obj2yaml.cpp @@ -17,6 +17,51 @@ using namespace llvm; using namespace llvm::object; +std::string postProcess(StringRef In) { + struct LineInfo { + size_t KeyLen; + size_t Colon; + StringRef Line; + }; + + struct ScanState { + size_t MaxKey = 0; + std::vector Lines; + } State; + + std::string Out; + auto FlushState = [&]() { + for (const LineInfo &LI : State.Lines) { + Out += LI.Line.take_front(LI.Colon + 1).str(); + Out += std::string(State.MaxKey - LI.KeyLen + 1, ' '); + Out += LI.Line.drop_front(LI.Colon + 1).ltrim(' '); + Out += '\n'; + } + State = {}; + }; + + SmallVector Lines; + In.split(Lines, '\n'); + + for (StringRef Line : Lines) { + size_t Colon = Line.find(':'); + if (Colon == StringRef::npos || Colon == Line.size() - 1) { + FlushState(); + Out += Line.str() + '\n'; + continue; + } + + if (Line.find('-') != StringRef::npos) + FlushState(); + + StringRef Key = Line.take_front(Colon).ltrim("- "); + if (Key.size() > State.MaxKey) + State.MaxKey = Key.size(); + State.Lines.push_back({Key.size(), Colon, Line}); + } + return Out; +} + static Error dumpObject(const ObjectFile &Obj) { if (Obj.isCOFF()) return errorCodeToError(coff2yaml(outs(), cast(Obj))); @@ -24,8 +69,15 @@ if (Obj.isXCOFF()) return errorCodeToError(xcoff2yaml(outs(), cast(Obj))); - if (Obj.isELF()) - return elf2yaml(outs(), Obj); + if (Obj.isELF()) { + SmallString<0> Storage; + raw_svector_ostream OS(Storage); + if (Error Err = elf2yaml(OS, Obj)) + return Err; + std::string Formatted = postProcess(Storage); + outs().write(Formatted.data(), Formatted.size()); + return Error::success(); + } if (Obj.isWasm()) return errorCodeToError(wasm2yaml(outs(), cast(Obj)));