Пример #1
0
int coff_syms(FILE *in)
{
	struct coff_header hdr;
	char *strtab;
	uint8_t *symtab;
	int strtab_len;
	int i;
	int ret = 0;

	if (read_header(in, &hdr) < 0)
		return -1;

	strtab_len = read_strtab(in, &hdr, &strtab);
	if (strtab_len < 0)
		return -1;

	if (read_symtab(in, &hdr, &symtab) < 0) {
		if (strtab)
			free(strtab);
		return -1;
	}

	for (i = 0; i < hdr.stab_count; i++) {
		uint8_t *entry = symtab + i * STAB_ENTRY_SIZE;
		uint32_t value = LE_LONG(entry, 8);
		int storage_class = entry[16];
		char namebuf[9];
		const char *name = NULL;

		if (LE_LONG(entry, 0)) {
			memcpy(namebuf, entry, 8);
			namebuf[8] = 0;
			name = namebuf;
		} else {
			uint32_t offset = LE_LONG(entry, 4);

			if (offset >= 4 && offset < strtab_len)
				name = strtab + offset;
		}

		if (name &&
		    (storage_class == C_EXT || storage_class == C_LABEL) &&
		    stab_set(name, value) < 0) {
			printc_err("coff: failed to insert symbol\n");
			ret = -1;
			break;
		}

		/* Skip auxiliary entries */
		i += entry[17];
	}

	if (symtab)
		free(symtab);
	if (strtab)
		free(strtab);

	return ret;
}
Пример #2
0
static int syms_load_syms(struct elf32_info *info, FILE *in,
			  Elf32_Shdr *s, stab_t stab)
{
	Elf32_Sym syms[N_SYMS];
	int len = s->sh_size / sizeof(syms[0]);

	if (fseek(in, s->sh_offset, SEEK_SET) < 0) {
		perror("elf32: can't seek to symbols");
		return -1;
	}

	while (len) {
		int req = N_SYMS > len ? len : N_SYMS;
		int count = fread(syms, sizeof(syms[0]), req, in);
		int i;

		if (!count) {
			fprintf(stderr, "elf32: eof reading symbols\n");
			return -1;
		}

		if (count < 0) {
			perror("elf32: error reading symbols");
			return -1;
		}

		for (i = 0; i < count; i++) {
			Elf32_Sym *y = &syms[i];

			if (y->st_name > info->string_len) {
				fprintf(stderr, "elf32: symbol out of "
					"bounds\n");
				return -1;
			}

			if (stab_set(stab, info->string_tab + y->st_name,
				     y->st_value) < 0)
				return -1;
		}

		len -= count;
	}

	return 0;
}
Пример #3
0
static int syms_load_syms(struct elf32_info *info, FILE *in,
			  Elf32_Shdr *s)
{
	int len = s->sh_size / 16;
	int i;

	if (fseek(in, s->sh_offset, SEEK_SET) < 0) {
		pr_error("elf32: can't seek to symbols");
		return -1;
	}

	for (i = 0; i < len; i++) {
		Elf32_Sym y;
		int st;
		const char *name;

		if (parse_sym(&y, in) < 0) {
			pr_error("elf32: error reading symbols");
			return -1;
		}

		st = ELF32_ST_TYPE(y.st_info);
		name = info->string_tab + y.st_name;

		if (y.st_name > info->string_len) {
			printc_err("elf32: symbol out of bounds\n");
			return -1;
		}

		if (name[0] &&
		    (st == STT_OBJECT || st == STT_FUNC ||
		     st == STT_SECTION || st == STT_COMMON ||
		     st == STT_TLS) &&
		    stab_set(info->string_tab + y.st_name,
			     y.st_value) < 0)
			return -1;
	}

	return 0;
}
Пример #4
0
static int syms_load_syms(struct elf32_info *info, FILE *in,
			  GElf_Shdr *s)
{
	const char sym_debug = 0;
	int number = 0;
	int added = 0;
	char *name;

	/* now loop through the symbol table and print it*/
#if 1
	/* Good: This works. */
	Elf32_Sym *esym;
	Elf32_Sym *lastsym;

	esym = (Elf32_Sym*) info->string_data->d_buf;
	lastsym = (Elf32_Sym*) ((char*)info->string_data->d_buf
			+ info->string_data->d_size);
	for (; esym && (esym < lastsym); esym++) {
#else
	/* BAD: For some reason, st_value = 0 for all symbols? */
	GElf_Sym isym;
	GElf_Sym *esym;

	while ((esym = gelf_getsym(info->string_data, number, &isym))) {
#endif
		int st;
		st = ELF32_ST_TYPE(esym->st_info);
		name = elf_strptr(info->elf, s->sh_link, (size_t)esym->st_name);
		if (sym_debug) {
			printc("[%3d] name:%16s st:%d sz:%d info:%d other:%d value:%d ",
				number,
				name ? name : "<NULL>",
				st,
				esym->st_size,
				esym->st_info,
				esym->st_other,
				esym->st_value);
		}
		if ((name != NULL && name[0] != 0) &&
				(st == STT_OBJECT || st == STT_FUNC ||
				st == STT_SECTION || st == STT_COMMON ||
				st == STT_TLS)) {
			if (sym_debug) {
				printc("stab_set(%s, %d)\n", name, esym->st_value);
			}
			if (stab_set(name, esym->st_value) < 0) {
				printc_err("elf32: stab_set #%d failed\n", number);
				return -1;
			}
			added++;
		} else {
			if (sym_debug) {
				printc("was ignored\n");
			}
		}
		if (name == NULL) {
			printc_err("elf32: null symbol name %s\n",
				elf_errmsg(elf_errno()));
			exit(-1);
		}
		number++;
	}
	printc("load_syms found %d symbols, added %d\n", number, added);

	return 0;
}

int elf32_syms(FILE *in)
{
	struct elf32_info info;
	GElf_Shdr *s;
	int ret = 0;

	if (read_all(&info, in) < 0)
		return -1;

	s = find_shdr(&info, SHT_SYMTAB);
	if (!s) {
		printc_err("elf32: no symbol table\n");
		return -1;
	}

	if (s->sh_link <= 0 || s->sh_link >= info.file_ehdr.e_shnum) {
		printc_err("elf32: no string table\n");
		return -1;
	}

	if (syms_load_strings(&info, in, &info.file_shdrs[s->sh_link]) < 0 ||
	    syms_load_syms(&info, in, s) < 0)
		ret = -1;

	return ret;
}