This is the mail archive of the elfutils-devel@sourceware.org mailing list for the elfutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: libelf RDWR and elf_newscn do not work


On 10/08/2013 11:24 AM, Mark Wielaard wrote:
> Hi Jiri,
> 
> On Tue, 2013-10-08 at 09:33 +0200, Jiri Slaby wrote:
>> if I add a section using the code below, I obtain a section like this:
>>   [29]                   NULL            0000000000000000
>> fff1000400000001 000000 00      0   0 281487861612544
>>
>> The attached patch fixed it for me. Any ideas?
> 
> Not immediately. Would you mind posting the full code?
> In particular where does the Elf_Scn that you are adding come from?
> The code you posted seems incomplete since it only sets sh_type but
> nothing else.

It does not matter (the other members are set implicitly). With the
patch, it works.

Anyway, see the "#if 0" section in the attached file, even if I
uncomment it, it does not work. See also the patch I attached earlier
what it does...


-- 
js
suse labs
#include <ctype.h>
#include <err.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <libelf.h>
#include <gelf.h>

#include <sys/types.h>
#include <sys/stat.h>

int main(int argc, char **argv)
{
	Elf *elf;
	Elf_Kind ek;
	Elf_Scn *scn;
	Elf_Data *data;
	const char *k;
	int fd;
//	size_t str_idx;

	if (elf_version(EV_CURRENT) == EV_NONE)
		errx(1, "elf_version: %s" , elf_errmsg(-1));

	fd = open(argv[1], O_RDWR, 0);
	if (fd < 0)
		err(1, "open");

	elf = elf_begin(fd, ELF_C_RDWR, NULL);
	if (!elf)
		errx(EXIT_FAILURE, "elf_begin: %s", elf_errmsg(-1));

	ek = elf_kind(elf);
	switch ( ek ) {
	case ELF_K_AR :
		k = " ar (1) archive " ;
		break ;
	case ELF_K_ELF :
		k = " elf object " ;
		break ;
	case ELF_K_NONE :
		k = " data " ;
		break ;
	default:
		k = " unrecognized " ;
	}
	printf("%s: %s \n" , argv[1], k);

	if (ek != ELF_K_ELF)
		errx(EXIT_FAILURE, "not an ELF");
#if 0
	puts("SEC");

	if (elf_getshdrstrndx(elf, &str_idx))
		errx(EXIT_FAILURE, "elf_getshdrstrndx: %s", elf_errmsg(-1));

/*	scn = elf_getscn(elf, str_idx);
	if (!scn)
		errx(EXIT_FAILURE, "!gelf_offscn: %s", elf_errmsg(-1));

	data = NULL;
	while ((data = elf_getdata(scn, data))) {
		size_t i;
		for (i = 0; i < data->d_size; i++) {
			char ch = ((char *)data->d_buf)[i];
			if (isascii(ch))
				printf(" %c ", ch);
			else
				printf("%.2x ", ch);
		}
		puts("");
	}*/

	scn = NULL;
	while ((scn = elf_nextscn(elf, scn))) {
		int datas = 0;
		GElf_Shdr dst;
		int type = 0;

		if (!gelf_getshdr(scn, &dst))
			errx(1, "gelf_getshdr: %s", elf_errmsg(-1));

		data = NULL;
		while ((data = elf_getdata(scn, data))) {
			type = data->d_type;
			datas++;
		}

		printf("%4zd %8zx-%8zx %4d datas=%4d (%2d): %s\n", elf_ndxscn(scn), dst.sh_offset, dst.sh_offset+dst.sh_size-1, dst.sh_name, datas, type, elf_strptr(elf, str_idx, dst.sh_name));
	}

	puts("PHDR");

	size_t i, num;

	if (elf_getphdrnum(elf, &num))
		errx(EXIT_FAILURE, "elf_getphdrnum: %s", elf_errmsg(-1));

	for (i = 0; i < num; i++) {
		GElf_Phdr dst;
		if (!gelf_getphdr(elf, i, &dst))
			errx(EXIT_FAILURE, "!gelf_getphdr: %s", elf_errmsg(-1));

		scn = gelf_offscn(elf, dst.p_offset);
		if (!scn) {
			warnx("gelf_offscn(%zd): %s", i, elf_errmsg(-1));
			continue;
		}

		printf("T=%8x %16lx-%16lx sec=%zd (%s)\n", dst.p_type, dst.p_offset, dst.p_offset + dst.p_filesz - 1, elf_ndxscn(scn), "");//elf_strptr(elf, str_idx, scn.sh_name));
	}
#endif
	scn = elf_newscn(elf);
	if (!scn)
		errx(EXIT_FAILURE, "elf_newscn: %s", elf_errmsg(-1));

	printf("new scn=%zd\n", elf_ndxscn(scn));

	data = elf_newdata(scn);
	if (!data)
		errx(1, "!elf_newdata: %s", elf_errmsg(-1));

	GElf_Shdr shdr_data, *shdr;
	shdr = gelf_getshdr(scn, &shdr_data);
	if (!shdr)
		errx(1, "gelf_getshdr: %s", elf_errmsg(-1));

	shdr->sh_type = SHT_NOBITS;
#if 0
	shdr->sh_name = 1;
	shdr->sh_flags = SHF_ALLOC | SHF_STRINGS;
	shdr->sh_addr = 0x10;
	shdr->sh_size = 1000;
	shdr->sh_offset = 10000000;

	data->d_buf = "ahoj";
	data->d_type = ELF_T_BYTE;
	data->d_size = 5;
	data->d_align = 1;
#endif
	if (!gelf_update_shdr(scn, shdr))
		errx(1, "!gelf_update_shdr: %s", elf_errmsg(-1));

//	printf("ok %d: %s\n", abfd->direction, bfd_printable_name(abfd));

	if (elf_update(elf, ELF_C_NULL) < 0)
		errx(EXIT_FAILURE, "elf_update1: %s", elf_errmsg(-1));

	if (elf_update(elf, ELF_C_WRITE) < 0)
		errx(EXIT_FAILURE, "elf_update2: %s", elf_errmsg(-1));

	if (elf_end(elf))
		errx(EXIT_FAILURE, "!elf_end: %s", elf_errmsg(-1));
	close(fd);

	return 0;
}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]