diff options
author | Michael I. Bushnell <mib@gnu.org> | 1996-07-18 04:35:29 +0000 |
---|---|---|
committer | Michael I. Bushnell <mib@gnu.org> | 1996-07-18 04:35:29 +0000 |
commit | 94cef36797600d11a50d09828fa80df8a73dfd1c (patch) | |
tree | b7cba9afef95489eedef534d3e6946eb13f595ba /exec/elfcore.c | |
parent | 88dbbbf9e48e24f1ac007c1e4eeffd9caf8e2fad (diff) | |
download | hurd-94cef36797600d11a50d09828fa80df8a73dfd1c.tar.gz hurd-94cef36797600d11a50d09828fa80df8a73dfd1c.tar.bz2 hurd-94cef36797600d11a50d09828fa80df8a73dfd1c.zip |
*** empty log message ***
Diffstat (limited to 'exec/elfcore.c')
-rw-r--r-- | exec/elfcore.c | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/exec/elfcore.c b/exec/elfcore.c new file mode 100644 index 00000000..4388a135 --- /dev/null +++ b/exec/elfcore.c @@ -0,0 +1,100 @@ +{ + processor_set_name_t pset; + host_t host; + processor_set_basic_info_data_t pinfo; + + thread_t *threads; + size_t nthreads; + + vm_address_t addr; + vm_size_t size; + vm_prot_t prot, maxprot; + vm_inherit_t inherit; + boolean_t shared; + memory_object_name_t objname; + vm_offset_t offset; + + /* Figure out what flavor of machine the task is on. */ + if (err = task_get_assignment (task, &pset)) + goto lose; + err = processor_set_info (pset, PROCESSOR_SET_BASIC_INFO, &host, + &pinfo, PROCESSOR_SET_BASIC_INFO_COUNT); + mach_port_deallocate (mach_task_self (), pset); + if (err) + goto lose; + err = bfd_mach_host_arch_mach (host, &arch, &machine, &e_machine); + mach_port_deallocate (mach_task_self (), host); + if (err) + goto lose; + + if (err = task_threads (task, &threads, &nthreads)) + goto lose; + + /* Create a BFD section to describe each contiguous chunk + of the task's address space with the same stats. */ + sec = NULL; + addr = 0; + while (!vm_region (task, &addr, &size, &prot, &maxprot, + &inherit, &shared, &objname, &offset)) + { + mach_port_deallocate (mach_task_self (), objname); + + if (prot != VM_PROT_NONE) + { + flagword flags = SEC_NO_FLAGS; + + if (!(prot & VM_PROT_WRITE)) + flags |= SEC_READONLY; + if (!(prot & VM_PROT_EXECUTE)) + flags |= SEC_DATA; + + if (sec != NULL && + (vm_address_t) (bfd_section_vma (bfd, sec) + + bfd_section_size (bfd, sec)) == addr && + flags == (bfd_get_section_flags (bfd, sec) & + (SEC_READONLY|SEC_DATA))) + /* Coalesce with the previous section. */ + bfd_set_section_size (bfd, sec, + bfd_section_size (bfd, sec) + size); + else + { + /* Make a new section (which might grow by + the next region being coalesced onto it). */ + char *name = bfd_intuit_section_name (addr, size, &flags); + if (name == NULL) + { + /* No guess from BFD. */ + if (asprintf (&name, "[%p,%p) %c%c%c", + (void *) addr, (void *) (addr + size), + (prot & VM_PROT_READ) ? 'r' : '-', + (prot & VM_PROT_WRITE) ? 'w' : '-', + (prot & VM_PROT_EXECUTE) ? 'x' : '-') == -1) + goto lose; + } + sec = bfd_make_section (name); + bfd_set_section_flags (bfd, sec, flags); + bfd_set_section_vma (bfd, sec, addr); + bfd_set_section_size (bfd, sec, size); + } + } + } + + /* Write all the sections' data. */ + for (sec = bfd->sections; sec != NULL; sec = sec->next) + { + void *data; + err = vm_read (task, bfd_section_vma (bfd, sec), + bfd_section_size (bfd, sec), &data); + if (err) + /* XXX What to do? + 1. lose + 2. remove this section + 3. mark this section as having ungettable contents (how?) + */ + goto lose; + err = bfd_set_section_contents (bfd, sec, data, 0, + bfd_section_size (bfd, sec)); + vm_deallocate (mach_task_self (), data, bfd_section_size (bfd, sec)); + if (err) + goto bfdlose; + } |