This happens with the dynamic_executable_sstrip from the Ruby-Elf testsuite[1], because the .note section is set having a 0-size, which causes an allocation error: [1] http://www.flameeyes.eu/projects/ruby-elf (gdb) break exit Breakpoint 1 at 0x7ffff7aa63f0: file exit.c, line 100. (gdb) r Starting program: /usr/bin/elfls tests/data/linux/amd64/gcc/dynamic_executable_sstrip tests/data/linux/amd64/gcc/dynamic_executable_sstrip* (?62) Program header table entries: 10 (40 - 270) Out of memory! Breakpoint 1, exit (status=1) at exit.c:100 100 exit.c: No such file or directory. in exit.c (gdb) bt #0 exit (status=1) at exit.c:100 #1 0x00000000004012f8 in getstring (offset=511, size=18446744073709551604, skip=0) at elfls.c:248 #2 0x0000000000401f18 in describephdr (argc=<value optimized out>, argv=<value optimized out>) at elfls.c:647 #3 main (argc=<value optimized out>, argv=<value optimized out>) at elfls.c:867 (gdb) frame 2 #2 0x0000000000401f18 in describephdr (argc=<value optimized out>, argv=<value optimized out>) at elfls.c:647 647 elfls.c: No such file or directory. in elfls.c (gdb) print phdr $1 = (Elf64_Phdr *) 0x605368 (gdb) print phdr->p_offset $2 = 499 (gdb) print phdr->p_filesz $3 = 0 Code: case PT_NOTE: str = getstring(phdr->p_offset + 12, phdr->p_filesz - 12, FALSE); if (str && *str) { readelf -l fragment of the file's NOTE PH NOTE 0x00000000000001f3 0x000000000040028c 0x000000000040028c 0x0000000000000000 0x0000000000000020 R 4
Okay, easy fix with possibly subtle consequences. Let me bounce my solution off of you before I commit. On line 648 we have: str = getstring(phdr->p_offset + 12, phdr->p_filesz - 12, FALSE); and on line 236+ we have: static char const *getstring(unsigned long offset, unsigned long size, int skip) ... if (!size) return ""; When phdr->p_filesz - 12 is less than 0, this returns a negative number which is mapped to a very large positive number when cast as an unsigned long. Thus changing the check to if (size <= 0) { return ""; } doesn't work. But if ((long)size <= 0) { return ""; } does. Alternatively, one can change the declaration of size from unsigned long to just long in the function header of getstring. phdr is of type Elf{32,64}_Phdr and p_filesz is of type Elf{32,64}_Word which is typedef uint32_t. Since sizeof(unsigned long) is 8 and sizeof(uint32_t) is 4, the redeclaration should be safe. Similarly, it should be safe to declare offset just long as well and add a sanity check for it. I'm leaning towards my second solution. Comments?
Redeclaration looks fine to me.
Okay, the fix is in the tree. I tested it and it worked. Please reopen if you find anything wrong.