Fix gdb could not get shared library list issue

Get dynamic flags from phdr table's correct entry rather the first
entry, so that the following DT_DEBUG entry can be set.

Also fix the undefined reference to LoadTask::deleter issue under gcc
-O0 option.

Bug: 17524778

(cherry picked from commit e93be99da0614ff38cbf8b2bb0624ff1dc79b8d0)

Change-Id: I347792dab25c7b19c3fc690e03d20899ce1e26e0
This commit is contained in:
Ningsheng Jian 2014-09-16 15:22:10 +08:00 committed by Dmitriy Ivanov
parent 1cd0c6777f
commit 04f5f4100c
3 changed files with 14 additions and 6 deletions

View File

@ -666,6 +666,8 @@ class LoadTask {
DISALLOW_IMPLICIT_CONSTRUCTORS(LoadTask);
};
LoadTask::deleter_t LoadTask::deleter;
template <typename T>
using linked_list_t = LinkedList<T, TypeBasedAllocator<LinkedListEntry<T>>>;
@ -1868,7 +1870,9 @@ static int nullify_closed_stdio() {
}
bool soinfo::PrelinkImage() {
phdr_table_get_dynamic_section(phdr, phnum, load_bias, &dynamic);
/* Extract dynamic section */
ElfW(Word) dynamic_flags = 0;
phdr_table_get_dynamic_section(phdr, phnum, load_bias, &dynamic, &dynamic_flags);
/* We can't log anything until the linker is relocated */
bool relocating_linker = (flags & FLAG_LINKER) != 0;
@ -1877,8 +1881,6 @@ bool soinfo::PrelinkImage() {
DEBUG("si->base = %p si->flags = 0x%08x", reinterpret_cast<void*>(base), flags);
}
/* Extract dynamic section */
ElfW(Word) dynamic_flags = phdr->p_flags;
if (dynamic == nullptr) {
if (!relocating_linker) {
DL_ERR("missing PT_DYNAMIC in \"%s\"", name);
@ -2240,7 +2242,7 @@ static void init_linker_info_for_gdb(ElfW(Addr) linker_base) {
ElfW(Ehdr)* elf_hdr = reinterpret_cast<ElfW(Ehdr)*>(linker_base);
ElfW(Phdr)* phdr = reinterpret_cast<ElfW(Phdr)*>(linker_base + elf_hdr->e_phoff);
phdr_table_get_dynamic_section(phdr, elf_hdr->e_phnum, linker_base,
&linker_soinfo_for_gdb.dynamic);
&linker_soinfo_for_gdb.dynamic, nullptr);
insert_soinfo_into_debug_map(&linker_soinfo_for_gdb);
}

View File

@ -702,15 +702,20 @@ int phdr_table_get_arm_exidx(const ElfW(Phdr)* phdr_table, size_t phdr_count,
* load_bias -> load bias
* Output:
* dynamic -> address of table in memory (null on failure).
* dynamic_flags -> protection flags for section (unset on failure)
* Return:
* void
*/
void phdr_table_get_dynamic_section(const ElfW(Phdr)* phdr_table, size_t phdr_count,
ElfW(Addr) load_bias, ElfW(Dyn)** dynamic) {
ElfW(Addr) load_bias, ElfW(Dyn)** dynamic,
ElfW(Word)* dynamic_flags) {
*dynamic = nullptr;
for (const ElfW(Phdr)* phdr = phdr_table, *phdr_limit = phdr + phdr_count; phdr < phdr_limit; phdr++) {
if (phdr->p_type == PT_DYNAMIC) {
*dynamic = reinterpret_cast<ElfW(Dyn)*>(load_bias + phdr->p_vaddr);
if (dynamic_flags) {
*dynamic_flags = phdr->p_flags;
}
return;
}
}

View File

@ -101,6 +101,7 @@ int phdr_table_get_arm_exidx(const ElfW(Phdr)* phdr_table, size_t phdr_count, El
#endif
void phdr_table_get_dynamic_section(const ElfW(Phdr)* phdr_table, size_t phdr_count,
ElfW(Addr) load_bias, ElfW(Dyn)** dynamic);
ElfW(Addr) load_bias, ElfW(Dyn)** dynamic,
ElfW(Word)* dynamic_flags);
#endif /* LINKER_PHDR_H */