OSDN Git Service

[MIPS] Set DT_DEBUG dyntab entry if it is writable
authorChris Dearman <chris@mips.com>
Fri, 11 Jan 2013 23:32:20 +0000 (15:32 -0800)
committerElliott Hughes <enh@google.com>
Mon, 14 Jan 2013 17:30:25 +0000 (09:30 -0800)
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>
linker/linker.cpp
linker/linker_phdr.cpp
linker/linker_phdr.h

index 09f479f..74a246d 100755 (executable)
@@ -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 */
index 1990366..94260fa 100644 (file)
@@ -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;
index 2d4d735..d9a4820 100644 (file)
@@ -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 */