mirror of
https://github.com/freebsd/freebsd-src
synced 2024-09-06 17:18:32 +00:00
Add extended segment support to gcore
A follow-up to r303099, D7255. Basically, apply the exact same change, with the exact same rationale, to gcore. gcore's elfcore.c is largely a clone of the kernel imgact_elf coredump facility. Reviewed by: emaste (earlier version, not substantially different) Requested by: jhb Sponsored by: EMC / Isilon Storage Division Differential Revision: https://reviews.freebsd.org/D7265
This commit is contained in:
parent
56e807d918
commit
bd0371c964
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=303114
|
@ -213,6 +213,8 @@ elf_coredump(int efd __unused, int fd, pid_t pid)
|
|||
*/
|
||||
sb = sbuf_new_auto();
|
||||
hdrsize = sizeof(Elf_Ehdr) + sizeof(Elf_Phdr) * (1 + seginfo.count);
|
||||
if (seginfo.count + 1 >= PN_XNUM)
|
||||
hdrsize += sizeof(Elf_Shdr);
|
||||
/* Start header + notes section. */
|
||||
sbuf_start_section(sb, NULL);
|
||||
/* Make empty header subsection. */
|
||||
|
@ -423,10 +425,10 @@ elf_puthdr(pid_t pid, vm_map_entry_t map, void *hdr, size_t hdrsize,
|
|||
{
|
||||
Elf_Ehdr *ehdr;
|
||||
Elf_Phdr *phdr;
|
||||
Elf_Shdr *shdr;
|
||||
struct phdr_closure phc;
|
||||
|
||||
ehdr = (Elf_Ehdr *)hdr;
|
||||
phdr = (Elf_Phdr *)((char *)hdr + sizeof(Elf_Ehdr));
|
||||
|
||||
ehdr->e_ident[EI_MAG0] = ELFMAG0;
|
||||
ehdr->e_ident[EI_MAG1] = ELFMAG1;
|
||||
|
@ -446,14 +448,40 @@ elf_puthdr(pid_t pid, vm_map_entry_t map, void *hdr, size_t hdrsize,
|
|||
ehdr->e_flags = 0;
|
||||
ehdr->e_ehsize = sizeof(Elf_Ehdr);
|
||||
ehdr->e_phentsize = sizeof(Elf_Phdr);
|
||||
ehdr->e_phnum = numsegs + 1;
|
||||
ehdr->e_shentsize = sizeof(Elf_Shdr);
|
||||
ehdr->e_shnum = 0;
|
||||
ehdr->e_shstrndx = SHN_UNDEF;
|
||||
if (numsegs + 1 < PN_XNUM) {
|
||||
ehdr->e_phnum = numsegs + 1;
|
||||
ehdr->e_shnum = 0;
|
||||
} else {
|
||||
ehdr->e_phnum = PN_XNUM;
|
||||
ehdr->e_shnum = 1;
|
||||
|
||||
ehdr->e_shoff = ehdr->e_phoff +
|
||||
(numsegs + 1) * ehdr->e_phentsize;
|
||||
|
||||
shdr = (Elf_Shdr *)((char *)hdr + ehdr->e_shoff);
|
||||
memset(shdr, 0, sizeof(*shdr));
|
||||
/*
|
||||
* A special first section is used to hold large segment and
|
||||
* section counts. This was proposed by Sun Microsystems in
|
||||
* Solaris and has been adopted by Linux; the standard ELF
|
||||
* tools are already familiar with the technique.
|
||||
*
|
||||
* See table 7-7 of the Solaris "Linker and Libraries Guide"
|
||||
* (or 12-7 depending on the version of the document) for more
|
||||
* details.
|
||||
*/
|
||||
shdr->sh_type = SHT_NULL;
|
||||
shdr->sh_size = ehdr->e_shnum;
|
||||
shdr->sh_link = ehdr->e_shstrndx;
|
||||
shdr->sh_info = numsegs + 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fill in the program header entries.
|
||||
*/
|
||||
phdr = (Elf_Phdr *)((char *)hdr + ehdr->e_phoff);
|
||||
|
||||
/* The note segement. */
|
||||
phdr->p_type = PT_NOTE;
|
||||
|
|
Loading…
Reference in a new issue