llvm.org GIT mirror llvm / 76e70f3
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! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178679 91177308-0d34-0410-b5e6-96231b3b80d8 Eric Christopher 7 years ago
34 changed file(s) with 3963 addition(s) and 556 deletion(s). Raw diff Collapse all Expand all
789789 uint64_t getNumSections() const;
790790 uint64_t getStringTableIndex() const;
791791 ELF::Elf64_Word getSymbolTableIndex(const Elf_Sym *symb) const;
792 const Elf_Ehdr *getElfHeader() const;
792793 const Elf_Shdr *getSection(const Elf_Sym *symb) const;
793794 const Elf_Shdr *getElfSection(section_iterator &It) const;
794795 const Elf_Sym *getElfSymbol(symbol_iterator &It) const;
965966 if (symb->st_shndx >= ELF::SHN_LORESERVE)
966967 return 0;
967968 return getSection(symb->st_shndx);
969 }
970
971 template
972 const typename ELFObjectFile::Elf_Ehdr *
973 ELFObjectFile::getElfHeader() const {
974 return Header;
968975 }
969976
970977 template
320320 IMAGE_COMDAT_SELECT_SAME_SIZE,
321321 IMAGE_COMDAT_SELECT_EXACT_MATCH,
322322 IMAGE_COMDAT_SELECT_ASSOCIATIVE,
323 IMAGE_COMDAT_SELECT_LARGEST
323 IMAGE_COMDAT_SELECT_LARGEST,
324 IMAGE_COMDAT_SELECT_NEWEST
324325 };
325326
326327 // Auxiliary Symbol Formats
105105 return reinterpret_cast(&UnwindCodes[(NumCodes+1) & ~1]);
106106 }
107107
108 /// \brief Return image-relativ offset of language-specific exception handler.
109 uint32_t getLanguageSpecificHandlerOffset() {
110 return *reinterpret_cast(getLanguageSpecificData());
108 /// \brief Return pointer to language specific data part of UnwindInfo.
109 const void *getLanguageSpecificData() const {
110 return reinterpret_cast(&UnwindCodes[(NumCodes+1) & ~1]);
111111 }
112112
113 /// \brief Set image-relativ offset of language-specific exception handler.
113 /// \brief Return image-relative offset of language-specific exception handler.
114 uint32_t getLanguageSpecificHandlerOffset() const {
115 return *reinterpret_cast(getLanguageSpecificData());
116 }
117
118 /// \brief Set image-relative offset of language-specific exception handler.
114119 void setLanguageSpecificHandlerOffset(uint32_t offset) {
115120 *reinterpret_cast(getLanguageSpecificData()) = offset;
116121 }
125130 RuntimeFunction *getChainedFunctionEntry() {
126131 return reinterpret_cast(getLanguageSpecificData());
127132 }
133
134 /// \brief Return pointer to chained unwind info.
135 const RuntimeFunction *getChainedFunctionEntry() const {
136 return reinterpret_cast(getLanguageSpecificData());
137 }
128138 };
129139
130140
0 // RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o %t
1 // RUN: llvm-readobj %t | FileCheck %s
1 // RUN: llvm-readobj -s %t | FileCheck %s
22
33 // CHECK: symtab_shndx
44
None RUN: llvm-readobj %p/Inputs/elf-versioning-test.i386 \
0 RUN: llvm-readobj -dt %p/Inputs/elf-versioning-test.i386 \
11 RUN: | FileCheck %s -check-prefix ELF
2 RUN: llvm-readobj %p/Inputs/elf-versioning-test.i386 \
2 RUN: llvm-readobj -dt %p/Inputs/elf-versioning-test.i386 \
33 RUN: | FileCheck %s -check-prefix ELF32
4 RUN: llvm-readobj %p/Inputs/elf-versioning-test.x86_64 \
4 RUN: llvm-readobj -dt %p/Inputs/elf-versioning-test.x86_64 \
55 RUN: | FileCheck %s -check-prefix ELF
6 RUN: llvm-readobj %p/Inputs/elf-versioning-test.x86_64 \
6 RUN: llvm-readobj -dt %p/Inputs/elf-versioning-test.x86_64 \
77 RUN: | FileCheck %s -check-prefix ELF64
88
9 ELF: foo@@VER2 FUNC .text {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} global
10 ELF: foo@VER1 FUNC .text {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} global
11 ELF: unversioned_define FUNC .text {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} global
9 ELF: DynamicSymbols [
10 ELF: Symbol {
11 ELF: Name: foo@@VER2
12 ELF: Binding: Global
13 ELF: Type: Function
14 ELF: Section: .text
15 ELF: }
16 ELF: Symbol {
17 ELF: Name: foo@VER1
18 ELF: Binding: Global
19 ELF: Type: Function
20 ELF: Section: .text
21 ELF: }
22 ELF: Symbol {
23 ELF: Name: unversioned_define
24 ELF: Binding: Global
25 ELF: Type: Function
26 ELF: Section: .text
27 ELF: }
28 ELF: ]
1229
13 ELF32: puts@GLIBC_2.0 FUNC {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} undef,global
14 ELF64: puts@GLIBC_2.2.5 FUNC {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} undef,global
30 ELF32: DynamicSymbols [
31 ELF32: Symbol {
32 ELF32: Name: puts@GLIBC_2.0
33 ELF32: Binding: Global
34 ELF32: Type: Function
35 ELF32: Section: (0x0)
36 ELF32: }
37 ELF32: ]
38 ELF64: DynamicSymbols [
39 ELF64: Symbol {
40 ELF64: Name: puts@GLIBC_2.2.5
41 ELF64: Binding: Global
42 ELF64: Type: Function
43 ELF64: Section: (0x0)
44 ELF64: }
45 ELF64: ]
None RUN: llvm-readobj %p/Inputs/shared-object-test.elf-i386 \
0 RUN: llvm-readobj -s -t -dt -dynamic-table -needed-libs \
1 RUN: %p/Inputs/shared-object-test.elf-i386 \
12 RUN: | FileCheck %s -check-prefix ELF
2 RUN: llvm-readobj %p/Inputs/shared-object-test.elf-i386 \
3 RUN: llvm-readobj -s -t -dt -dynamic-table -needed-libs \
4 RUN: %p/Inputs/shared-object-test.elf-i386 \
35 RUN: | FileCheck %s -check-prefix ELF32
46
5 RUN: llvm-readobj %p/Inputs/shared-object-test.elf-x86-64 \
7 RUN: llvm-readobj -s -t -dt -dynamic-table -needed-libs \
8 RUN: %p/Inputs/shared-object-test.elf-x86-64 \
69 RUN: | FileCheck %s -check-prefix ELF
7 RUN: llvm-readobj %p/Inputs/shared-object-test.elf-x86-64 \
10 RUN: llvm-readobj -s -t -dt -dynamic-table -needed-libs \
11 RUN: %p/Inputs/shared-object-test.elf-x86-64 \
812 RUN: | FileCheck %s -check-prefix ELF64
913
10 ELF64:File Format : ELF64-x86-64
11 ELF64:Arch : x86_64
12 ELF64:Address Size: 64 bits
13 ELF64:Load Name : libfoo.so
14
15 ELF32:File Format : ELF32-i386
16 ELF32:Arch : i386
17 ELF32:Address Size: 32 bits
18 ELF32:Load Name : libfoo.so
19
20 ELF:Symbols:
21 ELF: Name Type Section Address Size FileOffset Flags
22 ELF: .dynsym DBG .dynsym {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} formatspecific
23 ELF: .dynstr DBG .dynstr {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} formatspecific
24 ELF: .text DBG .text {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} formatspecific
25 ELF: .eh_frame DBG .eh_frame {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} formatspecific
26 ELF: .tdata DBG .tdata {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} formatspecific
27 ELF: .dynamic DBG .dynamic {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} formatspecific
28 ELF: .got.plt DBG .got.plt {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} formatspecific
29 ELF: .data DBG .data {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} formatspecific
30 ELF: .bss DBG .bss {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} formatspecific
31 ELF: shared.ll FILE {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} absolute,formatspecific
32 ELF: local_func FUNC .text {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}}
33 ELF: _GLOBAL_OFFSET_TABLE_ DATA {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} absolute
34 ELF: _DYNAMIC DATA {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} absolute
35 ELF: common_sym DATA .bss {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} global
36 ELF: tls_sym DATA .tdata {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} global,threadlocal
37 ELF: defined_sym DATA .data {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} global
38 ELF: __bss_start ? {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} global,absolute
39 ELF: _end ? {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} global,absolute
40 ELF: global_func FUNC .text {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} global
41 ELF: _edata ? {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} global,absolute
42 ELF: Total: 21
43
44 ELF:Dynamic Symbols:
45 ELF: Name Type Section Address Size FileOffset Flags
46 ELF: common_sym DATA .bss {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} global
47 ELF: tls_sym DATA .tdata {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} global,threadlocal
48 ELF: defined_sym DATA .data {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} global
49 ELF: __bss_start ? {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} global,absolute
50 ELF: _end ? {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} global,absolute
51 ELF: global_func FUNC .text {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} global
52 ELF: _edata ? {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} global,absolute
53 ELF: Total: {{[0-9a-f]+}}
54
55 ELF:Sections:
56 ELF: Name Address Size Align Flags
57 ELF: {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} rodata
58 ELF: .hash {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} required,rodata
59 ELF: .dynsym {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} required,rodata
60 ELF: .dynstr {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} required,rodata
61 ELF: .text {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} text,{{(data,)?}}required
62 ELF: .eh_frame {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} data,required,rodata
63 ELF: .tdata {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} data,required
64 ELF: .dynamic {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} required
65 ELF: .got.plt {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} data,required
66 ELF: .data {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} data,required
67 ELF: .bss {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} bss,required,virtual,zeroinit
68 ELF: .shstrtab {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} rodata
69 ELF: .symtab {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} rodata
70 ELF: .strtab {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} rodata
71 ELF: Total: 14
72
73 ELF:Dynamic section contains 9 entries
74 ELF: Tag Type Name/Value
75 ELF: 00000001 (NEEDED) Shared library: [libc.so.6]
76 ELF: 00000001 (NEEDED) Shared library: [libm.so.6]
77 ELF: 0000000e (SONAME) Library soname: [libfoo.so]
78 ELF: 00000004 (HASH) {{[0-9a-f]+}}
79 ELF: 00000005 (STRTAB) {{[0-9a-f]+}}
80 ELF: 00000006 (SYMTAB) {{[0-9a-f]+}}
81 ELF: 0000000a (STRSZ) {{[0-9]+}} (bytes)
82 ELF: 0000000b (SYMENT) {{[0-9]+}} (bytes)
83 ELF: 00000000 (NULL) 0x0
84 ELF: Total: 9
85
86 ELF:Libraries needed:
87 ELF: libc.so.6
88 ELF: libm.so.6
89 ELF: Total: 2
90
91
14 ELF64: Format: ELF64-x86-64
15 ELF64: Arch: x86_64
16 ELF64: AddressSize: 64bit
17 ELF64: LoadName: libfoo.so
18
19 ELF32: Format: ELF32-i386
20 ELF32: Arch: i386
21 ELF32: AddressSize: 32bit
22 ELF32: LoadName: libfoo.so
23
24 ELF: Sections [
25 ELF: Section {
26 ELF: Name: (0)
27 ELF: Type: SHT_NULL
28 ELF: Flags [ (0x0)
29 ELF: ]
30 ELF: }
31 ELF: Section {
32 ELF: Name: .hash
33 ELF: Type: SHT_HASH
34 ELF: Flags [ (0x2)
35 ELF: SHF_ALLOC
36 ELF: ]
37 ELF: }
38 ELF: Section {
39 ELF: Name: .dynsym
40 ELF: Type: SHT_DYNSYM
41 ELF: Flags [ (0x2)
42 ELF: SHF_ALLOC
43 ELF: ]
44 ELF: }
45 ELF: Section {
46 ELF: Name: .dynstr
47 ELF: Type: SHT_STRTAB
48 ELF: Flags [ (0x2)
49 ELF: SHF_ALLOC
50 ELF: ]
51 ELF: }
52 ELF: Section {
53 ELF: Name: .text
54 ELF: Type: SHT_PROGBITS
55 ELF: Flags [ (0x6)
56 ELF: SHF_ALLOC
57 ELF: SHF_EXECINSTR
58 ELF: ]
59 ELF: }
60 ELF: Section {
61 ELF: Name: .eh_frame
62 ELF: Type: SHT_PROGBITS
63 ELF: Flags [ (0x2)
64 ELF: SHF_ALLOC
65 ELF: ]
66 ELF: }
67 ELF: Section {
68 ELF: Name: .tdata
69 ELF: Type: SHT_PROGBITS
70 ELF: Flags [ (0x403)
71 ELF: SHF_ALLOC
72 ELF: SHF_TLS
73 ELF: SHF_WRITE
74 ELF: ]
75 ELF: }
76 ELF: Section {
77 ELF: Name: .dynamic
78 ELF: Type: SHT_DYNAMIC
79 ELF: Flags [ (0x3)
80 ELF: SHF_ALLOC
81 ELF: SHF_WRITE
82 ELF: ]
83 ELF: }
84 ELF: Section {
85 ELF: Name: .got.plt
86 ELF: Type: SHT_PROGBITS
87 ELF: Flags [ (0x3)
88 ELF: SHF_ALLOC
89 ELF: SHF_WRITE
90 ELF: ]
91 ELF: }
92 ELF: Section {
93 ELF: Name: .data
94 ELF: Type: SHT_PROGBITS
95 ELF: Flags [ (0x3)
96 ELF: SHF_ALLOC
97 ELF: SHF_WRITE
98 ELF: ]
99 ELF: }
100 ELF: Section {
101 ELF: Name: .bss
102 ELF: Type: SHT_NOBITS
103 ELF: Flags [ (0x3)
104 ELF: SHF_ALLOC
105 ELF: SHF_WRITE
106 ELF: ]
107 ELF: }
108 ELF: Section {
109 ELF: Name: .shstrtab
110 ELF: Type: SHT_STRTAB
111 ELF: Flags [ (0x0)
112 ELF: ]
113 ELF: }
114 ELF: Section {
115 ELF: Name: .symtab
116 ELF: Type: SHT_SYMTAB
117 ELF: Flags [ (0x0)
118 ELF: ]
119 ELF: }
120 ELF: Section {
121 ELF: Name: .strtab
122 ELF: Type: SHT_STRTAB
123 ELF: Flags [ (0x0)
124 ELF: ]
125 ELF: }
126 ELF: ]
127
128 ELF: Symbols [
129 ELF: Symbol {
130 ELF: Name: .hash
131 ELF: Binding: Local
132 ELF: Type: Section
133 ELF: Section: .hash
134 ELF: }
135 ELF: Symbol {
136 ELF: Name: .dynsym
137 ELF: Binding: Local
138 ELF: Type: Section
139 ELF: Section: .dynsym
140 ELF: }
141 ELF: Symbol {
142 ELF: Name: .dynstr
143 ELF: Binding: Local
144 ELF: Type: Section
145 ELF: Section: .dynstr
146 ELF: }
147 ELF: Symbol {
148 ELF: Name: .text
149 ELF: Binding: Local
150 ELF: Type: Section
151 ELF: Section: .text
152 ELF: }
153 ELF: Symbol {
154 ELF: Name: .eh_frame
155 ELF: Binding: Local
156 ELF: Type: Section
157 ELF: Section: .eh_frame
158 ELF: }
159 ELF: Symbol {
160 ELF: Name: .tdata
161 ELF: Binding: Local
162 ELF: Type: Section
163 ELF: Section: .tdata
164 ELF: }
165 ELF: Symbol {
166 ELF: Name: .dynamic
167 ELF: Binding: Local
168 ELF: Type: Section
169 ELF: Section: .dynamic
170 ELF: }
171 ELF: Symbol {
172 ELF: Name: .got.plt
173 ELF: Binding: Local
174 ELF: Type: Section
175 ELF: Section: .got.plt
176 ELF: }
177 ELF: Symbol {
178 ELF: Name: .data
179 ELF: Binding: Local
180 ELF: Type: Section
181 ELF: Section: .data
182 ELF: }
183 ELF: Symbol {
184 ELF: Name: .bss
185 ELF: Binding: Local
186 ELF: Type: Section
187 ELF: Section: .bss
188 ELF: }
189 ELF: Symbol {
190 ELF: Name: shared.ll
191 ELF: Binding: Local
192 ELF: Type: File
193 ELF: Section: (0xFFF1)
194 ELF: }
195 ELF: Symbol {
196 ELF: Name: local_func
197 ELF: Binding: Local
198 ELF: Type: Function
199 ELF: Section: .text
200 ELF: }
201 ELF: Symbol {
202 ELF: Name: _GLOBAL_OFFSET_TABLE_
203 ELF: Binding: Local
204 ELF: Type: Object
205 ELF: Section: (0xFFF1)
206 ELF: }
207 ELF: Symbol {
208 ELF: Name: _DYNAMIC
209 ELF: Binding: Local
210 ELF: Type: Object
211 ELF: Section: (0xFFF1)
212 ELF: }
213 ELF: Symbol {
214 ELF: Name: common_sym
215 ELF: Binding: Global
216 ELF: Type: Object
217 ELF: Section: .bss
218 ELF: }
219 ELF: Symbol {
220 ELF: Name: tls_sym
221 ELF: Binding: Global
222 ELF: Type: TLS
223 ELF: Section: .tdata
224 ELF: }
225 ELF: Symbol {
226 ELF: Name: defined_sym
227 ELF: Binding: Global
228 ELF: Type: Object
229 ELF: Section: .data
230 ELF: }
231 ELF: Symbol {
232 ELF: Name: __bss_start
233 ELF: Binding: Global
234 ELF: Type: None
235 ELF: Section: (0xFFF1)
236 ELF: }
237 ELF: Symbol {
238 ELF: Name: _end
239 ELF: Binding: Global
240 ELF: Type: None
241 ELF: Section: (0xFFF1)
242 ELF: }
243 ELF: Symbol {
244 ELF: Name: global_func
245 ELF: Binding: Global
246 ELF: Type: Function
247 ELF: Section: .text
248 ELF: }
249 ELF: Symbol {
250 ELF: Name: _edata
251 ELF: Binding: Global
252 ELF: Type: None
253 ELF: Section: (0xFFF1)
254 ELF: }
255 ELF: ]
256
257 ELF: DynamicSymbols [
258 ELF: Symbol {
259 ELF: Name: common_sym
260 ELF: Binding: Global
261 ELF: Type: Object
262 ELF: Section: .bss
263 ELF: }
264 ELF: Symbol {
265 ELF: Name: tls_sym
266 ELF: Binding: Global
267 ELF: Type: TLS
268 ELF: Section: .tdata
269 ELF: }
270 ELF: Symbol {
271 ELF: Name: defined_sym
272 ELF: Binding: Global
273 ELF: Type: Object
274 ELF: Section: .data
275 ELF: }
276 ELF: Symbol {
277 ELF: Name: __bss_start
278 ELF: Binding: Global
279 ELF: Type: None
280 ELF: Section: (0xFFF1)
281 ELF: }
282 ELF: Symbol {
283 ELF: Name: _end
284 ELF: Binding: Global
285 ELF: Type: None
286 ELF: Section: (0xFFF1)
287 ELF: }
288 ELF: Symbol {
289 ELF: Name: global_func
290 ELF: Binding: Global
291 ELF: Type: Function
292 ELF: Section: .text
293 ELF: }
294 ELF: Symbol {
295 ELF: Name: _edata
296 ELF: Binding: Global
297 ELF: Type: None
298 ELF: Section: (0xFFF1)
299 ELF: }
300 ELF: ]
301
302 ELF: DynamicSection [ (9 entries)
303 ELF: Tag Type Name/Value
304 ELF: 00000001 NEEDED SharedLibrary (libc.so.6)
305 ELF: 00000001 NEEDED SharedLibrary (libm.so.6)
306 ELF: 0000000E SONAME LibrarySoname (libfoo.so)
307 ELF: 00000004 HASH {{[0-9a-f]+}}
308 ELF: 00000005 STRTAB {{[0-9a-f]+}}
309 ELF: 00000006 SYMTAB {{[0-9a-f]+}}
310 ELF: 0000000A STRSZ {{[0-9]+}} (bytes)
311 ELF: 0000000B SYMENT {{[0-9]+}} (bytes)
312 ELF: 00000000 NULL 0x0
313 ELF: ]
314
315 ELF: NeededLibraries [
316 ELF-NEXT: libc.so.6
317 ELF-NEXT: libm.so.6
318 ELF-NEXT: ]
0 ; llc -mtriple=i386-pc-win32 trivial.ll -filetype=obj -o trivial-object-test.coff-i386
1 ; llc -mtriple=x86_64-pc-win32 trivial.ll -filetype=obj -o trivial-object-test.coff-x86-64
2 ; llc -mtriple=i386-linux-gnu trivial.ll -filetype=obj -o trivial-object-test.elf-i386 -relocation-model=pic
3 ; llc -mtriple=x86_64-linux-gnu trivial.ll -filetype=obj -o trivial-object-test.elf-x86-64 -relocation-model=pic
4 ; llc -mtriple=i386-apple-darwin10 trivial.ll -filetype=obj -o trivial-object-test.macho-i386 -relocation-model=pic
5 ; llc -mtriple=x86_64-apple-darwin10 trivial.ll -filetype=obj -o trivial-object-test.macho-x86-64 -relocation-model=pic
6
7 @.str = private unnamed_addr constant [13 x i8] c"Hello World\0A\00", align 1
8
9 define i32 @main() nounwind {
10 entry:
11 %call = tail call i32 @puts(i8* getelementptr inbounds ([13 x i8]* @.str, i32 0, i32 0)) nounwind
12 tail call void bitcast (void (...)* @SomeOtherFunction to void ()*)() nounwind
13 ret i32 0
14 }
15
16 declare i32 @puts(i8* nocapture) nounwind
17
18 declare void @SomeOtherFunction(...)
0 RUN: llvm-readobj -h %p/Inputs/trivial.obj.coff-i386 \
1 RUN: | FileCheck %s -check-prefix COFF32
2 RUN: llvm-readobj -h %p/Inputs/trivial.obj.coff-x86-64 \
3 RUN: | FileCheck %s -check-prefix COFF64
4 RUN: llvm-readobj -h %p/Inputs/trivial.obj.elf-i386 \
5 RUN: | FileCheck %s -check-prefix ELF32
6 RUN: llvm-readobj -h %p/Inputs/trivial.obj.elf-x86-64 \
7 RUN: | FileCheck %s -check-prefix ELF64
8
9 COFF32: File: {{(.*[/\\])?}}trivial.obj.coff-i386
10 COFF32-NEXT: Format: COFF-i386
11 COFF32-NEXT: Arch: i386
12 COFF32-NEXT: AddressSize: 32bit
13 COFF32-NEXT: ImageFileHeader {
14 COFF32-NEXT: Machine: IMAGE_FILE_MACHINE_I386 (0x14C)
15 COFF32-NEXT: SectionCount: 2
16 COFF32-NEXT: TimeDateStamp: 2013-03-20 17:56:46 (0x5149F85E)
17 COFF32-NEXT: PointerToSymbolTable: 0xA5
18 COFF32-NEXT: SymbolCount: 7
19 COFF32-NEXT: OptionalHeaderSize: 0
20 COFF32-NEXT: Characteristics [ (0x0)
21 COFF32-NEXT: ]
22 COFF32-NEXT: }
23
24 COFF64: File: {{(.*[/\\])?}}trivial.obj.coff-x86-64
25 COFF64-NEXT: Format: COFF-x86-64
26 COFF64-NEXT: Arch: x86_64
27 COFF64-NEXT: AddressSize: 64bit
28 COFF64-NEXT: ImageFileHeader {
29 COFF64-NEXT: Machine: IMAGE_FILE_MACHINE_AMD64 (0x8664)
30 COFF64-NEXT: SectionCount: 2
31 COFF64-NEXT: TimeDateStamp: 2013-03-20 17:56:46 (0x5149F85E)
32 COFF64-NEXT: PointerToSymbolTable: 0xAB
33 COFF64-NEXT: SymbolCount: 7
34 COFF64-NEXT: OptionalHeaderSize: 0
35 COFF64-NEXT: Characteristics [ (0x0)
36 COFF64-NEXT: ]
37 COFF64-NEXT: }
38
39 ELF32: File: {{(.*[/\\])?}}trivial.obj.elf-i386
40 ELF32-NEXT: Format: ELF32-i386
41 ELF32-NEXT: Arch: i386
42 ELF32-NEXT: AddressSize: 32bit
43 ELF32-NEXT: LoadName:
44 ELF32-NEXT: ElfHeader {
45 ELF32-NEXT: Ident {
46 ELF32-NEXT: Magic: (7F 45 4C 46)
47 ELF32-NEXT: Class: 32-bit (0x1)
48 ELF32-NEXT: DataEncoding: LittleEndian (0x1)
49 ELF32-NEXT: FileVersion: 1
50 ELF32-NEXT: OS/ABI: GNU/Linux (0x3)
51 ELF32-NEXT: ABIVersion: 0
52 ELF32-NEXT: Unused: (00 00 00 00 00 00 00)
53 ELF32-NEXT: }
54 ELF32-NEXT: Type: Relocatable (0x1)
55 ELF32-NEXT: Machine: EM_386 (0x3)
56 ELF32-NEXT: Version: 1
57 ELF32-NEXT: Entry: 0x0
58 ELF32-NEXT: ProgramHeaderOffset: 0x0
59 ELF32-NEXT: SectionHeaderOffset: 0xC8
60 ELF32-NEXT: Flags [ (0x0)
61 ELF32-NEXT: ]
62 ELF32-NEXT: HeaderSize: 52
63 ELF32-NEXT: ProgramHeaderEntrySize: 0
64 ELF32-NEXT: ProgramHeaderCount: 0
65 ELF32-NEXT: SectionHeaderEntrySize: 40
66 ELF32-NEXT: SectionHeaderCount: 10
67 ELF32-NEXT: StringTableSectionIndex: 7
68 ELF32-NEXT: }
69
70 ELF64: File: {{(.*[/\\])?}}trivial.obj.elf-x86-64
71 ELF64-NEXT: Format: ELF64-x86-64
72 ELF64-NEXT: Arch: x86_64
73 ELF64-NEXT: AddressSize: 64bit
74 ELF64-NEXT: LoadName:
75 ELF64-NEXT: ElfHeader {
76 ELF64-NEXT: Ident {
77 ELF64-NEXT: Magic: (7F 45 4C 46)
78 ELF64-NEXT: Class: 64-bit (0x2)
79 ELF64-NEXT: DataEncoding: LittleEndian (0x1)
80 ELF64-NEXT: FileVersion: 1
81 ELF64-NEXT: OS/ABI: GNU/Linux (0x3)
82 ELF64-NEXT: ABIVersion: 0
83 ELF64-NEXT: Unused: (00 00 00 00 00 00 00)
84 ELF64-NEXT: }
85 ELF64-NEXT: Type: Relocatable (0x1)
86 ELF64-NEXT: Machine: EM_X86_64 (0x3E)
87 ELF64-NEXT: Version: 1
88 ELF64-NEXT: Entry: 0x0
89 ELF64-NEXT: ProgramHeaderOffset: 0x0
90 ELF64-NEXT: SectionHeaderOffset: 0xB8
91 ELF64-NEXT: Flags [ (0x0)
92 ELF64-NEXT: ]
93 ELF64-NEXT: HeaderSize: 64
94 ELF64-NEXT: ProgramHeaderEntrySize: 0
95 ELF64-NEXT: ProgramHeaderCount: 0
96 ELF64-NEXT: SectionHeaderEntrySize: 64
97 ELF64-NEXT: SectionHeaderCount: 10
98 ELF64-NEXT: StringTableSectionIndex: 7
99 ELF64-NEXT: }
0 config.suffixes = ['.test']
0 RUN: llvm-readobj -r %p/Inputs/trivial.obj.coff-i386 \
1 RUN: | FileCheck %s -check-prefix COFF
2 RUN: llvm-readobj -r %p/Inputs/trivial.obj.elf-i386 \
3 RUN: | FileCheck %s -check-prefix ELF
4 RUN: llvm-readobj -r %p/Inputs/trivial.obj.macho-i386 \
5 RUN: | FileCheck %s -check-prefix MACHO
6
7 COFF: Relocations [
8 COFF-NEXT: Section (1) .text {
9 COFF-NEXT: 0x4 IMAGE_REL_I386_DIR32 .data
10 COFF-NEXT: 0x9 IMAGE_REL_I386_REL32 _puts
11 COFF-NEXT: 0xE IMAGE_REL_I386_REL32 _SomeOtherFunction
12 COFF-NEXT: }
13 COFF-NEXT: ]
14
15 ELF: Relocations [
16 ELF-NEXT: Section (1) .text {
17 ELF-NEXT: 0xC R_386_GOTPC _GLOBAL_OFFSET_TABLE_ 0x0
18 ELF-NEXT: 0x12 R_386_GOTOFF .L.str 0x0
19 ELF-NEXT: 0x1A R_386_PLT32 puts 0x0
20 ELF-NEXT: 0x1F R_386_PLT32 SomeOtherFunction 0x0
21 ELF-NEXT: }
22 ELF-NEXT: ]
23
24 MACHO: Relocations [
25 MACHO-NEXT: Section __text {
26 MACHO-NEXT: 0x18 GENERIC_RELOC_VANILLA _SomeOtherFunction 0x0
27 MACHO-NEXT: 0x13 GENERIC_RELOC_VANILLA _puts 0x0
28 MACHO-NEXT: 0xB GENERIC_RELOC_LOCAL_SECTDIFF _main 0x{{[0-9A-F]+}}
29 MACHO-NEXT: 0x0 GENERIC_RELOC_PAIR _main 0x{{[0-9A-F]+}}
30 MACHO-NEXT: }
31 MACHO-NEXT: ]
0 RUN: llvm-readobj -s -st -sr -sd %p/Inputs/trivial.obj.coff-i386 \
1 RUN: | FileCheck %s -check-prefix COFF
2 RUN: llvm-readobj -s -st -sr -sd %p/Inputs/trivial.obj.elf-i386 \
3 RUN: | FileCheck %s -check-prefix ELF
4 RUN: llvm-readobj -s -st -sr -sd %p/Inputs/trivial.obj.macho-i386 \
5 RUN: | FileCheck %s -check-prefix MACHO
6
7 COFF: Sections [
8 COFF-NEXT: Section {
9 COFF-NEXT: Number: 1
10 COFF-NEXT: Name: .text (2E 74 65 78 74 00 00 00)
11 COFF-NEXT: VirtualSize: 0x0
12 COFF-NEXT: VirtualAddress: 0x0
13 COFF-NEXT: RawDataSize: 22
14 COFF-NEXT: PointerToRawData: 0x64
15 COFF-NEXT: PointerToRelocations: 0x7A
16 COFF-NEXT: PointerToLineNumbers: 0x0
17 COFF-NEXT: RelocationCount: 3
18 COFF-NEXT: LineNumberCount: 0
19 COFF-NEXT: Characteristics [ (0x60500020)
20 COFF-NEXT: IMAGE_SCN_ALIGN_16BYTES (0x500000)
21 COFF-NEXT: IMAGE_SCN_CNT_CODE (0x20)
22 COFF-NEXT: IMAGE_SCN_MEM_EXECUTE (0x20000000)
23 COFF-NEXT: IMAGE_SCN_MEM_READ (0x40000000)
24 COFF-NEXT: ]
25 COFF-NEXT: Relocations [
26 COFF-NEXT: 0x4 IMAGE_REL_I386_DIR32 .data
27 COFF-NEXT: 0x9 IMAGE_REL_I386_REL32 _puts
28 COFF-NEXT: 0xE IMAGE_REL_I386_REL32 _SomeOtherFunction
29 COFF-NEXT: ]
30 COFF-NEXT: Symbols [
31 COFF-NEXT: Symbol {
32 COFF-NEXT: Name: .text
33 COFF-NEXT: Value: 0
34 COFF-NEXT: Section: .text (1)
35 COFF-NEXT: BaseType: Null (0x0)
36 COFF-NEXT: ComplexType: Null (0x0)
37 COFF-NEXT: StorageClass: Static (0x3)
38 COFF-NEXT: AuxSymbolCount: 1
39 COFF-NEXT: AuxSectionDef {
40 COFF-NEXT: Length: 22
41 COFF-NEXT: RelocationCount: 3
42 COFF-NEXT: LineNumberCount: 0
43 COFF-NEXT: Checksum: 0x0
44 COFF-NEXT: Number: 1
45 COFF-NEXT: Selection: 0x0
46 COFF-NEXT: Unused: (00 00 00)
47 COFF-NEXT: }
48 COFF-NEXT: }
49 COFF-NEXT: Symbol {
50 COFF-NEXT: Name: _main
51 COFF-NEXT: Value: 0
52 COFF-NEXT: Section: .text (1)
53 COFF-NEXT: BaseType: Null (0x0)
54 COFF-NEXT: ComplexType: Function (0x2)
55 COFF-NEXT: StorageClass: External (0x2)
56 COFF-NEXT: AuxSymbolCount: 0
57 COFF-NEXT: }
58 COFF-NEXT: ]
59 COFF-NEXT: SectionData (
60 COFF-NEXT: 0000: 50C70424 00000000 E8000000 00E80000 |P..$............|
61 COFF-NEXT: 0010: 000031C0 5AC3 |..1.Z.|
62 COFF-NEXT: )
63 COFF-NEXT: }
64
65 ELF: Sections [
66 ELF-NEXT: Section {
67 ELF-NEXT: Index: 0
68 ELF-NEXT: Name: (0)
69 ELF-NEXT: Type: SHT_NULL (0x0)
70 ELF-NEXT: Flags [ (0x0)
71 ELF-NEXT: ]
72 ELF-NEXT: Address: 0x0
73 ELF-NEXT: Offset: 0x0
74 ELF-NEXT: Size: 0
75 ELF-NEXT: Link: 0
76 ELF-NEXT: Info: 0
77 ELF-NEXT: AddressAlignment: 0
78 ELF-NEXT: EntrySize: 0
79 ELF-NEXT: Relocations [
80 ELF-NEXT: ]
81 ELF-NEXT: Symbols [
82 ELF-NEXT: ]
83 ELF-NEXT: SectionData (
84 ELF-NEXT: )
85 ELF-NEXT: }
86 ELF-NEXT: Section {
87 ELF-NEXT: Index: 1
88 ELF-NEXT: Name: .text (5)
89 ELF-NEXT: Type: SHT_PROGBITS (0x1)
90 ELF-NEXT: Flags [ (0x6)
91 ELF-NEXT: SHF_ALLOC (0x2)
92 ELF-NEXT: SHF_EXECINSTR (0x4)
93 ELF-NEXT: ]
94 ELF-NEXT: Address: 0x0
95 ELF-NEXT: Offset: 0x40
96 ELF-NEXT: Size: 42
97 ELF-NEXT: Link: 0
98 ELF-NEXT: Info: 0
99 ELF-NEXT: AddressAlignment: 16
100 ELF-NEXT: EntrySize: 0
101 ELF-NEXT: Relocations [
102 ELF-NEXT: 0xC R_386_GOTPC _GLOBAL_OFFSET_TABLE_ 0x0
103 ELF-NEXT: 0x12 R_386_GOTOFF .L.str 0x0
104 ELF-NEXT: 0x1A R_386_PLT32 puts 0x0
105 ELF-NEXT: 0x1F R_386_PLT32 SomeOtherFunction 0x0
106 ELF-NEXT: ]
107 ELF-NEXT: Symbols [
108 ELF-NEXT: Symbol {
109 ELF-NEXT: Name: .text (0)
110 ELF-NEXT: Value: 0x0
111 ELF-NEXT: Size: 0
112 ELF-NEXT: Binding: Local (0x0)
113 ELF-NEXT: Type: Section (0x3)
114 ELF-NEXT: Other: 0
115 ELF-NEXT: Section: .text (0x1)
116 ELF-NEXT: }
117 ELF-NEXT: Symbol {
118 ELF-NEXT: Name: main (12)
119 ELF-NEXT: Value: 0x0
120 ELF-NEXT: Size: 42
121 ELF-NEXT: Binding: Global (0x1)
122 ELF-NEXT: Type: Function (0x2)
123 ELF-NEXT: Other: 0
124 ELF-NEXT: Section: .text (0x1)
125 ELF-NEXT: }
126 ELF-NEXT: ]
127 ELF-NEXT: SectionData (
128 ELF-NEXT: 0000: 5383EC08 E8000000 005B81C3 03000000 |S........[......|
129 ELF-NEXT: 0010: 8D830000 00008904 24E8FCFF FFFFE8FC |........$.......|
130 ELF-NEXT: 0020: FFFFFF31 C083C408 5BC3 |...1....[.|
131 ELF-NEXT: )
132 ELF-NEXT: }
133
134 MACHO: Sections [
135 MACHO-NEXT: Section {
136 MACHO-NEXT: Index: 0
137 MACHO-NEXT: Name: __text (5F 5F 74 65 78 74 00 00 00 00 00 00 00 00 00 00)
138 MACHO-NEXT: Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00)
139 MACHO-NEXT: Address: 0x0
140 MACHO-NEXT: Size: 0x22
141 MACHO-NEXT: Offset: 324
142 MACHO-NEXT: Alignment: 4
143 MACHO-NEXT: RelocationOffset: 0x174
144 MACHO-NEXT: RelocationCount: 4
145 MACHO-NEXT: Type: 0x0
146 MACHO-NEXT: Attributes [ (0x800004)
147 MACHO-NEXT: PureInstructions (0x800000)
148 MACHO-NEXT: SomeInstructions (0x4)
149 MACHO-NEXT: ]
150 MACHO-NEXT: Reserved1: 0x0
151 MACHO-NEXT: Reserved2: 0x0
152 MACHO-NEXT: Relocations [
153 MACHO-NEXT: 0x18 GENERIC_RELOC_VANILLA _SomeOtherFunction 0x0
154 MACHO-NEXT: 0x13 GENERIC_RELOC_VANILLA _puts 0x0
155 MACHO-NEXT: 0xB GENERIC_RELOC_LOCAL_SECTDIFF _main 0x{{[0-9A-F]+}}
156 MACHO-NEXT: 0x0 GENERIC_RELOC_PAIR _main 0x{{[0-9A-F]+}}
157 MACHO-NEXT: ]
158 MACHO-NEXT: Symbols [
159 MACHO-NEXT: Symbol {
160 MACHO-NEXT: Name: _main (1)
161 MACHO-NEXT: Type: 0xF
162 MACHO-NEXT: Section: __text (0x1)
163 MACHO-NEXT: RefType: UndefinedNonLazy (0x0)
164 MACHO-NEXT: Flags [ (0x0)
165 MACHO-NEXT: ]
166 MACHO-NEXT: Value: 0x0
167 MACHO-NEXT: }
168 MACHO-NEXT: ]
169 MACHO-NEXT: SectionData (
170 MACHO-NEXT: 0000: 83EC0CE8 00000000 588D801A 00000089 |........X.......|
171 MACHO-NEXT: 0010: 0424E8E9 FFFFFFE8 E4FFFFFF 31C083C4 |.$..........1...|
172 MACHO-NEXT: 0020: 0CC3 |..|
173 MACHO-NEXT: )
174 MACHO-NEXT: }
0 RUN: llvm-readobj -s %p/Inputs/trivial.obj.coff-i386 \
1 RUN: | FileCheck %s -check-prefix COFF
2 RUN: llvm-readobj -s %p/Inputs/trivial.obj.elf-i386 \
3 RUN: | FileCheck %s -check-prefix ELF
4 RUN: llvm-readobj -s %p/Inputs/trivial.obj.macho-i386 \
5 RUN: | FileCheck %s -check-prefix MACHO
6
7 COFF: Sections [
8 COFF-NEXT: Section {
9 COFF-NEXT: Number: 1
10 COFF-NEXT: Name: .text (2E 74 65 78 74 00 00 00)
11 COFF-NEXT: VirtualSize: 0x0
12 COFF-NEXT: VirtualAddress: 0x0
13 COFF-NEXT: RawDataSize: 22
14 COFF-NEXT: PointerToRawData: 0x64
15 COFF-NEXT: PointerToRelocations: 0x7A
16 COFF-NEXT: PointerToLineNumbers: 0x0
17 COFF-NEXT: RelocationCount: 3
18 COFF-NEXT: LineNumberCount: 0
19 COFF-NEXT: Characteristics [ (0x60500020)
20 COFF-NEXT: IMAGE_SCN_ALIGN_16BYTES (0x500000)
21 COFF-NEXT: IMAGE_SCN_CNT_CODE (0x20)
22 COFF-NEXT: IMAGE_SCN_MEM_EXECUTE (0x20000000)
23 COFF-NEXT: IMAGE_SCN_MEM_READ (0x40000000)
24 COFF-NEXT: ]
25 COFF-NEXT: }
26 COFF-NEXT: Section {
27 COFF-NEXT: Number: 2
28 COFF-NEXT: Name: .data (2E 64 61 74 61 00 00 00)
29 COFF-NEXT: VirtualSize: 0x0
30 COFF-NEXT: VirtualAddress: 0x0
31 COFF-NEXT: RawDataSize: 13
32 COFF-NEXT: PointerToRawData: 0x98
33 COFF-NEXT: PointerToRelocations: 0x0
34 COFF-NEXT: PointerToLineNumbers: 0x0
35 COFF-NEXT: RelocationCount: 0
36 COFF-NEXT: LineNumberCount: 0
37 COFF-NEXT: Characteristics [ (0xC0300040)
38 COFF-NEXT: IMAGE_SCN_ALIGN_4BYTES (0x300000)
39 COFF-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA (0x40)
40 COFF-NEXT: IMAGE_SCN_MEM_READ (0x40000000)
41 COFF-NEXT: IMAGE_SCN_MEM_WRITE (0x80000000)
42 COFF-NEXT: ]
43 COFF-NEXT: }
44 COFF-NEXT: ]
45
46 ELF: Sections [
47 ELF-NEXT: Section {
48 ELF-NEXT: Index: 0
49 ELF-NEXT: Name: (0)
50 ELF-NEXT: Type: SHT_NULL (0x0)
51 ELF-NEXT: Flags [ (0x0)
52 ELF-NEXT: ]
53 ELF-NEXT: Address: 0x0
54 ELF-NEXT: Offset: 0x0
55 ELF-NEXT: Size: 0
56 ELF-NEXT: Link: 0
57 ELF-NEXT: Info: 0
58 ELF-NEXT: AddressAlignment: 0
59 ELF-NEXT: EntrySize: 0
60 ELF-NEXT: }
61 ELF-NEXT: Section {
62 ELF-NEXT: Index: 1
63 ELF-NEXT: Name: .text (5)
64 ELF-NEXT: Type: SHT_PROGBITS (0x1)
65 ELF-NEXT: Flags [ (0x6)
66 ELF-NEXT: SHF_ALLOC (0x2)
67 ELF-NEXT: SHF_EXECINSTR (0x4)
68 ELF-NEXT: ]
69 ELF-NEXT: Address: 0x0
70 ELF-NEXT: Offset: 0x40
71 ELF-NEXT: Size: 42
72 ELF-NEXT: Link: 0
73 ELF-NEXT: Info: 0
74 ELF-NEXT: AddressAlignment: 16
75 ELF-NEXT: EntrySize: 0
76 ELF-NEXT: }
77
78 MACHO: Sections [
79 MACHO-NEXT: Section {
80 MACHO-NEXT: Index: 0
81 MACHO-NEXT: Name: __text (5F 5F 74 65 78 74 00 00 00 00 00 00 00 00 00 00)
82 MACHO-NEXT: Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00)
83 MACHO-NEXT: Address: 0x0
84 MACHO-NEXT: Size: 0x22
85 MACHO-NEXT: Offset: 324
86 MACHO-NEXT: Alignment: 4
87 MACHO-NEXT: RelocationOffset: 0x174
88 MACHO-NEXT: RelocationCount: 4
89 MACHO-NEXT: Type: 0x0
90 MACHO-NEXT: Attributes [ (0x800004)
91 MACHO-NEXT: PureInstructions (0x800000)
92 MACHO-NEXT: SomeInstructions (0x4)
93 MACHO-NEXT: ]
94 MACHO-NEXT: Reserved1: 0x0
95 MACHO-NEXT: Reserved2: 0x0
96 MACHO-NEXT: }
97 MACHO-NEXT: Section {
98 MACHO-NEXT: Index: 1
99 MACHO-NEXT: Name: __cstring (5F 5F 63 73 74 72 69 6E 67 00 00 00 00 00 00 00)
100 MACHO-NEXT: Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00)
101 MACHO-NEXT: Address: 0x22
102 MACHO-NEXT: Size: 0xD
103 MACHO-NEXT: Offset: 358
104 MACHO-NEXT: Alignment: 0
105 MACHO-NEXT: RelocationOffset: 0x0
106 MACHO-NEXT: RelocationCount: 0
107 MACHO-NEXT: Type: ExtReloc (0x2)
108 MACHO-NEXT: Attributes [ (0x0)
109 MACHO-NEXT: ]
110 MACHO-NEXT: Reserved1: 0x0
111 MACHO-NEXT: Reserved2: 0x0
112 MACHO-NEXT: }
0 RUN: llvm-readobj -t %p/Inputs/trivial.obj.coff-i386 \
1 RUN: | FileCheck %s -check-prefix COFF
2 RUN: llvm-readobj -t %p/Inputs/trivial.obj.elf-i386 \
3 RUN: | FileCheck %s -check-prefix ELF
4
5 COFF: Symbols [
6 COFF-NEXT: Symbol {
7 COFF-NEXT: Name: .text
8 COFF-NEXT: Value: 0
9 COFF-NEXT: Section: .text (1)
10 COFF-NEXT: BaseType: Null (0x0)
11 COFF-NEXT: ComplexType: Null (0x0)
12 COFF-NEXT: StorageClass: Static (0x3)
13 COFF-NEXT: AuxSymbolCount: 1
14 COFF-NEXT: AuxSectionDef {
15 COFF-NEXT: Length: 22
16 COFF-NEXT: RelocationCount: 3
17 COFF-NEXT: LineNumberCount: 0
18 COFF-NEXT: Checksum: 0x0
19 COFF-NEXT: Number: 1
20 COFF-NEXT: Selection: 0x0
21 COFF-NEXT: Unused: (00 00 00)
22 COFF-NEXT: }
23 COFF-NEXT: }
24
25 ELF: Symbols [
26 ELF-NEXT: Symbol {
27 ELF-NEXT: Name: trivial.ll (1)
28 ELF-NEXT: Value: 0x0
29 ELF-NEXT: Size: 0
30 ELF-NEXT: Binding: Local (0x0)
31 ELF-NEXT: Type: File (0x4)
32 ELF-NEXT: Other: 0
33 ELF-NEXT: Section: (0xFFF1)
34 ELF-NEXT: }
35 ELF-NEXT: Symbol {
36 ELF-NEXT: Name: .L.str (39)
37 ELF-NEXT: Value: 0x0
38 ELF-NEXT: Size: 13
39 ELF-NEXT: Binding: Local (0x0)
40 ELF-NEXT: Type: Object (0x1)
41 ELF-NEXT: Other: 0
42 ELF-NEXT: Section: .rodata.str1.1 (0x5)
43 ELF-NEXT: }
None set(LLVM_LINK_COMPONENTS archive bitreader object)
0 set(LLVM_LINK_COMPONENTS
1 ${LLVM_TARGETS_TO_BUILD}
2 archive
3 bitreader
4 object)
15
26 add_llvm_tool(llvm-readobj
3 ELF.cpp
47 llvm-readobj.cpp
8 ObjDumper.cpp
9 COFFDumper.cpp
10 ELFDumper.cpp
11 MachODumper.cpp
12 Error.cpp
13 StreamWriter.cpp
514 )
0 //===-- COFFDumper.cpp - COFF-specific dumper -------------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 ///
9 /// \file
10 /// \brief This file implements the COFF-specific dumper for llvm-readobj.
11 ///
12 //===----------------------------------------------------------------------===//
13
14 #include "llvm-readobj.h"
15 #include "ObjDumper.h"
16
17 #include "Error.h"
18 #include "StreamWriter.h"
19
20 #include "llvm/ADT/DenseMap.h"
21 #include "llvm/ADT/SmallString.h"
22 #include "llvm/Object/COFF.h"
23 #include "llvm/Object/ObjectFile.h"
24 #include "llvm/Support/Casting.h"
25 #include "llvm/Support/Compiler.h"
26 #include "llvm/Support/Format.h"
27 #include "llvm/Support/SourceMgr.h"
28 #include "llvm/Support/Win64EH.h"
29 #include "llvm/Support/raw_ostream.h"
30 #include "llvm/Support/system_error.h"
31
32 #include
33 #include
34 #include
35
36 using namespace llvm;
37 using namespace llvm::object;
38 using namespace llvm::Win64EH;
39
40 namespace {
41
42 class COFFDumper : public ObjDumper {
43 public:
44 COFFDumper(const llvm::object::COFFObjectFile *Obj, StreamWriter& Writer)
45 : ObjDumper(Writer)
46 , Obj(Obj) {
47 cacheRelocations();
48 }
49
50 virtual void printFileHeaders() LLVM_OVERRIDE;
51 virtual void printSections() LLVM_OVERRIDE;
52 virtual void printRelocations() LLVM_OVERRIDE;
53 virtual void printSymbols() LLVM_OVERRIDE;
54 virtual void printDynamicSymbols() LLVM_OVERRIDE;
55 virtual void printUnwindInfo() LLVM_OVERRIDE;
56
57 private:
58 void printSymbol(symbol_iterator SymI);
59
60 void printRelocation(section_iterator SecI, relocation_iterator RelI);
61
62 void printX64UnwindInfo();
63
64 void printRuntimeFunction(
65 const RuntimeFunction& RTF,
66 uint64_t OffsetInSection,
67 const std::vector &Rels);
68
69 void printUnwindInfo(
70 const Win64EH::UnwindInfo& UI,
71 uint64_t OffsetInSection,
72 const std::vector &Rels);
73
74 void printUnwindCode(const Win64EH::UnwindInfo& UI, ArrayRef UCs);
75
76 void cacheRelocations();
77
78 error_code getSectionContents(
79 const std::vector &Rels,
80 uint64_t Offset,
81 ArrayRef &Contents,
82 uint64_t &Addr);
83
84 error_code getSection(
85 const std::vector &Rels,
86 uint64_t Offset,
87 const coff_section **Section,
88 uint64_t *AddrPtr);
89
90 typedef DenseMap > RelocMapTy;
91
92 const llvm::object::COFFObjectFile *Obj;
93 RelocMapTy RelocMap;
94 std::vector EmptyRelocs;
95 };
96
97 } // namespace
98
99
100 namespace llvm {
101
102 error_code createCOFFDumper(const object::ObjectFile *Obj,
103 StreamWriter& Writer,
104 OwningPtr &Result) {
105 const COFFObjectFile *COFFObj = dyn_cast(Obj);
106 if (!COFFObj)
107 return readobj_error::unsupported_obj_file_format;
108
109 Result.reset(new COFFDumper(COFFObj, Writer));
110 return readobj_error::success;
111 }
112
113 } // namespace llvm
114
115
116 // Returns the name of the unwind code.
117 static StringRef getUnwindCodeTypeName(uint8_t Code) {
118 switch(Code) {
119 default: llvm_unreachable("Invalid unwind code");
120 case UOP_PushNonVol: return "PUSH_NONVOL";
121 case UOP_AllocLarge: return "ALLOC_LARGE";
122 case UOP_AllocSmall: return "ALLOC_SMALL";
123 case UOP_SetFPReg: return "SET_FPREG";
124 case UOP_SaveNonVol: return "SAVE_NONVOL";
125 case UOP_SaveNonVolBig: return "SAVE_NONVOL_FAR";
126 case UOP_SaveXMM128: return "SAVE_XMM128";
127 case UOP_SaveXMM128Big: return "SAVE_XMM128_FAR";
128 case UOP_PushMachFrame: return "PUSH_MACHFRAME";
129 }
130 }
131
132 // Returns the name of a referenced register.
133 static StringRef getUnwindRegisterName(uint8_t Reg) {
134 switch(Reg) {
135 default: llvm_unreachable("Invalid register");
136 case 0: return "RAX";
137 case 1: return "RCX";
138 case 2: return "RDX";
139 case 3: return "RBX";
140 case 4: return "RSP";
141 case 5: return "RBP";
142 case 6: return "RSI";
143 case 7: return "RDI";
144 case 8: return "R8";
145 case 9: return "R9";
146 case 10: return "R10";
147 case 11: return "R11";
148 case 12: return "R12";
149 case 13: return "R13";
150 case 14: return "R14";
151 case 15: return "R15";
152 }
153 }
154
155 // Calculates the number of array slots required for the unwind code.
156 static unsigned getNumUsedSlots(const UnwindCode &UnwindCode) {
157 switch (UnwindCode.getUnwindOp()) {
158 default: llvm_unreachable("Invalid unwind code");
159 case UOP_PushNonVol:
160 case UOP_AllocSmall:
161 case UOP_SetFPReg:
162 case UOP_PushMachFrame:
163 return 1;
164 case UOP_SaveNonVol:
165 case UOP_SaveXMM128:
166 return 2;
167 case UOP_SaveNonVolBig:
168 case UOP_SaveXMM128Big:
169 return 3;
170 case UOP_AllocLarge:
171 return (UnwindCode.getOpInfo() == 0) ? 2 : 3;
172 }
173 }
174
175 // Given a symbol sym this functions returns the address and section of it.
176 static error_code resolveSectionAndAddress(const COFFObjectFile *Obj,
177 const SymbolRef &Sym,
178 const coff_section *&ResolvedSection,
179 uint64_t &ResolvedAddr) {
180 if (error_code EC = Sym.getAddress(ResolvedAddr))
181 return EC;
182
183 section_iterator iter(Obj->begin_sections());
184 if (error_code EC = Sym.getSection(iter))
185 return EC;
186
187 ResolvedSection = Obj->getCOFFSection(iter);
188 return object_error::success;
189 }
190
191 // Given a vector of relocations for a section and an offset into this section
192 // the function returns the symbol used for the relocation at the offset.
193 static error_code resolveSymbol(const std::vector &Rels,
194 uint64_t Offset, SymbolRef &Sym) {
195 for (std::vector::const_iterator RelI = Rels.begin(),
196 RelE = Rels.end();
197 RelI != RelE; ++RelI) {
198 uint64_t Ofs;
199 if (error_code EC = RelI->getOffset(Ofs))
200 return EC;
201
202 if (Ofs == Offset) {
203 if (error_code EC = RelI->getSymbol(Sym))
204 return EC;
205 return readobj_error::success;
206 }
207 }
208
209 return readobj_error::unknown_symbol;
210 }
211
212 // Given a vector of relocations for a section and an offset into this section
213 // the function returns the name of the symbol used for the relocation at the
214 // offset.
215 static error_code resolveSymbolName(const std::vector &Rels,
216 uint64_t Offset, StringRef &Name) {
217 SymbolRef Sym;
218 if (error_code EC = resolveSymbol(Rels, Offset, Sym)) return EC;
219 if (error_code EC = Sym.getName(Name)) return EC;
220 return object_error::success;
221 }
222
223 static const EnumEntry ImageFileMachineType[] = {
224 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_UNKNOWN ),
225 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_AM33 ),
226 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_AMD64 ),
227 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_ARM ),
228 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_ARMV7 ),
229 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_EBC ),
230 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_I386 ),
231 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_IA64 ),
232 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_M32R ),
233 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_MIPS16 ),
234 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_MIPSFPU ),
235 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_MIPSFPU16),
236 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_POWERPC ),
237 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_POWERPCFP),
238 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_R4000 ),
239 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_SH3 ),
240 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_SH3DSP ),
241 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_SH4 ),
242 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_SH5 ),
243 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_THUMB ),
244 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_WCEMIPSV2)
245 };
246
247 static const EnumEntry ImageFileCharacteristics[] = {
248 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_RELOCS_STRIPPED ),
249 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_EXECUTABLE_IMAGE ),
250 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_LINE_NUMS_STRIPPED ),
251 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_LOCAL_SYMS_STRIPPED ),
252 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_AGGRESSIVE_WS_TRIM ),
253 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_LARGE_ADDRESS_AWARE ),
254 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_BYTES_REVERSED_LO ),
255 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_32BIT_MACHINE ),
256 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_DEBUG_STRIPPED ),
257 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP),
258 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_NET_RUN_FROM_SWAP ),
259 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_SYSTEM ),
260 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_DLL ),
261 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_UP_SYSTEM_ONLY ),
262 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_BYTES_REVERSED_HI )
263 };
264
265 static const EnumEntry
266 ImageSectionCharacteristics[] = {
267 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_TYPE_NO_PAD ),
268 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_CNT_CODE ),
269 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_CNT_INITIALIZED_DATA ),
270 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_CNT_UNINITIALIZED_DATA),
271 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_LNK_OTHER ),
272 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_LNK_INFO ),
273 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_LNK_REMOVE ),
274 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_LNK_COMDAT ),
275 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_GPREL ),
276 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_MEM_PURGEABLE ),
277 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_MEM_16BIT ),
278 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_MEM_LOCKED ),
279 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_MEM_PRELOAD ),
280 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_1BYTES ),
281 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_2BYTES ),
282 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_4BYTES ),
283 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_8BYTES ),
284 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_16BYTES ),
285 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_32BYTES ),
286 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_64BYTES ),
287 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_128BYTES ),
288 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_256BYTES ),
289 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_512BYTES ),
290 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_1024BYTES ),
291 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_2048BYTES ),
292 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_4096BYTES ),
293 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_8192BYTES ),
294 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_LNK_NRELOC_OVFL ),
295 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_MEM_DISCARDABLE ),
296 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_MEM_NOT_CACHED ),
297 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_MEM_NOT_PAGED ),
298 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_MEM_SHARED ),
299 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_MEM_EXECUTE ),
300 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_MEM_READ ),
301 LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_MEM_WRITE )
302 };
303
304 static const EnumEntry ImageSymType[] = {
305 { "Null" , COFF::IMAGE_SYM_TYPE_NULL },
306 { "Void" , COFF::IMAGE_SYM_TYPE_VOID },
307 { "Char" , COFF::IMAGE_SYM_TYPE_CHAR },
308 { "Short" , COFF::IMAGE_SYM_TYPE_SHORT },
309 { "Int" , COFF::IMAGE_SYM_TYPE_INT },
310 { "Long" , COFF::IMAGE_SYM_TYPE_LONG },
311 { "Float" , COFF::IMAGE_SYM_TYPE_FLOAT },
312 { "Double", COFF::IMAGE_SYM_TYPE_DOUBLE },
313 { "Struct", COFF::IMAGE_SYM_TYPE_STRUCT },
314 { "Union" , COFF::IMAGE_SYM_TYPE_UNION },
315 { "Enum" , COFF::IMAGE_SYM_TYPE_ENUM },
316 { "MOE" , COFF::IMAGE_SYM_TYPE_MOE },
317 { "Byte" , COFF::IMAGE_SYM_TYPE_BYTE },
318 { "Word" , COFF::IMAGE_SYM_TYPE_WORD },
319 { "UInt" , COFF::IMAGE_SYM_TYPE_UINT },
320 { "DWord" , COFF::IMAGE_SYM_TYPE_DWORD }
321 };
322
323 static const EnumEntry ImageSymDType[] = {
324 { "Null" , COFF::IMAGE_SYM_DTYPE_NULL },
325 { "Pointer" , COFF::IMAGE_SYM_DTYPE_POINTER },
326 { "Function", COFF::IMAGE_SYM_DTYPE_FUNCTION },
327 { "Array" , COFF::IMAGE_SYM_DTYPE_ARRAY }
328 };
329
330 static const EnumEntry ImageSymClass[] = {
331 { "EndOfFunction" , COFF::IMAGE_SYM_CLASS_END_OF_FUNCTION },
332 { "Null" , COFF::IMAGE_SYM_CLASS_NULL },
333 { "Automatic" , COFF::IMAGE_SYM_CLASS_AUTOMATIC },
334 { "External" , COFF::IMAGE_SYM_CLASS_EXTERNAL },
335 { "Static" , COFF::IMAGE_SYM_CLASS_STATIC },
336 { "Register" , COFF::IMAGE_SYM_CLASS_REGISTER },
337 { "ExternalDef" , COFF::IMAGE_SYM_CLASS_EXTERNAL_DEF },
338 { "Label" , COFF::IMAGE_SYM_CLASS_LABEL },
339 { "UndefinedLabel" , COFF::IMAGE_SYM_CLASS_UNDEFINED_LABEL },
340 { "MemberOfStruct" , COFF::IMAGE_SYM_CLASS_MEMBER_OF_STRUCT },
341 { "Argument" , COFF::IMAGE_SYM_CLASS_ARGUMENT },
342 { "StructTag" , COFF::IMAGE_SYM_CLASS_STRUCT_TAG },
343 { "MemberOfUnion" , COFF::IMAGE_SYM_CLASS_MEMBER_OF_UNION },
344 { "UnionTag" , COFF::IMAGE_SYM_CLASS_UNION_TAG },
345 { "TypeDefinition" , COFF::IMAGE_SYM_CLASS_TYPE_DEFINITION },
346 { "UndefinedStatic", COFF::IMAGE_SYM_CLASS_UNDEFINED_STATIC },
347 { "EnumTag" , COFF::IMAGE_SYM_CLASS_ENUM_TAG },
348 { "MemberOfEnum" , COFF::IMAGE_SYM_CLASS_MEMBER_OF_ENUM },
349 { "RegisterParam" , COFF::IMAGE_SYM_CLASS_REGISTER_PARAM },
350 { "BitField" , COFF::IMAGE_SYM_CLASS_BIT_FIELD },
351 { "Block" , COFF::IMAGE_SYM_CLASS_BLOCK },
352 { "Function" , COFF::IMAGE_SYM_CLASS_FUNCTION },
353 { "EndOfStruct" , COFF::IMAGE_SYM_CLASS_END_OF_STRUCT },
354 { "File" , COFF::IMAGE_SYM_CLASS_FILE },
355 { "Section" , COFF::IMAGE_SYM_CLASS_SECTION },
356 { "WeakExternal" , COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL },
357 { "CLRToken" , COFF::IMAGE_SYM_CLASS_CLR_TOKEN }
358 };
359
360 static const EnumEntry ImageCOMDATSelect[] = {
361 { "NoDuplicates", COFF::IMAGE_COMDAT_SELECT_NODUPLICATES },
362 { "Any" , COFF::IMAGE_COMDAT_SELECT_ANY },
363 { "SameSize" , COFF::IMAGE_COMDAT_SELECT_SAME_SIZE },
364 { "ExactMatch" , COFF::IMAGE_COMDAT_SELECT_EXACT_MATCH },
365 { "Associative" , COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE },
366 { "Largest" , COFF::IMAGE_COMDAT_SELECT_LARGEST },
367 { "Newest" , COFF::IMAGE_COMDAT_SELECT_NEWEST }
368 };
369
370 static const EnumEntry
371 WeakExternalCharacteristics[] = {
372 { "NoLibrary", COFF::IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY },
373 { "Library" , COFF::IMAGE_WEAK_EXTERN_SEARCH_LIBRARY },
374 { "Alias" , COFF::IMAGE_WEAK_EXTERN_SEARCH_ALIAS }
375 };
376
377 static const EnumEntry UnwindFlags[] = {
378 { "ExceptionHandler", Win64EH::UNW_ExceptionHandler },
379 { "TerminateHandler", Win64EH::UNW_TerminateHandler },
380 { "ChainInfo" , Win64EH::UNW_ChainInfo }
381 };
382
383 static const EnumEntry UnwindOpInfo[] = {
384 { "RAX", 0 },
385 { "RCX", 1 },
386 { "RDX", 2 },
387 { "RBX", 3 },
388 { "RSP", 4 },
389 { "RBP", 5 },
390 { "RSI", 6 },
391 { "RDI", 7 },
392 { "R8", 8 },
393 { "R9", 9 },
394 { "R10", 10 },
395 { "R11", 11 },
396 { "R12", 12 },
397 { "R13", 13 },
398 { "R14", 14 },
399 { "R15", 15 }
400 };
401
402 // Some additional COFF structures not defined by llvm::object.
403 namespace {
404 struct coff_aux_function_definition {
405 support::ulittle32_t TagIndex;
406 support::ulittle32_t TotalSize;
407 support::ulittle32_t PointerToLineNumber;
408 support::ulittle32_t PointerToNextFunction;
409 uint8_t Unused[2];
410 };
411
412 struct coff_aux_weak_external_definition {
413 support::ulittle32_t TagIndex;
414 support::ulittle32_t Characteristics;
415 uint8_t Unused[10];
416 };
417
418 struct coff_aux_file_record {
419 char FileName[18];
420 };
421
422 struct coff_aux_clr_token {
423 support::ulittle8_t AuxType;
424 support::ulittle8_t Reserved;
425 support::ulittle32_t SymbolTableIndex;
426 uint8_t Unused[12];
427 };
428 } // namespace
429
430 static uint64_t getOffsetOfLSDA(const Win64EH::UnwindInfo& UI) {
431 return static_cast(UI.getLanguageSpecificData())
432 - reinterpret_cast(&UI);
433 }
434
435 static uint32_t getLargeSlotValue(ArrayRef UCs) {
436 if (UCs.size() < 3)
437 return 0;
438
439 return UCs[1].FrameOffset + (static_cast(UCs[2].FrameOffset) << 16);
440 }
441
442 template
443 static error_code getSymbolAuxData(const COFFObjectFile *Obj,
444 const coff_symbol *Symbol, const T* &Aux) {
445 ArrayRef AuxData = Obj->getSymbolAuxData(Symbol);
446 Aux = reinterpret_cast(AuxData.data());
447 return readobj_error::success;
448 }
449
450 static std::string formatSymbol(const std::vector &Rels,
451 uint64_t Offset, uint32_t Disp) {
452 std::string Buffer;
453 raw_string_ostream Str(Buffer);
454
455 StringRef Sym;
456 if (resolveSymbolName(Rels, Offset, Sym)) {
457 Str << format(" (0x%X)", Offset);
458 return Str.str();
459 }
460
461 Str << Sym;
462 if (Disp > 0) {
463 Str << format(" +0x%X (0x%X)", Disp, Offset);
464 } else {
465 Str << format(" (0x%X)", Offset);
466 }
467
468 return Str.str();
469 }
470
471 // Given a vector of relocations for a section and an offset into this section
472 // the function resolves the symbol used for the relocation at the offset and
473 // returns the section content and the address inside the content pointed to
474 // by the symbol.
475 error_code COFFDumper::getSectionContents(
476 const std::vector &Rels, uint64_t Offset,
477 ArrayRef &Contents, uint64_t &Addr) {
478
479 SymbolRef Sym;
480 const coff_section *Section;
481
482 if (error_code EC = resolveSymbol(Rels, Offset, Sym))
483 return EC;
484 if (error_code EC = resolveSectionAndAddress(Obj, Sym, Section, Addr))
485 return EC;
486 if (error_code EC = Obj->getSectionContents(Section, Contents))
487 return EC;
488
489 return object_error::success;
490 }
491
492 error_code COFFDumper::getSection(
493 const std::vector &Rels, uint64_t Offset,
494 const coff_section **SectionPtr, uint64_t *AddrPtr) {
495
496 SymbolRef Sym;
497 if (error_code EC = resolveSymbol(Rels, Offset, Sym))
498 return EC;
499
500 const coff_section *Section;
501 uint64_t Addr;
502 if (error_code EC = resolveSectionAndAddress(Obj, Sym, Section, Addr))
503 return EC;
504
505 if (SectionPtr)
506 *SectionPtr = Section;
507 if (AddrPtr)
508 *AddrPtr = Addr;
509
510 return object_error::success;
511 }
512
513 void COFFDumper::cacheRelocations() {
514 error_code EC;
515 for (section_iterator SecI = Obj->begin_sections(),
516 SecE = Obj->end_sections();
517 SecI != SecE; SecI.increment(EC)) {
518 if (error(EC))
519 break;
520
521 const coff_section *Section = Obj->getCOFFSection(SecI);
522
523 for (relocation_iterator RelI = SecI->begin_relocations(),
524 RelE = SecI->end_relocations();
525 RelI != RelE; RelI.increment(EC)) {
526 if (error(EC))
527 break;
528
529 RelocMap[Section].push_back(*RelI);
530 }
531
532 // Sort relocations by address.
533 std::sort(RelocMap[Section].begin(), RelocMap[Section].end(),
534 relocAddressLess);
535 }
536 }
537
538 void COFFDumper::printFileHeaders() {
539 const coff_file_header *Header = 0;
540 if (error(Obj->getHeader(Header)))
541 return;
542
543 time_t TDS = Header->TimeDateStamp;
544 char FormattedTime[20] = { };
545 strftime(FormattedTime, 20, "%Y-%m-%d %H:%M:%S", gmtime(&TDS));
546
547 {
548 DictScope D(W, "ImageFileHeader");
549 W.printEnum ("Machine", Header->Machine,
550 makeArrayRef(ImageFileMachineType));
551 W.printNumber("SectionCount", Header->NumberOfSections);
552 W.printHex ("TimeDateStamp", FormattedTime, Header->TimeDateStamp);
553 W.printHex ("PointerToSymbolTable", Header->PointerToSymbolTable);
554 W.printNumber("SymbolCount", Header->NumberOfSymbols);
555 W.printNumber("OptionalHeaderSize", Header->SizeOfOptionalHeader);
556 W.printFlags ("Characteristics", Header->Characteristics,
557 makeArrayRef(ImageFileCharacteristics));
558 }
559 }
560
561 void COFFDumper::printSections() {
562 error_code EC;
563
564 ListScope SectionsD(W, "Sections");
565 int SectionNumber = 0;
566 for (section_iterator SecI = Obj->begin_sections(),
567 SecE = Obj->end_sections();
568 SecI != SecE; SecI.increment(EC)) {
569 if (error(EC))
570 break;
571
572 ++SectionNumber;
573 const coff_section *Section = Obj->getCOFFSection(SecI);
574
575 StringRef Name;
576 if (error(SecI->getName(Name)))
577 Name = "";
578
579 DictScope D(W, "Section");
580 W.printNumber("Number", SectionNumber);
581 W.printBinary("Name", Name, Section->Name);
582 W.printHex ("VirtualSize", Section->VirtualSize);
583 W.printHex ("VirtualAddress", Section->VirtualAddress);
584 W.printNumber("RawDataSize", Section->SizeOfRawData);
585 W.printHex ("PointerToRawData", Section->PointerToRawData);
586 W.printHex ("PointerToRelocations", Section->PointerToRelocations);
587 W.printHex ("PointerToLineNumbers", Section->PointerToLinenumbers);
588 W.printNumber("RelocationCount", Section->NumberOfRelocations);
589 W.printNumber("LineNumberCount", Section->NumberOfLinenumbers);
590 W.printFlags ("Characteristics", Section->Characteristics,
591 makeArrayRef(ImageSectionCharacteristics),
592 COFF::SectionCharacteristics(0x00F00000));
593
594 if (opts::SectionRelocations) {
595 ListScope D(W, "Relocations");
596 for (relocation_iterator RelI = SecI->begin_relocations(),
597 RelE = SecI->end_relocations();
598 RelI != RelE; RelI.increment(EC)) {
599 if (error(EC)) break;
600
601 printRelocation(SecI, RelI);
602 }
603 }
604
605 if (opts::SectionSymbols) {
606 ListScope D(W, "Symbols");
607 for (symbol_iterator SymI = Obj->begin_symbols(),
608 SymE = Obj->end_symbols();
609 SymI != SymE; SymI.increment(EC)) {
610 if (error(EC)) break;
611
612 bool Contained = false;
613 if (SecI->containsSymbol(*SymI, Contained) || !Contained)
614 continue;
615
616 printSymbol(SymI);
617 }
618 }
619
620 if (opts::SectionData) {
621 StringRef Data;
622 if (error(SecI->getContents(Data))) break;
623
624 W.printBinaryBlock("SectionData", Data);
625 }
626 }
627 }
628
629 void COFFDumper::printRelocations() {
630 ListScope D(W, "Relocations");
631
632 error_code EC;
633 int SectionNumber = 0;
634 for (section_iterator SecI = Obj->begin_sections(),
635 SecE = Obj->end_sections();
636 SecI != SecE; SecI.increment(EC)) {
637 ++SectionNumber;
638 if (error(EC))
639 break;
640
641 StringRef Name;
642 if (error(SecI->getName(Name)))
643 continue;
644
645 bool PrintedGroup = false;
646 for (relocation_iterator RelI = SecI->begin_relocations(),
647 RelE = SecI->end_relocations();
648 RelI != RelE; RelI.increment(EC)) {
649 if (error(EC)) break;
650
651 if (!PrintedGroup) {
652 W.startLine() << "Section (" << SectionNumber << ") " << Name << " {\n";
653 W.indent();
654 PrintedGroup = true;
655 }
656
657 printRelocation(SecI, RelI);
658 }
659
660 if (PrintedGroup) {
661 W.unindent();
662 W.startLine() << "}\n";
663 }
664 }
665 }
666
667 void COFFDumper::printRelocation(section_iterator SecI,
668 relocation_iterator RelI) {
669 uint64_t Offset;
670 uint64_t RelocType;
671 SmallString<32> RelocName;
672 SymbolRef Symbol;
673 StringRef SymbolName;
674 StringRef Contents;
675 if (error(RelI->getOffset(Offset))) return;
676 if (error(RelI->getType(RelocType))) return;
677 if (error(RelI->getTypeName(RelocName))) return;
678 if (error(RelI->getSymbol(Symbol))) return;
679 if (error(Symbol.getName(SymbolName))) return;
680 if (error(SecI->getContents(Contents))) return;
681
682 raw_ostream& OS = W.startLine();
683 OS << W.hex(Offset)
684 << " " << RelocName
685 << " " << (SymbolName.size() > 0 ? SymbolName : "-")
686 << "\n";
687 }
688
689 void COFFDumper::printSymbols() {
690 ListScope Group(W, "Symbols");
691
692 error_code EC;
693 for (symbol_iterator SymI = Obj->begin_symbols(),
694 SymE = Obj->end_symbols();
695 SymI != SymE; SymI.increment(EC)) {
696 if (error(EC)) break;
697
698 printSymbol(SymI);
699 }
700 }
701
702 void COFFDumper::printDynamicSymbols() {
703 ListScope Group(W, "DynamicSymbols");
704 }
705
706 void COFFDumper::printSymbol(symbol_iterator SymI) {
707 DictScope D(W, "Symbol");
708
709 const coff_symbol *Symbol = Obj->getCOFFSymbol(SymI);
710 const coff_section *Section;
711 if (error_code EC = Obj->getSection(Symbol->SectionNumber, Section)) {
712 W.startLine() << "Invalid section number: " << EC.message() << "\n";
713 W.flush();
714 return;
715 }
716
717 StringRef SymbolName;
718 if (Obj->getSymbolName(Symbol, SymbolName))
719 SymbolName = "";
720
721 StringRef SectionName;
722 if (Section && Obj->getSectionName(Section, SectionName))
723 SectionName = "";
724
725 W.printString("Name", SymbolName);
726 W.printNumber("Value", Symbol->Value);
727 W.printNumber("Section", SectionName, Symbol->SectionNumber);
728 W.printEnum ("BaseType", Symbol->getBaseType(), makeArrayRef(ImageSymType));
729 W.printEnum ("ComplexType", Symbol->getComplexType(),
730 makeArrayRef(ImageSymDType));
731 W.printEnum ("StorageClass", Symbol->StorageClass,
732 makeArrayRef(ImageSymClass));
733 W.printNumber("AuxSymbolCount", Symbol->NumberOfAuxSymbols);
734
735 for (unsigned I = 0; I < Symbol->NumberOfAuxSymbols; ++I) {
736 if (Symbol->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL &&
737 Symbol->getBaseType() == COFF::IMAGE_SYM_TYPE_NULL &&
738 Symbol->getComplexType() == COFF::IMAGE_SYM_DTYPE_FUNCTION &&
739 Symbol->SectionNumber > 0) {
740 const coff_aux_function_definition *Aux;
741 if (error(getSymbolAuxData(Obj, Symbol + I, Aux)))
742 break;
743
744 DictScope AS(W, "AuxFunctionDef");
745 W.printNumber("TagIndex", Aux->TagIndex);
746 W.printNumber("TotalSize", Aux->TotalSize);
747 W.printHex("PointerToLineNumber", Aux->PointerToLineNumber);
748 W.printHex("PointerToNextFunction", Aux->PointerToNextFunction);
749 W.printBinary("Unused", makeArrayRef(Aux->Unused));
750
751 } else if (
752 Symbol->StorageClass == COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL ||
753 (Symbol->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL &&
754 Symbol->SectionNumber == 0 &&
755 Symbol->Value == 0)) {
756 const coff_aux_weak_external_definition *Aux;
757 if (error(getSymbolAuxData(Obj, Symbol + I, Aux)))
758 break;
759
760 const coff_symbol *Linked;
761 StringRef LinkedName;
762 error_code EC;
763 if ((EC = Obj->getSymbol(Aux->TagIndex, Linked)) ||
764 (EC = Obj->getSymbolName(Linked, LinkedName))) {
765 LinkedName = "";
766 error(EC);
767 }
768
769 DictScope AS(W, "AuxWeakExternal");
770 W.printNumber("Linked", LinkedName, Aux->TagIndex);
771 W.printEnum ("Search", Aux->Characteristics,
772 makeArrayRef(WeakExternalCharacteristics));
773 W.printBinary("Unused", Aux->Unused);
774
775 } else if (Symbol->StorageClass == COFF::IMAGE_SYM_CLASS_FILE) {
776 const coff_aux_file_record *Aux;
777 if (error(getSymbolAuxData(Obj, Symbol + I, Aux)))
778 break;
779
780 } else if (Symbol->StorageClass == COFF::IMAGE_SYM_CLASS_STATIC) {
781 const coff_aux_section_definition *Aux;
782 if (error(getSymbolAuxData(Obj, Symbol + I, Aux)))
783 break;
784
785 DictScope AS(W, "AuxSectionDef");
786 W.printNumber("Length", Aux->Length);
787 W.printNumber("RelocationCount", Aux->NumberOfRelocations);
788 W.printNumber("LineNumberCount", Aux->NumberOfLinenumbers);
789 W.printHex("Checksum", Aux->CheckSum);
790 W.printNumber("Number", Aux->Number);
791 W.printEnum("Selection", Aux->Selection, makeArrayRef(ImageCOMDATSelect));
792 W.printBinary("Unused", makeArrayRef(Aux->Unused));
793
794 if (Section->Characteristics & COFF::IMAGE_SCN_LNK_COMDAT
795 && Aux->Selection == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) {
796 const coff_section *Assoc;
797 StringRef AssocName;
798 error_code EC;
799 if ((EC = Obj->getSection(Aux->Number, Assoc)) ||
800 (EC = Obj->getSectionName(Assoc, AssocName))) {
801 AssocName = "";
802 error(EC);
803 }
804
805 W.printNumber("AssocSection", AssocName, Aux->Number);
806 }
807 } else if (Symbol->StorageClass == COFF::IMAGE_SYM_CLASS_CLR_TOKEN) {
808 const coff_aux_clr_token *Aux;
809 if (error(getSymbolAuxData(Obj, Symbol + I, Aux)))
810 break;
811
812 DictScope AS(W, "AuxCLRToken");
813 W.printNumber("AuxType", Aux->AuxType);
814 W.printNumber("Reserved", Aux->Reserved);
815 W.printNumber("SymbolTableIndex", Aux->SymbolTableIndex);
816 W.printBinary("Unused", Aux->Unused);
817
818 } else {
819 W.startLine() << "\n";
820 }
821 }
822 }
823
824 void COFFDumper::printUnwindInfo() {
825 const coff_file_header *Header;
826 if (error(Obj->getHeader(Header)))
827 return;
828
829 ListScope D(W, "UnwindInformation");
830 if (Header->Machine != COFF::IMAGE_FILE_MACHINE_AMD64) {
831 W.startLine() << "Unsupported image machine type "
832 "(currently only AMD64 is supported).\n";
833 return;
834 }
835
836 printX64UnwindInfo();
837 }
838
839 void COFFDumper::printX64UnwindInfo() {
840 error_code EC;
841 for (section_iterator SecI = Obj->begin_sections(),
842 SecE = Obj->end_sections();
843 SecI != SecE; SecI.increment(EC)) {
844 if (error(EC)) break;
845
846 StringRef Name;
847 if (error(SecI->getName(Name)))
848 continue;
849 if (Name != ".pdata" && !Name.startswith(".pdata$"))
850 continue;
851
852 const coff_section *PData = Obj->getCOFFSection(SecI);
853
854 ArrayRef Contents;
855 if (error(Obj->getSectionContents(PData, Contents)) ||
856 Contents.empty())
857 continue;
858
859 ArrayRef RFs(
860 reinterpret_cast(Contents.data()),
861 Contents.size() / sizeof(RuntimeFunction));
862
863 for (const RuntimeFunction *I = RFs.begin(), *E = RFs.end(); I < E; ++I) {
864 const uint64_t OffsetInSection = std::distance(RFs.begin(), I)
865 * sizeof(RuntimeFunction);
866
867 printRuntimeFunction(*I, OffsetInSection, RelocMap[PData]);
868 }
869 }
870 }
871
872 void COFFDumper::printRuntimeFunction(
873 const RuntimeFunction& RTF,
874 uint64_t OffsetInSection,
875 const std::vector &Rels) {
876
877 DictScope D(W, "RuntimeFunction");
878 W.printString("StartAddress",
879 formatSymbol(Rels, OffsetInSection + 0, RTF.StartAddress));
880 W.printString("EndAddress",
881 formatSymbol(Rels, OffsetInSection + 4, RTF.EndAddress));
882 W.printString("UnwindInfoAddress",
883 formatSymbol(Rels, OffsetInSection + 8, RTF.UnwindInfoOffset));
884
885 const coff_section* XData = 0;
886 uint64_t UnwindInfoOffset = 0;
887 if (error(getSection(Rels, OffsetInSection + 8, &XData, &UnwindInfoOffset)))
888 return;
889
890 ArrayRef XContents;
891 if (error(Obj->getSectionContents(XData, XContents)) || XContents.empty())
892 return;
893
894 UnwindInfoOffset += RTF.UnwindInfoOffset;
895 if (UnwindInfoOffset > XContents.size())
896 return;
897
898 const Win64EH::UnwindInfo *UI =
899 reinterpret_cast(
900 XContents.data() + UnwindInfoOffset);
901
902 printUnwindInfo(*UI, UnwindInfoOffset, RelocMap[XData]);
903 }
904
905 void COFFDumper::printUnwindInfo(
906 const Win64EH::UnwindInfo& UI,
907 uint64_t OffsetInSection,
908 const std::vector &Rels) {
909 DictScope D(W, "UnwindInfo");
910 W.printNumber("Version", UI.getVersion());
911 W.printFlags("Flags", UI.getFlags(), makeArrayRef(UnwindFlags));
912 W.printNumber("PrologSize", UI.PrologSize);
913 if (UI.getFrameRegister() != 0) {
914 W.printEnum("FrameRegister", UI.getFrameRegister(),
915 makeArrayRef(UnwindOpInfo));
916 W.printHex("FrameOffset", UI.getFrameOffset());
917 } else {
918 W.printString("FrameRegister", StringRef("-"));
919 W.printString("FrameOffset", StringRef("-"));
920 }
921
922 W.printNumber("UnwindCodeCount", UI.NumCodes);
923 {
924 ListScope CodesD(W, "UnwindCodes");
925 ArrayRef UCs(&UI.UnwindCodes[0], UI.NumCodes);
926 for (const UnwindCode *I = UCs.begin(), *E = UCs.end(); I < E; ++I) {
927 unsigned UsedSlots = getNumUsedSlots(*I);
928 if (UsedSlots > UCs.size()) {
929 errs() << "Corrupt unwind data";
930 return;
931 }
932 printUnwindCode(UI, ArrayRef(I, E));
933 I += UsedSlots - 1;
934 }
935 }
936
937 uint64_t LSDAOffset = OffsetInSection + getOffsetOfLSDA(UI);
938 if (UI.getFlags() & (UNW_ExceptionHandler | UNW_TerminateHandler)) {
939 W.printString("Handler", formatSymbol(Rels, LSDAOffset,
940 UI.getLanguageSpecificHandlerOffset()));
941 } else if (UI.getFlags() & UNW_ChainInfo) {
942 const RuntimeFunction *Chained = UI.getChainedFunctionEntry();
943 if (Chained) {
944 DictScope D(W, "Chained");
945 W.printString("StartAddress", formatSymbol(Rels, LSDAOffset + 0,
946 Chained->StartAddress));
947 W.printString("EndAddress", formatSymbol(Rels, LSDAOffset + 4,
948 Chained->EndAddress));
949 W.printString("UnwindInfoAddress", formatSymbol(Rels, LSDAOffset + 8,
950 Chained->UnwindInfoOffset));
951 }
952 }
953 }
954
955 // Prints one unwind code. Because an unwind code can occupy up to 3 slots in
956 // the unwind codes array, this function requires that the correct number of
957 // slots is provided.
958 void COFFDumper::printUnwindCode(const Win64EH::UnwindInfo& UI,
959 ArrayRef UCs) {
960 assert(UCs.size() >= getNumUsedSlots(UCs[0]));
961
962 W.startLine() << format("0x%02X: ", unsigned(UCs[0].u.CodeOffset))
963 << getUnwindCodeTypeName(UCs[0].getUnwindOp());
964
965 uint32_t AllocSize = 0;
966
967 switch (UCs[0].getUnwindOp()) {
968 case UOP_PushNonVol:
969 outs() << " reg=" << getUnwindRegisterName(UCs[0].getOpInfo());
970 break;
971
972 case UOP_AllocLarge:
973 if (UCs[0].getOpInfo() == 0) {
974 AllocSize = UCs[1].FrameOffset * 8;
975 } else {
976 AllocSize = getLargeSlotValue(UCs);
977 }
978 outs() << " size=" << AllocSize;
979 break;
980 case UOP_AllocSmall:
981 outs() << " size=" << ((UCs[0].getOpInfo() + 1) * 8);
982 break;
983 case UOP_SetFPReg:
984 if (UI.getFrameRegister() == 0) {
985 outs() << " reg=";
986 } else {
987 outs() << " reg=" << getUnwindRegisterName(UI.getFrameRegister())
988 << format(", offset=0x%X", UI.getFrameOffset() * 16);
989 }
990 break;
991 case UOP_SaveNonVol:
992 outs() << " reg=" << getUnwindRegisterName(UCs[0].getOpInfo())
993 << format(", offset=0x%X", UCs[1].FrameOffset * 8);
994 break;
995 case UOP_SaveNonVolBig:
996 outs() << " reg=" << getUnwindRegisterName(UCs[0].getOpInfo())
997 << format(", offset=0x%X", getLargeSlotValue(UCs));
998 break;
999 case UOP_SaveXMM128:
1000 outs() << " reg=XMM" << static_cast(UCs[0].getOpInfo())
1001 << format(", offset=0x%X", UCs[1].FrameOffset * 16);
1002 break;
1003 case UOP_SaveXMM128Big:
1004 outs() << " reg=XMM" << static_cast(UCs[0].getOpInfo())
1005 << format(", offset=0x%X", getLargeSlotValue(UCs));
1006 break;
1007 case UOP_PushMachFrame:
1008 outs() << " errcode=" << (UCs[0].getOpInfo() == 0 ? "no" : "yes");
1009 break;
1010 }
1011
1012 outs() << "\n";
1013 }
+0
-196
tools/llvm-readobj/ELF.cpp less more
None //===- llvm-readobj/ELF.cpp - ELF Specific Dumper -------------------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "llvm-readobj.h"
10
11 #include "llvm/Object/ELF.h"
12 #include "llvm/Support/Casting.h"
13 #include "llvm/Support/Format.h"
14
15 namespace llvm {
16 using namespace object;
17 using namespace ELF;
18
19 const char *getTypeString(uint64_t Type) {
20 switch (Type) {
21 case DT_BIND_NOW:
22 return "(BIND_NOW)";
23 case DT_DEBUG:
24 return "(DEBUG)";
25 case DT_FINI:
26 return "(FINI)";
27 case DT_FINI_ARRAY:
28 return "(FINI_ARRAY)";
29 case DT_FINI_ARRAYSZ:
30 return "(FINI_ARRAYSZ)";
31 case DT_FLAGS:
32 return "(FLAGS)";
33 case DT_HASH:
34 return "(HASH)";
35 case DT_INIT:
36 return "(INIT)";
37 case DT_INIT_ARRAY:
38 return "(INIT_ARRAY)";
39 case DT_INIT_ARRAYSZ:
40 return "(INIT_ARRAYSZ)";
41 case DT_PREINIT_ARRAY:
42 return "(PREINIT_ARRAY)";
43 case DT_PREINIT_ARRAYSZ:
44 return "(PREINIT_ARRAYSZ)";
45 case DT_JMPREL:
46 return "(JMPREL)";
47 case DT_NEEDED:
48 return "(NEEDED)";
49 case DT_NULL:
50 return "(NULL)";
51 case DT_PLTGOT:
52 return "(PLTGOT)";
53 case DT_PLTREL:
54 return "(PLTREL)";
55 case DT_PLTRELSZ:
56 return "(PLTRELSZ)";
57 case DT_REL:
58 return "(REL)";
59 case DT_RELA:
60 return "(RELA)";
61 case DT_RELENT:
62 return "(RELENT)";
63 case DT_RELSZ:
64 return "(RELSZ)";
65 case DT_RELAENT:
66 return "(RELAENT)";
67 case DT_RELASZ:
68 return "(RELASZ)";
69 case DT_RPATH:
70 return "(RPATH)";
71 case DT_RUNPATH:
72 return "(RUNPATH)";
73 case DT_SONAME:
74 return "(SONAME)";
75 case DT_STRSZ:
76 return "(STRSZ)";
77 case DT_STRTAB:
78 return "(STRTAB)";
79 case DT_SYMBOLIC:
80 return "(SYMBOLIC)";
81 case DT_SYMENT:
82 return "(SYMENT)";
83 case DT_SYMTAB:
84 return "(SYMTAB)";
85 case DT_TEXTREL:
86 return "(TEXTREL)";
87 default:
88 return "unknown";
89 }
90 }
91
92 template
93 void printValue(const ELFObjectFile *O, uint64_t Type, uint64_t Value,
94 bool Is64, raw_ostream &OS) {
95 switch (Type) {
96 case DT_PLTREL:
97 if (Value == DT_REL) {
98 OS << "REL";
99 break;
100 } else if (Value == DT_RELA) {
101 OS << "RELA";
102 break;
103 }
104 // Fallthrough.
105 case DT_PLTGOT:
106 case DT_HASH:
107 case DT_STRTAB:
108 case DT_SYMTAB:
109 case DT_RELA:
110 case DT_INIT:
111 case DT_FINI:
112 case DT_REL:
113 case DT_JMPREL:
114 case DT_INIT_ARRAY:
115 case DT_FINI_ARRAY:
116 case DT_PREINIT_ARRAY:
117 case DT_DEBUG:
118 case DT_NULL:
119 OS << format("0x%" PRIx64, Value);
120 break;
121 case DT_PLTRELSZ:
122 case DT_RELASZ:
123 case DT_RELAENT:
124 case DT_STRSZ:
125 case DT_SYMENT:
126 case DT_RELSZ:
127 case DT_RELENT:
128 case DT_INIT_ARRAYSZ:
129 case DT_FINI_ARRAYSZ:
130 case DT_PREINIT_ARRAYSZ:
131 OS << Value << " (bytes)";
132 break;
133 case DT_NEEDED:
134 OS << "Shared library: ["
135 << O->getString(O->getDynamicStringTableSectionHeader(), Value) << "]";
136 break;
137 case DT_SONAME:
138 OS << "Library soname: ["
139 << O->getString(O->getDynamicStringTableSectionHeader(), Value) << "]";
140 break;
141 }
142 }
143
144 template
145 ErrorOr dumpDynamicTable(const ELFObjectFile *O, raw_ostream &OS) {
146 typedef ELFObjectFile ELFO;
147 typedef typename ELFO::Elf_Dyn_iterator EDI;
148 EDI Start = O->begin_dynamic_table(),
149 End = O->end_dynamic_table(true);
150
151 if (Start == End)
152 return error_code::success();
153
154 ptrdiff_t Total = std::distance(Start, End);
155 OS << "Dynamic section contains " << Total << " entries\n";
156
157 bool Is64 = O->getBytesInAddress() == 8;
158
159 OS << " Tag" << (Is64 ? " " : " ") << "Type"
160 << " " << "Name/Value\n";
161 for (; Start != End; ++Start) {
162 OS << " "
163 << format(Is64 ? "0x%016" PRIx64 : "0x%08" PRIx64, Start->getTag())
164 << " " << format("%-21s", getTypeString(Start->getTag()));
165 printValue(O, Start->getTag(), Start->getVal(), Is64, OS);
166 OS << "\n";
167 }
168
169 OS << " Total: " << Total << "\n\n";
170 return error_code::success();
171 }
172
173 ErrorOr dumpELFDynamicTable(ObjectFile *O, raw_ostream &OS) {
174 // Little-endian 32-bit
175 if (const ELFObjectFile > *ELFObj =
176 dyn_cast > >(O))
177 return dumpDynamicTable(ELFObj, OS);
178
179 // Big-endian 32-bit
180 if (const ELFObjectFile > *ELFObj =
181 dyn_cast > >(O))
182 return dumpDynamicTable(ELFObj, OS);
183
184 // Little-endian 64-bit
185 if (const ELFObjectFile > *ELFObj =
186 dyn_cast > >(O))
187 return dumpDynamicTable(ELFObj, OS);
188
189 // Big-endian 64-bit
190 if (const ELFObjectFile > *ELFObj =
191 dyn_cast > >(O))
192 return dumpDynamicTable(ELFObj, OS);
193 return error_code(object_error::invalid_file_type);
194 }
195 } // end namespace llvm
0 //===-- ELFDumper.cpp - ELF-specific dumper ---------------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 ///
9 /// \file
10 /// \brief This file implements the ELF-specific dumper for llvm-readobj.
11 ///
12 //===----------------------------------------------------------------------===//
13
14 #include "llvm-readobj.h"
15 #include "Error.h"
16 #include "ObjDumper.h"
17 #include "StreamWriter.h"
18
19 #include "llvm/ADT/SmallString.h"
20 #include "llvm/Object/ELF.h"
21 #include "llvm/Support/Compiler.h"
22 #include "llvm/Support/Format.h"
23 #include "llvm/Support/MathExtras.h"
24 #include "llvm/Support/raw_ostream.h"
25
26 using namespace llvm;
27 using namespace llvm::object;
28 using namespace ELF;
29
30
31 #define LLVM_READOBJ_ENUM_CASE(ns, enum) \
32 case ns::enum: return #enum;
33
34 namespace {
35
36 template
37 class ELFDumper : public ObjDumper {
38 public:
39 ELFDumper(const ELFObjectFile *Obj, StreamWriter& Writer)
40 : ObjDumper(Writer)
41 , Obj(Obj) { }
42
43 virtual void printFileHeaders() LLVM_OVERRIDE;
44 virtual void printSections() LLVM_OVERRIDE;
45 virtual void printRelocations() LLVM_OVERRIDE;
46 virtual void printSymbols() LLVM_OVERRIDE;
47 virtual void printDynamicSymbols() LLVM_OVERRIDE;
48 virtual void printUnwindInfo() LLVM_OVERRIDE;
49
50 virtual void printDynamicTable() LLVM_OVERRIDE;
51 virtual void printNeededLibraries() LLVM_OVERRIDE;
52
53 private:
54 typedef typename ELFObjectFile::Elf_Shdr Elf_Shdr;
55 typedef typename ELFObjectFile::Elf_Sym Elf_Sym;
56
57 void printSymbol(symbol_iterator SymI, bool IsDynamic = false);
58
59 void printRelocation(section_iterator SecI, relocation_iterator RelI);
60
61 const ELFObjectFile *Obj;
62 };
63
64 } // namespace
65
66
67 namespace llvm {
68
69 error_code createELFDumper(const object::ObjectFile *Obj,
70 StreamWriter& Writer,
71 OwningPtr &Result) {
72 typedef ELFType Little32ELF;
73 typedef ELFType Big32ELF;
74 typedef ELFType Little64ELF;
75 typedef ELFType Big64ELF;
76
77 typedef ELFObjectFile LittleELF32Obj;
78 typedef ELFObjectFile BigELF32Obj;
79 typedef ELFObjectFile LittleELF64Obj;
80 typedef ELFObjectFile BigELF64Obj;
81
82 // Little-endian 32-bit
83 if (const LittleELF32Obj *ELFObj = dyn_cast(Obj)) {
84 Result.reset(new ELFDumper(ELFObj, Writer));
85 return readobj_error::success;
86 }
87
88 // Big-endian 32-bit
89 if (const BigELF32Obj *ELFObj = dyn_cast(Obj)) {
90 Result.reset(new ELFDumper(ELFObj, Writer));
91 return readobj_error::success;
92 }
93
94 // Little-endian 64-bit
95 if (const LittleELF64Obj *ELFObj = dyn_cast(Obj)) {
96 Result.reset(new ELFDumper(ELFObj, Writer));
97 return readobj_error::success;
98 }
99
100 // Big-endian 64-bit
101 if (const BigELF64Obj *ELFObj = dyn_cast(Obj)) {
102 Result.reset(new ELFDumper(ELFObj, Writer));
103 return readobj_error::success;
104 }
105
106 return readobj_error::unsupported_obj_file_format;
107 }
108
109 } // namespace llvm
110
111
112 static const EnumEntry ElfClass[] = {
113 { "None", ELF::ELFCLASSNONE },
114 { "32-bit", ELF::ELFCLASS32 },
115 { "64-bit", ELF::ELFCLASS64 },
116 };
117
118 static const EnumEntry ElfDataEncoding[] = {
119 { "None", ELF::ELFDATANONE },
120 { "LittleEndian", ELF::ELFDATA2LSB },
121 { "BigEndian", ELF::ELFDATA2MSB },
122 };
123
124 static const EnumEntry ElfObjectFileType[] = {
125 { "None", ELF::ET_NONE },
126 { "Relocatable", ELF::ET_REL },
127 { "Executable", ELF::ET_EXEC },
128 { "SharedObject", ELF::ET_DYN },
129 { "Core", ELF::ET_CORE },
130 };
131
132 static const EnumEntry ElfOSABI[] = {
133 { "SystemV", ELF::ELFOSABI_NONE },
134 { "HPUX", ELF::ELFOSABI_HPUX },
135 { "NetBSD", ELF::ELFOSABI_NETBSD },
136 { "GNU/Linux", ELF::ELFOSABI_LINUX },
137 { "GNU/Hurd", ELF::ELFOSABI_HURD },
138 { "Solaris", ELF::ELFOSABI_SOLARIS },
139 { "AIX", ELF::ELFOSABI_AIX },
140 { "IRIX", ELF::ELFOSABI_IRIX },
141 { "FreeBSD", ELF::ELFOSABI_FREEBSD },
142 { "TRU64", ELF::ELFOSABI_TRU64 },
143 { "Modesto", ELF::ELFOSABI_MODESTO },
144 { "OpenBSD", ELF::ELFOSABI_OPENBSD },
145 { "OpenVMS", ELF::ELFOSABI_OPENVMS },
146 { "NSK", ELF::ELFOSABI_NSK },
147 { "AROS", ELF::ELFOSABI_AROS },
148 { "FenixOS", ELF::ELFOSABI_FENIXOS },
149 { "C6000_ELFABI", ELF::ELFOSABI_C6000_ELFABI },
150 { "C6000_LINUX" , ELF::ELFOSABI_C6000_LINUX },
151 { "ARM", ELF::ELFOSABI_ARM },
152 { "Standalone" , ELF::ELFOSABI_STANDALONE }
153 };
154
155 static const EnumEntry ElfMachineType[] = {
156 LLVM_READOBJ_ENUM_ENT(ELF, EM_NONE ),
157 LLVM_READOBJ_ENUM_ENT(ELF, EM_M32 ),
158 LLVM_READOBJ_ENUM_ENT(ELF, EM_SPARC ),
159 LLVM_READOBJ_ENUM_ENT(ELF, EM_386 ),
160 LLVM_READOBJ_ENUM_ENT(ELF, EM_68K ),
161 LLVM_READOBJ_ENUM_ENT(ELF, EM_88K ),
162 LLVM_READOBJ_ENUM_ENT(ELF, EM_486 ),
163 LLVM_READOBJ_ENUM_ENT(ELF, EM_860 ),
164 LLVM_READOBJ_ENUM_ENT(ELF, EM_MIPS ),
165 LLVM_READOBJ_ENUM_ENT(ELF, EM_S370 ),
166 LLVM_READOBJ_ENUM_ENT(ELF, EM_MIPS_RS3_LE ),
167 LLVM_READOBJ_ENUM_ENT(ELF, EM_PARISC ),
168 LLVM_READOBJ_ENUM_ENT(ELF, EM_VPP500 ),
169 LLVM_READOBJ_ENUM_ENT(ELF, EM_SPARC32PLUS ),
170 LLVM_READOBJ_ENUM_ENT(ELF, EM_960 ),
171 LLVM_READOBJ_ENUM_ENT(ELF, EM_PPC ),
172 LLVM_READOBJ_ENUM_ENT(ELF, EM_PPC64 ),
173 LLVM_READOBJ_ENUM_ENT(ELF, EM_S390 ),
174 LLVM_READOBJ_ENUM_ENT(ELF, EM_SPU ),
175 LLVM_READOBJ_ENUM_ENT(ELF, EM_V800 ),
176 LLVM_READOBJ_ENUM_ENT(ELF, EM_FR20 ),
177 LLVM_READOBJ_ENUM_ENT(ELF, EM_RH32 ),
178 LLVM_READOBJ_ENUM_ENT(ELF, EM_RCE ),
179 LLVM_READOBJ_ENUM_ENT(ELF, EM_ARM ),
180 LLVM_READOBJ_ENUM_ENT(ELF, EM_ALPHA ),
181 LLVM_READOBJ_ENUM_ENT(ELF, EM_SH ),
182 LLVM_READOBJ_ENUM_ENT(ELF, EM_SPARCV9 ),
183 LLVM_READOBJ_ENUM_ENT(ELF, EM_TRICORE ),
184 LLVM_READOBJ_ENUM_ENT(ELF, EM_ARC ),
185 LLVM_READOBJ_ENUM_ENT(ELF, EM_H8_300 ),
186 LLVM_READOBJ_ENUM_ENT(ELF, EM_H8_300H ),
187 LLVM_READOBJ_ENUM_ENT(ELF, EM_H8S ),
188 LLVM_READOBJ_ENUM_ENT(ELF, EM_H8_500 ),
189 LLVM_READOBJ_ENUM_ENT(ELF, EM_IA_64 ),
190 LLVM_READOBJ_ENUM_ENT(ELF, EM_MIPS_X ),
191 LLVM_READOBJ_ENUM_ENT(ELF, EM_COLDFIRE ),
192 LLVM_READOBJ_ENUM_ENT(ELF, EM_68HC12 ),
193 LLVM_READOBJ_ENUM_ENT(ELF, EM_MMA ),
194 LLVM_READOBJ_ENUM_ENT(ELF, EM_PCP ),
195 LLVM_READOBJ_ENUM_ENT(ELF, EM_NCPU ),
196 LLVM_READOBJ_ENUM_ENT(ELF, EM_NDR1 ),
197 LLVM_READOBJ_ENUM_ENT(ELF, EM_STARCORE ),
198 LLVM_READOBJ_ENUM_ENT(ELF, EM_ME16 ),
199 LLVM_READOBJ_ENUM_ENT(ELF, EM_ST100 ),
200 LLVM_READOBJ_ENUM_ENT(ELF, EM_TINYJ ),
201 LLVM_READOBJ_ENUM_ENT(ELF, EM_X86_64 ),
202 LLVM_READOBJ_ENUM_ENT(ELF, EM_PDSP ),
203 LLVM_READOBJ_ENUM_ENT(ELF, EM_PDP10 ),
204 LLVM_READOBJ_ENUM_ENT(ELF, EM_PDP11 ),
205 LLVM_READOBJ_ENUM_ENT(ELF, EM_FX66 ),
206 LLVM_READOBJ_ENUM_ENT(ELF, EM_ST9PLUS ),
207 LLVM_READOBJ_ENUM_ENT(ELF, EM_ST7 ),
208 LLVM_READOBJ_ENUM_ENT(ELF, EM_68HC16 ),
209 LLVM_READOBJ_ENUM_ENT(ELF, EM_68HC11 ),
210 LLVM_READOBJ_ENUM_ENT(ELF, EM_68HC08 ),
211 LLVM_READOBJ_ENUM_ENT(ELF, EM_68HC05 ),
212 LLVM_READOBJ_ENUM_ENT(ELF, EM_SVX ),
213 LLVM_READOBJ_ENUM_ENT(ELF, EM_ST19 ),
214 LLVM_READOBJ_ENUM_ENT(ELF, EM_VAX ),
215 LLVM_READOBJ_ENUM_ENT(ELF, EM_CRIS ),
216 LLVM_READOBJ_ENUM_ENT(ELF, EM_JAVELIN ),
217 LLVM_READOBJ_ENUM_ENT(ELF, EM_FIREPATH ),
218 LLVM_READOBJ_ENUM_ENT(ELF, EM_ZSP ),
219 LLVM_READOBJ_ENUM_ENT(ELF, EM_MMIX ),
220 LLVM_READOBJ_ENUM_ENT(ELF, EM_HUANY ),
221 LLVM_READOBJ_ENUM_ENT(ELF, EM_PRISM ),
222 LLVM_READOBJ_ENUM_ENT(ELF, EM_AVR ),
223 LLVM_READOBJ_ENUM_ENT(ELF, EM_FR30 ),
224 LLVM_READOBJ_ENUM_ENT(ELF, EM_D10V ),
225 LLVM_READOBJ_ENUM_ENT(ELF, EM_D30V ),
226 LLVM_READOBJ_ENUM_ENT(ELF, EM_V850 ),
227 LLVM_READOBJ_ENUM_ENT(ELF, EM_M32R ),
228 LLVM_READOBJ_ENUM_ENT(ELF, EM_MN10300 ),
229 LLVM_READOBJ_ENUM_ENT(ELF, EM_MN10200 ),
230 LLVM_READOBJ_ENUM_ENT(ELF, EM_PJ ),
231 LLVM_READOBJ_ENUM_ENT(ELF, EM_OPENRISC ),
232 LLVM_READOBJ_ENUM_ENT(ELF, EM_ARC_COMPACT ),
233 LLVM_READOBJ_ENUM_ENT(ELF, EM_XTENSA ),
234 LLVM_READOBJ_ENUM_ENT(ELF, EM_VIDEOCORE ),
235 LLVM_READOBJ_ENUM_ENT(ELF, EM_TMM_GPP ),
236 LLVM_READOBJ_ENUM_ENT(ELF, EM_NS32K ),
237 LLVM_READOBJ_ENUM_ENT(ELF, EM_TPC ),
238 LLVM_READOBJ_ENUM_ENT(ELF, EM_SNP1K ),
239 LLVM_READOBJ_ENUM_ENT(ELF, EM_ST200 ),
240 LLVM_READOBJ_ENUM_ENT(ELF, EM_IP2K ),
241 LLVM_READOBJ_ENUM_ENT(ELF, EM_MAX ),
242 LLVM_READOBJ_ENUM_ENT(ELF, EM_CR ),
243 LLVM_READOBJ_ENUM_ENT(ELF, EM_F2MC16 ),
244 LLVM_READOBJ_ENUM_ENT(ELF, EM_MSP430 ),
245 LLVM_READOBJ_ENUM_ENT(ELF, EM_BLACKFIN ),
246 LLVM_READOBJ_ENUM_ENT(ELF, EM_SE_C33 ),
247 LLVM_READOBJ_ENUM_ENT(ELF, EM_SEP ),
248 LLVM_READOBJ_ENUM_ENT(ELF, EM_ARCA ),
249 LLVM_READOBJ_ENUM_ENT(ELF, EM_UNICORE ),
250 LLVM_READOBJ_ENUM_ENT(ELF, EM_EXCESS ),
251 LLVM_READOBJ_ENUM_ENT(ELF, EM_DXP ),
252 LLVM_READOBJ_ENUM_ENT(ELF, EM_ALTERA_NIOS2 ),
253 LLVM_READOBJ_ENUM_ENT(ELF, EM_CRX ),
254 LLVM_READOBJ_ENUM_ENT(ELF, EM_XGATE ),
255 LLVM_READOBJ_ENUM_ENT(ELF, EM_C166 ),
256 LLVM_READOBJ_ENUM_ENT(ELF, EM_M16C ),
257 LLVM_READOBJ_ENUM_ENT(ELF, EM_DSPIC30F ),
258 LLVM_READOBJ_ENUM_ENT(ELF, EM_CE ),
259 LLVM_READOBJ_ENUM_ENT(ELF, EM_M32C ),
260 LLVM_READOBJ_ENUM_ENT(ELF, EM_TSK3000 ),
261 LLVM_READOBJ_ENUM_ENT(ELF, EM_RS08 ),
262 LLVM_READOBJ_ENUM_ENT(ELF, EM_SHARC ),
263 LLVM_READOBJ_ENUM_ENT(ELF, EM_ECOG2 ),
264 LLVM_READOBJ_ENUM_ENT(ELF, EM_SCORE7 ),
265 LLVM_READOBJ_ENUM_ENT(ELF, EM_DSP24 ),
266 LLVM_READOBJ_ENUM_ENT(ELF, EM_VIDEOCORE3 ),
267 LLVM_READOBJ_ENUM_ENT(ELF, EM_LATTICEMICO32),
268 LLVM_READOBJ_ENUM_ENT(ELF, EM_SE_C17 ),
269 LLVM_READOBJ_ENUM_ENT(ELF, EM_TI_C6000 ),
270 LLVM_READOBJ_ENUM_ENT(ELF, EM_TI_C2000 ),
271 LLVM_READOBJ_ENUM_ENT(ELF, EM_TI_C5500 ),
272 LLVM_READOBJ_ENUM_ENT(ELF, EM_MMDSP_PLUS ),
273 LLVM_READOBJ_ENUM_ENT(ELF, EM_CYPRESS_M8C ),
274 LLVM_READOBJ_ENUM_ENT(ELF, EM_R32C ),
275 LLVM_READOBJ_ENUM_ENT(ELF, EM_TRIMEDIA ),
276 LLVM_READOBJ_ENUM_ENT(ELF, EM_HEXAGON ),
277 LLVM_READOBJ_ENUM_ENT(ELF, EM_8051 ),
278 LLVM_READOBJ_ENUM_ENT(ELF, EM_STXP7X ),
279 LLVM_READOBJ_ENUM_ENT(ELF, EM_NDS32 ),
280 LLVM_READOBJ_ENUM_ENT(ELF, EM_ECOG1 ),
281 LLVM_READOBJ_ENUM_ENT(ELF, EM_ECOG1X ),
282 LLVM_READOBJ_ENUM_ENT(ELF, EM_MAXQ30 ),
283 LLVM_READOBJ_ENUM_ENT(ELF, EM_XIMO16 ),
284 LLVM_READOBJ_ENUM_ENT(ELF, EM_MANIK ),
285 LLVM_READOBJ_ENUM_ENT(ELF, EM_CRAYNV2 ),
286 LLVM_READOBJ_ENUM_ENT(ELF, EM_RX ),
287 LLVM_READOBJ_ENUM_ENT(ELF, EM_METAG ),
288 LLVM_READOBJ_ENUM_ENT(ELF, EM_MCST_ELBRUS ),
289 LLVM_READOBJ_ENUM_ENT(ELF, EM_ECOG16 ),
290 LLVM_READOBJ_ENUM_ENT(ELF, EM_CR16 ),
291 LLVM_READOBJ_ENUM_ENT(ELF, EM_ETPU ),
292 LLVM_READOBJ_ENUM_ENT(ELF, EM_SLE9X ),
293 LLVM_READOBJ_ENUM_ENT(ELF, EM_L10M ),
294 LLVM_READOBJ_ENUM_ENT(ELF, EM_K10M ),
295 LLVM_READOBJ_ENUM_ENT(ELF, EM_AARCH64 ),
296 LLVM_READOBJ_ENUM_ENT(ELF, EM_AVR32 ),
297 LLVM_READOBJ_ENUM_ENT(ELF, EM_STM8 ),
298 LLVM_READOBJ_ENUM_ENT(ELF, EM_TILE64 ),
299 LLVM_READOBJ_ENUM_ENT(ELF, EM_TILEPRO ),
300 LLVM_READOBJ_ENUM_ENT(ELF, EM_MICROBLAZE ),
301 LLVM_READOBJ_ENUM_ENT(ELF, EM_CUDA ),
302 LLVM_READOBJ_ENUM_ENT(ELF, EM_TILEGX ),
303 LLVM_READOBJ_ENUM_ENT(ELF, EM_CLOUDSHIELD ),
304 LLVM_READOBJ_ENUM_ENT(ELF, EM_COREA_1ST ),
305 LLVM_READOBJ_ENUM_ENT(ELF, EM_COREA_2ND ),
306 LLVM_READOBJ_ENUM_ENT(ELF, EM_ARC_COMPACT2 ),
307 LLVM_READOBJ_ENUM_ENT(ELF, EM_OPEN8 ),
308 LLVM_READOBJ_ENUM_ENT(ELF, EM_RL78 ),
309 LLVM_READOBJ_ENUM_ENT(ELF, EM_VIDEOCORE5 ),
310 LLVM_READOBJ_ENUM_ENT(ELF, EM_78KOR ),
311 LLVM_READOBJ_ENUM_ENT(ELF, EM_56800EX ),
312 LLVM_READOBJ_ENUM_ENT(ELF, EM_MBLAZE )
313 };
314
315 static const EnumEntry ElfSymbolBindings[] = {
316 { "Local", ELF::STB_LOCAL },
317 { "Global", ELF::STB_GLOBAL },
318 { "Weak", ELF::STB_WEAK }
319 };
320
321 static const EnumEntry ElfSymbolTypes[] = {
322 { "None", ELF::STT_NOTYPE },
323 { "Object", ELF::STT_OBJECT },
324 { "Function", ELF::STT_FUNC },
325 { "Section", ELF::STT_SECTION },
326 { "File", ELF::STT_FILE },
327 { "Common", ELF::STT_COMMON },
328 { "TLS", ELF::STT_TLS },
329 { "GNU_IFunc", ELF::STT_GNU_IFUNC }
330 };
331
332 static const char *getElfSectionType(unsigned Arch, unsigned Type) {
333 switch (Arch) {
334 case Triple::arm:
335 switch (Type) {
336 LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_EXIDX);
337 LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_PREEMPTMAP);
338 LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_ATTRIBUTES);
339 LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_DEBUGOVERLAY);
340 LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_OVERLAYSECTION);
341 }
342 case Triple::hexagon:
343 switch (Type) {
344 LLVM_READOBJ_ENUM_CASE(ELF, SHT_HEX_ORDERED);
345 }
346 case Triple::x86_64:
347 switch (Type) {
348 LLVM_READOBJ_ENUM_CASE(ELF, SHT_X86_64_UNWIND);
349 }
350 case Triple::mips:
351 case Triple::mipsel:
352 switch (Type) {
353 LLVM_READOBJ_ENUM_CASE(ELF, SHT_MIPS_REGINFO);
354 LLVM_READOBJ_ENUM_CASE(ELF, SHT_MIPS_OPTIONS);
355 }
356 }
357
358 switch (Type) {
359 LLVM_READOBJ_ENUM_CASE(ELF, SHT_NULL );
360 LLVM_READOBJ_ENUM_CASE(ELF, SHT_PROGBITS );
361 LLVM_READOBJ_ENUM_CASE(ELF, SHT_SYMTAB );
362 LLVM_READOBJ_ENUM_CASE(ELF, SHT_STRTAB );
363 LLVM_READOBJ_ENUM_CASE(ELF, SHT_RELA );
364 LLVM_READOBJ_ENUM_CASE(ELF, SHT_HASH );
365 LLVM_READOBJ_ENUM_CASE(ELF, SHT_DYNAMIC );
366 LLVM_READOBJ_ENUM_CASE(ELF, SHT_NOTE );
367 LLVM_READOBJ_ENUM_CASE(ELF, SHT_NOBITS );
368 LLVM_READOBJ_ENUM_CASE(ELF, SHT_REL );
369 LLVM_READOBJ_ENUM_CASE(ELF, SHT_SHLIB );
370 LLVM_READOBJ_ENUM_CASE(ELF, SHT_DYNSYM );
371 LLVM_READOBJ_ENUM_CASE(ELF, SHT_INIT_ARRAY );
372 LLVM_READOBJ_ENUM_CASE(ELF, SHT_FINI_ARRAY );
373 LLVM_READOBJ_ENUM_CASE(ELF, SHT_PREINIT_ARRAY );
374 LLVM_READOBJ_ENUM_CASE(ELF, SHT_GROUP );
375 LLVM_READOBJ_ENUM_CASE(ELF, SHT_SYMTAB_SHNDX );
376 LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_ATTRIBUTES );
377 LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_HASH );
378 LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_verdef );
379 LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_verneed );
380 LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_versym );
381 default: return "";
382 }
383 }
384
385 static const EnumEntry ElfSectionFlags[] = {
386 LLVM_READOBJ_ENUM_ENT(ELF, SHF_WRITE ),
387 LLVM_READOBJ_ENUM_ENT(ELF, SHF_ALLOC ),
388 LLVM_READOBJ_ENUM_ENT(ELF, SHF_EXECINSTR ),
389 LLVM_READOBJ_ENUM_ENT(ELF, SHF_MERGE ),
390 LLVM_READOBJ_ENUM_ENT(ELF, SHF_STRINGS ),
391 LLVM_READOBJ_ENUM_ENT(ELF, SHF_INFO_LINK ),
392 LLVM_READOBJ_ENUM_ENT(ELF, SHF_LINK_ORDER ),
393 LLVM_READOBJ_ENUM_ENT(ELF, SHF_OS_NONCONFORMING),
394 LLVM_READOBJ_ENUM_ENT(ELF, SHF_GROUP ),
395 LLVM_READOBJ_ENUM_ENT(ELF, SHF_TLS ),
396 LLVM_READOBJ_ENUM_ENT(ELF, XCORE_SHF_CP_SECTION),
397 LLVM_READOBJ_ENUM_ENT(ELF, XCORE_SHF_DP_SECTION),
398 LLVM_READOBJ_ENUM_ENT(ELF, SHF_MIPS_NOSTRIP )
399 };
400
401
402 template
403 void ELFDumper::printFileHeaders() {
404 error_code EC;
405 typedef ELFObjectFile ELFO;
406
407 const typename ELFO::Elf_Ehdr *Header = Obj->getElfHeader();
408
409 {
410 DictScope D(W, "ElfHeader");
411 {
412 DictScope D(W, "Ident");
413 W.printBinary("Magic", makeArrayRef(Header->e_ident).slice(ELF::EI_MAG0,
414 4));
415 W.printEnum ("Class", Header->e_ident[ELF::EI_CLASS],
416 makeArrayRef(ElfClass));
417 W.printEnum ("DataEncoding", Header->e_ident[ELF::EI_DATA],
418 makeArrayRef(ElfDataEncoding));
419 W.printNumber("FileVersion", Header->e_ident[ELF::EI_VERSION]);
420 W.printEnum ("OS/ABI", Header->e_ident[ELF::EI_OSABI],
421 makeArrayRef(ElfOSABI));
422 W.printNumber("ABIVersion", Header->e_ident[ELF::EI_ABIVERSION]);
423 W.printBinary("Unused", makeArrayRef(Header->e_ident).slice(ELF::EI_PAD));
424 }
425
426 W.printEnum ("Type", Header->e_type, makeArrayRef(ElfObjectFileType));
427 W.printEnum ("Machine", Header->e_machine, makeArrayRef(ElfMachineType));
428 W.printNumber("Version", Header->e_version);
429 W.printHex ("Entry", Header->e_entry);
430 W.printHex ("ProgramHeaderOffset", Header->e_phoff);
431 W.printHex ("SectionHeaderOffset", Header->e_shoff);
432 W.printFlags ("Flags", Header->e_flags);
433 W.printNumber("HeaderSize", Header->e_ehsize);
434 W.printNumber("ProgramHeaderEntrySize", Header->e_phentsize);
435 W.printNumber("ProgramHeaderCount", Header->e_phnum);
436 W.printNumber("SectionHeaderEntrySize", Header->e_shentsize);
437 W.printNumber("SectionHeaderCount", Header->e_shnum);
438 W.printNumber("StringTableSectionIndex", Header->e_shstrndx);
439 }
440 }
441
442 template
443 void ELFDumper::printSections() {
444 ListScope SectionsD(W, "Sections");
445
446 int SectionIndex = -1;
447 error_code EC;
448 for (section_iterator SecI = Obj->begin_sections(),
449 SecE = Obj->end_sections();
450 SecI != SecE; SecI.increment(EC)) {
451 if (error(EC)) break;
452
453 ++SectionIndex;
454
455 const Elf_Shdr *Section = Obj->getElfSection(SecI);
456 StringRef Name;
457 if (error(SecI->getName(Name)))
458 Name = "";
459
460 DictScope SectionD(W, "Section");
461 W.printNumber("Index", SectionIndex);
462 W.printNumber("Name", Name, Section->sh_name);
463 W.printHex ("Type", getElfSectionType(Obj->getArch(), Section->sh_type),
464 Section->sh_type);
465 W.printFlags ("Flags", Section->sh_flags, makeArrayRef(ElfSectionFlags));
466 W.printHex ("Address", Section->sh_addr);
467 W.printHex ("Offset", Section->sh_offset);
468 W.printNumber("Size", Section->sh_size);
469 W.printNumber("Link", Section->sh_link);
470 W.printNumber("Info", Section->sh_info);
471 W.printNumber("AddressAlignment", Section->sh_addralign);
472 W.printNumber("EntrySize", Section->sh_entsize);
473
474 if (opts::SectionRelocations) {
475 ListScope D(W, "Relocations");
476 for (relocation_iterator RelI = SecI->begin_relocations(),
477 RelE = SecI->end_relocations();
478 RelI != RelE; RelI.increment(EC)) {
479 if (error(EC)) break;
480
481 printRelocation(SecI, RelI);
482 }
483 }
484
485 if (opts::SectionSymbols) {
486 ListScope D(W, "Symbols");
487 for (symbol_iterator SymI = Obj->begin_symbols(),
488 SymE = Obj->end_symbols();
489 SymI != SymE; SymI.increment(EC)) {
490 if (error(EC)) break;
491
492 bool Contained = false;
493 if (SecI->containsSymbol(*SymI, Contained) || !Contained)
494 continue;
495
496 printSymbol(SymI);
497 }
498 }
499
500 if (opts::SectionData) {
501 StringRef Data;
502 if (error(SecI->getContents(Data))) break;
503
504 W.printBinaryBlock("SectionData", Data);
505 }
506 }
507 }
508
509 template
510 void ELFDumper::printRelocations() {
511 ListScope D(W, "Relocations");
512
513 error_code EC;
514 int SectionNumber = -1;
515 for (section_iterator SecI = Obj->begin_sections(),
516 SecE = Obj->end_sections();
517 SecI != SecE; SecI.increment(EC)) {
518 if (error(EC)) break;
519
520 ++SectionNumber;
521 StringRef Name;
522 if (error(SecI->getName(Name)))
523 continue;
524
525 bool PrintedGroup = false;
526 for (relocation_iterator RelI = SecI->begin_relocations(),
527 RelE = SecI->end_relocations();
528 RelI != RelE; RelI.increment(EC)) {
529 if (error(EC)) break;
530
531 if (!PrintedGroup) {
532 W.startLine() << "Section (" << SectionNumber << ") " << Name << " {\n";
533 W.indent();
534 PrintedGroup = true;
535 }
536
537 printRelocation(SecI, RelI);
538 }
539
540 if (PrintedGroup) {
541 W.unindent();
542 W.startLine() << "}\n";
543 }
544 }
545 }
546
547 template
548 void ELFDumper::printRelocation(section_iterator Sec,
549 relocation_iterator RelI) {
550 uint64_t Offset;
551 SmallString<32> RelocName;
552 int64_t Info;
553 StringRef SymbolName;
554 SymbolRef Symbol;
555 if (error(RelI->getOffset(Offset))) return;
556 if (error(RelI->getTypeName(RelocName))) return;
557 if (error(RelI->getAdditionalInfo(Info))) return;
558 if (error(RelI->getSymbol(Symbol))) return;
559 if (error(Symbol.getName(SymbolName))) return;
560
561 raw_ostream& OS = W.startLine();
562 OS << W.hex(Offset)
563 << " " << RelocName
564 << " " << (SymbolName.size() > 0 ? SymbolName : "-")
565 << " " << W.hex(Info)
566 << "\n";
567 }
568
569 template
570 void ELFDumper::printSymbols() {
571 ListScope Group(W, "Symbols");
572
573 error_code EC;
574 for (symbol_iterator SymI = Obj->begin_symbols(), SymE = Obj->end_symbols();
575 SymI != SymE; SymI.increment(EC)) {
576 if (error(EC)) break;
577
578 printSymbol(SymI);
579 }
580 }
581
582 template
583 void ELFDumper::printDynamicSymbols() {
584 ListScope Group(W, "DynamicSymbols");
585
586 error_code EC;
587 for (symbol_iterator SymI = Obj->begin_dynamic_symbols(),
588 SymE = Obj->end_dynamic_symbols();
589 SymI != SymE; SymI.increment(EC)) {
590 if (error(EC)) break;
591
592 printSymbol(SymI, true);
593 }
594 }
595
596 template
597 void ELFDumper::printSymbol(symbol_iterator SymI, bool IsDynamic) {
598 error_code EC;
599
600 const Elf_Sym *Symbol = Obj->getElfSymbol(SymI);
601 const Elf_Shdr *Section = Obj->getSection(Symbol);
602
603 StringRef SymbolName;
604 if (SymI->getName(SymbolName))
605 SymbolName = "";
606
607 StringRef SectionName;
608 if (Section && Obj->getSectionName(Section, SectionName))
609 SectionName = "";
610
611 std::string FullSymbolName(SymbolName);
612 if (IsDynamic) {
613 StringRef Version;
614 bool IsDefault;
615 if (error(Obj->getSymbolVersion(*SymI, Version, IsDefault)))
616 return;
617 if (!Version.empty()) {
618 FullSymbolName += (IsDefault ? "@@" : "@");
619 FullSymbolName += Version;
620 }
621 }
622
623 DictScope D(W, "Symbol");
624 W.printNumber("Name", FullSymbolName, Symbol->st_name);
625 W.printHex ("Value", Symbol->st_value);
626 W.printNumber("Size", Symbol->st_size);
627 W.printEnum ("Binding", Symbol->getBinding(),
628 makeArrayRef(ElfSymbolBindings));
629 W.printEnum ("Type", Symbol->getType(), makeArrayRef(ElfSymbolTypes));
630 W.printNumber("Other", Symbol->st_other);
631 W.printHex ("Section", SectionName, Symbol->st_shndx);
632 }
633
634 #define LLVM_READOBJ_TYPE_CASE(name) \
635 case DT_##name: return #name
636
637 static const char *getTypeString(uint64_t Type) {
638 switch (Type) {
639 LLVM_READOBJ_TYPE_CASE(BIND_NOW);
640 LLVM_READOBJ_TYPE_CASE(DEBUG);
641 LLVM_READOBJ_TYPE_CASE(FINI);
642 LLVM_READOBJ_TYPE_CASE(FINI_ARRAY);
643 LLVM_READOBJ_TYPE_CASE(FINI_ARRAYSZ);
644 LLVM_READOBJ_TYPE_CASE(FLAGS);
645 LLVM_READOBJ_TYPE_CASE(HASH);
646 LLVM_READOBJ_TYPE_CASE(INIT);
647 LLVM_READOBJ_TYPE_CASE(INIT_ARRAY);
648 LLVM_READOBJ_TYPE_CASE(INIT_ARRAYSZ);
649 LLVM_READOBJ_TYPE_CASE(PREINIT_ARRAY);
650 LLVM_READOBJ_TYPE_CASE(PREINIT_ARRAYSZ);
651 LLVM_READOBJ_TYPE_CASE(JMPREL);
652 LLVM_READOBJ_TYPE_CASE(NEEDED);
653 LLVM_READOBJ_TYPE_CASE(NULL);
654 LLVM_READOBJ_TYPE_CASE(PLTGOT);
655 LLVM_READOBJ_TYPE_CASE(PLTREL);
656 LLVM_READOBJ_TYPE_CASE(PLTRELSZ);
657 LLVM_READOBJ_TYPE_CASE(REL);
658 LLVM_READOBJ_TYPE_CASE(RELA);
659 LLVM_READOBJ_TYPE_CASE(RELENT);
660 LLVM_READOBJ_TYPE_CASE(RELSZ);
661 LLVM_READOBJ_TYPE_CASE(RELAENT);
662 LLVM_READOBJ_TYPE_CASE(RELASZ);
663 LLVM_READOBJ_TYPE_CASE(RPATH);
664 LLVM_READOBJ_TYPE_CASE(RUNPATH);
665 LLVM_READOBJ_TYPE_CASE(SONAME);
666 LLVM_READOBJ_TYPE_CASE(STRSZ);
667 LLVM_READOBJ_TYPE_CASE(STRTAB);
668 LLVM_READOBJ_TYPE_CASE(SYMBOLIC);
669 LLVM_READOBJ_TYPE_CASE(SYMENT);
670 LLVM_READOBJ_TYPE_CASE(SYMTAB);
671 LLVM_READOBJ_TYPE_CASE(TEXTREL);
672 default: return "unknown";
673 }
674 }
675
676 #undef LLVM_READOBJ_TYPE_CASE
677
678 template
679 static void printValue(const ELFObjectFile *O, uint64_t Type,
680 uint64_t Value, bool Is64, raw_ostream &OS) {
681 switch (Type) {
682 case DT_PLTREL:
683 if (Value == DT_REL) {
684 OS << "REL";
685 break;
686 } else if (Value == DT_RELA) {
687 OS << "RELA";
688 break;
689 }
690 // Fallthrough.
691 case DT_PLTGOT:
692 case DT_HASH:
693 case DT_STRTAB:
694 case DT_SYMTAB:
695 case DT_RELA:
696 case DT_INIT:
697 case DT_FINI:
698 case DT_REL:
699 case DT_JMPREL:
700 case DT_INIT_ARRAY:
701 case DT_FINI_ARRAY:
702 case DT_PREINIT_ARRAY:
703 case DT_DEBUG:
704 case DT_NULL:
705 OS << format("0x%" PRIX64, Value);
706 break;
707 case DT_PLTRELSZ:
708 case DT_RELASZ:
709 case DT_RELAENT:
710 case DT_STRSZ:
711 case DT_SYMENT:
712 case DT_RELSZ:
713 case DT_RELENT:
714 case DT_INIT_ARRAYSZ:
715 case DT_FINI_ARRAYSZ:
716 case DT_PREINIT_ARRAYSZ:
717 OS << Value << " (bytes)";
718 break;
719 case DT_NEEDED:
720 OS << "SharedLibrary ("
721 << O->getString(O->getDynamicStringTableSectionHeader(), Value) << ")";
722 break;
723 case DT_SONAME:
724 OS << "LibrarySoname ("
725 << O->getString(O->getDynamicStringTableSectionHeader(), Value) << ")";
726 break;
727 }
728 }
729
730 template
731 void ELFDumper::printUnwindInfo() {
732 W.startLine() << "UnwindInfo not implemented.\n";
733 }
734
735 template
736 void ELFDumper::printDynamicTable() {
737 typedef ELFObjectFile ELFO;
738 typedef typename ELFO::Elf_Dyn_iterator EDI;
739 EDI Start = Obj->begin_dynamic_table(),
740 End = Obj->end_dynamic_table(true);
741
742 if (Start == End)
743 return;
744
745 ptrdiff_t Total = std::distance(Start, End);
746 raw_ostream &OS = W.getOStream();
747 W.startLine() << "DynamicSection [ (" << Total << " entries)\n";
748
749 bool Is64 = Obj->getBytesInAddress() == 8;
750
751 W.startLine()
752 << " Tag" << (Is64 ? " " : " ") << "Type"
753 << " " << "Name/Value\n";
754 for (; Start != End; ++Start) {
755 W.startLine()
756 << " "
757 << format(Is64 ? "0x%016" PRIX64 : "0x%08" PRIX64, Start->getTag())
758 << " " << format("%-21s", getTypeString(Start->getTag()));
759 printValue(Obj, Start->getTag(), Start->getVal(), Is64, OS);
760 OS << "\n";
761 }
762
763 W.startLine() << "]\n";
764 }
765
766 static bool compareLibraryName(const LibraryRef &L, const LibraryRef &R) {
767 StringRef LPath, RPath;
768 L.getPath(LPath);
769 R.getPath(RPath);
770 return LPath < RPath;
771 }
772
773 template
774 void ELFDumper::printNeededLibraries() {
775 ListScope D(W, "NeededLibraries");
776
777 error_code EC;
778
779 typedef std::vector LibsTy;
780 LibsTy Libs;
781
782 for (library_iterator I = Obj->begin_libraries_needed(),
783 E = Obj->end_libraries_needed();
784 I != E; I.increment(EC)) {
785 if (EC)
786 report_fatal_error("Needed libraries iteration failed");
787
788 Libs.push_back(*I);
789 }
790
791 std::sort(Libs.begin(), Libs.end(), &compareLibraryName);
792
793 for (LibsTy::const_iterator I = Libs.begin(), E = Libs.end();
794 I != E; ++I) {
795 StringRef Path;
796 I->getPath(Path);
797 outs() << " " << Path << "\n";
798 }
799 }
0 //===- Error.cpp - system_error extensions for llvm-readobj -----*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This defines a new error_category for the llvm-readobj tool.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #include "Error.h"
14 #include "llvm/Support/ErrorHandling.h"
15
16 using namespace llvm;
17
18 namespace {
19 class _readobj_error_category : public _do_message {
20 public:
21 virtual const char* name() const;
22 virtual std::string message(int ev) const;
23 virtual error_condition default_error_condition(int ev) const;
24 };
25 } // namespace
26
27 const char *_readobj_error_category::name() const {
28 return "llvm.readobj";
29 }
30
31 std::string _readobj_error_category::message(int ev) const {
32 switch (ev) {
33 case readobj_error::success: return "Success";
34 case readobj_error::file_not_found:
35 return "No such file.";
36 case readobj_error::unsupported_file_format:
37 return "The file was not recognized as a valid object file.";
38 case readobj_error::unrecognized_file_format:
39 return "Unrecognized file type.";
40 case readobj_error::unsupported_obj_file_format:
41 return "Unsupported object file format.";
42 case readobj_error::unknown_symbol:
43 return "Unknown symbol.";
44 default:
45 llvm_unreachable("An enumerator of readobj_error does not have a message "
46 "defined.");
47 }
48 }
49
50 error_condition _readobj_error_category::default_error_condition(int ev) const {
51 if (ev == readobj_error::success)
52 return errc::success;
53 return errc::invalid_argument;
54 }
55
56 namespace llvm {
57 const error_category &readobj_category() {
58 static _readobj_error_category o;
59 return o;
60 }
61 } // namespace llvm
0 //===- Error.h - system_error extensions for llvm-readobj -------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This declares a new error_category for the llvm-readobj tool.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #ifndef LLVM_READOBJ_ERROR_H
14 #define LLVM_READOBJ_ERROR_H
15
16 #include "llvm/Support/system_error.h"
17
18 namespace llvm {
19
20 const error_category &readobj_category();
21
22 struct readobj_error {
23 enum _ {
24 success = 0,
25 file_not_found,
26 unsupported_file_format,
27 unrecognized_file_format,
28 unsupported_obj_file_format,
29 unknown_symbol
30 };
31 _ v_;
32
33 readobj_error(_ v) : v_(v) {}
34 explicit readobj_error(int v) : v_(_(v)) {}
35 operator int() const {return v_;}
36 };
37
38 inline error_code make_error_code(readobj_error e) {
39 return error_code(static_cast(e), readobj_category());
40 }
41
42 template <> struct is_error_code_enum : true_type { };
43 template <> struct is_error_code_enum : true_type { };
44
45 } // namespace llvm
46
47 #endif
1818 type = Tool
1919 name = llvm-readobj
2020 parent = Tools
21 required_libraries = Archive BitReader Object
21 required_libraries = all-targets Archive BitReader Object
0 //===-- MachODump.cpp - Object file dumping utility for llvm --------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements the MachO-specific dumper for llvm-readobj.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #include "llvm-readobj.h"
14 #include "Error.h"
15 #include "ObjDumper.h"
16 #include "StreamWriter.h"
17
18 #include "llvm/ADT/SmallString.h"
19 #include "llvm/Object/MachO.h"
20 #include "llvm/Support/Casting.h"
21
22 using namespace llvm;
23 using namespace object;
24
25 namespace {
26
27 class MachODumper : public ObjDumper {
28 public:
29 MachODumper(const llvm::object::MachOObjectFile *Obj, StreamWriter& Writer)
30 : ObjDumper(Writer)
31 , Obj(Obj) { }
32
33 virtual void printFileHeaders() LLVM_OVERRIDE;
34 virtual void printSections() LLVM_OVERRIDE;
35 virtual void printRelocations() LLVM_OVERRIDE;
36 virtual void printSymbols() LLVM_OVERRIDE;
37 virtual void printDynamicSymbols() LLVM_OVERRIDE;
38 virtual void printUnwindInfo() LLVM_OVERRIDE;
39
40 private:
41 void printSymbol(symbol_iterator SymI);
42
43 void printRelocation(section_iterator SecI, relocation_iterator RelI);
44
45 const llvm::object::MachOObjectFile *Obj;
46 };
47
48 } // namespace
49
50
51 namespace llvm {
52
53 error_code createMachODumper(const object::ObjectFile *Obj,
54 StreamWriter& Writer,
55 OwningPtr &Result) {
56 const MachOObjectFile *MachOObj = dyn_cast(Obj);
57 if (!MachOObj)
58 return readobj_error::unsupported_obj_file_format;
59
60 Result.reset(new MachODumper(MachOObj, Writer));
61 return readobj_error::success;
62 }
63
64 } // namespace llvm
65
66
67 static const EnumEntry MachOSectionTypes[] = {
68 { "Regular" , 0x00 },
69 { "ZeroFill" , 0x01 },
70 { "CStringLiterals" , 0x02 },
71 { "4ByteLiterals" , 0x03 },
72 { "8ByteLiterals" , 0x04 },
73 { "LiteralPointers" , 0x05 },
74 { "NonLazySymbolPointers" , 0x06 },
75 { "LazySymbolPointers" , 0x07 },
76 { "SymbolStubs" , 0x08 },
77 { "ModInitFuncs" , 0x09 },
78 { "ModTermFuncs" , 0x0A },
79 { "Coalesced" , 0x0B },
80 { "GBZeroFill" , 0x0C },
81 { "Interposing" , 0x0D },
82 { "16ByteLiterals" , 0x0E },
83 { "DTraceDOF" , 0x0F },
84 { "LazyDylibSymbolPoints" , 0x10 },
85 { "ThreadLocalRegular" , 0x11 },
86 { "ThreadLocalZerofill" , 0x12 },
87 { "ThreadLocalVariables" , 0x13 },
88 { "ThreadLocalVariablePointers" , 0x14 },
89 { "ThreadLocalInitFunctionPointers", 0x15 }
90 };
91
92 static const EnumEntry MachOSectionAttributes[] = {
93 { "LocReloc" , 1 << 0 /*S_ATTR_LOC_RELOC */ },
94 { "ExtReloc" , 1 << 1 /*S_ATTR_EXT_RELOC */ },
95 { "SomeInstructions" , 1 << 2 /*S_ATTR_SOME_INSTRUCTIONS */ },
96 { "Debug" , 1 << 17 /*S_ATTR_DEBUG */ },
97 { "SelfModifyingCode", 1 << 18 /*S_ATTR_SELF_MODIFYING_CODE*/ },
98 { "LiveSupport" , 1 << 19 /*S_ATTR_LIVE_SUPPORT */ },
99 { "NoDeadStrip" , 1 << 20 /*S_ATTR_NO_DEAD_STRIP */ },
100 { "StripStaticSyms" , 1 << 21 /*S_ATTR_STRIP_STATIC_SYMS */ },
101 { "NoTOC" , 1 << 22 /*S_ATTR_NO_TOC */ },
102 { "PureInstructions" , 1 << 23 /*S_ATTR_PURE_INSTRUCTIONS */ },
103 };
104
105 static const EnumEntry MachOSymbolRefTypes[] = {
106 { "UndefinedNonLazy", 0 },
107 { "ReferenceFlagUndefinedLazy", 1 },
108 { "ReferenceFlagDefined", 2 },
109 { "ReferenceFlagPrivateDefined", 3 },
110 { "ReferenceFlagPrivateUndefinedNonLazy", 4 },
111 { "ReferenceFlagPrivateUndefinedLazy", 5 }
112 };
113
114 static const EnumEntry MachOSymbolFlags[] = {
115 { "ReferencedDynamically", 0x10 },
116 { "NoDeadStrip", 0x20 },
117 { "WeakRef", 0x40 },
118 { "WeakDef", 0x80 }
119 };
120
121 static const EnumEntry MachOSymbolTypes[] = {
122 { "Undef", 0x0 },
123 { "External", 0x1 },
124 { "Abs", 0x2 },
125 { "Indirect", 0xA },
126 { "PreboundUndef", 0xC },
127 { "Section", 0xE },
128 { "PrivateExternal", 0x10 }
129 };
130
131 namespace {
132 enum {
133 N_STAB = 0xE0
134 };
135
136 struct MachOSection {
137 ArrayRef Name;
138 ArrayRef SegmentName;
139 uint64_t Address;
140 uint64_t Size;
141 uint32_t Offset;
142 uint32_t Alignment;
143 uint32_t RelocationTableOffset;
144 uint32_t NumRelocationTableEntries;
145 uint32_t Flags;
146 uint32_t Reserved1;
147 uint32_t Reserved2;
148 };
149
150 struct MachOSymbol {
151 uint32_t StringIndex;
152 uint8_t Type;
153 uint8_t SectionIndex;
154 uint16_t Flags;
155 uint64_t Value;
156 };
157 }
158
159 static StringRef parseSegmentOrSectionName(ArrayRef P) {
160 if (P[15] == 0)
161 // Null terminated.
162 return StringRef(P.data());
163 // Not null terminated, so this is a 16 char string.
164 return StringRef(P.data(), 16);
165 }
166
167 static bool is64BitLoadCommand(const MachOObject *MachOObj, DataRefImpl DRI) {
168 LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a);
169 if (LCI.Command.Type == macho::LCT_Segment64)
170 return true;
171 assert(LCI.Command.Type == macho::LCT_Segment && "Unexpected Type.");
172 return false;
173 }
174
175 static void getSection(const MachOObject *MachOObj,
176 DataRefImpl DRI,
177 MachOSection &Section) {
178 LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a);
179 if (is64BitLoadCommand(MachOObj, DRI)) {
180 InMemoryStruct Sect;
181 MachOObj->ReadSection64(LCI, DRI.d.b, Sect);
182
183 Section.Name = ArrayRef(Sect->Name);
184 Section.SegmentName = ArrayRef(Sect->SegmentName);
185 Section.Address = Sect->Address;
186 Section.Size = Sect->Size;
187 Section.Offset = Sect->Offset;
188 Section.Alignment = Sect->Align;
189 Section.RelocationTableOffset = Sect->RelocationTableOffset;
190 Section.NumRelocationTableEntries = Sect->NumRelocationTableEntries;
191 Section.Flags = Sect->Flags;
192 Section.Reserved1 = Sect->Reserved1;
193 Section.Reserved2 = Sect->Reserved2;
194 } else {
195 InMemoryStruct Sect;
196 MachOObj->ReadSection(LCI, DRI.d.b, Sect);
197
198 Section.Name = Sect->Name;
199 Section.SegmentName = Sect->SegmentName;
200 Section.Address = Sect->Address;
201 Section.Size = Sect->Size;
202 Section.Offset = Sect->Offset;
203 Section.Alignment = Sect->Align;
204 Section.RelocationTableOffset = Sect->RelocationTableOffset;
205 Section.NumRelocationTableEntries = Sect->NumRelocationTableEntries;
206 Section.Flags = Sect->Flags;
207 Section.Reserved1 = Sect->Reserved1;
208 Section.Reserved2 = Sect->Reserved2;
209 }
210 }
211
212 static void getSymbolTableEntry(const MachOObject *MachO,
213 DataRefImpl DRI,
214 InMemoryStruct &Res) {
215 InMemoryStruct SymtabLoadCmd;
216 LoadCommandInfo LCI = MachO->getLoadCommandInfo(DRI.d.a);
217 MachO->ReadSymtabLoadCommand(LCI, SymtabLoadCmd);
218 MachO->ReadSymbolTableEntry(SymtabLoadCmd->SymbolTableOffset, DRI.d.b, Res);
219 }
220
221 static void getSymbol64TableEntry(const MachOObject *MachO,
222 DataRefImpl DRI,
223 InMemoryStruct &Res) {
224 InMemoryStruct SymtabLoadCmd;
225 LoadCommandInfo LCI = MachO->getLoadCommandInfo(DRI.d.a);
226 MachO->ReadSymtabLoadCommand(LCI, SymtabLoadCmd);
227 MachO->ReadSymbol64TableEntry(SymtabLoadCmd->SymbolTableOffset, DRI.d.b, Res);
228 }
229
230 static void getSymbol(const MachOObject *MachOObj,
231 DataRefImpl DRI,
232 MachOSymbol &Symbol) {
233 if (MachOObj->is64Bit()) {
234 InMemoryStruct Entry;
235 getSymbol64TableEntry(MachOObj, DRI, Entry);
236 Symbol.StringIndex = Entry->StringIndex;
237 Symbol.Type = Entry->Type;
238 Symbol.SectionIndex = Entry->SectionIndex;
239 Symbol.Flags = Entry->Flags;
240 Symbol.Value = Entry->Value;
241 } else {
242 InMemoryStruct Entry;
243 getSymbolTableEntry(MachOObj, DRI, Entry);
244 Symbol.StringIndex = Entry->StringIndex;
245 Symbol.Type = Entry->Type;
246 Symbol.SectionIndex = Entry->SectionIndex;
247 Symbol.Flags = Entry->Flags;
248 Symbol.Value = Entry->Value;
249 }
250 }
251
252 void MachODumper::printFileHeaders() {
253 W.startLine() << "FileHeaders not implemented.\n";
254 }
255
256 void MachODumper::printSections() {
257 ListScope Group(W, "Sections");
258
259 int SectionIndex = -1;
260 error_code EC;
261 for (section_iterator SecI = Obj->begin_sections(),
262 SecE = Obj->end_sections();
263 SecI != SecE; SecI.increment(EC)) {
264 if (error(EC)) break;
265
266 ++SectionIndex;
267
268 const MachOObject *MachO = const_cast(Obj)->getObject();
269
270 MachOSection Section;
271 getSection(MachO, SecI->getRawDataRefImpl(), Section);
272 StringRef Name;
273 if (error(SecI->getName(Name)))
274 Name = "";
275
276 DictScope SectionD(W, "Section");
277 W.printNumber("Index", SectionIndex);
278 W.printBinary("Name", Name, Section.Name);
279 W.printBinary("Segment", parseSegmentOrSectionName(Section.SegmentName),
280 Section.SegmentName);
281 W.printHex ("Address", Section.Address);
282 W.printHex ("Size", Section.Size);
283 W.printNumber("Offset", Section.Offset);
284 W.printNumber("Alignment", Section.Alignment);
285 W.printHex ("RelocationOffset", Section.RelocationTableOffset);
286 W.printNumber("RelocationCount", Section.NumRelocationTableEntries);
287 W.printEnum ("Type", Section.Flags & 0xFF,
288 makeArrayRef(MachOSectionAttributes));
289 W.printFlags ("Attributes", Section.Flags >> 8,
290 makeArrayRef(MachOSectionAttributes));
291 W.printHex ("Reserved1", Section.Reserved1);
292 W.printHex ("Reserved2", Section.Reserved2);
293
294 if (opts::SectionRelocations) {
295 ListScope D(W, "Relocations");