am 4a9fd609: Revert "Update all mapoff checks to check against 0."
* commit '4a9fd609328bb843b31d96bd8b3041eff4538ca6':
Revert "Update all mapoff checks to check against 0."
diff --git a/include/dwarf.h b/include/dwarf.h
index 72804d2..3665e00 100644
--- a/include/dwarf.h
+++ b/include/dwarf.h
@@ -411,7 +411,8 @@
/* ANDROID support update. */
extern int dwarf_find_unwind_table (struct elf_dyn_info *edi, struct elf_image *ei,
unw_addr_space_t as, char *path,
- unw_word_t segbase, unw_word_t ip);
+ unw_word_t segbase, unw_word_t mapoff,
+ unw_word_t ip);
/* End of ANDROID update. */
extern void dwarf_put_unwind_info (unw_addr_space_t as,
unw_proc_info_t *pi, void *arg);
diff --git a/include/tdep-aarch64/libunwind_i.h b/include/tdep-aarch64/libunwind_i.h
index 62a5b58..0690b1b 100644
--- a/include/tdep-aarch64/libunwind_i.h
+++ b/include/tdep-aarch64/libunwind_i.h
@@ -304,7 +304,8 @@
/* ANDROID support update. */
extern int tdep_get_elf_image (unw_addr_space_t as, struct elf_image *ei,
pid_t pid, unw_word_t ip,
- unsigned long *segbase, char **path, void *as_arg);
+ unsigned long *segbase, unsigned long *mapoff,
+ char **path, void *as_arg);
/* End of ANDROID update. */
extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg,
unw_word_t *valp, int write);
diff --git a/include/tdep-arm/libunwind_i.h b/include/tdep-arm/libunwind_i.h
index fc2bd0d..d782cc4 100644
--- a/include/tdep-arm/libunwind_i.h
+++ b/include/tdep-arm/libunwind_i.h
@@ -297,7 +297,8 @@
/* ANDROID support update. */
extern int tdep_get_elf_image (unw_addr_space_t as, struct elf_image *ei,
pid_t pid, unw_word_t ip,
- unsigned long *segbase, char **path, void *as_arg);
+ unsigned long *segbase, unsigned long *mapoff,
+ char **path, void *as_arg);
/* End of ANDROID update. */
extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg,
unw_word_t *valp, int write);
diff --git a/include/tdep-mips/libunwind_i.h b/include/tdep-mips/libunwind_i.h
index de3918d..41cc83f 100644
--- a/include/tdep-mips/libunwind_i.h
+++ b/include/tdep-mips/libunwind_i.h
@@ -343,7 +343,8 @@
/* ANDROID support update. */
extern int tdep_get_elf_image (unw_addr_space_t as, struct elf_image *ei,
pid_t pid, unw_word_t ip,
- unsigned long *segbase, char **path, void *as_arg);
+ unsigned long *segbase, unsigned long *mapoff,
+ char **path, void *as_arg);
/* End of ANDROID update. */
extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg,
unw_word_t *valp, int write);
diff --git a/include/tdep-x86/libunwind_i.h b/include/tdep-x86/libunwind_i.h
index e532441..f87bd71 100644
--- a/include/tdep-x86/libunwind_i.h
+++ b/include/tdep-x86/libunwind_i.h
@@ -291,7 +291,8 @@
/* ANDROID support update. */
extern int tdep_get_elf_image (unw_addr_space_t as, struct elf_image *ei,
pid_t pid, unw_word_t ip,
- unsigned long *segbase, char **path, void *as_arg);
+ unsigned long *segbase, unsigned long *mapoff,
+ char **path, void *as_arg);
/* End of ANDROID update. */
extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg,
unw_word_t *valp, int write);
diff --git a/include/tdep-x86_64/libunwind_i.h b/include/tdep-x86_64/libunwind_i.h
index 1be9363..184989e 100644
--- a/include/tdep-x86_64/libunwind_i.h
+++ b/include/tdep-x86_64/libunwind_i.h
@@ -237,7 +237,8 @@
/* ANDROID support update. */
extern int tdep_get_elf_image (unw_addr_space_t as, struct elf_image *ei,
pid_t pid, unw_word_t ip,
- unsigned long *segbase, char **path, void *as_arg);
+ unsigned long *segbase, unsigned long *mapoff,
+ char **path, void *as_arg);
/* End of ANDROID update. */
extern int tdep_access_reg (struct cursor *c, unw_regnum_t reg,
unw_word_t *valp, int write);
diff --git a/src/Los-common.c b/src/Los-common.c
index e8e2171..6341545 100644
--- a/src/Los-common.c
+++ b/src/Los-common.c
@@ -164,7 +164,7 @@
PROTECTED int
local_get_elf_image (unw_addr_space_t as, struct elf_image *ei, unw_word_t ip,
- unsigned long *segbase, char **path, void *as_arg)
+ unsigned long *segbase, unsigned long *mapoff, char **path, void *as_arg)
{
struct map_info *map;
intrmask_t saved_mask;
@@ -186,6 +186,7 @@
{
*ei = map->ei;
*segbase = map->start;
+ *mapoff = map->offset;
if (path != NULL)
{
if (map->path)
diff --git a/src/dwarf/Gfind_unwind_table.c b/src/dwarf/Gfind_unwind_table.c
index 1703cef..9de3ad5 100644
--- a/src/dwarf/Gfind_unwind_table.c
+++ b/src/dwarf/Gfind_unwind_table.c
@@ -125,7 +125,7 @@
static bool dwarf_find_unwind_table_memory (
struct elf_dyn_info *edi, struct elf_image *ei, unw_addr_space_t as, char *path,
- unw_word_t segbase, unw_word_t ip) {
+ unw_word_t segbase, unw_word_t mapoff, unw_word_t ip) {
Elf_W(Ehdr) ehdr;
GET_EHDR_FIELD(ei, &ehdr, e_phoff, false);
GET_EHDR_FIELD(ei, &ehdr, e_phnum, false);
@@ -157,13 +157,7 @@
}
GET_PHDR_FIELD(ei, offset, &phdr, p_offset);
- /* Always use zero as the map offset to match. The dlopen of a shared
- * library from an APK will result in a non-zero offset so it won't
- * match anything and cause unwinds to fail. There is no case where
- * the ANDROID linker will create an executable map that has a non-zero
- * map offset.
- */
- if (phdr.p_offset == 0) {
+ if (phdr.p_offset == mapoff) {
txt_phdr_offset = offset;
txt_pvaddr = phdr.p_vaddr;
}
@@ -244,7 +238,7 @@
int
dwarf_find_unwind_table (struct elf_dyn_info *edi, struct elf_image *ei,
unw_addr_space_t as, char *path,
- unw_word_t segbase, unw_word_t ip)
+ unw_word_t segbase, unw_word_t mapoff, unw_word_t ip)
{
Elf_W(Phdr) *phdr, *ptxt = NULL, *peh_hdr = NULL, *pdyn = NULL;
unw_word_t addr, eh_frame_start, fde_count, load_base;
@@ -269,7 +263,7 @@
return -UNW_ENOINFO;
if (!ei->mapped) {
- if (dwarf_find_unwind_table_memory (edi, ei, as, path, segbase, ip)) {
+ if (dwarf_find_unwind_table_memory (edi, ei, as, path, segbase, mapoff, ip)) {
return 1;
}
return -UNW_ENOINFO;
@@ -291,13 +285,7 @@
if (phdr[i].p_vaddr + phdr[i].p_memsz > end_ip)
end_ip = phdr[i].p_vaddr + phdr[i].p_memsz;
- /* Always use zero as the map offset to match. The dlopen of a shared
- * library from an APK will result in a non-zero offset so it won't
- * match anything and cause unwinds to fail. There is no case where
- * the ANDROID linker will create an executable map that has a non-zero
- * map offset.
- */
- if (phdr[i].p_offset == 0)
+ if (phdr[i].p_offset == mapoff)
ptxt = phdr + i;
#if 0
diff --git a/src/elfxx.c b/src/elfxx.c
index 50d5266..6676d0c 100644
--- a/src/elfxx.c
+++ b/src/elfxx.c
@@ -245,7 +245,8 @@
}
static bool elf_w (get_load_offset_memory) (
- struct elf_image* ei, unsigned long segbase, Elf_W(Ehdr)* ehdr, Elf_W(Addr)* load_offset) {
+ struct elf_image* ei, unsigned long segbase, unsigned long mapoff,
+ Elf_W(Ehdr)* ehdr, Elf_W(Addr)* load_offset) {
GET_EHDR_FIELD(ei, ehdr, e_phoff, true);
GET_EHDR_FIELD(ei, ehdr, e_phnum, true);
@@ -256,13 +257,7 @@
GET_PHDR_FIELD(ei, offset, &phdr, p_type);
if (phdr.p_type == PT_LOAD) {
GET_PHDR_FIELD(ei, offset, &phdr, p_offset);
- /* Always use zero as the map offset to match. The dlopen of a shared
- * library from an APK will result in a non-zero offset so it won't
- * match anything and cause unwinds to fail. There is no case where
- * the ANDROID linker will create an executable map that has a non-zero
- * map offset.
- */
- if (phdr.p_offset == 0) {
+ if (phdr.p_offset == mapoff) {
GET_PHDR_FIELD(ei, offset, &phdr, p_vaddr);
*load_offset = segbase - phdr.p_vaddr;
return true;
@@ -392,19 +387,13 @@
}
static bool elf_w (get_load_offset_mapped) (
- struct elf_image *ei, unsigned long segbase, Elf_W(Addr)* load_offset) {
+ struct elf_image *ei, unsigned long segbase, unsigned long mapoff, Elf_W(Addr)* load_offset) {
Elf_W(Ehdr) *ehdr = ei->u.mapped.image;
Elf_W(Phdr) *phdr = (Elf_W(Phdr) *) ((char *) ei->u.mapped.image + ehdr->e_phoff);
int i;
for (i = 0; i < ehdr->e_phnum; ++i) {
- /* Always use zero as the map offset to match. The dlopen of a shared
- * library from an APK will result in a non-zero offset so it won't
- * match anything and cause unwinds to fail. There is no case where
- * the ANDROID linker will create an executable map that has a non-zero
- * map offset.
- */
- if (phdr[i].p_type == PT_LOAD && phdr[i].p_offset == 0) {
+ if (phdr[i].p_type == PT_LOAD && phdr[i].p_offset == mapoff) {
*load_offset = segbase - phdr[i].p_vaddr;
return true;
}
@@ -436,11 +425,12 @@
}
static bool elf_w (get_load_offset) (
- struct elf_image* ei, unsigned long segbase, Elf_W(Ehdr)* ehdr, Elf_W(Addr)* load_offset) {
+ struct elf_image* ei, unsigned long segbase, unsigned long mapoff,
+ Elf_W(Ehdr)* ehdr, Elf_W(Addr)* load_offset) {
if (ei->mapped) {
- return elf_w (get_load_offset_mapped) (ei, segbase, load_offset);
+ return elf_w (get_load_offset_mapped) (ei, segbase, mapoff, load_offset);
} else {
- return elf_w (get_load_offset_memory) (ei, segbase, ehdr, load_offset);
+ return elf_w (get_load_offset_memory) (ei, segbase, mapoff, ehdr, load_offset);
}
}
@@ -561,12 +551,12 @@
// Find the ELF image that contains IP and return the procedure name from
// the symbol table that matches the IP.
HIDDEN bool elf_w (get_proc_name_in_image) (
- unw_addr_space_t as, struct elf_image* ei, unsigned long segbase,
+ unw_addr_space_t as, struct elf_image* ei, unsigned long segbase, unsigned long mapoff,
unw_word_t ip, char* buf, size_t buf_len, unw_word_t* offp) {
Elf_W(Ehdr) ehdr;
memset(&ehdr, 0, sizeof(ehdr));
Elf_W(Addr) load_offset;
- if (!elf_w (get_load_offset) (ei, segbase, &ehdr, &load_offset)) {
+ if (!elf_w (get_load_offset) (ei, segbase, mapoff, &ehdr, &load_offset)) {
return false;
}
@@ -578,7 +568,7 @@
// the MiniDebugInfo.
struct elf_image mdi;
if (elf_w (extract_minidebuginfo) (ei, &mdi, &ehdr)) {
- if (!elf_w (get_load_offset) (&mdi, segbase, &ehdr, &load_offset)) {
+ if (!elf_w (get_load_offset) (&mdi, segbase, mapoff, &ehdr, &load_offset)) {
return false;
}
if (elf_w (lookup_symbol) (as, ip, &mdi, load_offset, buf, buf_len, offp, &ehdr)) {
@@ -593,17 +583,17 @@
HIDDEN bool elf_w (get_proc_name) (
unw_addr_space_t as, pid_t pid, unw_word_t ip, char* buf, size_t buf_len,
unw_word_t* offp, void* as_arg) {
- unsigned long segbase;
+ unsigned long segbase, mapoff;
struct elf_image ei;
- if (tdep_get_elf_image(as, &ei, pid, ip, &segbase, NULL, as_arg) < 0) {
+ if (tdep_get_elf_image(as, &ei, pid, ip, &segbase, &mapoff, NULL, as_arg) < 0) {
return false;
}
- return elf_w (get_proc_name_in_image) (as, &ei, segbase, ip, buf, buf_len, offp);
+ return elf_w (get_proc_name_in_image) (as, &ei, segbase, mapoff, ip, buf, buf_len, offp);
}
-HIDDEN bool elf_w (get_load_base) (struct elf_image* ei, unw_word_t* load_base) {
+HIDDEN bool elf_w (get_load_base) (struct elf_image* ei, unw_word_t mapoff, unw_word_t* load_base) {
if (!ei->valid) {
return false;
}
@@ -613,13 +603,7 @@
Elf_W(Phdr)* phdr = (Elf_W(Phdr)*) ((char*) ei->u.mapped.image + ehdr->e_phoff);
int i;
for (i = 0; i < ehdr->e_phnum; ++i) {
- /* Always use zero as the map offset to match. The dlopen of a shared
- * library from an APK will result in a non-zero offset so it won't
- * match anything and cause unwinds to fail. There is no case where
- * the ANDROID linker will create an executable map that has a non-zero
- * map offset.
- */
- if (phdr[i].p_type == PT_LOAD && phdr[i].p_offset == 0) {
+ if (phdr[i].p_type == PT_LOAD && phdr[i].p_offset == mapoff) {
*load_base = phdr[i].p_vaddr;
return true;
}
@@ -635,13 +619,7 @@
Elf_W(Phdr) phdr;
GET_PHDR_FIELD(ei, offset, &phdr, p_type);
GET_PHDR_FIELD(ei, offset, &phdr, p_offset);
- /* Always use zero as the map offset to match. The dlopen of a shared
- * library from an APK will result in a non-zero offset so it won't
- * match anything and cause unwinds to fail. There is no case where
- * the ANDROID linker will create an executable map that has a non-zero
- * map offset.
- */
- if (phdr.p_type == PT_LOAD && phdr.p_offset == 0) {
+ if (phdr.p_type == PT_LOAD && phdr.p_offset == mapoff) {
GET_PHDR_FIELD(ei, offset, &phdr, p_vaddr);
*load_base = phdr.p_vaddr;
return true;
diff --git a/src/elfxx.h b/src/elfxx.h
index 9c5e699..e0343b4 100644
--- a/src/elfxx.h
+++ b/src/elfxx.h
@@ -76,9 +76,9 @@
extern bool elf_w (get_proc_name_in_image) (
unw_addr_space_t as, struct elf_image* ei, unsigned long segbase,
- unw_word_t ip, char* buf, size_t buf_len, unw_word_t* offp);
+ unsigned long mapoff, unw_word_t ip, char* buf, size_t buf_len, unw_word_t* offp);
-extern bool elf_w (get_load_base) (struct elf_image* ei, unw_word_t* load_base);
+extern bool elf_w (get_load_base) (struct elf_image* ei, unw_word_t mapoff, unw_word_t* load_base);
extern size_t elf_w (memory_read) (
struct elf_image* ei, unw_word_t addr, uint8_t* buffer, size_t bytes, bool string_read);
@@ -166,7 +166,7 @@
}
}
unw_word_t load_base;
- if (map->ei.valid && elf_w (get_load_base) (&map->ei, &load_base)) {
+ if (map->ei.valid && elf_w (get_load_base) (&map->ei, map->offset, &load_base)) {
map->load_base = load_base;
}
}
diff --git a/src/os-common.c b/src/os-common.c
index 6b23e9b..8f32af9 100644
--- a/src/os-common.c
+++ b/src/os-common.c
@@ -27,17 +27,19 @@
#include "map_info.h"
extern int local_get_elf_image (unw_addr_space_t as, struct elf_image *,
- unw_word_t, unsigned long *, char **, void *);
+ unw_word_t, unsigned long *, unsigned long *,
+ char **, void *);
PROTECTED int
tdep_get_elf_image (unw_addr_space_t as, struct elf_image *ei,
- pid_t pid, unw_word_t ip, unsigned long *segbase,
- char **path, void *as_arg)
+ pid_t pid, unw_word_t ip,
+ unsigned long *segbase, unsigned long *mapoff, char **path,
+ void *as_arg)
{
struct map_info *map;
if (pid == getpid())
- return local_get_elf_image (as, ei, ip, segbase, path, as_arg);
+ return local_get_elf_image (as, ei, ip, segbase, mapoff, path, as_arg);
map = map_find_from_addr (as->map_list, ip);
if (!map)
@@ -48,6 +50,7 @@
*ei = map->ei;
*segbase = map->start;
+ *mapoff = map->offset;
if (path != NULL)
{
*path = strdup (map->path);
diff --git a/src/os-linux.c b/src/os-linux.c
index eac3f04..f65c98a 100644
--- a/src/os-linux.c
+++ b/src/os-linux.c
@@ -86,7 +86,7 @@
&& elf_map_image (&ei, cur_map->path))
{
unw_word_t load_base;
- if (elf_w (get_load_base) (&ei, &load_base))
+ if (elf_w (get_load_base) (&ei, offset, &load_base))
cur_map->load_base = load_base;
munmap (ei.u.mapped.image, ei.u.mapped.size);
}
@@ -127,7 +127,7 @@
ei.u.memory.as_arg = as_arg;
ei.valid = elf_w (valid_object_memory) (&ei);
unw_word_t load_base;
- if (ei.valid && elf_w (get_load_base) (&ei, &load_base))
+ if (ei.valid && elf_w (get_load_base) (&ei, cur_map->offset, &load_base))
cur_map->load_base = load_base;
}
}
diff --git a/src/ptrace/_UPT_find_proc_info.c b/src/ptrace/_UPT_find_proc_info.c
index bbd800e..acaa5f9 100644
--- a/src/ptrace/_UPT_find_proc_info.c
+++ b/src/ptrace/_UPT_find_proc_info.c
@@ -63,10 +63,10 @@
invalidate_edi(edi);
/* ANDROID support update. */
- if (tdep_get_elf_image (as, &ei, pid, ip, &segbase, &path, as_arg) < 0)
+ if (tdep_get_elf_image (as, &ei, pid, ip, &segbase, &mapoff, &path, as_arg) < 0)
return -UNW_ENOINFO;
- ret = tdep_find_unwind_table (edi, &ei, as, path, segbase, ip);
+ ret = tdep_find_unwind_table (edi, &ei, as, path, segbase, mapoff, ip);
free(path);
if (ret < 0)
return ret;