44
44
#include " llvm/Support/MathExtras.h"
45
45
#include " llvm/Support/MemoryBuffer.h"
46
46
#include " llvm/Support/MipsABIFlags.h"
47
- #include " lldb/Target/Process.h"
48
47
49
48
#define CASE_AND_STREAM (s, def, width ) \
50
49
case def: \
@@ -3008,10 +3007,9 @@ void ObjectFileELF::ParseSymtab(Symtab &lldb_symtab) {
3008
3007
// section, nomatter if .symtab was already parsed or not. This is because
3009
3008
// minidebuginfo normally removes the .symtab symbols which have their
3010
3009
// matching .dynsym counterparts.
3011
- Section *dynsym = nullptr ;
3012
3010
if (!symtab ||
3013
3011
GetSectionList ()->FindSectionByName (ConstString (" .gnu_debugdata" ))) {
3014
- dynsym =
3012
+ Section * dynsym =
3015
3013
section_list->FindSectionByType (eSectionTypeELFDynamicSymbols, true )
3016
3014
.get ();
3017
3015
if (dynsym) {
@@ -3021,20 +3019,6 @@ void ObjectFileELF::ParseSymtab(Symtab &lldb_symtab) {
3021
3019
m_address_class_map.merge (address_class_map);
3022
3020
}
3023
3021
}
3024
- if (!dynsym) {
3025
- // Try and read the dynamic symbol table from the .dynamic section.
3026
- uint32_t num_symbols = 0 ;
3027
- std::optional<DataExtractor> symtab_data =
3028
- GetDynsymDataFromDynamic (num_symbols);
3029
- std::optional<DataExtractor> strtab_data = GetDynstrData ();
3030
- if (symtab_data && strtab_data) {
3031
- auto [num_symbols_parsed, address_class_map] =
3032
- ParseSymbols (&lldb_symtab, symbol_id, section_list, num_symbols,
3033
- symtab_data.value (), strtab_data.value ());
3034
- symbol_id += num_symbols_parsed;
3035
- m_address_class_map.merge (address_class_map);
3036
- }
3037
- }
3038
3022
3039
3023
// DT_JMPREL
3040
3024
// If present, this entry's d_ptr member holds the address of
@@ -3844,33 +3828,6 @@ ObjectFileELF::MapFileDataWritable(const FileSpec &file, uint64_t Size,
3844
3828
Offset);
3845
3829
}
3846
3830
3847
- std::optional<DataExtractor>
3848
- ObjectFileELF::ReadDataFromDynamic (const ELFDynamic *dyn, uint64_t length,
3849
- uint64_t offset) {
3850
- // ELFDynamic values contain a "d_ptr" member that will be a load address if
3851
- // we have an ELF file read from memory, or it will be a file address if it
3852
- // was read from a ELF file. This function will correctly fetch data pointed
3853
- // to by the ELFDynamic::d_ptr, or return std::nullopt if the data isn't
3854
- // available.
3855
- const lldb::addr_t d_ptr_addr = dyn->d_ptr + offset;
3856
- if (ProcessSP process_sp = m_process_wp.lock ()) {
3857
- if (DataBufferSP data_sp = ReadMemory (process_sp, d_ptr_addr, length))
3858
- return DataExtractor (data_sp, GetByteOrder (), GetAddressByteSize ());
3859
- } else {
3860
- // We have an ELF file with no section headers or we didn't find the
3861
- // .dynamic section. Try and find the .dynstr section.
3862
- Address addr;
3863
- if (!addr.ResolveAddressUsingFileSections (d_ptr_addr, GetSectionList ()))
3864
- return std::nullopt;
3865
- DataExtractor data;
3866
- addr.GetSection ()->GetSectionData (data);
3867
- return DataExtractor (data,
3868
- d_ptr_addr - addr.GetSection ()->GetFileAddress (),
3869
- length);
3870
- }
3871
- return std::nullopt;
3872
- }
3873
-
3874
3831
std::optional<DataExtractor> ObjectFileELF::GetDynstrData () {
3875
3832
if (SectionList *section_list = GetSectionList ()) {
3876
3833
// Find the SHT_DYNAMIC section.
@@ -3898,15 +3855,31 @@ std::optional<DataExtractor> ObjectFileELF::GetDynstrData() {
3898
3855
// and represent the dynamic symbol tables's string table. These are needed
3899
3856
// by the dynamic loader and we can read them from a process' address space.
3900
3857
//
3901
- // When loading and ELF file from memory, only the program headers are
3902
- // guaranteed end up being mapped into memory, and we can find these values in
3903
- // the PT_DYNAMIC segment.
3858
+ // When loading and ELF file from memory, only the program headers end up
3859
+ // being mapped into memory, and we can find these values in the PT_DYNAMIC
3860
+ // segment.
3904
3861
const ELFDynamic *strtab = FindDynamicSymbol (DT_STRTAB);
3905
3862
const ELFDynamic *strsz = FindDynamicSymbol (DT_STRSZ);
3906
3863
if (strtab == nullptr || strsz == nullptr )
3907
3864
return std::nullopt;
3908
3865
3909
- return ReadDataFromDynamic (strtab, strsz->d_val , /* offset=*/ 0 );
3866
+ if (ProcessSP process_sp = m_process_wp.lock ()) {
3867
+ if (DataBufferSP data_sp =
3868
+ ReadMemory (process_sp, strtab->d_ptr , strsz->d_val ))
3869
+ return DataExtractor (data_sp, GetByteOrder (), GetAddressByteSize ());
3870
+ } else {
3871
+ // We have an ELF file with no section headers or we didn't find the
3872
+ // .dynamic section. Try and find the .dynstr section.
3873
+ Address addr;
3874
+ if (addr.ResolveAddressUsingFileSections (strtab->d_ptr , GetSectionList ())) {
3875
+ DataExtractor data;
3876
+ addr.GetSection ()->GetSectionData (data);
3877
+ return DataExtractor (data,
3878
+ strtab->d_ptr - addr.GetSection ()->GetFileAddress (),
3879
+ strsz->d_val );
3880
+ }
3881
+ }
3882
+ return std::nullopt;
3910
3883
}
3911
3884
3912
3885
std::optional<lldb_private::DataExtractor> ObjectFileELF::GetDynamicData () {
@@ -3939,116 +3912,3 @@ std::optional<lldb_private::DataExtractor> ObjectFileELF::GetDynamicData() {
3939
3912
}
3940
3913
return std::nullopt;
3941
3914
}
3942
-
3943
- std::optional<uint32_t > ObjectFileELF::GetNumSymbolsFromDynamicHash () {
3944
- const ELFDynamic *hash = FindDynamicSymbol (DT_HASH);
3945
- if (hash == nullptr )
3946
- return std::nullopt;
3947
-
3948
- // The DT_HASH header looks like this:
3949
- struct DtHashHeader {
3950
- uint32_t nbucket;
3951
- uint32_t nchain;
3952
- };
3953
- if (auto data = ReadDataFromDynamic (hash, 8 )) {
3954
- // We don't need the number of buckets value "nbucket", we just need the
3955
- // "nchain" value which contains the number of symbols.
3956
- offset_t offset = offsetof (DtHashHeader, nchain);
3957
- return data->GetU32 (&offset);
3958
- }
3959
-
3960
- return std::nullopt;
3961
- }
3962
-
3963
- std::optional<uint32_t > ObjectFileELF::GetNumSymbolsFromDynamicGnuHash () {
3964
- const ELFDynamic *gnu_hash = FindDynamicSymbol (DT_GNU_HASH);
3965
- if (gnu_hash == nullptr )
3966
- return std::nullopt;
3967
-
3968
- // Create a DT_GNU_HASH header
3969
- // https://flapenguin.me/elf-dt-gnu-hash
3970
- struct DtGnuHashHeader {
3971
- uint32_t nbuckets = 0 ;
3972
- uint32_t symoffset = 0 ;
3973
- uint32_t bloom_size = 0 ;
3974
- uint32_t bloom_shift = 0 ;
3975
- };
3976
- uint32_t num_symbols = 0 ;
3977
- // Read enogh data for the DT_GNU_HASH header so we can extract the values.
3978
- if (auto data = ReadDataFromDynamic (gnu_hash, sizeof (DtGnuHashHeader))) {
3979
- offset_t offset = 0 ;
3980
- DtGnuHashHeader header;
3981
- header.nbuckets = data->GetU32 (&offset);
3982
- header.symoffset = data->GetU32 (&offset);
3983
- header.bloom_size = data->GetU32 (&offset);
3984
- header.bloom_shift = data->GetU32 (&offset);
3985
- const size_t addr_size = GetAddressByteSize ();
3986
- const addr_t buckets_offset =
3987
- sizeof (DtGnuHashHeader) + addr_size * header.bloom_size ;
3988
- std::vector<uint32_t > buckets;
3989
- if (auto bucket_data = ReadDataFromDynamic (gnu_hash, header.nbuckets * 4 , buckets_offset)) {
3990
- offset = 0 ;
3991
- for (uint32_t i = 0 ; i < header.nbuckets ; ++i)
3992
- buckets.push_back (bucket_data->GetU32 (&offset));
3993
- // Locate the chain that handles the largest index bucket.
3994
- uint32_t last_symbol = 0 ;
3995
- for (uint32_t bucket_value : buckets)
3996
- last_symbol = std::max (bucket_value, last_symbol);
3997
- if (last_symbol < header.symoffset ) {
3998
- num_symbols = header.symoffset ;
3999
- } else {
4000
- // Walk the bucket's chain to add the chain length to the total.
4001
- const addr_t chains_base_offset = buckets_offset + header.nbuckets * 4 ;
4002
- for (;;) {
4003
- if (auto chain_entry_data = ReadDataFromDynamic (gnu_hash, 4 , chains_base_offset + (last_symbol - header.symoffset ) * 4 )) {
4004
- offset = 0 ;
4005
- uint32_t chain_entry = chain_entry_data->GetU32 (&offset);
4006
- ++last_symbol;
4007
- // If the low bit is set, this entry is the end of the chain.
4008
- if (chain_entry & 1 )
4009
- break ;
4010
- } else {
4011
- break ;
4012
- }
4013
- }
4014
- num_symbols = last_symbol;
4015
- }
4016
- }
4017
- }
4018
- if (num_symbols > 0 )
4019
- return num_symbols;
4020
-
4021
- return std::nullopt;
4022
- }
4023
-
4024
- std::optional<DataExtractor>
4025
- ObjectFileELF::GetDynsymDataFromDynamic (uint32_t &num_symbols) {
4026
- // Every ELF file which represents an executable or shared library has
4027
- // mandatory .dynamic entries. The DT_SYMTAB value contains a pointer to the
4028
- // symbol table, and DT_SYMENT contains the size of a symbol table entry.
4029
- // We then can use either the DT_HASH or DT_GNU_HASH to find the number of
4030
- // symbols in the symbol table as the symbol count is not stored in the
4031
- // .dynamic section as a key/value pair.
4032
- //
4033
- // When loading and ELF file from memory, only the program headers end up
4034
- // being mapped into memory, and we can find these values in the PT_DYNAMIC
4035
- // segment.
4036
- num_symbols = 0 ;
4037
- // Get the process in case this is an in memory ELF file.
4038
- ProcessSP process_sp (m_process_wp.lock ());
4039
- const ELFDynamic *symtab = FindDynamicSymbol (DT_SYMTAB);
4040
- const ELFDynamic *syment = FindDynamicSymbol (DT_SYMENT);
4041
- // DT_SYMTAB and DT_SYMENT are mandatory.
4042
- if (symtab == nullptr || syment == nullptr )
4043
- return std::nullopt;
4044
-
4045
- if (std::optional<uint32_t > syms = GetNumSymbolsFromDynamicHash ())
4046
- num_symbols = *syms;
4047
- else if (std::optional<uint32_t > syms = GetNumSymbolsFromDynamicGnuHash ())
4048
- num_symbols = *syms;
4049
- else
4050
- return std::nullopt;
4051
- if (num_symbols == 0 )
4052
- return std::nullopt;
4053
- return ReadDataFromDynamic (symtab, syment->d_val * num_symbols);
4054
- }
0 commit comments