summaryrefslogtreecommitdiffstats
path: root/linker
diff options
context:
space:
mode:
authorChris Dearman <chris@mips.com>2013-01-11 15:32:20 -0800
committerElliott Hughes <enh@google.com>2013-01-14 09:30:25 -0800
commitcf23905a4bcc7bfdd109be5b6d69ad06877aa217 (patch)
tree76f72d3b20ea41a0ba60daa9dd1bd7a3d3acffc1 /linker
parent2c5153b043b44e9935a334ae9b2d5a4bc5258b40 (diff)
downloadbionic-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-xlinker/linker.cpp11
-rw-r--r--linker/linker_phdr.cpp7
-rw-r--r--linker/linker_phdr.h3
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 */