Beispiel #1
0
static void elf_file_read_elf_header(struct elf_file_t *elf_file)
{
	struct elf_buffer_t *buffer;
	Elf32_Ehdr *elf_header;
	int count;

	/* Read ELF header */
	buffer = &elf_file->buffer;
	elf_file->header = buffer->ptr;
	elf_header = elf_file->header;
	count = elf_buffer_read(buffer, NULL, sizeof(Elf32_Ehdr));
	if (count < EI_NIDENT)
		fatal("%s: not a valid ELF file\n", elf_file->path);

	/* Check magic characters */
	if (elf_header->e_ident[0] != 0x7f
		|| elf_header->e_ident[1] != 'E'
		|| elf_header->e_ident[2] != 'L'
		|| elf_header->e_ident[3] != 'F')
		fatal("%s: not a valid ELF file\n", elf_file->path);

	/* Check for 32-bit executable (field e_ident[EI_CLASS]) */
	if (elf_header->e_ident[4] == 2)
		fatal("%s: not supported architecture.\n%s",
			elf_file->path, elf_err_64bit);
	
	/* Check that header size is correct */
	if (elf_header->e_ehsize != sizeof(Elf32_Ehdr))
		fatal("%s: invalid ELF header size", elf_file->path);

	/* Check endianness */
	if (elf_header->e_ident[5] != 1)
		fatal("%s: ELF file endianness mismatch", elf_file->path);
}
Beispiel #2
0
/* Read a line from 'buffer'.
 * The line is placed in 'str', which is a buffer of 'size' bytes.
 * The function returns the number of bytes read. */
