diff options
author | Chris Dearman <chris@mips.com> | 2013-01-11 15:32:20 -0800 |
---|---|---|
committer | Elliott Hughes <enh@google.com> | 2013-01-14 09:30:25 -0800 |
commit | cf23905a4bcc7bfdd109be5b6d69ad06877aa217 (patch) | |
tree | 76f72d3b20ea41a0ba60daa9dd1bd7a3d3acffc1 /linker | |
parent | 2c5153b043b44e9935a334ae9b2d5a4bc5258b40 (diff) | |
download | bionic-cf23905a4bcc7bfdd109be5b6d69ad06877aa217.tar.gz bionic-cf23905a4bcc7bfdd109be5b6d69ad06877aa217.tar.bz2 bionic-cf23905a4bcc7bfdd109be5b6d69ad06877aa217.zip |
[MIPS] Set DT_DEBUG dyntab entry if it is writable
This is primarily for MIPS exutables that do not have a
DT_MIPS_RLD_MAP entry.
Change-Id: I4c221d92debcfed961eeee2515123f3fb21ec8e6
Signed-off-by: Chris Dearman <chris@mips.com>
Diffstat (limited to 'linker')
-rwxr-xr-x | linker/linker.cpp | 11 | ||||
-rw-r--r-- | linker/linker_phdr.cpp | 7 | ||||
-rw-r--r-- | linker/linker_phdr.h | 3 |
3 files changed, 14 insertions, 7 deletions
diff --git a/linker/linker.cpp b/linker/linker.cpp index 09f479fbb..74a246d0a 100755 --- a/linker/linker.cpp +++ b/linker/linker.cpp @@ -1511,8 +1511,9 @@ static bool soinfo_link_image(soinfo* si) { /* Extract dynamic section */ size_t dynamic_count; + Elf32_Word dynamic_flags; phdr_table_get_dynamic_section(phdr, phnum, base, &si->dynamic, - &dynamic_count); + &dynamic_count, &dynamic_flags); if (si->dynamic == NULL) { if (!relocating_linker) { DL_ERR("missing PT_DYNAMIC in \"%s\"", si->name); @@ -1568,10 +1569,10 @@ static bool soinfo_link_image(soinfo* si) { si->plt_got = (unsigned *)(base + *d); break; case DT_DEBUG: -#if !defined(ANDROID_MIPS_LINKER) // Set the DT_DEBUG entry to the address of _r_debug for GDB - *d = (int) &_r_debug; -#endif + // if the dynamic table is writable + if (dynamic_flags & PF_W) + *d = (int) &_r_debug; break; case DT_RELA: DL_ERR("unsupported DT_RELA in \"%s\"", si->name); @@ -1866,7 +1867,7 @@ static unsigned __linker_init_post_relocation(unsigned **elfdata, unsigned linke Elf32_Phdr *phdr = (Elf32_Phdr *)((unsigned char *) linker_base + elf_hdr->e_phoff); phdr_table_get_dynamic_section(phdr, elf_hdr->e_phnum, linker_base, - &linker_soinfo.dynamic, NULL); + &linker_soinfo.dynamic, NULL, NULL); insert_soinfo_into_debug_map(&linker_soinfo); /* extract information passed from the kernel */ diff --git a/linker/linker_phdr.cpp b/linker/linker_phdr.cpp index 199036645..94260fa9c 100644 --- a/linker/linker_phdr.cpp +++ b/linker/linker_phdr.cpp @@ -542,6 +542,7 @@ phdr_table_get_arm_exidx(const Elf32_Phdr* phdr_table, * Output: * dynamic -> address of table in memory (NULL on failure). * dynamic_count -> number of items in table (0 on failure). + * dynamic_flags -> protection flags for section (unset on failure) * Return: * void */ @@ -550,7 +551,8 @@ phdr_table_get_dynamic_section(const Elf32_Phdr* phdr_table, int phdr_count, Elf32_Addr load_bias, Elf32_Addr** dynamic, - size_t* dynamic_count) + size_t* dynamic_count, + Elf32_Word* dynamic_flags) { const Elf32_Phdr* phdr = phdr_table; const Elf32_Phdr* phdr_limit = phdr + phdr_count; @@ -564,6 +566,9 @@ phdr_table_get_dynamic_section(const Elf32_Phdr* phdr_table, if (dynamic_count) { *dynamic_count = (unsigned)(phdr->p_memsz / 8); } + if (dynamic_flags) { + *dynamic_flags = phdr->p_flags; + } return; } *dynamic = NULL; diff --git a/linker/linker_phdr.h b/linker/linker_phdr.h index 2d4d73544..d9a48208f 100644 --- a/linker/linker_phdr.h +++ b/linker/linker_phdr.h @@ -99,6 +99,7 @@ phdr_table_get_dynamic_section(const Elf32_Phdr* phdr_table, int phdr_count, Elf32_Addr load_bias, Elf32_Addr** dynamic, - size_t* dynamic_count); + size_t* dynamic_count, + Elf32_Word* dynamic_flags); #endif /* LINKER_PHDR_H */ |