Thread: Need problem points of custom elf highlighted

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

    Need problem points of custom elf highlighted

    I finally got my elf to execute but it immediately segfaulted when I was expecting it to return 0 straight away, the idea was simply to ensure I was handling a basic call to main correctly which would in turn allow me to understand the bare mininum for
    Code:
    int main() { return 0; }
    to output as, from there I plan to start writing my own addon supporting compiler under MIT license starting with just integer handling & a simple version of puts that was helpfully provided by flp1969 (didn't ask for it but very greatful for it)
    Output of readelf -all test.elf
    Code:
    ELF Header:
      Magic:   7f 45 4c 46 02 01 01 03 00 00 00 00 00 00 00 00 
      Class:                             ELF64
      Data:                              2's complement, little endian
      Version:                           1 (current)
      OS/ABI:                            UNIX - GNU
      ABI Version:                       0
      Type:                              EXEC (Executable file)
      Machine:                           Advanced Micro Devices X86-64
      Version:                           0x1
      Entry point address:               0x40
      Start of program headers:          95 (bytes into file)
      Start of section headers:          0 (bytes into file)
      Flags:                             0x0
      Size of this header:               64 (bytes)
      Size of program headers:           56 (bytes)
      Number of program headers:         1
      Size of section headers:           0 (bytes)
      Number of section headers:         0
      Section header string table index: 0
    
    There are no sections in this file.
    
    There are no sections to group in this file.
    
    Program Headers:
      Type           Offset             VirtAddr           PhysAddr
                     FileSiz            MemSiz              Flags  Align
      LOAD           0x0000000000000000 0x0000000000000000 0x0000000000000000
                     0x0000000000000000 0x0000000000000000         0x0
    
    There is no dynamic section in this file.
    
    There are no relocations in this file.
    
    The decoding of unwind sections for machine type Advanced Micro Devices X86-64 is not currently supported.
    
    Dynamic symbol information is not available for displaying symbols.
    
    No version information found in this file.
    test.elf - Google Drive

  2. #2
    Registered User
    Join Date
    Feb 2019
    Posts
    717
    It's very hard to run something from an empty ELF file...

  3. #3
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,023
    My post seems to have been deleted, anyway the intent behind uploading it was for a hex editor to be used on it to see anything not seen with readelf, as for it being empty it might seem that way if you're seeing it in kb or higher, only a couple hundred bytes since I needed to see how a function should be called and returned before trying to write any compiler for it

  4. #4
    Registered User
    Join Date
    Feb 2019
    Posts
    717
    Quote Originally Posted by awsdert View Post
    My post seems to have been deleted, anyway the intent behind uploading it was for a hex editor to be used on it to see anything not seen with readelf, as for it being empty it might seem that way if you're seeing it in kb or higher, only a couple hundred bytes since I needed to see how a function should be called and returned before trying to write any compiler for it
    Well... Your file have some data, alright. But the ELF header says it is empty:
    Need problem points of custom elf highlighted-fields-png
    For the meaning of these fields, look at SysV ABI documents...

  5. #5
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,023
    You got a link? all the docs I find lead me to the conclusion that the elf header is correct (8 byte addresses remember) and the point of suspicion is either the program header PT_LOAD (which I mostly 0'd out, only entry and after main()) or main() itself (which should be just 3 bytes near the end - look around C3)

  6. #6
    Registered User
    Join Date
    Feb 2019
    Posts
    717
    osdev wiki has alll the links you'll need:

    System V ABI - OSDev Wiki

  7. #7
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,023
    Not understood the cause of the segfault yet but I did manage to learn how to use the integer instructions, didn't know I needed to set a flag holder before using the instructions

  8. #8
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,023
    Okay, no knowing WHERE the segfault was coming from was definitly hindering me (kept trying to modify _start & main bytes) so I removed all but the essential syscall from _start() and still got a segfault, tried adding in a .text segment and still got the error, I've removed the old upload and here is a new upload, got gospel soon so just gonna hope someone can pin point where I'm going wrong there. By the way readelf is for some reason saying the segment size reported is less than the size it thinks they are, if you can figure out why that is despite me using sizeof(elsh64_t) then please be my gest, here's the typedef along with the enum I used:
    Code:
    enum {
    	ELSH_SHT_NULL = 0,
    	ELSH_SHT_PROGBITS,
    	ELSH_SHT_SYMTAB,
    	ELSH_SHT_STRTAB,
    	ELSH_SHT_RELA,
    	ELSH_SHT_HASH, // Used this one, haven'y found the note that states which one to use just yet
    	ELSH_SHT_DYNAMIC,
    	ELSH_SHT_NOTE,
    	ELSH_SHT_NOBITS,
    	ELSH_SHT_SHLIB,
    	ELSH_SHT_DYNSYM,
    	ELSH_SHT_INIT_ARRAY = 0xE,
    	ELSH_SHT_FINI_ARRAY,
    	ELSH_SHT_PREINIT_ARRAY,
    	ELSH_SHT_GROUP,
    	ELSH_SHT_SYMTAB_SHNDX,
    	ELSH_SHT_NUM,
    	ELSH_SHT_LOOS = 0x60000000,
    	ELSH_SHT_HIOS = 0x6FFFFFFF,
    	ELSH_SHT_LOPROC = 0x70000000,
    	ELSH_SHT_HIPROC = 0x7FFFFFFF
    };
    typedef struct __attribute__((packed)) {
    	d32 sh_name; // stored directly before the entrypoint after both the program header/s and segment header/s
    	u32 sh_type;
    	u64 sh_flags;
    	u64 sh_addr;
    	d64 sh_offset;
    	u32 sh_link;
    	u32 sh_info;
    	u64 sh_adralign;
    	u64 sh_entsize;
    } elsh64_t;

  9. #9
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,023
    After upgrading sh_link & sh_info to 8 bytes readelf stopped reporting a size issue so I'm guessing the doc I came across before was wrong, also the docs at osdev are really poor quality, after this experience I plan to write my own and publish it with my compiler once I get that into compiling basic integers and structs.

    Edit:
    Forgot I came here to ask for help understanding segment headers which the docs fail to make clear.
    So far this is my output after compiling my "compiler" (used quotes since it doesn't qualify as one yet however given it is to become one I had no other word for it)
    Code:
    misty alpha
    Writing header...
    Writing segment header/s...
    Writing program header/s...
    Writing executable code...
    Flushing file...
    ./test.elf
    Segmentation fault
    readelf -all test.elf
    ELF Header:
      Magic:   7f 45 4c 46 02 01 01 03 00 00 00 00 00 00 00 00 
      Class:                             ELF64
      Data:                              2's complement, little endian
      Version:                           1 (current)
      OS/ABI:                            UNIX - GNU
      ABI Version:                       0
      Type:                              EXEC (Executable file)
      Machine:                           Advanced Micro Devices X86-64
      Version:                           0x1
      Entry point address:               0xc2
      Start of program headers:          128 (bytes into file)
      Start of section headers:          64 (bytes into file)
      Flags:                             0x0
      Size of this header:               64 (bytes)
      Size of program headers:           56 (bytes)
      Number of program headers:         1
      Size of section headers:           64 (bytes)
      Number of section headers:         1
      Section header string table index: 0
    
    Section Header:
      [Nr] Name              Type             Address           Offset
           Size              EntSize          Flags  Link  Info  Align
      [ 0] <no-strings>      NULL             0000000000000000  00000000
           0000000000000000  0000000000000000           0     0     0
    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),
      l (large), p (processor specific)
    
    There are no section groups in this file.
    
    Program Headers:
      Type           Offset             VirtAddr           PhysAddr
                     FileSiz            MemSiz              Flags  Align
      LOAD           0x0000000000000000 0x00000000000000c2 0x00000000000000c2
                     0x0000000000000002 0x0000000000000002  RWE    0x0
    
    There is no dynamic section in this file.
    
    There are no relocations in this file.
    
    The decoding of unwind sections for machine type Advanced Micro Devices X86-64 is not currently supported.
    
    No version information found in this file.
    Exiting...
    
    
    ------------------
    (program exited with code: 0)
    Edit 2:
    By the way this is what I have for the segment header (the result above was nulled out because I forgot to remove an #ifdef from it)
    Code:
    /* Fill Segment Header/s */
    elsh64e->sh_name = entrytx;
    elsh64e->sh_type = ELSH_SHT_STRTAB;
    elsh64e->sh_flags = 0;
    elsh64e->sh_addr = entrytx;
    elsh64e->sh_offset = (entrytx - sizeof(elf64_t)) - 24;
    elsh64e->sh_link = 0;
    elsh64e->sh_info = 0;
    elsh64e->sh_adralign = 0;
    elsh64e->sh_entsize = sizeof(begin_t);
    The entrytx has '.', 't', 'e', 'x', 't', 0, 0, 0, 0, 0, entrypt code written to it
    Last edited by awsdert; 04-01-2019 at 02:59 AM.

  10. #10
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,023
    Went through the original docs I was reading from (not osdev) and found I missed a parameter called sh_size so I added it and corrected sh_link/sh_info back to 4 bytes. I still can't get the program to run without segfaulting but before I go back to that I'm having trouble getting readelf to find the names, currently I write the file in this order:

    elf header
    segment name text (each 16 bytes to help with reading in hex editor)
    segment headers
    program headers
    _start & main()

    and the segment headers are filled like so:
    Code:
    /* Fill Segment Header .shstrtab */
    elsh64e->sh_name = 0;
    elsh64e->sh_type = ELSH_SHT_STRTAB;
    elsh64e->sh_flags = 0x20;
    elsh64e->sh_addr = sizeof(elf64_t);
    elsh64e->sh_size = segments;
    elsh64e->sh_offset = 0;
    elsh64e->sh_link = 0;
    elsh64e->sh_info = 0;
    elsh64e->sh_adralign = 0;
    elsh64e->sh_entsize = SEG_NAME_SIZE;
    /* Fill segment header .text */
    elsh64e = &elsh64v[1];
    elsh64e->sh_name = 1;
    elsh64e->sh_type = ELSH_SHT_PROGBITS;
    elsh64e->sh_flags = 0xF00000A5;
    elsh64e->sh_addr = entrypt;
    elsh64e->sh_size = sizeof(begin_t);
    elsh64e->sh_offset = 0;
    elsh64e->sh_link = 0;
    elsh64e->sh_info = 0;
    elsh64e->sh_adralign = 0;
    elsh64e->sh_entsize = 0;
    I tried setting sh_name with every variation I could think of but nothing worked

    Edit: Thought you might want to see how the name array is filled:
    Code:
    #define SEG_NAME_SIZE (sizeof(char) * 16)
    #define segmentc 2
    u16 segments = SEG_NAME_SIZE * segmentc;
    char segmentv[segmentc][SEG_NAME_SIZE] = {
    	".shstrtab",
    	".text"
    };
    Edit 2: Gotta go do this "e-learning" thing at work premises so'll be checking back in about 2-3 hours earliest
    Last edited by awsdert; 04-01-2019 at 05:00 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. C++ Plot Simple Points / Graph, X & Y array points
    By Khadafi in forum C++ Programming
    Replies: 9
    Last Post: 11-11-2011, 03:47 AM
  2. Reading in Highlighted Text by Mouse
    By patriots21 in forum C Programming
    Replies: 2
    Last Post: 08-14-2010, 12:58 AM
  3. Outputting highlighted text?
    By Aramil in forum C Programming
    Replies: 4
    Last Post: 01-19-2010, 06:46 PM
  4. highlighted text
    By Unregistered in forum Linux Programming
    Replies: 2
    Last Post: 03-07-2002, 11:20 PM

Tags for this Thread