1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: cmELF.cxx,v $
6 Date: $Date: 2008-04-14 19:02:24 $
7 Version: $Revision: 1.9 $
9 Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
10 See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
12 This software is distributed WITHOUT ANY WARRANTY; without even
13 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 PURPOSE. See the above copyright notices for more information.
16 =========================================================================*/
17 #include "cmStandardIncludes.h" // to get CMAKE_USE_ELF_PARSER first
20 #include <cmsys/auto_ptr.hxx>
22 // Need the native byte order of the running CPU.
23 #include <cmsys/CPU.h>
25 // Include the ELF format information system header.
28 # include <sys/link.h> // For dynamic section information
31 //----------------------------------------------------------------------------
32 // Low-level byte swapping implementation.
33 template <size_t s
> struct cmELFByteSwapSize
{};
34 void cmELFByteSwap(char*, cmELFByteSwapSize
<1> const&)
37 void cmELFByteSwap(char* data
, cmELFByteSwapSize
<2> const&)
40 one_byte
= data
[0]; data
[0] = data
[1]; data
[1] = one_byte
;
42 void cmELFByteSwap(char* data
, cmELFByteSwapSize
<4> const&)
45 one_byte
= data
[0]; data
[0] = data
[3]; data
[3] = one_byte
;
46 one_byte
= data
[1]; data
[1] = data
[2]; data
[2] = one_byte
;
48 void cmELFByteSwap(char* data
, cmELFByteSwapSize
<8> const&)
51 one_byte
= data
[0]; data
[0] = data
[7]; data
[7] = one_byte
;
52 one_byte
= data
[1]; data
[1] = data
[6]; data
[6] = one_byte
;
53 one_byte
= data
[2]; data
[2] = data
[5]; data
[5] = one_byte
;
54 one_byte
= data
[3]; data
[3] = data
[4]; data
[4] = one_byte
;
57 // Low-level byte swapping interface.
59 void cmELFByteSwap(T
& x
)
61 cmELFByteSwap(reinterpret_cast<char*>(&x
), cmELFByteSwapSize
<sizeof(T
)>());
64 //----------------------------------------------------------------------------
68 typedef cmELF::StringEntry StringEntry
;
69 enum ByteOrderType
{ ByteOrderMSB
, ByteOrderLSB
};
71 // Construct and take ownership of the file stream object.
72 cmELFInternal(cmELF
* external
,
73 cmsys::auto_ptr
<std::ifstream
>& fin
,
76 Stream(*fin
.release()),
78 ELFType(cmELF::FileTypeInvalid
)
80 // In most cases the processor-specific byte order will match that
81 // of the target execution environment. If we choose wrong here
82 // it is fixed when the header is read.
83 #if cmsys_CPU_ENDIAN_ID == cmsys_CPU_ENDIAN_ID_LITTLE
84 this->NeedSwap
= (this->ByteOrder
== ByteOrderMSB
);
85 #elif cmsys_CPU_ENDIAN_ID == cmsys_CPU_ENDIAN_ID_BIG
86 this->NeedSwap
= (this->ByteOrder
== ByteOrderLSB
);
89 // We have not yet loaded the section info.
90 this->DynamicSectionIndex
= -1;
93 // Destruct and delete the file stream object.
94 virtual ~cmELFInternal()
99 // Forward to the per-class implementation.
100 virtual unsigned int GetNumberOfSections() const = 0;
101 virtual unsigned int GetDynamicEntryCount() = 0;
102 virtual unsigned long GetDynamicEntryPosition(int j
) = 0;
103 virtual StringEntry
const* GetDynamicSectionString(int tag
) = 0;
104 virtual void PrintInfo(std::ostream
& os
) const = 0;
106 bool ReadBytes(unsigned long pos
, unsigned long size
, char* buf
)
108 this->Stream
.seekg(pos
);
109 this->Stream
.read(buf
, size
);
110 return this->Stream
?true:false;
113 // Lookup the SONAME in the DYNAMIC section.
114 StringEntry
const* GetSOName()
116 return this->GetDynamicSectionString(DT_SONAME
);
119 // Lookup the RPATH in the DYNAMIC section.
120 StringEntry
const* GetRPath()
122 return this->GetDynamicSectionString(DT_RPATH
);
125 // Lookup the RUNPATH in the DYNAMIC section.
126 StringEntry
const* GetRunPath()
128 #if defined(DT_RUNPATH)
129 return this->GetDynamicSectionString(DT_RUNPATH
);
135 // Return the recorded ELF type.
136 cmELF::FileType
GetFileType() const { return this->ELFType
; }
138 // Data common to all ELF class implementations.
140 // The external cmELF object.
143 // The stream from which to read.
144 std::istream
& Stream
;
146 // The byte order of the ELF file.
147 ByteOrderType ByteOrder
;
149 // The ELF file type.
150 cmELF::FileType ELFType
;
152 // Whether we need to byte-swap structures read from the stream.
155 // The section header index of the DYNAMIC section (-1 if none).
156 int DynamicSectionIndex
;
158 // Helper methods for subclasses.
159 void SetErrorMessage(const char* msg
)
161 this->External
->ErrorMessage
= msg
;
162 this->ELFType
= cmELF::FileTypeInvalid
;
165 // Store string table entry states.
166 std::map
<int, StringEntry
> DynamicSectionStrings
;
169 //----------------------------------------------------------------------------
170 // Configure the implementation template for 32-bit ELF files.
173 typedef Elf32_Ehdr ELF_Ehdr
;
174 typedef Elf32_Shdr ELF_Shdr
;
175 typedef Elf32_Dyn ELF_Dyn
;
176 typedef Elf32_Half ELF_Half
;
177 static const char* GetName() { return "32-bit"; }
180 // Configure the implementation template for 32-bit ELF files.
183 typedef Elf64_Ehdr ELF_Ehdr
;
184 typedef Elf64_Shdr ELF_Shdr
;
185 typedef Elf64_Dyn ELF_Dyn
;
186 typedef Elf64_Half ELF_Half
;
187 static const char* GetName() { return "64-bit"; }
190 //----------------------------------------------------------------------------
191 // Parser implementation template.
192 template <class Types
>
193 class cmELFInternalImpl
: public cmELFInternal
196 // Copy the ELF file format types from our configuration parameter.
197 typedef typename
Types::ELF_Ehdr ELF_Ehdr
;
198 typedef typename
Types::ELF_Shdr ELF_Shdr
;
199 typedef typename
Types::ELF_Dyn ELF_Dyn
;
200 typedef typename
Types::ELF_Half ELF_Half
;
202 // Construct with a stream and byte swap indicator.
203 cmELFInternalImpl(cmELF
* external
,
204 cmsys::auto_ptr
<std::ifstream
>& fin
,
205 ByteOrderType order
);
207 // Return the number of sections as specified by the ELF header.
208 virtual unsigned int GetNumberOfSections() const
210 return static_cast<unsigned int>(this->ELFHeader
.e_shnum
);
213 // Get the file position and size of a dynamic section entry.
214 virtual unsigned int GetDynamicEntryCount();
215 virtual unsigned long GetDynamicEntryPosition(int j
);
217 // Lookup a string from the dynamic section with the given tag.
218 virtual StringEntry
const* GetDynamicSectionString(int tag
);
220 // Print information about the ELF file.
221 virtual void PrintInfo(std::ostream
& os
) const
223 os
<< "ELF " << Types::GetName();
224 if(this->ByteOrder
== ByteOrderMSB
)
228 else if(this->ByteOrder
== ByteOrderLSB
)
232 switch(this->ELFType
)
234 case cmELF::FileTypeInvalid
:
235 os
<< " invalid file";
237 case cmELF::FileTypeRelocatableObject
:
238 os
<< " relocatable object";
240 case cmELF::FileTypeExecutable
:
243 case cmELF::FileTypeSharedLibrary
:
244 os
<< " shared library";
246 case cmELF::FileTypeCore
:
249 case cmELF::FileTypeSpecificOS
:
250 os
<< " os-specific type";
252 case cmELF::FileTypeSpecificProc
:
253 os
<< " processor-specific type";
260 void ByteSwap(ELF_Ehdr
& elf_header
)
262 cmELFByteSwap(elf_header
.e_type
);
263 cmELFByteSwap(elf_header
.e_machine
);
264 cmELFByteSwap(elf_header
.e_version
);
265 cmELFByteSwap(elf_header
.e_entry
);
266 cmELFByteSwap(elf_header
.e_phoff
);
267 cmELFByteSwap(elf_header
.e_shoff
);
268 cmELFByteSwap(elf_header
.e_flags
);
269 cmELFByteSwap(elf_header
.e_ehsize
);
270 cmELFByteSwap(elf_header
.e_phentsize
);
271 cmELFByteSwap(elf_header
.e_phnum
);
272 cmELFByteSwap(elf_header
.e_shentsize
);
273 cmELFByteSwap(elf_header
.e_shnum
);
274 cmELFByteSwap(elf_header
.e_shstrndx
);
277 void ByteSwap(ELF_Shdr
& sec_header
)
279 cmELFByteSwap(sec_header
.sh_name
);
280 cmELFByteSwap(sec_header
.sh_type
);
281 cmELFByteSwap(sec_header
.sh_flags
);
282 cmELFByteSwap(sec_header
.sh_addr
);
283 cmELFByteSwap(sec_header
.sh_offset
);
284 cmELFByteSwap(sec_header
.sh_size
);
285 cmELFByteSwap(sec_header
.sh_link
);
286 cmELFByteSwap(sec_header
.sh_info
);
287 cmELFByteSwap(sec_header
.sh_addralign
);
288 cmELFByteSwap(sec_header
.sh_entsize
);
291 void ByteSwap(ELF_Dyn
& dyn
)
293 cmELFByteSwap(dyn
.d_tag
);
296 case DT_NULL
: /* dyn.d_un ignored */ break;
297 case DT_NEEDED
: cmELFByteSwap(dyn
.d_un
.d_val
); break;
298 case DT_PLTRELSZ
: cmELFByteSwap(dyn
.d_un
.d_val
); break;
299 case DT_PLTGOT
: cmELFByteSwap(dyn
.d_un
.d_ptr
); break;
300 case DT_HASH
: cmELFByteSwap(dyn
.d_un
.d_ptr
); break;
301 case DT_STRTAB
: cmELFByteSwap(dyn
.d_un
.d_ptr
); break;
302 case DT_SYMTAB
: cmELFByteSwap(dyn
.d_un
.d_ptr
); break;
303 case DT_RELA
: cmELFByteSwap(dyn
.d_un
.d_ptr
); break;
304 case DT_RELASZ
: cmELFByteSwap(dyn
.d_un
.d_val
); break;
305 case DT_RELAENT
: cmELFByteSwap(dyn
.d_un
.d_val
); break;
306 case DT_STRSZ
: cmELFByteSwap(dyn
.d_un
.d_val
); break;
307 case DT_SYMENT
: cmELFByteSwap(dyn
.d_un
.d_val
); break;
308 case DT_INIT
: cmELFByteSwap(dyn
.d_un
.d_ptr
); break;
309 case DT_FINI
: cmELFByteSwap(dyn
.d_un
.d_ptr
); break;
310 case DT_SONAME
: cmELFByteSwap(dyn
.d_un
.d_val
); break;
311 case DT_RPATH
: cmELFByteSwap(dyn
.d_un
.d_val
); break;
312 case DT_SYMBOLIC
: /* dyn.d_un ignored */ break;
313 case DT_REL
: cmELFByteSwap(dyn
.d_un
.d_ptr
); break;
314 case DT_RELSZ
: cmELFByteSwap(dyn
.d_un
.d_val
); break;
315 case DT_RELENT
: cmELFByteSwap(dyn
.d_un
.d_val
); break;
316 case DT_PLTREL
: cmELFByteSwap(dyn
.d_un
.d_val
); break;
317 case DT_DEBUG
: cmELFByteSwap(dyn
.d_un
.d_ptr
); break;
318 case DT_TEXTREL
: /* dyn.d_un ignored */ break;
319 case DT_JMPREL
: cmELFByteSwap(dyn
.d_un
.d_ptr
); break;
321 case T_BIND_NOW
: /* dyn.d_un ignored */ break;
324 case DT_INIT_ARRAY
: cmELFByteSwap(dyn
.d_un
.d_ptr
); break;
327 case DT_FINI_ARRAY
: cmELFByteSwap(dyn
.d_un
.d_ptr
); break;
329 #ifdef DT_INIT_ARRAYSZ
330 case DT_INIT_ARRAYSZ
: cmELFByteSwap(dyn
.d_un
.d_val
); break;
332 #ifdef DT_FINI_ARRAYSZ
333 case DT_FINI_ARRAYSZ
: cmELFByteSwap(dyn
.d_un
.d_val
); break;
336 case DT_RUNPATH
: cmELFByteSwap(dyn
.d_un
.d_val
); break;
339 case DT_FLAGS
: cmELFByteSwap(dyn
.d_un
.d_val
); break;
341 #ifdef DT_PREINIT_ARRAY
342 case DT_PREINIT_ARRAY
: cmELFByteSwap(dyn
.d_un
.d_ptr
); break;
344 #ifdef DT_PREINIT_ARRAYSZ
345 case DT_PREINIT_ARRAYSZ
: cmELFByteSwap(dyn
.d_un
.d_val
); break;
350 bool FileTypeValid(ELF_Half et
)
352 unsigned int eti
= static_cast<unsigned int>(et
);
353 if(eti
== ET_NONE
|| eti
== ET_REL
|| eti
== ET_EXEC
||
354 eti
== ET_DYN
|| eti
== ET_CORE
)
358 #if defined(ET_LOOS) && defined(ET_HIOS)
359 if(eti
>= ET_LOOS
&& eti
<= ET_HIOS
)
364 #if defined(ET_LOPROC) && defined(ET_HIPROC)
365 if(eti
>= ET_LOPROC
&& eti
<= ET_HIPROC
)
373 bool Read(ELF_Ehdr
& x
)
375 // Read the header from the file.
376 if(!this->Stream
.read(reinterpret_cast<char*>(&x
), sizeof(x
)))
381 // The byte order of ELF header fields may not match that of the
382 // processor-specific data. The header fields are ordered to
383 // match the target execution environment, so we may need to
384 // memorize the order of all platforms based on the e_machine
385 // value. As a heuristic, if the type is invalid but its
386 // swapped value is okay then flip our swap mode.
387 ELF_Half et
= x
.e_type
;
392 if(!this->FileTypeValid(et
))
395 if(this->FileTypeValid(et
))
397 // The previous byte order guess was wrong. Flip it.
398 this->NeedSwap
= !this->NeedSwap
;
402 // Fix the byte order of the header.
409 bool Read(ELF_Shdr
& x
)
411 if(this->Stream
.read(reinterpret_cast<char*>(&x
), sizeof(x
)) &&
416 return this->Stream
? true:false;
418 bool Read(ELF_Dyn
& x
)
420 if(this->Stream
.read(reinterpret_cast<char*>(&x
), sizeof(x
)) &&
425 return this->Stream
? true:false;
428 bool LoadSectionHeader(ELF_Half i
)
430 // Read the section header from the file.
431 this->Stream
.seekg(this->ELFHeader
.e_shoff
+
432 this->ELFHeader
.e_shentsize
* i
);
433 if(!this->Read(this->SectionHeaders
[i
]))
438 // Identify some important sections.
439 if(this->SectionHeaders
[i
].sh_type
== SHT_DYNAMIC
)
441 this->DynamicSectionIndex
= i
;
446 bool LoadDynamicSection();
448 // Store the main ELF header.
451 // Store all the section headers.
452 std::vector
<ELF_Shdr
> SectionHeaders
;
454 // Store all entries of the DYNAMIC section.
455 std::vector
<ELF_Dyn
> DynamicSectionEntries
;
458 //----------------------------------------------------------------------------
459 template <class Types
>
460 cmELFInternalImpl
<Types
>
461 ::cmELFInternalImpl(cmELF
* external
,
462 cmsys::auto_ptr
<std::ifstream
>& fin
,
463 ByteOrderType order
):
464 cmELFInternal(external
, fin
, order
)
466 // Read the main header.
467 if(!this->Read(this->ELFHeader
))
469 this->SetErrorMessage("Failed to read main ELF header.");
473 // Determine the ELF file type.
474 switch(this->ELFHeader
.e_type
)
477 this->SetErrorMessage("ELF file type is NONE.");
480 this->ELFType
= cmELF::FileTypeRelocatableObject
;
483 this->ELFType
= cmELF::FileTypeExecutable
;
486 this->ELFType
= cmELF::FileTypeSharedLibrary
;
489 this->ELFType
= cmELF::FileTypeCore
;
493 unsigned int eti
= static_cast<unsigned int>(this->ELFHeader
.e_type
);
494 #if defined(ET_LOOS) && defined(ET_HIOS)
495 if(eti
>= ET_LOOS
&& eti
<= ET_HIOS
)
497 this->ELFType
= cmELF::FileTypeSpecificOS
;
501 #if defined(ET_LOPROC) && defined(ET_HIPROC)
502 if(eti
>= ET_LOPROC
&& eti
<= ET_HIPROC
)
504 this->ELFType
= cmELF::FileTypeSpecificProc
;
509 e
<< "Unknown ELF file type " << eti
;
510 this->SetErrorMessage(e
.str().c_str());
515 // Load the section headers.
516 this->SectionHeaders
.resize(this->ELFHeader
.e_shnum
);
517 for(ELF_Half i
=0; i
< this->ELFHeader
.e_shnum
; ++i
)
519 if(!this->LoadSectionHeader(i
))
521 this->SetErrorMessage("Failed to load section headers.");
527 //----------------------------------------------------------------------------
528 template <class Types
>
529 bool cmELFInternalImpl
<Types
>::LoadDynamicSection()
531 // If there is no dynamic section we are done.
532 if(this->DynamicSectionIndex
< 0)
537 // If the section was already loaded we are done.
538 if(!this->DynamicSectionEntries
.empty())
543 // Allocate the dynamic section entries.
544 ELF_Shdr
const& sec
= this->SectionHeaders
[this->DynamicSectionIndex
];
545 int n
= sec
.sh_size
/ sec
.sh_entsize
;
546 this->DynamicSectionEntries
.resize(n
);
549 for(int j
=0; j
< n
; ++j
)
551 // Seek to the beginning of the section entry.
552 this->Stream
.seekg(sec
.sh_offset
+ sec
.sh_entsize
*j
);
553 ELF_Dyn
& dyn
= this->DynamicSectionEntries
[j
];
555 // Try reading the entry.
558 this->SetErrorMessage("Error reading entry from DYNAMIC section.");
559 this->DynamicSectionIndex
= -1;
566 //----------------------------------------------------------------------------
567 template <class Types
>
568 unsigned int cmELFInternalImpl
<Types
>::GetDynamicEntryCount()
570 if(!this->LoadDynamicSection())
574 for(unsigned int i
= 0; i
< this->DynamicSectionEntries
.size(); ++i
)
576 if(this->DynamicSectionEntries
[i
].d_tag
== DT_NULL
)
581 return this->DynamicSectionEntries
.size();
584 //----------------------------------------------------------------------------
585 template <class Types
>
586 unsigned long cmELFInternalImpl
<Types
>::GetDynamicEntryPosition(int j
)
588 if(!this->LoadDynamicSection())
592 if(j
< 0 || j
>= this->DynamicSectionEntries
.size())
596 ELF_Shdr
const& sec
= this->SectionHeaders
[this->DynamicSectionIndex
];
597 return sec
.sh_offset
+ sec
.sh_entsize
*j
;
600 //----------------------------------------------------------------------------
601 template <class Types
>
602 cmELF::StringEntry
const*
603 cmELFInternalImpl
<Types
>::GetDynamicSectionString(int tag
)
605 // Short-circuit if already checked.
606 std::map
<int, StringEntry
>::iterator dssi
=
607 this->DynamicSectionStrings
.find(tag
);
608 if(dssi
!= this->DynamicSectionStrings
.end())
610 if(dssi
->second
.Position
> 0)
612 return &dssi
->second
;
617 // Create an entry for this tag. Assume it is missing until found.
618 StringEntry
& se
= this->DynamicSectionStrings
[tag
];
621 se
.IndexInSection
= -1;
623 // Try reading the dynamic section.
624 if(!this->LoadDynamicSection())
629 // Get the string table referenced by the DYNAMIC section.
630 ELF_Shdr
const& sec
= this->SectionHeaders
[this->DynamicSectionIndex
];
631 if(sec
.sh_link
>= this->SectionHeaders
.size())
633 this->SetErrorMessage("Section DYNAMIC has invalid string table index.");
636 ELF_Shdr
const& strtab
= this->SectionHeaders
[sec
.sh_link
];
638 // Look for the requested entry.
639 for(typename
std::vector
<ELF_Dyn
>::iterator
640 di
= this->DynamicSectionEntries
.begin();
641 di
!= this->DynamicSectionEntries
.end(); ++di
)
646 // We found the tag requested.
647 // Make sure the position given is within the string section.
648 if(dyn
.d_un
.d_val
>= strtab
.sh_size
)
650 this->SetErrorMessage("Section DYNAMIC references string beyond "
651 "the end of its string section.");
655 // Seek to the position reported by the entry.
656 unsigned long first
= static_cast<unsigned long>(dyn
.d_un
.d_val
);
657 unsigned long last
= first
;
658 unsigned long end
= static_cast<unsigned long>(strtab
.sh_size
);
659 this->Stream
.seekg(strtab
.sh_offset
+ first
);
661 // Read the string. It may be followed by more than one NULL
662 // terminator. Count the total size of the region allocated to
663 // the string. This assumes that the next string in the table
664 // is non-empty, but the "chrpath" tool makes the same
666 bool terminated
= false;
668 while(last
!= end
&& this->Stream
.get(c
) && !(terminated
&& c
))
681 // Make sure the whole value was read.
684 this->SetErrorMessage("Dynamic section specifies unreadable RPATH.");
689 // The value has been read successfully. Report it.
690 se
.Position
= static_cast<unsigned long>(strtab
.sh_offset
+ first
);
691 se
.Size
= last
- first
;
692 se
.IndexInSection
= di
- this->DynamicSectionEntries
.begin();
699 //============================================================================
700 // External class implementation.
702 //----------------------------------------------------------------------------
703 cmELF::cmELF(const char* fname
): Internal(0)
705 // Try to open the file.
706 cmsys::auto_ptr
<std::ifstream
> fin(new std::ifstream(fname
));
708 // Quit now if the file could not be opened.
709 if(!fin
.get() || !*fin
)
711 this->ErrorMessage
= "Error opening input file.";
715 // Read the ELF identification block.
716 char ident
[EI_NIDENT
];
717 if(!fin
->read(ident
, EI_NIDENT
))
719 this->ErrorMessage
= "Error reading ELF identification.";
724 this->ErrorMessage
= "Error seeking to beginning of file.";
728 // Verify the ELF identification.
729 if(!(ident
[EI_MAG0
] == ELFMAG0
&&
730 ident
[EI_MAG1
] == ELFMAG1
&&
731 ident
[EI_MAG2
] == ELFMAG2
&&
732 ident
[EI_MAG3
] == ELFMAG3
))
734 this->ErrorMessage
= "File does not have a valid ELF identification.";
738 // Check the byte order in which the rest of the file is encoded.
739 cmELFInternal::ByteOrderType order
;
740 if(ident
[EI_DATA
] == ELFDATA2LSB
)
743 order
= cmELFInternal::ByteOrderLSB
;
745 else if(ident
[EI_DATA
] == ELFDATA2MSB
)
748 order
= cmELFInternal::ByteOrderMSB
;
752 this->ErrorMessage
= "ELF file is not LSB or MSB encoded.";
756 // Check the class of the file and construct the corresponding
757 // parser implementation.
758 if(ident
[EI_CLASS
] == ELFCLASS32
)
761 this->Internal
= new cmELFInternalImpl
<cmELFTypes32
>(this, fin
, order
);
763 else if(ident
[EI_CLASS
] == ELFCLASS64
)
766 this->Internal
= new cmELFInternalImpl
<cmELFTypes64
>(this, fin
, order
);
770 this->ErrorMessage
= "ELF file class is not 32-bit or 64-bit.";
775 //----------------------------------------------------------------------------
778 delete this->Internal
;
781 //----------------------------------------------------------------------------
782 bool cmELF::Valid() const
784 return this->Internal
&& this->Internal
->GetFileType() != FileTypeInvalid
;
787 //----------------------------------------------------------------------------
788 cmELF::FileType
cmELF::GetFileType() const
792 return this->Internal
->GetFileType();
796 return FileTypeInvalid
;
800 //----------------------------------------------------------------------------
801 unsigned int cmELF::GetNumberOfSections() const
805 return this->Internal
->GetNumberOfSections();
813 //----------------------------------------------------------------------------
814 unsigned int cmELF::GetDynamicEntryCount() const
818 return this->Internal
->GetDynamicEntryCount();
826 //----------------------------------------------------------------------------
827 unsigned long cmELF::GetDynamicEntryPosition(int index
) const
831 return this->Internal
->GetDynamicEntryPosition(index
);
839 //----------------------------------------------------------------------------
840 bool cmELF::ReadBytes(unsigned long pos
, unsigned long size
, char* buf
) const
844 return this->Internal
->ReadBytes(pos
, size
, buf
);
852 //----------------------------------------------------------------------------
853 bool cmELF::GetSOName(std::string
& soname
)
855 if(StringEntry
const* se
= this->GetSOName())
866 //----------------------------------------------------------------------------
867 cmELF::StringEntry
const* cmELF::GetSOName()
870 this->Internal
->GetFileType() == cmELF::FileTypeSharedLibrary
)
872 return this->Internal
->GetSOName();
880 //----------------------------------------------------------------------------
881 cmELF::StringEntry
const* cmELF::GetRPath()
884 this->Internal
->GetFileType() == cmELF::FileTypeExecutable
||
885 this->Internal
->GetFileType() == cmELF::FileTypeSharedLibrary
)
887 return this->Internal
->GetRPath();
895 //----------------------------------------------------------------------------
896 cmELF::StringEntry
const* cmELF::GetRunPath()
899 this->Internal
->GetFileType() == cmELF::FileTypeExecutable
||
900 this->Internal
->GetFileType() == cmELF::FileTypeSharedLibrary
)
902 return this->Internal
->GetRunPath();
910 //----------------------------------------------------------------------------
911 void cmELF::PrintInfo(std::ostream
& os
) const
915 this->Internal
->PrintInfo(os
);
919 os
<< "Not a valid ELF file.\n";