Skip to content

Commit

Permalink
[MIPS] Backport from master branch for reading PID from a core
Browse files Browse the repository at this point in the history
This includes:
	-BFD: Write Linux core PRSTATUS note into MIPS core file
	-BFD: Extract PID from MIPS core dump file
	-Add test for fetching TLS from core file

On MIPS o32, n32 and n64 platforms information such as PID was not
correctly written into core file from GDB.

In addition, on MIPS o32, n32 and n64 platforms, PID information was not
correctly propagated from core dump file to internal GDB
structures.  This patch fixes that behavior.
A correct PID is needed by `libthread_db' library supplied with
glibc repository revisions before commit c579f48edba8 ("Remove
cached PID/TID in clone") or released versions before 2.25 for
GDB to fetch value of TLS variable from core file.

Those patches are develped by myself and accepted by community.
  • Loading branch information
djolertrk authored and djtodoro committed Mar 9, 2019
1 parent c4e3d7a commit 6d486af
Show file tree
Hide file tree
Showing 6 changed files with 232 additions and 0 deletions.
46 changes: 46 additions & 0 deletions bfd/elf32-mips.c
Original file line number Diff line number Diff line change
Expand Up @@ -2353,6 +2353,8 @@ elf32_mips_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
return FALSE;

case 128: /* Linux/MIPS elf_prpsinfo */
elf_tdata (abfd)->core->pid
= bfd_get_32 (abfd, note->descdata + 16);
elf_tdata (abfd)->core->program
= _bfd_elfcore_strndup (abfd, note->descdata + 32, 16);
elf_tdata (abfd)->core->command
Expand All @@ -2373,6 +2375,45 @@ elf32_mips_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)

return TRUE;
}

/* Write Linux core PRSTATUS note into core file. */

static char *
elf32_mips_write_core_note (bfd *abfd, char *buf, int *bufsiz, int note_type,
...)
{
switch (note_type)
{
default:
return NULL;

case NT_PRPSINFO:
BFD_FAIL ();
return NULL;

case NT_PRSTATUS:
{
char data[256];
va_list ap;
long pid;
int cursig;
const void *greg;

va_start (ap, note_type);
memset (data, 0, 72);
pid = va_arg (ap, long);
bfd_put_32 (abfd, pid, data + 24);
cursig = va_arg (ap, int);
bfd_put_16 (abfd, cursig, data + 12);
greg = va_arg (ap, const void *);
memcpy (data + 72, greg, 180);
memset (data + 252, 0, 4);
va_end (ap);
return elfcore_write_note (abfd, buf, bufsiz,
"CORE", note_type, data, sizeof (data));
}
}
}

/* Depending on the target vector we generate some version of Irix
executables or "normal" MIPS ELF ABI executables. */
Expand Down Expand Up @@ -2554,6 +2595,9 @@ static const struct ecoff_debug_swap mips_elf32_ecoff_debug_swap = {
#define ELF_COMMONPAGESIZE 0x1000
#define elf32_bed elf32_tradbed

#undef elf_backend_write_core_note
#define elf_backend_write_core_note elf32_mips_write_core_note

/* Include the target file again for this target. */
#include "elf32-target.h"

Expand All @@ -2575,6 +2619,8 @@ static const struct ecoff_debug_swap mips_elf32_ecoff_debug_swap = {
#undef elf32_bed
#define elf32_bed elf32_fbsd_tradbed

#undef elf_backend_write_core_note

#include "elf32-target.h"
/* Implement elf_backend_final_write_processing for VxWorks. */

Expand Down
46 changes: 46 additions & 0 deletions bfd/elf64-mips.c
Original file line number Diff line number Diff line change
Expand Up @@ -4308,6 +4308,8 @@ elf64_mips_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
return FALSE;

case 136: /* Linux/MIPS - N64 kernel elf_prpsinfo */
elf_tdata (abfd)->core->pid
= bfd_get_32 (abfd, note->descdata + 24);
elf_tdata (abfd)->core->program
= _bfd_elfcore_strndup (abfd, note->descdata + 40, 16);
elf_tdata (abfd)->core->command
Expand All @@ -4328,6 +4330,45 @@ elf64_mips_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)

return TRUE;
}

/* Write Linux core PRSTATUS note into core file. */

static char *
elf64_mips_write_core_note (bfd *abfd, char *buf, int *bufsiz, int note_type,
...)
{
switch (note_type)
{
default:
return NULL;

case NT_PRPSINFO:
BFD_FAIL ();
return NULL;

case NT_PRSTATUS:
{
char data[480];
va_list ap;
long pid;
int cursig;
const void *greg;

va_start (ap, note_type);
memset (data, 0, 112);
pid = va_arg (ap, long);
bfd_put_32 (abfd, pid, data + 32);
cursig = va_arg (ap, int);
bfd_put_16 (abfd, cursig, data + 12);
greg = va_arg (ap, const void *);
memcpy (data + 112, greg, 360);
memset (data + 472, 0, 8);
va_end (ap);
return elfcore_write_note (abfd, buf, bufsiz,
"CORE", note_type, data, sizeof (data));
}
}
}

/* ECOFF swapping routines. These are used when dealing with the
.mdebug section, which is in the ECOFF debugging format. */
Expand Down Expand Up @@ -4538,6 +4579,9 @@ const struct elf_size_info mips_elf64_size_info =
#define ELF_COMMONPAGESIZE 0x1000
#define elf64_bed elf64_tradbed

#undef elf_backend_write_core_note
#define elf_backend_write_core_note elf64_mips_write_core_note

/* Include the target file again for this target. */
#include "elf64-target.h"

Expand All @@ -4560,4 +4604,6 @@ const struct elf_size_info mips_elf64_size_info =
#undef elf64_bed
#define elf64_bed elf64_fbsd_tradbed

#undef elf64_mips_write_core_note

#include "elf64-target.h"
46 changes: 46 additions & 0 deletions bfd/elfn32-mips.c
Original file line number Diff line number Diff line change
Expand Up @@ -3558,6 +3558,8 @@ elf32_mips_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
return FALSE;

case 128: /* Linux/MIPS elf_prpsinfo */
elf_tdata (abfd)->core->pid
= bfd_get_32 (abfd, note->descdata + 16);
elf_tdata (abfd)->core->program
= _bfd_elfcore_strndup (abfd, note->descdata + 32, 16);
elf_tdata (abfd)->core->command
Expand Down Expand Up @@ -3590,6 +3592,45 @@ elf_n32_mips_irix_compat (bfd *abfd)
else
return ict_none;
}

/* Write Linux core PRSTATUS note into core file. */

static char *
elf32_mips_write_core_note (bfd *abfd, char *buf, int *bufsiz, int note_type,
...)
{
switch (note_type)
{
default:
return NULL;

case NT_PRPSINFO:
BFD_FAIL ();
return NULL;

case NT_PRSTATUS:
{
char data[440];
va_list ap;
long pid;
int cursig;
const void *greg;

va_start (ap, note_type);
memset (data, 0, 72);
pid = va_arg (ap, long);
bfd_put_32 (abfd, pid, data + 24);
cursig = va_arg (ap, int);
bfd_put_16 (abfd, cursig, data + 12);
greg = va_arg (ap, const void *);
memcpy (data + 72, greg, 360);
memset (data + 432, 0, 8);
va_end (ap);
return elfcore_write_note (abfd, buf, bufsiz,
"CORE", note_type, data, sizeof (data));
}
}
}

/* ECOFF swapping routines. These are used when dealing with the
.mdebug section, which is in the ECOFF debugging format. */
Expand Down Expand Up @@ -3753,6 +3794,9 @@ static const struct ecoff_debug_swap mips_elf32_ecoff_debug_swap = {
#define ELF_COMMONPAGESIZE 0x1000
#define elf32_bed elf32_tradbed

#undef elf_backend_write_core_note
#define elf_backend_write_core_note elf32_mips_write_core_note

/* Include the target file again for this target. */
#include "elf32-target.h"

Expand All @@ -3775,4 +3819,6 @@ static const struct ecoff_debug_swap mips_elf32_ecoff_debug_swap = {
#undef elf32_bed
#define elf32_bed elf32_fbsd_tradbed

#undef elf_backend_write_core_note

#include "elf32-target.h"
1 change: 1 addition & 0 deletions bfd/elfxx-mips.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "elf/common.h"
#include "elf/internal.h"
#include "elf/mips.h"
#include <stdarg.h>

extern bfd_boolean _bfd_mips_elf_mkobject
(bfd *);
Expand Down
37 changes: 37 additions & 0 deletions gdb/testsuite/gdb.threads/tls-core.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/* This test is part of GDB, the GNU debugger.
Copyright 2017 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */

#include <pthread.h>

int __thread foo = 0xdeadbeef;

static void *
thread_proc (void *arg)
{
return arg;
}

int
main (void)
{
pthread_t thread;

pthread_create (&thread, NULL, thread_proc, NULL);
pthread_join (thread, NULL);

return 0;
}
56 changes: 56 additions & 0 deletions gdb/testsuite/gdb.threads/tls-core.exp
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Copyright 2017 Free Software Foundation, Inc.

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

standard_testfile

if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" \
executable { debug }] != "" } {
return -1
}


clean_restart ${binfile}

runto thread_proc

#
# Generate corefile.
#
set corefile [standard_output_file gcore.test]
set core_supported [gdb_gcore_cmd "$corefile" "save a corefile"]
if {!$core_supported} {
return 0
}

#
# Restart gdb and load generated corefile.
#
clean_restart ${binfile}

set core_loaded [gdb_core_cmd "$corefile" "load generated corefile"]
if { $core_loaded != 1 } {
# No use proceeding from here.
return 0
}

# This fails in cross-debugging due to the use of native `libthread_db'.
if {![string match $host_triplet $target_triplet]} {
setup_kfail "threads/22381" "*-*-*"
}
gdb_test "p/x foo" \
"\\$\[0-9]+ = 0xdeadbeef" \
"print thread-local storage variable"

gdb_exit

0 comments on commit 6d486af

Please sign in to comment.