1

I have a a.out file from "hello world" in c:

#include <stdio.h>
#include <stdlib.h>
int main(){
    printf("hello world\n");
}

Which I can see in hexdump (file a.out) with command :%!xxd -g1

00000000: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00  .ELF............
00000010: 03 00 3e 00 01 00 00 00 50 10 00 00 00 00 00 00  ..>.....P.......
00000020: 40 00 00 00 00 00 00 00 c3 b8 40 00 00 00 00 00  @.........@.....
00000030: 00 00 00 00 00 40 00 38 00 0b 00 40 00 23 00 22  [email protected]...@.#."
00000040: 00 06 00 00 00 04 00 00 00 40 00 00 00 00 00 00  .........@......
00000050: 00 40 00 00 00 00 00 00 00 40 00 00 00 00 00 00  .@.......@......
00000060: 00 68 02 00 00 00 00 00 00 68 02 00 00 00 00 00  .h.......h......
00000070: 00 08 00 00 00 00 00 00 00 03 00 00 00 04 00 00  ................
00000080: 00 c2 a8 02 00 00 00 00 00 00 c2 a8 02 00 00 00  ................
00000090: 00 00 00 c2 a8 02 00 00 00 00 00 00 1c 00 00 00  ................
000000a0: 00 00 00 00 1c 00 00 00 00 00 00 00 01 00 00 00  ................
000000b0: 00 00 00 00 01 00 00 00 04 00 00 00 00 00 00 00  ................
000000c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
...

after seeing the hexdump (not modifying), I will try to revert back haxdump to binary with command :%!xxd -r. After which the file cannot be run anymore:

$./a.out
bash: ./a.out: cannot execute binary file: Exec format error

I have not made any changes. So did vim saved it with some changes, or why cannot bash recognize the format ELF?

3
  • Welcome to Vi and Vim!
    – filbranden
    Commented Jun 20, 2020 at 14:34
  • Does this issue still happen if you open the a.out file using vim -b (for "binary")? Vim will potentially mess up with line endings and possibly add a newline to the very end of the file. It might also mess with encodings. -b should neutralize all that. Check whether it works please?
    – filbranden
    Commented Jun 20, 2020 at 14:37
  • 1
    @filbranden is completely correct; binaries will be corrupted when not using vim -b—I know it has to do with encodings/line-endings, and it's not enough to set the options appropriately after the file has loaded. It must be done ahead of time, such as using -b or ++bin options (see :help edit-binary). See also github.com/benknoble/vim-hex/issues/4
    – D. Ben Knoble
    Commented Jun 20, 2020 at 15:04

1 Answer 1

2

As I started to explain in comments, the issue is described in :help edit-binary:

8. Editing binary files                 *edit-binary*

Although Vim was made to edit text files, it is possible to edit binary
files.  The |-b| Vim argument (b for binary) makes Vim do file I/O in binary
mode, and sets some options for editing binary files ('binary' on, 'textwidth'
to 0, 'modeline' off, 'expandtab' off).  Setting the 'binary' option has the
same effect.  Don't forget to do this before reading the file.

There are a few things to remember when editing binary files:
- When editing executable files the number of characters must not change.
  Use only the "R" or "r" command to change text.  Do not delete characters
  with "x" or by backspacing.
- Set the 'textwidth' option to 0.  Otherwise lines will unexpectedly be
  split in two.
- When there are not many <EOL>s, the lines will become very long.  If you
  want to edit a line that does not fit on the screen reset the 'wrap' option.
  Horizontal scrolling is used then.  If a line becomes too long (more than
  about 32767 characters on the Amiga, much more on 32-bit systems, see
  |limits|) you cannot edit that line.  The line will be split when reading
  the file.  It is also possible that you get an "out of memory" error when
  reading the file.
- Make sure the 'binary' option is set BEFORE loading the
  file.  Otherwise both <CR> <NL> and <NL> are considered to end a line
  and when the file is written the <NL> will be replaced with <CR> <NL>.
- <Nul> characters are shown on the screen as ^@.  You can enter them with
  "CTRL-V CTRL-@" or "CTRL-V 000"
- To insert a <NL> character in the file split a line.  When writing the
  buffer to a file a <NL> will be written for the <EOL>.
- Vim normally appends an <EOL> at the end of the file if there is none.
  Setting the 'binary' option prevents this.  If you want to add the final
  <EOL>, set the 'endofline' option.  You can also read the value of this
  option to see if there was an <EOL> for the last line (you cannot see this
  in the text).

Note that the flag must be set before loading the file! This is relevant to my hex-editing plugin as well.

5
  • But how to set that flag -b, when opening file from outside via :%!? As I am doing with the outside program xxd? is it possible? Commented Jun 20, 2020 at 15:44
  • You need to either vim -b a.out, or :edit ++bin a.out. Then you should have no troubles with :%!xxd
    – D. Ben Knoble
    Commented Jun 20, 2020 at 15:53
  • @milanHrabos When you use :%! you're filtering the contents of the current buffer, so the buffer options will be preserved. If you opened the buffer with vim -b initially, then that should be preserved over a :%! filter.
    – filbranden
    Commented Jun 20, 2020 at 15:54
  • But thats the thing, is there a filetype or somthing to resolve its actually bin file? because if I forgot to open it with that flag, and will edit it, then it will crash. I would like to "active" bin mode once open as "regular" file. I know manuals says to open it already with the flag, but is it possible to "activate" bin mode once open as regulare file? Commented Jun 20, 2020 at 15:57
  • @milanHrabos you can :set binary, but it still won’t work (it’s too late). You might be able to use an autocommand on BufReadPre or something, but it wont work for everything (ie, you could match patterns but not everything is a.out; you could try if the file is executable, but that catches scripts too, etc.). In my opinion, better to remember manually than rely on automation that doesnt work, but I would love to see someone solve that problem.
    – D. Ben Knoble
    Commented Jun 20, 2020 at 17:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.