foss-for-synopsys-dwc-arc-processors / linux

Helpful resources for users & developers of Linux kernel for ARC
22 stars 13 forks source link

[ARC64] obscure errors when trying to run ARCv2 binaries on ARCv3 system #44

Closed vineetgarc closed 3 years ago

vineetgarc commented 3 years ago

Host

arc-linux-gcc -Wall -g3 -L. main.c -ldl -o main
arc-linux-gcc -Wall -g3 -fPIC -c -o lib.o libc.c
arc-linux-gcc -shared -Wl,-soname,lib.so -o lib.so lib.o

ARC64 Target (QEMU)


# cat /proc/cpuinfo  | egrep "(IDEN|ISA)"
IDENTITY    : ARCVER [0x70] ARCNUM [0x0] CHIPID [0xffff]
processor [0]   : HS68 (ARC64 ARCv3 ISA) 
ISA Extn    : atomic unalign 

# cd /nfs/mounted/host/
# LD_LIBRARY_PATH=. ./main
./main: line 1: syntax error: unexpected word (expecting ")")

For aRCv2 we have better messages when we would try to run ARCompact binaries !

VVIsaev commented 3 years ago

I think this message is specific to shell. So ash (busybox default) will raise this message on any platform:

$ arc-elf32-readelf -h ./hello | grep Machine
  Machine:                           ARCompact
$ busybox sh
~ $ uname -m
x86_64
~ $ ./hello
./hello: line 1: syntax error: unexpected "("
~ $ ssh qemu-arcv2
# cat /proc/cpuinfo  | egrep "(IDEN|ISA)"
IDENTITY        : ARCVER [0x54] ARCNUM [0x0] CHIPID [0xffff]
processor [0]   : HS38 R3.10a (ARCv2 ISA)
ISA Extn        : mpy[opt 7]
# ./hello
./hello: line 1: syntax error: unexpected "("

Here is code (busybox/shell/ash.c) responsible for executing binaries in ash:

static void
tryexec(IF_FEATURE_SH_STANDALONE(int applet_no,) const char *cmd, char **argv, char **envp)
{
...
        execve(cmd, argv, envp);

        if (cmd != bb_busybox_exec_path && errno == ENOEXEC) {
                /* Run "cmd" as a shell script:
                 * http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html
                 * "If the execve() function fails with ENOEXEC, the shell
                 * shall execute a command equivalent to having a shell invoked
                 * with the command name as its first operand,
                 * with any remaining arguments passed to the new shell"
                 *
                 * That is, do not use $SHELL, user's shell, or /bin/sh;
                 * just call ourselves.
                 *
                 * Note that bash reads ~80 chars of the file, and if it sees
                 * a zero byte before it sees newline, it doesn't try to
                 * interpret it, but fails with "cannot execute binary file"
                 * message and exit code 126. For one, this prevents attempts
                 * to interpret foreign ELF binaries as shell scripts.
                 */
                argv[0] = (char*) cmd;
                cmd = bb_busybox_exec_path;
                /* NB: this is only possible because all callers of shellexec()
                 * ensure that the argv[-1] slot exists!
                 */
                argv--;
                argv[0] = (char*) "ash";
...

So in case of ENOEXEC it tries to interpret it as a shell script. ENOEXEC looks like correct error here (man execve):

ENOEXEC
    An executable is not in a recognized format, is for the wrong architecture, or has some other format error that means it cannot be executed.

So I have no ideas what to fix here. Please close or reassign the issue back to me if I missed something.

cupertinomiranda commented 3 years ago

Nice analysis @VVIsaev ! :+1:

vineetgarc commented 3 years ago

@VVIsaev commit merged.