From: Aleksandar Ristovski <aristovski@qnx.com>
To: Jan Kratochvil <jan.kratochvil@redhat.com>
Cc: "gdb-patches@sourceware.org" <gdb-patches@sourceware.org>
Subject: Re: [patch 6/6] gdbserver build-id attribute generator
Date: Fri, 05 Apr 2013 15:05:00 -0000 [thread overview]
Message-ID: <515ECB30.5010504@qnx.com> (raw)
In-Reply-To: <20130403193258.GA9853@host2.jankratochvil.net>
[-- Attachment #1: Type: text/plain, Size: 2754 bytes --]
Rebased to master e96bd93d436e464a532a7e1161e1d201c9fc50c7
On 13-04-03 03:32 PM, Jan Kratochvil wrote:
> On Tue, 02 Apr 2013 18:22:48 +0200, Aleksandar Ristovski wrote:
>>>> +static int
>>>> +find_phdr_p (const void *const phdr, const int is_elf64,
>>>> + const void *const data)
>>>
>>> But I do not understand why this function exists - it could be integrated in
>>> find_phdr as very every caller of find_phdr passse as find_phdr_p parameter
>>> this find_phdr_p implementation.
>>
>>
>> [AR] Yes, but I am eyeing solib-svr4.c loops over pheaders
>> generalization - find_phdr could be moved to 'common' and possibly
>> called 'iterate_phdrs' with the ability to pass in any function, not
>> necessarily a predicate only. E.g. svr4_exec_displacement, etc...)
>
> It is not relevant for this patch what do you plan. In the form as is it is
> needlessly overcomplicated. That more thorough generalization would be
> possibly good but it is not here and it may never happen. GDB will just
> remain with needlessly complicated code.
>
>
>
>>> You need to check here also the name content, it is "GNU\x00" (n_namesz == 4).
>>
>> [AR], can it be any other name if type is NT_GNU_BUILD_ID? Added the
>> check but seems like an overkill to me.
>
> NT_GNU_BUILD_ID is just number 3. I find very realistic for example
> "SUNW Solaris" would use at least 3 note types (does not use it already?).
>
>
>>>> +/* Linear reverse find starting from RBEGIN towards REND looking for
>>>> + the lowest vaddr mapping of the same inode and zero offset. */
>>>> +
>>>> +static mapping_entry_s *
>>>> +lrfind_mapping_entry (mapping_entry_s *const rbegin,
>>>> + const mapping_entry_s *const rend)
>>>> +{
>>>> + mapping_entry_s *p;
>>>> +
>>>> + for (p = rbegin - 1; p >= rend && p->inode == rbegin->inode; --p)
>>>> + if (p->offset == 0)
>>>> + return p;
>>>
>>> I had here this layout:
>>> 7ffff7ddc000-7ffff7dfd000 r-xp 00000000 fd:01 51415762 /usr/lib64/ld-2.17.so
>>> 7ffff7ff9000-7ffff7ffa000 rw-p 00000000 00:00 0
>>> 7ffff7ffa000-7ffff7ffc000 r-xp 00000000 00:00 0 [vdso]
>>> 7ffff7ffc000-7ffff7ffe000 rw-p 00020000 fd:01 51415762 /usr/lib64/ld-2.17.so
>>>
>>> so it should rather be:
>>> for (p = rbegin - 1; p >= rend; --p)
>>> if (p->offset == 0 && p->inode == rbegin->inode)
>>> return p;
>>>
>>> Fortunately it should not have any real performance impact.
>>
>> [AR] Ok, though we are not adding mappings with inode == 0. See
>> 'find_memory_region_callback'.
>
> Hmm, that's true, I do not see now why it failed for me. But that could be
> even non-zero-inode mapping so a change was appropriate.
>
>
> This is not yet a full review.
>
>
> Thanks,
> Jan
>
[-- Attachment #2: 0006-gdbserver-build-id-attribute-generator.patch --]
[-- Type: text/x-patch, Size: 19046 bytes --]
From 8a176b511f358b82d5b1f4c5556a501b62bf6dc6 Mon Sep 17 00:00:00 2001
From: Aleksandar Ristovski <ARistovski@qnx.com>
Date: Wed, 27 Mar 2013 11:56:57 -0400
Subject: [PATCH 6/8] gdbserver build-id attribute generator
* doc/gdb.texinfo (Library List Format for SVR4 Targets): Add
'build-id' in description, example, new attribute in dtd.
* features/library-list-svr4.dtd (library-list-svr4): New
'build-id' attribute.
* linux-low.c (linux-maps.h, search.h): Include.
(ElfXX_Ehdr, ElfXX_Phdr, ElfXX_Nhdr): New.
(ELFXX_FLD, ELFXX_SIZEOF, ELFXX_ROUNDUP, BUILD_ID_INVALID): New.
(find_phdr_p_ftype, find_phdr, find_phdr_p): New.
(get_dynamic): Use find_pdhr to traverse program headers.
(struct mapping_entry): New structure.
(mapping_entry_s): New typedef, new vector type def.
(free_mapping_entry, compare_mapping_entry,
compare_mapping_entry_range, compare_mapping_entry_inode): New.
(struct find_memory_region_callback_data): New.
(find_memory_region_callback): New fwd. declaration.
(read_build_id, find_memory_region_callback, get_hex_build_id): New.
(linux_qxfer_libraries_svr4): Add optional build-id attribute
to reply XML document.
---
gdb/doc/gdb.texinfo | 17 +-
gdb/features/library-list-svr4.dtd | 13 +-
gdb/gdbserver/linux-low.c | 409 +++++++++++++++++++++++++++++++++---
3 files changed, 402 insertions(+), 37 deletions(-)
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 8ae7259..0002d23 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -40354,6 +40354,8 @@ memory address. It is a displacement of absolute memory address against
address the file was prelinked to during the library load.
@item
@code{l_ld}, which is memory address of the @code{PT_DYNAMIC} segment
+@item
+@code{build-id}, hex encoded @code{NT_GNU_BUILD_ID} note, if it exists.
@end itemize
Additionally the single @code{main-lm} attribute specifies address of
@@ -40371,7 +40373,7 @@ looks like this:
<library name="/lib/ld-linux.so.2" lm="0xe4f51c" l_addr="0xe2d000"
l_ld="0xe4eefc"/>
<library name="/lib/libc.so.6" lm="0xe4fbe8" l_addr="0x154000"
- l_ld="0x152350"/>
+ l_ld="0x152350" build-id="9afccf7cc41e6293476223fe72480854"/>
</library-list-svr>
@end smallexample
@@ -40380,13 +40382,14 @@ The format of an SVR4 library list is described by this DTD:
@smallexample
<!-- library-list-svr4: Root element with versioning -->
<!ELEMENT library-list-svr4 (library)*>
-<!ATTLIST library-list-svr4 version CDATA #FIXED "1.0">
-<!ATTLIST library-list-svr4 main-lm CDATA #IMPLIED>
+<!ATTLIST library-list-svr4 version CDATA #FIXED "1.0">
+<!ATTLIST library-list-svr4 main-lm CDATA #IMPLIED>
<!ELEMENT library EMPTY>
-<!ATTLIST library name CDATA #REQUIRED>
-<!ATTLIST library lm CDATA #REQUIRED>
-<!ATTLIST library l_addr CDATA #REQUIRED>
-<!ATTLIST library l_ld CDATA #REQUIRED>
+<!ATTLIST library name CDATA #REQUIRED>
+<!ATTLIST library lm CDATA #REQUIRED>
+<!ATTLIST library l_addr CDATA #REQUIRED>
+<!ATTLIST library l_ld CDATA #REQUIRED>
+<!ATTLIST library build-id CDATA #IMPLIED>
@end smallexample
@node Memory Map Format
diff --git a/gdb/features/library-list-svr4.dtd b/gdb/features/library-list-svr4.dtd
index cae7fd8..fdd6ec0 100644
--- a/gdb/features/library-list-svr4.dtd
+++ b/gdb/features/library-list-svr4.dtd
@@ -6,11 +6,12 @@
<!-- library-list-svr4: Root element with versioning -->
<!ELEMENT library-list-svr4 (library)*>
-<!ATTLIST library-list-svr4 version CDATA #FIXED "1.0">
-<!ATTLIST library-list-svr4 main-lm CDATA #IMPLIED>
+<!ATTLIST library-list-svr4 version CDATA #FIXED "1.0">
+<!ATTLIST library-list-svr4 main-lm CDATA #IMPLIED>
<!ELEMENT library EMPTY>
-<!ATTLIST library name CDATA #REQUIRED>
-<!ATTLIST library lm CDATA #REQUIRED>
-<!ATTLIST library l_addr CDATA #REQUIRED>
-<!ATTLIST library l_ld CDATA #REQUIRED>
+<!ATTLIST library name CDATA #REQUIRED>
+<!ATTLIST library lm CDATA #REQUIRED>
+<!ATTLIST library l_addr CDATA #REQUIRED>
+<!ATTLIST library l_ld CDATA #REQUIRED>
+<!ATTLIST library build-id CDATA #IMPLIED>
diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
index 72c51e0..61da37c 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -20,6 +20,7 @@
#include "linux-low.h"
#include "linux-osdata.h"
#include "agent.h"
+#include "linux-maps.h"
#include "gdb_wait.h"
#include <stdio.h>
@@ -43,6 +44,7 @@
#include "gdb_stat.h"
#include <sys/vfs.h>
#include <sys/uio.h>
+#include <search.h>
#ifndef ELFMAG0
/* Don't include <linux/elf.h> here. If it got included by gdb_proc_service.h
then ELFMAG0 will have been defined. If it didn't get included by
@@ -118,6 +120,33 @@ typedef struct
} Elf64_auxv_t;
#endif
+typedef union ElfXX_Ehdr
+{
+ Elf32_Ehdr _32;
+ Elf64_Ehdr _64;
+} ElfXX_Ehdr;
+
+typedef union ElfXX_Phdr
+{
+ Elf32_Phdr _32;
+ Elf64_Phdr _64;
+} ElfXX_Phdr;
+
+typedef union ElfXX_Nhdr
+{
+ Elf32_Nhdr _32;
+ Elf64_Nhdr _64;
+} ElfXX_Nhdr;
+
+#define ELFXX_FLD(hdr, fld) ((is_elf64) ? (hdr)._64.fld : (hdr)._32.fld)
+#define ELFXX_SIZEOF(hdr) ((is_elf64) ? sizeof ((hdr)._64) \
+ : sizeof ((hdr)._32))
+#define ELFXX_ROUNDUP(what) ((is_elf64) ? (((what) + sizeof (Elf64_Word) - 1) \
+ & ~(sizeof (Elf64_Word) - 1)) \
+ : (((what) + sizeof (Elf32_Word) - 1) \
+ & ~(sizeof (Elf32_Word) - 1)))
+#define BUILD_ID_INVALID "?"
+
/* ``all_threads'' is keyed by the LWP ID, which we use as the GDB protocol
representation of the thread ID.
@@ -5432,15 +5461,76 @@ get_phdr_phnum_from_proc_auxv (const int pid, const int is_elf64,
return 0;
}
+/* Predicate function type returns 1 if the given phdr is what is
+ being looked for. Returns 0 otherwise. */
+
+typedef int (find_phdr_p_ftype) (const void *phdr, int is_elf64,
+ const void *data);
+
+/* Linearly traverse pheaders given in PHDR until supplied
+ predicate function returns 1. If supplied predicate function
+ did return 1, stop traversal and return that PHDR. */
+
+static const void *
+find_phdr (int is_elf64, const void *const phdr_begin,
+ const void *const phdr_end, find_phdr_p_ftype *const find_phdr_p,
+ const void *const data)
+{
+#define PHDR_NEXT(hdrp) ((const void *) ((const gdb_byte *) (hdrp) + \
+ ELFXX_SIZEOF (*hdrp)))
+
+ const ElfXX_Phdr *phdr = phdr_begin;
+
+ if (phdr == NULL)
+ return NULL;
+
+ while (PHDR_NEXT (phdr) <= phdr_end)
+ {
+ if (find_phdr_p (phdr, is_elf64, data) == 1)
+ return phdr;
+ phdr = PHDR_NEXT (phdr);
+ }
+
+ return NULL;
+#undef PHDR_NEXT
+}
+
+/* Predicate function for find_phdr iteration. */
+
+static int
+find_phdr_p (const void *const phdr, const int is_elf64,
+ const void *const data)
+{
+ const ULONGEST *const type = data;
+
+ if (is_elf64)
+ {
+ const Elf64_Phdr *const p = phdr;
+
+ if (p->p_type == *type)
+ return 1;
+ }
+ else
+ {
+ const Elf32_Phdr *const p = phdr;
+
+ if (p->p_type == *type)
+ return 1;
+ }
+ return 0;
+}
+
/* Return &_DYNAMIC (via PT_DYNAMIC) in the inferior, or 0 if not present. */
static CORE_ADDR
get_dynamic (const int pid, const int is_elf64)
{
CORE_ADDR phdr_memaddr, relocation;
- int num_phdr, i;
+ int num_phdr;
unsigned char *phdr_buf;
const int phdr_size = is_elf64 ? sizeof (Elf64_Phdr) : sizeof (Elf32_Phdr);
+ const void *phdr;
+ ULONGEST p_type;
if (get_phdr_phnum_from_proc_auxv (pid, is_elf64, &phdr_memaddr, &num_phdr))
return 0;
@@ -5454,21 +5544,24 @@ get_dynamic (const int pid, const int is_elf64)
/* Compute relocation: it is expected to be 0 for "regular" executables,
non-zero for PIE ones. */
relocation = -1;
- for (i = 0; relocation == -1 && i < num_phdr; i++)
- if (is_elf64)
- {
- Elf64_Phdr *const p = (Elf64_Phdr *) (phdr_buf + i * phdr_size);
+ p_type = PT_PHDR;
+ phdr = find_phdr (is_elf64, phdr_buf, phdr_buf + num_phdr * phdr_size,
+ find_phdr_p, &p_type);
+ if (phdr != NULL)
+ {
+ if (is_elf64)
+ {
+ const Elf64_Phdr *const p = phdr;
- if (p->p_type == PT_PHDR)
relocation = phdr_memaddr - p->p_vaddr;
- }
- else
- {
- Elf32_Phdr *const p = (Elf32_Phdr *) (phdr_buf + i * phdr_size);
+ }
+ else
+ {
+ const Elf32_Phdr *const p = phdr;
- if (p->p_type == PT_PHDR)
relocation = phdr_memaddr - p->p_vaddr;
- }
+ }
+ }
if (relocation == -1)
{
@@ -5485,21 +5578,23 @@ get_dynamic (const int pid, const int is_elf64)
return 0;
}
- for (i = 0; i < num_phdr; i++)
+ p_type = PT_DYNAMIC;
+ phdr = find_phdr (is_elf64, phdr_buf, phdr_buf + num_phdr * phdr_size,
+ find_phdr_p, &p_type);
+
+ if (phdr != NULL)
{
if (is_elf64)
{
- Elf64_Phdr *const p = (Elf64_Phdr *) (phdr_buf + i * phdr_size);
+ const Elf64_Phdr *const p = phdr;
- if (p->p_type == PT_DYNAMIC)
- return p->p_vaddr + relocation;
+ return p->p_vaddr + relocation;
}
else
{
- Elf32_Phdr *const p = (Elf32_Phdr *) (phdr_buf + i * phdr_size);
+ const Elf32_Phdr *const p = phdr;
- if (p->p_type == PT_DYNAMIC)
- return p->p_vaddr + relocation;
+ return p->p_vaddr + relocation;
}
}
@@ -5641,6 +5736,254 @@ struct link_map_offsets
int l_prev_offset;
};
+
+/* Structure for holding a mapping. Only mapping
+ containing l_ld can have hex_build_id set. */
+
+struct mapping_entry
+{
+ /* Fields are populated from linux_find_memory_region parameters. */
+
+ ULONGEST vaddr;
+ ULONGEST size;
+ ULONGEST offset;
+ ULONGEST inode;
+
+ /* Hex encoded string allocated using xmalloc, and
+ needs to be freed. It can be NULL. */
+
+ char *hex_build_id;
+};
+
+typedef struct mapping_entry mapping_entry_s;
+
+DEF_VEC_O(mapping_entry_s);
+
+static void
+free_mapping_entry (VEC (mapping_entry_s) *lst)
+{
+ int ix;
+ mapping_entry_s *p;
+
+ for (ix = 0; VEC_iterate (mapping_entry_s, lst, ix, p); ++ix)
+ xfree (p->hex_build_id);
+
+ VEC_free (mapping_entry_s, lst);
+}
+
+/* Used for finding a mapping containing the given
+ l_ld passed in K. */
+
+static int
+compare_mapping_entry_range (const void *const k, const void *const b)
+{
+ const ULONGEST key = *(CORE_ADDR*) k;
+ const mapping_entry_s *const p = b;
+
+ if (key < p->vaddr)
+ return -1;
+
+ if (key < p->vaddr + p->size)
+ return 0;
+
+ return 1;
+}
+
+struct find_memory_region_callback_data
+{
+ unsigned is_elf64;
+
+ /* Return. Ordered list of all object mappings sorted in
+ ascending order by VADDR. Must be freed with free_mapping_entry. */
+ VEC (mapping_entry_s) *list;
+};
+
+static linux_find_memory_region_ftype find_memory_region_callback;
+
+/* Read build-id from PT_NOTE. */
+
+static void
+read_build_id (struct find_memory_region_callback_data *const p,
+ mapping_entry_s *const bil, const CORE_ADDR load_addr,
+ const CORE_ADDR l_addr)
+{
+ const int is_elf64 = p->is_elf64;
+ ElfXX_Ehdr ehdr;
+
+ if (linux_read_memory (load_addr, (unsigned char *) &ehdr,
+ ELFXX_SIZEOF (ehdr)) == 0
+ && ELFXX_FLD (ehdr, e_ident[EI_MAG0]) == ELFMAG0
+ && ELFXX_FLD (ehdr, e_ident[EI_MAG1]) == ELFMAG1
+ && ELFXX_FLD (ehdr, e_ident[EI_MAG2]) == ELFMAG2
+ && ELFXX_FLD (ehdr, e_ident[EI_MAG3]) == ELFMAG3)
+ {
+ const ElfXX_Phdr *phdr;
+ void *phdr_buf;
+ const ULONGEST p_type = PT_NOTE;
+ const unsigned e_phentsize = ELFXX_FLD (ehdr, e_phentsize);
+
+ gdb_assert (ELFXX_FLD (ehdr, e_phnum) < 100); /* Basic sanity check. */
+ gdb_assert (e_phentsize == ELFXX_SIZEOF (*phdr));
+ phdr_buf = alloca (ELFXX_FLD (ehdr, e_phnum) * e_phentsize);
+
+ if (linux_read_memory (load_addr + ELFXX_FLD (ehdr, e_phoff), phdr_buf,
+ ELFXX_FLD (ehdr, e_phnum) * e_phentsize) != 0)
+ {
+ warning ("Could not read program header.");
+ return;
+ }
+
+ phdr = phdr_buf;
+
+ for (;;)
+ {
+ gdb_byte *pt_note;
+ const gdb_byte *pt_end;
+ const ElfXX_Nhdr *nhdr;
+
+ phdr = find_phdr (p->is_elf64, phdr, (gdb_byte *) phdr_buf
+ + ELFXX_FLD (ehdr, e_phnum) * e_phentsize,
+ find_phdr_p, &p_type);
+ if (phdr == NULL)
+ break;
+ pt_note = xmalloc (ELFXX_FLD (*phdr, p_memsz));
+ pt_end = (gdb_byte*) pt_note + ELFXX_FLD (*phdr, p_memsz);
+
+ if (linux_read_memory (ELFXX_FLD (*phdr, p_vaddr) + l_addr, pt_note,
+ ELFXX_FLD (*phdr, p_memsz)) != 0)
+ {
+ xfree (pt_note);
+ warning ("Could not read note.");
+ break;
+ }
+
+ nhdr = (void *) pt_note;
+ while ((void *) nhdr < (void *) pt_end)
+ {
+ const size_t namesz
+ = ELFXX_ROUNDUP (ELFXX_FLD (*nhdr, n_namesz));
+ const size_t descsz
+ = ELFXX_ROUNDUP (ELFXX_FLD (*nhdr, n_descsz));
+ const size_t note_sz = ELFXX_SIZEOF (*nhdr) + namesz + descsz;
+
+ if (((gdb_byte *) nhdr + note_sz) > pt_end || note_sz == 0
+ || descsz == 0)
+ {
+ warning ("Malformed PT_NOTE\n");
+ break;
+ }
+ if (ELFXX_FLD (*nhdr, n_type) == NT_GNU_BUILD_ID
+ && ELFXX_FLD (*nhdr, n_namesz) == 4)
+ {
+ const char gnu[4] = "GNU\0";
+ const char *const pname
+ = (char *) nhdr + ELFXX_SIZEOF (*nhdr);
+
+ if (memcmp (pname, gnu, 4) == 0)
+ {
+ const size_t n_descsz = ELFXX_FLD (*nhdr, n_descsz);
+
+ bil->hex_build_id = xmalloc (n_descsz * 2 + 1);
+ bin2hex ((gdb_byte*) pname + namesz, bil->hex_build_id,
+ n_descsz);
+ xfree (pt_note);
+ return;
+ }
+ }
+ nhdr = (void*) ((gdb_byte *) nhdr + note_sz);
+ }
+ xfree (pt_note);
+ }
+ }
+}
+
+/* Add mapping_entry. */
+
+static int
+find_memory_region_callback (ULONGEST vaddr, ULONGEST size, ULONGEST offset,
+ ULONGEST inode, int read, int write, int exec,
+ int modified, const char *filename, void *data)
+{
+ if (inode != 0)
+ {
+ struct find_memory_region_callback_data *const p = data;
+ mapping_entry_s bil;
+
+ bil.vaddr = vaddr;
+ bil.size = size;
+ bil.offset = offset;
+ bil.inode = inode;
+ bil.hex_build_id = NULL;
+
+ VEC_safe_push (mapping_entry_s, p->list, &bil);
+ }
+
+ /* Continue the traversal. */
+ return 0;
+}
+
+/* Linear reverse find starting from RBEGIN towards REND looking for
+ the lowest vaddr mapping of the same inode and zero offset. */
+
+static mapping_entry_s *
+lrfind_mapping_entry (mapping_entry_s *const rbegin,
+ const mapping_entry_s *const rend)
+{
+ mapping_entry_s *p;
+
+ for (p = rbegin - 1; p >= rend; --p)
+ if (p->offset == 0 && p->inode == rbegin->inode)
+ return p;
+
+ return NULL;
+}
+
+/* Get build-id for the given L_LD. DATA must point to
+ already filled list of mapping_entry elements.
+
+ Return build_id as stored in the list element corresponding
+ to L_LD.
+
+ NULL may be returned if build-id could not be fetched.
+
+ Returned string must not be freed explicitly. */
+
+static const char *
+get_hex_build_id (const CORE_ADDR l_addr, const CORE_ADDR l_ld,
+ struct find_memory_region_callback_data *const data)
+{
+ mapping_entry_s *bil;
+
+ if (VEC_address (mapping_entry_s, data->list) == NULL)
+ return NULL;
+
+ bil = bsearch (&l_ld, VEC_address (mapping_entry_s, data->list),
+ VEC_length (mapping_entry_s, data->list),
+ sizeof (mapping_entry_s), compare_mapping_entry_range);
+
+ if (bil == NULL)
+ return NULL;
+
+ if (bil->hex_build_id == NULL)
+ {
+ mapping_entry_s *bil_min;
+
+ bil_min = lrfind_mapping_entry (bil, VEC_address (mapping_entry_s,
+ data->list));
+ if (bil_min != NULL)
+ read_build_id (data, bil, bil_min->vaddr, l_addr);
+ else
+ {
+ /* Do not try to find hex_build_id again. */
+ bil->hex_build_id = xstrdup (BUILD_ID_INVALID);
+ warning ("Could not determine load address; "
+ "build-id can not be used.");
+ }
+ }
+
+ return bil->hex_build_id;
+}
+
/* Construct qXfer:libraries-svr4:read reply. */
static int
@@ -5653,6 +5996,7 @@ linux_qxfer_libraries_svr4 (const char *annex, unsigned char *readbuf,
struct process_info_private *const priv = current_process ()->private;
char filename[PATH_MAX];
int pid, is_elf64;
+ struct find_memory_region_callback_data data;
static const struct link_map_offsets lmo_32bit_offsets =
{
@@ -5688,6 +6032,13 @@ linux_qxfer_libraries_svr4 (const char *annex, unsigned char *readbuf,
is_elf64 = elf_64_file_p (filename, &machine);
lmo = is_elf64 ? &lmo_64bit_offsets : &lmo_32bit_offsets;
+ data.is_elf64 = is_elf64;
+ data.list = NULL;
+ VEC_reserve (mapping_entry_s, data.list, 16);
+ if (linux_find_memory_regions_full (pid, find_memory_region_callback, &data,
+ NULL) < 0)
+ warning ("Finding memory regions failed");
+
if (priv->r_debug == 0)
priv->r_debug = get_r_debug (pid, is_elf64);
@@ -5762,6 +6113,7 @@ linux_qxfer_libraries_svr4 (const char *annex, unsigned char *readbuf,
/* 6x the size for xml_escape_text below. */
size_t len = 6 * strlen ((char *) libname);
char *name;
+ const char *hex_enc_build_id = NULL;
if (!header_done)
{
@@ -5770,21 +6122,29 @@ linux_qxfer_libraries_svr4 (const char *annex, unsigned char *readbuf,
header_done = 1;
}
- while (allocated < p - document + len + 200)
+ name = xml_escape_text ((char *) libname);
+ hex_enc_build_id = get_hex_build_id (l_addr, l_ld, &data);
+
+ while (allocated < (p - document + len + 200
+ + (hex_enc_build_id != NULL
+ ? strlen (hex_enc_build_id) : 0)))
{
/* Expand to guarantee sufficient storage. */
- uintptr_t document_len = p - document;
+ const ptrdiff_t document_len = p - document;
- document = xrealloc (document, 2 * allocated);
allocated *= 2;
+ document = xrealloc (document, allocated);
p = document + document_len;
}
- name = xml_escape_text ((char *) libname);
p += sprintf (p, "<library name=\"%s\" lm=\"0x%lx\" "
- "l_addr=\"0x%lx\" l_ld=\"0x%lx\"/>",
+ "l_addr=\"0x%lx\" l_ld=\"0x%lx\"",
name, (unsigned long) lm_addr,
(unsigned long) l_addr, (unsigned long) l_ld);
+ if (hex_enc_build_id != NULL
+ && strcmp (hex_enc_build_id, BUILD_ID_INVALID) != 0)
+ p += sprintf (p, " build-id=\"%s\"", hex_enc_build_id);
+ p += sprintf(p, "/>");
free (name);
}
else if (lm_prev == 0)
@@ -5819,6 +6179,7 @@ linux_qxfer_libraries_svr4 (const char *annex, unsigned char *readbuf,
memcpy (readbuf, document + offset, len);
xfree (document);
+ free_mapping_entry (data.list);
return len;
}
--
1.7.10.4
next prev parent reply other threads:[~2013-04-05 13:03 UTC|newest]
Thread overview: 79+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-02-22 15:07 [patch] gdbserver build-id in qxfer_libraries reply Aleksandar Ristovski
2013-02-22 18:39 ` Aleksandar Ristovski
2013-02-26 12:01 ` Pedro Alves
2013-02-27 17:25 ` Aleksandar Ristovski
2013-02-27 17:31 ` Aleksandar Ristovski
2013-02-27 18:44 ` Eli Zaretskii
2013-03-10 21:07 ` [draft patch 0/6] Split FYI and some review notes Jan Kratochvil
2013-03-11 14:25 ` Aleksandar Ristovski
2013-03-11 15:07 ` Jan Kratochvil
2013-03-14 18:43 ` Gary Benson
2013-03-14 19:55 ` Tom Tromey
2013-03-15 15:35 ` Aleksandar Ristovski
2013-03-15 15:44 ` Aleksandar Ristovski
2013-03-15 15:38 ` Aleksandar Ristovski
2013-03-15 16:28 ` Jan Kratochvil
2013-03-15 16:43 ` Aleksandar Ristovski
2013-03-10 21:08 ` [draft patch 1/6] Move utility functions to common/ Jan Kratochvil
2013-03-22 13:13 ` [patch " Aleksandar Ristovski
2013-03-22 13:05 ` Aleksandar Ristovski
2013-04-07 18:54 ` Aleksandar Ristovski
2013-04-05 13:06 ` Aleksandar Ristovski
2013-03-10 21:08 ` [draft patch 3/6] Create empty common/linux-maps.[ch] Jan Kratochvil
2013-03-22 14:54 ` [patch " Aleksandar Ristovski
2013-03-22 13:06 ` Aleksandar Ristovski
2013-04-05 13:25 ` Aleksandar Ristovski
2013-03-10 21:08 ` [draft patch 4/6] Prepare linux_find_memory_regions_full & co. for move Jan Kratochvil
2013-03-22 13:34 ` [patch " Aleksandar Ristovski
2013-03-22 13:54 ` Aleksandar Ristovski
2013-03-26 18:11 ` Jan Kratochvil
2013-03-27 20:44 ` Aleksandar Ristovski
2013-03-27 21:54 ` Aleksandar Ristovski
2013-03-28 23:02 ` Jan Kratochvil
2013-03-29 0:26 ` Aleksandar Ristovski
2013-03-29 0:29 ` Pedro Alves
2013-04-01 22:39 ` Aleksandar Ristovski
2013-04-01 21:13 ` Aleksandar Ristovski
2013-04-02 13:41 ` Jan Kratochvil
2013-04-02 13:41 ` Aleksandar Ristovski
2013-04-02 13:41 ` Jan Kratochvil
2013-04-05 15:37 ` Aleksandar Ristovski
2013-04-07 14:28 ` Aleksandar Ristovski
2013-03-10 21:08 ` [draft patch 2/6] Merge multiple hex conversions Jan Kratochvil
2013-03-22 13:05 ` [patch " Aleksandar Ristovski
2013-04-05 16:07 ` Aleksandar Ristovski
2013-03-10 21:09 ` [draft patch 6/6] gdbserver build-id attribute generator (unfixed) Jan Kratochvil
2013-03-10 22:04 ` Eli Zaretskii
2013-03-22 13:05 ` [patch 6/6] gdbserver build-id attribute generator Aleksandar Ristovski
2013-03-22 15:19 ` Aleksandar Ristovski
2013-03-22 17:24 ` Eli Zaretskii
2013-03-26 23:45 ` Jan Kratochvil
2013-03-27 17:54 ` Aleksandar Ristovski
2013-03-27 18:08 ` Jan Kratochvil
2013-03-27 18:12 ` Eli Zaretskii
2013-03-27 20:46 ` Aleksandar Ristovski
2013-03-29 0:13 ` Aleksandar Ristovski
2013-03-29 0:20 ` Aleksandar Ristovski
2013-03-29 16:19 ` Jan Kratochvil
[not found] ` <20130331174322.GB21374@host2.jankratochvil.net>
2013-04-02 17:18 ` Aleksandar Ristovski
2013-04-04 2:22 ` Jan Kratochvil
2013-04-05 15:05 ` Aleksandar Ristovski [this message]
2013-04-09 15:28 ` Gary Benson
2013-04-09 15:28 ` Jan Kratochvil
2013-04-09 15:29 ` Aleksandar Ristovski
2013-04-09 15:29 ` Gary Benson
2013-04-09 15:28 ` Aleksandar Ristovski
2013-04-09 19:26 ` Gary Benson
2013-04-12 15:28 ` Jan Kratochvil
2013-03-10 21:09 ` [draft patch 5/6] Move linux_find_memory_regions_full & co Jan Kratochvil
2013-03-22 13:05 ` [patch " Aleksandar Ristovski
2013-03-22 13:34 ` Aleksandar Ristovski
2013-03-26 18:27 ` Jan Kratochvil
2013-03-27 21:25 ` Aleksandar Ristovski
2013-03-28 22:38 ` Jan Kratochvil
2013-04-01 23:19 ` Aleksandar Ristovski
2013-04-02 2:33 ` Jan Kratochvil
2013-04-07 18:54 ` Aleksandar Ristovski
2013-04-05 15:37 ` Aleksandar Ristovski
2013-04-02 2:33 ` Aleksandar Ristovski
2013-04-04 16:08 ` [patch] gdbserver build-id in qxfer_libraries reply Jan Kratochvil
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=515ECB30.5010504@qnx.com \
--to=aristovski@qnx.com \
--cc=gdb-patches@sourceware.org \
--cc=jan.kratochvil@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox