SIGSEGV when executing 32 bit binary on 64 bit Linux - linux

You may have heard of StoneKnifeForth, a project by kragen: https://github.com/kragen/stoneknifeforth. It's a Python program that acts as a small Forth interpreter and a Forth program that acts as a Forth compiler. Therefore you can build a Forth compiler binary using those two in unison.
After porting StoneKnifeForth to C++ (https://github.com/tekknolagi/stoneknifecpp), I noticed that all binaries produced by StoneKnifeForth (either variety) segfault on 64 bit Linux. That is, if you clone stoneknifecpp and run:
make
./l01compiler # produced by the Forth program
You'll get the following:
willow% ./l01compiler
[1] 31614 segmentation fault ./l01compiler
This isn't a very interesting error message, obviously, so I thought I would strace it:
willow% strace ./l01compiler
execve("./l01compiler", ["./l01compiler"], [/* 110 vars */]) = -1 EPERM (Operation not permitted)
--- SIGSEGV {si_signo=SIGSEGV, si_code=SI_KERNEL, si_addr=0} ---
+++ killed by SIGSEGV +++
[1] 31615 segmentation fault (core dumped) strace ./l01compiler
And got... somewhat more information. It looks like the ELF header is wrong somehow, except for the following two interesting tidbits:
It runs fine under 32 bit qemu
It runs fine if I sudo ./l01compiler
I'm a bit of a loss as to why this is, even after internet searching for possible differences between ELF header formats between 32 bit and 64 bit Linux kernels, etc. If anyone has any information, I would be delighted.
I have attached the header below:
willow% readelf -h l01compiler
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: Intel 80386
Version: 0x1
Entry point address: 0x1e39
Start of program headers: 52 (bytes into file)
Start of section headers: 0 (bytes into file)
Flags: 0x0
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 1
Size of section headers: 40 (bytes)
Number of section headers: 0
Section header string table index: 0

Big thanks to Tom Hebb (tchebb) for confirming my suspicions and figuring this out. As can be seen in this commit, the problem was that the origin address was simply too low. It's not related to 32 bit or 64 bit, but instead earlier kernel vs newer kernel.
The newer kernels have increased the vm.mmap_min_addr sysctl parameter, meaning that the old origin would prohibit the program from starting at all. That explains why sudo worked. As Tom explained, "Unless you invoke qemu with KVM support, qemu is an emulator not a hypervisor, so it simulates the entire address space and virtual memory subsystem in software and presumably doesn't impose any load address restrictions."

Related

External USB 3.0 HDD Spin down and power off when powering off or rebooting the Raspberry Pi 4B

An external USB 3.0 HDD Seagate Expantion Drive 1TB is connected to my Raspberry Pi 4B on the Raspbian Buster.
The hard drive rarely works, so the first thing I would like it to shut down during idle time (rotation stopped).
I must say right away that I tried the "hdparm" utility, but it absolutely does not work for me. On my old Raspberry Pi 3B +, it did its job perfectly, but it doesn’t work at all on the new one.
I tried doing
sudo hdparm -S 10 / dev / sda1
and
sudo hdparm -Y / dev / sda1
But all he gives out is
/dev/sda:
issuing sleep command
SG_IO: bad / missing sense data, sb []: 70 00 05 00 00 00 00 0a 00 00 00 00 24 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
At the same time, the disk continues to rotate and the LED on the case is on, no matter how much I wait
I also tried to register the following settings in hdparm.conf:
/dev/sda1 {
spindown_time = 20
}
But this also did not give any effect, the disk continues to rotate.
Also, knowing that udisks2 is installed in the raspbian buster, I tried to create a configuration file Seagate_Expansion_NA4B2GTR-0: 0.conf (this is exactly what the command "udevadm info / dev / sda" gave me) in the directory /etc/udisks2/ with the contents
[ATA]
StandbyTimeout = 20
But it didn't work either.
The fact that the disk does not stop spinning is my first problem. The second problem is that when you turn off or restart Raspberry, the disk does not park its heads and its power is interrupted abruptly, which causes a very unpleasant rattle. I found similar queries on the Internet, this is a very common problem.
I would like that during the procedure of shutting down the OS, the disk should be correctly unmounted and its power turned off before power is lost on the USB 3.0 port.
Fortunately, I was able to write a similar script and it works great:
hddshutdown.sh
sudo umount -f /dev/sda1
sudo udisksclt power-off -b /dev/sda1
sleep 5
If I run this script just while the OS is running, it does exactly what I need: The disk is unmounted, the disk rotation stops and the LED on the case goes out. However, I cannot get this script to work the same way during the OS shutdown procedure.
I wrote this unit for systemd:
hddshutdown.service in /usr/lib/systemd/system/
[Unit]
Description=[=======USB-HDD-spindown============]
DefaultDependencies=no
After=umount.target
Before=shutdown.target poweroff.target reboot.target halt.target
[Service]
ExecStart=/bin/sh /home/pi/hddshutdown.sh
Type=oneshot
RemainAfterExit=yes
[Install]
WantedBy=reboot.target
I did "sudo systemctl enable hddshutdown", tried several different configuration options, played with different Before, After, and WantedBy values, but none of the options worked, just one, the drive is successfully unmounted, but the power does not turn off, the drive continues to spin and LED is on until the moment the Pi is turned off. Moreover, I know for sure that the sh-script starts exactly, the "sleep" delay, which I set at the end of the script, really works.
I do not know Linux very well and this was my first experience writing units for systemd. I found information that udisksctl needs DBus to work, but it doesn’t exist during shutdown, and that’s why the drive’s power cannot turn off. I could not find a way to execute this unit as early as possible during the shutdown procedure when DBus is still available. (I don’t even know what it is, maybe I said stupidity)
Please help me solve 2 of these problems, thanks in advance.
I myself found the answer to my question. Because I use the Seagate Expansion drive, I used the Seagate Dashboard program from the official site to "reprogram" my hard drive. I was able to turn off the external LED-indicator and set the rotation shutdown time to 10 minutes and now on any system the hard disk is turned off after 10 minutes. Using programs like hdparm or udisks is no longer required!
What worked for me to make my HDD spin-down automatically when idle was this new implementation of hd-idle.
My particular setup is: Raspberry Pi 4B + Suptronics X835 + WD Blue WD20EZRZ.
Non of the other usual tools worked for me (hdparm, original hd-idle).

Load binary into stm32f103c8t6 with OpenOCD and arm-none-eabi-gdb

I tried to load binary that is compiled from rust code, but it doesn't work.
First, I downloaded Rust code from https://github.com/rust-embedded/discovery.
Then, I built it.
# I am in the `src/05-led-roulette` directory
rustup target add thumbv7m-none-eabi
cargo build --target thumbv7m-none-eabi
It was successfully compiled.
After that, I successfully connected with stm32f103c8t6 using OpenOCD.
Then, I run this command.
arm-none-eabi-gdb -q target/thumbv7m-none-eabi/debug/led-roulette
But it seemed like it didn't finish reading.
Reading symbols from target/thumbv7m-none-eabi/debug/led-roulette...
(gdb)
(not done?!)
After that, I tried loadcommand, but it returned following sentences.
Start address 0x0, load size 0
Transfer rate: 0 bits in <1 sec.
I have no idea about why it doesn't work.
Please help me.
First see if your binary is good, then try telnet, then gdb. Rust also multiplies the odds of failure, so start with something simple:
so.s
.thumb
.globl _start
_start:
.word 0x20001000
.word reset
.thumb_func
reset:
ldr r0,some_addr
ldr r1,[r0]
add r1,r1,#1
str r1,[r0]
b .
.align
some_addr: .word 0x20000000
build it
arm-none-eabi-as so.s -o so.o
arm-none-eabi-ld -Ttext=0x08000000 so.o -o so.elf
arm-none-eabi-objdump -D so.elf
arm-none-eabi-objdump -D so.elf
so.elf: file format elf32-littlearm
Disassembly of section .text:
08000000 <_start>:
8000000: 20001000 andcs r1, r0, r0
8000004: 08000009 stmdaeq r0, {r0, r3}
08000008 :
8000008: 4802 ldr r0, [pc, #8] ; (8000014 <some_addr>)
800000a: 6801 ldr r1, [r0, #0]
800000c: 3101 adds r1, #1
800000e: 6001 str r1, [r0, #0]
8000010: e7fe b.n 8000010 <reset+0x8>
8000012: 46c0 nop ; (mov r8, r8)
08000014 <some_addr>:
8000014: 20000000 andcs r0, r0, r0
for small programs (Read the st documentation) this can be based at address 0x08000000 or 0x00000000 for this part. 0x08000000 is preferred. The vector table must be first in this case ignore the disassembly just look at the values
8000000: 20001000 andcs r1, r0, r0
8000004: 08000009 stmdaeq r0, {r0, r3}
The 0x08000009 is the reset address ORRed with one. so 0x08000008 | 1 is 0x08000009. So that will at least boot and try to fetch code without a fault.
This code simply reads the word at address 0x20000000 and increments it, sram is not affected by a reset so we can keep resetting and seeing that value increment.
using whatever configs you have and interface, I combine the openocd one for the st part into a single file and carry that with the project along with ones for the various interfaces (stlinks of different versions and jlink).
openocd -f jlink.cfg -f target.cfg
Open On-Chip Debugger 0.9.0 (2019-04-28-23:34)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
Info : JLink SWD mode enabled
swd
adapter speed: 1000 kHz
adapter_nsrst_delay: 100
none separate
cortex_m reset_config sysresetreq
Info : J-Link ARM-OB STM32 compiled Jun 30 2009 11:14:15
Info : J-Link caps 0x88ea5833
Info : J-Link hw version 70000
Info : J-Link hw type J-Link
Info : J-Link max mem block 15344
Info : J-Link configuration
Info : USB-Address: 0x0
Info : Kickstart power on JTAG-pin 19: 0x0
Info : Vref = 3.300 TCK = 1 TDI = 1 TDO = 1 TMS = 1 SRST = 1 TRST = 1
Info : J-Link JTAG Interface ready
Info : clock speed 1000 kHz
Info : SWD IDCODE 0x1ba01477
Info : stm32f1x.cpu: hardware has 6 breakpoints, 4 watchpoints
If you don't see the watchpoints line if it returns to the console, it didn't work.
In another window
telnet localhost 4444
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Open On-Chip Debugger
>
Now let's stop the chip and write our program. The psr, pc, etc values may be different depending than mine depending on what you had running.
> reset halt
target state: halted
target halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x08000010 msp: 0x20001000
> flash write_image erase so.elf
auto erase enabled
device id = 0x20036410
flash size = 64kbytes
wrote 1024 bytes from file so.elf in 0.437883s (2.284 KiB/s)
Let's read it and see that it is there, should match the words from the disassembly
> mdw 0x08000000 20
0x08000000: 20001000 08000009 5000f04f 31016801 e7fe6001 ffffffff ffffffff ffffffff
0x08000020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
0x08000040: ffffffff ffffffff ffffffff ffffffff
Assume this is random garbage and that is fine so long as we see it increment.
> mdw 0x20000000
0x20000000: 2e006816
> reset
> halt
target state: halted
target halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x08000012 msp: 0x20001000
> mdw 0x20000000
0x20000000: 2e006817
So the value incremented if you do a reset, then do a halt (not a reset halt in one command) then dump that memory location it should keep incrementing every time.
Now you can choose to take the gdb path (I don't have a use for gdb so don't have one installed) with this binary or examine your rust binary by first examining the vector table to see it is correct, without at least the reset vector being correct then you will fault and not run any code on the processor. Can flash it using telnet or you can try gdb.
If gdb is having a problem with the file then perhaps you are using the wrong file. or the file is incorrectly built. did you try a simple program in that repository? can you make a minimal program from that repository, an empty entry function or an infinite loop or a counter that counts forever?
Is this truly a gdb problem? Is this an openocd problem? Is this a Rust tools problem? Is this a Rust binary problem? Is this a bug in the docs and you are pointing gdb at the wrong file problem? If the above works then openocd works, binutils at least works, the debugger/hardware works, it eliminates those and then becomes is this a rust thing, a gdb thing, using the wrong file thing, or something else?
After connecting openocd with the board don't forget to connect the debugger
arm-none-eabi-gdb with openocd.
> arm-none-eabi-gdb -se target/thumbv7em-none-eabi/release/your_binary
(gdb) target remote localhost:3333
If all is OK in the terminal console where openocd is running you will see the message:
accepting 'gdb' connection on tcp/3333`
and you should be able to start debugging.
To optimize connection setup you may create/update the .gdbinit file with the content:
target remote localhost:3333

Rust embedded application is not linked correctly under AArch64 system

I'm trying to compile and debug an embedded rust application for stm32f0 using an ARM system as host.
The application already compiles and works under an Intel installation.
I am running on a Pinebook Pro, powered by a Quad Cortex-A53, 64-bit CPU. The OS is a 64-bit version of Debian:
$ uname -a
Linux pinebook 4.4.196 #1 SMP Tue Oct 15 16:54:21 EDT 2019 aarch64 GNU/Linux
I installed rust and cargo with rustup for AArch64 (channel stable):
$ rustc --version
rustc 1.39.0 (4560ea788 2019-11-04)
$ cargo --version
cargo 1.39.0 (1c6ec66d5 2019-09-30)
As per this issue I found out that rust-lld is not distributed in binary form for ARM systems, so I had to compile it from sources:
$ ld.lld --version
LLD 10.0.0 (https://github.com/llvm/llvm-project.git 1c247dd028b368875bc36cd2a9ccc7fd90507776) (compatible with GNU linkers)
Now the compilation process completes without issues:
export RUSTFLAGS="-C linker=ld.lld"
cargo build
However the resulting elf file seems to be linked incorrectly: trying to load it with gdb through openocd results in some kind of silent failure:
(gdb) target remote :3333
Remote debugging using :3333
0x00000000 in ?? ()
(gdb) load
Start address 0x0, load size 0
Transfer rate: 0 bits in <1 sec.
(gdb)
The load size is empty, so no new program is flashed. In contrast, when using the elf compiled in my Intel system (with openocd still running on the arm laptop) everything works as expected:
(gdb) target remote 192.168.1.153:3333
Remote debugging using 192.168.1.153:3333
0x00000000 in ?? ()
(gdb) load
Loading section .vector_table, size 0xc0 lma 0x8000000
Loading section .text, size 0x686e lma 0x80000c0
Loading section .rodata, size 0x4a0 lma 0x8006940
Start address 0x8005b58, load size 28110
Transfer rate: 19 KB/sec, 7027 bytes/write.
(gdb)
It would seems like the elf is not linked correctly. Running readelf -l highlights that on my ARM system the entry point set is 0x0, which is wrong for the stm32f0.
This is readelf on my ARM laptop:
lf file type is EXEC (Executable file)
Entry point 0x0
There are 3 program headers, starting at offset 52
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
PHDR 0x000034 0x00010034 0x00010034 0x00060 0x00060 R 0x4
LOAD 0x000000 0x00010000 0x00010000 0x00094 0x00094 R 0x1000
GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0
Section to Segment mapping:
Segment Sections...
00
01
02
While this is from the elf that works, compiled under my Intel system:
Elf file type is EXEC (Executable file)
Entry point 0x8005b59
There are 3 program headers, starting at offset 52
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
LOAD 0x001000 0x08000000 0x08000000 0x06de0 0x06de0 R E 0x1000
LOAD 0x007de0 0x20000000 0x08006de0 0x00000 0x00028 RW 0x1000
GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0
Section to Segment mapping:
Segment Sections...
00 .vector_table .text .rodata
01 .data .bss
02
I'm not sure if this has something to do with the target architecture being the same as the host (thus using the linux userland linking) or simple because arm systems are less supported.
Can anyone point me in the right direction?
I was correct in assuming there was a problem with the linker, and there are a couple of solutions.
Since two years ago Rust uses LLD as the default linker for the ARM architecture (https://rust-embedded.github.io/blog/2018-08-2x-psa-cortex-m-breakage/). Unfortunately rust-lld itself is not distributed in binary form for the ARM platforms (ironic, isn't it?), so I had to compile it from source and specify it via command line.
Exporting the RUSTFLAGS variable works but overwrites its default value defined in .cargo/config, which would include also the directive for the linker script (-C link-arg=-Tlink.x). In short I was convinced of using the correct linker script because it was listed in .cargo/config, but the RUSTFLAGS env variable was removing it.
The solution is to either
include the linker script explicitly when exporting RUSTFLAGS:
export RUSTFLAGS="-C linker=ldd -C link-arg=-Tlink.x"
specify "-C", "linker=lld" as a rust flag in the .cargo/config file with the other options
Enable the old linker (arm-none-eabi-ld) which is more easily retrievable by uncommenting the following line in .cargo/config: "-C", "linker=arm-none-eabi-gcc"
You have to create raw binary image by using a linker srcipt dedicated to that board.
https://github.com/szczys/stm32f0-discovery-basic-template/tree/master/Device/ldscripts

ec2 Instance Status Checks failed

I am trying to backup 20GB mongoDB data from a running EC2 instance. I create a snapshot of EBS volumes. Create an AMI base on the snapshot and launch the AMI instance.
But the instance launch fails due to the status checks. It does pass the "System Status Checks" but not the "Instance Status Checks". Does anyone know how to fix it? Thanks very much.
**
Here is the system log:
**
Linux version 2.6.16-xenU (builder#xenbat.amazonsa) (gcc version 4.0.1 20050727 (Red Hat 4.0.1-5)) #14 SMP Mon May 28 03:41:48 SAST 2007
BIOS-provided physical RAM map:
Xen: 0000000000000000 - 0000000023530000 (usable)
0MB HIGHMEM available.
565MB LOWMEM available.
NX (Execute Disable) protection: active
Built 1 zonelists
Kernel command line: root=/dev/sda1 ro console=hvc0 4
Enabling fast FPU save and restore... done.
Enabling unmasked SIMD FPU exception support... done.
Initializing CPU#0
PID hash table entries: 4096 (order: 12, 65536 bytes)
Xen reported: 1799.999 MHz processor.
Console: colour dummy device 80x25
Dentry cache hash table entries: 131072 (order: 7, 524288 bytes)
Inode-cache hash table entries: 65536 (order: 6, 262144 bytes)
Software IO TLB disabled
vmalloc area: e4000000-ff5fe000, maxmem 379fe000
Memory: 559744k/578752k available (1974k kernel code, 10400k reserved, 628k data, 156k init, 0k highmem)
Checking if this processor honours the WP bit even in supervisor mode... Ok.
Calibrating delay using timer specific routine.. 3613.44 BogoMIPS (lpj=18067215)
Mount-cache hash table entries: 512
CPU: L1 I cache: 32K, L1 D cache: 32K
CPU: L2 cache: 256K
CPU: L3 cache: 20480K
Checking 'hlt' instruction... OK.
Brought up 1 CPUs
migration_cost=0
Grant table initialized
NET: Registered protocol family 16
Brought up 1 CPUs
xen_mem: Initialising balloon driver.
VFS: Disk quotas dquot_6.5.1
Dquot-cache hash table entries: 1024 (order 0, 4096 bytes)
Initializing Cryptographic API
io scheduler noop registered
io scheduler anticipatory registered (default)
io scheduler deadline registered
io scheduler cfq registered
i8042.c: No controller found.
RAMDISK driver initialized: 16 RAM disks of 4096K size 1024 blocksize
Xen virtual console successfully installed as tty1
Event-channel device installed.
netfront: Initialising virtual ethernet driver.
mice: PS/2 mouse device common for all mice
md: md driver 0.90.3 MAX_MD_DEVS=256, MD_SB_DISKS=27
md: bitmap version 4.39
NET: Registered protocol family 2
Registering block device major 8
netfront: device eth0 has copying receive path.
IP route cache hash table entries: 32768 (order: 5, 131072 bytes)
TCP established hash table entries: 131072 (order: 8, 1048576 bytes)
TCP bind hash table entries: 65536 (order: 7, 524288 bytes)
TCP: Hash tables configured (established 131072 bind 65536)
TCP reno registered
TCP bic registered
NET: Registered protocol family 1
NET: Registered protocol family 17
NET: Registered protocol family 15
Using IPI No-Shortcut mode
XENBUS: Device with no driver: device/console/0
md: Autodetecting RAID arrays.
md: autorun ...
md: ... autorun DONE.
end_request: I/O error, dev sda1, sector 2
EXT3-fs: unable to read superblock
Unable to handle kernel NULL pointer dereference at virtual address 00000024
printing eip:
c0256ebd
0047a000 -> *pde = 00000000:24480067
00480000 -> *pme = 00000000:00000000
Oops: 0000 [#1]
SMP
Modules linked in:
CPU: 0
EIP: 0061:[<c0256ebd>] Not tainted VLI
EFLAGS: 00010097 (2.6.16-xenU #14)
EIP is at blkif_int+0x11d/0x270
eax: 00000000 ebx: 00000001 ecx: e2c5f0ac edx: 00000000
esi: 08010100 edi: 00000000 ebp: c038deb0 esp: c038de78
ds: 007b es: 007b ss: e021
Process swapper (pid: 0, threadinfo=c038c000 task=c0339400)
Stack: <0>c0352360 00000001 00000000 e2ae407c 00000000 e2c5f0ac 00000001 00000002
00000000 c34adc7c 00000001 e2aa75c0 00000000 00000000 c038ded8 c013f64f
00000105 e2ae4000 c038df40 c038df40 00000105 00008280 c0381680 00000105
Call Trace:
[<c010592d>] show_stack_log_lvl+0xcd/0x120
[<c0105b2b>] show_registers+0x1ab/0x240
[<c0105e31>] die+0x111/0x240
[<c0113157>] do_page_fault+0x707/0xc32
[<c0105307>] error_code+0x2b/0x30
[<c013f64f>] handle_IRQ_event+0x3f/0xd0
[<c013f76e>] __do_IRQ+0x8e/0xf0
[<c0106f0d>] do_IRQ+0x1d/0x30
[<c024c111>] evtchn_do_upcall+0xa1/0xe0
[<c0105349>] hypervisor_callback+0x3d/0x48
[<c01039ef>] xen_idle+0x2f/0x60
[<c0103a92>] cpu_idle+0x72/0xc0
[<c0102035>] rest_init+0x35/0x40
[<c038e56a>] start_kernel+0x2ea/0x3a0
[<c010006f>] 0xc010006f
Code: 89 82 84 00 00 00 8b 55 0c 89 b2 fc 13 00 00 8b 4d dc 0f bf 51 0a 0f b6 41 08 66 85 d2 0f 94 c3 3c 01 0f 87 38 ff ff ff 8b 55 d8 <8b> 42 24 89 5c 24 04 89 14 24 89 44 24 08 e8 60 f3 fb ff 85 c0
<0>Kernel panic - not syncing: Fatal exception in interrupt
Creating a snapshot from an EBS volume is possible, but as John Hanley pointed out, not guaranteed to succeed. Amazon has a doc with some specifics that you might want to go over: Creating an Amazon EBS-Backed Linux AMI.
The important part for you, under Creating a Linux AMI from a Snapshot, is this snippet:
If you have a snapshot of the root device volume of an instance, you can create an AMI from this snapshot using the AWS Management Console or the command line.
Important
[ ... ]
Similarly, although you can create a Windows AMI from a snapshot, you can't successfully launch an instance from the AMI.
In general, AWS advises against manually creating AMIs from snapshots.
If you want to take an exact replica of the machine you're on, the preferred way is to take an AMI of the instance:
Create an AMI from an Amazon EC2 Instance
You need to attach another private IP then stop and start instance follow this tutorial which fixed my Instance Status Checks failed issue: https://www.reluscloud.com/blog/troubleshooting-failed-ec2-status-checks

Application shows up as DYN (Shared object file) [duplicate]

This question already has answers here:
Output of 'make' is a shared object and not an executable
(2 answers)
Closed 6 years ago.
I have an application on my Ubuntu system, built with CMake, using add_executable predicate. It runs fine by itself, however, readelf shows it as DYN (Shared object file) which is usually applied to shared libraries:
root#3cced4f9860d build# readelf -h ./unittest/unittests
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: DYN (Shared object file)
Machine: Advanced Micro Devices X86-64
Version: 0x1
Entry point address: 0x3e3660
Start of program headers: 64 (bytes into file)
Start of section headers: 19112592 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 56 (bytes)
Number of program headers: 9
Size of section headers: 64 (bytes)
Number of section headers: 31
Section header string table index: 28
Does anyone know why this may happen?
On modern distros executables are compiled to position-independent code by default (see e.g. this question) which causes tools (file, etc.) to think that they are shared libs. I suggest you file a bug against respective tools so that they produce more user-friendly output.

Resources