Handle VDSO section headers past end of page
When a VDSO gets large enough that it doesn't entirely fit in one page, but not so large that the part described by the program header exceeds one page, then gdb/BFD doesn't read the section headers and symbol table information. This patch cures that by passing the size of the vdso to BFD, and fixes a number of other issues in the BFD code. bfd/ * elfcode.h (bfd_from_remote_memory): Add "size" parameter. Consolidate code handling possible section headers past end of segment. Don't use p_align for page size guess, instead use minpagesize. Take note of ld.so clearing section headers when p_memsz > p_filesz. Handle file header specifying no section headers. Handle zero p_align throughout. Default loadbase to zero. Add comments. Rename contents_size to high_offset, and make it a bfd_vma. Delete unnecessary bfd_set_error calls. * bfd-in.h (bfd_elf_bfd_from_remote_memory): Update prototpe. * elf-bfd.h (struct elf_backend_data <elf_backend_from_remote_memory>): Likewise. (_bfd_elf32_bfd_from_remote_memory): Likewise. (_bfd_elf64_bfd_from_remote_memory): Likewise. * elf.c (bfd_elf_bfd_from_remote_memory): Adjust. * bfd-in2.h: Regnerate. gdb/ * symfile-mem.c (symbol_file_add_from_memory): Add size parameter. Pass to bfd_elf_bfd_from_remote_memory. Adjust all callers. (struct symbol_file_add_from_memory_args): Add size field. (find_vdso_size): New function. (add_vsyscall_page): Attempt to find vdso size.
This commit is contained in:
parent
cf2a3e9905
commit
5979d6b69b
8 changed files with 180 additions and 94 deletions
|
@ -1,3 +1,21 @@
|
|||
2014-04-02 Alan Modra <amodra@gmail.com>
|
||||
|
||||
* elfcode.h (bfd_from_remote_memory): Add "size" parameter.
|
||||
Consolidate code handling possible section headers past end of
|
||||
segment. Don't use p_align for page size guess, instead use
|
||||
minpagesize. Take note of ld.so clearing section headers when
|
||||
p_memsz > p_filesz. Handle file header specifying no section
|
||||
headers. Handle zero p_align throughout. Default loadbase to
|
||||
zero. Add comments. Rename contents_size to high_offset, and
|
||||
make it a bfd_vma. Delete unnecessary bfd_set_error calls.
|
||||
* bfd-in.h (bfd_elf_bfd_from_remote_memory): Update prototpe.
|
||||
* elf-bfd.h (struct elf_backend_data <elf_backend_from_remote_memory>):
|
||||
Likewise.
|
||||
(_bfd_elf32_bfd_from_remote_memory): Likewise.
|
||||
(_bfd_elf64_bfd_from_remote_memory): Likewise.
|
||||
* elf.c (bfd_elf_bfd_from_remote_memory): Adjust.
|
||||
* bfd-in2.h: Regnerate.
|
||||
|
||||
2014-04-01 Tristan Gingold <gingold@adacore.com>
|
||||
|
||||
* mach-o.c (bfd_mach_o_canonicalize_one_reloc): Avoid to crash
|
||||
|
|
24
bfd/bfd-in.h
24
bfd/bfd-in.h
|
@ -680,19 +680,21 @@ extern int bfd_get_elf_phdrs
|
|||
(bfd *abfd, void *phdrs);
|
||||
|
||||
/* Create a new BFD as if by bfd_openr. Rather than opening a file,
|
||||
reconstruct an ELF file by reading the segments out of remote memory
|
||||
based on the ELF file header at EHDR_VMA and the ELF program headers it
|
||||
points to. If not null, *LOADBASEP is filled in with the difference
|
||||
between the VMAs from which the segments were read, and the VMAs the
|
||||
file headers (and hence BFD's idea of each section's VMA) put them at.
|
||||
reconstruct an ELF file by reading the segments out of remote
|
||||
memory based on the ELF file header at EHDR_VMA and the ELF program
|
||||
headers it points to. If non-zero, SIZE is the known extent of the
|
||||
object. If not null, *LOADBASEP is filled in with the difference
|
||||
between the VMAs from which the segments were read, and the VMAs
|
||||
the file headers (and hence BFD's idea of each section's VMA) put
|
||||
them at.
|
||||
|
||||
The function TARGET_READ_MEMORY is called to copy LEN bytes from the
|
||||
remote memory at target address VMA into the local buffer at MYADDR; it
|
||||
should return zero on success or an `errno' code on failure. TEMPL must
|
||||
be a BFD for an ELF target with the word size and byte order found in
|
||||
the remote memory. */
|
||||
The function TARGET_READ_MEMORY is called to copy LEN bytes from
|
||||
the remote memory at target address VMA into the local buffer at
|
||||
MYADDR; it should return zero on success or an `errno' code on
|
||||
failure. TEMPL must be a BFD for a target with the word size and
|
||||
byte order found in the remote memory. */
|
||||
extern bfd *bfd_elf_bfd_from_remote_memory
|
||||
(bfd *templ, bfd_vma ehdr_vma, bfd_vma *loadbasep,
|
||||
(bfd *templ, bfd_vma ehdr_vma, size_t size, bfd_vma *loadbasep,
|
||||
int (*target_read_memory) (bfd_vma vma, bfd_byte *myaddr,
|
||||
bfd_size_type len));
|
||||
|
||||
|
|
|
@ -687,19 +687,21 @@ extern int bfd_get_elf_phdrs
|
|||
(bfd *abfd, void *phdrs);
|
||||
|
||||
/* Create a new BFD as if by bfd_openr. Rather than opening a file,
|
||||
reconstruct an ELF file by reading the segments out of remote memory
|
||||
based on the ELF file header at EHDR_VMA and the ELF program headers it
|
||||
points to. If not null, *LOADBASEP is filled in with the difference
|
||||
between the VMAs from which the segments were read, and the VMAs the
|
||||
file headers (and hence BFD's idea of each section's VMA) put them at.
|
||||
reconstruct an ELF file by reading the segments out of remote
|
||||
memory based on the ELF file header at EHDR_VMA and the ELF program
|
||||
headers it points to. If non-zero, SIZE is the known extent of the
|
||||
object. If not null, *LOADBASEP is filled in with the difference
|
||||
between the VMAs from which the segments were read, and the VMAs
|
||||
the file headers (and hence BFD's idea of each section's VMA) put
|
||||
them at.
|
||||
|
||||
The function TARGET_READ_MEMORY is called to copy LEN bytes from the
|
||||
remote memory at target address VMA into the local buffer at MYADDR; it
|
||||
should return zero on success or an `errno' code on failure. TEMPL must
|
||||
be a BFD for an ELF target with the word size and byte order found in
|
||||
the remote memory. */
|
||||
The function TARGET_READ_MEMORY is called to copy LEN bytes from
|
||||
the remote memory at target address VMA into the local buffer at
|
||||
MYADDR; it should return zero on success or an `errno' code on
|
||||
failure. TEMPL must be a BFD for a target with the word size and
|
||||
byte order found in the remote memory. */
|
||||
extern bfd *bfd_elf_bfd_from_remote_memory
|
||||
(bfd *templ, bfd_vma ehdr_vma, bfd_vma *loadbasep,
|
||||
(bfd *templ, bfd_vma ehdr_vma, size_t size, bfd_vma *loadbasep,
|
||||
int (*target_read_memory) (bfd_vma vma, bfd_byte *myaddr,
|
||||
bfd_size_type len));
|
||||
|
||||
|
|
|
@ -1191,9 +1191,9 @@ struct elf_backend_data
|
|||
/* This function implements `bfd_elf_bfd_from_remote_memory';
|
||||
see elf.c, elfcode.h. */
|
||||
bfd *(*elf_backend_bfd_from_remote_memory)
|
||||
(bfd *templ, bfd_vma ehdr_vma, bfd_vma *loadbasep,
|
||||
int (*target_read_memory) (bfd_vma vma, bfd_byte *myaddr,
|
||||
bfd_size_type len));
|
||||
(bfd *templ, bfd_vma ehdr_vma, size_t size, bfd_vma *loadbasep,
|
||||
int (*target_read_memory) (bfd_vma vma, bfd_byte *myaddr,
|
||||
bfd_size_type len));
|
||||
|
||||
/* This function is used by `_bfd_elf_get_synthetic_symtab';
|
||||
see elf.c. */
|
||||
|
@ -2334,10 +2334,10 @@ extern char *elfcore_write_ppc_linux_prpsinfo32
|
|||
(bfd *, char *, int *, const struct elf_internal_linux_prpsinfo *);
|
||||
|
||||
extern bfd *_bfd_elf32_bfd_from_remote_memory
|
||||
(bfd *templ, bfd_vma ehdr_vma, bfd_vma *loadbasep,
|
||||
(bfd *templ, bfd_vma ehdr_vma, size_t size, bfd_vma *loadbasep,
|
||||
int (*target_read_memory) (bfd_vma, bfd_byte *, bfd_size_type));
|
||||
extern bfd *_bfd_elf64_bfd_from_remote_memory
|
||||
(bfd *templ, bfd_vma ehdr_vma, bfd_vma *loadbasep,
|
||||
(bfd *templ, bfd_vma ehdr_vma, size_t size, bfd_vma *loadbasep,
|
||||
int (*target_read_memory) (bfd_vma, bfd_byte *, bfd_size_type));
|
||||
|
||||
extern bfd_vma bfd_elf_obj_attr_size (bfd *);
|
||||
|
|
|
@ -9908,11 +9908,12 @@ bfd *
|
|||
bfd_elf_bfd_from_remote_memory
|
||||
(bfd *templ,
|
||||
bfd_vma ehdr_vma,
|
||||
size_t size,
|
||||
bfd_vma *loadbasep,
|
||||
int (*target_read_memory) (bfd_vma, bfd_byte *, bfd_size_type))
|
||||
{
|
||||
return (*get_elf_backend_data (templ)->elf_backend_bfd_from_remote_memory)
|
||||
(templ, ehdr_vma, loadbasep, target_read_memory);
|
||||
(templ, ehdr_vma, size, loadbasep, target_read_memory);
|
||||
}
|
||||
|
||||
long
|
||||
|
|
149
bfd/elfcode.h
149
bfd/elfcode.h
|
@ -1587,37 +1587,40 @@ elf_debug_file (Elf_Internal_Ehdr *ehdrp)
|
|||
#endif
|
||||
|
||||
/* Create a new BFD as if by bfd_openr. Rather than opening a file,
|
||||
reconstruct an ELF file by reading the segments out of remote memory
|
||||
based on the ELF file header at EHDR_VMA and the ELF program headers it
|
||||
points to. If not null, *LOADBASEP is filled in with the difference
|
||||
between the VMAs from which the segments were read, and the VMAs the
|
||||
file headers (and hence BFD's idea of each section's VMA) put them at.
|
||||
reconstruct an ELF file by reading the segments out of remote
|
||||
memory based on the ELF file header at EHDR_VMA and the ELF program
|
||||
headers it points to. If non-zero, SIZE is the known extent of the
|
||||
object. If not null, *LOADBASEP is filled in with the difference
|
||||
between the VMAs from which the segments were read, and the VMAs
|
||||
the file headers (and hence BFD's idea of each section's VMA) put
|
||||
them at.
|
||||
|
||||
The function TARGET_READ_MEMORY is called to copy LEN bytes from the
|
||||
remote memory at target address VMA into the local buffer at MYADDR; it
|
||||
should return zero on success or an `errno' code on failure. TEMPL must
|
||||
be a BFD for a target with the word size and byte order found in the
|
||||
remote memory. */
|
||||
The function TARGET_READ_MEMORY is called to copy LEN bytes from
|
||||
the remote memory at target address VMA into the local buffer at
|
||||
MYADDR; it should return zero on success or an `errno' code on
|
||||
failure. TEMPL must be a BFD for a target with the word size and
|
||||
byte order found in the remote memory. */
|
||||
|
||||
bfd *
|
||||
NAME(_bfd_elf,bfd_from_remote_memory)
|
||||
(bfd *templ,
|
||||
bfd_vma ehdr_vma,
|
||||
size_t size,
|
||||
bfd_vma *loadbasep,
|
||||
int (*target_read_memory) (bfd_vma, bfd_byte *, bfd_size_type))
|
||||
{
|
||||
Elf_External_Ehdr x_ehdr; /* Elf file header, external form */
|
||||
Elf_Internal_Ehdr i_ehdr; /* Elf file header, internal form */
|
||||
Elf_External_Phdr *x_phdrs;
|
||||
Elf_Internal_Phdr *i_phdrs, *last_phdr;
|
||||
Elf_Internal_Phdr *i_phdrs, *last_phdr, *first_phdr;
|
||||
bfd *nbfd;
|
||||
struct bfd_in_memory *bim;
|
||||
int contents_size;
|
||||
bfd_byte *contents;
|
||||
int err;
|
||||
unsigned int i;
|
||||
bfd_vma high_offset;
|
||||
bfd_vma shdr_end;
|
||||
bfd_vma loadbase;
|
||||
bfd_boolean loadbase_set;
|
||||
|
||||
/* Read in the ELF header in external format. */
|
||||
err = target_read_memory (ehdr_vma, (bfd_byte *) &x_ehdr, sizeof x_ehdr);
|
||||
|
@ -1677,10 +1680,7 @@ NAME(_bfd_elf,bfd_from_remote_memory)
|
|||
x_phdrs = (Elf_External_Phdr *)
|
||||
bfd_malloc (i_ehdr.e_phnum * (sizeof *x_phdrs + sizeof *i_phdrs));
|
||||
if (x_phdrs == NULL)
|
||||
{
|
||||
bfd_set_error (bfd_error_no_memory);
|
||||
return NULL;
|
||||
}
|
||||
return NULL;
|
||||
err = target_read_memory (ehdr_vma + i_ehdr.e_phoff, (bfd_byte *) x_phdrs,
|
||||
i_ehdr.e_phnum * sizeof x_phdrs[0]);
|
||||
if (err)
|
||||
|
@ -1692,34 +1692,44 @@ NAME(_bfd_elf,bfd_from_remote_memory)
|
|||
}
|
||||
i_phdrs = (Elf_Internal_Phdr *) &x_phdrs[i_ehdr.e_phnum];
|
||||
|
||||
contents_size = 0;
|
||||
high_offset = 0;
|
||||
loadbase = 0;
|
||||
first_phdr = NULL;
|
||||
last_phdr = NULL;
|
||||
loadbase = ehdr_vma;
|
||||
loadbase_set = FALSE;
|
||||
for (i = 0; i < i_ehdr.e_phnum; ++i)
|
||||
{
|
||||
elf_swap_phdr_in (templ, &x_phdrs[i], &i_phdrs[i]);
|
||||
if (i_phdrs[i].p_type == PT_LOAD)
|
||||
{
|
||||
bfd_vma segment_end;
|
||||
segment_end = (i_phdrs[i].p_offset + i_phdrs[i].p_filesz
|
||||
+ i_phdrs[i].p_align - 1) & -i_phdrs[i].p_align;
|
||||
if (segment_end > (bfd_vma) contents_size)
|
||||
contents_size = segment_end;
|
||||
bfd_vma segment_end = i_phdrs[i].p_offset + i_phdrs[i].p_filesz;
|
||||
|
||||
/* LOADADDR is the `Base address' from the gELF specification:
|
||||
`lowest p_vaddr value for a PT_LOAD segment' is P_VADDR from the
|
||||
first PT_LOAD as PT_LOADs are ordered by P_VADDR. */
|
||||
if (!loadbase_set && (i_phdrs[i].p_offset & -i_phdrs[i].p_align) == 0)
|
||||
if (segment_end > high_offset)
|
||||
{
|
||||
loadbase = ehdr_vma - (i_phdrs[i].p_vaddr & -i_phdrs[i].p_align);
|
||||
loadbase_set = TRUE;
|
||||
high_offset = segment_end;
|
||||
last_phdr = &i_phdrs[i];
|
||||
}
|
||||
|
||||
last_phdr = &i_phdrs[i];
|
||||
/* If this program header covers offset zero, where the file
|
||||
header sits, then we can figure out the loadbase. */
|
||||
if (first_phdr == NULL)
|
||||
{
|
||||
bfd_vma p_offset = i_phdrs[i].p_offset;
|
||||
bfd_vma p_vaddr = i_phdrs[i].p_vaddr;
|
||||
|
||||
if (i_phdrs[i].p_align > 1)
|
||||
{
|
||||
p_offset &= -i_phdrs[i].p_align;
|
||||
p_vaddr &= -i_phdrs[i].p_align;
|
||||
}
|
||||
if (p_offset == 0)
|
||||
{
|
||||
loadbase = ehdr_vma - p_vaddr;
|
||||
first_phdr = &i_phdrs[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (last_phdr == NULL)
|
||||
if (high_offset == 0)
|
||||
{
|
||||
/* There were no PT_LOAD segments, so we don't have anything to read. */
|
||||
free (x_phdrs);
|
||||
|
@ -1727,40 +1737,64 @@ NAME(_bfd_elf,bfd_from_remote_memory)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* Trim the last segment so we don't bother with zeros in the last page
|
||||
that are off the end of the file. However, if the extra bit in that
|
||||
page includes the section headers, keep them. */
|
||||
if ((bfd_vma) contents_size > last_phdr->p_offset + last_phdr->p_filesz
|
||||
&& (bfd_vma) contents_size >= (i_ehdr.e_shoff
|
||||
+ i_ehdr.e_shnum * i_ehdr.e_shentsize))
|
||||
shdr_end = 0;
|
||||
if (i_ehdr.e_shoff != 0 && i_ehdr.e_shnum != 0 && i_ehdr.e_shentsize != 0)
|
||||
{
|
||||
contents_size = last_phdr->p_offset + last_phdr->p_filesz;
|
||||
if ((bfd_vma) contents_size < (i_ehdr.e_shoff
|
||||
+ i_ehdr.e_shnum * i_ehdr.e_shentsize))
|
||||
contents_size = i_ehdr.e_shoff + i_ehdr.e_shnum * i_ehdr.e_shentsize;
|
||||
shdr_end = i_ehdr.e_shoff + i_ehdr.e_shnum * i_ehdr.e_shentsize;
|
||||
|
||||
if (last_phdr->p_filesz != last_phdr->p_memsz)
|
||||
{
|
||||
/* If the last PT_LOAD header has a bss area then ld.so will
|
||||
have cleared anything past p_filesz, zapping the section
|
||||
headers. */
|
||||
}
|
||||
else if (size >= shdr_end)
|
||||
high_offset = shdr_end;
|
||||
else
|
||||
{
|
||||
bfd_vma page_size = get_elf_backend_data (templ)->minpagesize;
|
||||
bfd_vma segment_end = last_phdr->p_offset + last_phdr->p_filesz;
|
||||
|
||||
/* Assume we loaded full pages, allowing us to sometimes see
|
||||
section headers. */
|
||||
if (page_size > 1 && shdr_end > segment_end)
|
||||
{
|
||||
bfd_vma page_end = (segment_end + page_size - 1) & -page_size;
|
||||
|
||||
if (page_end >= shdr_end)
|
||||
/* Whee, section headers covered. */
|
||||
high_offset = shdr_end;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
contents_size = last_phdr->p_offset + last_phdr->p_filesz;
|
||||
|
||||
/* Now we know the size of the whole image we want read in. */
|
||||
contents = (bfd_byte *) bfd_zmalloc (contents_size);
|
||||
contents = (bfd_byte *) bfd_zmalloc (high_offset);
|
||||
if (contents == NULL)
|
||||
{
|
||||
free (x_phdrs);
|
||||
bfd_set_error (bfd_error_no_memory);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < i_ehdr.e_phnum; ++i)
|
||||
if (i_phdrs[i].p_type == PT_LOAD)
|
||||
{
|
||||
bfd_vma start = i_phdrs[i].p_offset & -i_phdrs[i].p_align;
|
||||
bfd_vma end = (i_phdrs[i].p_offset + i_phdrs[i].p_filesz
|
||||
+ i_phdrs[i].p_align - 1) & -i_phdrs[i].p_align;
|
||||
if (end > (bfd_vma) contents_size)
|
||||
end = contents_size;
|
||||
err = target_read_memory ((loadbase + i_phdrs[i].p_vaddr)
|
||||
& -i_phdrs[i].p_align,
|
||||
bfd_vma start = i_phdrs[i].p_offset;
|
||||
bfd_vma end = start + i_phdrs[i].p_filesz;
|
||||
bfd_vma vaddr = i_phdrs[i].p_vaddr;
|
||||
|
||||
/* Extend the beginning of the first pt_load to cover file
|
||||
header and program headers, if we proved earlier that its
|
||||
aligned offset is 0. */
|
||||
if (first_phdr == &i_phdrs[i])
|
||||
{
|
||||
vaddr -= start;
|
||||
start = 0;
|
||||
}
|
||||
/* Extend the end of the last pt_load to cover section headers. */
|
||||
if (last_phdr == &i_phdrs[i])
|
||||
end = high_offset;
|
||||
err = target_read_memory (loadbase + vaddr,
|
||||
contents + start, end - start);
|
||||
if (err)
|
||||
{
|
||||
|
@ -1775,8 +1809,7 @@ NAME(_bfd_elf,bfd_from_remote_memory)
|
|||
|
||||
/* If the segments visible in memory didn't include the section headers,
|
||||
then clear them from the file header. */
|
||||
if ((bfd_vma) contents_size < (i_ehdr.e_shoff
|
||||
+ i_ehdr.e_shnum * i_ehdr.e_shentsize))
|
||||
if (high_offset < shdr_end)
|
||||
{
|
||||
memset (&x_ehdr.e_shoff, 0, sizeof x_ehdr.e_shoff);
|
||||
memset (&x_ehdr.e_shnum, 0, sizeof x_ehdr.e_shnum);
|
||||
|
@ -1792,7 +1825,6 @@ NAME(_bfd_elf,bfd_from_remote_memory)
|
|||
if (bim == NULL)
|
||||
{
|
||||
free (contents);
|
||||
bfd_set_error (bfd_error_no_memory);
|
||||
return NULL;
|
||||
}
|
||||
nbfd = _bfd_new_bfd ();
|
||||
|
@ -1800,12 +1832,11 @@ NAME(_bfd_elf,bfd_from_remote_memory)
|
|||
{
|
||||
free (bim);
|
||||
free (contents);
|
||||
bfd_set_error (bfd_error_no_memory);
|
||||
return NULL;
|
||||
}
|
||||
nbfd->filename = xstrdup ("<in-memory>");
|
||||
nbfd->xvec = templ->xvec;
|
||||
bim->size = contents_size;
|
||||
bim->size = high_offset;
|
||||
bim->buffer = contents;
|
||||
nbfd->iostream = bim;
|
||||
nbfd->flags = BFD_IN_MEMORY;
|
||||
|
|
|
@ -1,3 +1,11 @@
|
|||
2014-04-02 Alan Modra <amodra@gmail.com>
|
||||
|
||||
* symfile-mem.c (symbol_file_add_from_memory): Add size parameter.
|
||||
Pass to bfd_elf_bfd_from_remote_memory. Adjust all callers.
|
||||
(struct symbol_file_add_from_memory_args): Add size field.
|
||||
(find_vdso_size): New function.
|
||||
(add_vsyscall_page): Attempt to find vdso size.
|
||||
|
||||
2014-04-01 Doug Evans <dje@google.com>
|
||||
|
||||
* dwarf2read.c (read_cutu_die_from_dwo): Improve comment.
|
||||
|
|
|
@ -76,13 +76,14 @@ target_read_memory_bfd (bfd_vma memaddr, bfd_byte *myaddr, bfd_size_type len)
|
|||
}
|
||||
|
||||
/* Read inferior memory at ADDR to find the header of a loaded object file
|
||||
and read its in-core symbols out of inferior memory. TEMPL is a bfd
|
||||
and read its in-core symbols out of inferior memory. SIZE, if
|
||||
non-zero, is the known size of the object. TEMPL is a bfd
|
||||
representing the target's format. NAME is the name to use for this
|
||||
symbol file in messages; it can be NULL or a malloc-allocated string
|
||||
which will be attached to the BFD. */
|
||||
static struct objfile *
|
||||
symbol_file_add_from_memory (struct bfd *templ, CORE_ADDR addr, char *name,
|
||||
int from_tty)
|
||||
symbol_file_add_from_memory (struct bfd *templ, CORE_ADDR addr,
|
||||
size_t size, char *name, int from_tty)
|
||||
{
|
||||
struct objfile *objf;
|
||||
struct bfd *nbfd;
|
||||
|
@ -95,7 +96,7 @@ symbol_file_add_from_memory (struct bfd *templ, CORE_ADDR addr, char *name,
|
|||
if (bfd_get_flavour (templ) != bfd_target_elf_flavour)
|
||||
error (_("add-symbol-file-from-memory not supported for this target"));
|
||||
|
||||
nbfd = bfd_elf_bfd_from_remote_memory (templ, addr, &loadbase,
|
||||
nbfd = bfd_elf_bfd_from_remote_memory (templ, addr, size, &loadbase,
|
||||
target_read_memory_bfd);
|
||||
if (nbfd == NULL)
|
||||
error (_("Failed to read a valid object file image from memory."));
|
||||
|
@ -158,7 +159,7 @@ add_symbol_file_from_memory_command (char *args, int from_tty)
|
|||
error (_("Must use symbol-file or exec-file "
|
||||
"before add-symbol-file-from-memory."));
|
||||
|
||||
symbol_file_add_from_memory (templ, addr, NULL, from_tty);
|
||||
symbol_file_add_from_memory (templ, addr, 0, NULL, from_tty);
|
||||
}
|
||||
|
||||
/* Arguments for symbol_file_add_from_memory_wrapper. */
|
||||
|
@ -167,6 +168,7 @@ struct symbol_file_add_from_memory_args
|
|||
{
|
||||
struct bfd *bfd;
|
||||
CORE_ADDR sysinfo_ehdr;
|
||||
size_t size;
|
||||
char *name;
|
||||
int from_tty;
|
||||
};
|
||||
|
@ -179,8 +181,25 @@ symbol_file_add_from_memory_wrapper (struct ui_out *uiout, void *data)
|
|||
{
|
||||
struct symbol_file_add_from_memory_args *args = data;
|
||||
|
||||
symbol_file_add_from_memory (args->bfd, args->sysinfo_ehdr, args->name,
|
||||
args->from_tty);
|
||||
symbol_file_add_from_memory (args->bfd, args->sysinfo_ehdr, args->size,
|
||||
args->name, args->from_tty);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Rummage through mappings to find the vsyscall page size. */
|
||||
|
||||
static int
|
||||
find_vdso_size (CORE_ADDR vaddr, unsigned long size,
|
||||
int read, int write, int exec, int modified,
|
||||
void *data)
|
||||
{
|
||||
struct symbol_file_add_from_memory_args *args = data;
|
||||
|
||||
if (vaddr == args->sysinfo_ehdr)
|
||||
{
|
||||
args->size = size;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -217,6 +236,11 @@ add_vsyscall_page (struct target_ops *target, int from_tty)
|
|||
}
|
||||
args.bfd = bfd;
|
||||
args.sysinfo_ehdr = sysinfo_ehdr;
|
||||
args.size = 0;
|
||||
if (gdbarch_find_memory_regions_p (target_gdbarch ()))
|
||||
(void) gdbarch_find_memory_regions (target_gdbarch (),
|
||||
find_vdso_size, &args);
|
||||
|
||||
args.name = xstrprintf ("system-supplied DSO at %s",
|
||||
paddress (target_gdbarch (), sysinfo_ehdr));
|
||||
/* Pass zero for FROM_TTY, because the action of loading the
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue