Thread: Error in offset calculations

  1. #1
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733

    Error in offset calculations

    Struggling to see where I'm going wrong here (btw I did not spend my absence just getting to this point, I was slaking off big time)
    Code:
    #include <elf.h>
    typedef Elf32_Ehdr	elf32_init_header_t;
    typedef Elf64_Ehdr	elf64_init_header_t;
    typedef Elf32_Phdr	elf32_prog_header_t;
    typedef Elf64_Phdr	elf64_prog_header_t;
    typedef Elf32_Shdr	elf32_sect_header_t;
    typedef Elf64_Shdr	elf64_sect_header_t;
    typedef Elf32_Sym		elf32_exec_symbol_t;
    typedef Elf64_Sym		elf64_exec_symbol_t;
    ...
    /* Fill Offsets */
    	init64.e_phoff = sizeof(elf64_init_header_t);
    	init64.e_phnum = ld_prog_headers->list.upto;
    	init64.e_phentsize = sizeof(elf64_prog_header_t);
    	init64.e_shoff = init64.e_phoff + ld_prog_headers->data.size;
    	init64.e_shnum = ld_sect_headers->list.upto;
    	init64.e_shentsize = sizeof(elf64_sect_header_t);
    	init64.e_shstrndx = sh_name_strings_spot.ipos;
    	sect = (elf64_sect_header_t*)ld_sect_headers->data.data;
    	bytes = init64.e_shoff + ld_sect_headers->data.size;
    	for ( i = 1; i < init64.e_shnum; ++i ) {
    		sect[i].sh_offset = prev.sh_offset + prev.sh_size;
    		prev = sect[i];
    		sect[i].sh_offset += bytes;
    		sect[i].sh_addr = sect[i].sh_offset;
    	}
    	sect = &sect[sh_exec_symbols_spot.ipos];
    	exec = (elf64_exec_symbol_t*)ld_exec_symbols->data.data;
    	for ( i = 1; i < ld_exec_symbols->list.used; ++i ) {
    		exec[i].st_value += sect->sh_offset;
    	}
    My compile time output (readelf was executed too)
    Code:
    ...
    clang	-o mitsy.elf mitsy.o memory.o
    ./mitsy.elf
    readelf -all test.elf
    ELF Header:
      Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
      Class:                             ELF64
      Data:                              2's complement, little endian
      Version:                           1 (current)
      OS/ABI:                            UNIX - System V
      ABI Version:                       0
      Type:                              EXEC (Executable file)
      Machine:                           None
      Version:                           0x1
      Entry point address:               0x2c9
      Start of program headers:          64 (bytes into file)
      Start of section headers:          344 (bytes into file)
      Flags:                             0x0
      Size of this header:               0 (bytes)
      Size of program headers:           56 (bytes)
      Number of program headers:         5
      Size of section headers:           64 (bytes)
      Number of section headers:         5
      Section header string table index: 1
    Section Headers:
      [Nr] Name              Type             Address           Offset
           Size              EntSize          Flags  Link  Info  Align
      [ 0]                   NULL             0000000000000298  00000298
           0000000000000000  0000000000000000           0     0     0
      [ 1] .shstrtab         STRTAB           0000000000000298  00000298
           0000000000000017  0000000000000001   A       0     0     1
      [ 2] <corrupt>         NULL             00000000000002af  000002af
           0000000000000013  0000000000000001   A       0     0     1
      [ 3] <corrupt>         SYMTAB           00000000000002c2  000002c2
           0000000000000048  0000000000000018   A       1     3     8
      [ 4] <corrupt>         PROGBITS         000000000000030a  0000030a
           0000000000000011  0000000000000008  AX       0     0     8
    Key to Flags:
      W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
      L (link order), O (extra OS processing required), G (group), T (TLS),
      C (compressed), x (unknown), o (OS specific), E (exclude),
      p (processor specific)
    There are no section groups in this file.
    Program Headers:
      Type           Offset             VirtAddr           PhysAddr
                     FileSiz            MemSiz              Flags  Align
      NULL           0x0000000000000000 0x0000000000000000 0x0000000000000000
                     0x0000000000000000 0x0000000000000000  R      0x0
      PHDR           0x0000000000000040 0x0000000000000040 0x0000000000000040
                     0x0000000000000118 0x0000000000000118  R      0x8
      LOAD           0x0000000000000040 0x0000000000000040 0x0000000000000040
                     0x0000000000000118 0x0000000000000118  R      0x8
      INTERP         0x0000000000000407 0x0000000000000407 0x0000000000000407
                     0x0000000000000013 0x0000000000000013  R      0x1
          [Requesting program interpreter: ]
      LOAD           0x0000000000000462 0x0000000000000462 0x0000000000000462
                     0x0000000000000011 0x0000000000000011  RWE    0x1
     Section to Segment mapping:
      Segment Sections...
       00
       01
       02
       03
       04
    There is no dynamic section in this file.
    There are no relocations in this file.
    The decoding of unwind sections for machine type None is not currently supported.
    Symbol table '<corrupt>' contains 3 entries:
       Num:    Value          Size Type    Bind   Vis      Ndx Name
         0: ffffffe800000000   239 <OS specific>: 12 <unknown>: 3 PROTECTED [<other>: c]  bad section index[47365] <corrupt>
         1: 00000000000002c2     0 FUNC    LOCAL  DEFAULT    1 exit
         2: 00000000000002c9     0 FUNC    LOCAL  DEFAULT    1 _start
    No version information found in this file.
    Compilation finished successfully.
    Last edited by awsdert; 05-08-2019 at 04:00 AM. Reason: Grammar error

  2. #2
    Registered User
    Join Date
    Feb 2019
    Posts
    1,078
    Just an idea: What if you use a debugger?

  3. #3
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    For one debuggers are a pain to use
    Two, the GUI won't install or run os something, I'll go back to that later
    Three, on the way to work I realized I was using the wrong byte point when setting the symbol offsets, when I get home I'll add after the first loop an override of the reused bytes variable and use that as the base, hopefully that'll fix it

  4. #4
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Well I gave my thought a try, didn't fix the issue though it probably did fix an unnoticed issue, here's what the modified code now looks like:
    Code:
    bytes = init64.e_shoff + ld_sect_headers->data.size;
    for ( i = 1; i < init64.e_shnum; ++i ) {
    	sect[i].sh_offset = prev.sh_offset + prev.sh_size;
    	prev = sect[i];
    	sect[i].sh_offset += bytes;
    	sect[i].sh_addr = sect[i].sh_offset;
    }
    bytes += prev.sh_offset + prev.sh_size;
    exec = (elf64_exec_symbol_t*)ld_exec_symbols->data.data;
    for ( i = 1; i < ld_exec_symbols->list.used; ++i ) {
    	exec[i].st_value += bytes;
    }
    Will be going to bed soon, not really expecting anyone to actually fix it but one can hope. I'm hoping that fresh eyes will it least notice problems I've yet (incidentally upto this point sizes are set but offsets are ignored, the elf file first has all needed bytes written as plain 0s then lseek64 is used with these offsets to write the data itself)
    Just in case anyone wants to see the code where I write the actual bytes:
    Code:
    sect = GetSpot( ld_sect_headers, sh_exec_content_spot );
    bytes = sect->sh_offset + sect->sh_size;
    /* Prepare for seeking anywhere need to */
    for ( ; bytes > BUFSIZ; bytes -= BUFSIZ ) {
    	if ( mitsy_write( fd, null_buff, BUFSIZ, NULL ) != BUFSIZ )
    		goto fail_writing;
    }
    if ( mitsy_write( fd, null_buff, (size_t)bytes, NULL ) != bytes )
    	goto fail_writing;
    (void)fsync(fd);
    /* Fill in Elf Header */
    (void)mitsy_seek( fd, 0, SEEK_SET );
    (void)mitsy_write( fd, &init64, sizeof(elf64_init_header_t), NULL );
    /* Fill in .segments */
    (void)mitsy_seek( fd, init64.e_phoff, SEEK_SET );
    (void)mitsy_write( fd,
    	ld_prog_headers->data.data, ld_prog_headers->data.size, NULL );
    /* Fill in .sections */
    (void)mitsy_seek( fd, init64.e_shoff, SEEK_SET );
    (void)mitsy_write( fd,
    	ld_sect_headers->data.data, ld_sect_headers->data.size, NULL );
    /* Fill in .interp */
    sect = GetSpot( ld_sect_headers, sh_dynamic_lder_spot );
    (void)mitsy_seek( fd, sect->sh_offset, SEEK_SET );
    (void)mitsy_write( fd, dynamic_lder, sect->sh_size, NULL );
    /* Fill in .shstrtab */
    sect = GetSpot( ld_sect_headers, sh_name_strings_spot );
    (void)mitsy_seek( fd, sect->sh_offset, SEEK_SET );
    (void)mitsy_write( fd,
    	ld_name_strings->data.data, sect->sh_size, NULL );
    /* Fill in .symtab & .text */
    sect = GetSpot( ld_sect_headers, sh_exec_symbols_spot );
    (void)mitsy_seek( fd, sect->sh_offset, SEEK_SET );
    (void)mitsy_write( fd,
    	ld_exec_symbols->data.data, sect->sh_size, NULL );
    spots = (spot_t*)ld_exec_symbols->list.data.data;
    exec_spots = (spot_t*)cc_exec_content.list.data.data;
    for ( i = 1; i < ld_exec_symbols->list.used; ++i ) {
    	if ( !spots[i].size ) continue;
    	exec = GetSpot( ld_exec_symbols, spots[i] );
    	(void)mitsy_seek( fd, exec->st_value, SEEK_SET );
    	(void)mitsy_write( fd,
    		&(cc_exec_content.data.data[exec_spots[i-1].spot]),
    		exec_spots[i-1].size, NULL );
    }
    (void)fsync(fd);
    Last edited by awsdert; 05-08-2019 at 04:41 PM. Reason: Forgot to close a code tag

  5. #5
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    As it turns out I wasn't even getting to the offset calculations, need to take a closer look at the loop adding my symbols,
    when even codelite wasn't reaching the breakpoints I started becoming suspicious and added a bunch of puts & printf statements and found the last to print was the message before entering my symbols loop.

  6. #6
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Finally found the cause, that loop wasn't the issue, it was an earlier loop in main() that was checking against a different parameter, it was fine until I had added a filename with 0 data & 0 size, since the loop was checking against the data parameter and not the name parameter it never added the symbols, I forgot this detail by the time I added the filename. After resolving that issue there was an issue with some segfaults in my 'compiler/linker' but after fixing those the test.elf was built fine, it seems the resulting offsets where fine too since the program happend to look fine to readelf, got work to prep for now so will try to get it 'running' some other day (maybe tomorrow?)

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Find the offset
    By PrimeSec in forum C Programming
    Replies: 9
    Last Post: 09-29-2013, 12:32 PM
  2. Using Offset in C
    By nickman in forum C Programming
    Replies: 1
    Last Post: 11-15-2011, 12:52 PM
  3. help! (int*)+offset
    By RobotGymnast in forum C++ Programming
    Replies: 6
    Last Post: 01-06-2008, 01:12 PM
  4. offset
    By Rhidian in forum C Programming
    Replies: 6
    Last Post: 04-14-2005, 08:57 AM
  5. What exactly is an 'offset' to something?
    By Shadow12345 in forum C++ Programming
    Replies: 4
    Last Post: 11-08-2002, 10:28 PM

Tags for this Thread