It seems that binaries created with gcc 4.9.2 on Linux (Ubuntu 15.04, 32-bit) have a couple of thousand unused bytes between sections .eh_frame and .init_array. Example output from objdump -h for a simple executable:
Sections:
Idx Name Size VMA LMA File off Algn
[...]
16 .eh_frame 000000c0 080484ac 080484ac 000004ac 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
17 .init_array 00000004 08049f08 08049f08 00000f08 2**2
CONTENTS, ALLOC, LOAD, DATA
[...]
.eh_frame ends at file offset 0x56c but .init_array starts at 0xf08 leaving a hole of 0x99c = 2460 bytes. All other sections start immediately after the end of the previous section.
The size of the unused space varies, making it hard to observe how certain changes affect code size.
Where does this hole come from? Is there a way to avoid it?
Update: Output of ld --verbose:
$ cat so.c
int main() {
return 0;
}
$ gcc so.c -Wl,--verbose -o so
GNU ld (GNU Binutils for Ubuntu) 2.25
Supported emulations:
elf_i386
i386linux
elf32_x86_64
elf_x86_64
elf_l1om
elf_k1om
i386pep
i386pe
using internal linker script:
==================================================
/* Script for -z combreloc: combine and sort reloc sections */
/* Copyright (C) 2014 Free Software Foundation, Inc.
Copying and distribution of this script, with or without modification,
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved. */
OUTPUT_FORMAT("elf32-i386", "elf32-i386",
"elf32-i386")
OUTPUT_ARCH(i386)
ENTRY(_start)
SEARCH_DIR("=/usr/i686-linux-gnu/lib32"); SEARCH_DIR("=/usr/local/lib32"); SEARCH_DIR("=/lib32"); SEARCH_DIR("=/usr/lib32"); SEARCH_DIR("=/usr/i686-linux-gnu/lib"); SEARCH_DIR("=/usr/local/lib/i386-linux-gnu"); SEARCH_DIR("=/usr/local/lib"); SEARCH_DIR("=/lib/i386-linux-gnu"); SEARCH_DIR("=/lib"); SEARCH_DIR("=/usr/lib/i386-linux-gnu"); SEARCH_DIR("=/usr/lib");
SECTIONS
{
/* Read-only sections, merged into text segment: */
PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x08048000)); . = SEGMENT_START("text-segment", 0x08048000) + SIZEOF_HEADERS;
.interp : { *(.interp) }
.note.gnu.build-id : { *(.note.gnu.build-id) }
.hash : { *(.hash) }
.gnu.hash : { *(.gnu.hash) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.gnu.version : { *(.gnu.version) }
.gnu.version_d : { *(.gnu.version_d) }
.gnu.version_r : { *(.gnu.version_r) }
.rel.dyn :
{
*(.rel.init)
*(.rel.text .rel.text.* .rel.gnu.linkonce.t.*)
*(.rel.fini)
*(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*)
*(.rel.data.rel.ro .rel.data.rel.ro.* .rel.gnu.linkonce.d.rel.ro.*)
*(.rel.data .rel.data.* .rel.gnu.linkonce.d.*)
*(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*)
*(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*)
*(.rel.ctors)
*(.rel.dtors)
*(.rel.got)
*(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*)
*(.rel.ifunc)
}
.rel.plt :
{
*(.rel.plt)
PROVIDE_HIDDEN (__rel_iplt_start = .);
*(.rel.iplt)
PROVIDE_HIDDEN (__rel_iplt_end = .);
}
.init :
{
KEEP (*(SORT_NONE(.init)))
}
.plt : { *(.plt) *(.iplt) }
.text :
{
*(.text.unlikely .text.*_unlikely .text.unlikely.*)
*(.text.exit .text.exit.*)
*(.text.startup .text.startup.*)
*(.text.hot .text.hot.*)
*(.text .stub .text.* .gnu.linkonce.t.*)
/* .gnu.warning sections are handled specially by elf32.em. */
*(.gnu.warning)
}
.fini :
{
KEEP (*(SORT_NONE(.fini)))
}
PROVIDE (__etext = .);
PROVIDE (_etext = .);
PROVIDE (etext = .);
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
.rodata1 : { *(.rodata1) }
.eh_frame_hdr : { *(.eh_frame_hdr) }
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) }
.gcc_except_table : ONLY_IF_RO { *(.gcc_except_table
.gcc_except_table.*) }
/* These sections are generated by the Sun/Oracle C++ compiler. */
.exception_ranges : ONLY_IF_RO { *(.exception_ranges
.exception_ranges*) }
/* Adjust the address for the data segment. We want to adjust up to
the same address within the page on the next page up. */
. = ALIGN (CONSTANT (MAXPAGESIZE)) - ((CONSTANT (MAXPAGESIZE) - .) & (CONSTANT (MAXPAGESIZE) - 1)); . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));
/* Exception handling */
.eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) }
.gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
.exception_ranges : ONLY_IF_RW { *(.exception_ranges .exception_ranges*) }
/* Thread Local Storage sections */
.tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
.tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
}
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
PROVIDE_HIDDEN (__init_array_end = .);
}
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
PROVIDE_HIDDEN (__fini_array_end = .);
}
.ctors :
{
/* gcc uses crtbegin.o to find the start of
the constructors, so we make sure it is
first. Because this is a wildcard, it
doesn't matter if the user does not
actually link against crtbegin.o; the
linker won't look for a file to match a
wildcard. The wildcard also means that it
doesn't matter which directory crtbegin.o
is in. */
KEEP (*crtbegin.o(.ctors))
KEEP (*crtbegin?.o(.ctors))
/* We don't want to include the .ctor section from
the crtend.o file until after the sorted ctors.
The .ctor section from the crtend file contains the
end of ctors marker and it must be last */
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
}
.dtors :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*crtbegin?.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
}
.jcr : { KEEP (*(.jcr)) }
.data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) }
.dynamic : { *(.dynamic) }
.got : { *(.got) *(.igot) }
. = DATA_SEGMENT_RELRO_END (SIZEOF (.got.plt) >= 12 ? 12 : 0, .);
.got.plt : { *(.got.plt) *(.igot.plt) }
.data :
{
*(.data .data.* .gnu.linkonce.d.*)
SORT(CONSTRUCTORS)
}
.data1 : { *(.data1) }
_edata = .; PROVIDE (edata = .);
. = .;
__bss_start = .;
.bss :
{
*(.dynbss)
*(.bss .bss.* .gnu.linkonce.b.*)
*(COMMON)
/* Align here to ensure that the .bss section occupies space up to
_end. Align after .bss to ensure correct alignment even if the
.bss section disappears because there are no input sections.
FIXME: Why do we need it? When there is no .bss section, we don't
pad the .data section. */
. = ALIGN(. != 0 ? 32 / 8 : 1);
}
. = ALIGN(32 / 8);
. = SEGMENT_START("ldata-segment", .);
. = ALIGN(32 / 8);
_end = .; PROVIDE (end = .);
. = DATA_SEGMENT_END (.);
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end ) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
/* DWARF 3 */
.debug_pubtypes 0 : { *(.debug_pubtypes) }
.debug_ranges 0 : { *(.debug_ranges) }
/* DWARF Extension. */
.debug_macro 0 : { *(.debug_macro) }
.gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }
/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }
}
==================================================
attempt to open /usr/lib/gcc/i686-linux-gnu/4.9/../../../i386-linux-gnu/crt1.o succeeded
/usr/lib/gcc/i686-linux-gnu/4.9/../../../i386-linux-gnu/crt1.o
attempt to open /usr/lib/gcc/i686-linux-gnu/4.9/../../../i386-linux-gnu/crti.o succeeded
/usr/lib/gcc/i686-linux-gnu/4.9/../../../i386-linux-gnu/crti.o
attempt to open /usr/lib/gcc/i686-linux-gnu/4.9/crtbegin.o succeeded
/usr/lib/gcc/i686-linux-gnu/4.9/crtbegin.o
attempt to open /tmp/ccQ0fTTK.o succeeded
/tmp/ccQ0fTTK.o
attempt to open /usr/lib/gcc/i686-linux-gnu/4.9/libgcc.so failed
attempt to open /usr/lib/gcc/i686-linux-gnu/4.9/libgcc.a succeeded
attempt to open /usr/lib/gcc/i686-linux-gnu/4.9/libgcc_s.so succeeded
-lgcc_s (/usr/lib/gcc/i686-linux-gnu/4.9/libgcc_s.so)
attempt to open /usr/lib/gcc/i686-linux-gnu/4.9/libc.so failed
attempt to open /usr/lib/gcc/i686-linux-gnu/4.9/libc.a failed
attempt to open /usr/lib/gcc/i686-linux-gnu/4.9/../../../i386-linux-gnu/libc.so succeeded
opened script file /usr/lib/gcc/i686-linux-gnu/4.9/../../../i386-linux-gnu/libc.so
opened script file /usr/lib/gcc/i686-linux-gnu/4.9/../../../i386-linux-gnu/libc.so
attempt to open /lib/i386-linux-gnu/libc.so.6 succeeded
/lib/i386-linux-gnu/libc.so.6
attempt to open /usr/lib/i386-linux-gnu/libc_nonshared.a succeeded
(/usr/lib/i386-linux-gnu/libc_nonshared.a)elf-init.oS
attempt to open /lib/i386-linux-gnu/ld-linux.so.2 succeeded
/lib/i386-linux-gnu/ld-linux.so.2
/lib/i386-linux-gnu/ld-linux.so.2
attempt to open /usr/lib/gcc/i686-linux-gnu/4.9/libgcc.so failed
attempt to open /usr/lib/gcc/i686-linux-gnu/4.9/libgcc.a succeeded
attempt to open /usr/lib/gcc/i686-linux-gnu/4.9/libgcc_s.so succeeded
-lgcc_s (/usr/lib/gcc/i686-linux-gnu/4.9/libgcc_s.so)
attempt to open /usr/lib/gcc/i686-linux-gnu/4.9/crtend.o succeeded
/usr/lib/gcc/i686-linux-gnu/4.9/crtend.o
attempt to open /usr/lib/gcc/i686-linux-gnu/4.9/../../../i386-linux-gnu/crtn.o succeeded
/usr/lib/gcc/i686-linux-gnu/4.9/../../../i386-linux-gnu/crtn.o
ld-linux.so.2 needed by /lib/i386-linux-gnu/libc.so.6
found ld-linux.so.2 at /lib/i386-linux-gnu/ld-linux.so.2
There are three regions of memory to consider there:
Read-only data.
Non-lazy relocations that can be fixed up at load time.
Data.
Now, the .eh_frame section is marked READONLY, so it goes into the first section.
.init_array is an array of function pointers to initialization functions, which can be resolved to their absolute addresses when loading the program/library, and then marked read-only (writing to function pointers is a common way to exploit vulnerabilities), so it goes into the second region.
The relevant parts of the linker script are:
[...]
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) }
[...]
/* Adjust the address for the data segment. We want to adjust up to
the same address within the page on the next page up. */
. = ALIGN (CONSTANT (MAXPAGESIZE)) - ((CONSTANT (MAXPAGESIZE) - .) & (CONSTANT (MAXPAGESIZE) - 1));
. = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));
[...]
.init_array :
[...]
.got : { *(.got) *(.igot) }
. = DATA_SEGMENT_RELRO_END (SIZEOF (.got.plt) >= 12 ? 12 : 0, .);
.got.plt : { *(.got.plt) *(.igot.plt) }
.data :
[...]
. = DATA_SEGMENT_END (.);
You can consult the documentation for builtin functions for GNU ld linker scripts at https://sourceware.org/binutils/docs/ld/Builtin-Functions.html. But beware that DATA_SEGMENT_ALIGN documentation is incorrect, as reported by Stephen Kell at binutils bug #19203: "DATA_SEGMENT_ALIGN documentation is not consistent with behaviour", apparently since Jakub Jelinek's [PATCH] Fix DATA_SEGMENT_ALIGN. DATA_SEGMENT_ALIGN itself was introduced at a binutils' mailing list thread called [RFC PATCH] Smarter aligning of data segment.
Somehow, the following:
. = ALIGN (CONSTANT (MAXPAGESIZE)) - ((CONSTANT (MAXPAGESIZE) - .) & (CONSTANT (MAXPAGESIZE) - 1));
. = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));
causes a 1-page jump, which in your example would move you from 0x0804856c to 0x0804956c.
When the linker option -z relro is used, requesting relocations fixed up at load time to be marked read-only, DATA_SEGMENT_RELRO_END causes the previous DATA_SEGMENT_ALIGN to add enough padding to cause the sum of the two arguments of DATA_SEGMENT_RELRO_END to be aligned to a new page.
So, assuming .got.plt has at least three pointers, those first three pointers (which are used right away by the loader) will be in the second region, and the rest of .got.plt on the third.
The padding added by DATA_SEGMENT_ALIGN moves you from 0x0804956c to 0x08049f08. When everything that can be mprotected read-only after fix-ups is emitted, you'll be at 0x0804a000, in a new page, which will be kept read-write.
Related
Update: the virtual address is invalid address, not null pointer.
=======================================================
Invalid virtual address problem happened in my project, but I did not modify the code, some information as below:
[ 1150.456387] Unable to handle kernel paging request at virtual address 0000000000010000
[ 1150.456393] Mem abort info:
[ 1150.456395] ESR = 0x96000005
[ 1150.456398] EC = 0x25: DABT (current EL), IL = 32 bits
[ 1150.456400] SET = 0, FnV = 0
[ 1150.456402] EA = 0, S1PTW = 0
[ 1150.456404] FSC = 0x05: level 1 translation fault
[ 1150.456407] Data abort info:
[ 1150.456409] ISV = 0, ISS = 0x00000005
[ 1150.456411] CM = 0, WnR = 0
[ 1150.456413] user pgtable: 4k pages, 39-bit VAs, pgdp=00000008e7572000
[ 1150.456415] [0000000000010000] pgd=0000000000000000, p4d=0000000000000000, pud=0000000000000000
[ 1150.456676] Internal error: Oops: 96000005 [#1] PREEMPT SMP
[ 1150.456802] Skip md ftrace buffer dump for: 0xa00f50
[ 1150.457154] pc : percpu_ref_get_many+0x2c/0x104
[ 1150.457164] lr : percpu_ref_get_many+0x2c/0x104
[ 1150.457167] sp : ffffffc02e513a20
[ 1150.457168] x29: ffffffc02e513a20 x28: ffffffef9324a000 x27: fffffffe00000008
[ 1150.457171] x26: fffffffe00000000 x25: 0000008000000000 x24: ffffff88661d3800
[ 1150.457175] x23: 0000000000000000 x22: ffffff8970f94408 x21: 0000000000000001
[ 1150.457178] x20: 0000000000010000 x19: 0000000000000001 x18: ffffffc01ce1b078
[ 1150.457181] x17: 430e0000071d4992 x16: 0001400000000000 x15: 000000008e83ddb6
[ 1150.457184] x14: 00000000ab032363 x13: 00000000d860b6cd x12: ffffff88661d4230
[ 1150.457187] x11: ffffffef93f46de8 x10: 0000000000000018 x9 : 0000000000000080
[ 1150.457190] x8 : 00000000000000c0 x7 : 0000000000000000 x6 : ffffffef910a04c0
[ 1150.457192] x5 : 0000000000000000 x4 : 0000000000000000 x3 : 0000000000000002
[ 1150.457195] x2 : 0000000000000000 x1 : ffffffef92f6e370 x0 : 0000000000000005
[ 1150.457198] Call trace:
[ 1150.457199] percpu_ref_get_many+0x2c/0x104
[ 1150.457202] refill_obj_stock.llvm.3785610425212570905+0xa8/0x24c
[ 1150.457208] memcg_slab_free_hook+0x138/0x1a8
[ 1150.457212] kmem_cache_free+0x14c/0x378
[ 1150.457214] unlink_anon_vmas+0x60/0x1e0
[ 1150.457217] free_pgtables+0x54/0x190
[ 1150.457219] unmap_region+0xfc/0x148
[ 1150.457223] __do_munmap+0x588/0x79c
[ 1150.457225] __vm_munmap.llvm.11919687734878218350+0x88/0x174
[ 1150.457228] __arm64_sys_munmap+0x44/0x5c
[ 1150.457231] invoke_syscall+0x60/0x150
[ 1150.457235] el0_svc_common.llvm.8274709215075016746+0xc8/0x114
[ 1150.457237] do_el0_svc+0x28/0xa0
[ 1150.457239] el0_svc+0x28/0x90
[ 1150.457243] el0t_64_sync_handler+0x88/0xec
[ 1150.457246] el0t_64_sync+0x1b4/0x1b8
[ 1150.457250] Code: 9402597f b0014e20 91196000 97fb46b8 (f8bfc289)
I parsed the information with the tool crash. The invalid address problem happened on the line percpu_ptr = READ_ONCE(ref->percpu_count_ptr); as below:
/*
* Internal helper. Don't use outside percpu-refcount proper. The
* function doesn't return the pointer and let the caller test it for NULL
* because doing so forces the compiler to generate two conditional
* branches as it can't assume that #ref->percpu_count is not NULL.
*/
static inline bool __ref_is_percpu(struct percpu_ref *ref,
unsigned long __percpu **percpu_countp)
{
unsigned long percpu_ptr;
/*
* The value of #ref->percpu_count_ptr is tested for
* !__PERCPU_REF_ATOMIC, which may be set asynchronously, and then
* used as a pointer. If the compiler generates a separate fetch
* when using it as a pointer, __PERCPU_REF_ATOMIC may be set in
* between contaminating the pointer value, meaning that
* READ_ONCE() is required when fetching it.
*
* The dependency ordering from the READ_ONCE() pairs
* with smp_store_release() in __percpu_ref_switch_to_percpu().
*/
percpu_ptr = READ_ONCE(ref->percpu_count_ptr);
/*
* Theoretically, the following could test just ATOMIC; however,
* then we'd have to mask off DEAD separately as DEAD may be
* visible without ATOMIC if we race with percpu_ref_kill(). DEAD
* implies ATOMIC anyway. Test them together.
*/
if (unlikely(percpu_ptr & __PERCPU_REF_ATOMIC_DEAD))
return false;
*percpu_countp = (unsigned long __percpu *)percpu_ptr;
return true;
}
Another case happend on line if (unlikely(percpu_ptr & __PERCPU_REF_ATOMIC_DEAD)).
pointer variable ref comes from an address &objcg->refcnt as blow:
static inline void obj_cgroup_get(struct obj_cgroup *objcg)
{
percpu_ref_get(&objcg->refcnt);
}
So it cann't be invalid. Why did invalid address problem happened?
I have written a simple driver which is supposed to check if VMX is enabled or not, and the code for that is below.
#include <linux/module.h>
#include <linux/init.h>
inline bool vmxSupport(void)
{
int getVmxSupport, vmxBit;
__asm__ ("mov $1, %rax");
__asm__ ("cpuid");
__asm__ ("mov %%ecx , %0\n\t":"=r" (getVmxSupport));
//pr_info("\n");
vmxBit = (getVmxSupport >> 5) & 1;
if (vmxBit == 1){
return true;
}
else {
return false;
}
}
static int __init my_init(void)
{
vmxSupport();
pr_info("Hello world from mod1\n");
return 0;
}
static void __exit my_exit(void)
{
pr_info("Goodbye world from mod1\n");
}
module_init(my_init);
module_exit(my_exit);
MODULE_AUTHOR("vpn");
MODULE_DESCRIPTION("module1.c");
MODULE_LICENSE("GPL v2");
Short snippet of the error i'm getting:
Hello world from mod1
[ 908.381100] ------------[ cut here ]------------
[ 908.389199] initcall my_init+0x0/0x1000 [module1] returned with preemption imbalance
[ 908.396171] WARNING: CPU: 1 PID: 5049 at init/main.c:1300 do_one_initcall+0x2b8/0x320
[ 908.401424] Modules linked in: module1(OE+) intel_rapl_msr(E) intel_rapl_common(E)
.
.
.
R10: 0000000000000003 R11: 0000000000000246 R12: 0000559e223dc260
[ 908.560509] R13: 0000000000000000 R14: 0000559e235ec750 R15: 0000000000000000
[ 908.562768] ---[ end trace 0d070b847da4cd90 ]---
[ 908.565107] BUG: scheduling while atomic: insmod/5049/0x01000800
But when I add a pr_info(remove the comment from the shared code) after the 3rd __asm__ i don't get this issue.
Things i have tried:
Disable optimization for the function vmxSupport
inline / uninline the vmxSupport function
Checked the disassembly, i don't see anything crazy.
Any idea why I'm getting this error?
"Cpuid" alters RBX, RCX, and RDX registers. I suggest you to save them (push) before, and restore them (pop) after the instruction, because the compiler assumes that some of them are preserved. Your problem is probably due to a side effect of altering registers.
I have the files port.cpp and port.h.
The code isn't relevant for this question. The problem, I believe, is the linker script.
The linker script contains the following code:
ENTRY(loader)
OUTPUT_FORMAT(elf32-i386)
OUTPUT_ARCH(i386:i386)
SECTIONS
{
. = 0x0100000;
.text :
{
*(.multiboot)
*(.text*)
*(.rodata)
}
.data :
{
start_ctors = .;
KEEP(*( .init_array ));
KEEP(*(SORT_BY_INIT_PRIORITY( .init_array.* )));
end_ctors = .;
*(.data)
}
.bss :
{
*(.bss)
}
/DISCARD/ :
{
*(.fini_array*)
*(.comment)
}
}
And when I run ld with the only flag being -melf_i386 I get this error:
`.note.gnu.property' referenced in section `.text' of port.o: defined in discarded section `.note.gnu.property' of port.o
I believe the problem is the linker, but even after reading ld documentation, looking at the assembly code being generated and adding KEEP(*( .note.gnu.property )); I could not fix it.
I am trying to create a minimum executable using gcc/binutils.
My ld scripts is as below:
OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64",
"elf64-x86-64")
OUTPUT_ARCH(i386:x86-64)
ENTRY(_start)
SEARCH_DIR("/usr/x86_64-pc-linux-gnu/lib64"); SEARCH_DIR("/usr/lib64/binutils/x86_64-pc-linux-gnu/2.35.164"); SEARCH_DIR("/usr/local/lib64"); SEARCH_DIR("/lib64"); SEARCH_DIR("/usr/lib64"); SEARCH_DIR("/usr/x86_64-pc-linux-gnu/lib"); SEARCH_DIR("/usr/lib64/binutils/x86_64-pc-linux-gnu/2.35.1"); SEARCH_DIR("/usr/local/lib"); SEARCH_DIR("/lib"); SEARCH_DIR("/usr/lib");
SECTIONS
{
PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x400000)); . = SEGMENT_START("text-segment", 0x400000) + SIZEOF_HEADERS;
.text :
{
*(.text.unlikely .text.*_unlikely .text.unlikely.*)
*(.text.exit .text.exit.*)
*(.text.startup .text.startup.*)
*(.text.hot .text.hot.*)
*(SORT(.text.sorted.*))
*(.text .stub .text.* .gnu.linkonce.t.*)
/* .gnu.warning sections are handled specially by elf.em. */
*(.gnu.warning)
}
.data :
{
*(.data .data.* .gnu.linkonce.d.*)
SORT(CONSTRUCTORS)
}
.bss :
{
*(.dynbss)
*(.bss .bss.* .gnu.linkonce.b.*)
*(COMMON)
}
}
Everything is OK for me, except that I see a extra segment header named "GNU_STACK" with size 0.
The header increases 56 bytes of course. Does anyone know how to remove it? Creating elf by hand is crazy, I want to use gcc/binutils to do it.
Looks like no way to do it. Finally I modified binutils source to remove it.
Note: the GNU_STACK ELF program header entry is required to mark the stack as not executable on legacy systems (32-bits x86, arm and powerpc, for example). If you remove it, the stack will be automatically marked as executable by the kernel:
linux-5.17/arch/arm/kernel.elf.c#n80
In modern architectures GNU_STACK is not needed, so your linker script should be modified with the following:
OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64",
"elf64-x86-64")
OUTPUT_ARCH(i386:x86-64)
ENTRY(_start)
SEARCH_DIR("/usr/x86_64-pc-linux-gnu/lib64"); SEARCH_DIR("/usr/lib64/binutils/x86_64-pc-linux-gnu/2.35.164"); SEARCH_DIR("/usr/local/lib64"); SEARCH_DIR("/lib64"); SEARCH_DIR("/usr/lib64"); SEARCH_DIR("/usr/x86_64-pc-linux-gnu/lib"); SEARCH_DIR("/usr/lib64/binutils/x86_64-pc-linux-gnu/2.35.1"); SEARCH_DIR("/usr/local/lib"); SEARCH_DIR("/lib"); SEARCH_DIR("/usr/lib");
PHDRS
{
READONLY PT_LOAD FILEHDR PHDRS;
READWRITE PT_LOAD;
}
SECTIONS
{
PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x400000)); . = SEGMENT_START("text-segment", 0x400000) + SIZEOF_HEADERS;
.text :
{
*(.text.unlikely .text.*_unlikely .text.unlikely.*)
*(.text.exit .text.exit.*)
*(.text.startup .text.startup.*)
*(.text.hot .text.hot.*)
*(SORT(.text.sorted.*))
*(.text .stub .text.* .gnu.linkonce.t.*)
/* .gnu.warning sections are handled specially by elf.em. */
*(.gnu.warning)
} : READONLY
. = ALIGN(0x1000);
.data :
{
*(.data .data.* .gnu.linkonce.d.*)
SORT(CONSTRUCTORS)
} : READWRITE
.bss :
{
*(.dynbss)
*(.bss .bss.* .gnu.linkonce.b.*)
*(COMMON)
}
}
Change the PHDRS configuration as you prefer.
If you remove the GNU_STACK entry, you should probably use the -Wtrampoline or -fno-trampolines compiler flags:
3.8 Options to Request or Suppress Warnings
3.17 Options for Code Generation Conventions
I'm trying to compile a library from this repo. Running make test in the root folder produces an executable file tests that depends on libpcreposix and libpcre. The linking line looks like this:
gfortran -std=f2008 -fall-intrinsics -ffree-line-length-none -Wall -Wextra -Wpedantic -Wno-target-lifetime -Wno-compare-reals -Jbuild.gnu.debug -g -Og -fcheck=bounds,do,mem,pointer,recursion -Isrc -Itests -DUSE_PCRE tests/tests.F90 build.gnu.debug/*.o -lpcreposix -lpcre -o build.gnu.debug/tests
As you can see, the required libraries are linked via -lpcreposix -lpcre and this line executes successfully, producing executable tests, which, however, crashes at runtime. I strongly suspect that this crash has something to do with these libraries, so I ran ldd tests, which showed the following output:
$ ldd build.gnu.debug/tests
linux-vdso.so.1 (0x00007ffe5b481000)
libgfortran.so.5 => /usr/lib/x86_64-linux-gnu/libgfortran.so.5 (0x00007fd307a59000)
libm.so.6 => /usr/lib/x86_64-linux-gnu/libm.so.6 (0x00007fd30790a000)
libgcc_s.so.1 => /usr/lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fd3078ef000)
libquadmath.so.0 => /usr/lib/x86_64-linux-gnu/libquadmath.so.0 (0x00007fd3078a5000)
libc.so.6 => /usr/lib/x86_64-linux-gnu/libc.so.6 (0x00007fd3076b3000)
/lib64/ld-linux-x86-64.so.2 (0x00007fd307e24000)
As you can see, libpcreposix and libpcre and not even on this list. The libraries were installed via sudo apt install libpcre3 libpcre3-dev and I can see them in /usr/lib/x86_64-linux-gnu/libpcreposix.so.3.13 and /usr/lib/x86_64-linux-gnu/libpcre.so.3.13.3. I have added this path to LD_LIBRARY_PATH (which did not even exist before that), but it did not change anything.
$ echo $LD_LIBRARY_PATH
/usr/lib/x86_64-linux-gnu
The executable tests definitely depends on these libraries, but just in case I have also tried to add -Wl,--no-as-needed to the linking line, which also did not change anything. I have tried the exact same sequence of actions on another machine and it worked without issues (and I was able to see the required libraries in the output of ldd), so it has to be related with the setup of my machine. The machine where I have issues is a recently created virtual machine (Ubuntu 20), so I might have forgotten to install of set up something here.
Edit:
Output of linking with -Wl,--verbose:
$ gfortran -std=f2008 -fall-intrinsics -ffree-line-length-none -Wall -Wextra -Wpedantic -Wno-target-lifetime -Wno-compare-reals -Jbuild.gnu.debug -g -Og -fcheck=bounds,do,mem,pointer,recursion -Isrc -Itests -DUSE_PCRE tests/tests.F90 build.gnu.debug/*.o -lpcreposix -lpcre -o build.gnu.debug/tests -Wl,--verbose
GNU ld (GNU Binutils for Ubuntu) 2.34
Supported emulations:
elf_x86_64
elf32_x86_64
elf_i386
elf_iamcu
elf_l1om
elf_k1om
i386pep
i386pe
using internal linker script:
==================================================
/* Script for -pie -z combreloc -z separate-code -z relro -z now */
/* Copyright (C) 2014-2020 Free Software Foundation, Inc.
Copying and distribution of this script, with or without modification,
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved. */
OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64",
"elf64-x86-64")
OUTPUT_ARCH(i386:x86-64)
ENTRY(_start)
SEARCH_DIR("=/usr/local/lib/x86_64-linux-gnu"); SEARCH_DIR("=/lib/x86_64-linux-gnu"); SEARCH_DIR("=/usr/lib/x86_64-linux-gnu"); SEARCH_DIR("=/usr/lib/x86_64-linux-gnu64"); SEARCH_DIR("=/usr/local/lib64"); SEARCH_DIR("=/lib64"); SEARCH_DIR("=/usr/lib64"); SEARCH_DIR("=/usr/local/lib"); SEARCH_DIR("=/lib"); SEARCH_DIR("=/usr/lib"); SEARCH_DIR("=/usr/x86_64-linux-gnu/lib64"); SEARCH_DIR("=/usr/x86_64-linux-gnu/lib");
SECTIONS
{
PROVIDE (__executable_start = SEGMENT_START("text-segment", 0)); . = SEGMENT_START("text-segment", 0) + SIZEOF_HEADERS;
.interp : { *(.interp) }
.note.gnu.build-id : { *(.note.gnu.build-id) }
.hash : { *(.hash) }
.gnu.hash : { *(.gnu.hash) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.gnu.version : { *(.gnu.version) }
.gnu.version_d : { *(.gnu.version_d) }
.gnu.version_r : { *(.gnu.version_r) }
.rela.dyn :
{
*(.rela.init)
*(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
*(.rela.fini)
*(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
*(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
*(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
*(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
*(.rela.ctors)
*(.rela.dtors)
*(.rela.got)
*(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
*(.rela.ldata .rela.ldata.* .rela.gnu.linkonce.l.*)
*(.rela.lbss .rela.lbss.* .rela.gnu.linkonce.lb.*)
*(.rela.lrodata .rela.lrodata.* .rela.gnu.linkonce.lr.*)
*(.rela.ifunc)
}
.rela.plt :
{
*(.rela.plt)
*(.rela.iplt)
}
. = ALIGN(CONSTANT (MAXPAGESIZE));
.init :
{
KEEP (*(SORT_NONE(.init)))
}
.plt : { *(.plt) *(.iplt) }
.plt.got : { *(.plt.got) }
.plt.sec : { *(.plt.sec) }
.text :
{
*(.text.unlikely .text.*_unlikely .text.unlikely.*)
*(.text.exit .text.exit.*)
*(.text.startup .text.startup.*)
*(.text.hot .text.hot.*)
*(SORT(.text.sorted.*))
*(.text .stub .text.* .gnu.linkonce.t.*)
/* .gnu.warning sections are handled specially by elf.em. */
*(.gnu.warning)
}
.fini :
{
KEEP (*(SORT_NONE(.fini)))
}
PROVIDE (__etext = .);
PROVIDE (_etext = .);
PROVIDE (etext = .);
. = ALIGN(CONSTANT (MAXPAGESIZE));
/* Adjust the address for the rodata segment. We want to adjust up to
the same address within the page on the next page up. */
. = SEGMENT_START("rodata-segment", ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)));
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
.rodata1 : { *(.rodata1) }
.eh_frame_hdr : { *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) }
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) }
.gcc_except_table : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) }
.gnu_extab : ONLY_IF_RO { *(.gnu_extab*) }
/* These sections are generated by the Sun/Oracle C++ compiler. */
.exception_ranges : ONLY_IF_RO { *(.exception_ranges*) }
/* Adjust the address for the data segment. We want to adjust up to
the same address within the page on the next page up. */
. = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));
/* Exception handling */
.eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) }
.gnu_extab : ONLY_IF_RW { *(.gnu_extab) }
.gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
.exception_ranges : ONLY_IF_RW { *(.exception_ranges*) }
/* Thread Local Storage sections */
.tdata :
{
PROVIDE_HIDDEN (__tdata_start = .);
*(.tdata .tdata.* .gnu.linkonce.td.*)
}
.tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
}
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
PROVIDE_HIDDEN (__init_array_end = .);
}
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
PROVIDE_HIDDEN (__fini_array_end = .);
}
.ctors :
{
/* gcc uses crtbegin.o to find the start of
the constructors, so we make sure it is
first. Because this is a wildcard, it
doesn't matter if the user does not
actually link against crtbegin.o; the
linker won't look for a file to match a
wildcard. The wildcard also means that it
doesn't matter which directory crtbegin.o
is in. */
KEEP (*crtbegin.o(.ctors))
KEEP (*crtbegin?.o(.ctors))
/* We don't want to include the .ctor section from
the crtend.o file until after the sorted ctors.
The .ctor section from the crtend file contains the
end of ctors marker and it must be last */
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
}
.dtors :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*crtbegin?.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
}
.jcr : { KEEP (*(.jcr)) }
.data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) }
.dynamic : { *(.dynamic) }
.got : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) }
. = DATA_SEGMENT_RELRO_END (0, .);
.data :
{
*(.data .data.* .gnu.linkonce.d.*)
SORT(CONSTRUCTORS)
}
.data1 : { *(.data1) }
_edata = .; PROVIDE (edata = .);
. = .;
__bss_start = .;
.bss :
{
*(.dynbss)
*(.bss .bss.* .gnu.linkonce.b.*)
*(COMMON)
/* Align here to ensure that the .bss section occupies space up to
_end. Align after .bss to ensure correct alignment even if the
.bss section disappears because there are no input sections.
FIXME: Why do we need it? When there is no .bss section, we do not
pad the .data section. */
. = ALIGN(. != 0 ? 64 / 8 : 1);
}
.lbss :
{
*(.dynlbss)
*(.lbss .lbss.* .gnu.linkonce.lb.*)
*(LARGE_COMMON)
}
. = ALIGN(64 / 8);
. = SEGMENT_START("ldata-segment", .);
.lrodata ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) :
{
*(.lrodata .lrodata.* .gnu.linkonce.lr.*)
}
.ldata ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) :
{
*(.ldata .ldata.* .gnu.linkonce.l.*)
. = ALIGN(. != 0 ? 64 / 8 : 1);
}
. = ALIGN(64 / 8);
_end = .; PROVIDE (end = .);
. = DATA_SEGMENT_END (.);
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
.gnu.build.attributes : { *(.gnu.build.attributes .gnu.build.attributes.*) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
/* DWARF 3 */
.debug_pubtypes 0 : { *(.debug_pubtypes) }
.debug_ranges 0 : { *(.debug_ranges) }
/* DWARF Extension. */
.debug_macro 0 : { *(.debug_macro) }
.debug_addr 0 : { *(.debug_addr) }
.gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }
/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }
}
==================================================
/usr/bin/ld: mode elf_x86_64
attempt to open /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/Scrt1.o succeeded
/usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/Scrt1.o
attempt to open /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/crti.o succeeded
/usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/crti.o
attempt to open /usr/lib/gcc/x86_64-linux-gnu/9/crtbeginS.o succeeded
/usr/lib/gcc/x86_64-linux-gnu/9/crtbeginS.o
attempt to open /tmp/ccJNio1k.o succeeded
/tmp/ccJNio1k.o
attempt to open build.gnu.debug/Animals.o succeeded
build.gnu.debug/Animals.o
attempt to open build.gnu.debug/ftlAlgorithmsTests.o succeeded
build.gnu.debug/ftlAlgorithmsTests.o
attempt to open build.gnu.debug/ftlArrayIntAlgorithms.o succeeded
build.gnu.debug/ftlArrayIntAlgorithms.o
attempt to open build.gnu.debug/ftlArrayTests.o succeeded
build.gnu.debug/ftlArrayTests.o
attempt to open build.gnu.debug/ftlDynArrayIntAlgorithms.o succeeded
build.gnu.debug/ftlDynArrayIntAlgorithms.o
attempt to open build.gnu.debug/ftlDynArrayInt.o succeeded
build.gnu.debug/ftlDynArrayInt.o
attempt to open build.gnu.debug/ftlDynArrayLeaky.o succeeded
build.gnu.debug/ftlDynArrayLeaky.o
attempt to open build.gnu.debug/ftlDynArrayMovableLeaky.o succeeded
build.gnu.debug/ftlDynArrayMovableLeaky.o
attempt to open build.gnu.debug/ftlDynArrayPoint2DAlgorithms.o succeeded
build.gnu.debug/ftlDynArrayPoint2DAlgorithms.o
attempt to open build.gnu.debug/ftlDynArrayPoint2D.o succeeded
build.gnu.debug/ftlDynArrayPoint2D.o
attempt to open build.gnu.debug/ftlDynArrayString.o succeeded
build.gnu.debug/ftlDynArrayString.o
attempt to open build.gnu.debug/ftlDynArrayTests.o succeeded
build.gnu.debug/ftlDynArrayTests.o
attempt to open build.gnu.debug/ftlHashMapStringInt.o succeeded
build.gnu.debug/ftlHashMapStringInt.o
attempt to open build.gnu.debug/ftlHashMapStrInt.o succeeded
build.gnu.debug/ftlHashMapStrInt.o
attempt to open build.gnu.debug/ftlHashMapTests.o succeeded
build.gnu.debug/ftlHashMapTests.o
attempt to open build.gnu.debug/ftlHash.o succeeded
build.gnu.debug/ftlHash.o
attempt to open build.gnu.debug/ftlHashSetInt.o succeeded
build.gnu.debug/ftlHashSetInt.o
attempt to open build.gnu.debug/ftlHashSetString.o succeeded
build.gnu.debug/ftlHashSetString.o
attempt to open build.gnu.debug/ftlHashSetTests.o succeeded
build.gnu.debug/ftlHashSetTests.o
attempt to open build.gnu.debug/ftlKinds.o succeeded
build.gnu.debug/ftlKinds.o
attempt to open build.gnu.debug/ftlListIntAlgorithms.o succeeded
build.gnu.debug/ftlListIntAlgorithms.o
attempt to open build.gnu.debug/ftlListInt.o succeeded
build.gnu.debug/ftlListInt.o
attempt to open build.gnu.debug/ftlListLeaky.o succeeded
build.gnu.debug/ftlListLeaky.o
attempt to open build.gnu.debug/ftlListMovableLeaky.o succeeded
build.gnu.debug/ftlListMovableLeaky.o
attempt to open build.gnu.debug/ftlListTests.o succeeded
build.gnu.debug/ftlListTests.o
attempt to open build.gnu.debug/ftlRegex.o succeeded
build.gnu.debug/ftlRegex.o
attempt to open build.gnu.debug/ftlRegexTests.o succeeded
build.gnu.debug/ftlRegexTests.o
attempt to open build.gnu.debug/ftlSharedPtrInt.o succeeded
build.gnu.debug/ftlSharedPtrInt.o
attempt to open build.gnu.debug/ftlSharedPtrTests.o succeeded
build.gnu.debug/ftlSharedPtrTests.o
attempt to open build.gnu.debug/ftlStringAlgorithms.o succeeded
build.gnu.debug/ftlStringAlgorithms.o
attempt to open build.gnu.debug/ftlString.o succeeded
build.gnu.debug/ftlString.o
attempt to open build.gnu.debug/ftlStringTests.o succeeded
build.gnu.debug/ftlStringTests.o
attempt to open build.gnu.debug/ftlTestTools.o succeeded
build.gnu.debug/ftlTestTools.o
attempt to open build.gnu.debug/Leaky.o succeeded
build.gnu.debug/Leaky.o
attempt to open build.gnu.debug/Point2D.o succeeded
build.gnu.debug/Point2D.o
attempt to open /usr/lib/gcc/x86_64-linux-gnu/9/libpcreposix.so failed
attempt to open /usr/lib/gcc/x86_64-linux-gnu/9/libpcreposix.a failed
attempt to open /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/libpcreposix.so succeeded
/usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/libpcreposix.so
attempt to open /usr/lib/gcc/x86_64-linux-gnu/9/libpcre.so failed
attempt to open /usr/lib/gcc/x86_64-linux-gnu/9/libpcre.a failed
attempt to open /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/libpcre.so succeeded
/usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/libpcre.so
attempt to open /usr/lib/gcc/x86_64-linux-gnu/9/libgfortran.so succeeded
/usr/lib/gcc/x86_64-linux-gnu/9/libgfortran.so
attempt to open /usr/lib/gcc/x86_64-linux-gnu/9/libm.so failed
attempt to open /usr/lib/gcc/x86_64-linux-gnu/9/libm.a failed
attempt to open /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/libm.so succeeded
opened script file /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/libm.so
/usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/libm.so
opened script file /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/libm.so
attempt to open /lib/x86_64-linux-gnu/libm.so.6 succeeded
/lib/x86_64-linux-gnu/libm.so.6
attempt to open /lib/x86_64-linux-gnu/libmvec.so.1 succeeded
/lib/x86_64-linux-gnu/libmvec.so.1
/lib/x86_64-linux-gnu/libmvec.so.1
attempt to open /usr/lib/gcc/x86_64-linux-gnu/9/libgcc_s.so succeeded
opened script file /usr/lib/gcc/x86_64-linux-gnu/9/libgcc_s.so
/usr/lib/gcc/x86_64-linux-gnu/9/libgcc_s.so
opened script file /usr/lib/gcc/x86_64-linux-gnu/9/libgcc_s.so
attempt to open libgcc_s.so.1 failed
attempt to open /usr/lib/gcc/x86_64-linux-gnu/9/libgcc_s.so.1 failed
attempt to open /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/libgcc_s.so.1 succeeded
/usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/libgcc_s.so.1
attempt to open /usr/lib/gcc/x86_64-linux-gnu/9/libgcc.so failed
attempt to open /usr/lib/gcc/x86_64-linux-gnu/9/libgcc.a succeeded
/usr/lib/gcc/x86_64-linux-gnu/9/libgcc.a
attempt to open /usr/lib/gcc/x86_64-linux-gnu/9/libgcc.so failed
attempt to open /usr/lib/gcc/x86_64-linux-gnu/9/libgcc.a succeeded
/usr/lib/gcc/x86_64-linux-gnu/9/libgcc.a
attempt to open /usr/lib/gcc/x86_64-linux-gnu/9/libquadmath.so succeeded
/usr/lib/gcc/x86_64-linux-gnu/9/libquadmath.so
attempt to open /usr/lib/gcc/x86_64-linux-gnu/9/libm.so failed
attempt to open /usr/lib/gcc/x86_64-linux-gnu/9/libm.a failed
attempt to open /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/libm.so succeeded
opened script file /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/libm.so
/usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/libm.so
opened script file /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/libm.so
attempt to open /lib/x86_64-linux-gnu/libm.so.6 succeeded
/lib/x86_64-linux-gnu/libm.so.6
attempt to open /lib/x86_64-linux-gnu/libmvec.so.1 succeeded
/lib/x86_64-linux-gnu/libmvec.so.1
attempt to open /usr/lib/gcc/x86_64-linux-gnu/9/libgcc_s.so succeeded
opened script file /usr/lib/gcc/x86_64-linux-gnu/9/libgcc_s.so
/usr/lib/gcc/x86_64-linux-gnu/9/libgcc_s.so
opened script file /usr/lib/gcc/x86_64-linux-gnu/9/libgcc_s.so
attempt to open libgcc_s.so.1 failed
attempt to open /usr/lib/gcc/x86_64-linux-gnu/9/libgcc_s.so.1 failed
attempt to open /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/libgcc_s.so.1 succeeded
/usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/libgcc_s.so.1
attempt to open /usr/lib/gcc/x86_64-linux-gnu/9/libgcc.so failed
attempt to open /usr/lib/gcc/x86_64-linux-gnu/9/libgcc.a succeeded
/usr/lib/gcc/x86_64-linux-gnu/9/libgcc.a
attempt to open /usr/lib/gcc/x86_64-linux-gnu/9/libgcc.so failed
attempt to open /usr/lib/gcc/x86_64-linux-gnu/9/libgcc.a succeeded
/usr/lib/gcc/x86_64-linux-gnu/9/libgcc.a
attempt to open /usr/lib/gcc/x86_64-linux-gnu/9/libc.so failed
attempt to open /usr/lib/gcc/x86_64-linux-gnu/9/libc.a failed
attempt to open /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/libc.so succeeded
opened script file /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/libc.so
/usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/libc.so
opened script file /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/libc.so
attempt to open /lib/x86_64-linux-gnu/libc.so.6 succeeded
/lib/x86_64-linux-gnu/libc.so.6
attempt to open /usr/lib/x86_64-linux-gnu/libc_nonshared.a succeeded
/usr/lib/x86_64-linux-gnu/libc_nonshared.a
(/usr/lib/x86_64-linux-gnu/libc_nonshared.a)elf-init.oS
attempt to open /lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 succeeded
/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
/usr/lib/x86_64-linux-gnu/libc_nonshared.a
/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
attempt to open /usr/lib/gcc/x86_64-linux-gnu/9/libgcc_s.so succeeded
opened script file /usr/lib/gcc/x86_64-linux-gnu/9/libgcc_s.so
/usr/lib/gcc/x86_64-linux-gnu/9/libgcc_s.so
opened script file /usr/lib/gcc/x86_64-linux-gnu/9/libgcc_s.so
attempt to open libgcc_s.so.1 failed
attempt to open /usr/lib/gcc/x86_64-linux-gnu/9/libgcc_s.so.1 failed
attempt to open /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/libgcc_s.so.1 succeeded
/usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/libgcc_s.so.1
attempt to open /usr/lib/gcc/x86_64-linux-gnu/9/libgcc.so failed
attempt to open /usr/lib/gcc/x86_64-linux-gnu/9/libgcc.a succeeded
/usr/lib/gcc/x86_64-linux-gnu/9/libgcc.a
attempt to open /usr/lib/gcc/x86_64-linux-gnu/9/libgcc.so failed
attempt to open /usr/lib/gcc/x86_64-linux-gnu/9/libgcc.a succeeded
/usr/lib/gcc/x86_64-linux-gnu/9/libgcc.a
attempt to open /usr/lib/gcc/x86_64-linux-gnu/9/crtendS.o succeeded
/usr/lib/gcc/x86_64-linux-gnu/9/crtendS.o
attempt to open /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/crtn.o succeeded
/usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/crtn.o
libquadmath.so.0 needed by /usr/lib/gcc/x86_64-linux-gnu/9/libgfortran.so
found libquadmath.so at /usr/lib/gcc/x86_64-linux-gnu/9/libquadmath.so
libgcc_s.so.1 needed by /usr/lib/gcc/x86_64-linux-gnu/9/libgfortran.so
found libgcc_s.so.1 at /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/libgcc_s.so.1
ld-linux-x86-64.so.2 needed by /usr/lib/gcc/x86_64-linux-gnu/9/libgfortran.so
found ld-linux-x86-64.so.2 at /lib/x86_64-linux-gnu/ld-linux-x86-64.so.2