diff options
author | Aleksandar Ristovski <aristovski@qnx.com> | 2011-10-18 14:00:42 +0000 |
---|---|---|
committer | Aleksandar Ristovski <aristovski@qnx.com> | 2011-10-18 14:00:42 +0000 |
commit | 4313697959ffcaf3bf59556ef690914d0d7b84c3 (patch) | |
tree | 05e96c58735795e00e46f434bbba79056646090c /gdb/solib-svr4.c | |
parent | 9b0f109b0a400247d9c001cb815572e03cedb7f0 (diff) | |
download | gdb-4313697959ffcaf3bf59556ef690914d0d7b84c3.zip gdb-4313697959ffcaf3bf59556ef690914d0d7b84c3.tar.gz gdb-4313697959ffcaf3bf59556ef690914d0d7b84c3.tar.bz2 |
* solib-svr4.c (read_program_header): New variables pt_phdr, pt_phdr_p,
initialize them from target PT_PHDR p_vaddr, relocate sect_addr by
pt_phdr if PT_PHDR was found.
* gdb.base/attach-pie-noexec.c: New files.
* gdb.base/attach-pie-noexec.exp: New files.
Diffstat (limited to 'gdb/solib-svr4.c')
-rw-r--r-- | gdb/solib-svr4.c | 43 |
1 files changed, 38 insertions, 5 deletions
diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c index 2bb31a9..85bf27e 100644 --- a/gdb/solib-svr4.c +++ b/gdb/solib-svr4.c @@ -364,10 +364,11 @@ static gdb_byte * read_program_header (int type, int *p_sect_size, int *p_arch_size) { enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch); - CORE_ADDR at_phdr, at_phent, at_phnum; + CORE_ADDR at_phdr, at_phent, at_phnum, pt_phdr = 0; int arch_size, sect_size; CORE_ADDR sect_addr; gdb_byte *buf; + int pt_phdr_p = 0; /* Get required auxv elements from target. */ if (target_auxv_search (¤t_target, AT_PHDR, &at_phdr) <= 0) @@ -401,12 +402,23 @@ read_program_header (int type, int *p_sect_size, int *p_arch_size) /* Search for requested PHDR. */ for (i = 0; i < at_phnum; i++) { + int p_type; + if (target_read_memory (at_phdr + i * sizeof (phdr), (gdb_byte *)&phdr, sizeof (phdr))) return 0; - if (extract_unsigned_integer ((gdb_byte *)phdr.p_type, - 4, byte_order) == type) + p_type = extract_unsigned_integer ((gdb_byte *) phdr.p_type, + 4, byte_order); + + if (p_type == PT_PHDR) + { + pt_phdr_p = 1; + pt_phdr = extract_unsigned_integer ((gdb_byte *) phdr.p_vaddr, + 4, byte_order); + } + + if (p_type == type) break; } @@ -427,12 +439,23 @@ read_program_header (int type, int *p_sect_size, int *p_arch_size) /* Search for requested PHDR. */ for (i = 0; i < at_phnum; i++) { + int p_type; + if (target_read_memory (at_phdr + i * sizeof (phdr), (gdb_byte *)&phdr, sizeof (phdr))) return 0; - if (extract_unsigned_integer ((gdb_byte *)phdr.p_type, - 4, byte_order) == type) + p_type = extract_unsigned_integer ((gdb_byte *) phdr.p_type, + 4, byte_order); + + if (p_type == PT_PHDR) + { + pt_phdr_p = 1; + pt_phdr = extract_unsigned_integer ((gdb_byte *) phdr.p_vaddr, + 8, byte_order); + } + + if (p_type == type) break; } @@ -446,6 +469,16 @@ read_program_header (int type, int *p_sect_size, int *p_arch_size) 8, byte_order); } + /* PT_PHDR is optional, but we really need it + for PIE to make this work in general. */ + + if (pt_phdr_p) + { + /* at_phdr is real address in memory. pt_phdr is what pheader says it is. + Relocation offset is the difference between the two. */ + sect_addr = sect_addr + (at_phdr - pt_phdr); + } + /* Read in requested program header. */ buf = xmalloc (sect_size); if (target_read_memory (sect_addr, buf, sect_size)) |