@@ -1645,6 +1645,7 @@ typedef struct elf64_shdr {
#define NT_TASKSTRUCT 4
#define NT_AUXV 6
#define NT_PRXFPREG 0x46e62b7f /* copied from
gdb5.1/include/elf/common.h */
+#define NT_FILE 0x46494c45 /* copied from
gdb/include/elf/common.h */
#define NT_S390_GS_CB 0x30b /* s390 guarded storage registers
*/
#define NT_S390_VXRS_HIGH 0x30a /* s390 vector registers 16-31 */
#define NT_S390_VXRS_LOW 0x309 /* s390 vector registers 0-15
(lower half) */
@@ -3317,6 +3317,13 @@ struct target_elf_prpsinfo {
char pr_psargs[ELF_PRARGSZ]; /* initial part of arg list */
};
+struct target_ntfile_entry {
+ abi_ulong vm_start;
+ abi_ulong vm_end;
+ abi_ulong page_offset;
+ char *path;
+};
+
/* Here is the structure in which status of each thread is captured. */
struct elf_thread_status {
QTAILQ_ENTRY(elf_thread_status) ets_link;
@@ -3677,6 +3684,84 @@ static void fill_auxv_note(struct memelfnote *note,
const TaskState *ts)
}
}
+static void fill_ntfile_note(struct memelfnote *note, TaskState *ts)
+{
+ GSList *map_info = read_self_maps();
+ GSList *s;
+ int count = 0;
+ int data_size = sizeof(abi_long)*2; // reserve space for num_map_entry
and page_size
+ struct target_ntfile_entry *entries = NULL;
+
+ // grab memory mapping first
+ for (s = map_info; s; s = g_slist_next(s)) {
+ MapInfo *e = (MapInfo *) s->data;
+
+ if (h2g_valid(e->start)) {
+ unsigned long min = e->start;
+ unsigned long max = e->end;
+ int flags = page_get_flags(h2g(min));
+ const char *path;
+
+ max = h2g_valid(max - 1) ?
+ max : (uintptr_t) g2h(GUEST_ADDR_MAX) + 1;
+
+ if (page_check_range(h2g(min), max - min, flags) == -1) {
+ continue;
+ }
+
+ if (h2g(min) == ts->info->stack_limit) {
+ path = "[stack]";
+ } else {
+ path = e->path;
+ }
+
+ count++;
+ entries = realloc(entries, sizeof(struct
target_ntfile_entry)*count);
+ struct target_ntfile_entry *entry = &entries[count-1];
+ memset(entry, 0, sizeof(*entry));
+
+ data_size += sizeof(abi_long)*3 + strlen(path) + 1;
+ entry->vm_start = h2g(min);
+ entry->vm_end = h2g(max - 1) + 1;
+ entry->page_offset = e->offset;
+ entry->path = strdup(path);
+ }
+ }
+
+ // prepare the memory mapping in NT_FILE format
+ char *ptr;
+ int idx = 0;
+ ptr = (char *)g_malloc0(data_size);
+ abi_long *long_ptr = (abi_long *)ptr;
+
+ // memory mappings
+ long_ptr[idx++] = count; // number of map entries
+ long_ptr[idx++] = TARGET_PAGE_SIZE; // target page size
+ for(int i=0; i<count; i++) {
+ struct target_ntfile_entry *entry = &entries[i];
+ long_ptr[idx++] = entry->vm_start;
+ long_ptr[idx++] = entry->vm_end;
+ long_ptr[idx++] = entry->page_offset;
+ }
+
+ // path names
+ idx *= sizeof(abi_long);
+ for(int i=0; i<count; i++) {
+ struct target_ntfile_entry *entry = &entries[i];
+ int path_size = strlen(entry->path);
+ strcpy(&ptr[idx], entry->path);
+ idx += path_size + 1;
+ free(entry->path);
+ }
+
+ // write it out
+ fill_note(note, "CORE", NT_FILE, data_size, ptr);
+
+ // cleanup
+ free(entries);
+ free_self_maps(map_info);
+}
+