Skip to content

Commit

Permalink
bpf: Add size arg to build_id_parse function
Browse files Browse the repository at this point in the history
It's possible to have other build id types (other than default SHA1).
Currently there's also ld support for MD5 build id.

Adding size argument to build_id_parse function, that returns (if defined)
size of the parsed build id, so we can recognize the build id type.

Signed-off-by: Jiri Olsa <[email protected]>
Signed-off-by: Alexei Starovoitov <[email protected]>
Link: https://lore.kernel.org/bpf/[email protected]
  • Loading branch information
olsajiri authored and Alexei Starovoitov committed Jan 15, 2021
1 parent bd7525d commit 921f88f
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 10 deletions.
3 changes: 2 additions & 1 deletion include/linux/buildid.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#define BUILD_ID_SIZE_MAX 20

int build_id_parse(struct vm_area_struct *vma, unsigned char *build_id);
int build_id_parse(struct vm_area_struct *vma, unsigned char *build_id,
__u32 *size);

#endif
2 changes: 1 addition & 1 deletion kernel/bpf/stackmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ static void stack_map_get_build_id_offset(struct bpf_stack_build_id *id_offs,

for (i = 0; i < trace_nr; i++) {
vma = find_vma(current->mm, ips[i]);
if (!vma || build_id_parse(vma, id_offs[i].build_id)) {
if (!vma || build_id_parse(vma, id_offs[i].build_id, NULL)) {
/* per entry fall back to ips */
id_offs[i].status = BPF_STACK_BUILD_ID_IP;
id_offs[i].ip = ips[i];
Expand Down
29 changes: 21 additions & 8 deletions lib/buildid.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
*/
static inline int parse_build_id(void *page_addr,
unsigned char *build_id,
__u32 *size,
void *note_start,
Elf32_Word note_size)
{
Expand All @@ -38,6 +39,8 @@ static inline int parse_build_id(void *page_addr,
nhdr->n_descsz);
memset(build_id + nhdr->n_descsz, 0,
BUILD_ID_SIZE_MAX - nhdr->n_descsz);
if (size)
*size = nhdr->n_descsz;
return 0;
}
new_offs = note_offs + sizeof(Elf32_Nhdr) +
Expand All @@ -50,7 +53,8 @@ static inline int parse_build_id(void *page_addr,
}

/* Parse build ID from 32-bit ELF */
static int get_build_id_32(void *page_addr, unsigned char *build_id)
static int get_build_id_32(void *page_addr, unsigned char *build_id,
__u32 *size)
{
Elf32_Ehdr *ehdr = (Elf32_Ehdr *)page_addr;
Elf32_Phdr *phdr;
Expand All @@ -65,7 +69,7 @@ static int get_build_id_32(void *page_addr, unsigned char *build_id)

for (i = 0; i < ehdr->e_phnum; ++i) {
if (phdr[i].p_type == PT_NOTE &&
!parse_build_id(page_addr, build_id,
!parse_build_id(page_addr, build_id, size,
page_addr + phdr[i].p_offset,
phdr[i].p_filesz))
return 0;
Expand All @@ -74,7 +78,8 @@ static int get_build_id_32(void *page_addr, unsigned char *build_id)
}

/* Parse build ID from 64-bit ELF */
static int get_build_id_64(void *page_addr, unsigned char *build_id)
static int get_build_id_64(void *page_addr, unsigned char *build_id,
__u32 *size)
{
Elf64_Ehdr *ehdr = (Elf64_Ehdr *)page_addr;
Elf64_Phdr *phdr;
Expand All @@ -89,16 +94,24 @@ static int get_build_id_64(void *page_addr, unsigned char *build_id)

for (i = 0; i < ehdr->e_phnum; ++i) {
if (phdr[i].p_type == PT_NOTE &&
!parse_build_id(page_addr, build_id,
!parse_build_id(page_addr, build_id, size,
page_addr + phdr[i].p_offset,
phdr[i].p_filesz))
return 0;
}
return -EINVAL;
}

/* Parse build ID of ELF file mapped to vma */
int build_id_parse(struct vm_area_struct *vma, unsigned char *build_id)
/*
* Parse build ID of ELF file mapped to vma
* @vma: vma object
* @build_id: buffer to store build id, at least BUILD_ID_SIZE long
* @size: returns actual build id size in case of success
*
* Returns 0 on success, otherwise error (< 0).
*/
int build_id_parse(struct vm_area_struct *vma, unsigned char *build_id,
__u32 *size)
{
Elf32_Ehdr *ehdr;
struct page *page;
Expand Down Expand Up @@ -126,9 +139,9 @@ int build_id_parse(struct vm_area_struct *vma, unsigned char *build_id)
goto out;

if (ehdr->e_ident[EI_CLASS] == ELFCLASS32)
ret = get_build_id_32(page_addr, build_id);
ret = get_build_id_32(page_addr, build_id, size);
else if (ehdr->e_ident[EI_CLASS] == ELFCLASS64)
ret = get_build_id_64(page_addr, build_id);
ret = get_build_id_64(page_addr, build_id, size);
out:
kunmap_atomic(page_addr);
put_page(page);
Expand Down

0 comments on commit 921f88f

Please sign in to comment.