This is the mail archive of the
elfutils-devel@sourceware.org
mailing list for the elfutils project.
Re: libelf RDWR and elf_newscn do not work
- From: Jiri Slaby <jslaby at suse dot cz>
- To: elfutils-devel at lists dot fedorahosted dot org
- Date: Tue, 08 Oct 2013 13:49:30 +0200
- Subject: 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;
}