1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: cmELF.cxx,v $
6 Date: $Date: 2008-08-04 13:38:38 $
7 Version: $Revision: 1.13 $
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 #define cmsys_CPU_UNKNOWN_OKAY // We can decide at runtime if not known.
24 #include <cmsys/CPU.h>
26 // Include the ELF format information system header.
29 # include <sys/link.h> // For dynamic section information
32 //----------------------------------------------------------------------------
33 // Low-level byte swapping implementation.
34 template <size_t s
> struct cmELFByteSwapSize
{};
35 void cmELFByteSwap(char*, cmELFByteSwapSize
<1> const&)
38 void cmELFByteSwap(char* data
, cmELFByteSwapSize
<2> const&)
41 one_byte
= data
[0]; data
[0] = data
[1]; data
[1] = one_byte
;
43 void cmELFByteSwap(char* data
, cmELFByteSwapSize
<4> const&)
46 one_byte
= data
[0]; data
[0] = data
[3]; data
[3] = one_byte
;
47 one_byte
= data
[1]; data
[1] = data
[2]; data
[2] = one_byte
;
49 void cmELFByteSwap(char* data
, cmELFByteSwapSize
<8> const&)
52 one_byte
= data
[0]; data
[0] = data
[7]; data
[7] = one_byte
;
53 one_byte
= data
[1]; data
[1] = data
[6]; data
[6] = one_byte
;
54 one_byte
= data
[2]; data
[2] = data
[5]; data
[5] = one_byte
;
55 one_byte
= data
[3]; data
[3] = data
[4]; data
[4] = one_byte
;
58 // Low-level byte swapping interface.
60 void cmELFByteSwap(T
& x
)
62 cmELFByteSwap(reinterpret_cast<char*>(&x
), cmELFByteSwapSize
<sizeof(T
)>());
65 //----------------------------------------------------------------------------
69 typedef cmELF::StringEntry StringEntry
;
70 enum ByteOrderType
{ ByteOrderMSB
, ByteOrderLSB
};
72 // Construct and take ownership of the file stream object.
73 cmELFInternal(cmELF
* external
,
74 cmsys::auto_ptr
<std::ifstream
>& fin
,
77 Stream(*fin
.release()),
79 ELFType(cmELF::FileTypeInvalid
)
81 // In most cases the processor-specific byte order will match that
82 // of the target execution environment. If we choose wrong here
83 // it is fixed when the header is read.
84 #if cmsys_CPU_ENDIAN_ID == cmsys_CPU_ENDIAN_ID_LITTLE
85 this->NeedSwap
= (this->ByteOrder
== ByteOrderMSB
);
86 #elif cmsys_CPU_ENDIAN_ID == cmsys_CPU_ENDIAN_ID_BIG
87 this->NeedSwap
= (this->ByteOrder
== ByteOrderLSB
);
89 this->NeedSwap
= false; // Final decision is at runtime anyway.
92 // We have not yet loaded the section info.
93 this->DynamicSectionIndex
= -1;
96 // Destruct and delete the file stream object.
97 virtual ~cmELFInternal()
102 // Forward to the per-class implementation.
103 virtual unsigned int GetNumberOfSections() const = 0;
104 virtual unsigned int GetDynamicEntryCount() = 0;
105 virtual unsigned long GetDynamicEntryPosition(int j
) = 0;
106 virtual StringEntry
const* GetDynamicSectionString(int tag
) = 0;
107 virtual void PrintInfo(std::ostream
& os
) const = 0;
109 bool ReadBytes(unsigned long pos
, unsigned long size
, char* buf
)
111 this->Stream
.seekg(pos
);
112 this->Stream
.read(buf
, size
);
113 return this->Stream
?true:false;
116 // Lookup the SONAME in the DYNAMIC section.
117 StringEntry
const* GetSOName()
119 return this->GetDynamicSectionString(DT_SONAME
);
122 // Lookup the RPATH in the DYNAMIC section.
123 StringEntry
const* GetRPath()
125 return this->GetDynamicSectionString(DT_RPATH
);
128 // Lookup the RUNPATH in the DYNAMIC section.
129 StringEntry
const* GetRunPath()
131 #if defined(DT_RUNPATH)
132 return this->GetDynamicSectionString(DT_RUNPATH
);
138 // Return the recorded ELF type.
139 cmELF::FileType
GetFileType() const { return this->ELFType
; }
141 // Data common to all ELF class implementations.
143 // The external cmELF object.
146 // The stream from which to read.
147 std::istream
& Stream
;
149 // The byte order of the ELF file.
150 ByteOrderType ByteOrder
;
152 // The ELF file type.
153 cmELF::FileType ELFType
;
155 // Whether we need to byte-swap structures read from the stream.
158 // The section header index of the DYNAMIC section (-1 if none).
159 int DynamicSectionIndex
;
161 // Helper methods for subclasses.
162 void SetErrorMessage(const char* msg
)
164 this->External
->ErrorMessage
= msg
;
165 this->ELFType
= cmELF::FileTypeInvalid
;
168 // Store string table entry states.
169 std::map
<int, StringEntry
> DynamicSectionStrings
;
172 //----------------------------------------------------------------------------
173 // Configure the implementation template for 32-bit ELF files.
176 typedef Elf32_Ehdr ELF_Ehdr
;
177 typedef Elf32_Shdr ELF_Shdr
;
178 typedef Elf32_Dyn ELF_Dyn
;
179 typedef Elf32_Half ELF_Half
;
180 static const char* GetName() { return "32-bit"; }
183 // Configure the implementation template for 32-bit ELF files.
186 typedef Elf64_Ehdr ELF_Ehdr
;
187 typedef Elf64_Shdr ELF_Shdr
;
188 typedef Elf64_Dyn ELF_Dyn
;
189 typedef Elf64_Half ELF_Half
;
190 static const char* GetName() { return "64-bit"; }
193 //----------------------------------------------------------------------------
194 // Parser implementation template.
195 template <class Types
>
196 class cmELFInternalImpl
: public cmELFInternal
199 // Copy the ELF file format types from our configuration parameter.
200 typedef typename
Types::ELF_Ehdr ELF_Ehdr
;
201 typedef typename
Types::ELF_Shdr ELF_Shdr
;
202 typedef typename
Types::ELF_Dyn ELF_Dyn
;
203 typedef typename
Types::ELF_Half ELF_Half
;
205 // Construct with a stream and byte swap indicator.
206 cmELFInternalImpl(cmELF
* external
,
207 cmsys::auto_ptr
<std::ifstream
>& fin
,
208 ByteOrderType order
);
210 // Return the number of sections as specified by the ELF header.
211 virtual unsigned int GetNumberOfSections() const
213 return static_cast<unsigned int>(this->ELFHeader
.e_shnum
);
216 // Get the file position and size of a dynamic section entry.
217 virtual unsigned int GetDynamicEntryCount();
218 virtual unsigned long GetDynamicEntryPosition(int j
);
220 // Lookup a string from the dynamic section with the given tag.
221 virtual StringEntry
const* GetDynamicSectionString(int tag
);
223 // Print information about the ELF file.
224 virtual void PrintInfo(std::ostream
& os
) const
226 os
<< "ELF " << Types::GetName();
227 if(this->ByteOrder
== ByteOrderMSB
)
231 else if(this->ByteOrder
== ByteOrderLSB
)
235 switch(this->ELFType
)
237 case cmELF::FileTypeInvalid
:
238 os
<< " invalid file";
240 case cmELF::FileTypeRelocatableObject
:
241 os
<< " relocatable object";
243 case cmELF::FileTypeExecutable
:
246 case cmELF::FileTypeSharedLibrary
:
247 os
<< " shared library";
249 case cmELF::FileTypeCore
:
252 case cmELF::FileTypeSpecificOS
:
253 os
<< " os-specific type";
255 case cmELF::FileTypeSpecificProc
:
256 os
<< " processor-specific type";
263 void ByteSwap(ELF_Ehdr
& elf_header
)
265 cmELFByteSwap(elf_header
.e_type
);
266 cmELFByteSwap(elf_header
.e_machine
);
267 cmELFByteSwap(elf_header
.e_version
);
268 cmELFByteSwap(elf_header
.e_entry
);
269 cmELFByteSwap(elf_header
.e_phoff
);
270 cmELFByteSwap(elf_header
.e_shoff
);
271 cmELFByteSwap(elf_header
.e_flags
);
272 cmELFByteSwap(elf_header
.e_ehsize
);
273 cmELFByteSwap(elf_header
.e_phentsize
);
274 cmELFByteSwap(elf_header
.e_phnum
);
275 cmELFByteSwap(elf_header
.e_shentsize
);
276 cmELFByteSwap(elf_header
.e_shnum
);
277 cmELFByteSwap(elf_header
.e_shstrndx
);
280 void ByteSwap(ELF_Shdr
& sec_header
)
282 cmELFByteSwap(sec_header
.sh_name
);
283 cmELFByteSwap(sec_header
.sh_type
);
284 cmELFByteSwap(sec_header
.sh_flags
);
285 cmELFByteSwap(sec_header
.sh_addr
);
286 cmELFByteSwap(sec_header
.sh_offset
);
287 cmELFByteSwap(sec_header
.sh_size
);
288 cmELFByteSwap(sec_header
.sh_link
);
289 cmELFByteSwap(sec_header
.sh_info
);
290 cmELFByteSwap(sec_header
.sh_addralign
);
291 cmELFByteSwap(sec_header
.sh_entsize
);
294 void ByteSwap(ELF_Dyn
& dyn
)
296 cmELFByteSwap(dyn
.d_tag
);
299 case DT_NULL
: /* dyn.d_un ignored */ break;
300 case DT_NEEDED
: cmELFByteSwap(dyn
.d_un
.d_val
); break;
301 case DT_PLTRELSZ
: cmELFByteSwap(dyn
.d_un
.d_val
); break;
302 case DT_PLTGOT
: cmELFByteSwap(dyn
.d_un
.d_ptr
); break;
303 case DT_HASH
: cmELFByteSwap(dyn
.d_un
.d_ptr
); break;
304 case DT_STRTAB
: cmELFByteSwap(dyn
.d_un
.d_ptr
); break;
305 case DT_SYMTAB
: cmELFByteSwap(dyn
.d_un
.d_ptr
); break;
306 case DT_RELA
: cmELFByteSwap(dyn
.d_un
.d_ptr
); break;
307 case DT_RELASZ
: cmELFByteSwap(dyn
.d_un
.d_val
); break;
308 case DT_RELAENT
: cmELFByteSwap(dyn
.d_un
.d_val
); break;
309 case DT_STRSZ
: cmELFByteSwap(dyn
.d_un
.d_val
); break;
310 case DT_SYMENT
: cmELFByteSwap(dyn
.d_un
.d_val
); break;
311 case DT_INIT
: cmELFByteSwap(dyn
.d_un
.d_ptr
); break;
312 case DT_FINI
: cmELFByteSwap(dyn
.d_un
.d_ptr
); break;
313 case DT_SONAME
: cmELFByteSwap(dyn
.d_un
.d_val
); break;
314 case DT_RPATH
: cmELFByteSwap(dyn
.d_un
.d_val
); break;
315 case DT_SYMBOLIC
: /* dyn.d_un ignored */ break;
316 case DT_REL
: cmELFByteSwap(dyn
.d_un
.d_ptr
); break;
317 case DT_RELSZ
: cmELFByteSwap(dyn
.d_un
.d_val
); break;
318 case DT_RELENT
: cmELFByteSwap(dyn
.d_un
.d_val
); break;
319 case DT_PLTREL
: cmELFByteSwap(dyn
.d_un
.d_val
); break;
320 case DT_DEBUG
: cmELFByteSwap(dyn
.d_un
.d_ptr
); break;
321 case DT_TEXTREL
: /* dyn.d_un ignored */ break;
322 case DT_JMPREL
: cmELFByteSwap(dyn
.d_un
.d_ptr
); break;
324 case T_BIND_NOW
: /* dyn.d_un ignored */ break;
327 case DT_INIT_ARRAY
: cmELFByteSwap(dyn
.d_un
.d_ptr
); break;
330 case DT_FINI_ARRAY
: cmELFByteSwap(dyn
.d_un
.d_ptr
); break;
332 #ifdef DT_INIT_ARRAYSZ
333 case DT_INIT_ARRAYSZ
: cmELFByteSwap(dyn
.d_un
.d_val
); break;
335 #ifdef DT_FINI_ARRAYSZ
336 case DT_FINI_ARRAYSZ
: cmELFByteSwap(dyn
.d_un
.d_val
); break;
339 case DT_RUNPATH
: cmELFByteSwap(dyn
.d_un
.d_val
); break;
342 case DT_FLAGS
: cmELFByteSwap(dyn
.d_un
.d_val
); break;
344 #ifdef DT_PREINIT_ARRAY
345 case DT_PREINIT_ARRAY
: cmELFByteSwap(dyn
.d_un
.d_ptr
); break;
347 #ifdef DT_PREINIT_ARRAYSZ
348 case DT_PREINIT_ARRAYSZ
: cmELFByteSwap(dyn
.d_un
.d_val
); break;
353 bool FileTypeValid(ELF_Half et
)
355 unsigned int eti
= static_cast<unsigned int>(et
);
356 if(eti
== ET_NONE
|| eti
== ET_REL
|| eti
== ET_EXEC
||
357 eti
== ET_DYN
|| eti
== ET_CORE
)
361 #if defined(ET_LOOS) && defined(ET_HIOS)
362 if(eti
>= ET_LOOS
&& eti
<= ET_HIOS
)
367 #if defined(ET_LOPROC) && defined(ET_HIPROC)
368 if(eti
>= ET_LOPROC
&& eti
<= ET_HIPROC
)
376 bool Read(ELF_Ehdr
& x
)
378 // Read the header from the file.
379 if(!this->Stream
.read(reinterpret_cast<char*>(&x
), sizeof(x
)))
384 // The byte order of ELF header fields may not match that of the
385 // processor-specific data. The header fields are ordered to
386 // match the target execution environment, so we may need to
387 // memorize the order of all platforms based on the e_machine
388 // value. As a heuristic, if the type is invalid but its
389 // swapped value is okay then flip our swap mode.
390 ELF_Half et
= x
.e_type
;
395 if(!this->FileTypeValid(et
))
398 if(this->FileTypeValid(et
))
400 // The previous byte order guess was wrong. Flip it.
401 this->NeedSwap
= !this->NeedSwap
;
405 // Fix the byte order of the header.
412 bool Read(ELF_Shdr
& x
)
414 if(this->Stream
.read(reinterpret_cast<char*>(&x
), sizeof(x
)) &&
419 return this->Stream
? true:false;
421 bool Read(ELF_Dyn
& x
)
423 if(this->Stream
.read(reinterpret_cast<char*>(&x
), sizeof(x
)) &&
428 return this->Stream
? true:false;
431 bool LoadSectionHeader(ELF_Half i
)
433 // Read the section header from the file.
434 this->Stream
.seekg(this->ELFHeader
.e_shoff
+
435 this->ELFHeader
.e_shentsize
* i
);
436 if(!this->Read(this->SectionHeaders
[i
]))
441 // Identify some important sections.
442 if(this->SectionHeaders
[i
].sh_type
== SHT_DYNAMIC
)
444 this->DynamicSectionIndex
= i
;
449 bool LoadDynamicSection();
451 // Store the main ELF header.
454 // Store all the section headers.
455 std::vector
<ELF_Shdr
> SectionHeaders
;
457 // Store all entries of the DYNAMIC section.
458 std::vector
<ELF_Dyn
> DynamicSectionEntries
;
461 //----------------------------------------------------------------------------
462 template <class Types
>
463 cmELFInternalImpl
<Types
>
464 ::cmELFInternalImpl(cmELF
* external
,
465 cmsys::auto_ptr
<std::ifstream
>& fin
,
466 ByteOrderType order
):
467 cmELFInternal(external
, fin
, order
)
469 // Read the main header.
470 if(!this->Read(this->ELFHeader
))
472 this->SetErrorMessage("Failed to read main ELF header.");
476 // Determine the ELF file type.
477 switch(this->ELFHeader
.e_type
)
480 this->SetErrorMessage("ELF file type is NONE.");
483 this->ELFType
= cmELF::FileTypeRelocatableObject
;
486 this->ELFType
= cmELF::FileTypeExecutable
;
489 this->ELFType
= cmELF::FileTypeSharedLibrary
;
492 this->ELFType
= cmELF::FileTypeCore
;
496 unsigned int eti
= static_cast<unsigned int>(this->ELFHeader
.e_type
);
497 #if defined(ET_LOOS) && defined(ET_HIOS)
498 if(eti
>= ET_LOOS
&& eti
<= ET_HIOS
)
500 this->ELFType
= cmELF::FileTypeSpecificOS
;
504 #if defined(ET_LOPROC) && defined(ET_HIPROC)
505 if(eti
>= ET_LOPROC
&& eti
<= ET_HIPROC
)
507 this->ELFType
= cmELF::FileTypeSpecificProc
;
512 e
<< "Unknown ELF file type " << eti
;
513 this->SetErrorMessage(e
.str().c_str());
518 // Load the section headers.
519 this->SectionHeaders
.resize(this->ELFHeader
.e_shnum
);
520 for(ELF_Half i
=0; i
< this->ELFHeader
.e_shnum
; ++i
)
522 if(!this->LoadSectionHeader(i
))
524 this->SetErrorMessage("Failed to load section headers.");
530 //----------------------------------------------------------------------------
531 template <class Types
>
532 bool cmELFInternalImpl
<Types
>::LoadDynamicSection()
534 // If there is no dynamic section we are done.
535 if(this->DynamicSectionIndex
< 0)
540 // If the section was already loaded we are done.
541 if(!this->DynamicSectionEntries
.empty())
546 // Allocate the dynamic section entries.
547 ELF_Shdr
const& sec
= this->SectionHeaders
[this->DynamicSectionIndex
];
548 int n
= sec
.sh_size
/ sec
.sh_entsize
;
549 this->DynamicSectionEntries
.resize(n
);
552 for(int j
=0; j
< n
; ++j
)
554 // Seek to the beginning of the section entry.
555 this->Stream
.seekg(sec
.sh_offset
+ sec
.sh_entsize
*j
);
556 ELF_Dyn
& dyn
= this->DynamicSectionEntries
[j
];
558 // Try reading the entry.
561 this->SetErrorMessage("Error reading entry from DYNAMIC section.");
562 this->DynamicSectionIndex
= -1;
569 //----------------------------------------------------------------------------
570 template <class Types
>
571 unsigned int cmELFInternalImpl
<Types
>::GetDynamicEntryCount()
573 if(!this->LoadDynamicSection())
577 for(unsigned int i
= 0; i
< this->DynamicSectionEntries
.size(); ++i
)
579 if(this->DynamicSectionEntries
[i
].d_tag
== DT_NULL
)
584 return this->DynamicSectionEntries
.size();
587 //----------------------------------------------------------------------------
588 template <class Types
>
589 unsigned long cmELFInternalImpl
<Types
>::GetDynamicEntryPosition(int j
)
591 if(!this->LoadDynamicSection())
595 if(j
< 0 || j
>= static_cast<int>(this->DynamicSectionEntries
.size()))
599 ELF_Shdr
const& sec
= this->SectionHeaders
[this->DynamicSectionIndex
];
600 return sec
.sh_offset
+ sec
.sh_entsize
*j
;
603 //----------------------------------------------------------------------------
604 template <class Types
>
605 cmELF::StringEntry
const*
606 cmELFInternalImpl
<Types
>::GetDynamicSectionString(int tag
)
608 // Short-circuit if already checked.
609 std::map
<int, StringEntry
>::iterator dssi
=
610 this->DynamicSectionStrings
.find(tag
);
611 if(dssi
!= this->DynamicSectionStrings
.end())
613 if(dssi
->second
.Position
> 0)
615 return &dssi
->second
;
620 // Create an entry for this tag. Assume it is missing until found.
621 StringEntry
& se
= this->DynamicSectionStrings
[tag
];
624 se
.IndexInSection
= -1;
626 // Try reading the dynamic section.
627 if(!this->LoadDynamicSection())
632 // Get the string table referenced by the DYNAMIC section.
633 ELF_Shdr
const& sec
= this->SectionHeaders
[this->DynamicSectionIndex
];
634 if(sec
.sh_link
>= this->SectionHeaders
.size())
636 this->SetErrorMessage("Section DYNAMIC has invalid string table index.");
639 ELF_Shdr
const& strtab
= this->SectionHeaders
[sec
.sh_link
];
641 // Look for the requested entry.
642 for(typename
std::vector
<ELF_Dyn
>::iterator
643 di
= this->DynamicSectionEntries
.begin();
644 di
!= this->DynamicSectionEntries
.end(); ++di
)
649 // We found the tag requested.
650 // Make sure the position given is within the string section.
651 if(dyn
.d_un
.d_val
>= strtab
.sh_size
)
653 this->SetErrorMessage("Section DYNAMIC references string beyond "
654 "the end of its string section.");
658 // Seek to the position reported by the entry.
659 unsigned long first
= static_cast<unsigned long>(dyn
.d_un
.d_val
);
660 unsigned long last
= first
;
661 unsigned long end
= static_cast<unsigned long>(strtab
.sh_size
);
662 this->Stream
.seekg(strtab
.sh_offset
+ first
);
664 // Read the string. It may be followed by more than one NULL
665 // terminator. Count the total size of the region allocated to
666 // the string. This assumes that the next string in the table
667 // is non-empty, but the "chrpath" tool makes the same
669 bool terminated
= false;
671 while(last
!= end
&& this->Stream
.get(c
) && !(terminated
&& c
))
684 // Make sure the whole value was read.
687 this->SetErrorMessage("Dynamic section specifies unreadable RPATH.");
692 // The value has been read successfully. Report it.
693 se
.Position
= static_cast<unsigned long>(strtab
.sh_offset
+ first
);
694 se
.Size
= last
- first
;
695 se
.IndexInSection
= di
- this->DynamicSectionEntries
.begin();
702 //============================================================================
703 // External class implementation.
705 //----------------------------------------------------------------------------
706 cmELF::cmELF(const char* fname
): Internal(0)
708 // Try to open the file.
709 cmsys::auto_ptr
<std::ifstream
> fin(new std::ifstream(fname
));
711 // Quit now if the file could not be opened.
712 if(!fin
.get() || !*fin
)
714 this->ErrorMessage
= "Error opening input file.";
718 // Read the ELF identification block.
719 char ident
[EI_NIDENT
];
720 if(!fin
->read(ident
, EI_NIDENT
))
722 this->ErrorMessage
= "Error reading ELF identification.";
727 this->ErrorMessage
= "Error seeking to beginning of file.";
731 // Verify the ELF identification.
732 if(!(ident
[EI_MAG0
] == ELFMAG0
&&
733 ident
[EI_MAG1
] == ELFMAG1
&&
734 ident
[EI_MAG2
] == ELFMAG2
&&
735 ident
[EI_MAG3
] == ELFMAG3
))
737 this->ErrorMessage
= "File does not have a valid ELF identification.";
741 // Check the byte order in which the rest of the file is encoded.
742 cmELFInternal::ByteOrderType order
;
743 if(ident
[EI_DATA
] == ELFDATA2LSB
)
746 order
= cmELFInternal::ByteOrderLSB
;
748 else if(ident
[EI_DATA
] == ELFDATA2MSB
)
751 order
= cmELFInternal::ByteOrderMSB
;
755 this->ErrorMessage
= "ELF file is not LSB or MSB encoded.";
759 // Check the class of the file and construct the corresponding
760 // parser implementation.
761 if(ident
[EI_CLASS
] == ELFCLASS32
)
764 this->Internal
= new cmELFInternalImpl
<cmELFTypes32
>(this, fin
, order
);
766 else if(ident
[EI_CLASS
] == ELFCLASS64
)
769 this->Internal
= new cmELFInternalImpl
<cmELFTypes64
>(this, fin
, order
);
773 this->ErrorMessage
= "ELF file class is not 32-bit or 64-bit.";
778 //----------------------------------------------------------------------------
781 delete this->Internal
;
784 //----------------------------------------------------------------------------
785 bool cmELF::Valid() const
787 return this->Internal
&& this->Internal
->GetFileType() != FileTypeInvalid
;
790 //----------------------------------------------------------------------------
791 cmELF::FileType
cmELF::GetFileType() const
795 return this->Internal
->GetFileType();
799 return FileTypeInvalid
;
803 //----------------------------------------------------------------------------
804 unsigned int cmELF::GetNumberOfSections() const
808 return this->Internal
->GetNumberOfSections();
816 //----------------------------------------------------------------------------
817 unsigned int cmELF::GetDynamicEntryCount() const
821 return this->Internal
->GetDynamicEntryCount();
829 //----------------------------------------------------------------------------
830 unsigned long cmELF::GetDynamicEntryPosition(int index
) const
834 return this->Internal
->GetDynamicEntryPosition(index
);
842 //----------------------------------------------------------------------------
843 bool cmELF::ReadBytes(unsigned long pos
, unsigned long size
, char* buf
) const
847 return this->Internal
->ReadBytes(pos
, size
, buf
);
855 //----------------------------------------------------------------------------
856 bool cmELF::GetSOName(std::string
& soname
)
858 if(StringEntry
const* se
= this->GetSOName())
869 //----------------------------------------------------------------------------
870 cmELF::StringEntry
const* cmELF::GetSOName()
873 this->Internal
->GetFileType() == cmELF::FileTypeSharedLibrary
)
875 return this->Internal
->GetSOName();
883 //----------------------------------------------------------------------------
884 cmELF::StringEntry
const* cmELF::GetRPath()
887 (this->Internal
->GetFileType() == cmELF::FileTypeExecutable
||
888 this->Internal
->GetFileType() == cmELF::FileTypeSharedLibrary
))
890 return this->Internal
->GetRPath();
898 //----------------------------------------------------------------------------
899 cmELF::StringEntry
const* cmELF::GetRunPath()
902 (this->Internal
->GetFileType() == cmELF::FileTypeExecutable
||
903 this->Internal
->GetFileType() == cmELF::FileTypeSharedLibrary
))
905 return this->Internal
->GetRunPath();
913 //----------------------------------------------------------------------------
914 void cmELF::PrintInfo(std::ostream
& os
) const
918 this->Internal
->PrintInfo(os
);
922 os
<< "Not a valid ELF file.\n";