Fix linker's _r_debug (gdb) info
* Initialize the exe's l_ld correctly, and initialize its l_addr field
earlier.
* Copy the phdr/phnum fields from the linker's temporary soinfo to its
final soinfo. This change ensures that dl_iterate_phdr shows the phdr
table for the linker.
* Change init_linker_info_for_gdb a little: use an soinfo's fields to
init the soinfo::link_map_head field, then reuse the new
init_link_map_head function to handle the linker and the executable.
Test: manual
Test: bionic-unit-tests
Bug: https://issuetracker.google.com/112627083
Bug: http://b/110967431
Change-Id: I40fad2c4d48f409347aaa1ccb98d96db89da1dfe
diff --git a/linker/dlfcn.cpp b/linker/dlfcn.cpp
index 4b84537..dfe8e8c 100644
--- a/linker/dlfcn.cpp
+++ b/linker/dlfcn.cpp
@@ -303,9 +303,7 @@
static soinfo* __libdl_info = nullptr;
// This is used by the dynamic linker. Every process gets these symbols for free.
-soinfo* get_libdl_info(const char* linker_path,
- const soinfo& linker_si,
- const link_map& linker_map) {
+soinfo* get_libdl_info(const char* linker_path, const soinfo& linker_si) {
CHECK((linker_si.flags_ & FLAG_GNU_HASH) != 0);
if (__libdl_info == nullptr) {
@@ -314,6 +312,8 @@
__libdl_info->strtab_ = linker_si.strtab_;
__libdl_info->symtab_ = linker_si.symtab_;
__libdl_info->load_bias = linker_si.load_bias;
+ __libdl_info->phdr = linker_si.phdr;
+ __libdl_info->phnum = linker_si.phnum;
__libdl_info->gnu_nbucket_ = linker_si.gnu_nbucket_;
__libdl_info->gnu_maskwords_ = linker_si.gnu_maskwords_;
@@ -328,9 +328,6 @@
__libdl_info->soname_ = linker_si.soname_;
__libdl_info->target_sdk_version_ = __ANDROID_API__;
__libdl_info->generate_handle();
- __libdl_info->link_map_head.l_addr = linker_map.l_addr;
- __libdl_info->link_map_head.l_name = linker_map.l_name;
- __libdl_info->link_map_head.l_ld = linker_map.l_ld;
#if defined(__work_around_b_24465209__)
strlcpy(__libdl_info->old_name_, __libdl_info->soname_, sizeof(__libdl_info->old_name_));
#endif