[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>
This commit is contained in:
Chris Dearman 2013-01-11 15:32:20 -08:00 committed by Elliott Hughes
parent 2c5153b043
commit cf23905a4b
3 changed files with 14 additions and 7 deletions

View File

@ -1511,8 +1511,9 @@ static bool soinfo_link_image(soinfo* si) {
/* Extract dynamic section */ /* Extract dynamic section */
size_t dynamic_count; size_t dynamic_count;
Elf32_Word dynamic_flags;
phdr_table_get_dynamic_section(phdr, phnum, base, &si->dynamic, phdr_table_get_dynamic_section(phdr, phnum, base, &si->dynamic,
&dynamic_count); &dynamic_count, &dynamic_flags);
if (si->dynamic == NULL) { if (si->dynamic == NULL) {
if (!relocating_linker) { if (!relocating_linker) {
DL_ERR("missing PT_DYNAMIC in \"%s\"", si->name); 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); si->plt_got = (unsigned *)(base + *d);
break; break;
case DT_DEBUG: case DT_DEBUG:
#if !defined(ANDROID_MIPS_LINKER)
// Set the DT_DEBUG entry to the address of _r_debug for GDB // Set the DT_DEBUG entry to the address of _r_debug for GDB
*d = (int) &_r_debug; // if the dynamic table is writable
#endif if (dynamic_flags & PF_W)
*d = (int) &_r_debug;
break; break;
case DT_RELA: case DT_RELA:
DL_ERR("unsupported DT_RELA in \"%s\"", si->name); 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 *phdr =
(Elf32_Phdr *)((unsigned char *) linker_base + elf_hdr->e_phoff); (Elf32_Phdr *)((unsigned char *) linker_base + elf_hdr->e_phoff);
phdr_table_get_dynamic_section(phdr, elf_hdr->e_phnum, linker_base, 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); insert_soinfo_into_debug_map(&linker_soinfo);
/* extract information passed from the kernel */ /* extract information passed from the kernel */

View File

@ -542,6 +542,7 @@ phdr_table_get_arm_exidx(const Elf32_Phdr* phdr_table,
* Output: * Output:
* dynamic -> address of table in memory (NULL on failure). * dynamic -> address of table in memory (NULL on failure).
* dynamic_count -> number of items in table (0 on failure). * dynamic_count -> number of items in table (0 on failure).
* dynamic_flags -> protection flags for section (unset on failure)
* Return: * Return:
* void * void
*/ */
@ -550,7 +551,8 @@ phdr_table_get_dynamic_section(const Elf32_Phdr* phdr_table,
int phdr_count, int phdr_count,
Elf32_Addr load_bias, Elf32_Addr load_bias,
Elf32_Addr** dynamic, 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 = phdr_table;
const Elf32_Phdr* phdr_limit = phdr + phdr_count; 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) { if (dynamic_count) {
*dynamic_count = (unsigned)(phdr->p_memsz / 8); *dynamic_count = (unsigned)(phdr->p_memsz / 8);
} }
if (dynamic_flags) {
*dynamic_flags = phdr->p_flags;
}
return; return;
} }
*dynamic = NULL; *dynamic = NULL;

View File

@ -99,6 +99,7 @@ phdr_table_get_dynamic_section(const Elf32_Phdr* phdr_table,
int phdr_count, int phdr_count,
Elf32_Addr load_bias, Elf32_Addr load_bias,
Elf32_Addr** dynamic, Elf32_Addr** dynamic,
size_t* dynamic_count); size_t* dynamic_count,
Elf32_Word* dynamic_flags);
#endif /* LINKER_PHDR_H */ #endif /* LINKER_PHDR_H */