OLD | NEW |
(Empty) | |
| 1 /* |
| 2 * Copyright (c) 2013 The Native Client Authors. All rights reserved. |
| 3 * Use of this source code is governed by a BSD-style license that can be |
| 4 * found in the LICENSE file. |
| 5 */ |
| 6 |
| 7 #include <assert.h> |
| 8 #include <string.h> |
| 9 |
| 10 #include "native_client/src/include/elf32.h" |
| 11 |
| 12 |
| 13 /* |
| 14 * The next-generation (upstream) linkers define this symbol when the |
| 15 * ELF file and program headers are visible in the address space. We |
| 16 * use a weak reference to be compatible with the old nacl-binutils |
| 17 * linkers and layout, where this symbol is not defined and the |
| 18 * headers are not visible in the address space. |
| 19 */ |
| 20 extern const Elf32_Ehdr __ehdr_start __attribute__((weak)); |
| 21 |
| 22 static uintptr_t note_align(uintptr_t value) { |
| 23 return (value + 3) & ~3; |
| 24 } |
| 25 |
| 26 int nacl_get_build_id(const char **data, size_t *size) { |
| 27 if (&__ehdr_start != NULL && |
| 28 __ehdr_start.e_ident[EI_CLASS] == ELFCLASS32 && |
| 29 __ehdr_start.e_phentsize == sizeof(Elf32_Phdr)) { |
| 30 int phnum = __ehdr_start.e_phnum; |
| 31 uintptr_t start_addr = (uintptr_t) &__ehdr_start; |
| 32 Elf32_Phdr *phdrs = (Elf32_Phdr *) (start_addr + __ehdr_start.e_phoff); |
| 33 for (int i = 0; i < phnum; ++i) { |
| 34 Elf32_Phdr *phdr = &phdrs[i]; |
| 35 if (phdr->p_type == PT_NOTE) { |
| 36 Elf32_Nhdr *note = (Elf32_Nhdr *) (start_addr + phdr->p_offset); |
| 37 uintptr_t note_end = (uintptr_t) note + phdr->p_memsz; |
| 38 while ((uintptr_t) note < note_end) { |
| 39 uintptr_t name_ptr = (uintptr_t) ¬e[1]; |
| 40 assert(name_ptr <= note_end); |
| 41 uintptr_t desc_ptr = note_align(name_ptr + note->n_namesz); |
| 42 uintptr_t next_ptr = note_align(desc_ptr + note->n_descsz); |
| 43 assert(next_ptr <= note_end); |
| 44 if (note->n_type == NT_GNU_BUILD_ID && |
| 45 note->n_namesz == sizeof(ELF_NOTE_GNU) && |
| 46 memcmp((const char *) name_ptr, ELF_NOTE_GNU, |
| 47 sizeof(ELF_NOTE_GNU)) == 0) { |
| 48 *data = (const char *) desc_ptr; |
| 49 *size = note->n_descsz; |
| 50 return 1; |
| 51 } |
| 52 note = (Elf32_Nhdr *) next_ptr; |
| 53 } |
| 54 } |
| 55 } |
| 56 } |
| 57 return 0; |
| 58 } |
OLD | NEW |