[llvm] r178679 - Implements low-level object file format specific output for COFF and
Brendan Kirby
brendan.kirby at imgtec.com
Thu Apr 4 18:43:20 PDT 2013
It looks like the "LLVM :: tools__llvm-readobj__sections.test" and "LLVM
:: tools__llvm-readobj__sections-ext.test" tests for MACHO have started
failing after r178688 on MIPS. I think this is due to how the tests
were written. It looks like the llvm-readobj command dumps it's whole
buffer as hex and the test expects the buffer to be zeroed out.
However, the buffer is a string. So, everything after the first zero
can be anything.
Here is the URL to the first time this failed on MIPS:
http://lab.llvm.org:8011/builders/llvm-mips-linux/builds/1830
and here is the error for the "LLVM ::
tools__llvm-readobj__sections.test" test:
Exit Code: 1
Command Output (stderr):
--
/scratch/bb-slaves/mipsswbrd002/llvm-mips-linux/llvm/test/tools/llvm-readobj/sections.test:82:13:
error: expected string not found in input
MACHO-NEXT: Name: __text (5F 5F 74 65 78 74 00 00 00 00 00 00 00 00 00 00)
^
<stdin>:9:2: note: scanning from here
Name: __text (5F 5F 74 65 78 74 00 00 00 00 00 00 00 59 E4 60)
^
--
Notice that the last three bytes are not zeros. Can the output for
llvm-readobj be changed to fix this?
Thanks,
Brendan
On 04/03/13 11:31, Eric Christopher wrote:
> Author: echristo
> Date: Wed Apr 3 13:31:38 2013
> New Revision: 178679
>
> URL: http://llvm.org/viewvc/llvm-project?rev=178679&view=rev
> Log:
> Implements low-level object file format specific output for COFF and
> ELF with support for:
>
> - File headers
> - Section headers + data
> - Relocations
> - Symbols
> - Unwind data (only COFF/Win64)
>
> The output format follows a few rules:
> - Values are almost always output one per line (as elf-dump/coff-dump already do). - Many values are translated to something readable (like enum names), with the raw value in parentheses.
> - Hex numbers are output in uppercase, prefixed with "0x".
> - Flags are sorted alphabetically.
> - Lists and groups are always delimited.
>
> Example output:
> ---------- snip ----------
> Sections [
> Section {
> Index: 1
> Name: .text (5)
> Type: SHT_PROGBITS (0x1)
> Flags [ (0x6)
> SHF_ALLOC (0x2)
> SHF_EXECINSTR (0x4)
> ]
> Address: 0x0
> Offset: 0x40
> Size: 33
> Link: 0
> Info: 0
> AddressAlignment: 16
> EntrySize: 0
> Relocations [
> 0x6 R_386_32 .rodata.str1.1 0x0
> 0xB R_386_PC32 puts 0x0
> 0x12 R_386_32 .rodata.str1.1 0x0
> 0x17 R_386_PC32 puts 0x0
> ]
> SectionData (
> 0000: 83EC04C7 04240000 0000E8FC FFFFFFC7 |.....$..........|
> 0010: 04240600 0000E8FC FFFFFF31 C083C404 |.$.........1....|
> 0020: C3 |.|
> )
> }
> ]
> ---------- snip ----------
>
> Relocations and symbols can be output standalone or together with the section header as displayed in the example.
> This feature set supports all tests in test/MC/COFF and test/MC/ELF (and I suspect all additional tests using elf-dump), making elf-dump and coff-dump deprecated.
>
> Patch by Nico Rieck!
>
> Added:
> llvm/trunk/test/tools/llvm-readobj/
> llvm/trunk/test/tools/llvm-readobj/Inputs/
> llvm/trunk/test/tools/llvm-readobj/Inputs/trivial.ll
> llvm/trunk/test/tools/llvm-readobj/Inputs/trivial.obj.coff-i386
> llvm/trunk/test/tools/llvm-readobj/Inputs/trivial.obj.coff-x86-64
> llvm/trunk/test/tools/llvm-readobj/Inputs/trivial.obj.elf-i386
> llvm/trunk/test/tools/llvm-readobj/Inputs/trivial.obj.elf-x86-64
> llvm/trunk/test/tools/llvm-readobj/Inputs/trivial.obj.macho-i386
> llvm/trunk/test/tools/llvm-readobj/Inputs/trivial.obj.macho-x86-64
> llvm/trunk/test/tools/llvm-readobj/file-headers.test
> llvm/trunk/test/tools/llvm-readobj/lit.local.cfg
> llvm/trunk/test/tools/llvm-readobj/relocations.test
> llvm/trunk/test/tools/llvm-readobj/sections-ext.test
> llvm/trunk/test/tools/llvm-readobj/sections.test
> llvm/trunk/test/tools/llvm-readobj/symbols.test
> llvm/trunk/tools/llvm-readobj/COFFDumper.cpp
> llvm/trunk/tools/llvm-readobj/ELFDumper.cpp
> llvm/trunk/tools/llvm-readobj/Error.cpp
> llvm/trunk/tools/llvm-readobj/Error.h
> llvm/trunk/tools/llvm-readobj/MachODumper.cpp
> llvm/trunk/tools/llvm-readobj/ObjDumper.cpp
> llvm/trunk/tools/llvm-readobj/ObjDumper.h
> llvm/trunk/tools/llvm-readobj/StreamWriter.cpp
> llvm/trunk/tools/llvm-readobj/StreamWriter.h
> Removed:
> llvm/trunk/tools/llvm-readobj/ELF.cpp
> Modified:
> llvm/trunk/include/llvm/Object/ELF.h
> llvm/trunk/include/llvm/Support/COFF.h
> llvm/trunk/include/llvm/Support/Win64EH.h
> llvm/trunk/test/MC/ELF/many-sections-2.s
> llvm/trunk/test/Object/readobj-elf-versioning.test
> llvm/trunk/test/Object/readobj-shared-object.test
> llvm/trunk/tools/llvm-readobj/CMakeLists.txt
> llvm/trunk/tools/llvm-readobj/LLVMBuild.txt
> llvm/trunk/tools/llvm-readobj/Makefile
> llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp
> llvm/trunk/tools/llvm-readobj/llvm-readobj.h
>
> Modified: llvm/trunk/include/llvm/Object/ELF.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/ELF.h?rev=178679&r1=178678&r2=178679&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/Object/ELF.h (original)
> +++ llvm/trunk/include/llvm/Object/ELF.h Wed Apr 3 13:31:38 2013
> @@ -790,6 +790,7 @@ public:
> uint64_t getNumSections() const;
> uint64_t getStringTableIndex() const;
> ELF::Elf64_Word getSymbolTableIndex(const Elf_Sym *symb) const;
> + const Elf_Ehdr *getElfHeader() const;
> const Elf_Shdr *getSection(const Elf_Sym *symb) const;
> const Elf_Shdr *getElfSection(section_iterator &It) const;
> const Elf_Sym *getElfSymbol(symbol_iterator &It) const;
> @@ -969,6 +970,12 @@ ELFObjectFile<ELFT>::getSection(const El
> }
>
> template<class ELFT>
> +const typename ELFObjectFile<ELFT>::Elf_Ehdr *
> +ELFObjectFile<ELFT>::getElfHeader() const {
> + return Header;
> +}
> +
> +template<class ELFT>
> const typename ELFObjectFile<ELFT>::Elf_Shdr *
> ELFObjectFile<ELFT>::getElfSection(section_iterator &It) const {
> llvm::object::DataRefImpl ShdrRef = It->getRawDataRefImpl();
>
> Modified: llvm/trunk/include/llvm/Support/COFF.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/COFF.h?rev=178679&r1=178678&r2=178679&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/Support/COFF.h (original)
> +++ llvm/trunk/include/llvm/Support/COFF.h Wed Apr 3 13:31:38 2013
> @@ -321,7 +321,8 @@ namespace COFF {
> IMAGE_COMDAT_SELECT_SAME_SIZE,
> IMAGE_COMDAT_SELECT_EXACT_MATCH,
> IMAGE_COMDAT_SELECT_ASSOCIATIVE,
> - IMAGE_COMDAT_SELECT_LARGEST
> + IMAGE_COMDAT_SELECT_LARGEST,
> + IMAGE_COMDAT_SELECT_NEWEST
> };
>
> // Auxiliary Symbol Formats
>
> Modified: llvm/trunk/include/llvm/Support/Win64EH.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/Win64EH.h?rev=178679&r1=178678&r2=178679&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/Support/Win64EH.h (original)
> +++ llvm/trunk/include/llvm/Support/Win64EH.h Wed Apr 3 13:31:38 2013
> @@ -106,12 +106,17 @@ struct UnwindInfo {
> return reinterpret_cast<void *>(&UnwindCodes[(NumCodes+1) & ~1]);
> }
>
> - /// \brief Return image-relativ offset of language-specific exception handler.
> - uint32_t getLanguageSpecificHandlerOffset() {
> - return *reinterpret_cast<uint32_t *>(getLanguageSpecificData());
> + /// \brief Return pointer to language specific data part of UnwindInfo.
> + const void *getLanguageSpecificData() const {
> + return reinterpret_cast<const void *>(&UnwindCodes[(NumCodes+1) & ~1]);
> }
>
> - /// \brief Set image-relativ offset of language-specific exception handler.
> + /// \brief Return image-relative offset of language-specific exception handler.
> + uint32_t getLanguageSpecificHandlerOffset() const {
> + return *reinterpret_cast<const uint32_t *>(getLanguageSpecificData());
> + }
> +
> + /// \brief Set image-relative offset of language-specific exception handler.
> void setLanguageSpecificHandlerOffset(uint32_t offset) {
> *reinterpret_cast<uint32_t *>(getLanguageSpecificData()) = offset;
> }
> @@ -126,6 +131,11 @@ struct UnwindInfo {
> RuntimeFunction *getChainedFunctionEntry() {
> return reinterpret_cast<RuntimeFunction *>(getLanguageSpecificData());
> }
> +
> + /// \brief Return pointer to chained unwind info.
> + const RuntimeFunction *getChainedFunctionEntry() const {
> + return reinterpret_cast<const RuntimeFunction *>(getLanguageSpecificData());
> + }
> };
>
>
>
> Modified: llvm/trunk/test/MC/ELF/many-sections-2.s
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/many-sections-2.s?rev=178679&r1=178678&r2=178679&view=diff
> ==============================================================================
> --- llvm/trunk/test/MC/ELF/many-sections-2.s (original)
> +++ llvm/trunk/test/MC/ELF/many-sections-2.s Wed Apr 3 13:31:38 2013
> @@ -1,5 +1,5 @@
> // RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o %t
> -// RUN: llvm-readobj %t | FileCheck %s
> +// RUN: llvm-readobj -s %t | FileCheck %s
>
> // CHECK: symtab_shndx
>
>
> Modified: llvm/trunk/test/Object/readobj-elf-versioning.test
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Object/readobj-elf-versioning.test?rev=178679&r1=178678&r2=178679&view=diff
> ==============================================================================
> --- llvm/trunk/test/Object/readobj-elf-versioning.test (original)
> +++ llvm/trunk/test/Object/readobj-elf-versioning.test Wed Apr 3 13:31:38 2013
> @@ -1,15 +1,46 @@
> -RUN: llvm-readobj %p/Inputs/elf-versioning-test.i386 \
> +RUN: llvm-readobj -dt %p/Inputs/elf-versioning-test.i386 \
> RUN: | FileCheck %s -check-prefix ELF
> -RUN: llvm-readobj %p/Inputs/elf-versioning-test.i386 \
> +RUN: llvm-readobj -dt %p/Inputs/elf-versioning-test.i386 \
> RUN: | FileCheck %s -check-prefix ELF32
> -RUN: llvm-readobj %p/Inputs/elf-versioning-test.x86_64 \
> +RUN: llvm-readobj -dt %p/Inputs/elf-versioning-test.x86_64 \
> RUN: | FileCheck %s -check-prefix ELF
> -RUN: llvm-readobj %p/Inputs/elf-versioning-test.x86_64 \
> +RUN: llvm-readobj -dt %p/Inputs/elf-versioning-test.x86_64 \
> RUN: | FileCheck %s -check-prefix ELF64
>
> -ELF: foo@@VER2 FUNC .text {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} global
> -ELF: foo at VER1 FUNC .text {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} global
> -ELF: unversioned_define FUNC .text {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} global
> +ELF: DynamicSymbols [
> +ELF: Symbol {
> +ELF: Name: foo@@VER2
> +ELF: Binding: Global
> +ELF: Type: Function
> +ELF: Section: .text
> +ELF: }
> +ELF: Symbol {
> +ELF: Name: foo at VER1
> +ELF: Binding: Global
> +ELF: Type: Function
> +ELF: Section: .text
> +ELF: }
> +ELF: Symbol {
> +ELF: Name: unversioned_define
> +ELF: Binding: Global
> +ELF: Type: Function
> +ELF: Section: .text
> +ELF: }
> +ELF: ]
>
> -ELF32: puts at GLIBC_2.0 FUNC {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} undef,global
> -ELF64: puts at GLIBC_2.2.5 FUNC {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} undef,global
> +ELF32: DynamicSymbols [
> +ELF32: Symbol {
> +ELF32: Name: puts at GLIBC_2.0
> +ELF32: Binding: Global
> +ELF32: Type: Function
> +ELF32: Section: (0x0)
> +ELF32: }
> +ELF32: ]
> +ELF64: DynamicSymbols [
> +ELF64: Symbol {
> +ELF64: Name: puts at GLIBC_2.2.5
> +ELF64: Binding: Global
> +ELF64: Type: Function
> +ELF64: Section: (0x0)
> +ELF64: }
> +ELF64: ]
>
> Modified: llvm/trunk/test/Object/readobj-shared-object.test
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Object/readobj-shared-object.test?rev=178679&r1=178678&r2=178679&view=diff
> ==============================================================================
> --- llvm/trunk/test/Object/readobj-shared-object.test (original)
> +++ llvm/trunk/test/Object/readobj-shared-object.test Wed Apr 3 13:31:38 2013
> @@ -1,92 +1,319 @@
> -RUN: llvm-readobj %p/Inputs/shared-object-test.elf-i386 \
> +RUN: llvm-readobj -s -t -dt -dynamic-table -needed-libs \
> +RUN: %p/Inputs/shared-object-test.elf-i386 \
> RUN: | FileCheck %s -check-prefix ELF
> -RUN: llvm-readobj %p/Inputs/shared-object-test.elf-i386 \
> +RUN: llvm-readobj -s -t -dt -dynamic-table -needed-libs \
> +RUN: %p/Inputs/shared-object-test.elf-i386 \
> RUN: | FileCheck %s -check-prefix ELF32
>
> -RUN: llvm-readobj %p/Inputs/shared-object-test.elf-x86-64 \
> +RUN: llvm-readobj -s -t -dt -dynamic-table -needed-libs \
> +RUN: %p/Inputs/shared-object-test.elf-x86-64 \
> RUN: | FileCheck %s -check-prefix ELF
> -RUN: llvm-readobj %p/Inputs/shared-object-test.elf-x86-64 \
> +RUN: llvm-readobj -s -t -dt -dynamic-table -needed-libs \
> +RUN: %p/Inputs/shared-object-test.elf-x86-64 \
> RUN: | FileCheck %s -check-prefix ELF64
>
> -ELF64:File Format : ELF64-x86-64
> -ELF64:Arch : x86_64
> -ELF64:Address Size: 64 bits
> -ELF64:Load Name : libfoo.so
> -
> -ELF32:File Format : ELF32-i386
> -ELF32:Arch : i386
> -ELF32:Address Size: 32 bits
> -ELF32:Load Name : libfoo.so
> -
> -ELF:Symbols:
> -ELF: Name Type Section Address Size FileOffset Flags
> -ELF: .dynsym DBG .dynsym {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} formatspecific
> -ELF: .dynstr DBG .dynstr {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} formatspecific
> -ELF: .text DBG .text {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} formatspecific
> -ELF: .eh_frame DBG .eh_frame {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} formatspecific
> -ELF: .tdata DBG .tdata {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} formatspecific
> -ELF: .dynamic DBG .dynamic {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} formatspecific
> -ELF: .got.plt DBG .got.plt {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} formatspecific
> -ELF: .data DBG .data {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} formatspecific
> -ELF: .bss DBG .bss {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} formatspecific
> -ELF: shared.ll FILE {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} absolute,formatspecific
> -ELF: local_func FUNC .text {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}}
> -ELF: _GLOBAL_OFFSET_TABLE_ DATA {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} absolute
> -ELF: _DYNAMIC DATA {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} absolute
> -ELF: common_sym DATA .bss {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} global
> -ELF: tls_sym DATA .tdata {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} global,threadlocal
> -ELF: defined_sym DATA .data {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} global
> -ELF: __bss_start ? {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} global,absolute
> -ELF: _end ? {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} global,absolute
> -ELF: global_func FUNC .text {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} global
> -ELF: _edata ? {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} global,absolute
> -ELF: Total: 21
> -
> -ELF:Dynamic Symbols:
> -ELF: Name Type Section Address Size FileOffset Flags
> -ELF: common_sym DATA .bss {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} global
> -ELF: tls_sym DATA .tdata {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} global,threadlocal
> -ELF: defined_sym DATA .data {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} global
> -ELF: __bss_start ? {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} global,absolute
> -ELF: _end ? {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} global,absolute
> -ELF: global_func FUNC .text {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} global
> -ELF: _edata ? {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} global,absolute
> -ELF: Total: {{[0-9a-f]+}}
> -
> -ELF:Sections:
> -ELF: Name Address Size Align Flags
> -ELF: {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} rodata
> -ELF: .hash {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} required,rodata
> -ELF: .dynsym {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} required,rodata
> -ELF: .dynstr {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} required,rodata
> -ELF: .text {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} text,{{(data,)?}}required
> -ELF: .eh_frame {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} data,required,rodata
> -ELF: .tdata {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} data,required
> -ELF: .dynamic {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} required
> -ELF: .got.plt {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} data,required
> -ELF: .data {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} data,required
> -ELF: .bss {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} bss,required,virtual,zeroinit
> -ELF: .shstrtab {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} rodata
> -ELF: .symtab {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} rodata
> -ELF: .strtab {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} rodata
> -ELF: Total: 14
> -
> -ELF:Dynamic section contains 9 entries
> -ELF: Tag Type Name/Value
> -ELF: 00000001 (NEEDED) Shared library: [libc.so.6]
> -ELF: 00000001 (NEEDED) Shared library: [libm.so.6]
> -ELF: 0000000e (SONAME) Library soname: [libfoo.so]
> -ELF: 00000004 (HASH) {{[0-9a-f]+}}
> -ELF: 00000005 (STRTAB) {{[0-9a-f]+}}
> -ELF: 00000006 (SYMTAB) {{[0-9a-f]+}}
> -ELF: 0000000a (STRSZ) {{[0-9]+}} (bytes)
> -ELF: 0000000b (SYMENT) {{[0-9]+}} (bytes)
> -ELF: 00000000 (NULL) 0x0
> -ELF: Total: 9
> -
> -ELF:Libraries needed:
> -ELF: libc.so.6
> -ELF: libm.so.6
> -ELF: Total: 2
> +ELF64: Format: ELF64-x86-64
> +ELF64: Arch: x86_64
> +ELF64: AddressSize: 64bit
> +ELF64: LoadName: libfoo.so
>
> +ELF32: Format: ELF32-i386
> +ELF32: Arch: i386
> +ELF32: AddressSize: 32bit
> +ELF32: LoadName: libfoo.so
>
> +ELF: Sections [
> +ELF: Section {
> +ELF: Name: (0)
> +ELF: Type: SHT_NULL
> +ELF: Flags [ (0x0)
> +ELF: ]
> +ELF: }
> +ELF: Section {
> +ELF: Name: .hash
> +ELF: Type: SHT_HASH
> +ELF: Flags [ (0x2)
> +ELF: SHF_ALLOC
> +ELF: ]
> +ELF: }
> +ELF: Section {
> +ELF: Name: .dynsym
> +ELF: Type: SHT_DYNSYM
> +ELF: Flags [ (0x2)
> +ELF: SHF_ALLOC
> +ELF: ]
> +ELF: }
> +ELF: Section {
> +ELF: Name: .dynstr
> +ELF: Type: SHT_STRTAB
> +ELF: Flags [ (0x2)
> +ELF: SHF_ALLOC
> +ELF: ]
> +ELF: }
> +ELF: Section {
> +ELF: Name: .text
> +ELF: Type: SHT_PROGBITS
> +ELF: Flags [ (0x6)
> +ELF: SHF_ALLOC
> +ELF: SHF_EXECINSTR
> +ELF: ]
> +ELF: }
> +ELF: Section {
> +ELF: Name: .eh_frame
> +ELF: Type: SHT_PROGBITS
> +ELF: Flags [ (0x2)
> +ELF: SHF_ALLOC
> +ELF: ]
> +ELF: }
> +ELF: Section {
> +ELF: Name: .tdata
> +ELF: Type: SHT_PROGBITS
> +ELF: Flags [ (0x403)
> +ELF: SHF_ALLOC
> +ELF: SHF_TLS
> +ELF: SHF_WRITE
> +ELF: ]
> +ELF: }
> +ELF: Section {
> +ELF: Name: .dynamic
> +ELF: Type: SHT_DYNAMIC
> +ELF: Flags [ (0x3)
> +ELF: SHF_ALLOC
> +ELF: SHF_WRITE
> +ELF: ]
> +ELF: }
> +ELF: Section {
> +ELF: Name: .got.plt
> +ELF: Type: SHT_PROGBITS
> +ELF: Flags [ (0x3)
> +ELF: SHF_ALLOC
> +ELF: SHF_WRITE
> +ELF: ]
> +ELF: }
> +ELF: Section {
> +ELF: Name: .data
> +ELF: Type: SHT_PROGBITS
> +ELF: Flags [ (0x3)
> +ELF: SHF_ALLOC
> +ELF: SHF_WRITE
> +ELF: ]
> +ELF: }
> +ELF: Section {
> +ELF: Name: .bss
> +ELF: Type: SHT_NOBITS
> +ELF: Flags [ (0x3)
> +ELF: SHF_ALLOC
> +ELF: SHF_WRITE
> +ELF: ]
> +ELF: }
> +ELF: Section {
> +ELF: Name: .shstrtab
> +ELF: Type: SHT_STRTAB
> +ELF: Flags [ (0x0)
> +ELF: ]
> +ELF: }
> +ELF: Section {
> +ELF: Name: .symtab
> +ELF: Type: SHT_SYMTAB
> +ELF: Flags [ (0x0)
> +ELF: ]
> +ELF: }
> +ELF: Section {
> +ELF: Name: .strtab
> +ELF: Type: SHT_STRTAB
> +ELF: Flags [ (0x0)
> +ELF: ]
> +ELF: }
> +ELF: ]
> +
> +ELF: Symbols [
> +ELF: Symbol {
> +ELF: Name: .hash
> +ELF: Binding: Local
> +ELF: Type: Section
> +ELF: Section: .hash
> +ELF: }
> +ELF: Symbol {
> +ELF: Name: .dynsym
> +ELF: Binding: Local
> +ELF: Type: Section
> +ELF: Section: .dynsym
> +ELF: }
> +ELF: Symbol {
> +ELF: Name: .dynstr
> +ELF: Binding: Local
> +ELF: Type: Section
> +ELF: Section: .dynstr
> +ELF: }
> +ELF: Symbol {
> +ELF: Name: .text
> +ELF: Binding: Local
> +ELF: Type: Section
> +ELF: Section: .text
> +ELF: }
> +ELF: Symbol {
> +ELF: Name: .eh_frame
> +ELF: Binding: Local
> +ELF: Type: Section
> +ELF: Section: .eh_frame
> +ELF: }
> +ELF: Symbol {
> +ELF: Name: .tdata
> +ELF: Binding: Local
> +ELF: Type: Section
> +ELF: Section: .tdata
> +ELF: }
> +ELF: Symbol {
> +ELF: Name: .dynamic
> +ELF: Binding: Local
> +ELF: Type: Section
> +ELF: Section: .dynamic
> +ELF: }
> +ELF: Symbol {
> +ELF: Name: .got.plt
> +ELF: Binding: Local
> +ELF: Type: Section
> +ELF: Section: .got.plt
> +ELF: }
> +ELF: Symbol {
> +ELF: Name: .data
> +ELF: Binding: Local
> +ELF: Type: Section
> +ELF: Section: .data
> +ELF: }
> +ELF: Symbol {
> +ELF: Name: .bss
> +ELF: Binding: Local
> +ELF: Type: Section
> +ELF: Section: .bss
> +ELF: }
> +ELF: Symbol {
> +ELF: Name: shared.ll
> +ELF: Binding: Local
> +ELF: Type: File
> +ELF: Section: (0xFFF1)
> +ELF: }
> +ELF: Symbol {
> +ELF: Name: local_func
> +ELF: Binding: Local
> +ELF: Type: Function
> +ELF: Section: .text
> +ELF: }
> +ELF: Symbol {
> +ELF: Name: _GLOBAL_OFFSET_TABLE_
> +ELF: Binding: Local
> +ELF: Type: Object
> +ELF: Section: (0xFFF1)
> +ELF: }
> +ELF: Symbol {
> +ELF: Name: _DYNAMIC
> +ELF: Binding: Local
> +ELF: Type: Object
> +ELF: Section: (0xFFF1)
> +ELF: }
> +ELF: Symbol {
> +ELF: Name: common_sym
> +ELF: Binding: Global
> +ELF: Type: Object
> +ELF: Section: .bss
> +ELF: }
> +ELF: Symbol {
> +ELF: Name: tls_sym
> +ELF: Binding: Global
> +ELF: Type: TLS
> +ELF: Section: .tdata
> +ELF: }
> +ELF: Symbol {
> +ELF: Name: defined_sym
> +ELF: Binding: Global
> +ELF: Type: Object
> +ELF: Section: .data
> +ELF: }
> +ELF: Symbol {
> +ELF: Name: __bss_start
> +ELF: Binding: Global
> +ELF: Type: None
> +ELF: Section: (0xFFF1)
> +ELF: }
> +ELF: Symbol {
> +ELF: Name: _end
> +ELF: Binding: Global
> +ELF: Type: None
> +ELF: Section: (0xFFF1)
> +ELF: }
> +ELF: Symbol {
> +ELF: Name: global_func
> +ELF: Binding: Global
> +ELF: Type: Function
> +ELF: Section: .text
> +ELF: }
> +ELF: Symbol {
> +ELF: Name: _edata
> +ELF: Binding: Global
> +ELF: Type: None
> +ELF: Section: (0xFFF1)
> +ELF: }
> +ELF: ]
> +
> +ELF: DynamicSymbols [
> +ELF: Symbol {
> +ELF: Name: common_sym
> +ELF: Binding: Global
> +ELF: Type: Object
> +ELF: Section: .bss
> +ELF: }
> +ELF: Symbol {
> +ELF: Name: tls_sym
> +ELF: Binding: Global
> +ELF: Type: TLS
> +ELF: Section: .tdata
> +ELF: }
> +ELF: Symbol {
> +ELF: Name: defined_sym
> +ELF: Binding: Global
> +ELF: Type: Object
> +ELF: Section: .data
> +ELF: }
> +ELF: Symbol {
> +ELF: Name: __bss_start
> +ELF: Binding: Global
> +ELF: Type: None
> +ELF: Section: (0xFFF1)
> +ELF: }
> +ELF: Symbol {
> +ELF: Name: _end
> +ELF: Binding: Global
> +ELF: Type: None
> +ELF: Section: (0xFFF1)
> +ELF: }
> +ELF: Symbol {
> +ELF: Name: global_func
> +ELF: Binding: Global
> +ELF: Type: Function
> +ELF: Section: .text
> +ELF: }
> +ELF: Symbol {
> +ELF: Name: _edata
> +ELF: Binding: Global
> +ELF: Type: None
> +ELF: Section: (0xFFF1)
> +ELF: }
> +ELF: ]
> +
> +ELF: DynamicSection [ (9 entries)
> +ELF: Tag Type Name/Value
> +ELF: 00000001 NEEDED SharedLibrary (libc.so.6)
> +ELF: 00000001 NEEDED SharedLibrary (libm.so.6)
> +ELF: 0000000E SONAME LibrarySoname (libfoo.so)
> +ELF: 00000004 HASH {{[0-9a-f]+}}
> +ELF: 00000005 STRTAB {{[0-9a-f]+}}
> +ELF: 00000006 SYMTAB {{[0-9a-f]+}}
> +ELF: 0000000A STRSZ {{[0-9]+}} (bytes)
> +ELF: 0000000B SYMENT {{[0-9]+}} (bytes)
> +ELF: 00000000 NULL 0x0
> +ELF: ]
> +
> +ELF: NeededLibraries [
> +ELF-NEXT: libc.so.6
> +ELF-NEXT: libm.so.6
> +ELF-NEXT: ]
>
> Added: llvm/trunk/test/tools/llvm-readobj/Inputs/trivial.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/Inputs/trivial.ll?rev=178679&view=auto
> ==============================================================================
> --- llvm/trunk/test/tools/llvm-readobj/Inputs/trivial.ll (added)
> +++ llvm/trunk/test/tools/llvm-readobj/Inputs/trivial.ll Wed Apr 3 13:31:38 2013
> @@ -0,0 +1,19 @@
> +; llc -mtriple=i386-pc-win32 trivial.ll -filetype=obj -o trivial-object-test.coff-i386
> +; llc -mtriple=x86_64-pc-win32 trivial.ll -filetype=obj -o trivial-object-test.coff-x86-64
> +; llc -mtriple=i386-linux-gnu trivial.ll -filetype=obj -o trivial-object-test.elf-i386 -relocation-model=pic
> +; llc -mtriple=x86_64-linux-gnu trivial.ll -filetype=obj -o trivial-object-test.elf-x86-64 -relocation-model=pic
> +; llc -mtriple=i386-apple-darwin10 trivial.ll -filetype=obj -o trivial-object-test.macho-i386 -relocation-model=pic
> +; llc -mtriple=x86_64-apple-darwin10 trivial.ll -filetype=obj -o trivial-object-test.macho-x86-64 -relocation-model=pic
> +
> + at .str = private unnamed_addr constant [13 x i8] c"Hello World\0A\00", align 1
> +
> +define i32 @main() nounwind {
> +entry:
> + %call = tail call i32 @puts(i8* getelementptr inbounds ([13 x i8]* @.str, i32 0, i32 0)) nounwind
> + tail call void bitcast (void (...)* @SomeOtherFunction to void ()*)() nounwind
> + ret i32 0
> +}
> +
> +declare i32 @puts(i8* nocapture) nounwind
> +
> +declare void @SomeOtherFunction(...)
>
> Added: llvm/trunk/test/tools/llvm-readobj/Inputs/trivial.obj.coff-i386
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/Inputs/trivial.obj.coff-i386?rev=178679&view=auto
> ==============================================================================
> Binary files llvm/trunk/test/tools/llvm-readobj/Inputs/trivial.obj.coff-i386 (added) and llvm/trunk/test/tools/llvm-readobj/Inputs/trivial.obj.coff-i386 Wed Apr 3 13:31:38 2013 differ
>
> Added: llvm/trunk/test/tools/llvm-readobj/Inputs/trivial.obj.coff-x86-64
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/Inputs/trivial.obj.coff-x86-64?rev=178679&view=auto
> ==============================================================================
> Binary files llvm/trunk/test/tools/llvm-readobj/Inputs/trivial.obj.coff-x86-64 (added) and llvm/trunk/test/tools/llvm-readobj/Inputs/trivial.obj.coff-x86-64 Wed Apr 3 13:31:38 2013 differ
>
> Added: llvm/trunk/test/tools/llvm-readobj/Inputs/trivial.obj.elf-i386
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/Inputs/trivial.obj.elf-i386?rev=178679&view=auto
> ==============================================================================
> Binary files llvm/trunk/test/tools/llvm-readobj/Inputs/trivial.obj.elf-i386 (added) and llvm/trunk/test/tools/llvm-readobj/Inputs/trivial.obj.elf-i386 Wed Apr 3 13:31:38 2013 differ
>
> Added: llvm/trunk/test/tools/llvm-readobj/Inputs/trivial.obj.elf-x86-64
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/Inputs/trivial.obj.elf-x86-64?rev=178679&view=auto
> ==============================================================================
> Binary files llvm/trunk/test/tools/llvm-readobj/Inputs/trivial.obj.elf-x86-64 (added) and llvm/trunk/test/tools/llvm-readobj/Inputs/trivial.obj.elf-x86-64 Wed Apr 3 13:31:38 2013 differ
>
> Added: llvm/trunk/test/tools/llvm-readobj/Inputs/trivial.obj.macho-i386
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/Inputs/trivial.obj.macho-i386?rev=178679&view=auto
> ==============================================================================
> Binary files llvm/trunk/test/tools/llvm-readobj/Inputs/trivial.obj.macho-i386 (added) and llvm/trunk/test/tools/llvm-readobj/Inputs/trivial.obj.macho-i386 Wed Apr 3 13:31:38 2013 differ
>
> Added: llvm/trunk/test/tools/llvm-readobj/Inputs/trivial.obj.macho-x86-64
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/Inputs/trivial.obj.macho-x86-64?rev=178679&view=auto
> ==============================================================================
> Binary files llvm/trunk/test/tools/llvm-readobj/Inputs/trivial.obj.macho-x86-64 (added) and llvm/trunk/test/tools/llvm-readobj/Inputs/trivial.obj.macho-x86-64 Wed Apr 3 13:31:38 2013 differ
>
> Added: llvm/trunk/test/tools/llvm-readobj/file-headers.test
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/file-headers.test?rev=178679&view=auto
> ==============================================================================
> --- llvm/trunk/test/tools/llvm-readobj/file-headers.test (added)
> +++ llvm/trunk/test/tools/llvm-readobj/file-headers.test Wed Apr 3 13:31:38 2013
> @@ -0,0 +1,100 @@
> +RUN: llvm-readobj -h %p/Inputs/trivial.obj.coff-i386 \
> +RUN: | FileCheck %s -check-prefix COFF32
> +RUN: llvm-readobj -h %p/Inputs/trivial.obj.coff-x86-64 \
> +RUN: | FileCheck %s -check-prefix COFF64
> +RUN: llvm-readobj -h %p/Inputs/trivial.obj.elf-i386 \
> +RUN: | FileCheck %s -check-prefix ELF32
> +RUN: llvm-readobj -h %p/Inputs/trivial.obj.elf-x86-64 \
> +RUN: | FileCheck %s -check-prefix ELF64
> +
> +COFF32: File: {{(.*[/\\])?}}trivial.obj.coff-i386
> +COFF32-NEXT: Format: COFF-i386
> +COFF32-NEXT: Arch: i386
> +COFF32-NEXT: AddressSize: 32bit
> +COFF32-NEXT: ImageFileHeader {
> +COFF32-NEXT: Machine: IMAGE_FILE_MACHINE_I386 (0x14C)
> +COFF32-NEXT: SectionCount: 2
> +COFF32-NEXT: TimeDateStamp: 2013-03-20 17:56:46 (0x5149F85E)
> +COFF32-NEXT: PointerToSymbolTable: 0xA5
> +COFF32-NEXT: SymbolCount: 7
> +COFF32-NEXT: OptionalHeaderSize: 0
> +COFF32-NEXT: Characteristics [ (0x0)
> +COFF32-NEXT: ]
> +COFF32-NEXT: }
> +
> +COFF64: File: {{(.*[/\\])?}}trivial.obj.coff-x86-64
> +COFF64-NEXT: Format: COFF-x86-64
> +COFF64-NEXT: Arch: x86_64
> +COFF64-NEXT: AddressSize: 64bit
> +COFF64-NEXT: ImageFileHeader {
> +COFF64-NEXT: Machine: IMAGE_FILE_MACHINE_AMD64 (0x8664)
> +COFF64-NEXT: SectionCount: 2
> +COFF64-NEXT: TimeDateStamp: 2013-03-20 17:56:46 (0x5149F85E)
> +COFF64-NEXT: PointerToSymbolTable: 0xAB
> +COFF64-NEXT: SymbolCount: 7
> +COFF64-NEXT: OptionalHeaderSize: 0
> +COFF64-NEXT: Characteristics [ (0x0)
> +COFF64-NEXT: ]
> +COFF64-NEXT: }
> +
> +ELF32: File: {{(.*[/\\])?}}trivial.obj.elf-i386
> +ELF32-NEXT: Format: ELF32-i386
> +ELF32-NEXT: Arch: i386
> +ELF32-NEXT: AddressSize: 32bit
> +ELF32-NEXT: LoadName:
> +ELF32-NEXT: ElfHeader {
> +ELF32-NEXT: Ident {
> +ELF32-NEXT: Magic: (7F 45 4C 46)
> +ELF32-NEXT: Class: 32-bit (0x1)
> +ELF32-NEXT: DataEncoding: LittleEndian (0x1)
> +ELF32-NEXT: FileVersion: 1
> +ELF32-NEXT: OS/ABI: GNU/Linux (0x3)
> +ELF32-NEXT: ABIVersion: 0
> +ELF32-NEXT: Unused: (00 00 00 00 00 00 00)
> +ELF32-NEXT: }
> +ELF32-NEXT: Type: Relocatable (0x1)
> +ELF32-NEXT: Machine: EM_386 (0x3)
> +ELF32-NEXT: Version: 1
> +ELF32-NEXT: Entry: 0x0
> +ELF32-NEXT: ProgramHeaderOffset: 0x0
> +ELF32-NEXT: SectionHeaderOffset: 0xC8
> +ELF32-NEXT: Flags [ (0x0)
> +ELF32-NEXT: ]
> +ELF32-NEXT: HeaderSize: 52
> +ELF32-NEXT: ProgramHeaderEntrySize: 0
> +ELF32-NEXT: ProgramHeaderCount: 0
> +ELF32-NEXT: SectionHeaderEntrySize: 40
> +ELF32-NEXT: SectionHeaderCount: 10
> +ELF32-NEXT: StringTableSectionIndex: 7
> +ELF32-NEXT: }
> +
> +ELF64: File: {{(.*[/\\])?}}trivial.obj.elf-x86-64
> +ELF64-NEXT: Format: ELF64-x86-64
> +ELF64-NEXT: Arch: x86_64
> +ELF64-NEXT: AddressSize: 64bit
> +ELF64-NEXT: LoadName:
> +ELF64-NEXT: ElfHeader {
> +ELF64-NEXT: Ident {
> +ELF64-NEXT: Magic: (7F 45 4C 46)
> +ELF64-NEXT: Class: 64-bit (0x2)
> +ELF64-NEXT: DataEncoding: LittleEndian (0x1)
> +ELF64-NEXT: FileVersion: 1
> +ELF64-NEXT: OS/ABI: GNU/Linux (0x3)
> +ELF64-NEXT: ABIVersion: 0
> +ELF64-NEXT: Unused: (00 00 00 00 00 00 00)
> +ELF64-NEXT: }
> +ELF64-NEXT: Type: Relocatable (0x1)
> +ELF64-NEXT: Machine: EM_X86_64 (0x3E)
> +ELF64-NEXT: Version: 1
> +ELF64-NEXT: Entry: 0x0
> +ELF64-NEXT: ProgramHeaderOffset: 0x0
> +ELF64-NEXT: SectionHeaderOffset: 0xB8
> +ELF64-NEXT: Flags [ (0x0)
> +ELF64-NEXT: ]
> +ELF64-NEXT: HeaderSize: 64
> +ELF64-NEXT: ProgramHeaderEntrySize: 0
> +ELF64-NEXT: ProgramHeaderCount: 0
> +ELF64-NEXT: SectionHeaderEntrySize: 64
> +ELF64-NEXT: SectionHeaderCount: 10
> +ELF64-NEXT: StringTableSectionIndex: 7
> +ELF64-NEXT: }
>
> Added: llvm/trunk/test/tools/llvm-readobj/lit.local.cfg
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/lit.local.cfg?rev=178679&view=auto
> ==============================================================================
> --- llvm/trunk/test/tools/llvm-readobj/lit.local.cfg (added)
> +++ llvm/trunk/test/tools/llvm-readobj/lit.local.cfg Wed Apr 3 13:31:38 2013
> @@ -0,0 +1 @@
> +config.suffixes = ['.test']
>
> Added: llvm/trunk/test/tools/llvm-readobj/relocations.test
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/relocations.test?rev=178679&view=auto
> ==============================================================================
> --- llvm/trunk/test/tools/llvm-readobj/relocations.test (added)
> +++ llvm/trunk/test/tools/llvm-readobj/relocations.test Wed Apr 3 13:31:38 2013
> @@ -0,0 +1,32 @@
> +RUN: llvm-readobj -r %p/Inputs/trivial.obj.coff-i386 \
> +RUN: | FileCheck %s -check-prefix COFF
> +RUN: llvm-readobj -r %p/Inputs/trivial.obj.elf-i386 \
> +RUN: | FileCheck %s -check-prefix ELF
> +RUN: llvm-readobj -r %p/Inputs/trivial.obj.macho-i386 \
> +RUN: | FileCheck %s -check-prefix MACHO
> +
> +COFF: Relocations [
> +COFF-NEXT: Section (1) .text {
> +COFF-NEXT: 0x4 IMAGE_REL_I386_DIR32 .data
> +COFF-NEXT: 0x9 IMAGE_REL_I386_REL32 _puts
> +COFF-NEXT: 0xE IMAGE_REL_I386_REL32 _SomeOtherFunction
> +COFF-NEXT: }
> +COFF-NEXT: ]
> +
> +ELF: Relocations [
> +ELF-NEXT: Section (1) .text {
> +ELF-NEXT: 0xC R_386_GOTPC _GLOBAL_OFFSET_TABLE_ 0x0
> +ELF-NEXT: 0x12 R_386_GOTOFF .L.str 0x0
> +ELF-NEXT: 0x1A R_386_PLT32 puts 0x0
> +ELF-NEXT: 0x1F R_386_PLT32 SomeOtherFunction 0x0
> +ELF-NEXT: }
> +ELF-NEXT: ]
> +
> +MACHO: Relocations [
> +MACHO-NEXT: Section __text {
> +MACHO-NEXT: 0x18 GENERIC_RELOC_VANILLA _SomeOtherFunction 0x0
> +MACHO-NEXT: 0x13 GENERIC_RELOC_VANILLA _puts 0x0
> +MACHO-NEXT: 0xB GENERIC_RELOC_LOCAL_SECTDIFF _main 0x{{[0-9A-F]+}}
> +MACHO-NEXT: 0x0 GENERIC_RELOC_PAIR _main 0x{{[0-9A-F]+}}
> +MACHO-NEXT: }
> +MACHO-NEXT: ]
>
> Added: llvm/trunk/test/tools/llvm-readobj/sections-ext.test
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/sections-ext.test?rev=178679&view=auto
> ==============================================================================
> --- llvm/trunk/test/tools/llvm-readobj/sections-ext.test (added)
> +++ llvm/trunk/test/tools/llvm-readobj/sections-ext.test Wed Apr 3 13:31:38 2013
> @@ -0,0 +1,175 @@
> +RUN: llvm-readobj -s -st -sr -sd %p/Inputs/trivial.obj.coff-i386 \
> +RUN: | FileCheck %s -check-prefix COFF
> +RUN: llvm-readobj -s -st -sr -sd %p/Inputs/trivial.obj.elf-i386 \
> +RUN: | FileCheck %s -check-prefix ELF
> +RUN: llvm-readobj -s -st -sr -sd %p/Inputs/trivial.obj.macho-i386 \
> +RUN: | FileCheck %s -check-prefix MACHO
> +
> +COFF: Sections [
> +COFF-NEXT: Section {
> +COFF-NEXT: Number: 1
> +COFF-NEXT: Name: .text (2E 74 65 78 74 00 00 00)
> +COFF-NEXT: VirtualSize: 0x0
> +COFF-NEXT: VirtualAddress: 0x0
> +COFF-NEXT: RawDataSize: 22
> +COFF-NEXT: PointerToRawData: 0x64
> +COFF-NEXT: PointerToRelocations: 0x7A
> +COFF-NEXT: PointerToLineNumbers: 0x0
> +COFF-NEXT: RelocationCount: 3
> +COFF-NEXT: LineNumberCount: 0
> +COFF-NEXT: Characteristics [ (0x60500020)
> +COFF-NEXT: IMAGE_SCN_ALIGN_16BYTES (0x500000)
> +COFF-NEXT: IMAGE_SCN_CNT_CODE (0x20)
> +COFF-NEXT: IMAGE_SCN_MEM_EXECUTE (0x20000000)
> +COFF-NEXT: IMAGE_SCN_MEM_READ (0x40000000)
> +COFF-NEXT: ]
> +COFF-NEXT: Relocations [
> +COFF-NEXT: 0x4 IMAGE_REL_I386_DIR32 .data
> +COFF-NEXT: 0x9 IMAGE_REL_I386_REL32 _puts
> +COFF-NEXT: 0xE IMAGE_REL_I386_REL32 _SomeOtherFunction
> +COFF-NEXT: ]
> +COFF-NEXT: Symbols [
> +COFF-NEXT: Symbol {
> +COFF-NEXT: Name: .text
> +COFF-NEXT: Value: 0
> +COFF-NEXT: Section: .text (1)
> +COFF-NEXT: BaseType: Null (0x0)
> +COFF-NEXT: ComplexType: Null (0x0)
> +COFF-NEXT: StorageClass: Static (0x3)
> +COFF-NEXT: AuxSymbolCount: 1
> +COFF-NEXT: AuxSectionDef {
> +COFF-NEXT: Length: 22
> +COFF-NEXT: RelocationCount: 3
> +COFF-NEXT: LineNumberCount: 0
> +COFF-NEXT: Checksum: 0x0
> +COFF-NEXT: Number: 1
> +COFF-NEXT: Selection: 0x0
> +COFF-NEXT: Unused: (00 00 00)
> +COFF-NEXT: }
> +COFF-NEXT: }
> +COFF-NEXT: Symbol {
> +COFF-NEXT: Name: _main
> +COFF-NEXT: Value: 0
> +COFF-NEXT: Section: .text (1)
> +COFF-NEXT: BaseType: Null (0x0)
> +COFF-NEXT: ComplexType: Function (0x2)
> +COFF-NEXT: StorageClass: External (0x2)
> +COFF-NEXT: AuxSymbolCount: 0
> +COFF-NEXT: }
> +COFF-NEXT: ]
> +COFF-NEXT: SectionData (
> +COFF-NEXT: 0000: 50C70424 00000000 E8000000 00E80000 |P..$............|
> +COFF-NEXT: 0010: 000031C0 5AC3 |..1.Z.|
> +COFF-NEXT: )
> +COFF-NEXT: }
> +
> +ELF: Sections [
> +ELF-NEXT: Section {
> +ELF-NEXT: Index: 0
> +ELF-NEXT: Name: (0)
> +ELF-NEXT: Type: SHT_NULL (0x0)
> +ELF-NEXT: Flags [ (0x0)
> +ELF-NEXT: ]
> +ELF-NEXT: Address: 0x0
> +ELF-NEXT: Offset: 0x0
> +ELF-NEXT: Size: 0
> +ELF-NEXT: Link: 0
> +ELF-NEXT: Info: 0
> +ELF-NEXT: AddressAlignment: 0
> +ELF-NEXT: EntrySize: 0
> +ELF-NEXT: Relocations [
> +ELF-NEXT: ]
> +ELF-NEXT: Symbols [
> +ELF-NEXT: ]
> +ELF-NEXT: SectionData (
> +ELF-NEXT: )
> +ELF-NEXT: }
> +ELF-NEXT: Section {
> +ELF-NEXT: Index: 1
> +ELF-NEXT: Name: .text (5)
> +ELF-NEXT: Type: SHT_PROGBITS (0x1)
> +ELF-NEXT: Flags [ (0x6)
> +ELF-NEXT: SHF_ALLOC (0x2)
> +ELF-NEXT: SHF_EXECINSTR (0x4)
> +ELF-NEXT: ]
> +ELF-NEXT: Address: 0x0
> +ELF-NEXT: Offset: 0x40
> +ELF-NEXT: Size: 42
> +ELF-NEXT: Link: 0
> +ELF-NEXT: Info: 0
> +ELF-NEXT: AddressAlignment: 16
> +ELF-NEXT: EntrySize: 0
> +ELF-NEXT: Relocations [
> +ELF-NEXT: 0xC R_386_GOTPC _GLOBAL_OFFSET_TABLE_ 0x0
> +ELF-NEXT: 0x12 R_386_GOTOFF .L.str 0x0
> +ELF-NEXT: 0x1A R_386_PLT32 puts 0x0
> +ELF-NEXT: 0x1F R_386_PLT32 SomeOtherFunction 0x0
> +ELF-NEXT: ]
> +ELF-NEXT: Symbols [
> +ELF-NEXT: Symbol {
> +ELF-NEXT: Name: .text (0)
> +ELF-NEXT: Value: 0x0
> +ELF-NEXT: Size: 0
> +ELF-NEXT: Binding: Local (0x0)
> +ELF-NEXT: Type: Section (0x3)
> +ELF-NEXT: Other: 0
> +ELF-NEXT: Section: .text (0x1)
> +ELF-NEXT: }
> +ELF-NEXT: Symbol {
> +ELF-NEXT: Name: main (12)
> +ELF-NEXT: Value: 0x0
> +ELF-NEXT: Size: 42
> +ELF-NEXT: Binding: Global (0x1)
> +ELF-NEXT: Type: Function (0x2)
> +ELF-NEXT: Other: 0
> +ELF-NEXT: Section: .text (0x1)
> +ELF-NEXT: }
> +ELF-NEXT: ]
> +ELF-NEXT: SectionData (
> +ELF-NEXT: 0000: 5383EC08 E8000000 005B81C3 03000000 |S........[......|
> +ELF-NEXT: 0010: 8D830000 00008904 24E8FCFF FFFFE8FC |........$.......|
> +ELF-NEXT: 0020: FFFFFF31 C083C408 5BC3 |...1....[.|
> +ELF-NEXT: )
> +ELF-NEXT: }
> +
> +MACHO: Sections [
> +MACHO-NEXT: Section {
> +MACHO-NEXT: Index: 0
> +MACHO-NEXT: Name: __text (5F 5F 74 65 78 74 00 00 00 00 00 00 00 00 00 00)
> +MACHO-NEXT: Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00)
> +MACHO-NEXT: Address: 0x0
> +MACHO-NEXT: Size: 0x22
> +MACHO-NEXT: Offset: 324
> +MACHO-NEXT: Alignment: 4
> +MACHO-NEXT: RelocationOffset: 0x174
> +MACHO-NEXT: RelocationCount: 4
> +MACHO-NEXT: Type: 0x0
> +MACHO-NEXT: Attributes [ (0x800004)
> +MACHO-NEXT: PureInstructions (0x800000)
> +MACHO-NEXT: SomeInstructions (0x4)
> +MACHO-NEXT: ]
> +MACHO-NEXT: Reserved1: 0x0
> +MACHO-NEXT: Reserved2: 0x0
> +MACHO-NEXT: Relocations [
> +MACHO-NEXT: 0x18 GENERIC_RELOC_VANILLA _SomeOtherFunction 0x0
> +MACHO-NEXT: 0x13 GENERIC_RELOC_VANILLA _puts 0x0
> +MACHO-NEXT: 0xB GENERIC_RELOC_LOCAL_SECTDIFF _main 0x{{[0-9A-F]+}}
> +MACHO-NEXT: 0x0 GENERIC_RELOC_PAIR _main 0x{{[0-9A-F]+}}
> +MACHO-NEXT: ]
> +MACHO-NEXT: Symbols [
> +MACHO-NEXT: Symbol {
> +MACHO-NEXT: Name: _main (1)
> +MACHO-NEXT: Type: 0xF
> +MACHO-NEXT: Section: __text (0x1)
> +MACHO-NEXT: RefType: UndefinedNonLazy (0x0)
> +MACHO-NEXT: Flags [ (0x0)
> +MACHO-NEXT: ]
> +MACHO-NEXT: Value: 0x0
> +MACHO-NEXT: }
> +MACHO-NEXT: ]
> +MACHO-NEXT: SectionData (
> +MACHO-NEXT: 0000: 83EC0CE8 00000000 588D801A 00000089 |........X.......|
> +MACHO-NEXT: 0010: 0424E8E9 FFFFFFE8 E4FFFFFF 31C083C4 |.$..........1...|
> +MACHO-NEXT: 0020: 0CC3 |..|
> +MACHO-NEXT: )
> +MACHO-NEXT: }
>
> Added: llvm/trunk/test/tools/llvm-readobj/sections.test
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/sections.test?rev=178679&view=auto
> ==============================================================================
> --- llvm/trunk/test/tools/llvm-readobj/sections.test (added)
> +++ llvm/trunk/test/tools/llvm-readobj/sections.test Wed Apr 3 13:31:38 2013
> @@ -0,0 +1,113 @@
> +RUN: llvm-readobj -s %p/Inputs/trivial.obj.coff-i386 \
> +RUN: | FileCheck %s -check-prefix COFF
> +RUN: llvm-readobj -s %p/Inputs/trivial.obj.elf-i386 \
> +RUN: | FileCheck %s -check-prefix ELF
> +RUN: llvm-readobj -s %p/Inputs/trivial.obj.macho-i386 \
> +RUN: | FileCheck %s -check-prefix MACHO
> +
> +COFF: Sections [
> +COFF-NEXT: Section {
> +COFF-NEXT: Number: 1
> +COFF-NEXT: Name: .text (2E 74 65 78 74 00 00 00)
> +COFF-NEXT: VirtualSize: 0x0
> +COFF-NEXT: VirtualAddress: 0x0
> +COFF-NEXT: RawDataSize: 22
> +COFF-NEXT: PointerToRawData: 0x64
> +COFF-NEXT: PointerToRelocations: 0x7A
> +COFF-NEXT: PointerToLineNumbers: 0x0
> +COFF-NEXT: RelocationCount: 3
> +COFF-NEXT: LineNumberCount: 0
> +COFF-NEXT: Characteristics [ (0x60500020)
> +COFF-NEXT: IMAGE_SCN_ALIGN_16BYTES (0x500000)
> +COFF-NEXT: IMAGE_SCN_CNT_CODE (0x20)
> +COFF-NEXT: IMAGE_SCN_MEM_EXECUTE (0x20000000)
> +COFF-NEXT: IMAGE_SCN_MEM_READ (0x40000000)
> +COFF-NEXT: ]
> +COFF-NEXT: }
> +COFF-NEXT: Section {
> +COFF-NEXT: Number: 2
> +COFF-NEXT: Name: .data (2E 64 61 74 61 00 00 00)
> +COFF-NEXT: VirtualSize: 0x0
> +COFF-NEXT: VirtualAddress: 0x0
> +COFF-NEXT: RawDataSize: 13
> +COFF-NEXT: PointerToRawData: 0x98
> +COFF-NEXT: PointerToRelocations: 0x0
> +COFF-NEXT: PointerToLineNumbers: 0x0
> +COFF-NEXT: RelocationCount: 0
> +COFF-NEXT: LineNumberCount: 0
> +COFF-NEXT: Characteristics [ (0xC0300040)
> +COFF-NEXT: IMAGE_SCN_ALIGN_4BYTES (0x300000)
> +COFF-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA (0x40)
> +COFF-NEXT: IMAGE_SCN_MEM_READ (0x40000000)
> +COFF-NEXT: IMAGE_SCN_MEM_WRITE (0x80000000)
> +COFF-NEXT: ]
> +COFF-NEXT: }
> +COFF-NEXT: ]
> +
> +ELF: Sections [
> +ELF-NEXT: Section {
> +ELF-NEXT: Index: 0
> +ELF-NEXT: Name: (0)
> +ELF-NEXT: Type: SHT_NULL (0x0)
> +ELF-NEXT: Flags [ (0x0)
> +ELF-NEXT: ]
> +ELF-NEXT: Address: 0x0
> +ELF-NEXT: Offset: 0x0
> +ELF-NEXT: Size: 0
> +ELF-NEXT: Link: 0
> +ELF-NEXT: Info: 0
> +ELF-NEXT: AddressAlignment: 0
> +ELF-NEXT: EntrySize: 0
> +ELF-NEXT: }
> +ELF-NEXT: Section {
> +ELF-NEXT: Index: 1
> +ELF-NEXT: Name: .text (5)
> +ELF-NEXT: Type: SHT_PROGBITS (0x1)
> +ELF-NEXT: Flags [ (0x6)
> +ELF-NEXT: SHF_ALLOC (0x2)
> +ELF-NEXT: SHF_EXECINSTR (0x4)
> +ELF-NEXT: ]
> +ELF-NEXT: Address: 0x0
> +ELF-NEXT: Offset: 0x40
> +ELF-NEXT: Size: 42
> +ELF-NEXT: Link: 0
> +ELF-NEXT: Info: 0
> +ELF-NEXT: AddressAlignment: 16
> +ELF-NEXT: EntrySize: 0
> +ELF-NEXT: }
> +
> +MACHO: Sections [
> +MACHO-NEXT: Section {
> +MACHO-NEXT: Index: 0
> +MACHO-NEXT: Name: __text (5F 5F 74 65 78 74 00 00 00 00 00 00 00 00 00 00)
> +MACHO-NEXT: Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00)
> +MACHO-NEXT: Address: 0x0
> +MACHO-NEXT: Size: 0x22
> +MACHO-NEXT: Offset: 324
> +MACHO-NEXT: Alignment: 4
> +MACHO-NEXT: RelocationOffset: 0x174
> +MACHO-NEXT: RelocationCount: 4
> +MACHO-NEXT: Type: 0x0
> +MACHO-NEXT: Attributes [ (0x800004)
> +MACHO-NEXT: PureInstructions (0x800000)
> +MACHO-NEXT: SomeInstructions (0x4)
> +MACHO-NEXT: ]
> +MACHO-NEXT: Reserved1: 0x0
> +MACHO-NEXT: Reserved2: 0x0
> +MACHO-NEXT: }
> +MACHO-NEXT: Section {
> +MACHO-NEXT: Index: 1
> +MACHO-NEXT: Name: __cstring (5F 5F 63 73 74 72 69 6E 67 00 00 00 00 00 00 00)
> +MACHO-NEXT: Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00)
> +MACHO-NEXT: Address: 0x22
> +MACHO-NEXT: Size: 0xD
> +MACHO-NEXT: Offset: 358
> +MACHO-NEXT: Alignment: 0
> +MACHO-NEXT: RelocationOffset: 0x0
> +MACHO-NEXT: RelocationCount: 0
> +MACHO-NEXT: Type: ExtReloc (0x2)
> +MACHO-NEXT: Attributes [ (0x0)
> +MACHO-NEXT: ]
> +MACHO-NEXT: Reserved1: 0x0
> +MACHO-NEXT: Reserved2: 0x0
> +MACHO-NEXT: }
>
> Added: llvm/trunk/test/tools/llvm-readobj/symbols.test
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/symbols.test?rev=178679&view=auto
> ==============================================================================
> --- llvm/trunk/test/tools/llvm-readobj/symbols.test (added)
> +++ llvm/trunk/test/tools/llvm-readobj/symbols.test Wed Apr 3 13:31:38 2013
> @@ -0,0 +1,44 @@
> +RUN: llvm-readobj -t %p/Inputs/trivial.obj.coff-i386 \
> +RUN: | FileCheck %s -check-prefix COFF
> +RUN: llvm-readobj -t %p/Inputs/trivial.obj.elf-i386 \
> +RUN: | FileCheck %s -check-prefix ELF
> +
> +COFF: Symbols [
> +COFF-NEXT: Symbol {
> +COFF-NEXT: Name: .text
> +COFF-NEXT: Value: 0
> +COFF-NEXT: Section: .text (1)
> +COFF-NEXT: BaseType: Null (0x0)
> +COFF-NEXT: ComplexType: Null (0x0)
> +COFF-NEXT: StorageClass: Static (0x3)
> +COFF-NEXT: AuxSymbolCount: 1
> +COFF-NEXT: AuxSectionDef {
> +COFF-NEXT: Length: 22
> +COFF-NEXT: RelocationCount: 3
> +COFF-NEXT: LineNumberCount: 0
> +COFF-NEXT: Checksum: 0x0
> +COFF-NEXT: Number: 1
> +COFF-NEXT: Selection: 0x0
> +COFF-NEXT: Unused: (00 00 00)
> +COFF-NEXT: }
> +COFF-NEXT: }
> +
> +ELF: Symbols [
> +ELF-NEXT: Symbol {
> +ELF-NEXT: Name: trivial.ll (1)
> +ELF-NEXT: Value: 0x0
> +ELF-NEXT: Size: 0
> +ELF-NEXT: Binding: Local (0x0)
> +ELF-NEXT: Type: File (0x4)
> +ELF-NEXT: Other: 0
> +ELF-NEXT: Section: (0xFFF1)
> +ELF-NEXT: }
> +ELF-NEXT: Symbol {
> +ELF-NEXT: Name: .L.str (39)
> +ELF-NEXT: Value: 0x0
> +ELF-NEXT: Size: 13
> +ELF-NEXT: Binding: Local (0x0)
> +ELF-NEXT: Type: Object (0x1)
> +ELF-NEXT: Other: 0
> +ELF-NEXT: Section: .rodata.str1.1 (0x5)
> +ELF-NEXT: }
>
> Modified: llvm/trunk/tools/llvm-readobj/CMakeLists.txt
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/CMakeLists.txt?rev=178679&r1=178678&r2=178679&view=diff
> ==============================================================================
> --- llvm/trunk/tools/llvm-readobj/CMakeLists.txt (original)
> +++ llvm/trunk/tools/llvm-readobj/CMakeLists.txt Wed Apr 3 13:31:38 2013
> @@ -1,6 +1,15 @@
> -set(LLVM_LINK_COMPONENTS archive bitreader object)
> +set(LLVM_LINK_COMPONENTS
> + ${LLVM_TARGETS_TO_BUILD}
> + archive
> + bitreader
> + object)
>
> add_llvm_tool(llvm-readobj
> - ELF.cpp
> llvm-readobj.cpp
> + ObjDumper.cpp
> + COFFDumper.cpp
> + ELFDumper.cpp
> + MachODumper.cpp
> + Error.cpp
> + StreamWriter.cpp
> )
>
> Added: llvm/trunk/tools/llvm-readobj/COFFDumper.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/COFFDumper.cpp?rev=178679&view=auto
> ==============================================================================
> --- llvm/trunk/tools/llvm-readobj/COFFDumper.cpp (added)
> +++ llvm/trunk/tools/llvm-readobj/COFFDumper.cpp Wed Apr 3 13:31:38 2013
> @@ -0,0 +1,1014 @@
> +//===-- COFFDumper.cpp - COFF-specific dumper -------------------*- C++ -*-===//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===----------------------------------------------------------------------===//
> +///
> +/// \file
> +/// \brief This file implements the COFF-specific dumper for llvm-readobj.
> +///
> +//===----------------------------------------------------------------------===//
> +
> +#include "llvm-readobj.h"
> +#include "ObjDumper.h"
> +
> +#include "Error.h"
> +#include "StreamWriter.h"
> +
> +#include "llvm/ADT/DenseMap.h"
> +#include "llvm/ADT/SmallString.h"
> +#include "llvm/Object/COFF.h"
> +#include "llvm/Object/ObjectFile.h"
> +#include "llvm/Support/Casting.h"
> +#include "llvm/Support/Compiler.h"
> +#include "llvm/Support/Format.h"
> +#include "llvm/Support/SourceMgr.h"
> +#include "llvm/Support/Win64EH.h"
> +#include "llvm/Support/raw_ostream.h"
> +#include "llvm/Support/system_error.h"
> +
> +#include <algorithm>
> +#include <cstring>
> +#include <time.h>
> +
> +using namespace llvm;
> +using namespace llvm::object;
> +using namespace llvm::Win64EH;
> +
> +namespace {
> +
> +class COFFDumper : public ObjDumper {
> +public:
> + COFFDumper(const llvm::object::COFFObjectFile *Obj, StreamWriter& Writer)
> + : ObjDumper(Writer)
> + , Obj(Obj) {
> + cacheRelocations();
> + }
> +
> + virtual void printFileHeaders() LLVM_OVERRIDE;
> + virtual void printSections() LLVM_OVERRIDE;
> + virtual void printRelocations() LLVM_OVERRIDE;
> + virtual void printSymbols() LLVM_OVERRIDE;
> + virtual void printDynamicSymbols() LLVM_OVERRIDE;
> + virtual void printUnwindInfo() LLVM_OVERRIDE;
> +
> +private:
> + void printSymbol(symbol_iterator SymI);
> +
> + void printRelocation(section_iterator SecI, relocation_iterator RelI);
> +
> + void printX64UnwindInfo();
> +
> + void printRuntimeFunction(
> + const RuntimeFunction& RTF,
> + uint64_t OffsetInSection,
> + const std::vector<RelocationRef> &Rels);
> +
> + void printUnwindInfo(
> + const Win64EH::UnwindInfo& UI,
> + uint64_t OffsetInSection,
> + const std::vector<RelocationRef> &Rels);
> +
> + void printUnwindCode(const Win64EH::UnwindInfo& UI, ArrayRef<UnwindCode> UCs);
> +
> + void cacheRelocations();
> +
> + error_code getSectionContents(
> + const std::vector<RelocationRef> &Rels,
> + uint64_t Offset,
> + ArrayRef<uint8_t> &Contents,
> + uint64_t &Addr);
> +
> + error_code getSection(
> + const std::vector<RelocationRef> &Rels,
> + uint64_t Offset,
> + const coff_section **Section,
> + uint64_t *AddrPtr);
> +
> + typedef DenseMap<const coff_section*, std::vector<RelocationRef> > RelocMapTy;
> +
> + const llvm::object::COFFObjectFile *Obj;
> + RelocMapTy RelocMap;
> + std::vector<RelocationRef> EmptyRelocs;
> +};
> +
> +} // namespace
> +
> +
> +namespace llvm {
> +
> +error_code createCOFFDumper(const object::ObjectFile *Obj,
> + StreamWriter& Writer,
> + OwningPtr<ObjDumper> &Result) {
> + const COFFObjectFile *COFFObj = dyn_cast<COFFObjectFile>(Obj);
> + if (!COFFObj)
> + return readobj_error::unsupported_obj_file_format;
> +
> + Result.reset(new COFFDumper(COFFObj, Writer));
> + return readobj_error::success;
> +}
> +
> +} // namespace llvm
> +
> +
> +// Returns the name of the unwind code.
> +static StringRef getUnwindCodeTypeName(uint8_t Code) {
> + switch(Code) {
> + default: llvm_unreachable("Invalid unwind code");
> + case UOP_PushNonVol: return "PUSH_NONVOL";
> + case UOP_AllocLarge: return "ALLOC_LARGE";
> + case UOP_AllocSmall: return "ALLOC_SMALL";
> + case UOP_SetFPReg: return "SET_FPREG";
> + case UOP_SaveNonVol: return "SAVE_NONVOL";
> + case UOP_SaveNonVolBig: return "SAVE_NONVOL_FAR";
> + case UOP_SaveXMM128: return "SAVE_XMM128";
> + case UOP_SaveXMM128Big: return "SAVE_XMM128_FAR";
> + case UOP_PushMachFrame: return "PUSH_MACHFRAME";
> + }
> +}
> +
> +// Returns the name of a referenced register.
> +static StringRef getUnwindRegisterName(uint8_t Reg) {
> + switch(Reg) {
> + default: llvm_unreachable("Invalid register");
> + case 0: return "RAX";
> + case 1: return "RCX";
> + case 2: return "RDX";
> + case 3: return "RBX";
> + case 4: return "RSP";
> + case 5: return "RBP";
> + case 6: return "RSI";
> + case 7: return "RDI";
> + case 8: return "R8";
> + case 9: return "R9";
> + case 10: return "R10";
> + case 11: return "R11";
> + case 12: return "R12";
> + case 13: return "R13";
> + case 14: return "R14";
> + case 15: return "R15";
> + }
> +}
> +
> +// Calculates the number of array slots required for the unwind code.
> +static unsigned getNumUsedSlots(const UnwindCode &UnwindCode) {
> + switch (UnwindCode.getUnwindOp()) {
> + default: llvm_unreachable("Invalid unwind code");
> + case UOP_PushNonVol:
> + case UOP_AllocSmall:
> + case UOP_SetFPReg:
> + case UOP_PushMachFrame:
> + return 1;
> + case UOP_SaveNonVol:
> + case UOP_SaveXMM128:
> + return 2;
> + case UOP_SaveNonVolBig:
> + case UOP_SaveXMM128Big:
> + return 3;
> + case UOP_AllocLarge:
> + return (UnwindCode.getOpInfo() == 0) ? 2 : 3;
> + }
> +}
> +
> +// Given a symbol sym this functions returns the address and section of it.
> +static error_code resolveSectionAndAddress(const COFFObjectFile *Obj,
> + const SymbolRef &Sym,
> + const coff_section *&ResolvedSection,
> + uint64_t &ResolvedAddr) {
> + if (error_code EC = Sym.getAddress(ResolvedAddr))
> + return EC;
> +
> + section_iterator iter(Obj->begin_sections());
> + if (error_code EC = Sym.getSection(iter))
> + return EC;
> +
> + ResolvedSection = Obj->getCOFFSection(iter);
> + return object_error::success;
> +}
> +
> +// Given a vector of relocations for a section and an offset into this section
> +// the function returns the symbol used for the relocation at the offset.
> +static error_code resolveSymbol(const std::vector<RelocationRef> &Rels,
> + uint64_t Offset, SymbolRef &Sym) {
> + for (std::vector<RelocationRef>::const_iterator RelI = Rels.begin(),
> + RelE = Rels.end();
> + RelI != RelE; ++RelI) {
> + uint64_t Ofs;
> + if (error_code EC = RelI->getOffset(Ofs))
> + return EC;
> +
> + if (Ofs == Offset) {
> + if (error_code EC = RelI->getSymbol(Sym))
> + return EC;
> + return readobj_error::success;
> + }
> + }
> +
> + return readobj_error::unknown_symbol;
> +}
> +
> +// Given a vector of relocations for a section and an offset into this section
> +// the function returns the name of the symbol used for the relocation at the
> +// offset.
> +static error_code resolveSymbolName(const std::vector<RelocationRef> &Rels,
> + uint64_t Offset, StringRef &Name) {
> + SymbolRef Sym;
> + if (error_code EC = resolveSymbol(Rels, Offset, Sym)) return EC;
> + if (error_code EC = Sym.getName(Name)) return EC;
> + return object_error::success;
> +}
> +
> +static const EnumEntry<COFF::MachineTypes> ImageFileMachineType[] = {
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_UNKNOWN ),
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_AM33 ),
> + 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_ARMV7 ),
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_EBC ),
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_I386 ),
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_IA64 ),
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_M32R ),
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_MIPS16 ),
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_MIPSFPU ),
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_MIPSFPU16),
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_POWERPC ),
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_POWERPCFP),
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_R4000 ),
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_SH3 ),
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_SH3DSP ),
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_SH4 ),
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_SH5 ),
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_THUMB ),
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_WCEMIPSV2)
> +};
> +
> +static const EnumEntry<COFF::Characteristics> ImageFileCharacteristics[] = {
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_RELOCS_STRIPPED ),
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_EXECUTABLE_IMAGE ),
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_LINE_NUMS_STRIPPED ),
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_LOCAL_SYMS_STRIPPED ),
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_AGGRESSIVE_WS_TRIM ),
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_LARGE_ADDRESS_AWARE ),
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_BYTES_REVERSED_LO ),
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_32BIT_MACHINE ),
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_DEBUG_STRIPPED ),
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP),
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_NET_RUN_FROM_SWAP ),
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_SYSTEM ),
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_DLL ),
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_UP_SYSTEM_ONLY ),
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_BYTES_REVERSED_HI )
> +};
> +
> +static const EnumEntry<COFF::SectionCharacteristics>
> +ImageSectionCharacteristics[] = {
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_TYPE_NO_PAD ),
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_CNT_CODE ),
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_CNT_INITIALIZED_DATA ),
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_CNT_UNINITIALIZED_DATA),
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_LNK_OTHER ),
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_LNK_INFO ),
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_LNK_REMOVE ),
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_LNK_COMDAT ),
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_GPREL ),
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_MEM_PURGEABLE ),
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_MEM_16BIT ),
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_MEM_LOCKED ),
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_MEM_PRELOAD ),
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_1BYTES ),
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_2BYTES ),
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_4BYTES ),
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_8BYTES ),
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_16BYTES ),
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_32BYTES ),
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_64BYTES ),
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_128BYTES ),
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_256BYTES ),
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_512BYTES ),
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_1024BYTES ),
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_2048BYTES ),
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_4096BYTES ),
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_8192BYTES ),
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_LNK_NRELOC_OVFL ),
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_MEM_DISCARDABLE ),
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_MEM_NOT_CACHED ),
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_MEM_NOT_PAGED ),
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_MEM_SHARED ),
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_MEM_EXECUTE ),
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_MEM_READ ),
> + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_MEM_WRITE )
> +};
> +
> +static const EnumEntry<COFF::SymbolBaseType> ImageSymType[] = {
> + { "Null" , COFF::IMAGE_SYM_TYPE_NULL },
> + { "Void" , COFF::IMAGE_SYM_TYPE_VOID },
> + { "Char" , COFF::IMAGE_SYM_TYPE_CHAR },
> + { "Short" , COFF::IMAGE_SYM_TYPE_SHORT },
> + { "Int" , COFF::IMAGE_SYM_TYPE_INT },
> + { "Long" , COFF::IMAGE_SYM_TYPE_LONG },
> + { "Float" , COFF::IMAGE_SYM_TYPE_FLOAT },
> + { "Double", COFF::IMAGE_SYM_TYPE_DOUBLE },
> + { "Struct", COFF::IMAGE_SYM_TYPE_STRUCT },
> + { "Union" , COFF::IMAGE_SYM_TYPE_UNION },
> + { "Enum" , COFF::IMAGE_SYM_TYPE_ENUM },
> + { "MOE" , COFF::IMAGE_SYM_TYPE_MOE },
> + { "Byte" , COFF::IMAGE_SYM_TYPE_BYTE },
> + { "Word" , COFF::IMAGE_SYM_TYPE_WORD },
> + { "UInt" , COFF::IMAGE_SYM_TYPE_UINT },
> + { "DWord" , COFF::IMAGE_SYM_TYPE_DWORD }
> +};
> +
> +static const EnumEntry<COFF::SymbolComplexType> ImageSymDType[] = {
> + { "Null" , COFF::IMAGE_SYM_DTYPE_NULL },
> + { "Pointer" , COFF::IMAGE_SYM_DTYPE_POINTER },
> + { "Function", COFF::IMAGE_SYM_DTYPE_FUNCTION },
> + { "Array" , COFF::IMAGE_SYM_DTYPE_ARRAY }
> +};
> +
> +static const EnumEntry<COFF::SymbolStorageClass> ImageSymClass[] = {
> + { "EndOfFunction" , COFF::IMAGE_SYM_CLASS_END_OF_FUNCTION },
> + { "Null" , COFF::IMAGE_SYM_CLASS_NULL },
> + { "Automatic" , COFF::IMAGE_SYM_CLASS_AUTOMATIC },
> + { "External" , COFF::IMAGE_SYM_CLASS_EXTERNAL },
> + { "Static" , COFF::IMAGE_SYM_CLASS_STATIC },
> + { "Register" , COFF::IMAGE_SYM_CLASS_REGISTER },
> + { "ExternalDef" , COFF::IMAGE_SYM_CLASS_EXTERNAL_DEF },
> + { "Label" , COFF::IMAGE_SYM_CLASS_LABEL },
> + { "UndefinedLabel" , COFF::IMAGE_SYM_CLASS_UNDEFINED_LABEL },
> + { "MemberOfStruct" , COFF::IMAGE_SYM_CLASS_MEMBER_OF_STRUCT },
> + { "Argument" , COFF::IMAGE_SYM_CLASS_ARGUMENT },
> + { "StructTag" , COFF::IMAGE_SYM_CLASS_STRUCT_TAG },
> + { "MemberOfUnion" , COFF::IMAGE_SYM_CLASS_MEMBER_OF_UNION },
> + { "UnionTag" , COFF::IMAGE_SYM_CLASS_UNION_TAG },
> + { "TypeDefinition" , COFF::IMAGE_SYM_CLASS_TYPE_DEFINITION },
> + { "UndefinedStatic", COFF::IMAGE_SYM_CLASS_UNDEFINED_STATIC },
> + { "EnumTag" , COFF::IMAGE_SYM_CLASS_ENUM_TAG },
> + { "MemberOfEnum" , COFF::IMAGE_SYM_CLASS_MEMBER_OF_ENUM },
> + { "RegisterParam" , COFF::IMAGE_SYM_CLASS_REGISTER_PARAM },
> + { "BitField" , COFF::IMAGE_SYM_CLASS_BIT_FIELD },
> + { "Block" , COFF::IMAGE_SYM_CLASS_BLOCK },
> + { "Function" , COFF::IMAGE_SYM_CLASS_FUNCTION },
> + { "EndOfStruct" , COFF::IMAGE_SYM_CLASS_END_OF_STRUCT },
> + { "File" , COFF::IMAGE_SYM_CLASS_FILE },
> + { "Section" , COFF::IMAGE_SYM_CLASS_SECTION },
> + { "WeakExternal" , COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL },
> + { "CLRToken" , COFF::IMAGE_SYM_CLASS_CLR_TOKEN }
> +};
> +
> +static const EnumEntry<COFF::COMDATType> ImageCOMDATSelect[] = {
> + { "NoDuplicates", COFF::IMAGE_COMDAT_SELECT_NODUPLICATES },
> + { "Any" , COFF::IMAGE_COMDAT_SELECT_ANY },
> + { "SameSize" , COFF::IMAGE_COMDAT_SELECT_SAME_SIZE },
> + { "ExactMatch" , COFF::IMAGE_COMDAT_SELECT_EXACT_MATCH },
> + { "Associative" , COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE },
> + { "Largest" , COFF::IMAGE_COMDAT_SELECT_LARGEST },
> + { "Newest" , COFF::IMAGE_COMDAT_SELECT_NEWEST }
> +};
> +
> +static const EnumEntry<COFF::WeakExternalCharacteristics>
> +WeakExternalCharacteristics[] = {
> + { "NoLibrary", COFF::IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY },
> + { "Library" , COFF::IMAGE_WEAK_EXTERN_SEARCH_LIBRARY },
> + { "Alias" , COFF::IMAGE_WEAK_EXTERN_SEARCH_ALIAS }
> +};
> +
> +static const EnumEntry<unsigned> UnwindFlags[] = {
> + { "ExceptionHandler", Win64EH::UNW_ExceptionHandler },
> + { "TerminateHandler", Win64EH::UNW_TerminateHandler },
> + { "ChainInfo" , Win64EH::UNW_ChainInfo }
> +};
> +
> +static const EnumEntry<unsigned> UnwindOpInfo[] = {
> + { "RAX", 0 },
> + { "RCX", 1 },
> + { "RDX", 2 },
> + { "RBX", 3 },
> + { "RSP", 4 },
> + { "RBP", 5 },
> + { "RSI", 6 },
> + { "RDI", 7 },
> + { "R8", 8 },
> + { "R9", 9 },
> + { "R10", 10 },
> + { "R11", 11 },
> + { "R12", 12 },
> + { "R13", 13 },
> + { "R14", 14 },
> + { "R15", 15 }
> +};
> +
> +// Some additional COFF structures not defined by llvm::object.
> +namespace {
> + struct coff_aux_function_definition {
> + support::ulittle32_t TagIndex;
> + support::ulittle32_t TotalSize;
> + support::ulittle32_t PointerToLineNumber;
> + support::ulittle32_t PointerToNextFunction;
> + uint8_t Unused[2];
> + };
> +
> + struct coff_aux_weak_external_definition {
> + support::ulittle32_t TagIndex;
> + support::ulittle32_t Characteristics;
> + uint8_t Unused[10];
> + };
> +
> + struct coff_aux_file_record {
> + char FileName[18];
> + };
> +
> + struct coff_aux_clr_token {
> + support::ulittle8_t AuxType;
> + support::ulittle8_t Reserved;
> + support::ulittle32_t SymbolTableIndex;
> + uint8_t Unused[12];
> + };
> +} // namespace
> +
> +static uint64_t getOffsetOfLSDA(const Win64EH::UnwindInfo& UI) {
> + return static_cast<const char*>(UI.getLanguageSpecificData())
> + - reinterpret_cast<const char*>(&UI);
> +}
> +
> +static uint32_t getLargeSlotValue(ArrayRef<UnwindCode> UCs) {
> + if (UCs.size() < 3)
> + return 0;
> +
> + return UCs[1].FrameOffset + (static_cast<uint32_t>(UCs[2].FrameOffset) << 16);
> +}
> +
> +template<typename T>
> +static error_code getSymbolAuxData(const COFFObjectFile *Obj,
> + const coff_symbol *Symbol, const T* &Aux) {
> + ArrayRef<uint8_t> AuxData = Obj->getSymbolAuxData(Symbol);
> + Aux = reinterpret_cast<const T*>(AuxData.data());
> + return readobj_error::success;
> +}
> +
> +static std::string formatSymbol(const std::vector<RelocationRef> &Rels,
> + uint64_t Offset, uint32_t Disp) {
> + std::string Buffer;
> + raw_string_ostream Str(Buffer);
> +
> + StringRef Sym;
> + if (resolveSymbolName(Rels, Offset, Sym)) {
> + Str << format(" (0x%X)", Offset);
> + return Str.str();
> + }
> +
> + Str << Sym;
> + if (Disp > 0) {
> + Str << format(" +0x%X (0x%X)", Disp, Offset);
> + } else {
> + Str << format(" (0x%X)", Offset);
> + }
> +
> + return Str.str();
> +}
> +
> +// Given a vector of relocations for a section and an offset into this section
> +// the function resolves the symbol used for the relocation at the offset and
> +// returns the section content and the address inside the content pointed to
> +// by the symbol.
> +error_code COFFDumper::getSectionContents(
> + const std::vector<RelocationRef> &Rels, uint64_t Offset,
> + ArrayRef<uint8_t> &Contents, uint64_t &Addr) {
> +
> + SymbolRef Sym;
> + const coff_section *Section;
> +
> + if (error_code EC = resolveSymbol(Rels, Offset, Sym))
> + return EC;
> + if (error_code EC = resolveSectionAndAddress(Obj, Sym, Section, Addr))
> + return EC;
> + if (error_code EC = Obj->getSectionContents(Section, Contents))
> + return EC;
> +
> + return object_error::success;
> +}
> +
> +error_code COFFDumper::getSection(
> + const std::vector<RelocationRef> &Rels, uint64_t Offset,
> + const coff_section **SectionPtr, uint64_t *AddrPtr) {
> +
> + SymbolRef Sym;
> + if (error_code EC = resolveSymbol(Rels, Offset, Sym))
> + return EC;
> +
> + const coff_section *Section;
> + uint64_t Addr;
> + if (error_code EC = resolveSectionAndAddress(Obj, Sym, Section, Addr))
> + return EC;
> +
> + if (SectionPtr)
> + *SectionPtr = Section;
> + if (AddrPtr)
> + *AddrPtr = Addr;
> +
> + return object_error::success;
> +}
> +
> +void COFFDumper::cacheRelocations() {
> + error_code EC;
> + for (section_iterator SecI = Obj->begin_sections(),
> + SecE = Obj->end_sections();
> + SecI != SecE; SecI.increment(EC)) {
> + if (error(EC))
> + break;
> +
> + const coff_section *Section = Obj->getCOFFSection(SecI);
> +
> + for (relocation_iterator RelI = SecI->begin_relocations(),
> + RelE = SecI->end_relocations();
> + RelI != RelE; RelI.increment(EC)) {
> + if (error(EC))
> + break;
> +
> + RelocMap[Section].push_back(*RelI);
> + }
> +
> + // Sort relocations by address.
> + std::sort(RelocMap[Section].begin(), RelocMap[Section].end(),
> + relocAddressLess);
> + }
> +}
> +
> +void COFFDumper::printFileHeaders() {
> + const coff_file_header *Header = 0;
> + if (error(Obj->getHeader(Header)))
> + return;
> +
> + time_t TDS = Header->TimeDateStamp;
> + char FormattedTime[20] = { };
> + strftime(FormattedTime, 20, "%Y-%m-%d %H:%M:%S", gmtime(&TDS));
> +
> + {
> + DictScope D(W, "ImageFileHeader");
> + W.printEnum ("Machine", Header->Machine,
> + makeArrayRef(ImageFileMachineType));
> + W.printNumber("SectionCount", Header->NumberOfSections);
> + W.printHex ("TimeDateStamp", FormattedTime, Header->TimeDateStamp);
> + W.printHex ("PointerToSymbolTable", Header->PointerToSymbolTable);
> + W.printNumber("SymbolCount", Header->NumberOfSymbols);
> + W.printNumber("OptionalHeaderSize", Header->SizeOfOptionalHeader);
> + W.printFlags ("Characteristics", Header->Characteristics,
> + makeArrayRef(ImageFileCharacteristics));
> + }
> +}
> +
> +void COFFDumper::printSections() {
> + error_code EC;
> +
> + ListScope SectionsD(W, "Sections");
> + int SectionNumber = 0;
> + for (section_iterator SecI = Obj->begin_sections(),
> + SecE = Obj->end_sections();
> + SecI != SecE; SecI.increment(EC)) {
> + if (error(EC))
> + break;
> +
> + ++SectionNumber;
> + const coff_section *Section = Obj->getCOFFSection(SecI);
> +
> + StringRef Name;
> + if (error(SecI->getName(Name)))
> + Name = "";
> +
> + DictScope D(W, "Section");
> + W.printNumber("Number", SectionNumber);
> + W.printBinary("Name", Name, Section->Name);
> + W.printHex ("VirtualSize", Section->VirtualSize);
> + W.printHex ("VirtualAddress", Section->VirtualAddress);
> + W.printNumber("RawDataSize", Section->SizeOfRawData);
> + W.printHex ("PointerToRawData", Section->PointerToRawData);
> + W.printHex ("PointerToRelocations", Section->PointerToRelocations);
> + 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));
> +
> + if (opts::SectionRelocations) {
> + ListScope D(W, "Relocations");
> + for (relocation_iterator RelI = SecI->begin_relocations(),
> + RelE = SecI->end_relocations();
> + RelI != RelE; RelI.increment(EC)) {
> + if (error(EC)) break;
> +
> + printRelocation(SecI, RelI);
> + }
> + }
> +
> + if (opts::SectionSymbols) {
> + ListScope D(W, "Symbols");
> + for (symbol_iterator SymI = Obj->begin_symbols(),
> + SymE = Obj->end_symbols();
> + SymI != SymE; SymI.increment(EC)) {
> + if (error(EC)) break;
> +
> + bool Contained = false;
> + if (SecI->containsSymbol(*SymI, Contained) || !Contained)
> + continue;
> +
> + printSymbol(SymI);
> + }
> + }
> +
> + if (opts::SectionData) {
> + StringRef Data;
> + if (error(SecI->getContents(Data))) break;
> +
> + W.printBinaryBlock("SectionData", Data);
> + }
> + }
> +}
> +
> +void COFFDumper::printRelocations() {
> + ListScope D(W, "Relocations");
> +
> + error_code EC;
> + int SectionNumber = 0;
> + for (section_iterator SecI = Obj->begin_sections(),
> + SecE = Obj->end_sections();
> + SecI != SecE; SecI.increment(EC)) {
> + ++SectionNumber;
> + if (error(EC))
> + break;
> +
> + StringRef Name;
> + if (error(SecI->getName(Name)))
> + continue;
> +
> + bool PrintedGroup = false;
> + for (relocation_iterator RelI = SecI->begin_relocations(),
> + RelE = SecI->end_relocations();
> + RelI != RelE; RelI.increment(EC)) {
> + if (error(EC)) break;
> +
> + if (!PrintedGroup) {
> + W.startLine() << "Section (" << SectionNumber << ") " << Name << " {\n";
> + W.indent();
> + PrintedGroup = true;
> + }
> +
> + printRelocation(SecI, RelI);
> + }
> +
> + if (PrintedGroup) {
> + W.unindent();
> + W.startLine() << "}\n";
> + }
> + }
> +}
> +
> +void COFFDumper::printRelocation(section_iterator SecI,
> + relocation_iterator RelI) {
> + uint64_t Offset;
> + uint64_t RelocType;
> + SmallString<32> RelocName;
> + SymbolRef Symbol;
> + StringRef SymbolName;
> + StringRef Contents;
> + if (error(RelI->getOffset(Offset))) return;
> + if (error(RelI->getType(RelocType))) return;
> + if (error(RelI->getTypeName(RelocName))) return;
> + if (error(RelI->getSymbol(Symbol))) return;
> + if (error(Symbol.getName(SymbolName))) return;
> + if (error(SecI->getContents(Contents))) return;
> +
> + raw_ostream& OS = W.startLine();
> + OS << W.hex(Offset)
> + << " " << RelocName
> + << " " << (SymbolName.size() > 0 ? SymbolName : "-")
> + << "\n";
> +}
> +
> +void COFFDumper::printSymbols() {
> + ListScope Group(W, "Symbols");
> +
> + error_code EC;
> + for (symbol_iterator SymI = Obj->begin_symbols(),
> + SymE = Obj->end_symbols();
> + SymI != SymE; SymI.increment(EC)) {
> + if (error(EC)) break;
> +
> + printSymbol(SymI);
> + }
> +}
> +
> +void COFFDumper::printDynamicSymbols() {
> + ListScope Group(W, "DynamicSymbols");
> +}
> +
> +void COFFDumper::printSymbol(symbol_iterator SymI) {
> + DictScope D(W, "Symbol");
> +
> + const coff_symbol *Symbol = Obj->getCOFFSymbol(SymI);
> + const coff_section *Section;
> + if (error_code EC = Obj->getSection(Symbol->SectionNumber, Section)) {
> + W.startLine() << "Invalid section number: " << EC.message() << "\n";
> + W.flush();
> + return;
> + }
> +
> + StringRef SymbolName;
> + if (Obj->getSymbolName(Symbol, SymbolName))
> + SymbolName = "";
> +
> + StringRef SectionName;
> + if (Section && Obj->getSectionName(Section, SectionName))
> + SectionName = "";
> +
> + W.printString("Name", SymbolName);
> + W.printNumber("Value", Symbol->Value);
> + W.printNumber("Section", SectionName, Symbol->SectionNumber);
> + W.printEnum ("BaseType", Symbol->getBaseType(), makeArrayRef(ImageSymType));
> + W.printEnum ("ComplexType", Symbol->getComplexType(),
> + makeArrayRef(ImageSymDType));
> + W.printEnum ("StorageClass", Symbol->StorageClass,
> + makeArrayRef(ImageSymClass));
> + W.printNumber("AuxSymbolCount", Symbol->NumberOfAuxSymbols);
> +
> + for (unsigned I = 0; I < Symbol->NumberOfAuxSymbols; ++I) {
> + if (Symbol->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL &&
> + Symbol->getBaseType() == COFF::IMAGE_SYM_TYPE_NULL &&
> + Symbol->getComplexType() == COFF::IMAGE_SYM_DTYPE_FUNCTION &&
> + Symbol->SectionNumber > 0) {
> + const coff_aux_function_definition *Aux;
> + if (error(getSymbolAuxData(Obj, Symbol + I, Aux)))
> + break;
> +
> + DictScope AS(W, "AuxFunctionDef");
> + W.printNumber("TagIndex", Aux->TagIndex);
> + W.printNumber("TotalSize", Aux->TotalSize);
> + W.printHex("PointerToLineNumber", Aux->PointerToLineNumber);
> + W.printHex("PointerToNextFunction", Aux->PointerToNextFunction);
> + W.printBinary("Unused", makeArrayRef(Aux->Unused));
> +
> + } else if (
> + Symbol->StorageClass == COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL ||
> + (Symbol->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL &&
> + Symbol->SectionNumber == 0 &&
> + Symbol->Value == 0)) {
> + const coff_aux_weak_external_definition *Aux;
> + if (error(getSymbolAuxData(Obj, Symbol + I, Aux)))
> + break;
> +
> + const coff_symbol *Linked;
> + StringRef LinkedName;
> + error_code EC;
> + if ((EC = Obj->getSymbol(Aux->TagIndex, Linked)) ||
> + (EC = Obj->getSymbolName(Linked, LinkedName))) {
> + LinkedName = "";
> + error(EC);
> + }
> +
> + DictScope AS(W, "AuxWeakExternal");
> + W.printNumber("Linked", LinkedName, Aux->TagIndex);
> + W.printEnum ("Search", Aux->Characteristics,
> + makeArrayRef(WeakExternalCharacteristics));
> + W.printBinary("Unused", Aux->Unused);
> +
> + } else if (Symbol->StorageClass == COFF::IMAGE_SYM_CLASS_FILE) {
> + const coff_aux_file_record *Aux;
> + if (error(getSymbolAuxData(Obj, Symbol + I, Aux)))
> + break;
> +
> + } else if (Symbol->StorageClass == COFF::IMAGE_SYM_CLASS_STATIC) {
> + const coff_aux_section_definition *Aux;
> + if (error(getSymbolAuxData(Obj, Symbol + I, Aux)))
> + break;
> +
> + DictScope AS(W, "AuxSectionDef");
> + W.printNumber("Length", Aux->Length);
> + W.printNumber("RelocationCount", Aux->NumberOfRelocations);
> + W.printNumber("LineNumberCount", Aux->NumberOfLinenumbers);
> + W.printHex("Checksum", Aux->CheckSum);
> + W.printNumber("Number", Aux->Number);
> + W.printEnum("Selection", Aux->Selection, makeArrayRef(ImageCOMDATSelect));
> + W.printBinary("Unused", makeArrayRef(Aux->Unused));
> +
> + if (Section->Characteristics & COFF::IMAGE_SCN_LNK_COMDAT
> + && Aux->Selection == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) {
> + const coff_section *Assoc;
> + StringRef AssocName;
> + error_code EC;
> + if ((EC = Obj->getSection(Aux->Number, Assoc)) ||
> + (EC = Obj->getSectionName(Assoc, AssocName))) {
> + AssocName = "";
> + error(EC);
> + }
> +
> + W.printNumber("AssocSection", AssocName, Aux->Number);
> + }
> + } else if (Symbol->StorageClass == COFF::IMAGE_SYM_CLASS_CLR_TOKEN) {
> + const coff_aux_clr_token *Aux;
> + if (error(getSymbolAuxData(Obj, Symbol + I, Aux)))
> + break;
> +
> + DictScope AS(W, "AuxCLRToken");
> + W.printNumber("AuxType", Aux->AuxType);
> + W.printNumber("Reserved", Aux->Reserved);
> + W.printNumber("SymbolTableIndex", Aux->SymbolTableIndex);
> + W.printBinary("Unused", Aux->Unused);
> +
> + } else {
> + W.startLine() << "<unhandled auxiliary record>\n";
> + }
> + }
> +}
> +
> +void COFFDumper::printUnwindInfo() {
> + const coff_file_header *Header;
> + if (error(Obj->getHeader(Header)))
> + return;
> +
> + ListScope D(W, "UnwindInformation");
> + if (Header->Machine != COFF::IMAGE_FILE_MACHINE_AMD64) {
> + W.startLine() << "Unsupported image machine type "
> + "(currently only AMD64 is supported).\n";
> + return;
> + }
> +
> + printX64UnwindInfo();
> +}
> +
> +void COFFDumper::printX64UnwindInfo() {
> + error_code EC;
> + for (section_iterator SecI = Obj->begin_sections(),
> + SecE = Obj->end_sections();
> + SecI != SecE; SecI.increment(EC)) {
> + if (error(EC)) break;
> +
> + StringRef Name;
> + if (error(SecI->getName(Name)))
> + continue;
> + if (Name != ".pdata" && !Name.startswith(".pdata$"))
> + continue;
> +
> + const coff_section *PData = Obj->getCOFFSection(SecI);
> +
> + ArrayRef<uint8_t> Contents;
> + if (error(Obj->getSectionContents(PData, Contents)) ||
> + Contents.empty())
> + continue;
> +
> + ArrayRef<RuntimeFunction> RFs(
> + reinterpret_cast<const RuntimeFunction *>(Contents.data()),
> + Contents.size() / sizeof(RuntimeFunction));
> +
> + for (const RuntimeFunction *I = RFs.begin(), *E = RFs.end(); I < E; ++I) {
> + const uint64_t OffsetInSection = std::distance(RFs.begin(), I)
> + * sizeof(RuntimeFunction);
> +
> + printRuntimeFunction(*I, OffsetInSection, RelocMap[PData]);
> + }
> + }
> +}
> +
> +void COFFDumper::printRuntimeFunction(
> + const RuntimeFunction& RTF,
> + uint64_t OffsetInSection,
> + const std::vector<RelocationRef> &Rels) {
> +
> + DictScope D(W, "RuntimeFunction");
> + W.printString("StartAddress",
> + formatSymbol(Rels, OffsetInSection + 0, RTF.StartAddress));
> + W.printString("EndAddress",
> + formatSymbol(Rels, OffsetInSection + 4, RTF.EndAddress));
> + W.printString("UnwindInfoAddress",
> + formatSymbol(Rels, OffsetInSection + 8, RTF.UnwindInfoOffset));
> +
> + const coff_section* XData = 0;
> + uint64_t UnwindInfoOffset = 0;
> + if (error(getSection(Rels, OffsetInSection + 8, &XData, &UnwindInfoOffset)))
> + return;
> +
> + ArrayRef<uint8_t> XContents;
> + if (error(Obj->getSectionContents(XData, XContents)) || XContents.empty())
> + return;
> +
> + UnwindInfoOffset += RTF.UnwindInfoOffset;
> + if (UnwindInfoOffset > XContents.size())
> + return;
> +
> + const Win64EH::UnwindInfo *UI =
> + reinterpret_cast<const Win64EH::UnwindInfo *>(
> + XContents.data() + UnwindInfoOffset);
> +
> + printUnwindInfo(*UI, UnwindInfoOffset, RelocMap[XData]);
> +}
> +
> +void COFFDumper::printUnwindInfo(
> + const Win64EH::UnwindInfo& UI,
> + uint64_t OffsetInSection,
> + const std::vector<RelocationRef> &Rels) {
> + DictScope D(W, "UnwindInfo");
> + W.printNumber("Version", UI.getVersion());
> + W.printFlags("Flags", UI.getFlags(), makeArrayRef(UnwindFlags));
> + W.printNumber("PrologSize", UI.PrologSize);
> + if (UI.getFrameRegister() != 0) {
> + W.printEnum("FrameRegister", UI.getFrameRegister(),
> + makeArrayRef(UnwindOpInfo));
> + W.printHex("FrameOffset", UI.getFrameOffset());
> + } else {
> + W.printString("FrameRegister", StringRef("-"));
> + W.printString("FrameOffset", StringRef("-"));
> + }
> +
> + W.printNumber("UnwindCodeCount", UI.NumCodes);
> + {
> + ListScope CodesD(W, "UnwindCodes");
> + ArrayRef<UnwindCode> UCs(&UI.UnwindCodes[0], UI.NumCodes);
> + for (const UnwindCode *I = UCs.begin(), *E = UCs.end(); I < E; ++I) {
> + unsigned UsedSlots = getNumUsedSlots(*I);
> + if (UsedSlots > UCs.size()) {
> + errs() << "Corrupt unwind data";
> + return;
> + }
> + printUnwindCode(UI, ArrayRef<UnwindCode>(I, E));
> + I += UsedSlots - 1;
> + }
> + }
> +
> + uint64_t LSDAOffset = OffsetInSection + getOffsetOfLSDA(UI);
> + if (UI.getFlags() & (UNW_ExceptionHandler | UNW_TerminateHandler)) {
> + W.printString("Handler", formatSymbol(Rels, LSDAOffset,
> + UI.getLanguageSpecificHandlerOffset()));
> + } else if (UI.getFlags() & UNW_ChainInfo) {
> + const RuntimeFunction *Chained = UI.getChainedFunctionEntry();
> + if (Chained) {
> + DictScope D(W, "Chained");
> + W.printString("StartAddress", formatSymbol(Rels, LSDAOffset + 0,
> + Chained->StartAddress));
> + W.printString("EndAddress", formatSymbol(Rels, LSDAOffset + 4,
> + Chained->EndAddress));
> + W.printString("UnwindInfoAddress", formatSymbol(Rels, LSDAOffset + 8,
> + Chained->UnwindInfoOffset));
> + }
> + }
> +}
> +
> +// Prints one unwind code. Because an unwind code can occupy up to 3 slots in
> +// the unwind codes array, this function requires that the correct number of
> +// slots is provided.
> +void COFFDumper::printUnwindCode(const Win64EH::UnwindInfo& UI,
> + ArrayRef<UnwindCode> UCs) {
> + assert(UCs.size() >= getNumUsedSlots(UCs[0]));
> +
> + W.startLine() << format("0x%02X: ", unsigned(UCs[0].u.CodeOffset))
> + << getUnwindCodeTypeName(UCs[0].getUnwindOp());
> +
> + uint32_t AllocSize = 0;
> +
> + switch (UCs[0].getUnwindOp()) {
> + case UOP_PushNonVol:
> + outs() << " reg=" << getUnwindRegisterName(UCs[0].getOpInfo());
> + break;
> +
> + case UOP_AllocLarge:
> + if (UCs[0].getOpInfo() == 0) {
> + AllocSize = UCs[1].FrameOffset * 8;
> + } else {
> + AllocSize = getLargeSlotValue(UCs);
> + }
> + outs() << " size=" << AllocSize;
> + break;
> + case UOP_AllocSmall:
> + outs() << " size=" << ((UCs[0].getOpInfo() + 1) * 8);
> + break;
> + case UOP_SetFPReg:
> + if (UI.getFrameRegister() == 0) {
> + outs() << " reg=<invalid>";
> + } else {
> + outs() << " reg=" << getUnwindRegisterName(UI.getFrameRegister())
> + << format(", offset=0x%X", UI.getFrameOffset() * 16);
> + }
> + break;
> + case UOP_SaveNonVol:
> + outs() << " reg=" << getUnwindRegisterName(UCs[0].getOpInfo())
> + << format(", offset=0x%X", UCs[1].FrameOffset * 8);
> + break;
> + case UOP_SaveNonVolBig:
> + outs() << " reg=" << getUnwindRegisterName(UCs[0].getOpInfo())
> + << format(", offset=0x%X", getLargeSlotValue(UCs));
> + break;
> + case UOP_SaveXMM128:
> + outs() << " reg=XMM" << static_cast<uint32_t>(UCs[0].getOpInfo())
> + << format(", offset=0x%X", UCs[1].FrameOffset * 16);
> + break;
> + case UOP_SaveXMM128Big:
> + outs() << " reg=XMM" << static_cast<uint32_t>(UCs[0].getOpInfo())
> + << format(", offset=0x%X", getLargeSlotValue(UCs));
> + break;
> + case UOP_PushMachFrame:
> + outs() << " errcode=" << (UCs[0].getOpInfo() == 0 ? "no" : "yes");
> + break;
> + }
> +
> + outs() << "\n";
> +}
>
> Removed: llvm/trunk/tools/llvm-readobj/ELF.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/ELF.cpp?rev=178678&view=auto
> ==============================================================================
> --- llvm/trunk/tools/llvm-readobj/ELF.cpp (original)
> +++ llvm/trunk/tools/llvm-readobj/ELF.cpp (removed)
> @@ -1,196 +0,0 @@
> -//===- llvm-readobj/ELF.cpp - ELF Specific Dumper -------------------------===//
> -//
> -// The LLVM Compiler Infrastructure
> -//
> -// This file is distributed under the University of Illinois Open Source
> -// License. See LICENSE.TXT for details.
> -//
> -//===----------------------------------------------------------------------===//
> -
> -#include "llvm-readobj.h"
> -
> -#include "llvm/Object/ELF.h"
> -#include "llvm/Support/Casting.h"
> -#include "llvm/Support/Format.h"
> -
> -namespace llvm {
> -using namespace object;
> -using namespace ELF;
> -
> -const char *getTypeString(uint64_t Type) {
> - switch (Type) {
> - case DT_BIND_NOW:
> - return "(BIND_NOW)";
> - case DT_DEBUG:
> - return "(DEBUG)";
> - case DT_FINI:
> - return "(FINI)";
> - case DT_FINI_ARRAY:
> - return "(FINI_ARRAY)";
> - case DT_FINI_ARRAYSZ:
> - return "(FINI_ARRAYSZ)";
> - case DT_FLAGS:
> - return "(FLAGS)";
> - case DT_HASH:
> - return "(HASH)";
> - case DT_INIT:
> - return "(INIT)";
> - case DT_INIT_ARRAY:
> - return "(INIT_ARRAY)";
> - case DT_INIT_ARRAYSZ:
> - return "(INIT_ARRAYSZ)";
> - case DT_PREINIT_ARRAY:
> - return "(PREINIT_ARRAY)";
> - case DT_PREINIT_ARRAYSZ:
> - return "(PREINIT_ARRAYSZ)";
> - case DT_JMPREL:
> - return "(JMPREL)";
> - case DT_NEEDED:
> - return "(NEEDED)";
> - case DT_NULL:
> - return "(NULL)";
> - case DT_PLTGOT:
> - return "(PLTGOT)";
> - case DT_PLTREL:
> - return "(PLTREL)";
> - case DT_PLTRELSZ:
> - return "(PLTRELSZ)";
> - case DT_REL:
> - return "(REL)";
> - case DT_RELA:
> - return "(RELA)";
> - case DT_RELENT:
> - return "(RELENT)";
> - case DT_RELSZ:
> - return "(RELSZ)";
> - case DT_RELAENT:
> - return "(RELAENT)";
> - case DT_RELASZ:
> - return "(RELASZ)";
> - case DT_RPATH:
> - return "(RPATH)";
> - case DT_RUNPATH:
> - return "(RUNPATH)";
> - case DT_SONAME:
> - return "(SONAME)";
> - case DT_STRSZ:
> - return "(STRSZ)";
> - case DT_STRTAB:
> - return "(STRTAB)";
> - case DT_SYMBOLIC:
> - return "(SYMBOLIC)";
> - case DT_SYMENT:
> - return "(SYMENT)";
> - case DT_SYMTAB:
> - return "(SYMTAB)";
> - case DT_TEXTREL:
> - return "(TEXTREL)";
> - default:
> - return "unknown";
> - }
> -}
> -
> -template <class ELFT>
> -void printValue(const ELFObjectFile<ELFT> *O, uint64_t Type, uint64_t Value,
> - bool Is64, raw_ostream &OS) {
> - switch (Type) {
> - case DT_PLTREL:
> - if (Value == DT_REL) {
> - OS << "REL";
> - break;
> - } else if (Value == DT_RELA) {
> - OS << "RELA";
> - break;
> - }
> - // Fallthrough.
> - case DT_PLTGOT:
> - case DT_HASH:
> - case DT_STRTAB:
> - case DT_SYMTAB:
> - case DT_RELA:
> - case DT_INIT:
> - case DT_FINI:
> - case DT_REL:
> - case DT_JMPREL:
> - case DT_INIT_ARRAY:
> - case DT_FINI_ARRAY:
> - case DT_PREINIT_ARRAY:
> - case DT_DEBUG:
> - case DT_NULL:
> - OS << format("0x%" PRIx64, Value);
> - break;
> - case DT_PLTRELSZ:
> - case DT_RELASZ:
> - case DT_RELAENT:
> - case DT_STRSZ:
> - case DT_SYMENT:
> - case DT_RELSZ:
> - case DT_RELENT:
> - case DT_INIT_ARRAYSZ:
> - case DT_FINI_ARRAYSZ:
> - case DT_PREINIT_ARRAYSZ:
> - OS << Value << " (bytes)";
> - break;
> - case DT_NEEDED:
> - OS << "Shared library: ["
> - << O->getString(O->getDynamicStringTableSectionHeader(), Value) << "]";
> - break;
> - case DT_SONAME:
> - OS << "Library soname: ["
> - << O->getString(O->getDynamicStringTableSectionHeader(), Value) << "]";
> - break;
> - }
> -}
> -
> -template <class ELFT>
> -ErrorOr<void> dumpDynamicTable(const ELFObjectFile<ELFT> *O, raw_ostream &OS) {
> - typedef ELFObjectFile<ELFT> ELFO;
> - typedef typename ELFO::Elf_Dyn_iterator EDI;
> - EDI Start = O->begin_dynamic_table(),
> - End = O->end_dynamic_table(true);
> -
> - if (Start == End)
> - return error_code::success();
> -
> - ptrdiff_t Total = std::distance(Start, End);
> - OS << "Dynamic section contains " << Total << " entries\n";
> -
> - bool Is64 = O->getBytesInAddress() == 8;
> -
> - OS << " Tag" << (Is64 ? " " : " ") << "Type"
> - << " " << "Name/Value\n";
> - for (; Start != End; ++Start) {
> - OS << " "
> - << format(Is64 ? "0x%016" PRIx64 : "0x%08" PRIx64, Start->getTag())
> - << " " << format("%-21s", getTypeString(Start->getTag()));
> - printValue(O, Start->getTag(), Start->getVal(), Is64, OS);
> - OS << "\n";
> - }
> -
> - OS << " Total: " << Total << "\n\n";
> - return error_code::success();
> -}
> -
> -ErrorOr<void> dumpELFDynamicTable(ObjectFile *O, raw_ostream &OS) {
> - // Little-endian 32-bit
> - if (const ELFObjectFile<ELFType<support::little, 4, false> > *ELFObj =
> - dyn_cast<ELFObjectFile<ELFType<support::little, 4, false> > >(O))
> - return dumpDynamicTable(ELFObj, OS);
> -
> - // Big-endian 32-bit
> - if (const ELFObjectFile<ELFType<support::big, 4, false> > *ELFObj =
> - dyn_cast<ELFObjectFile<ELFType<support::big, 4, false> > >(O))
> - return dumpDynamicTable(ELFObj, OS);
> -
> - // Little-endian 64-bit
> - if (const ELFObjectFile<ELFType<support::little, 8, true> > *ELFObj =
> - dyn_cast<ELFObjectFile<ELFType<support::little, 8, true> > >(O))
> - return dumpDynamicTable(ELFObj, OS);
> -
> - // Big-endian 64-bit
> - if (const ELFObjectFile<ELFType<support::big, 8, true> > *ELFObj =
> - dyn_cast<ELFObjectFile<ELFType<support::big, 8, true> > >(O))
> - return dumpDynamicTable(ELFObj, OS);
> - return error_code(object_error::invalid_file_type);
> -}
> -} // end namespace llvm
>
> Added: llvm/trunk/tools/llvm-readobj/ELFDumper.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/ELFDumper.cpp?rev=178679&view=auto
> ==============================================================================
> --- llvm/trunk/tools/llvm-readobj/ELFDumper.cpp (added)
> +++ llvm/trunk/tools/llvm-readobj/ELFDumper.cpp Wed Apr 3 13:31:38 2013
> @@ -0,0 +1,800 @@
> +//===-- ELFDumper.cpp - ELF-specific dumper ---------------------*- C++ -*-===//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===----------------------------------------------------------------------===//
> +///
> +/// \file
> +/// \brief This file implements the ELF-specific dumper for llvm-readobj.
> +///
> +//===----------------------------------------------------------------------===//
> +
> +#include "llvm-readobj.h"
> +#include "Error.h"
> +#include "ObjDumper.h"
> +#include "StreamWriter.h"
> +
> +#include "llvm/ADT/SmallString.h"
> +#include "llvm/Object/ELF.h"
> +#include "llvm/Support/Compiler.h"
> +#include "llvm/Support/Format.h"
> +#include "llvm/Support/MathExtras.h"
> +#include "llvm/Support/raw_ostream.h"
> +
> +using namespace llvm;
> +using namespace llvm::object;
> +using namespace ELF;
> +
> +
> +#define LLVM_READOBJ_ENUM_CASE(ns, enum) \
> + case ns::enum: return #enum;
> +
> +namespace {
> +
> +template<typename ELFT>
> +class ELFDumper : public ObjDumper {
> +public:
> + ELFDumper(const ELFObjectFile<ELFT> *Obj, StreamWriter& Writer)
> + : ObjDumper(Writer)
> + , Obj(Obj) { }
> +
> + virtual void printFileHeaders() LLVM_OVERRIDE;
> + virtual void printSections() LLVM_OVERRIDE;
> + virtual void printRelocations() LLVM_OVERRIDE;
> + virtual void printSymbols() LLVM_OVERRIDE;
> + virtual void printDynamicSymbols() LLVM_OVERRIDE;
> + virtual void printUnwindInfo() LLVM_OVERRIDE;
> +
> + virtual void printDynamicTable() LLVM_OVERRIDE;
> + virtual void printNeededLibraries() LLVM_OVERRIDE;
> +
> +private:
> + typedef typename ELFObjectFile<ELFT>::Elf_Shdr Elf_Shdr;
> + typedef typename ELFObjectFile<ELFT>::Elf_Sym Elf_Sym;
> +
> + void printSymbol(symbol_iterator SymI, bool IsDynamic = false);
> +
> + void printRelocation(section_iterator SecI, relocation_iterator RelI);
> +
> + const ELFObjectFile<ELFT> *Obj;
> +};
> +
> +} // namespace
> +
> +
> +namespace llvm {
> +
> +error_code createELFDumper(const object::ObjectFile *Obj,
> + StreamWriter& Writer,
> + OwningPtr<ObjDumper> &Result) {
> + typedef ELFType<support::little, 4, false> Little32ELF;
> + typedef ELFType<support::big, 4, false> Big32ELF;
> + typedef ELFType<support::little, 4, true > Little64ELF;
> + typedef ELFType<support::big, 8, true > Big64ELF;
> +
> + typedef ELFObjectFile<Little32ELF> LittleELF32Obj;
> + typedef ELFObjectFile<Big32ELF > BigELF32Obj;
> + typedef ELFObjectFile<Little64ELF> LittleELF64Obj;
> + typedef ELFObjectFile<Big64ELF > BigELF64Obj;
> +
> + // Little-endian 32-bit
> + if (const LittleELF32Obj *ELFObj = dyn_cast<LittleELF32Obj>(Obj)) {
> + Result.reset(new ELFDumper<Little32ELF>(ELFObj, Writer));
> + return readobj_error::success;
> + }
> +
> + // Big-endian 32-bit
> + if (const BigELF32Obj *ELFObj = dyn_cast<BigELF32Obj>(Obj)) {
> + Result.reset(new ELFDumper<Big32ELF>(ELFObj, Writer));
> + return readobj_error::success;
> + }
> +
> + // Little-endian 64-bit
> + if (const LittleELF64Obj *ELFObj = dyn_cast<LittleELF64Obj>(Obj)) {
> + Result.reset(new ELFDumper<Little64ELF>(ELFObj, Writer));
> + return readobj_error::success;
> + }
> +
> + // Big-endian 64-bit
> + if (const BigELF64Obj *ELFObj = dyn_cast<BigELF64Obj>(Obj)) {
> + Result.reset(new ELFDumper<Big64ELF>(ELFObj, Writer));
> + return readobj_error::success;
> + }
> +
> + return readobj_error::unsupported_obj_file_format;
> +}
> +
> +} // namespace llvm
> +
> +
> +static const EnumEntry<unsigned> ElfClass[] = {
> + { "None", ELF::ELFCLASSNONE },
> + { "32-bit", ELF::ELFCLASS32 },
> + { "64-bit", ELF::ELFCLASS64 },
> +};
> +
> +static const EnumEntry<unsigned> ElfDataEncoding[] = {
> + { "None", ELF::ELFDATANONE },
> + { "LittleEndian", ELF::ELFDATA2LSB },
> + { "BigEndian", ELF::ELFDATA2MSB },
> +};
> +
> +static const EnumEntry<unsigned> ElfObjectFileType[] = {
> + { "None", ELF::ET_NONE },
> + { "Relocatable", ELF::ET_REL },
> + { "Executable", ELF::ET_EXEC },
> + { "SharedObject", ELF::ET_DYN },
> + { "Core", ELF::ET_CORE },
> +};
> +
> +static const EnumEntry<unsigned> ElfOSABI[] = {
> + { "SystemV", ELF::ELFOSABI_NONE },
> + { "HPUX", ELF::ELFOSABI_HPUX },
> + { "NetBSD", ELF::ELFOSABI_NETBSD },
> + { "GNU/Linux", ELF::ELFOSABI_LINUX },
> + { "GNU/Hurd", ELF::ELFOSABI_HURD },
> + { "Solaris", ELF::ELFOSABI_SOLARIS },
> + { "AIX", ELF::ELFOSABI_AIX },
> + { "IRIX", ELF::ELFOSABI_IRIX },
> + { "FreeBSD", ELF::ELFOSABI_FREEBSD },
> + { "TRU64", ELF::ELFOSABI_TRU64 },
> + { "Modesto", ELF::ELFOSABI_MODESTO },
> + { "OpenBSD", ELF::ELFOSABI_OPENBSD },
> + { "OpenVMS", ELF::ELFOSABI_OPENVMS },
> + { "NSK", ELF::ELFOSABI_NSK },
> + { "AROS", ELF::ELFOSABI_AROS },
> + { "FenixOS", ELF::ELFOSABI_FENIXOS },
> + { "C6000_ELFABI", ELF::ELFOSABI_C6000_ELFABI },
> + { "C6000_LINUX" , ELF::ELFOSABI_C6000_LINUX },
> + { "ARM", ELF::ELFOSABI_ARM },
> + { "Standalone" , ELF::ELFOSABI_STANDALONE }
> +};
> +
> +static const EnumEntry<unsigned> ElfMachineType[] = {
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_NONE ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_M32 ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_SPARC ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_386 ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_68K ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_88K ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_486 ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_860 ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_MIPS ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_S370 ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_MIPS_RS3_LE ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_PARISC ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_VPP500 ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_SPARC32PLUS ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_960 ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_PPC ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_PPC64 ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_S390 ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_SPU ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_V800 ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_FR20 ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_RH32 ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_RCE ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_ARM ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_ALPHA ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_SH ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_SPARCV9 ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_TRICORE ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_ARC ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_H8_300 ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_H8_300H ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_H8S ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_H8_500 ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_IA_64 ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_MIPS_X ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_COLDFIRE ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_68HC12 ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_MMA ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_PCP ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_NCPU ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_NDR1 ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_STARCORE ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_ME16 ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_ST100 ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_TINYJ ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_X86_64 ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_PDSP ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_PDP10 ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_PDP11 ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_FX66 ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_ST9PLUS ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_ST7 ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_68HC16 ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_68HC11 ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_68HC08 ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_68HC05 ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_SVX ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_ST19 ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_VAX ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_CRIS ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_JAVELIN ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_FIREPATH ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_ZSP ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_MMIX ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_HUANY ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_PRISM ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_AVR ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_FR30 ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_D10V ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_D30V ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_V850 ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_M32R ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_MN10300 ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_MN10200 ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_PJ ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_OPENRISC ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_ARC_COMPACT ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_XTENSA ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_VIDEOCORE ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_TMM_GPP ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_NS32K ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_TPC ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_SNP1K ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_ST200 ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_IP2K ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_MAX ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_CR ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_F2MC16 ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_MSP430 ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_BLACKFIN ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_SE_C33 ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_SEP ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_ARCA ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_UNICORE ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_EXCESS ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_DXP ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_ALTERA_NIOS2 ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_CRX ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_XGATE ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_C166 ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_M16C ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_DSPIC30F ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_CE ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_M32C ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_TSK3000 ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_RS08 ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_SHARC ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_ECOG2 ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_SCORE7 ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_DSP24 ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_VIDEOCORE3 ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_LATTICEMICO32),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_SE_C17 ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_TI_C6000 ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_TI_C2000 ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_TI_C5500 ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_MMDSP_PLUS ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_CYPRESS_M8C ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_R32C ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_TRIMEDIA ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_HEXAGON ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_8051 ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_STXP7X ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_NDS32 ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_ECOG1 ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_ECOG1X ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_MAXQ30 ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_XIMO16 ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_MANIK ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_CRAYNV2 ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_RX ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_METAG ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_MCST_ELBRUS ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_ECOG16 ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_CR16 ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_ETPU ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_SLE9X ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_L10M ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_K10M ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_AARCH64 ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_AVR32 ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_STM8 ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_TILE64 ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_TILEPRO ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_MICROBLAZE ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_CUDA ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_TILEGX ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_CLOUDSHIELD ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_COREA_1ST ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_COREA_2ND ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_ARC_COMPACT2 ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_OPEN8 ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_RL78 ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_VIDEOCORE5 ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_78KOR ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_56800EX ),
> + LLVM_READOBJ_ENUM_ENT(ELF, EM_MBLAZE )
> +};
> +
> +static const EnumEntry<unsigned> ElfSymbolBindings[] = {
> + { "Local", ELF::STB_LOCAL },
> + { "Global", ELF::STB_GLOBAL },
> + { "Weak", ELF::STB_WEAK }
> +};
> +
> +static const EnumEntry<unsigned> ElfSymbolTypes[] = {
> + { "None", ELF::STT_NOTYPE },
> + { "Object", ELF::STT_OBJECT },
> + { "Function", ELF::STT_FUNC },
> + { "Section", ELF::STT_SECTION },
> + { "File", ELF::STT_FILE },
> + { "Common", ELF::STT_COMMON },
> + { "TLS", ELF::STT_TLS },
> + { "GNU_IFunc", ELF::STT_GNU_IFUNC }
> +};
> +
> +static const char *getElfSectionType(unsigned Arch, unsigned Type) {
> + switch (Arch) {
> + case Triple::arm:
> + switch (Type) {
> + LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_EXIDX);
> + LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_PREEMPTMAP);
> + LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_ATTRIBUTES);
> + LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_DEBUGOVERLAY);
> + LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_OVERLAYSECTION);
> + }
> + case Triple::hexagon:
> + switch (Type) {
> + LLVM_READOBJ_ENUM_CASE(ELF, SHT_HEX_ORDERED);
> + }
> + case Triple::x86_64:
> + switch (Type) {
> + LLVM_READOBJ_ENUM_CASE(ELF, SHT_X86_64_UNWIND);
> + }
> + case Triple::mips:
> + case Triple::mipsel:
> + switch (Type) {
> + LLVM_READOBJ_ENUM_CASE(ELF, SHT_MIPS_REGINFO);
> + LLVM_READOBJ_ENUM_CASE(ELF, SHT_MIPS_OPTIONS);
> + }
> + }
> +
> + switch (Type) {
> + LLVM_READOBJ_ENUM_CASE(ELF, SHT_NULL );
> + LLVM_READOBJ_ENUM_CASE(ELF, SHT_PROGBITS );
> + LLVM_READOBJ_ENUM_CASE(ELF, SHT_SYMTAB );
> + LLVM_READOBJ_ENUM_CASE(ELF, SHT_STRTAB );
> + LLVM_READOBJ_ENUM_CASE(ELF, SHT_RELA );
> + LLVM_READOBJ_ENUM_CASE(ELF, SHT_HASH );
> + LLVM_READOBJ_ENUM_CASE(ELF, SHT_DYNAMIC );
> + LLVM_READOBJ_ENUM_CASE(ELF, SHT_NOTE );
> + LLVM_READOBJ_ENUM_CASE(ELF, SHT_NOBITS );
> + LLVM_READOBJ_ENUM_CASE(ELF, SHT_REL );
> + LLVM_READOBJ_ENUM_CASE(ELF, SHT_SHLIB );
> + LLVM_READOBJ_ENUM_CASE(ELF, SHT_DYNSYM );
> + LLVM_READOBJ_ENUM_CASE(ELF, SHT_INIT_ARRAY );
> + LLVM_READOBJ_ENUM_CASE(ELF, SHT_FINI_ARRAY );
> + LLVM_READOBJ_ENUM_CASE(ELF, SHT_PREINIT_ARRAY );
> + LLVM_READOBJ_ENUM_CASE(ELF, SHT_GROUP );
> + LLVM_READOBJ_ENUM_CASE(ELF, SHT_SYMTAB_SHNDX );
> + LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_ATTRIBUTES );
> + LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_HASH );
> + LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_verdef );
> + LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_verneed );
> + LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_versym );
> + default: return "";
> + }
> +}
> +
> +static const EnumEntry<unsigned> ElfSectionFlags[] = {
> + LLVM_READOBJ_ENUM_ENT(ELF, SHF_WRITE ),
> + LLVM_READOBJ_ENUM_ENT(ELF, SHF_ALLOC ),
> + LLVM_READOBJ_ENUM_ENT(ELF, SHF_EXECINSTR ),
> + LLVM_READOBJ_ENUM_ENT(ELF, SHF_MERGE ),
> + LLVM_READOBJ_ENUM_ENT(ELF, SHF_STRINGS ),
> + LLVM_READOBJ_ENUM_ENT(ELF, SHF_INFO_LINK ),
> + LLVM_READOBJ_ENUM_ENT(ELF, SHF_LINK_ORDER ),
> + LLVM_READOBJ_ENUM_ENT(ELF, SHF_OS_NONCONFORMING),
> + LLVM_READOBJ_ENUM_ENT(ELF, SHF_GROUP ),
> + LLVM_READOBJ_ENUM_ENT(ELF, SHF_TLS ),
> + LLVM_READOBJ_ENUM_ENT(ELF, XCORE_SHF_CP_SECTION),
> + LLVM_READOBJ_ENUM_ENT(ELF, XCORE_SHF_DP_SECTION),
> + LLVM_READOBJ_ENUM_ENT(ELF, SHF_MIPS_NOSTRIP )
> +};
> +
> +
> +template<class ELFT>
> +void ELFDumper<ELFT>::printFileHeaders() {
> + error_code EC;
> + typedef ELFObjectFile<ELFT> ELFO;
> +
> + const typename ELFO::Elf_Ehdr *Header = Obj->getElfHeader();
> +
> + {
> + DictScope D(W, "ElfHeader");
> + {
> + DictScope D(W, "Ident");
> + W.printBinary("Magic", makeArrayRef(Header->e_ident).slice(ELF::EI_MAG0,
> + 4));
> + W.printEnum ("Class", Header->e_ident[ELF::EI_CLASS],
> + makeArrayRef(ElfClass));
> + W.printEnum ("DataEncoding", Header->e_ident[ELF::EI_DATA],
> + makeArrayRef(ElfDataEncoding));
> + W.printNumber("FileVersion", Header->e_ident[ELF::EI_VERSION]);
> + W.printEnum ("OS/ABI", Header->e_ident[ELF::EI_OSABI],
> + makeArrayRef(ElfOSABI));
> + W.printNumber("ABIVersion", Header->e_ident[ELF::EI_ABIVERSION]);
> + W.printBinary("Unused", makeArrayRef(Header->e_ident).slice(ELF::EI_PAD));
> + }
> +
> + W.printEnum ("Type", Header->e_type, makeArrayRef(ElfObjectFileType));
> + W.printEnum ("Machine", Header->e_machine, makeArrayRef(ElfMachineType));
> + W.printNumber("Version", Header->e_version);
> + W.printHex ("Entry", Header->e_entry);
> + W.printHex ("ProgramHeaderOffset", Header->e_phoff);
> + W.printHex ("SectionHeaderOffset", Header->e_shoff);
> + W.printFlags ("Flags", Header->e_flags);
> + W.printNumber("HeaderSize", Header->e_ehsize);
> + W.printNumber("ProgramHeaderEntrySize", Header->e_phentsize);
> + W.printNumber("ProgramHeaderCount", Header->e_phnum);
> + W.printNumber("SectionHeaderEntrySize", Header->e_shentsize);
> + W.printNumber("SectionHeaderCount", Header->e_shnum);
> + W.printNumber("StringTableSectionIndex", Header->e_shstrndx);
> + }
> +}
> +
> +template<class ELFT>
> +void ELFDumper<ELFT>::printSections() {
> + ListScope SectionsD(W, "Sections");
> +
> + int SectionIndex = -1;
> + error_code EC;
> + for (section_iterator SecI = Obj->begin_sections(),
> + SecE = Obj->end_sections();
> + SecI != SecE; SecI.increment(EC)) {
> + if (error(EC)) break;
> +
> + ++SectionIndex;
> +
> + const Elf_Shdr *Section = Obj->getElfSection(SecI);
> + StringRef Name;
> + if (error(SecI->getName(Name)))
> + Name = "";
> +
> + DictScope SectionD(W, "Section");
> + W.printNumber("Index", SectionIndex);
> + W.printNumber("Name", Name, Section->sh_name);
> + W.printHex ("Type", getElfSectionType(Obj->getArch(), Section->sh_type),
> + Section->sh_type);
> + W.printFlags ("Flags", Section->sh_flags, makeArrayRef(ElfSectionFlags));
> + W.printHex ("Address", Section->sh_addr);
> + W.printHex ("Offset", Section->sh_offset);
> + W.printNumber("Size", Section->sh_size);
> + W.printNumber("Link", Section->sh_link);
> + W.printNumber("Info", Section->sh_info);
> + W.printNumber("AddressAlignment", Section->sh_addralign);
> + W.printNumber("EntrySize", Section->sh_entsize);
> +
> + if (opts::SectionRelocations) {
> + ListScope D(W, "Relocations");
> + for (relocation_iterator RelI = SecI->begin_relocations(),
> + RelE = SecI->end_relocations();
> + RelI != RelE; RelI.increment(EC)) {
> + if (error(EC)) break;
> +
> + printRelocation(SecI, RelI);
> + }
> + }
> +
> + if (opts::SectionSymbols) {
> + ListScope D(W, "Symbols");
> + for (symbol_iterator SymI = Obj->begin_symbols(),
> + SymE = Obj->end_symbols();
> + SymI != SymE; SymI.increment(EC)) {
> + if (error(EC)) break;
> +
> + bool Contained = false;
> + if (SecI->containsSymbol(*SymI, Contained) || !Contained)
> + continue;
> +
> + printSymbol(SymI);
> + }
> + }
> +
> + if (opts::SectionData) {
> + StringRef Data;
> + if (error(SecI->getContents(Data))) break;
> +
> + W.printBinaryBlock("SectionData", Data);
> + }
> + }
> +}
> +
> +template<class ELFT>
> +void ELFDumper<ELFT>::printRelocations() {
> + ListScope D(W, "Relocations");
> +
> + error_code EC;
> + int SectionNumber = -1;
> + for (section_iterator SecI = Obj->begin_sections(),
> + SecE = Obj->end_sections();
> + SecI != SecE; SecI.increment(EC)) {
> + if (error(EC)) break;
> +
> + ++SectionNumber;
> + StringRef Name;
> + if (error(SecI->getName(Name)))
> + continue;
> +
> + bool PrintedGroup = false;
> + for (relocation_iterator RelI = SecI->begin_relocations(),
> + RelE = SecI->end_relocations();
> + RelI != RelE; RelI.increment(EC)) {
> + if (error(EC)) break;
> +
> + if (!PrintedGroup) {
> + W.startLine() << "Section (" << SectionNumber << ") " << Name << " {\n";
> + W.indent();
> + PrintedGroup = true;
> + }
> +
> + printRelocation(SecI, RelI);
> + }
> +
> + if (PrintedGroup) {
> + W.unindent();
> + W.startLine() << "}\n";
> + }
> + }
> +}
> +
> +template<class ELFT>
> +void ELFDumper<ELFT>::printRelocation(section_iterator Sec,
> + relocation_iterator RelI) {
> + uint64_t Offset;
> + SmallString<32> RelocName;
> + int64_t Info;
> + StringRef SymbolName;
> + SymbolRef Symbol;
> + if (error(RelI->getOffset(Offset))) return;
> + if (error(RelI->getTypeName(RelocName))) return;
> + if (error(RelI->getAdditionalInfo(Info))) return;
> + if (error(RelI->getSymbol(Symbol))) return;
> + if (error(Symbol.getName(SymbolName))) return;
> +
> + raw_ostream& OS = W.startLine();
> + OS << W.hex(Offset)
> + << " " << RelocName
> + << " " << (SymbolName.size() > 0 ? SymbolName : "-")
> + << " " << W.hex(Info)
> + << "\n";
> +}
> +
> +template<class ELFT>
> +void ELFDumper<ELFT>::printSymbols() {
> + ListScope Group(W, "Symbols");
> +
> + error_code EC;
> + for (symbol_iterator SymI = Obj->begin_symbols(), SymE = Obj->end_symbols();
> + SymI != SymE; SymI.increment(EC)) {
> + if (error(EC)) break;
> +
> + printSymbol(SymI);
> + }
> +}
> +
> +template<class ELFT>
> +void ELFDumper<ELFT>::printDynamicSymbols() {
> + ListScope Group(W, "DynamicSymbols");
> +
> + error_code EC;
> + for (symbol_iterator SymI = Obj->begin_dynamic_symbols(),
> + SymE = Obj->end_dynamic_symbols();
> + SymI != SymE; SymI.increment(EC)) {
> + if (error(EC)) break;
> +
> + printSymbol(SymI, true);
> + }
> +}
> +
> +template<class ELFT>
> +void ELFDumper<ELFT>::printSymbol(symbol_iterator SymI, bool IsDynamic) {
> + error_code EC;
> +
> + const Elf_Sym *Symbol = Obj->getElfSymbol(SymI);
> + const Elf_Shdr *Section = Obj->getSection(Symbol);
> +
> + StringRef SymbolName;
> + if (SymI->getName(SymbolName))
> + SymbolName = "";
> +
> + StringRef SectionName;
> + if (Section && Obj->getSectionName(Section, SectionName))
> + SectionName = "";
> +
> + std::string FullSymbolName(SymbolName);
> + if (IsDynamic) {
> + StringRef Version;
> + bool IsDefault;
> + if (error(Obj->getSymbolVersion(*SymI, Version, IsDefault)))
> + return;
> + if (!Version.empty()) {
> + FullSymbolName += (IsDefault ? "@@" : "@");
> + FullSymbolName += Version;
> + }
> + }
> +
> + DictScope D(W, "Symbol");
> + 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 ("Type", Symbol->getType(), makeArrayRef(ElfSymbolTypes));
> + W.printNumber("Other", Symbol->st_other);
> + W.printHex ("Section", SectionName, Symbol->st_shndx);
> +}
> +
> +#define LLVM_READOBJ_TYPE_CASE(name) \
> + case DT_##name: return #name
> +
> +static const char *getTypeString(uint64_t Type) {
> + switch (Type) {
> + LLVM_READOBJ_TYPE_CASE(BIND_NOW);
> + LLVM_READOBJ_TYPE_CASE(DEBUG);
> + LLVM_READOBJ_TYPE_CASE(FINI);
> + LLVM_READOBJ_TYPE_CASE(FINI_ARRAY);
> + LLVM_READOBJ_TYPE_CASE(FINI_ARRAYSZ);
> + LLVM_READOBJ_TYPE_CASE(FLAGS);
> + LLVM_READOBJ_TYPE_CASE(HASH);
> + LLVM_READOBJ_TYPE_CASE(INIT);
> + LLVM_READOBJ_TYPE_CASE(INIT_ARRAY);
> + LLVM_READOBJ_TYPE_CASE(INIT_ARRAYSZ);
> + LLVM_READOBJ_TYPE_CASE(PREINIT_ARRAY);
> + LLVM_READOBJ_TYPE_CASE(PREINIT_ARRAYSZ);
> + LLVM_READOBJ_TYPE_CASE(JMPREL);
> + LLVM_READOBJ_TYPE_CASE(NEEDED);
> + LLVM_READOBJ_TYPE_CASE(NULL);
> + LLVM_READOBJ_TYPE_CASE(PLTGOT);
> + LLVM_READOBJ_TYPE_CASE(PLTREL);
> + LLVM_READOBJ_TYPE_CASE(PLTRELSZ);
> + LLVM_READOBJ_TYPE_CASE(REL);
> + LLVM_READOBJ_TYPE_CASE(RELA);
> + LLVM_READOBJ_TYPE_CASE(RELENT);
> + LLVM_READOBJ_TYPE_CASE(RELSZ);
> + LLVM_READOBJ_TYPE_CASE(RELAENT);
> + LLVM_READOBJ_TYPE_CASE(RELASZ);
> + LLVM_READOBJ_TYPE_CASE(RPATH);
> + LLVM_READOBJ_TYPE_CASE(RUNPATH);
> + LLVM_READOBJ_TYPE_CASE(SONAME);
> + LLVM_READOBJ_TYPE_CASE(STRSZ);
> + LLVM_READOBJ_TYPE_CASE(STRTAB);
> + LLVM_READOBJ_TYPE_CASE(SYMBOLIC);
> + LLVM_READOBJ_TYPE_CASE(SYMENT);
> + LLVM_READOBJ_TYPE_CASE(SYMTAB);
> + LLVM_READOBJ_TYPE_CASE(TEXTREL);
> + default: return "unknown";
> + }
> +}
> +
> +#undef LLVM_READOBJ_TYPE_CASE
> +
> +template<class ELFT>
> +static void printValue(const ELFObjectFile<ELFT> *O, uint64_t Type,
> + uint64_t Value, bool Is64, raw_ostream &OS) {
> + switch (Type) {
> + case DT_PLTREL:
> + if (Value == DT_REL) {
> + OS << "REL";
> + break;
> + } else if (Value == DT_RELA) {
> + OS << "RELA";
> + break;
> + }
> + // Fallthrough.
> + case DT_PLTGOT:
> + case DT_HASH:
> + case DT_STRTAB:
> + case DT_SYMTAB:
> + case DT_RELA:
> + case DT_INIT:
> + case DT_FINI:
> + case DT_REL:
> + case DT_JMPREL:
> + case DT_INIT_ARRAY:
> + case DT_FINI_ARRAY:
> + case DT_PREINIT_ARRAY:
> + case DT_DEBUG:
> + case DT_NULL:
> + OS << format("0x%" PRIX64, Value);
> + break;
> + case DT_PLTRELSZ:
> + case DT_RELASZ:
> + case DT_RELAENT:
> + case DT_STRSZ:
> + case DT_SYMENT:
> + case DT_RELSZ:
> + case DT_RELENT:
> + case DT_INIT_ARRAYSZ:
> + case DT_FINI_ARRAYSZ:
> + case DT_PREINIT_ARRAYSZ:
> + OS << Value << " (bytes)";
> + break;
> + case DT_NEEDED:
> + OS << "SharedLibrary ("
> + << O->getString(O->getDynamicStringTableSectionHeader(), Value) << ")";
> + break;
> + case DT_SONAME:
> + OS << "LibrarySoname ("
> + << O->getString(O->getDynamicStringTableSectionHeader(), Value) << ")";
> + break;
> + }
> +}
> +
> +template<class ELFT>
> +void ELFDumper<ELFT>::printUnwindInfo() {
> + W.startLine() << "UnwindInfo not implemented.\n";
> +}
> +
> +template<class ELFT>
> +void ELFDumper<ELFT>::printDynamicTable() {
> + typedef ELFObjectFile<ELFT> ELFO;
> + typedef typename ELFO::Elf_Dyn_iterator EDI;
> + EDI Start = Obj->begin_dynamic_table(),
> + End = Obj->end_dynamic_table(true);
> +
> + if (Start == End)
> + return;
> +
> + ptrdiff_t Total = std::distance(Start, End);
> + raw_ostream &OS = W.getOStream();
> + W.startLine() << "DynamicSection [ (" << Total << " entries)\n";
> +
> + bool Is64 = Obj->getBytesInAddress() == 8;
> +
> + W.startLine()
> + << " Tag" << (Is64 ? " " : " ") << "Type"
> + << " " << "Name/Value\n";
> + for (; Start != End; ++Start) {
> + W.startLine()
> + << " "
> + << format(Is64 ? "0x%016" PRIX64 : "0x%08" PRIX64, Start->getTag())
> + << " " << format("%-21s", getTypeString(Start->getTag()));
> + printValue(Obj, Start->getTag(), Start->getVal(), Is64, OS);
> + OS << "\n";
> + }
> +
> + W.startLine() << "]\n";
> +}
> +
> +static bool compareLibraryName(const LibraryRef &L, const LibraryRef &R) {
> + StringRef LPath, RPath;
> + L.getPath(LPath);
> + R.getPath(RPath);
> + return LPath < RPath;
> +}
> +
> +template<class ELFT>
> +void ELFDumper<ELFT>::printNeededLibraries() {
> + ListScope D(W, "NeededLibraries");
> +
> + error_code EC;
> +
> + typedef std::vector<LibraryRef> LibsTy;
> + LibsTy Libs;
> +
> + for (library_iterator I = Obj->begin_libraries_needed(),
> + E = Obj->end_libraries_needed();
> + I != E; I.increment(EC)) {
> + if (EC)
> + report_fatal_error("Needed libraries iteration failed");
> +
> + Libs.push_back(*I);
> + }
> +
> + std::sort(Libs.begin(), Libs.end(), &compareLibraryName);
> +
> + for (LibsTy::const_iterator I = Libs.begin(), E = Libs.end();
> + I != E; ++I) {
> + StringRef Path;
> + I->getPath(Path);
> + outs() << " " << Path << "\n";
> + }
> +}
>
> Added: llvm/trunk/tools/llvm-readobj/Error.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/Error.cpp?rev=178679&view=auto
> ==============================================================================
> --- llvm/trunk/tools/llvm-readobj/Error.cpp (added)
> +++ llvm/trunk/tools/llvm-readobj/Error.cpp Wed Apr 3 13:31:38 2013
> @@ -0,0 +1,62 @@
> +//===- Error.cpp - system_error extensions for llvm-readobj -----*- C++ -*-===//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===----------------------------------------------------------------------===//
> +//
> +// This defines a new error_category for the llvm-readobj tool.
> +//
> +//===----------------------------------------------------------------------===//
> +
> +#include "Error.h"
> +#include "llvm/Support/ErrorHandling.h"
> +
> +using namespace llvm;
> +
> +namespace {
> +class _readobj_error_category : public _do_message {
> +public:
> + virtual const char* name() const;
> + virtual std::string message(int ev) const;
> + virtual error_condition default_error_condition(int ev) const;
> +};
> +} // namespace
> +
> +const char *_readobj_error_category::name() const {
> + return "llvm.readobj";
> +}
> +
> +std::string _readobj_error_category::message(int ev) const {
> + switch (ev) {
> + case readobj_error::success: return "Success";
> + case readobj_error::file_not_found:
> + return "No such file.";
> + case readobj_error::unsupported_file_format:
> + return "The file was not recognized as a valid object file.";
> + case readobj_error::unrecognized_file_format:
> + return "Unrecognized file type.";
> + case readobj_error::unsupported_obj_file_format:
> + return "Unsupported object file format.";
> + case readobj_error::unknown_symbol:
> + return "Unknown symbol.";
> + default:
> + llvm_unreachable("An enumerator of readobj_error does not have a message "
> + "defined.");
> + }
> +}
> +
> +error_condition _readobj_error_category::default_error_condition(int ev) const {
> + if (ev == readobj_error::success)
> + return errc::success;
> + return errc::invalid_argument;
> +}
> +
> +namespace llvm {
> +const error_category &readobj_category() {
> + static _readobj_error_category o;
> + return o;
> +}
> +} // namespace llvm
>
> Added: llvm/trunk/tools/llvm-readobj/Error.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/Error.h?rev=178679&view=auto
> ==============================================================================
> --- llvm/trunk/tools/llvm-readobj/Error.h (added)
> +++ llvm/trunk/tools/llvm-readobj/Error.h Wed Apr 3 13:31:38 2013
> @@ -0,0 +1,48 @@
> +//===- Error.h - system_error extensions for llvm-readobj -------*- C++ -*-===//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===----------------------------------------------------------------------===//
> +//
> +// This declares a new error_category for the llvm-readobj tool.
> +//
> +//===----------------------------------------------------------------------===//
> +
> +#ifndef LLVM_READOBJ_ERROR_H
> +#define LLVM_READOBJ_ERROR_H
> +
> +#include "llvm/Support/system_error.h"
> +
> +namespace llvm {
> +
> +const error_category &readobj_category();
> +
> +struct readobj_error {
> + enum _ {
> + success = 0,
> + file_not_found,
> + unsupported_file_format,
> + unrecognized_file_format,
> + unsupported_obj_file_format,
> + unknown_symbol
> + };
> + _ v_;
> +
> + readobj_error(_ v) : v_(v) {}
> + explicit readobj_error(int v) : v_(_(v)) {}
> + operator int() const {return v_;}
> +};
> +
> +inline error_code make_error_code(readobj_error e) {
> + return error_code(static_cast<int>(e), readobj_category());
> +}
> +
> +template <> struct is_error_code_enum<readobj_error> : true_type { };
> +template <> struct is_error_code_enum<readobj_error::_> : true_type { };
> +
> +} // namespace llvm
> +
> +#endif
>
> Modified: llvm/trunk/tools/llvm-readobj/LLVMBuild.txt
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/LLVMBuild.txt?rev=178679&r1=178678&r2=178679&view=diff
> ==============================================================================
> --- llvm/trunk/tools/llvm-readobj/LLVMBuild.txt (original)
> +++ llvm/trunk/tools/llvm-readobj/LLVMBuild.txt Wed Apr 3 13:31:38 2013
> @@ -19,4 +19,4 @@
> type = Tool
> name = llvm-readobj
> parent = Tools
> -required_libraries = Archive BitReader Object
> +required_libraries = all-targets Archive BitReader Object
>
> Added: llvm/trunk/tools/llvm-readobj/MachODumper.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/MachODumper.cpp?rev=178679&view=auto
> ==============================================================================
> --- llvm/trunk/tools/llvm-readobj/MachODumper.cpp (added)
> +++ llvm/trunk/tools/llvm-readobj/MachODumper.cpp Wed Apr 3 13:31:38 2013
> @@ -0,0 +1,438 @@
> +//===-- MachODump.cpp - Object file dumping utility for llvm --------------===//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===----------------------------------------------------------------------===//
> +//
> +// This file implements the MachO-specific dumper for llvm-readobj.
> +//
> +//===----------------------------------------------------------------------===//
> +
> +#include "llvm-readobj.h"
> +#include "Error.h"
> +#include "ObjDumper.h"
> +#include "StreamWriter.h"
> +
> +#include "llvm/ADT/SmallString.h"
> +#include "llvm/Object/MachO.h"
> +#include "llvm/Support/Casting.h"
> +
> +using namespace llvm;
> +using namespace object;
> +
> +namespace {
> +
> +class MachODumper : public ObjDumper {
> +public:
> + MachODumper(const llvm::object::MachOObjectFile *Obj, StreamWriter& Writer)
> + : ObjDumper(Writer)
> + , Obj(Obj) { }
> +
> + virtual void printFileHeaders() LLVM_OVERRIDE;
> + virtual void printSections() LLVM_OVERRIDE;
> + virtual void printRelocations() LLVM_OVERRIDE;
> + virtual void printSymbols() LLVM_OVERRIDE;
> + virtual void printDynamicSymbols() LLVM_OVERRIDE;
> + virtual void printUnwindInfo() LLVM_OVERRIDE;
> +
> +private:
> + void printSymbol(symbol_iterator SymI);
> +
> + void printRelocation(section_iterator SecI, relocation_iterator RelI);
> +
> + const llvm::object::MachOObjectFile *Obj;
> +};
> +
> +} // namespace
> +
> +
> +namespace llvm {
> +
> +error_code createMachODumper(const object::ObjectFile *Obj,
> + StreamWriter& Writer,
> + OwningPtr<ObjDumper> &Result) {
> + const MachOObjectFile *MachOObj = dyn_cast<MachOObjectFile>(Obj);
> + if (!MachOObj)
> + return readobj_error::unsupported_obj_file_format;
> +
> + Result.reset(new MachODumper(MachOObj, Writer));
> + return readobj_error::success;
> +}
> +
> +} // namespace llvm
> +
> +
> +static const EnumEntry<unsigned> MachOSectionTypes[] = {
> + { "Regular" , 0x00 },
> + { "ZeroFill" , 0x01 },
> + { "CStringLiterals" , 0x02 },
> + { "4ByteLiterals" , 0x03 },
> + { "8ByteLiterals" , 0x04 },
> + { "LiteralPointers" , 0x05 },
> + { "NonLazySymbolPointers" , 0x06 },
> + { "LazySymbolPointers" , 0x07 },
> + { "SymbolStubs" , 0x08 },
> + { "ModInitFuncs" , 0x09 },
> + { "ModTermFuncs" , 0x0A },
> + { "Coalesced" , 0x0B },
> + { "GBZeroFill" , 0x0C },
> + { "Interposing" , 0x0D },
> + { "16ByteLiterals" , 0x0E },
> + { "DTraceDOF" , 0x0F },
> + { "LazyDylibSymbolPoints" , 0x10 },
> + { "ThreadLocalRegular" , 0x11 },
> + { "ThreadLocalZerofill" , 0x12 },
> + { "ThreadLocalVariables" , 0x13 },
> + { "ThreadLocalVariablePointers" , 0x14 },
> + { "ThreadLocalInitFunctionPointers", 0x15 }
> +};
> +
> +static const EnumEntry<unsigned> MachOSectionAttributes[] = {
> + { "LocReloc" , 1 << 0 /*S_ATTR_LOC_RELOC */ },
> + { "ExtReloc" , 1 << 1 /*S_ATTR_EXT_RELOC */ },
> + { "SomeInstructions" , 1 << 2 /*S_ATTR_SOME_INSTRUCTIONS */ },
> + { "Debug" , 1 << 17 /*S_ATTR_DEBUG */ },
> + { "SelfModifyingCode", 1 << 18 /*S_ATTR_SELF_MODIFYING_CODE*/ },
> + { "LiveSupport" , 1 << 19 /*S_ATTR_LIVE_SUPPORT */ },
> + { "NoDeadStrip" , 1 << 20 /*S_ATTR_NO_DEAD_STRIP */ },
> + { "StripStaticSyms" , 1 << 21 /*S_ATTR_STRIP_STATIC_SYMS */ },
> + { "NoTOC" , 1 << 22 /*S_ATTR_NO_TOC */ },
> + { "PureInstructions" , 1 << 23 /*S_ATTR_PURE_INSTRUCTIONS */ },
> +};
> +
> +static const EnumEntry<unsigned> MachOSymbolRefTypes[] = {
> + { "UndefinedNonLazy", 0 },
> + { "ReferenceFlagUndefinedLazy", 1 },
> + { "ReferenceFlagDefined", 2 },
> + { "ReferenceFlagPrivateDefined", 3 },
> + { "ReferenceFlagPrivateUndefinedNonLazy", 4 },
> + { "ReferenceFlagPrivateUndefinedLazy", 5 }
> +};
> +
> +static const EnumEntry<unsigned> MachOSymbolFlags[] = {
> + { "ReferencedDynamically", 0x10 },
> + { "NoDeadStrip", 0x20 },
> + { "WeakRef", 0x40 },
> + { "WeakDef", 0x80 }
> +};
> +
> +static const EnumEntry<unsigned> MachOSymbolTypes[] = {
> + { "Undef", 0x0 },
> + { "External", 0x1 },
> + { "Abs", 0x2 },
> + { "Indirect", 0xA },
> + { "PreboundUndef", 0xC },
> + { "Section", 0xE },
> + { "PrivateExternal", 0x10 }
> +};
> +
> +namespace {
> + enum {
> + N_STAB = 0xE0
> + };
> +
> + struct MachOSection {
> + ArrayRef<char> Name;
> + ArrayRef<char> SegmentName;
> + uint64_t Address;
> + uint64_t Size;
> + uint32_t Offset;
> + uint32_t Alignment;
> + uint32_t RelocationTableOffset;
> + uint32_t NumRelocationTableEntries;
> + uint32_t Flags;
> + uint32_t Reserved1;
> + uint32_t Reserved2;
> + };
> +
> + struct MachOSymbol {
> + uint32_t StringIndex;
> + uint8_t Type;
> + uint8_t SectionIndex;
> + uint16_t Flags;
> + uint64_t Value;
> + };
> +}
> +
> +static StringRef parseSegmentOrSectionName(ArrayRef<char> P) {
> + if (P[15] == 0)
> + // Null terminated.
> + return StringRef(P.data());
> + // Not null terminated, so this is a 16 char string.
> + return StringRef(P.data(), 16);
> +}
> +
> +static bool is64BitLoadCommand(const MachOObject *MachOObj, DataRefImpl DRI) {
> + LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a);
> + if (LCI.Command.Type == macho::LCT_Segment64)
> + return true;
> + assert(LCI.Command.Type == macho::LCT_Segment && "Unexpected Type.");
> + return false;
> +}
> +
> +static void getSection(const MachOObject *MachOObj,
> + DataRefImpl DRI,
> + MachOSection &Section) {
> + LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a);
> + if (is64BitLoadCommand(MachOObj, DRI)) {
> + InMemoryStruct<macho::Section64> Sect;
> + MachOObj->ReadSection64(LCI, DRI.d.b, Sect);
> +
> + Section.Name = ArrayRef<char>(Sect->Name);
> + Section.SegmentName = ArrayRef<char>(Sect->SegmentName);
> + Section.Address = Sect->Address;
> + Section.Size = Sect->Size;
> + Section.Offset = Sect->Offset;
> + Section.Alignment = Sect->Align;
> + Section.RelocationTableOffset = Sect->RelocationTableOffset;
> + Section.NumRelocationTableEntries = Sect->NumRelocationTableEntries;
> + Section.Flags = Sect->Flags;
> + Section.Reserved1 = Sect->Reserved1;
> + Section.Reserved2 = Sect->Reserved2;
> + } else {
> + InMemoryStruct<macho::Section> Sect;
> + MachOObj->ReadSection(LCI, DRI.d.b, Sect);
> +
> + Section.Name = Sect->Name;
> + Section.SegmentName = Sect->SegmentName;
> + Section.Address = Sect->Address;
> + Section.Size = Sect->Size;
> + Section.Offset = Sect->Offset;
> + Section.Alignment = Sect->Align;
> + Section.RelocationTableOffset = Sect->RelocationTableOffset;
> + Section.NumRelocationTableEntries = Sect->NumRelocationTableEntries;
> + Section.Flags = Sect->Flags;
> + Section.Reserved1 = Sect->Reserved1;
> + Section.Reserved2 = Sect->Reserved2;
> + }
> +}
> +
> +static void getSymbolTableEntry(const MachOObject *MachO,
> + DataRefImpl DRI,
> + InMemoryStruct<macho::SymbolTableEntry> &Res) {
> + InMemoryStruct<macho::SymtabLoadCommand> SymtabLoadCmd;
> + LoadCommandInfo LCI = MachO->getLoadCommandInfo(DRI.d.a);
> + MachO->ReadSymtabLoadCommand(LCI, SymtabLoadCmd);
> + MachO->ReadSymbolTableEntry(SymtabLoadCmd->SymbolTableOffset, DRI.d.b, Res);
> +}
> +
> +static void getSymbol64TableEntry(const MachOObject *MachO,
> + DataRefImpl DRI,
> + InMemoryStruct<macho::Symbol64TableEntry> &Res) {
> + InMemoryStruct<macho::SymtabLoadCommand> SymtabLoadCmd;
> + LoadCommandInfo LCI = MachO->getLoadCommandInfo(DRI.d.a);
> + MachO->ReadSymtabLoadCommand(LCI, SymtabLoadCmd);
> + MachO->ReadSymbol64TableEntry(SymtabLoadCmd->SymbolTableOffset, DRI.d.b, Res);
> +}
> +
> +static void getSymbol(const MachOObject *MachOObj,
> + DataRefImpl DRI,
> + MachOSymbol &Symbol) {
> + if (MachOObj->is64Bit()) {
> + InMemoryStruct<macho::Symbol64TableEntry> Entry;
> + getSymbol64TableEntry(MachOObj, DRI, Entry);
> + Symbol.StringIndex = Entry->StringIndex;
> + Symbol.Type = Entry->Type;
> + Symbol.SectionIndex = Entry->SectionIndex;
> + Symbol.Flags = Entry->Flags;
> + Symbol.Value = Entry->Value;
> + } else {
> + InMemoryStruct<macho::SymbolTableEntry> Entry;
> + getSymbolTableEntry(MachOObj, DRI, Entry);
> + Symbol.StringIndex = Entry->StringIndex;
> + Symbol.Type = Entry->Type;
> + Symbol.SectionIndex = Entry->SectionIndex;
> + Symbol.Flags = Entry->Flags;
> + Symbol.Value = Entry->Value;
> + }
> +}
> +
> +void MachODumper::printFileHeaders() {
> + W.startLine() << "FileHeaders not implemented.\n";
> +}
> +
> +void MachODumper::printSections() {
> + ListScope Group(W, "Sections");
> +
> + int SectionIndex = -1;
> + error_code EC;
> + for (section_iterator SecI = Obj->begin_sections(),
> + SecE = Obj->end_sections();
> + SecI != SecE; SecI.increment(EC)) {
> + if (error(EC)) break;
> +
> + ++SectionIndex;
> +
> + const MachOObject *MachO = const_cast<MachOObjectFile*>(Obj)->getObject();
> +
> + MachOSection Section;
> + getSection(MachO, SecI->getRawDataRefImpl(), Section);
> + StringRef Name;
> + if (error(SecI->getName(Name)))
> + Name = "";
> +
> + DictScope SectionD(W, "Section");
> + W.printNumber("Index", SectionIndex);
> + W.printBinary("Name", Name, Section.Name);
> + W.printBinary("Segment", parseSegmentOrSectionName(Section.SegmentName),
> + Section.SegmentName);
> + W.printHex ("Address", Section.Address);
> + W.printHex ("Size", Section.Size);
> + W.printNumber("Offset", Section.Offset);
> + W.printNumber("Alignment", Section.Alignment);
> + W.printHex ("RelocationOffset", Section.RelocationTableOffset);
> + W.printNumber("RelocationCount", Section.NumRelocationTableEntries);
> + W.printEnum ("Type", Section.Flags & 0xFF,
> + makeArrayRef(MachOSectionAttributes));
> + W.printFlags ("Attributes", Section.Flags >> 8,
> + makeArrayRef(MachOSectionAttributes));
> + W.printHex ("Reserved1", Section.Reserved1);
> + W.printHex ("Reserved2", Section.Reserved2);
> +
> + if (opts::SectionRelocations) {
> + ListScope D(W, "Relocations");
> + for (relocation_iterator RelI = SecI->begin_relocations(),
> + RelE = SecI->end_relocations();
> + RelI != RelE; RelI.increment(EC)) {
> + if (error(EC)) break;
> +
> + printRelocation(SecI, RelI);
> + }
> + }
> +
> + if (opts::SectionSymbols) {
> + ListScope D(W, "Symbols");
> + for (symbol_iterator SymI = Obj->begin_symbols(),
> + SymE = Obj->end_symbols();
> + SymI != SymE; SymI.increment(EC)) {
> + if (error(EC)) break;
> +
> + bool Contained = false;
> + if (SecI->containsSymbol(*SymI, Contained) || !Contained)
> + continue;
> +
> + printSymbol(SymI);
> + }
> + }
> +
> + if (opts::SectionData) {
> + StringRef Data;
> + if (error(SecI->getContents(Data))) break;
> +
> + W.printBinaryBlock("SectionData", Data);
> + }
> + }
> +}
> +
> +void MachODumper::printRelocations() {
> + ListScope D(W, "Relocations");
> +
> + error_code EC;
> + for (section_iterator SecI = Obj->begin_sections(),
> + SecE = Obj->end_sections();
> + SecI != SecE; SecI.increment(EC)) {
> + if (error(EC)) break;
> +
> + StringRef Name;
> + if (error(SecI->getName(Name)))
> + continue;
> +
> + bool PrintedGroup = false;
> + for (relocation_iterator RelI = SecI->begin_relocations(),
> + RelE = SecI->end_relocations();
> + RelI != RelE; RelI.increment(EC)) {
> + if (error(EC)) break;
> +
> + if (!PrintedGroup) {
> + W.startLine() << "Section " << Name << " {\n";
> + W.indent();
> + PrintedGroup = true;
> + }
> +
> + printRelocation(SecI, RelI);
> + }
> +
> + if (PrintedGroup) {
> + W.unindent();
> + W.startLine() << "}\n";
> + }
> + }
> +}
> +
> +void MachODumper::printRelocation(section_iterator SecI,
> + relocation_iterator RelI) {
> + uint64_t Offset;
> + SmallString<32> RelocName;
> + int64_t Info;
> + StringRef SymbolName;
> + SymbolRef Symbol;
> + if (error(RelI->getOffset(Offset))) return;
> + if (error(RelI->getTypeName(RelocName))) return;
> + if (error(RelI->getAdditionalInfo(Info))) return;
> + if (error(RelI->getSymbol(Symbol))) return;
> + if (error(Symbol.getName(SymbolName))) return;
> +
> + raw_ostream& OS = W.startLine();
> + OS << W.hex(Offset)
> + << " " << RelocName
> + << " " << (SymbolName.size() > 0 ? SymbolName : "-")
> + << " " << W.hex(Info)
> + << "\n";
> +}
> +
> +void MachODumper::printSymbols() {
> + ListScope Group(W, "Symbols");
> +
> + error_code EC;
> + for (symbol_iterator SymI = Obj->begin_symbols(),
> + SymE = Obj->end_symbols();
> + SymI != SymE; SymI.increment(EC)) {
> + if (error(EC)) break;
> +
> + printSymbol(SymI);
> + }
> +}
> +
> +void MachODumper::printDynamicSymbols() {
> + ListScope Group(W, "DynamicSymbols");
> +}
> +
> +void MachODumper::printSymbol(symbol_iterator SymI) {
> + error_code EC;
> +
> + StringRef SymbolName;
> + if (SymI->getName(SymbolName))
> + SymbolName = "";
> +
> + const MachOObject *MachO = const_cast<MachOObjectFile*>(Obj)->getObject();
> +
> + MachOSymbol Symbol;
> + getSymbol(MachO, SymI->getRawDataRefImpl(), Symbol);
> +
> + StringRef SectionName;
> + section_iterator SecI(Obj->end_sections());
> + if (error(SymI->getSection(SecI)) ||
> + error(SecI->getName(SectionName)))
> + SectionName = "";
> +
> + DictScope D(W, "Symbol");
> + W.printNumber("Name", SymbolName, Symbol.StringIndex);
> + if (Symbol.Type & N_STAB) {
> + W.printHex ("Type", "SymDebugTable", Symbol.Type);
> + } else {
> + W.printEnum("Type", Symbol.Type, makeArrayRef(MachOSymbolTypes));
> + }
> + W.printHex ("Section", SectionName, Symbol.SectionIndex);
> + W.printEnum ("RefType", static_cast<uint16_t>(Symbol.Flags & 0xF),
> + makeArrayRef(MachOSymbolRefTypes));
> + W.printFlags ("Flags", static_cast<uint16_t>(Symbol.Flags & ~0xF),
> + makeArrayRef(MachOSymbolFlags));
> + W.printHex ("Value", Symbol.Value);
> +}
> +
> +void MachODumper::printUnwindInfo() {
> + W.startLine() << "UnwindInfo not implemented.\n";
> +}
>
> Modified: llvm/trunk/tools/llvm-readobj/Makefile
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/Makefile?rev=178679&r1=178678&r2=178679&view=diff
> ==============================================================================
> --- llvm/trunk/tools/llvm-readobj/Makefile (original)
> +++ llvm/trunk/tools/llvm-readobj/Makefile Wed Apr 3 13:31:38 2013
> @@ -9,7 +9,7 @@
>
> LEVEL := ../..
> TOOLNAME := llvm-readobj
> -LINK_COMPONENTS := archive bitreader object
> +LINK_COMPONENTS := archive bitreader object all-targets
>
> # This tool has no plugins, optimize startup time.
> TOOL_NO_EXPORTS := 1
>
> Added: llvm/trunk/tools/llvm-readobj/ObjDumper.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/ObjDumper.cpp?rev=178679&view=auto
> ==============================================================================
> --- llvm/trunk/tools/llvm-readobj/ObjDumper.cpp (added)
> +++ llvm/trunk/tools/llvm-readobj/ObjDumper.cpp Wed Apr 3 13:31:38 2013
> @@ -0,0 +1,33 @@
> +//===-- ObjDumper.cpp - Base dumper class -----------------------*- C++ -*-===//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===----------------------------------------------------------------------===//
> +///
> +/// \file
> +/// \brief This file implements ObjDumper.
> +///
> +//===----------------------------------------------------------------------===//
> +
> +#include "ObjDumper.h"
> +
> +#include "Error.h"
> +#include "StreamWriter.h"
> +
> +#include "llvm/ADT/StringRef.h"
> +#include "llvm/Object/ObjectFile.h"
> +#include "llvm/Support/raw_ostream.h"
> +
> +namespace llvm {
> +
> +ObjDumper::ObjDumper(StreamWriter& Writer)
> + : W(Writer) {
> +}
> +
> +ObjDumper::~ObjDumper() {
> +}
> +
> +} // namespace llvm
>
> Added: llvm/trunk/tools/llvm-readobj/ObjDumper.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/ObjDumper.h?rev=178679&view=auto
> ==============================================================================
> --- llvm/trunk/tools/llvm-readobj/ObjDumper.h (added)
> +++ llvm/trunk/tools/llvm-readobj/ObjDumper.h Wed Apr 3 13:31:38 2013
> @@ -0,0 +1,60 @@
> +//===-- ObjDumper.h -------------------------------------------------------===//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===----------------------------------------------------------------------===//
> +
> +#ifndef LLVM_READOBJ_OBJDUMPER_H
> +#define LLVM_READOBJ_OBJDUMPER_H
> +
> +namespace llvm {
> +
> +namespace object {
> + class ObjectFile;
> +}
> +
> +class error_code;
> +
> +template<typename T>
> +class OwningPtr;
> +
> +class StreamWriter;
> +
> +class ObjDumper {
> +public:
> + ObjDumper(StreamWriter& Writer);
> + virtual ~ObjDumper();
> +
> + virtual void printFileHeaders() = 0;
> + virtual void printSections() = 0;
> + virtual void printRelocations() = 0;
> + virtual void printSymbols() = 0;
> + virtual void printDynamicSymbols() = 0;
> + virtual void printUnwindInfo() = 0;
> +
> + // Only implemented for ELF at this time.
> + virtual void printDynamicTable() { }
> + virtual void printNeededLibraries() { }
> +
> +protected:
> + StreamWriter& W;
> +};
> +
> +error_code createCOFFDumper(const object::ObjectFile *Obj,
> + StreamWriter& Writer,
> + OwningPtr<ObjDumper> &Result);
> +
> +error_code createELFDumper(const object::ObjectFile *Obj,
> + StreamWriter& Writer,
> + OwningPtr<ObjDumper> &Result);
> +
> +error_code createMachODumper(const object::ObjectFile *Obj,
> + StreamWriter& Writer,
> + OwningPtr<ObjDumper> &Result);
> +
> +} // namespace llvm
> +
> +#endif
>
> Added: llvm/trunk/tools/llvm-readobj/StreamWriter.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/StreamWriter.cpp?rev=178679&view=auto
> ==============================================================================
> --- llvm/trunk/tools/llvm-readobj/StreamWriter.cpp (added)
> +++ llvm/trunk/tools/llvm-readobj/StreamWriter.cpp Wed Apr 3 13:31:38 2013
> @@ -0,0 +1,79 @@
> +#include "StreamWriter.h"
> +#include "llvm/ADT/StringExtras.h"
> +#include "llvm/Support/Format.h"
> +#include <cctype>
> +
> +using namespace llvm::support;
> +
> +namespace llvm {
> +
> +raw_ostream &operator<<(raw_ostream &OS, const HexNumber& Value) {
> + uint64_t N = Value.Value;
> + // Zero is a special case.
> + if (N == 0)
> + return OS << "0x0";
> +
> + char NumberBuffer[20];
> + char *EndPtr = NumberBuffer + sizeof(NumberBuffer);
> + char *CurPtr = EndPtr;
> +
> + while (N) {
> + uintptr_t X = N % 16;
> + *--CurPtr = (X < 10 ? '0' + X : 'A' + X - 10);
> + N /= 16;
> + }
> +
> + OS << "0x";
> + return OS.write(CurPtr, EndPtr - CurPtr);
> +}
> +
> +void StreamWriter::printBinaryImpl(StringRef Label, StringRef Str,
> + ArrayRef<uint8_t> Data, bool Block) {
> + if (Data.size() > 16)
> + Block = true;
> +
> + if (Block) {
> + startLine() << Label;
> + if (Str.size() > 0)
> + OS << ": " << Str;
> + OS << " (\n";
> + for (size_t addr = 0, end = Data.size(); addr < end; addr += 16) {
> + startLine() << format(" %04" PRIX64 ": ", uint64_t(addr));
> + // Dump line of hex.
> + for (size_t i = 0; i < 16; ++i) {
> + if (i != 0 && i % 4 == 0)
> + OS << ' ';
> + if (addr + i < end)
> + OS << hexdigit((Data[addr + i] >> 4) & 0xF, false)
> + << hexdigit(Data[addr + i] & 0xF, false);
> + else
> + OS << " ";
> + }
> + // Print ascii.
> + OS << " |";
> + for (std::size_t i = 0; i < 16 && addr + i < end; ++i) {
> + if (std::isprint(Data[addr + i] & 0xFF))
> + OS << Data[addr + i];
> + else
> + OS << ".";
> + }
> + OS << "|\n";
> + }
> +
> + startLine() << ")\n";
> + } else {
> + startLine() << Label << ":";
> + if (Str.size() > 0)
> + OS << " " << Str;
> + OS << " (";
> + for (size_t i = 0; i < Data.size(); ++i) {
> + if (i > 0)
> + OS << " ";
> +
> + OS << format("%02X", static_cast<int>(Data[i]));
> + }
> + OS << ")\n";
> + }
> +}
> +
> +} // namespace llvm
>
> Added: llvm/trunk/tools/llvm-readobj/StreamWriter.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/StreamWriter.h?rev=178679&view=auto
> ==============================================================================
> --- llvm/trunk/tools/llvm-readobj/StreamWriter.h (added)
> +++ llvm/trunk/tools/llvm-readobj/StreamWriter.h Wed Apr 3 13:31:38 2013
> @@ -0,0 +1,282 @@
> +//===-- StreamWriter.h ----------------------------------------------------===//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===----------------------------------------------------------------------===//
> +
> +#ifndef LLVM_READOBJ_STREAMWRITER_H
> +#define LLVM_READOBJ_STREAMWRITER_H
> +
> +#include "llvm/ADT/ArrayRef.h"
> +#include "llvm/ADT/StringRef.h"
> +#include "llvm/ADT/SmallVector.h"
> +#include "llvm/Support/DataTypes.h"
> +#include "llvm/Support/Endian.h"
> +#include "llvm/Support/raw_ostream.h"
> +#include <algorithm>
> +
> +using namespace llvm;
> +using namespace llvm::support;
> +
> +namespace llvm {
> +
> +template<typename T>
> +struct EnumEntry {
> + StringRef Name;
> + T Value;
> +};
> +
> +struct HexNumber {
> + // To avoid sign-extension we have to explicitly cast to the appropriate
> + // unsigned type. The overloads are here so that every type that is implicitly
> + // convertible to an integer (including enums and endian helpers) can be used
> + // without requiring type traits or call-site changes.
> + HexNumber(int8_t Value) : Value(static_cast<uint8_t >(Value)) { }
> + HexNumber(int16_t Value) : Value(static_cast<uint16_t>(Value)) { }
> + HexNumber(int32_t Value) : Value(static_cast<uint32_t>(Value)) { }
> + HexNumber(int64_t Value) : Value(static_cast<uint64_t>(Value)) { }
> + HexNumber(uint8_t Value) : Value(Value) { }
> + HexNumber(uint16_t Value) : Value(Value) { }
> + HexNumber(uint32_t Value) : Value(Value) { }
> + HexNumber(uint64_t Value) : Value(Value) { }
> + uint64_t Value;
> +};
> +
> +raw_ostream &operator<<(raw_ostream &OS, const HexNumber& Value);
> +
> +class StreamWriter {
> +public:
> + StreamWriter(raw_ostream &OS)
> + : OS(OS)
> + , IndentLevel(0) {
> + }
> +
> + void flush() {
> + OS.flush();
> + }
> +
> + void indent(int Levels = 1) {
> + IndentLevel += Levels;
> + }
> +
> + void unindent(int Levels = 1) {
> + IndentLevel = std::max(0, IndentLevel - Levels);
> + }
> +
> + void printIndent() {
> + for (int i = 0; i < IndentLevel; ++i)
> + OS << " ";
> + }
> +
> + template<typename T>
> + HexNumber hex(T Value) {
> + return HexNumber(Value);
> + }
> +
> + template<typename T, typename TEnum>
> + void printEnum(StringRef Label, T Value,
> + ArrayRef<EnumEntry<TEnum> > EnumValues) {
> + StringRef Name;
> + bool Found = false;
> + for (size_t i = 0; i < EnumValues.size(); ++i) {
> + if (EnumValues[i].Value == Value) {
> + Name = EnumValues[i].Name;
> + Found = true;
> + break;
> + }
> + }
> +
> + if (Found) {
> + startLine() << Label << ": " << Name << " (" << hex(Value) << ")\n";
> + } else {
> + startLine() << Label << ": " << hex(Value) << "\n";
> + }
> + }
> +
> + template<typename T, typename TFlag>
> + void printFlags(StringRef Label, T Value, ArrayRef<EnumEntry<TFlag> > Flags,
> + TFlag EnumMask = TFlag(0)) {
> + typedef EnumEntry<TFlag> FlagEntry;
> + typedef SmallVector<FlagEntry, 10> FlagVector;
> + FlagVector SetFlags;
> +
> + for (typename ArrayRef<FlagEntry>::const_iterator I = Flags.begin(),
> + E = Flags.end(); I != E; ++I) {
> + if (I->Value == 0)
> + continue;
> +
> + bool IsEnum = (I->Value & EnumMask) != 0;
> + if ((!IsEnum && (Value & I->Value) == I->Value) ||
> + (IsEnum && (Value & EnumMask) == I->Value)) {
> + SetFlags.push_back(*I);
> + }
> + }
> +
> + std::sort(SetFlags.begin(), SetFlags.end(), &flagName<TFlag>);
> +
> + startLine() << Label << " [ (" << hex(Value) << ")\n";
> + for (typename FlagVector::const_iterator I = SetFlags.begin(),
> + E = SetFlags.end();
> + I != E; ++I) {
> + startLine() << " " << I->Name << " (" << hex(I->Value) << ")\n";
> + }
> + startLine() << "]\n";
> + }
> +
> + template<typename T>
> + void printFlags(StringRef Label, T Value) {
> + startLine() << Label << " [ (" << hex(Value) << ")\n";
> + uint64_t Flag = 1;
> + uint64_t Curr = Value;
> + while (Curr > 0) {
> + if (Curr & 1)
> + startLine() << " " << hex(Flag) << "\n";
> + Curr >>= 1;
> + Flag <<= 1;
> + }
> + startLine() << "]\n";
> + }
> +
> + void printNumber(StringRef Label, uint64_t Value) {
> + startLine() << Label << ": " << Value << "\n";
> + }
> +
> + void printNumber(StringRef Label, uint32_t Value) {
> + startLine() << Label << ": " << Value << "\n";
> + }
> +
> + void printNumber(StringRef Label, uint16_t Value) {
> + startLine() << Label << ": " << Value << "\n";
> + }
> +
> + void printNumber(StringRef Label, uint8_t Value) {
> + startLine() << Label << ": " << unsigned(Value) << "\n";
> + }
> +
> + void printNumber(StringRef Label, int64_t Value) {
> + startLine() << Label << ": " << Value << "\n";
> + }
> +
> + void printNumber(StringRef Label, int32_t Value) {
> + startLine() << Label << ": " << Value << "\n";
> + }
> +
> + void printNumber(StringRef Label, int16_t Value) {
> + startLine() << Label << ": " << Value << "\n";
> + }
> +
> + void printNumber(StringRef Label, int8_t Value) {
> + startLine() << Label << ": " << int(Value) << "\n";
> + }
> +
> + template<typename T>
> + void printHex(StringRef Label, T Value) {
> + startLine() << Label << ": " << hex(Value) << "\n";
> + }
> +
> + template<typename T>
> + void printHex(StringRef Label, StringRef Str, T Value) {
> + startLine() << Label << ": " << Str << " (" << hex(Value) << ")\n";
> + }
> +
> + void printString(StringRef Label, StringRef Value) {
> + startLine() << Label << ": " << Value << "\n";
> + }
> +
> + void printString(StringRef Label, const std::string &Value) {
> + startLine() << Label << ": " << Value << "\n";
> + }
> +
> + template<typename T>
> + void printNumber(StringRef Label, StringRef Str, T Value) {
> + startLine() << Label << ": " << Str << " (" << Value << ")\n";
> + }
> +
> + void printBinary(StringRef Label, StringRef Str, ArrayRef<uint8_t> Value) {
> + printBinaryImpl(Label, Str, Value, false);
> + }
> +
> + void printBinary(StringRef Label, StringRef Str, ArrayRef<char> Value) {
> + ArrayRef<uint8_t> V(reinterpret_cast<const uint8_t*>(Value.data()),
> + Value.size());
> + printBinaryImpl(Label, Str, V, false);
> + }
> +
> + void printBinary(StringRef Label, ArrayRef<uint8_t> Value) {
> + printBinaryImpl(Label, StringRef(), Value, false);
> + }
> +
> + void printBinary(StringRef Label, ArrayRef<char> Value) {
> + ArrayRef<uint8_t> V(reinterpret_cast<const uint8_t*>(Value.data()),
> + Value.size());
> + printBinaryImpl(Label, StringRef(), V, false);
> + }
> +
> + void printBinary(StringRef Label, StringRef Value) {
> + ArrayRef<uint8_t> V(reinterpret_cast<const uint8_t*>(Value.data()),
> + Value.size());
> + printBinaryImpl(Label, StringRef(), V, false);
> + }
> +
> + void printBinaryBlock(StringRef Label, StringRef Value) {
> + ArrayRef<uint8_t> V(reinterpret_cast<const uint8_t*>(Value.data()),
> + Value.size());
> + printBinaryImpl(Label, StringRef(), V, true);
> + }
> +
> + raw_ostream& startLine() {
> + printIndent();
> + return OS;
> + }
> +
> + raw_ostream& getOStream() {
> + return OS;
> + }
> +
> +private:
> + template<typename T>
> + static bool flagName(const EnumEntry<T>& lhs, const EnumEntry<T>& rhs) {
> + return lhs.Name < rhs.Name;
> + }
> +
> + void printBinaryImpl(StringRef Label, StringRef Str, ArrayRef<uint8_t> Value,
> + bool Block);
> +
> + raw_ostream &OS;
> + int IndentLevel;
> +};
> +
> +struct DictScope {
> + DictScope(StreamWriter& W, StringRef N) : W(W) {
> + W.startLine() << N << " {\n";
> + W.indent();
> + }
> +
> + ~DictScope() {
> + W.unindent();
> + W.startLine() << "}\n";
> + }
> +
> + StreamWriter& W;
> +};
> +
> +struct ListScope {
> + ListScope(StreamWriter& W, StringRef N) : W(W) {
> + W.startLine() << N << " [\n";
> + W.indent();
> + }
> +
> + ~ListScope() {
> + W.unindent();
> + W.startLine() << "]\n";
> + }
> +
> + StreamWriter& W;
> +};
> +
> +} // namespace llvm
> +
> +#endif
>
> Modified: llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp?rev=178679&r1=178678&r2=178679&view=diff
> ==============================================================================
> --- llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp (original)
> +++ llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp Wed Apr 3 13:31:38 2013
> @@ -21,268 +21,263 @@
>
> #include "llvm-readobj.h"
>
> -#include "llvm/ADT/Triple.h"
> -#include "llvm/Analysis/Verifier.h"
> -#include "llvm/Object/ELF.h"
> +#include "Error.h"
> +#include "ObjDumper.h"
> +#include "StreamWriter.h"
> +
> +#include "llvm/Object/Archive.h"
> #include "llvm/Object/ObjectFile.h"
> +#include "llvm/Support/Casting.h"
> #include "llvm/Support/CommandLine.h"
> +#include "llvm/Support/DataTypes.h"
> #include "llvm/Support/Debug.h"
> -#include "llvm/Support/Format.h"
> -#include "llvm/Support/FormattedStream.h"
> +#include "llvm/Support/FileSystem.h"
> +#include "llvm/Support/ManagedStatic.h"
> #include "llvm/Support/PrettyStackTrace.h"
> #include "llvm/Support/Signals.h"
> +#include "llvm/Support/TargetRegistry.h"
> +#include "llvm/Support/TargetSelect.h"
> +#include "llvm/Support/system_error.h"
> +
> +#include <string>
> +
>
> using namespace llvm;
> using namespace llvm::object;
>
> -static cl::opt<std::string>
> -InputFilename(cl::Positional, cl::desc("<input object>"), cl::init(""));
> -
> -static void dumpSymbolHeader() {
> - outs() << format(" %-32s", (const char *)"Name")
> - << format(" %-4s", (const char *)"Type")
> - << format(" %-4s", (const char *)"Section")
> - << format(" %-16s", (const char *)"Address")
> - << format(" %-16s", (const char *)"Size")
> - << format(" %-16s", (const char *)"FileOffset")
> - << format(" %-26s", (const char *)"Flags") << "\n";
> -}
> +namespace opts {
> + cl::list<std::string> InputFilenames(cl::Positional,
> + cl::desc("<input object files>"),
> + cl::ZeroOrMore);
> +
> + // -file-headers, -h
> + cl::opt<bool> FileHeaders("file-headers",
> + cl::desc("Display file headers "));
> + cl::alias FileHeadersShort("h",
> + cl::desc("Alias for --file-headers"),
> + cl::aliasopt(FileHeaders));
> +
> + // -sections, -s
> + cl::opt<bool> Sections("sections",
> + cl::desc("Display all sections."));
> + cl::alias SectionsShort("s",
> + cl::desc("Alias for --sections"),
> + cl::aliasopt(Sections));
> +
> + // -section-relocations, -sr
> + cl::opt<bool> SectionRelocations("section-relocations",
> + cl::desc("Display relocations for each section shown."));
> + cl::alias SectionRelocationsShort("sr",
> + cl::desc("Alias for --section-relocations"),
> + cl::aliasopt(SectionRelocations));
> +
> + // -section-symbols, -st
> + cl::opt<bool> SectionSymbols("section-symbols",
> + cl::desc("Display symbols for each section shown."));
> + cl::alias SectionSymbolsShort("st",
> + cl::desc("Alias for --section-symbols"),
> + cl::aliasopt(SectionSymbols));
> +
> + // -section-data, -sd
> + cl::opt<bool> SectionData("section-data",
> + cl::desc("Display section data for each section shown."));
> + cl::alias SectionDataShort("sd",
> + cl::desc("Alias for --section-data"),
> + cl::aliasopt(SectionData));
> +
> + // -relocations, -r
> + cl::opt<bool> Relocations("relocations",
> + cl::desc("Display the relocation entries in the file"));
> + cl::alias RelocationsShort("r",
> + cl::desc("Alias for --relocations"),
> + cl::aliasopt(Relocations));
> +
> + // -symbols, -t
> + cl::opt<bool> Symbols("symbols",
> + cl::desc("Display the symbol table"));
> + cl::alias SymbolsShort("t",
> + cl::desc("Alias for --symbols"),
> + cl::aliasopt(Symbols));
> +
> + // -dyn-symbols, -dt
> + cl::opt<bool> DynamicSymbols("dyn-symbols",
> + cl::desc("Display the dynamic symbol table"));
> + cl::alias DynamicSymbolsShort("dt",
> + cl::desc("Alias for --dyn-symbols"),
> + cl::aliasopt(DynamicSymbols));
> +
> + // -unwind, -u
> + cl::opt<bool> UnwindInfo("unwind",
> + cl::desc("Display unwind information"));
> + cl::alias UnwindInfoShort("u",
> + cl::desc("Alias for --unwind"),
> + cl::aliasopt(UnwindInfo));
> +
> + // -dynamic-table
> + cl::opt<bool> DynamicTable("dynamic-table",
> + cl::desc("Display the ELF .dynamic section table"));
> +
> + // -needed-libs
> + cl::opt<bool> NeededLibraries("needed-libs",
> + cl::desc("Display the needed libraries"));
> +} // namespace opts
> +
> +namespace llvm {
> +
> +bool error(error_code EC) {
> + if (!EC)
> + return false;
> +
> + outs() << "\nError reading file: " << EC.message() << ".\n";
> + outs().flush();
> + return true;
> +}
> +
> +bool relocAddressLess(RelocationRef a, RelocationRef b) {
> + uint64_t a_addr, b_addr;
> + if (error(a.getAddress(a_addr))) return false;
> + if (error(b.getAddress(b_addr))) return false;
> + return a_addr < b_addr;
> +}
> +
> +} // namespace llvm
> +
> +
> +static void reportError(StringRef Input, error_code EC) {
> + if (Input == "-")
> + Input = "<stdin>";
> +
> + errs() << Input << ": " << EC.message() << "\n";
> + errs().flush();
> +}
> +
> +static void reportError(StringRef Input, StringRef Message) {
> + if (Input == "-")
> + Input = "<stdin>";
> +
> + errs() << Input << ": " << Message << "\n";
> +}
> +
> +/// @brief Creates an format-specific object file dumper.
> +static error_code createDumper(const ObjectFile *Obj,
> + StreamWriter &Writer,
> + OwningPtr<ObjDumper> &Result) {
> + if (!Obj)
> + return readobj_error::unsupported_file_format;
> +
> + if (Obj->isCOFF())
> + return createCOFFDumper(Obj, Writer, Result);
> + if (Obj->isELF())
> + return createELFDumper(Obj, Writer, Result);
> + if (Obj->isMachO())
> + return createMachODumper(Obj, Writer, Result);
> +
> + return readobj_error::unsupported_obj_file_format;
> +}
> +
> +
> +/// @brief Dumps the specified object file.
> +static void dumpObject(const ObjectFile *Obj) {
> + StreamWriter Writer(outs());
> + OwningPtr<ObjDumper> Dumper;
> + if (error_code EC = createDumper(Obj, Writer, Dumper)) {
> + reportError(Obj->getFileName(), EC);
> + return;
> + }
>
> -static void dumpSectionHeader() {
> - outs() << format(" %-24s", (const char*)"Name")
> - << format(" %-16s", (const char*)"Address")
> - << format(" %-16s", (const char*)"Size")
> - << format(" %-8s", (const char*)"Align")
> - << format(" %-26s", (const char*)"Flags")
> + outs() << '\n';
> + outs() << "File: " << Obj->getFileName() << "\n";
> + outs() << "Format: " << Obj->getFileFormatName() << "\n";
> + outs() << "Arch: "
> + << Triple::getArchTypeName((llvm::Triple::ArchType)Obj->getArch())
> << "\n";
> + outs() << "AddressSize: " << (8*Obj->getBytesInAddress()) << "bit\n";
> + if (Obj->isELF())
> + outs() << "LoadName: " << Obj->getLoadName() << "\n";
> +
> + if (opts::FileHeaders)
> + Dumper->printFileHeaders();
> + if (opts::Sections)
> + Dumper->printSections();
> + if (opts::Relocations)
> + Dumper->printRelocations();
> + if (opts::Symbols)
> + Dumper->printSymbols();
> + if (opts::DynamicSymbols)
> + Dumper->printDynamicSymbols();
> + if (opts::UnwindInfo)
> + Dumper->printUnwindInfo();
> + if (opts::DynamicTable)
> + Dumper->printDynamicTable();
> + if (opts::NeededLibraries)
> + Dumper->printNeededLibraries();
> }
>
> -static const char *getTypeStr(SymbolRef::Type Type) {
> - switch (Type) {
> - case SymbolRef::ST_Unknown: return "?";
> - case SymbolRef::ST_Data: return "DATA";
> - case SymbolRef::ST_Debug: return "DBG";
> - case SymbolRef::ST_File: return "FILE";
> - case SymbolRef::ST_Function: return "FUNC";
> - case SymbolRef::ST_Other: return "-";
> - }
> - return "INV";
> -}
>
> -static std::string getSymbolFlagStr(uint32_t Flags) {
> - std::string result;
> - if (Flags & SymbolRef::SF_Undefined)
> - result += "undef,";
> - if (Flags & SymbolRef::SF_Global)
> - result += "global,";
> - if (Flags & SymbolRef::SF_Weak)
> - result += "weak,";
> - if (Flags & SymbolRef::SF_Absolute)
> - result += "absolute,";
> - if (Flags & SymbolRef::SF_ThreadLocal)
> - result += "threadlocal,";
> - if (Flags & SymbolRef::SF_Common)
> - result += "common,";
> - if (Flags & SymbolRef::SF_FormatSpecific)
> - result += "formatspecific,";
> -
> - // Remove trailing comma
> - if (result.size() > 0) {
> - result.erase(result.size() - 1);
> - }
> - return result;
> -}
> +/// @brief Dumps each object file in \a Arc;
> +static void dumpArchive(const Archive *Arc) {
> + for (Archive::child_iterator ArcI = Arc->begin_children(),
> + ArcE = Arc->end_children();
> + ArcI != ArcE; ++ArcI) {
> + OwningPtr<Binary> child;
> + if (error_code EC = ArcI->getAsBinary(child)) {
> + // Ignore non-object files.
> + if (EC != object_error::invalid_file_type)
> + reportError(Arc->getFileName(), EC.message());
> + continue;
> + }
>
> -static void checkError(error_code ec, const char *msg) {
> - if (ec)
> - report_fatal_error(std::string(msg) + ": " + ec.message());
> + if (ObjectFile *Obj = dyn_cast<ObjectFile>(child.get()))
> + dumpObject(Obj);
> + else
> + reportError(Arc->getFileName(), readobj_error::unrecognized_file_format);
> + }
> }
>
> -static std::string getSectionFlagStr(const SectionRef &Section) {
> - const struct {
> - error_code (SectionRef::*MemF)(bool &) const;
> - const char *FlagStr, *ErrorStr;
> - } Work[] =
> - {{ &SectionRef::isText, "text,", "Section.isText() failed" },
> - { &SectionRef::isData, "data,", "Section.isData() failed" },
> - { &SectionRef::isBSS, "bss,", "Section.isBSS() failed" },
> - { &SectionRef::isRequiredForExecution, "required,",
> - "Section.isRequiredForExecution() failed" },
> - { &SectionRef::isVirtual, "virtual,", "Section.isVirtual() failed" },
> - { &SectionRef::isZeroInit, "zeroinit,", "Section.isZeroInit() failed" },
> - { &SectionRef::isReadOnlyData, "rodata,",
> - "Section.isReadOnlyData() failed" }};
> -
> - std::string result;
> - for (uint32_t I = 0; I < sizeof(Work)/sizeof(*Work); ++I) {
> - bool B;
> - checkError((Section.*Work[I].MemF)(B), Work[I].ErrorStr);
> - if (B)
> - result += Work[I].FlagStr;
> - }
>
> - // Remove trailing comma
> - if (result.size() > 0) {
> - result.erase(result.size() - 1);
> +/// @brief Opens \a File and dumps it.
> +static void dumpInput(StringRef File) {
> + // If file isn't stdin, check that it exists.
> + if (File != "-" && !sys::fs::exists(File)) {
> + reportError(File, readobj_error::file_not_found);
> + return;
> }
> - return result;
> -}
>
> -static void
> -dumpSymbol(const SymbolRef &Sym, const ObjectFile *obj, bool IsDynamic) {
> - StringRef Name;
> - SymbolRef::Type Type;
> - uint32_t Flags;
> - uint64_t Address;
> - uint64_t Size;
> - uint64_t FileOffset;
> - checkError(Sym.getName(Name), "SymbolRef.getName() failed");
> - checkError(Sym.getAddress(Address), "SymbolRef.getAddress() failed");
> - checkError(Sym.getSize(Size), "SymbolRef.getSize() failed");
> - checkError(Sym.getFileOffset(FileOffset),
> - "SymbolRef.getFileOffset() failed");
> - checkError(Sym.getType(Type), "SymbolRef.getType() failed");
> - checkError(Sym.getFlags(Flags), "SymbolRef.getFlags() failed");
> - std::string FullName = Name;
> -
> - llvm::object::section_iterator symSection(obj->begin_sections());
> - Sym.getSection(symSection);
> - StringRef sectionName;
> -
> - if (symSection != obj->end_sections())
> - checkError(symSection->getName(sectionName),
> - "SectionRef::getName() failed");
> -
> - // If this is a dynamic symbol from an ELF object, append
> - // the symbol's version to the name.
> - if (IsDynamic && obj->isELF()) {
> - StringRef Version;
> - bool IsDefault;
> - GetELFSymbolVersion(obj, Sym, Version, IsDefault);
> - if (!Version.empty()) {
> - FullName += (IsDefault ? "@@" : "@");
> - FullName += Version;
> - }
> + // Attempt to open the binary.
> + OwningPtr<Binary> Binary;
> + if (error_code EC = createBinary(File, Binary)) {
> + reportError(File, EC);
> + return;
> }
>
> - // format() can't handle StringRefs
> - outs() << format(" %-32s", FullName.c_str())
> - << format(" %-4s", getTypeStr(Type))
> - << format(" %-32s", std::string(sectionName).c_str())
> - << format(" %16" PRIx64, Address) << format(" %16" PRIx64, Size)
> - << format(" %16" PRIx64, FileOffset) << " "
> - << getSymbolFlagStr(Flags) << "\n";
> -}
> -
> -static void dumpStaticSymbol(const SymbolRef &Sym, const ObjectFile *obj) {
> - return dumpSymbol(Sym, obj, false);
> -}
> -
> -static void dumpDynamicSymbol(const SymbolRef &Sym, const ObjectFile *obj) {
> - return dumpSymbol(Sym, obj, true);
> -}
> -
> -static void dumpSection(const SectionRef &Section, const ObjectFile *obj) {
> - StringRef Name;
> - checkError(Section.getName(Name), "SectionRef::getName() failed");
> - uint64_t Addr, Size, Align;
> - checkError(Section.getAddress(Addr), "SectionRef::getAddress() failed");
> - checkError(Section.getSize(Size), "SectionRef::getSize() failed");
> - checkError(Section.getAlignment(Align), "SectionRef::getAlignment() failed");
> - outs() << format(" %-24s", std::string(Name).c_str())
> - << format(" %16" PRIx64, Addr)
> - << format(" %16" PRIx64, Size)
> - << format(" %8" PRIx64, Align)
> - << " " << getSectionFlagStr(Section)
> - << "\n";
> -}
> -
> -static void dumpLibrary(const LibraryRef &lib, const ObjectFile *obj) {
> - StringRef path;
> - lib.getPath(path);
> - outs() << " " << path << "\n";
> + if (Archive *Arc = dyn_cast<Archive>(Binary.get()))
> + dumpArchive(Arc);
> + else if (ObjectFile *Obj = dyn_cast<ObjectFile>(Binary.get()))
> + dumpObject(Obj);
> + else
> + reportError(File, readobj_error::unrecognized_file_format);
> }
>
> -template<typename Iterator, typename Func>
> -static void dump(const ObjectFile *obj, Func f, Iterator begin, Iterator end,
> - const char *errStr) {
> - error_code ec;
> - uint32_t count = 0;
> - Iterator it = begin, ie = end;
> - while (it != ie) {
> - f(*it, obj);
> - it.increment(ec);
> - if (ec)
> - report_fatal_error(errStr);
> - ++count;
> - }
> - outs() << " Total: " << count << "\n\n";
> -}
>
> -static void dumpHeaders(const ObjectFile *obj) {
> - outs() << "File Format : " << obj->getFileFormatName() << "\n";
> - outs() << "Arch : "
> - << Triple::getArchTypeName((llvm::Triple::ArchType)obj->getArch())
> - << "\n";
> - outs() << "Address Size: " << (8*obj->getBytesInAddress()) << " bits\n";
> - outs() << "Load Name : " << obj->getLoadName() << "\n";
> - outs() << "\n";
> -}
> -
> -int main(int argc, char** argv) {
> - error_code ec;
> +int main(int argc, const char *argv[]) {
> sys::PrintStackTraceOnErrorSignal();
> PrettyStackTraceProgram X(argc, argv);
> + llvm_shutdown_obj Y;
>
> - cl::ParseCommandLineOptions(argc, argv,
> - "LLVM Object Reader\n");
> + // Initialize targets.
> + llvm::InitializeAllTargetInfos();
>
> - if (InputFilename.empty()) {
> - errs() << "Please specify an input filename\n";
> - return 1;
> - }
> + // Register the target printer for --version.
> + cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion);
>
> - // Open the object file
> - OwningPtr<MemoryBuffer> File;
> - if (MemoryBuffer::getFile(InputFilename, File)) {
> - errs() << InputFilename << ": Open failed\n";
> - return 1;
> - }
> + cl::ParseCommandLineOptions(argc, argv, "LLVM Object Reader\n");
>
> - OwningPtr<ObjectFile> o(ObjectFile::createObjectFile(File.take()));
> - ObjectFile *obj = o.get();
> - if (!obj) {
> - errs() << InputFilename << ": Object type not recognized\n";
> - }
> + // Default to stdin if no filename is specified.
> + if (opts::InputFilenames.size() == 0)
> + opts::InputFilenames.push_back("-");
>
> - dumpHeaders(obj);
> -
> - outs() << "Symbols:\n";
> - dumpSymbolHeader();
> - dump(obj, dumpStaticSymbol, obj->begin_symbols(), obj->end_symbols(),
> - "Symbol iteration failed");
> -
> - outs() << "Dynamic Symbols:\n";
> - dumpSymbolHeader();
> - dump(obj, dumpDynamicSymbol, obj->begin_dynamic_symbols(),
> - obj->end_dynamic_symbols(), "Symbol iteration failed");
> -
> - outs() << "Sections:\n";
> - dumpSectionHeader();
> - dump(obj, &dumpSection, obj->begin_sections(), obj->end_sections(),
> - "Section iteration failed");
> -
> - if (obj->isELF()) {
> - if (ErrorOr<void> e = dumpELFDynamicTable(obj, outs()))
> - ;
> - else
> - errs() << "InputFilename" << ": " << error_code(e).message() << "\n";
> - }
> -
> - outs() << "Libraries needed:\n";
> - dump(obj, &dumpLibrary, obj->begin_libraries_needed(),
> - obj->end_libraries_needed(), "Needed libraries iteration failed");
> + std::for_each(opts::InputFilenames.begin(), opts::InputFilenames.end(),
> + dumpInput);
>
> return 0;
> }
> -
>
> Modified: llvm/trunk/tools/llvm-readobj/llvm-readobj.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/llvm-readobj.h?rev=178679&r1=178678&r2=178679&view=diff
> ==============================================================================
> --- llvm/trunk/tools/llvm-readobj/llvm-readobj.h (original)
> +++ llvm/trunk/tools/llvm-readobj/llvm-readobj.h Wed Apr 3 13:31:38 2013
> @@ -1,4 +1,4 @@
> -//===- llvm-readobj.h - Dump contents of an Object File -------------------===//
> +//===-- llvm-readobj.h ----------------------------------------------------===//
> //
> // The LLVM Compiler Infrastructure
> //
> @@ -10,13 +10,36 @@
> #ifndef LLVM_TOOLS_READ_OBJ_H
> #define LLVM_TOOLS_READ_OBJ_H
>
> -#include "llvm/Support/ErrorOr.h"
> +#include "llvm/Support/CommandLine.h"
> +#include <string>
>
> namespace llvm {
> -namespace object { class ObjectFile; }
> -class raw_ostream;
> + namespace object {
> + class RelocationRef;
> + }
>
> -ErrorOr<void> dumpELFDynamicTable(object::ObjectFile *O, raw_ostream &OS);
> -} // end namespace llvm
> + class error_code;
> +
> + // Various helper functions.
> + bool error(error_code ec);
> + bool relocAddressLess(object::RelocationRef A,
> + object::RelocationRef B);
> +} // namespace llvm
> +
> +namespace opts {
> + extern llvm::cl::list<std::string> InputFilenames;
> + extern llvm::cl::opt<bool> FileHeaders;
> + extern llvm::cl::opt<bool> Sections;
> + extern llvm::cl::opt<bool> SectionRelocations;
> + extern llvm::cl::opt<bool> SectionSymbols;
> + extern llvm::cl::opt<bool> SectionData;
> + extern llvm::cl::opt<bool> Relocations;
> + extern llvm::cl::opt<bool> Symbols;
> + extern llvm::cl::opt<bool> DynamicSymbols;
> + extern llvm::cl::opt<bool> UnwindInfo;
> +} // namespace opts
> +
> +#define LLVM_READOBJ_ENUM_ENT(ns, enum) \
> + { #enum, ns::enum }
>
> #endif
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list