int elf_buffer_read_line(struct elf_buffer_t *buffer, char *str, int size)
{
	int read_count = 0;
	int write_count = 0;

	for (;;) {

		/* If only 1 byte left, use it for null termination */
		if (size == 1) {
			*str = '\0';
			break;
		}

		/* Copy one character */
		read_count = elf_buffer_read(buffer, str, 1);
		if (!read_count) {
			*str = '\0';
			break;
		}
		if (*str == '\n' || *str == '\0') {
			*str = '\0';
			break;
		}

		/* Advance string */
		size--;
		str++;
		write_count++;
	}

	return write_count;
}
Beispiel #3
0
static void elf_file_read_program_headers(struct elf_file_t *elf_file)
{
	struct elf_buffer_t *buffer;
	struct elf_program_header_t *program_header;
	Elf32_Ehdr *elf_header;

	int count;
	int i;

	/* Create program header list */
	buffer = &elf_file->buffer;
	elf_header = elf_file->header;
	elf_file->program_header_list = list_create();
	if (!elf_header->e_phnum)
		return;

	/* Check program header size */
	if (elf_header->e_phentsize != sizeof(Elf32_Phdr))
		fatal("%s: program header size %d (should be %d)",
			elf_file->path, elf_header->e_phentsize, (int) sizeof(Elf32_Phdr));

	/* Read program headers */
	elf_buffer_seek(buffer, elf_header->e_phoff);
	for (i = 0; i < elf_header->e_phnum; i++)
	{
		/* Allocate program header */
		program_header = calloc(1, sizeof(struct elf_program_header_t));
		program_header->header = elf_buffer_tell(buffer);

		/* Advance buffer */
		count = elf_buffer_read(buffer, NULL, sizeof(Elf32_Phdr));
		if (count < sizeof(Elf32_Phdr))
			fatal("%s: unexpected end of file while reading program headers", elf_file->path);

		/* Add program header to list */
		list_add(elf_file->program_header_list, program_header);
	}

	/* Dump program headers */
	elf_debug("Program headers:\n");
	elf_debug("idx type       offset     vaddr      paddr      filesz    memsz     flags  align\n");
	for (i = 0; i < 80; i++)
		elf_debug("-");
	elf_debug("\n");
	for (i = 0; i < list_count(elf_file->program_header_list); i++) {
		program_header = list_get(elf_file->program_header_list, i);
		elf_debug("%-3d 0x%-8x 0x%-8x 0x%-8x 0x%-8x %-9u %-9u %-6u %u\n", i,
			program_header->header->p_type,
			program_header->header->p_offset,
			program_header->header->p_vaddr,
			program_header->header->p_paddr,
			program_header->header->p_filesz,
			program_header->header->p_memsz,
			program_header->header->p_flags,
			program_header->header->p_align);
	}
	elf_debug("\n");
}
Beispiel #4
0
static void elf_file_read_section_headers(struct elf_file_t *elf_file)
{
	int i, count;

	struct elf_buffer_t *buffer;
	struct elf_section_t *section;
	Elf32_Ehdr *elf_header;

	/* Create section list */
	elf_file->section_list = list_create();

	/* Check section size and number */
	buffer = &elf_file->buffer;
	elf_header = elf_file->header;
	if (!elf_header->e_shnum || elf_header->e_shentsize != sizeof(Elf32_Shdr))
		fatal("%s: number of sections is 0 or section size is not %d",
			elf_file->path, (int) sizeof(Elf32_Shdr));

	/* Read section headers */
	elf_buffer_seek(buffer, elf_header->e_shoff);
	for (i = 0; i < elf_header->e_shnum; i++)
	{
		/* Allocate section */
		section = xcalloc(1, sizeof(struct elf_section_t));
		section->header = elf_buffer_tell(buffer);

		/* Advance buffer */
		count = elf_buffer_read(buffer, NULL, sizeof(Elf32_Shdr));
		if (count < sizeof(Elf32_Shdr))
			fatal("%s: unexpected end of file while reading section headers", elf_file->path);

		/* Get section contents, if section type is not SHT_NOBITS (8) */
		if (section->header->sh_type != 8)
		{
			section->buffer.ptr = buffer->ptr + section->header->sh_offset;
			section->buffer.size = section->header->sh_size;
			section->buffer.pos = 0;
			assert(section->buffer.ptr >= buffer->ptr);
			if (section->buffer.ptr + section->buffer.size > buffer->ptr + buffer->size)
				fatal("section %d out of the ELF boundaries (offs=0x%x, size=%u, ELF_size=%u)",
						i, section->header->sh_offset, section->header->sh_size, buffer->size);
		}

		/* Add section to list */
		list_add(elf_file->section_list, section);
	}

	/* Read string table, and update section names */
	assert(elf_header->e_shstrndx < elf_header->e_shnum);
	elf_file->string_table = list_get(elf_file->section_list, elf_header->e_shstrndx);
	assert(elf_file->string_table->header->sh_type == 3);
	for (i = 0; i < list_count(elf_file->section_list); i++) {
		section = list_get(elf_file->section_list, i);
		section->name = elf_file->string_table->buffer.ptr + section->header->sh_name;
	}
}
Beispiel #5
0
static void elf_file_read_elf_header(struct elf_file_t *elf_file)
{
	struct elf_buffer_t *buffer;
	Elf32_Ehdr *elf_header;
	int count;

	/* Read ELF header */
	buffer = &elf_file->buffer;
	elf_file->header = buffer->ptr;
	elf_header = elf_file->header;
	count = elf_buffer_read(buffer, NULL, sizeof(Elf32_Ehdr));
	if (count < EI_NIDENT)
		fatal("%s: not a valid ELF file\n", elf_file->path);

	/* Check magic characters */
	if (elf_header->e_ident[0] != 0x7f
		|| elf_header->e_ident[1] != 'E'
		|| elf_header->e_ident[2] != 'L'
		|| elf_header->e_ident[3] != 'F')
		fatal("%s: not a valid ELF file\n", elf_file->path);

	/* Check for 32-bit executable (field e_ident[EI_CLASS]) */
	if (elf_header->e_ident[4] == 2)
		fatal("%s: not supported architecture.\n%s",
			elf_file->path, err_elf_64bit);
	
	/* Check that header size is correct */
	if (elf_header->e_ehsize != sizeof(Elf32_Ehdr))
		fatal("%s: invalid ELF header size", elf_file->path);

	/* Check endianness */
	if (elf_header->e_ident[5] != 1)
		fatal("%s: ELF file endianness mismatch", elf_file->path);

	/* Debug */
	elf_debug("ELF header:\n");
	elf_debug("  ehdr.e_ident: EI_CLASS=%d, EI_DATA=%d, EI_VERSION=%d\n",
		elf_header->e_ident[4], elf_header->e_ident[5], elf_header->e_ident[6]);
	elf_debug("  ehdr.e_type: %d\n", elf_header->e_type);
	elf_debug("  ehdr.e_machine: %u\n", elf_header->e_machine);
	elf_debug("  ehdr.e_entry: 0x%x (program entry point)\n", elf_header->e_entry);
	elf_debug("  ehdr.e_phoff: %u (program header table offset)\n", elf_header->e_phoff);
	elf_debug("  ehdr.e_shoff: %u (section header table offset)\n", elf_header->e_shoff);
	elf_debug("  ehdr.e_phentsize: %u\n", elf_header->e_phentsize);
	elf_debug("  ehdr.e_phnum: %u\n", elf_header->e_phnum);
	elf_debug("  ehdr.e_shentsize: %u\n", elf_header->e_shentsize);
	elf_debug("  ehdr.e_shnum: %u\n", elf_header->e_shnum);
	elf_debug("  ehdr.e_shstrndx: %u\n", (uint32_t) elf_header->e_shstrndx);
	elf_debug("\n");
}
Beispiel #6
0
static void elf_file_read_program_headers(struct elf_file_t *elf_file)
{
	struct elf_buffer_t *buffer;
	struct elf_program_header_t *program_header;
	Elf32_Ehdr *elf_header;

	int count;
	int i;

	/* Create program header list */
	buffer = &elf_file->buffer;
	elf_header = elf_file->header;
	elf_file->program_header_list = list_create();
	if (!elf_header->e_phnum)
		return;

	/* Check program header size */
	if (elf_header->e_phentsize != sizeof(Elf32_Phdr))
		fatal("%s: program header size %d (should be %d)",
			elf_file->path, elf_header->e_phentsize, (int) sizeof(Elf32_Phdr));

	/* Read program headers */
	elf_buffer_seek(buffer, elf_header->e_phoff);
	for (i = 0; i < elf_header->e_phnum; i++)
	{
		/* Allocate program header */
		program_header = xcalloc(1, sizeof(struct elf_program_header_t));
		program_header->header = elf_buffer_tell(buffer);

		/* Advance buffer */
		count = elf_buffer_read(buffer, NULL, sizeof(Elf32_Phdr));
		if (count < sizeof(Elf32_Phdr))
			fatal("%s: unexpected end of file while reading program headers", elf_file->path);

		/* Add program header to list */
		list_add(elf_file->program_header_list, program_header);
	}
}
Beispiel #7
0
static void si_bin_file_read_enc_dict(struct si_bin_file_t *bin_file)
{
    struct elf_file_t *elf_file;
    struct elf_buffer_t *buffer;
    Elf32_Ehdr *elf_header;

    struct elf_program_header_t *program_header;

    struct si_bin_enc_dict_entry_t *enc_dict_entry;
    struct si_bin_enc_dict_entry_header_t *enc_dict_entry_header;
    int enc_dict_entry_count;

    int i;

    /* ELF header */
    elf_file = bin_file->elf_file;
    elf_header = elf_file->header;
    buffer = &elf_file->buffer;
    elf_debug("**\n** Parsing AMD Binary (Internal ELF file)\n** %s\n**\n\n", elf_file->path);
    SI_BIN_FILE_NOT_SUPPORTED_NEQ(elf_header->e_ident[EI_CLASS], ELFCLASS32);
    SI_BIN_FILE_NOT_SUPPORTED_NEQ(elf_header->e_ident[EI_DATA], ELFDATA2LSB);
    SI_BIN_FILE_NOT_SUPPORTED_NEQ(elf_header->e_ident[EI_OSABI], 0x64);
    SI_BIN_FILE_NOT_SUPPORTED_NEQ(elf_header->e_ident[EI_ABIVERSION], 1);
    SI_BIN_FILE_NOT_SUPPORTED_NEQ(elf_header->e_type, ET_EXEC);
    SI_BIN_FILE_NOT_SUPPORTED_NEQ(elf_header->e_machine, 0x7d);
    SI_BIN_FILE_NOT_SUPPORTED_NEQ(elf_header->e_entry, 0);

    /* Look for encoding dictionary (program header with type 'PT_LOPROC+2') */
    program_header = NULL;
    for (i = 0; i < list_count(elf_file->program_header_list); i++)
    {
        program_header = list_get(elf_file->program_header_list, i);
        if (program_header->header->p_type == PT_LOPROC + 2)
            break;
    }
    if (i == list_count(elf_file->program_header_list) || !program_header)
        fatal("%s: no encoding dictionary", elf_file->path);
    elf_debug("Encoding dictionary found in program header %d\n", i);

    /* Parse encoding dictionary */
    SI_BIN_FILE_NOT_SUPPORTED_NEQ(program_header->header->p_vaddr, 0);
    SI_BIN_FILE_NOT_SUPPORTED_NEQ(program_header->header->p_paddr, 0);
    SI_BIN_FILE_NOT_SUPPORTED_NEQ(program_header->header->p_memsz, 0);
    SI_BIN_FILE_NOT_SUPPORTED_NEQ(program_header->header->p_flags, 0);
    SI_BIN_FILE_NOT_SUPPORTED_NEQ(program_header->header->p_align, 0);
    assert(program_header->header->p_filesz % sizeof(struct si_bin_enc_dict_entry_header_t) == 0);
    enc_dict_entry_count = program_header->header->p_filesz / sizeof(struct si_bin_enc_dict_entry_header_t);
    elf_debug("  -> %d entries\n\n", enc_dict_entry_count);

    /* Read encoding dictionary entries */
    bin_file->enc_dict = list_create();
    elf_buffer_seek(buffer, program_header->header->p_offset);
    for (i = 0; i < enc_dict_entry_count; i++) {

        /* Create entry */
        enc_dict_entry = calloc(1, sizeof(struct si_bin_enc_dict_entry_t));
        enc_dict_entry->header = elf_buffer_tell(buffer);
        elf_buffer_read(buffer, NULL, sizeof(struct si_bin_enc_dict_entry_header_t));
        list_add(bin_file->enc_dict, enc_dict_entry);

        /* Store encoding dictionary entry for Evergreen (code 9) */
        if (enc_dict_entry->header->d_machine == 9)
        {
            bin_file->enc_dict_entry_southern_islands = enc_dict_entry;
        }
        else if (enc_dict_entry->header->d_machine == 26)
        {
            /* Southern Islands has code 26 */
            bin_file->enc_dict_entry_southern_islands = enc_dict_entry;
        }
    }

    /* Debug */
    elf_debug("idx %-15s %-10s %-10s %-10s %-10s\n", "d_machine", "d_type",
              "d_offset", "d_size", "d_flags");
    for (i = 0; i < 80; i++)
        elf_debug("-");
    elf_debug("\n");
    for (i = 0; i < list_count(bin_file->enc_dict); i++)
    {
        char machine_str[MAX_STRING_SIZE];

        enc_dict_entry = list_get(bin_file->enc_dict, i);
        enc_dict_entry_header = enc_dict_entry->header;
        snprintf(machine_str, sizeof(machine_str), "%d (%s)",
                 enc_dict_entry_header->d_machine, map_value(&enc_dict_machine_map,
                         enc_dict_entry_header->d_machine - 1));
        elf_debug("%3d %-15s 0x%-8x 0x%-8x %-10d 0x%-8x\n",
                  i, machine_str,
                  enc_dict_entry_header->d_type,
                  enc_dict_entry_header->d_offset,
                  enc_dict_entry_header->d_size,
                  enc_dict_entry_header->d_flags);
    }
    elf_debug("\n\n");
}
Beispiel #8
0
/* Read next note at the current position of the PT_NOTE segment */
static void si_bin_file_read_note_header(struct si_bin_file_t *bin_file, struct si_bin_enc_dict_entry_t *enc_dict_entry)
{
    struct elf_buffer_t *buffer;

    struct pt_note_header_t *header;
    void *desc;

    int count;
    char *note_type_str;

    /* Read note header */
    buffer = &enc_dict_entry->pt_note_buffer;
    header = elf_buffer_tell(buffer);
    count = elf_buffer_read(buffer, NULL, sizeof(struct pt_note_header_t));
    if (count < sizeof(struct pt_note_header_t))
        fatal("%s: error decoding note header", bin_file->elf_file->path);

    /* Read note description (payload) */
    desc = elf_buffer_tell(buffer);
    count = elf_buffer_read(buffer, NULL, header->descsz);
    if (count < header->descsz)
        fatal("%s: error decoding note description", bin_file->elf_file->path);

    /* Debug */
    note_type_str = map_value(&pt_note_type_map, header->type);
    elf_debug("  note: type=%d (%s), descsz=%d\n",
              header->type, note_type_str, header->descsz);

    /* Analyze note */
    switch (header->type)
    {

    case 1:  /* ELF_NOTE_ATI_PROGINFO */
    {
        int prog_info_count;
        struct pt_note_prog_info_entry_t *prog_info_entry;
        int i;

        /* Get number of entries */
        assert(header->descsz % sizeof(struct pt_note_prog_info_entry_t) == 0);
        prog_info_count = header->descsz / sizeof(struct pt_note_prog_info_entry_t);
        elf_debug("\tnote including device configuration unique to the program (%d entries)\n",
                  prog_info_count);

        /* Decode entries */
        for (i = 0; i < prog_info_count; i++)
        {
            prog_info_entry = desc + i * sizeof(struct pt_note_prog_info_entry_t);
            elf_debug("\tprog_info_entry: addr=0x%x (%s), value=%u\n",
                      prog_info_entry->address, map_value(&prog_info_entry_map,
                              prog_info_entry->address), prog_info_entry->value);

            /* Analyze entry */
            switch (prog_info_entry->address)
            {

            case 0x00002e13:  /* COMPUTE_PGM_RSRC2 */
                enc_dict_entry->compute_pgm_rsrc2 = (struct si_bin_compute_pgm_rsrc2_t*)&prog_info_entry->value;
                break;

            case 0x80000080:  /* AMU_ABI_NUM_GPR_USED */
                enc_dict_entry->num_gpr_used = prog_info_entry->value;
                break;

            case 0x80000082:  /* AMU_ABI_LDS_SIZE_USED */
                enc_dict_entry->lds_size_used = prog_info_entry->value;
                break;

            case 0x80000084:  /* AMU_ABI_STACK_SIZE_USED */
                enc_dict_entry->stack_size_used = prog_info_entry->value;
                break;
            case 0x80001000:  /* AMU_ABI_USER_ELEMENT_COUNT */
                enc_dict_entry->userElementCount = prog_info_entry->value;
                i++;

                /* Analyze user elements */
                for(int j = 0; j < 4 * enc_dict_entry->userElementCount; j++)
                {
                    prog_info_entry = desc + i * sizeof(struct pt_note_prog_info_entry_t);
                    elf_debug("\tprog_info_entry: addr=0x%x (%s), value=%u\n",
                              prog_info_entry->address, map_value(&prog_info_entry_map,
                                      prog_info_entry->address), prog_info_entry->value);
                    switch(j % 4)
                    {
                    case 0:
                        enc_dict_entry->userElements[j / 4].dataClass = prog_info_entry->value;
                        break;
                    case 1:
                        enc_dict_entry->userElements[j / 4].apiSlot = prog_info_entry->value;
                        break;
                    case 2:
                        enc_dict_entry->userElements[j / 4].startUserReg = prog_info_entry->value;
                        break;
                    case 3:
                        enc_dict_entry->userElements[j / 4].userRegCount = prog_info_entry->value;
                        break;
                    }

                    i++;
                }
                break;
            }
        }
        break;
    }


    case 2:  /* ELF_NOTE_ATI_INPUTS */
    {
        /* FIXME: Analyze program inputs */
        if (header->descsz)
            warning("%s: pt_note '%s' with descsz != 0 ignored (desc value = 0x%x)",
                    note_type_str, __FUNCTION__, * (unsigned int *) desc);

        break;
    }


    case 3:  /* ELF_NOTE_ATI_OUTPUTS */
    {
        /* FIXME: Analyze program inputs */
        if (header->descsz)
            warning("%s: pt_note '%s' with descsz != 0 ignored (desc value = 0x%x)",
                    note_type_str, __FUNCTION__, * (unsigned int *) desc);

        break;
    }


    case 4:  /* ELF_NOTE_ATI_CONDOUT */
        break;

    case 5:  /* ELF_NOTE_ATI_FLOAT32CONSTS */
    case 6:  /* ELF_NOTE_ATI_INT32CONSTS */
    case 7:  /* ELF_NOTE_ATI_BOOL32CONSTS */
    {
        int data_segment_desc_count;
        struct pt_note_data_segment_desc_t *data_segment_desc;

        struct si_bin_enc_dict_entry_consts_t *consts;
        char const_value[MAX_STRING_SIZE];

        int j;

        /* Get number of entries */
        consts = enc_dict_entry->consts;
        assert(header->descsz % sizeof(struct pt_note_data_segment_desc_t) == 0);
        data_segment_desc_count = header->descsz / sizeof(struct pt_note_data_segment_desc_t);
        elf_debug("\tnote including data for constant buffers (%d entries)\n",
                  data_segment_desc_count);

        /* Decode entries */
        for (j = 0; j < data_segment_desc_count; j++)
        {
            data_segment_desc = desc + j * sizeof(struct pt_note_data_segment_desc_t);
            if (header->type == 5)
                snprintf(const_value, sizeof(const_value), "{%g,%g,%g,%g}",
                         consts->float_consts[data_segment_desc->offset][0],
                         consts->float_consts[data_segment_desc->offset][1],
                         consts->float_consts[data_segment_desc->offset][2],
                         consts->float_consts[data_segment_desc->offset][3]);
            else if (header->type == 6)
                snprintf(const_value, sizeof(const_value), "{%u,%u,%u,%u}",
                         consts->int_consts[data_segment_desc->offset][0],
                         consts->int_consts[data_segment_desc->offset][1],
                         consts->int_consts[data_segment_desc->offset][2],
                         consts->int_consts[data_segment_desc->offset][3]);
            else
                snprintf(const_value, sizeof(const_value), "%d",
                         consts->bool_consts[data_segment_desc->offset]);
            elf_debug("\tdata_segment_desc[%d]: offset=0x%x, size=%d, value=%s\n",
                      j, data_segment_desc->offset, data_segment_desc->size, const_value);
        }
        break;
    }


    case 8:  /* ELF_NOTE_ATI_EARLYEXIT */
    {
        Elf32_Word early_exit;

        /* Get 'early_exit' value */
        early_exit = header->descsz ? * (uint32_t *) desc : 0;
        elf_debug("\tearly_exit = %s\n", early_exit ? "TRUE" : "FALSE");
        break;
    }


    case 9:  /* ELF_NOTE_ATI_GLOBAL_BUFFERS */
    {
        Elf32_Word global_buffers;
        global_buffers = header->descsz ? * (uint32_t *) desc : 0;
        elf_debug("\tglobal_buffers = %s\n", global_buffers ? "TRUE" : "FALSE");
        break;
    }


    case 10:  /* ELF_NOTE_ATI_CONSTANT_BUFFERS */
    {
        int constant_buffer_count;
        struct pt_note_constant_buffer_mask_t *constant_buffer_mask;
        int i;

        /* Get number of entries */
        assert(header->descsz % sizeof(struct pt_note_constant_buffer_mask_t) == 0);
        constant_buffer_count = header->descsz / sizeof(struct pt_note_constant_buffer_mask_t);
        elf_debug("\tnote including number and size of constant buffers (%d entries)\n",
                  constant_buffer_count);

        /* Decode entries */
        for (i = 0; i < constant_buffer_count; i++) {
            constant_buffer_mask = desc + i * sizeof(struct pt_note_constant_buffer_mask_t);
            elf_debug("\tconstant_buffer[%d].size = %d (vec4f constants)\n",
                      constant_buffer_mask->index, constant_buffer_mask->size);
        }
        break;
    }


    case 11:  /* ELF_NOTE_ATI_INPUT_SAMPLERS */
        break;

    case 12:  /* ELF_NOTE_ATI_PERSISTENT_BUFFERS */
    {
        Elf32_Word persistent_buffers;
        persistent_buffers = header->descsz ? * (uint32_t *) desc : 0;
        elf_debug("\tpersistent_buffers = %s\n", persistent_buffers ? "TRUE" : "FALSE");
        break;
    }


    case 13:  /* ELF_NOTE_ATI_SCRATCH_BUFFERS */
    {
        Elf32_Word scratch_buffers;
        scratch_buffers = header->descsz ? * (uint32_t *) desc : 0;
        elf_debug("\tscratch_buffers = %s\n", scratch_buffers ? "TRUE" : "FALSE");
        break;
    }


    case 14:  /* ELF_NOTE_ATI_SUB_CONSTANT_BUFFERS */
        break;

    case 15:  /* ELF_NOTE_ATI_UAV_MAILBOX_SIZE */
        break;

    case 16:  /* ELF_NOTE_ATI_UAV */
    {
        int uav_entry_count;
        struct pt_note_uav_entry_t *uav_entry;
        int i;

        assert(header->descsz % sizeof(struct pt_note_uav_entry_t) == 0);
        uav_entry_count = header->descsz / sizeof(struct pt_note_uav_entry_t);
        elf_debug("\tnote (%d entries)\n", uav_entry_count);

        /* Decode entries */
        for (i = 0; i < uav_entry_count; i++) {
            uav_entry = desc + i * sizeof(struct pt_note_uav_entry_t);
            elf_debug("\tuav_entry[%d].uav = %d [%d, %d, %d]\n", i, uav_entry->id,
                      uav_entry->unknown1, uav_entry->unknown2, uav_entry->unknown3);
        }
        break;
    }


    case 17:  /* ELF_NOTE_ATI_UAV_OP_MASK */
        break;

    default:
        elf_debug("\tunknown type\n");
    }
}
Beispiel #9
0
static void si_bin_file_read_enc_dict(struct si_bin_file_t *bin_file) {
  struct elf_file_t *elf_file;
  struct elf_buffer_t *buffer;
  Elf32_Ehdr *elf_header;

  struct elf_program_header_t *program_header;

  struct si_bin_enc_dict_entry_t *enc_dict_entry;
  struct si_bin_enc_dict_entry_header_t *enc_dict_entry_header;
  int enc_dict_entry_count;

  int i;

  /* ELF header */
  elf_file = bin_file->elf_file;
  elf_header = elf_file->header;
  buffer = &elf_file->buffer;
  elf_debug("**\n** Parsing AMD Binary (Internal ELF file)\n** %s\n**\n\n",
            elf_file->path);
  SI_BIN_FILE_NOT_SUPPORTED_NEQ(elf_header->e_ident[EI_CLASS], ELFCLASS32);
  SI_BIN_FILE_NOT_SUPPORTED_NEQ(elf_header->e_ident[EI_DATA], ELFDATA2LSB);
  SI_BIN_FILE_NOT_SUPPORTED_NEQ(elf_header->e_ident[EI_OSABI], 0x64);
  SI_BIN_FILE_NOT_SUPPORTED_NEQ(elf_header->e_ident[EI_ABIVERSION], 1);
  SI_BIN_FILE_NOT_SUPPORTED_NEQ(elf_header->e_type, ET_EXEC);
  SI_BIN_FILE_NOT_SUPPORTED_NEQ(elf_header->e_machine, 0x7d);
  SI_BIN_FILE_NOT_SUPPORTED_NEQ(elf_header->e_entry, 0);

  /* Look for encoding dictionary (program header with type 'PT_LOPROC+2') */
  program_header = NULL;
  for (i = 0; i < list_count(elf_file->program_header_list); i++) {
    program_header = list_get(elf_file->program_header_list, i);
    if (program_header->header->p_type == PT_LOPROC + 2) break;
  }
  if (i == list_count(elf_file->program_header_list) || !program_header)
    fatal("%s: no encoding dictionary", elf_file->path);
  elf_debug("Encoding dictionary found in program header %d\n", i);

  /* Parse encoding dictionary */
  SI_BIN_FILE_NOT_SUPPORTED_NEQ(program_header->header->p_vaddr, 0);
  SI_BIN_FILE_NOT_SUPPORTED_NEQ(program_header->header->p_paddr, 0);
  SI_BIN_FILE_NOT_SUPPORTED_NEQ(program_header->header->p_memsz, 0);
  SI_BIN_FILE_NOT_SUPPORTED_NEQ(program_header->header->p_flags, 0);
  SI_BIN_FILE_NOT_SUPPORTED_NEQ(program_header->header->p_align, 0);
  assert(program_header->header->p_filesz %
             sizeof(struct si_bin_enc_dict_entry_header_t) ==
         0);
  enc_dict_entry_count = program_header->header->p_filesz /
                         sizeof(struct si_bin_enc_dict_entry_header_t);
  elf_debug("  -> %d entries\n\n", enc_dict_entry_count);

  /* Read encoding dictionary entries */
  bin_file->enc_dict = list_create();
  elf_buffer_seek(buffer, program_header->header->p_offset);
  for (i = 0; i < enc_dict_entry_count; i++) {
    /* Create entry */
    enc_dict_entry = xcalloc(1, sizeof(struct si_bin_enc_dict_entry_t));
    enc_dict_entry->header = elf_buffer_tell(buffer);
    elf_buffer_read(buffer, NULL,
                    sizeof(struct si_bin_enc_dict_entry_header_t));
    list_add(bin_file->enc_dict, enc_dict_entry);

    /* Store encoding dictionary entry for Southern Islands.
     * Apparently the valid code changes by driver version */
    if (enc_dict_entry->header->d_machine == 9) {
      /* Driver XXX */
      elf_debug("machine = %d (tahiti or pitcairn)\n",
                enc_dict_entry->header->d_machine);
      bin_file->enc_dict_entry_southern_islands = enc_dict_entry;
    } else if (enc_dict_entry->header->d_machine == 25) {
      /* This entry is always present but doesn't seem
       * useful information.  We should probably figure
       * out what is stored here. */
      elf_debug("machine = 25 (skip this entry)\n");
    } else if (enc_dict_entry->header->d_machine == 26) {
      /* Driver XXX */
      elf_debug("machine = %d (tahiti or pitcairn)\n",
                enc_dict_entry->header->d_machine);
      bin_file->enc_dict_entry_southern_islands = enc_dict_entry;
    } else if (enc_dict_entry->header->d_machine == 27) {
      /* Driver 12.4 */
      elf_debug("machine = %d (tahiti or pitcairn)\n",
                enc_dict_entry->header->d_machine);
      bin_file->enc_dict_entry_southern_islands = enc_dict_entry;
    } else if (enc_dict_entry->header->d_machine == 28) {
      elf_debug("machine = %d (capeverde)\n",
                enc_dict_entry->header->d_machine);
      bin_file->enc_dict_entry_southern_islands = enc_dict_entry;
    } else {
      fatal("%s: unknown machine number (%d)\n", __FUNCTION__,
            enc_dict_entry->header->d_machine);
    }
  }

  /* Debug */
  elf_debug("idx %-15s %-10s %-10s %-10s %-10s\n", "d_machine", "d_type",
            "d_offset", "d_size", "d_flags");
  for (i = 0; i < 80; i++) elf_debug("-");
  elf_debug("\n");
  for (i = 0; i < list_count(bin_file->enc_dict); i++) {
    char machine_str[MAX_STRING_SIZE];

    enc_dict_entry = list_get(bin_file->enc_dict, i);
    enc_dict_entry_header = enc_dict_entry->header;
    snprintf(machine_str, sizeof(machine_str), "%d (%s)",
             enc_dict_entry_header->d_machine,
             str_map_value(&enc_dict_machine_map,
                           enc_dict_entry_header->d_machine - 1));
    elf_debug("%3d %-15s 0x%-8x 0x%-8x %-10d 0x%-8x\n", i, machine_str,
              enc_dict_entry_header->d_type, enc_dict_entry_header->d_offset,
              enc_dict_entry_header->d_size, enc_dict_entry_header->d_flags);
  }
  elf_debug("\n\n");
}
Beispiel #10
0
struct cuda_function_t *cuda_function_create(struct cuda_module_t *module,
	char *func_name)
{
	struct cuda_function_t *function;

	struct elf_file_t *cubin;
	struct elf_section_t *sec;
	struct elf_section_t *func_text_sec;
	struct elf_section_t *func_info_sec;
	char func_text_sec_name[MAX_STRING_SIZE];
	char func_info_sec_name[MAX_STRING_SIZE];
	unsigned char inst_bin_byte;
	char arg_name[MAX_STRING_SIZE];
	int i;

	/* Allocate */
	function = xcalloc(1, sizeof(struct cuda_function_t));

	/* Initialization */
	function->id = list_count(function_list);
	function->name = xstrdup(func_name);
	function->module_id = module->id;

	/* Get cubin */
	cubin = module->elf_file;

	/* Get .text.kernel_name section */
	snprintf(func_text_sec_name, sizeof func_text_sec_name, ".text.%s",
			func_name);
	for (i = 0; i < list_count(cubin->section_list); ++i)
	{
		sec = list_get(cubin->section_list, i);
		if (!strncmp(sec->name, func_text_sec_name, strlen(func_text_sec_name)))
		{
			func_text_sec = list_get(cubin->section_list, i);
			break;
		}
	}
	assert(i < list_count(cubin->section_list));

	/* Get instruction binary */
	function->inst_bin_size = func_text_sec->header->sh_size;
	function->inst_bin = xcalloc(1, function->inst_bin_size);
	for (i = 0; i < function->inst_bin_size; ++i)
	{
		elf_buffer_seek(&(cubin->buffer), func_text_sec->header->sh_offset + i);
		elf_buffer_read(&(cubin->buffer), &inst_bin_byte, 1);
		if (i % 8 == 0 || i % 8 == 1 || i % 8 == 2 || i % 8 == 3)
		{
			function->inst_bin[i / 8] |= (unsigned long long int)(inst_bin_byte)
					<< (i * 8 + 32);
		}
		else
		{
			function->inst_bin[i / 8] |= (unsigned long long int)(inst_bin_byte)
					<< (i * 8 - 32);
		}
	}

	/* Get GPR usage */
	function->num_gpr = func_text_sec->header->sh_info >> 24;

	/* Get .nv.info.kernel_name section */
	snprintf(func_info_sec_name, MAX_STRING_SIZE, ".nv.info.%s",
			function->name);
	for (i = 0; i < list_count(cubin->section_list); ++i)
	{
		sec = list_get(cubin->section_list, i);
		if (!strncmp(sec->name, func_info_sec_name, strlen(func_info_sec_name)))
		{
			func_info_sec = list_get(cubin->section_list, i);
			break;
		}
	}
	assert(i < list_count(cubin->section_list));

	/* Get the number of arguments */
	function->arg_count = ((unsigned char *)func_info_sec->buffer.ptr)[10] / 4;

	/* Create arguments */
	function->arg_array = xcalloc(function->arg_count, 
			sizeof(struct cuda_function_arg_t *));
	for (i = 0; i < function->arg_count; ++i)
	{
		snprintf(arg_name, MAX_STRING_SIZE, "arg_%d", i);
		function->arg_array[i] = cuda_function_arg_create(arg_name);
	}

	/* Add function to function list */
	list_add(function_list, function);

	return function;
}