Ejemplo n.º 1
0
static int
check_notes (Dwfl_Module *mod, bool set, Elf_Data *data, GElf_Addr data_vaddr)
{
  size_t pos = 0;
  GElf_Nhdr nhdr;
  size_t name_pos;
  size_t desc_pos;
  while ((pos = gelf_getnote (data, pos, &nhdr, &name_pos, &desc_pos)) > 0)
    if (nhdr.n_type == NT_GNU_BUILD_ID
	&& nhdr.n_namesz == sizeof "GNU" && !memcmp (data->d_buf + name_pos,
						     "GNU", sizeof "GNU"))
      return found_build_id (mod, set,
			     data->d_buf + desc_pos, nhdr.n_descsz,
			     data_vaddr == NO_VADDR ? 0
			     : data_vaddr + desc_pos);
  return 0;
}
Ejemplo n.º 2
0
/** Get the build-id (NT_GNU_BUILD_ID) from the ELF file
 *
 *  This build-id may is used to locate an external debug (DWARF) file
 *  for this ELF file.
 *
 *  @param  elf libelf handle for an ELF file
 *  @return build-id for this ELF file (or an empty vector if none is found)
 */
static
std::vector<char> get_build_id(Elf* elf)
{
#ifdef __linux
  // Summary: the GNU build ID is stored in a ("GNU, NT_GNU_BUILD_ID) note
  // found in a PT_NOTE entry in the program header table.

  size_t phnum;
  if (elf_getphdrnum (elf, &phnum) != 0)
    xbt_die("Could not read program headers");

  // Iterate over the program headers and find the PT_NOTE ones:
  for (size_t i = 0; i < phnum; ++i) {
    GElf_Phdr phdr_temp;
    GElf_Phdr *phdr = gelf_getphdr(elf, i, &phdr_temp);
    if (phdr->p_type != PT_NOTE)
      continue;

    Elf_Data* data = elf_getdata_rawchunk(elf, phdr->p_offset, phdr->p_filesz, ELF_T_NHDR);

    // Iterate over the notes and find the NT_GNU_BUILD_ID one:
    size_t pos = 0;
    while (pos < data->d_size) {
      GElf_Nhdr nhdr;
      // Location of the name within Elf_Data:
      size_t name_pos;
      size_t desc_pos;
      pos = gelf_getnote(data, pos, &nhdr, &name_pos, &desc_pos);
      // A build ID note is identified by the pair ("GNU", NT_GNU_BUILD_ID)
      // (a namespace and a type within this namespace):
      if (nhdr.n_type == NT_GNU_BUILD_ID
          && nhdr.n_namesz == sizeof("GNU")
          && memcmp((char*) data->d_buf + name_pos, "GNU", sizeof("GNU")) == 0) {
        XBT_DEBUG("Found GNU/NT_GNU_BUILD_ID note");
        char* start = (char*) data->d_buf + desc_pos;
        char* end = (char*) start + nhdr.n_descsz;
        return std::vector<char>(start, end);
      }
    }

  }
#endif
  return std::vector<char>();
}
Ejemplo n.º 3
0
Archivo: elfp.c Proyecto: nwnk/elflets
static void *
get_buildid(Elf *elf, size_t *sz)
{
    Elf_Scn *scn;
    size_t notesz;
    size_t offset = 0;
    Elf_Data *data;
    GElf_Shdr shdr;

    scn = get_scn_named(elf, ".note.gnu.build-id", &shdr);
    if (!scn)
	return NULL;

    data = elf_getdata(scn, NULL);
    if (!data)
	return NULL;

    do {
	size_t nameoff;
	size_t descoff;
	GElf_Nhdr nhdr;
	char *name;

	notesz = gelf_getnote(data, offset, &nhdr, &nameoff, &descoff);
	if (!notesz)
	    break;
	offset += notesz;

	if (nhdr.n_type != NT_GNU_BUILD_ID)
	    continue;

	name = data->d_buf + nameoff;
	if (!name || strcmp(name, ELF_NOTE_GNU))
	    continue;

	*sz = nhdr.n_descsz;
	return data->d_buf + descoff;
    } while (notesz);
    return NULL;
}
Ejemplo n.º 4
0
short
get_signal_number(Elf *e, const char *elf_file)
{
    const char NOTE_CORE[] = "CORE";

    size_t nphdr;
    if (elf_getphdrnum(e, &nphdr) != 0)
    {
        warn_elf("elf_getphdrnum");
        return 0;
    }

    /* Go through phdrs, look for prstatus note */
    int i;
    for (i = 0; i < nphdr; i++)
    {
        GElf_Phdr phdr;
        if (gelf_getphdr(e, i, &phdr) != &phdr)
        {
            warn_elf("gelf_getphdr");
            continue;
        }

        if (phdr.p_type != PT_NOTE)
        {
            continue;
        }

        Elf_Data *data, *name_data, *desc_data;
        GElf_Nhdr nhdr;
        size_t note_offset = 0;
        size_t name_offset, desc_offset;
        /* Elf_Data buffers are freed when elf_end is called. */
        data = elf_getdata_rawchunk(e, phdr.p_offset, phdr.p_filesz,
                                    ELF_T_NHDR);
        if (!data)
        {
            warn_elf("elf_getdata_rawchunk");
            continue;
        }

        while ((note_offset = gelf_getnote(data, note_offset, &nhdr,
                                           &name_offset, &desc_offset)) != 0)
        {
            /*
            printf("Note: type:%x name:%x+%d desc:%x+%d\n", nhdr.n_type,
                   name_offset, nhdr.n_namesz, desc_offset, nhdr.n_descsz);
            */

            if (nhdr.n_type != NT_PRSTATUS
                || nhdr.n_namesz < sizeof(NOTE_CORE))
                continue;

            name_data = elf_getdata_rawchunk(e, phdr.p_offset + name_offset,
                                             nhdr.n_namesz, ELF_T_BYTE);
            desc_data = elf_getdata_rawchunk(e, phdr.p_offset + desc_offset,
                                             nhdr.n_descsz, ELF_T_BYTE);
            if (!(name_data && desc_data))
                continue;

            if (name_data->d_size < sizeof(NOTE_CORE))
                continue;

            if (strcmp(NOTE_CORE, name_data->d_buf))
                continue;

            if (desc_data->d_size != sizeof(struct elf_prstatus))
            {
                warn("PRSTATUS core note of size %zu found, expected size: %zu",
                    desc_data->d_size, sizeof(struct elf_prstatus));
                continue;
            }

            struct elf_prstatus *prstatus = (struct elf_prstatus*)desc_data->d_buf;
            short signal = prstatus->pr_cursig;
            if (signal)
                return signal;
        }
    }

    return 0;
}