llvm.org GIT mirror llvm / 5c2b4ea
[Object] * Add begin_dynamic_table() / end_dynamic_table() private interface to ELFObjectFile. * Add begin_libraries_needed() / end_libraries_needed() interface to ObjectFile, for grabbing the list of needed libraries for a shared object or dynamic executable. * Implement this new interface completely for ELF, leave stubs for COFF and MachO. * Add 'llvm-readobj' tool for dumping ObjectFile information. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@151785 91177308-0d34-0410-b5e6-96231b3b80d8 David Meyer 8 years ago
16 changed file(s) with 654 addition(s) and 4 deletion(s). Raw diff Collapse all Expand all
144144 virtual error_code getRelocationValueString(DataRefImpl Rel,
145145 SmallVectorImpl &Result) const;
146146
147 virtual error_code getLibraryNext(DataRefImpl LibData,
148 LibraryRef &Result) const;
149 virtual error_code getLibraryPath(DataRefImpl LibData,
150 StringRef &Result) const;
151
147152 public:
148153 COFFObjectFile(MemoryBuffer *Object, error_code &ec);
149154 virtual symbol_iterator begin_symbols() const;
150155 virtual symbol_iterator end_symbols() const;
151156 virtual symbol_iterator begin_dynamic_symbols() const;
152157 virtual symbol_iterator end_dynamic_symbols() const;
158 virtual library_iterator begin_libraries_needed() const;
159 virtual library_iterator end_libraries_needed() const;
153160 virtual section_iterator begin_sections() const;
154161 virtual section_iterator end_sections() const;
155162
175175 }
176176 };
177177
178 // Elf_Dyn: Entry in the dynamic table
179 template
180 struct Elf_Dyn_Base;
181
182 template
183 struct Elf_Dyn_Base {
184 LLVM_ELF_IMPORT_TYPES(target_endianness, false)
185 Elf_Sword d_tag;
186 union {
187 Elf_Word d_val;
188 Elf_Addr d_ptr;
189 } d_un;
190 };
191
192 template
193 struct Elf_Dyn_Base {
194 LLVM_ELF_IMPORT_TYPES(target_endianness, true)
195 Elf_Sxword d_tag;
196 union {
197 Elf_Xword d_val;
198 Elf_Addr d_ptr;
199 } d_un;
200 };
201
202 template
203 struct Elf_Dyn_Impl : Elf_Dyn_Base {
204 using Elf_Dyn_Base::d_tag;
205 using Elf_Dyn_Base::d_un;
206 int64_t getTag() const { return d_tag; }
207 uint64_t getVal() const { return d_un.d_val; }
208 uint64_t getPtr() const { return d_un.ptr; }
209 };
210
211 template
212 class ELFObjectFile;
213
214 // DynRefImpl: Reference to an entry in the dynamic table
215 // This is an ELF-specific interface.
216 template
217 class DynRefImpl {
218 typedef Elf_Dyn_Impl Elf_Dyn;
219 typedef ELFObjectFile OwningType;
220
221 DataRefImpl DynPimpl;
222 const OwningType *OwningObject;
223
224 public:
225 DynRefImpl() : OwningObject(NULL) {
226 std::memset(&DynPimpl, 0, sizeof(DynPimpl));
227 }
228
229 DynRefImpl(DataRefImpl DynP, const OwningType *Owner);
230
231 bool operator==(const DynRefImpl &Other) const;
232 bool operator <(const DynRefImpl &Other) const;
233
234 error_code getNext(DynRefImpl &Result) const;
235 int64_t getTag() const;
236 uint64_t getVal() const;
237 uint64_t getPtr() const;
238
239 DataRefImpl getRawDataRefImpl() const;
240 };
241
242 // Elf_Rel: Elf Relocation
178243 template
179244 struct Elf_Rel_Base;
180245
254319
255320 typedef Elf_Shdr_Impl Elf_Shdr;
256321 typedef Elf_Sym_Impl Elf_Sym;
322 typedef Elf_Dyn_Impl Elf_Dyn;
257323 typedef Elf_Rel_Impl Elf_Rel;
258324 typedef Elf_Rel_Impl Elf_Rela;
325 typedef DynRefImpl DynRef;
326 typedef content_iterator dyn_iterator;
259327
260328 protected:
261329 struct Elf_Ehdr {
299367 IndexMap_t SymbolTableSectionsIndexMap;
300368 DenseMap ExtendedSymbolTable;
301369
370 const Elf_Shdr *dot_dynamic_sec; // .dynamic
371
302372 /// @brief Map sections to an array of relocation sections that reference
303373 /// them sorted by section index.
304374 RelocMap_t SectionRelocMap;
328398 const Elf_Sym *getSymbol(DataRefImpl Symb) const; // FIXME: Should be private?
329399 void validateSymbol(DataRefImpl Symb) const;
330400
401 public:
402 const Elf_Dyn *getDyn(DataRefImpl DynData) const;
403
331404 protected:
332405 virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const;
333406 virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const;
339412 virtual error_code getSymbolType(DataRefImpl Symb, SymbolRef::Type &Res) const;
340413 virtual error_code getSymbolSection(DataRefImpl Symb,
341414 section_iterator &Res) const;
415
416 friend class DynRefImpl;
417 virtual error_code getDynNext(DataRefImpl DynData, DynRef &Result) const;
418
419 virtual error_code getLibraryNext(DataRefImpl Data, LibraryRef &Result) const;
420 virtual error_code getLibraryPath(DataRefImpl Data, StringRef &Res) const;
342421
343422 virtual error_code getSectionNext(DataRefImpl Sec, SectionRef &Res) const;
344423 virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const;
375454 ELFObjectFile(MemoryBuffer *Object, error_code &ec);
376455 virtual symbol_iterator begin_symbols() const;
377456 virtual symbol_iterator end_symbols() const;
457
378458 virtual symbol_iterator begin_dynamic_symbols() const;
379459 virtual symbol_iterator end_dynamic_symbols() const;
460
380461 virtual section_iterator begin_sections() const;
381462 virtual section_iterator end_sections() const;
463
464 virtual library_iterator begin_libraries_needed() const;
465 virtual library_iterator end_libraries_needed() const;
466
467 virtual dyn_iterator begin_dynamic_table() const;
468 virtual dyn_iterator end_dynamic_table() const;
382469
383470 virtual uint8_t getBytesInAddress() const;
384471 virtual StringRef getFileFormatName() const;
11701257 , SectionHeaderTable(0)
11711258 , dot_shstrtab_sec(0)
11721259 , dot_strtab_sec(0)
1173 , dot_dynstr_sec(0) {
1260 , dot_dynstr_sec(0)
1261 , dot_dynamic_sec(0) {
11741262
11751263 const uint64_t FileSize = Data->getBufferSize();
11761264
12251313 }
12261314 if (sh->sh_type == ELF::SHT_REL || sh->sh_type == ELF::SHT_RELA) {
12271315 SectionRelocMap[getSection(sh->sh_info)].push_back(i);
1316 }
1317 if (sh->sh_type == ELF::SHT_DYNAMIC) {
1318 if (dot_dynamic_sec != NULL)
1319 // FIXME: Proper error handling.
1320 report_fatal_error("More than one .dynamic!");
1321 dot_dynamic_sec = sh;
12281322 }
12291323 ++sh;
12301324 }
13521446 }
13531447
13541448 template
1449 typename ELFObjectFile::dyn_iterator
1450 ELFObjectFile::begin_dynamic_table() const {
1451 DataRefImpl DynData;
1452 memset(&DynData, 0, sizeof(DynData));
1453 if (dot_dynamic_sec == NULL || dot_dynamic_sec->sh_size == 0) {
1454 DynData.d.a = std::numeric_limits::max();
1455 } else {
1456 DynData.d.a = 0;
1457 }
1458 return dyn_iterator(DynRef(DynData, this));
1459 }
1460
1461 template
1462 typename ELFObjectFile::dyn_iterator
1463 ELFObjectFile
1464 ::end_dynamic_table() const {
1465 DataRefImpl DynData;
1466 memset(&DynData, 0, sizeof(DynData));
1467 DynData.d.a = std::numeric_limits::max();
1468 return dyn_iterator(DynRef(DynData, this));
1469 }
1470
1471 template
1472 error_code ELFObjectFile
1473 ::getDynNext(DataRefImpl DynData,
1474 DynRef &Result) const {
1475 ++DynData.d.a;
1476
1477 // Check to see if we are at the end of .dynamic
1478 if (DynData.d.a >= dot_dynamic_sec->getEntityCount()) {
1479 // We are at the end. Return the terminator.
1480 DynData.d.a = std::numeric_limits::max();
1481 }
1482
1483 Result = DynRef(DynData, this);
1484 return object_error::success;
1485 }
1486
1487 template
1488 library_iterator ELFObjectFile
1489 ::begin_libraries_needed() const {
1490 // Find the first DT_NEEDED entry
1491 dyn_iterator i = begin_dynamic_table();
1492 dyn_iterator e = end_dynamic_table();
1493 error_code ec;
1494 while (i != e) {
1495 if (i->getTag() == ELF::DT_NEEDED)
1496 break;
1497 i.increment(ec);
1498 if (ec)
1499 report_fatal_error("dynamic table iteration failed");
1500 }
1501 // Use the same DataRefImpl format as DynRef.
1502 return library_iterator(LibraryRef(i->getRawDataRefImpl(), this));
1503 }
1504
1505 template
1506 error_code ELFObjectFile
1507 ::getLibraryNext(DataRefImpl Data,
1508 LibraryRef &Result) const {
1509 // Use the same DataRefImpl format as DynRef.
1510 dyn_iterator i = dyn_iterator(DynRef(Data, this));
1511 dyn_iterator e = end_dynamic_table();
1512
1513 // Skip the current dynamic table entry.
1514 error_code ec;
1515 if (i != e) {
1516 i.increment(ec);
1517 // TODO: proper error handling
1518 if (ec)
1519 report_fatal_error("dynamic table iteration failed");
1520 }
1521
1522 // Find the next DT_NEEDED entry.
1523 while (i != e) {
1524 if (i->getTag() == ELF::DT_NEEDED)
1525 break;
1526 i.increment(ec);
1527 if (ec)
1528 report_fatal_error("dynamic table iteration failed");
1529 }
1530 Result = LibraryRef(i->getRawDataRefImpl(), this);
1531 return object_error::success;
1532 }
1533
1534 template
1535 error_code ELFObjectFile
1536 ::getLibraryPath(DataRefImpl Data, StringRef &Res) const {
1537 dyn_iterator i = dyn_iterator(DynRef(Data, this));
1538 if (i == end_dynamic_table())
1539 report_fatal_error("getLibraryPath() called on iterator end");
1540
1541 if (i->getTag() != ELF::DT_NEEDED)
1542 report_fatal_error("Invalid library_iterator");
1543
1544 // This uses .dynstr to lookup the name of the DT_NEEDED entry.
1545 // THis works as long as DT_STRTAB == .dynstr. This is true most of
1546 // the time, but the specification allows exceptions.
1547 // TODO: This should really use DT_STRTAB instead. Doing this requires
1548 // reading the program headers.
1549 if (dot_dynstr_sec == NULL)
1550 report_fatal_error("Dynamic string table is missing");
1551 Res = getString(dot_dynstr_sec, i->getVal());
1552 return object_error::success;
1553 }
1554
1555 template
1556 library_iterator ELFObjectFile
1557 ::end_libraries_needed() const {
1558 dyn_iterator e = end_dynamic_table();
1559 // Use the same DataRefImpl format as DynRef.
1560 return library_iterator(LibraryRef(e->getRawDataRefImpl(), this));
1561 }
1562
1563 template
13551564 uint8_t ELFObjectFile::getBytesInAddress() const {
13561565 return is64Bits ? 8 : 4;
13571566 }
14491658 }
14501659
14511660 template
1661 const typename ELFObjectFile::Elf_Dyn *
1662 ELFObjectFile::getDyn(DataRefImpl DynData) const {
1663 return getEntry(dot_dynamic_sec, DynData.d.a);
1664 }
1665
1666 template
14521667 const typename ELFObjectFile::Elf_Rel *
14531668 ELFObjectFile::getRel(DataRefImpl Rel) const {
14541669 return getEntry(Rel.w.b, Rel.w.c);
15261741 return object_error::success;
15271742 }
15281743
1744 template
1745 inline DynRefImpl
1746 ::DynRefImpl(DataRefImpl DynP, const OwningType *Owner)
1747 : DynPimpl(DynP)
1748 , OwningObject(Owner) {}
1749
1750 template
1751 inline bool DynRefImpl
1752 ::operator==(const DynRefImpl &Other) const {
1753 return DynPimpl == Other.DynPimpl;
1754 }
1755
1756 template
1757 inline bool DynRefImpl
1758 ::operator <(const DynRefImpl &Other) const {
1759 return DynPimpl < Other.DynPimpl;
1760 }
1761
1762 template
1763 inline error_code DynRefImpl
1764 ::getNext(DynRefImpl &Result) const {
1765 return OwningObject->getDynNext(DynPimpl, Result);
1766 }
1767
1768 template
1769 inline int64_t DynRefImpl
1770 ::getTag() const {
1771 return OwningObject->getDyn(DynPimpl)->d_tag;
1772 }
1773
1774 template
1775 inline uint64_t DynRefImpl
1776 ::getVal() const {
1777 return OwningObject->getDyn(DynPimpl)->d_un.d_val;
1778 }
1779
1780 template
1781 inline uint64_t DynRefImpl
1782 ::getPtr() const {
1783 return OwningObject->getDyn(DynPimpl)->d_un.d_ptr;
1784 }
1785
1786 template
1787 inline DataRefImpl DynRefImpl
1788 ::getRawDataRefImpl() const {
1789 return DynPimpl;
1790 }
1791
15291792 }
15301793 }
15311794
3333 virtual symbol_iterator end_symbols() const;
3434 virtual symbol_iterator begin_dynamic_symbols() const;
3535 virtual symbol_iterator end_dynamic_symbols() const;
36 virtual library_iterator begin_libraries_needed() const;
37 virtual library_iterator end_libraries_needed() const;
3638 virtual section_iterator begin_sections() const;
3739 virtual section_iterator end_sections() const;
3840
9193 SmallVectorImpl &Result) const;
9294 virtual error_code getRelocationHidden(DataRefImpl Rel, bool &Result) const;
9395
96 virtual error_code getLibraryNext(DataRefImpl LibData, LibraryRef &Res) const;
97 virtual error_code getLibraryPath(DataRefImpl LibData, StringRef &Res) const;
98
9499 private:
95100 MachOObject *MachOObj;
96101 mutable uint32_t RegisteredStringTable;
226226 DataRefImpl getRawDataRefImpl() const;
227227 };
228228 typedef content_iterator symbol_iterator;
229
230 /// LibraryRef - This is a value type class that represents a single library in
231 /// the list of libraries needed by a shared or dynamic object.
232 class LibraryRef {
233 friend class SectionRef;
234 DataRefImpl LibraryPimpl;
235 const ObjectFile *OwningObject;
236
237 public:
238 LibraryRef() : OwningObject(NULL) {
239 std::memset(&LibraryPimpl, 0, sizeof(LibraryPimpl));
240 }
241
242 LibraryRef(DataRefImpl LibraryP, const ObjectFile *Owner);
243
244 bool operator==(const LibraryRef &Other) const;
245 bool operator <(const LibraryRef &Other) const;
246
247 error_code getNext(LibraryRef &Result) const;
248
249 // Get the path to this library, as stored in the object file.
250 error_code getPath(StringRef &Result) const;
251
252 DataRefImpl getRawDataRefImpl() const;
253 };
254 typedef content_iterator library_iterator;
229255
230256 const uint64_t UnknownAddressOrSize = ~0ULL;
231257
306332 return object_error::success;
307333 }
308334
335 // Same for LibraryRef
336 friend class LibraryRef;
337 virtual error_code getLibraryNext(DataRefImpl Lib, LibraryRef &Res) const = 0;
338 virtual error_code getLibraryPath(DataRefImpl Lib, StringRef &Res) const = 0;
339
309340 public:
310341
311342 virtual symbol_iterator begin_symbols() const = 0;
316347
317348 virtual section_iterator begin_sections() const = 0;
318349 virtual section_iterator end_sections() const = 0;
350
351 virtual library_iterator begin_libraries_needed() const = 0;
352 virtual library_iterator end_libraries_needed() const = 0;
319353
320354 /// @brief The number of bytes used to represent an address in this object
321355 /// file format.
508542 inline error_code RelocationRef::getHidden(bool &Result) const {
509543 return OwningObject->getRelocationHidden(RelocationPimpl, Result);
510544 }
545 // Inline function definitions.
546 inline LibraryRef::LibraryRef(DataRefImpl LibraryP, const ObjectFile *Owner)
547 : LibraryPimpl(LibraryP)
548 , OwningObject(Owner) {}
549
550 inline bool LibraryRef::operator==(const LibraryRef &Other) const {
551 return LibraryPimpl == Other.LibraryPimpl;
552 }
553
554 inline bool LibraryRef::operator <(const LibraryRef &Other) const {
555 return LibraryPimpl < Other.LibraryPimpl;
556 }
557
558 inline error_code LibraryRef::getNext(LibraryRef &Result) const {
559 return OwningObject->getLibraryNext(LibraryPimpl, Result);
560 }
561
562 inline error_code LibraryRef::getPath(StringRef &Result) const {
563 return OwningObject->getLibraryPath(LibraryPimpl, Result);
564 }
511565
512566 } // end namespace object
513567 } // end namespace llvm
512512 symbol_iterator COFFObjectFile::end_dynamic_symbols() const {
513513 // TODO: implement
514514 report_fatal_error("Dynamic symbols unimplemented in COFFObjectFile");
515 }
516
517 library_iterator COFFObjectFile::begin_libraries_needed() const {
518 // TODO: implement
519 report_fatal_error("Libraries needed unimplemented in COFFObjectFile");
520 }
521
522 library_iterator COFFObjectFile::end_libraries_needed() const {
523 // TODO: implement
524 report_fatal_error("Libraries needed unimplemented in COFFObjectFile");
515525 }
516526
517527 section_iterator COFFObjectFile::begin_sections() const {
725735 return object_error::success;
726736 }
727737
738 error_code COFFObjectFile::getLibraryNext(DataRefImpl LibData,
739 LibraryRef &Result) const {
740 report_fatal_error("getLibraryNext not implemented in COFFObjectFile");
741 }
742
743 error_code COFFObjectFile::getLibraryPath(DataRefImpl LibData,
744 StringRef &Result) const {
745 report_fatal_error("getLibraryPath not implemented in COFFObjectFile");
746 }
747
728748 namespace llvm {
729749
730750 ObjectFile *ObjectFile::createCOFFObjectFile(MemoryBuffer *Object) {
374374 symbol_iterator MachOObjectFile::end_dynamic_symbols() const {
375375 // TODO: implement
376376 report_fatal_error("Dynamic symbols unimplemented in MachOObjectFile");
377 }
378
379 library_iterator MachOObjectFile::begin_libraries_needed() const {
380 // TODO: implement
381 report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
382 }
383
384 library_iterator MachOObjectFile::end_libraries_needed() const {
385 // TODO: implement
386 report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
377387 }
378388
379389 /*===-- Sections ----------------------------------------------------------===*/
11741184 return object_error::success;
11751185 }
11761186
1187 error_code MachOObjectFile::getLibraryNext(DataRefImpl LibData,
1188 LibraryRef &Res) const {
1189 report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
1190 }
1191
1192 error_code MachOObjectFile::getLibraryPath(DataRefImpl LibData,
1193 StringRef &Res) const {
1194 report_fatal_error("Needed libraries unimplemented in MachOObjectFile");
1195 }
1196
1197
11771198 /*===-- Miscellaneous -----------------------------------------------------===*/
11781199
11791200 uint8_t MachOObjectFile::getBytesInAddress() const {
0 ; How to make the shared objects from this file:
1 ;
2 ; LDARGS="--unresolved-symbols=ignore-all -soname=libfoo.so --no-as-needed -lc -lm"
13 ;
24 ; X86-32 ELF:
35 ; llc -mtriple=i386-linux-gnu shared.ll -filetype=obj -o tmp32.o -relocation-model=pic
4 ; ld -melf_i386 -shared tmp32.o -o shared-object-test.elf-i386 --unresolved-symbols=ignore-all
6 ; ld -melf_i386 -shared tmp32.o -o shared-object-test.elf-i386 $LDARGS
57 ;
68 ; X86-64 ELF:
79 ; llc -mtriple=x86_64-linux-gnu shared.ll -filetype=obj -o tmp64.o -relocation-model=pic
8 ; ld -melf_x86_64 -shared tmp64.o -o shared-object-test.elf-x86-64 --unresolved-symbols=ignore-all
10 ; ld -melf_x86_64 -shared tmp64.o -o shared-object-test.elf-x86-64 $LDARGS
911
1012 @defined_sym = global i32 1, align 4
1113
0 RUN: llvm-readobj %p/Inputs/shared-object-test.elf-i386 \
1 RUN: | FileCheck %s -check-prefix ELF
2 RUN: llvm-readobj %p/Inputs/shared-object-test.elf-x86-64 \
3 RUN: | FileCheck %s -check-prefix ELF
4
5 ELF:Symbols:
6 ELF: .dynsym DBG {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} formatspecific
7 ELF: .dynstr DBG {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} formatspecific
8 ELF: .text DBG {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} formatspecific
9 ELF: .eh_frame DBG {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} formatspecific
10 ELF: .tdata DBG {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} formatspecific
11 ELF: .dynamic DBG {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} formatspecific
12 ELF: .got.plt DBG {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} formatspecific
13 ELF: .data DBG {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} formatspecific
14 ELF: .bss DBG {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} formatspecific
15 ELF: shared.ll FILE {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} absolute,formatspecific
16 ELF: local_func FUNC {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}}
17 ELF: _GLOBAL_OFFSET_TABLE_ DATA {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} absolute
18 ELF: _DYNAMIC DATA {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} absolute
19 ELF: common_sym DATA {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} global
20 ELF: tls_sym DATA {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} global,threadlocal
21 ELF: defined_sym DATA {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} global
22 ELF: __bss_start ? {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} global,absolute
23 ELF: _end ? {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} global,absolute
24 ELF: global_func FUNC {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} global
25 ELF: _edata ? {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} global,absolute
26 ELF: Total: 21
27
28 ELF:Dynamic Symbols:
29 ELF: common_sym DATA {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} global
30 ELF: tls_sym DATA {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} global,threadlocal
31 ELF: defined_sym DATA {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} global
32 ELF: __bss_start ? {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} global,absolute
33 ELF: _end ? {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} global,absolute
34 ELF: global_func FUNC {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} global
35 ELF: _edata ? {{[0-9a-f]+}} {{[0-9a-f]+}} {{[0-9a-f]+}} global,absolute
36 ELF: Total: {{[0-9a-f]+}}
37
38 ELF:Libraries needed:
39 ELF: libc.so.6
40 ELF: libm.so.6
41 ELF: Total: 2
42
43
3636 add_subdirectory(llvm-diff)
3737 add_subdirectory(macho-dump)
3838 add_subdirectory(llvm-objdump)
39 add_subdirectory(llvm-readobj)
3940 add_subdirectory(llvm-rtdyld)
4041 add_subdirectory(llvm-dwarfdump)
4142
3131 llvm-ld llvm-prof llvm-link \
3232 lli llvm-extract llvm-mc \
3333 bugpoint llvm-bcanalyzer llvm-stub \
34 llvm-diff macho-dump llvm-objdump \
34 llvm-diff macho-dump llvm-objdump llvm-readobj \
3535 llvm-rtdyld llvm-dwarfdump llvm-cov \
3636 llvm-size llvm-stress
3737
0 set(LLVM_LINK_COMPONENTS archive bitreader object)
1
2 add_llvm_tool(llvm-readobj
3 llvm-readobj.cpp
4 )
0 ;===- ./tools/llvm-readobj/LLVMBuild.txt ---------------------------*- Conf -*--===;
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 is an LLVMBuild description file for the components in this subdirectory.
10 ;
11 ; For more information on the LLVMBuild system, please see:
12 ;
13 ; http://llvm.org/docs/LLVMBuild.html
14 ;
15 ;===------------------------------------------------------------------------===;
16
17 [component_0]
18 type = Tool
19 name = llvm-readobj
20 parent = Tools
21 required_libraries = Archive BitReader Object
0 ##===- tools/llvm-readobj/Makefile -----------------------------*- Makefile -*-===##
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 LEVEL := ../..
10 TOOLNAME := llvm-readobj
11 LINK_COMPONENTS := archive bitreader object
12
13 # This tool has no plugins, optimize startup time.
14 TOOL_NO_EXPORTS := 1
15
16 include $(LEVEL)/Makefile.common
17
0 /*===- pso-stub.c - Stub executable to run llvm bitcode files -------------===//
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 //===----------------------------------------------------------------------===*/
10
11 #include
12 #include
13 #include
14 #include "llvm/Object/ObjectFile.h"
15 #include "llvm/Analysis/Verifier.h"
16 #include "llvm/Support/Format.h"
17 #include "llvm/Support/CommandLine.h"
18 #include "llvm/Support/PrettyStackTrace.h"
19 #include "llvm/Support/Debug.h"
20 #include "llvm/Support/Signals.h"
21 #include "llvm/Support/FormattedStream.h"
22
23 using namespace llvm;
24 using namespace llvm::object;
25
26 static cl::opt
27 InputFilename(cl::Positional, cl::desc(""), cl::init(""));
28
29 void DumpSymbolHeader() {
30 outs() << format(" %-32s", (const char*)"Name")
31 << format(" %-4s", (const char*)"Type")
32 << format(" %-16s", (const char*)"Address")
33 << format(" %-16s", (const char*)"Size")
34 << format(" %-16s", (const char*)"FileOffset")
35 << format(" %-26s", (const char*)"Flags")
36 << "\n";
37 }
38
39 const char *GetTypeStr(SymbolRef::Type Type) {
40 switch (Type) {
41 case SymbolRef::ST_Unknown: return "?";
42 case SymbolRef::ST_Data: return "DATA";
43 case SymbolRef::ST_Debug: return "DBG";
44 case SymbolRef::ST_File: return "FILE";
45 case SymbolRef::ST_Function: return "FUNC";
46 case SymbolRef::ST_Other: return "-";
47 }
48 return "INV";
49 }
50
51 std::string GetFlagStr(uint32_t Flags) {
52 std::string result;
53 if (Flags & SymbolRef::SF_Undefined)
54 result += "undef,";
55 if (Flags & SymbolRef::SF_Global)
56 result += "global,";
57 if (Flags & SymbolRef::SF_Weak)
58 result += "weak,";
59 if (Flags & SymbolRef::SF_Absolute)
60 result += "absolute,";
61 if (Flags & SymbolRef::SF_ThreadLocal)
62 result += "threadlocal,";
63 if (Flags & SymbolRef::SF_Common)
64 result += "common,";
65 if (Flags & SymbolRef::SF_FormatSpecific)
66 result += "formatspecific,";
67
68 // Remove trailing comma
69 if (result.size() > 0) {
70 result.erase(result.size() - 1);
71 }
72 return result;
73 }
74
75 void DumpSymbol(const SymbolRef &sym) {
76 StringRef Name;
77 SymbolRef::Type Type;
78 uint32_t Flags;
79 uint64_t Address;
80 uint64_t Size;
81 uint64_t FileOffset;
82 sym.getName(Name);
83 sym.getAddress(Address);
84 sym.getSize(Size);
85 sym.getFileOffset(FileOffset);
86 sym.getType(Type);
87 sym.getFlags(Flags);
88
89 // format() can't handle StringRefs
90 outs() << format(" %-32s", Name.str().c_str())
91 << format(" %-4s", GetTypeStr(Type))
92 << format(" %16"PRIx64, Address)
93 << format(" %16"PRIx64, Size)
94 << format(" %16"PRIx64, FileOffset)
95 << " " << GetFlagStr(Flags)
96 << "\n";
97 }
98
99
100 // Iterate through the normal symbols in the ObjectFile
101 void DumpSymbols(const ObjectFile *obj) {
102 error_code ec;
103 uint32_t count = 0;
104 outs() << "Symbols:\n";
105 symbol_iterator it = obj->begin_symbols();
106 symbol_iterator ie = obj->end_symbols();
107 while (it != ie) {
108 DumpSymbol(*it);
109 it.increment(ec);
110 if (ec)
111 report_fatal_error("Symbol iteration failed");
112 ++count;
113 }
114 outs() << " Total: " << count << "\n\n";
115 }
116
117 // Iterate through the dynamic symbols in the ObjectFile.
118 void DumpDynamicSymbols(const ObjectFile *obj) {
119 error_code ec;
120 uint32_t count = 0;
121 outs() << "Dynamic Symbols:\n";
122 symbol_iterator it = obj->begin_dynamic_symbols();
123 symbol_iterator ie = obj->end_dynamic_symbols();
124 while (it != ie) {
125 DumpSymbol(*it);
126 it.increment(ec);
127 if (ec)
128 report_fatal_error("Symbol iteration failed");
129 ++count;
130 }
131 outs() << " Total: " << count << "\n\n";
132 }
133
134 void DumpLibrary(const LibraryRef &lib) {
135 StringRef path;
136 lib.getPath(path);
137 outs() << " " << path << "\n";
138 }
139
140 // Iterate through needed libraries
141 void DumpLibrariesNeeded(const ObjectFile *obj) {
142 error_code ec;
143 uint32_t count = 0;
144 library_iterator it = obj->begin_libraries_needed();
145 library_iterator ie = obj->end_libraries_needed();
146 outs() << "Libraries needed:\n";
147 while (it != ie) {
148 DumpLibrary(*it);
149 it.increment(ec);
150 if (ec)
151 report_fatal_error("Needed libraries iteration failed");
152 ++count;
153 }
154 outs() << " Total: " << count << "\n\n";
155 }
156
157 int main(int argc, char** argv) {
158 error_code ec;
159 sys::PrintStackTraceOnErrorSignal();
160 PrettyStackTraceProgram X(argc, argv);
161
162 cl::ParseCommandLineOptions(argc, argv,
163 "LLVM Object Reader\n");
164
165 if (InputFilename.empty()) {
166 errs() << "Please specify an input filename\n";
167 return 1;
168 }
169
170 // Open the object file
171 OwningPtr File;
172 if (MemoryBuffer::getFile(InputFilename, File)) {
173 errs() << InputFilename << ": Open failed\n";
174 return 1;
175 }
176
177 ObjectFile *obj = ObjectFile::createObjectFile(File.take());
178 if (!obj) {
179 errs() << InputFilename << ": Object type not recognized\n";
180 }
181
182 DumpSymbols(obj);
183 DumpDynamicSymbols(obj);
184 DumpLibrariesNeeded(obj);
185 return 0;
186 }
187