[ELF] stringtable ist kein stringtable?



  • Ich versuche grad ein bisschen mit "ELF-magie" rumzuspielen. Klappt aber nicht so richtg. Hier erst mal mein linker-\1:(woanders geklaut)

    OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64",
    	      "elf64-x86-64")
    OUTPUT_ARCH(i386:x86-64)
    
    page_size = 0x1000;
    
    TARGET("binary")
    
    PHDRS
    {
      headers PT_PHDR FILEHDR PHDRS;
      file_list PT_LOAD;
    }
    
    INPUT("driver")
    
    SECTIONS
    {
      . = SIZEOF_HEADERS;
    
      drv ALIGN(page_size): { "driver" }
    
      foo ALIGN(page_size): { BYTE(1) } : file_list
    }
    

    Mein proggie:

    #include <stdio.h>
    #include <assert.h>
    #include <string.h>
    
    #include <sys/types.h>
    #include <sys/mman.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    
    #include <elf.h>
    
    int main(int argc,char** argv)
    {
    	assert(argc == 2);
    	int fd=open(argv[1],O_RDONLY);
    	assert(fd!=-1);
    	caddr_t addr=mmap(0,15000,PROT_READ,MAP_SHARED,fd,0);
    
    	Elf64_Ehdr* elf=(Elf64_Ehdr*)addr;
    
    	assert(			elf->e_ident[EI_MAG0]==ELFMAG0
    				&&	elf->e_ident[EI_MAG1]==ELFMAG1
    				&&	elf->e_ident[EI_MAG2]==ELFMAG2
    				&&	elf->e_ident[EI_MAG3]==ELFMAG3);
    
    	printf("ist ELF-Datei\n");
    
    	assert(elf->e_shstrndx!=SHN_UNDEF&&elf->e_shstrndx<elf->e_shnum);
    
    	printf("%i sections, %i ist der string table\n",elf->e_shnum, elf->e_shstrndx);
    
    	Elf64_Shdr* strtable=(Elf64_Shdr*)(addr + elf->e_shoff + elf->e_shstrndx * elf->e_shentsize);
    
    	assert(strtable->sh_type == SHT_STRTAB);
    	assert(strtable->sh_size != 0);
    
    	printf("\n");
    
    	Elf64_Shdr* tmpsh;
    	unsigned i;
    	for(i=1;i<elf->e_shnum;++i)
    	{
    		tmpsh=(Elf64_Shdr*)(addr + elf->e_shoff+ i * elf->e_shentsize);
    		//if(!strcmp((char*)(addr+strtable->sh_offset)+tmpsh->sh_name,"drv"))
    			printf("%s\t%i\n",(char*)(addr+strtable->sh_offset)+tmpsh->sh_name,tmpsh->sh_addr);
    	};
    
    	/*printf("\n");
    
    	unsigned j;
    	Elf64_Phdr* tmpph;
    	for (j = 0; j < elf->e_phnum; j++)
    	{
    		tmpph = (Elf64_Phdr *) (addr + elf->e_phoff + j * elf->e_phentsize);
    		printf("%i",tmpph->p_vaddr);
    		for(i=1;i<elf->e_shnum;++i)
    		{
    			tmpsh=(Elf64_Shdr*)(addr + elf->e_shoff+ i * elf->e_shentsize);
    			if(tmpsh->sh_addr==tmpph->p_vaddr)
    			{
    				printf("\t%s",(char*)(addr+strtable->sh_offset)+tmpsh->sh_name);
    				break;
    			};
    		};
    		printf("\n");
    	}*/
    
    	close(fd);
    	return 0;
    };
    

    Das Programm beendet mit

    read: read.c:34: main: Assertion `strtable->sh_type == 3' failed.
    

    Wenn ich im ldscript die section foo weglasse, funktioniert das, aber ich bekomme (von ld) die warnung

    ld: drv: warning: allocated section `drv' not in segment
    

    Und: readelf liest programme, die mit dem 1. script erzeugt wurden, ohne zu murren.
    Irgendwie hab ich das gefühl, irgendwo in meinem code liegt der fehler 😃 ...


Anmelden zum Antworten