Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F154443488
D34446.id103739.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D34446.id103739.diff
View Options
diff --git a/sys/arm64/arm64/elf_machdep.c b/sys/arm64/arm64/elf_machdep.c
--- a/sys/arm64/arm64/elf_machdep.c
+++ b/sys/arm64/arm64/elf_machdep.c
@@ -143,25 +143,9 @@
ELF_REGSET(regset_arm64_addr_mask);
void
-elf64_dump_thread(struct thread *td, void *dst, size_t *off)
+elf64_dump_thread(struct thread *td __unused, void *dst __unused,
+ size_t *off __unused)
{
- struct arm64_addr_mask addr_mask;
- size_t len, mask_size;
-
- len = 0;
- if (dst != NULL) {
- mask_size = sizeof(addr_mask);
- get_arm64_addr_mask(®set_arm64_addr_mask, td, &addr_mask,
- &mask_size);
-
- len += elf64_populate_note(NT_ARM_ADDR_MASK, &addr_mask, dst,
- sizeof(addr_mask), NULL);
- } else {
- len += elf64_populate_note(NT_ARM_ADDR_MASK, NULL, NULL,
- sizeof(addr_mask), NULL);
- }
-
- *off += len;
}
bool
diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c
--- a/sys/kern/imgact_elf.c
+++ b/sys/kern/imgact_elf.c
@@ -102,6 +102,8 @@
uint32_t *fctl0);
static vm_prot_t __elfN(trans_prot)(Elf_Word);
static Elf_Word __elfN(untrans_prot)(vm_prot_t);
+static size_t __elfN(prepare_register_notes)(struct thread *td,
+ struct note_info_list *list, struct thread *target_td);
SYSCTL_NODE(_kern, OID_AUTO, __CONCAT(elf, __ELF_WORD_SIZE),
CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
@@ -1519,6 +1521,7 @@
struct note_info {
int type; /* Note type. */
+ struct regset *regset; /* Register set. */
outfunc_t outfunc; /* Output function. */
void *outarg; /* Argument for the output function. */
size_t outsize; /* Output size. */
@@ -1538,9 +1541,7 @@
struct note_info_list *, size_t, int);
static void __elfN(putnote)(struct thread *td, struct note_info *, struct sbuf *);
-static void __elfN(note_fpregset)(void *, struct sbuf *, size_t *);
static void __elfN(note_prpsinfo)(void *, struct sbuf *, size_t *);
-static void __elfN(note_prstatus)(void *, struct sbuf *, size_t *);
static void __elfN(note_threadmd)(void *, struct sbuf *, size_t *);
static void __elfN(note_thrmisc)(void *, struct sbuf *, size_t *);
static void __elfN(note_ptlwpinfo)(void *, struct sbuf *, size_t *);
@@ -1833,7 +1834,8 @@
p = td->td_proc;
size = 0;
- size += __elfN(register_note)(td, list, NT_PRPSINFO, __elfN(note_prpsinfo), p);
+ size += __elfN(register_note)(td, list, NT_PRPSINFO,
+ __elfN(note_prpsinfo), p);
/*
* To have the debugger select the right thread (LWP) as the initial
@@ -1843,10 +1845,7 @@
*/
thr = td;
while (thr != NULL) {
- size += __elfN(register_note)(td, list, NT_PRSTATUS,
- __elfN(note_prstatus), thr);
- size += __elfN(register_note)(td, list, NT_FPREGSET,
- __elfN(note_fpregset), thr);
+ size += __elfN(prepare_register_notes)(td, list, thr);
size += __elfN(register_note)(td, list, NT_THRMISC,
__elfN(note_thrmisc), thr);
size += __elfN(register_note)(td, list, NT_PTLWPINFO,
@@ -1968,6 +1967,34 @@
each_dumpable_segment(td, cb_put_phdr, &phc, flags);
}
+static size_t
+__elfN(register_regset_note)(struct thread *td, struct note_info_list *list,
+ struct regset *regset, struct thread *target_td)
+{
+ const struct sysentvec *sv;
+ struct note_info *ninfo;
+ size_t size, notesize;
+
+ size = 0;
+ if (!regset->get(regset, target_td, NULL, &size) || size == 0)
+ return (0);
+
+ ninfo = malloc(sizeof(*ninfo), M_TEMP, M_ZERO | M_WAITOK);
+ ninfo->type = regset->note;
+ ninfo->regset = regset;
+ ninfo->outarg = target_td;
+ ninfo->outsize = size;
+ TAILQ_INSERT_TAIL(list, ninfo, link);
+
+ sv = td->td_proc->p_sysent;
+ notesize = sizeof(Elf_Note) + /* note header */
+ roundup2(strlen(sv->sv_elf_core_abi_vendor) + 1, ELF_NOTE_ROUNDSIZE) +
+ /* note name */
+ roundup2(size, ELF_NOTE_ROUNDSIZE); /* note description */
+
+ return (notesize);
+}
+
size_t
__elfN(register_note)(struct thread *td, struct note_info_list *list,
int type, outfunc_t out, void *arg)
@@ -2066,7 +2093,16 @@
if (note.n_descsz == 0)
return;
sbuf_start_section(sb, &old_len);
- ninfo->outfunc(ninfo->outarg, sb, &ninfo->outsize);
+ if (ninfo->regset != NULL) {
+ struct regset *regset = ninfo->regset;
+ void *buf;
+
+ buf = malloc(ninfo->outsize, M_TEMP, M_ZERO | M_WAITOK);
+ (void)regset->get(regset, ninfo->outarg, buf, &ninfo->outsize);
+ sbuf_bcat(sb, buf, ninfo->outsize);
+ free(buf, M_TEMP);
+ } else
+ ninfo->outfunc(ninfo->outarg, sb, &ninfo->outsize);
sect_len = sbuf_end_section(sb, old_len, ELF_NOTE_ROUNDSIZE, 0);
if (sect_len < 0)
return;
@@ -2237,24 +2273,6 @@
};
ELF_REGSET(__elfN(regset_prstatus));
-static void
-__elfN(note_prstatus)(void *arg, struct sbuf *sb, size_t *sizep)
-{
- struct thread *td;
- elf_prstatus_t *status;
-
- td = arg;
- if (sb != NULL) {
- KASSERT(*sizep == sizeof(*status), ("%s: invalid size",
- __func__));
- status = malloc(sizeof(*status), M_TEMP, M_ZERO | M_WAITOK);
- __elfN(get_prstatus)(NULL, td, status, sizep);
- sbuf_bcat(sb, status, sizeof(*status));
- free(status, M_TEMP);
- }
- *sizep = sizeof(*status);
-}
-
static bool
__elfN(get_fpregset)(struct regset *rs, struct thread *td, void *buf,
size_t *sizep)
@@ -2299,21 +2317,37 @@
};
ELF_REGSET(__elfN(regset_fpregset));
-static void
-__elfN(note_fpregset)(void *arg, struct sbuf *sb, size_t *sizep)
+static size_t
+__elfN(prepare_register_notes)(struct thread *td, struct note_info_list *list,
+ struct thread *target_td)
{
- struct thread *td;
- elf_prfpregset_t *fpregset;
+ struct sysentvec *sv = td->td_proc->p_sysent;
+ struct regset **regsetp, **regset_end, *regset;
+ size_t size;
- td = arg;
- if (sb != NULL) {
- KASSERT(*sizep == sizeof(*fpregset), ("invalid size"));
- fpregset = malloc(sizeof(*fpregset), M_TEMP, M_ZERO | M_WAITOK);
- __elfN(get_fpregset)(NULL, td, fpregset, sizep);
- sbuf_bcat(sb, fpregset, sizeof(*fpregset));
- free(fpregset, M_TEMP);
+ size = 0;
+
+ /* NT_PRSTATUS must be the first register set note. */
+ size += __elfN(register_regset_note)(td, list, &__elfN(regset_prstatus),
+ target_td);
+
+ regsetp = sv->sv_regset_begin;
+ if (regsetp == NULL) {
+ /* XXX: This shouldn't be true for any FreeBSD ABIs. */
+ size += __elfN(register_regset_note)(td, list,
+ &__elfN(regset_fpregset), target_td);
+ return (size);
}
- *sizep = sizeof(*fpregset);
+ regset_end = sv->sv_regset_end;
+ MPASS(regset_end != NULL);
+ for (; regsetp < regset_end; regsetp++) {
+ regset = *regsetp;
+ if (regset->note == NT_PRSTATUS)
+ continue;
+ size += __elfN(register_regset_note)(td, list, regset,
+ target_td);
+ }
+ return (size);
}
static void
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Apr 29, 2:34 PM (1 h, 46 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
32259135
Default Alt Text
D34446.id103739.diff (6 KB)
Attached To
Mode
D34446: Store core dump notes for all valid register sets for FreeBSD processes.
Attached
Detach File
Event Timeline
Log In to Comment