Unresolved external symbol during dll linking - c++11

ALL,
I have a static link library which exports a class. This class contains a member of std::mutex.
When I link this library to my main project there is no problem, but when I try to link the library to dynamic link library in the same project I'm getting the undefined external symbol.
I double check and all the libraries I link are the same.
Whats weird is that the linker complain about the member and not the class itself.
What could be the issue?
TIA!
P.S. if it matter - I'm working with msvc 2017 on Windows 8.1.
P.P.S.:
Command to build the application:
/GS /analyze- /W4 /Zc:wchar_t /I"C:\Program Files (x86)\Visual Leak Detector\include" /I"..\dbinterface" /I"..\libdbwindow\res\gui" /I"c:\wxWidgets\lib\vc_dll\mswud" /I"c:\wxWidgets\include" /I"." /I"C:\Program Files (x86)\Visual Leak Detector\include" /Zi /Gm- /Od /Fd"vc_mswuddll\docview.pdb" /Zc:inline /fp:precise /D "WIN32" /D "_DEBUG" /D "_CRT_SECURE_NO_DEPRECATE=1" /D "_CRT_NON_CONFORMING_SWPRINTFS=1" /D "_SCL_SECURE_NO_WARNINGS=1" /D "WXMSW" /D "_UNICODE" /D "WXUSINGDLL" /D "_WINDOWS" /D "NOPCH" /D "UNICODE" /errorReport:prompt /WX- /Zc:forScope /RTC1 /Gd /Oy- /MDd /FC /Fa"vc_mswuddll" /EHsc /nologo /Fo"vc_mswuddll\docview" /Fp"vc_mswuddll\docview.pch" /diagnostics:classic
Command to build the library:
/GS /analyze- /W4 /Zc:wchar_t /I"C:\Program Files (x86)\Visual Leak Detector\include" /I"..\dbinterface" /I"..\libfieldswindow" /I"..\libshapeframework" /I"..\libpropertypages" /I"..\libpropertieshandlers" /I"c:\wxWidgets\lib\vc_dll\mswud" /I"c:\wxWidgets\include" /I"." /Zi /Gm- /Od /Fd"vc_mswuddll\tabledataedit.pdb" /Zc:inline /fp:precise /D "MEMORYLEAKS" /D "WIN32" /D "_USRDLL" /D "DLL_EXPORTS" /D "_DEBUG" /D "_CRT_SECURE_NO_DEPRECATE=1" /D "_CRT_NON_CONFORMING_SWPRINTFS=1" /D "_SCL_SECURE_NO_WARNINGS=1" /D "WXMSW" /D "_UNICODE" /D "WXUSINGDLL" /D "MY_DLL_BUILDING" /D "_WINDLL" /D "UNICODE" /errorReport:prompt /WX- /Zc:forScope /RTC1 /GR /Gd /Oy- /MDd /FC /Fa"vc_mswuddll" /EHsc /nologo /Fo"vc_mswuddll" /Fp"vc_mswuddll\tabledataedit.pch" /diagnostics:classic
The symbol is declared as
class __declspec(dllexport) Database
{
protected:
struct Impl;
Impl *pimpl;
// more members here
};
struct Database::Impl
{
static std::mutex my_mutex;
// more members here
};
EDIT:
c:\Users\Igor\OneDrive\Documents\dbhandler_app\dbhandler\Debug>dumpbin /symbols
dbinterface.lib
Microsoft (R) COFF/PE Dumper Version 14.16.27045.0
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file dbinterface.lib
File Type: LIBRARY
COFF SYMBOL TABLE
000 010569A5 ABS notype Static | #comp.id
001 80000191 ABS notype Static | #feat.00
002 00000000 SECT1 notype Static | .drectve
Section length 41, #relocs 0, #linenums 0, checksum 0
Relocation CRC 00000000
005 00000000 SECT2 notype Static | .debug$S
Section length 23FC, #relocs 2, #linenums 0, checksum 0
Relocation CRC 3EE39AC2
008 00000000 SECT3 notype Static | .debug$T
Section length 70, #relocs 0, #linenums 0, checksum 0
Relocation CRC 00000000
00B 00000000 SECT4 notype Static | .bss
Section length 4, #relocs 0, #linenums 0, checksum 0, select
ion 2 (pick any)
Relocation CRC 00000000
00E 00000000 SECT4 notype External | ___##_PchSym_#00#UfhvihUrtliUlmv
wirevUwlxfnvmghUwyszmwoviPzkkUwyrmgviuzxvUwvyftUhgwzucOlyq#4B2008FD98C1DD4
00F 00000000 SECT5 notype Static | .msvcjmc
Section length 1, #relocs 0, #linenums 0, checksum 77073096
Relocation CRC 00000000
012 00000000 SECT5 notype Static | __BDBDE527_dbinterface#pch
013 00000000 SECT6 notype Static | .debug$S
Section length 84, #relocs 2, #linenums 0, checksum 0, select
ion 5 (pick associative Section 0x4)
Relocation CRC 4D9779EE
016 00000000 SECT7 notype Static | .chks64
Section length 38, #relocs 0, #linenums 0, checksum 0
Relocation CRC 00000000
String Table Size = 0x8A bytes
Summary
4 .bss
38 .chks64
2480 .debug$S
70 .debug$T
41 .drectve
1 .msvcjmc
EDIT 1:
Link command for application:
/OUT:"vc_mswuddll\docview.exe" /MANIFEST /NXCOMPAT /PDB:"vc_mswuddll\docview.pdb" /DYNAMICBASE "vld.lib" "dbinterface.lib" "wxmsw31ud_core.lib" "wxbase31ud.lib" "wxtiffd.lib" "wxjpegd.lib" "wxpngd.lib" "wxzlibd.lib" "wxregexud.lib" "wxexpatd.lib" "kernel32.lib" "user32.lib" "gdi32.lib" "comdlg32.lib" "winspool.lib" "winmm.lib" "shell32.lib" "shlwapi.lib" "comctl32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "rpcrt4.lib" "advapi32.lib" "version.lib" "wsock32.lib" "wininet.lib" "odbc32.lib" "odbccp32.lib" /DEBUG /MACHINE:X86 /SAFESEH /INCREMENTAL /PGD:"vc_mswuddll\docview.pgd" /SUBSYSTEM:WINDOWS /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /ManifestFile:"vc_mswuddll\docview.exe.intermediate.manifest" /ERRORREPORT:PROMPT /NOLOGO /LIBPATH:"C:\Program Files (x86)\Visual Leak Detector\lib\Win32" /LIBPATH:".\Debug" /LIBPATH:"c:\wxWidgets\lib\vc_dll" /TLBID:1
Link command for the dynamic library:
/OUT:"..\dbhandler\vc_mswuddll\tabledataedit.dll" /MANIFEST /NXCOMPAT /PDB:"vc_mswuddll\tabledataedit.pdb" /DYNAMICBASE "vld.lib" "dbinterface.lib" "fieldswindow.lib" "shapeframework.lib" "propertieshandlers.lib" "propertypages.lib" "wxmsw31ud_adv.lib" "wxmsw31ud_core.lib" "wxbase31ud.lib" "wxtiffd.lib" "wxjpegd.lib" "wxpngd.lib" "wxzlibd.lib" "wxregexud.lib" "wxexpatd.lib" "kernel32.lib" "user32.lib" "gdi32.lib" "comdlg32.lib" "winspool.lib" "winmm.lib" "shell32.lib" "shlwapi.lib" "comctl32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "rpcrt4.lib" "advapi32.lib" "version.lib" "wsock32.lib" "wininet.lib" "odbc32.lib" "odbccp32.lib" /IMPLIB:"vc_mswuddll\tabledataedit.lib" /DEBUG /DLL /MACHINE:X86 /SAFESEH /INCREMENTAL /PGD:"vc_mswuddll\tabledataedit.pgd" /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /ManifestFile:"vc_mswuddll\tabledataedit.dll.intermediate.manifest" /ERRORREPORT:PROMPT /NOLOGO /LIBPATH:"C:\Program Files (x86)\Visual Leak Detector\lib\Win32" /LIBPATH:"..\dbhandler\Debug" /LIBPATH:"..\libfieldswindow\vc_mswuddll" /LIBPATH:"..\libshapeframework\vc_mswuddll" /LIBPATH:"..\libpropertieshandlers\vc_mswuddll" /LIBPATH:"..\libpropertypages\vc_mswuddll" /LIBPATH:"c:\wxWidgets\lib\vc_dll" /TLBID:1
EDIT:
And here is the result of dumpbin with the change:
c:\Users\Igor\OneDrive\Documents\dbhandler_app\dbhandler\Debug>dumpbin /symbols
dbinterface.lib
Microsoft (R) COFF/PE Dumper Version 14.16.27045.0
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file dbinterface.lib
File Type: LIBRARY
COFF SYMBOL TABLE
000 010569A5 ABS notype Static | #comp.id
001 80000191 ABS notype Static | #feat.00
002 00000000 SECT1 notype Static | .drectve
Section length 41, #relocs 0, #linenums 0, checksum 0
Relocation CRC 00000000
005 00000000 SECT2 notype Static | .debug$S
Section length 23FC, #relocs 2, #linenums 0, checksum 0
Relocation CRC 3EE39AC2
008 00000000 SECT3 notype Static | .debug$T
Section length 70, #relocs 0, #linenums 0, checksum 0
Relocation CRC 00000000
00B 00000000 SECT4 notype Static | .bss
Section length 4, #relocs 0, #linenums 0, checksum 0, select
ion 2 (pick any)
Relocation CRC 00000000
00E 00000000 SECT4 notype External | ___##_PchSym_#00#UfhvihUrtliUlmv
wirevUwlxfnvmghUwyszmwoviPzkkUwyrmgviuzxvUwvyftUhgwzucOlyq#4B2008FD98C1DD4
00F 00000000 SECT5 notype Static | .msvcjmc
Section length 1, #relocs 0, #linenums 0, checksum 77073096
Relocation CRC 00000000
012 00000000 SECT5 notype Static | __BDBDE527_dbinterface#pch
013 00000000 SECT6 notype Static | .debug$S
Section length 84, #relocs 2, #linenums 0, checksum 0, select
ion 5 (pick associative Section 0x4)
Relocation CRC 4D9779EE
016 00000000 SECT7 notype Static | .chks64
Section length 38, #relocs 0, #linenums 0, checksum 0
Relocation CRC 00000000
String Table Size = 0x8A bytes
Summary
4 .bss
38 .chks64
2480 .debug$S
70 .debug$T
41 .drectve
1 .msvcjmc

__declspec(dllexport) means the question is about an import library of a DLL (not a "static link library"), and in that case the error is due to my_mutex not being exported. This could be resolved by exporting:
either the entire nested class;
struct __declspec(dllexport) Database::Impl
{
static std::mutex my_mutex;
// more members here
};
or just the static variable in question.
struct Database::Impl
{
static __declspec(dllexport) std::mutex my_mutex;
// more members here
};
This should work for the std::mutex used in the example here, but will run into C4251 with other STL templatized classes. That, in turn, can be worked around (see One way of eliminating C4251 warning when using stl-classes in the dll-interface for example), but a better solution might be to rearrange the APIs so that my_mutex does not need to be exported to begin with.

Related

NASM and clang/LLVM generating different object files

I'm trying to make a simple kernel with multiboot. I got the multiboot header working in NASM, but now I'm trying to rewrite it in GNU AS syntax. I think problem is that clang (as on MacOS) is placing the multiboot header at a different address (beyond 8K), but I can't figure out how to get it to work the same as NASM. I'm using the same linker script.
Below is my NASM code, GAS code, linker script, and the output of nm kernel-nasm.bin kernel-gas.bin (sorry for the verbosity).
Here's the working NASM code:
MBALIGN equ 1 << 0
MEMINFO equ 1 << 1
FLAGS equ MBALIGN | MEMINFO
MAGIC equ 0x1BADB002
CHECKSUM equ -(MAGIC + FLAGS)
section .multiboot_header
header_start:
align 4
dd MAGIC
dd FLAGS
dd CHECKSUM
header_end:
section .text
global start
start:
mov dword [0xb8000], 0x2f4b2f4f
hlt
And here's the not working GNU AS code:
.set MBALIGN, 1 << 0
.set MEMINFO, 1 << 1
.set FLAGS, MBALIGN | MEMINFO
.set MAGIC, 0x1BADB002
.set CHECKSUM, -(MAGIC + FLAGS)
.section .multiboot_header
header_start:
.align 4
.long MAGIC
.long FLAGS
.long CHECKSUM
header_end:
.section .text
.global start
start:
movl $0x2f4b2f4f, (0xb8000)
hlt
Linker Script:
ENTRY(start)
SECTIONS {
. = 1M;
.boot : ALIGN(4K)
{
/* ensure that the multiboot header is at the beginning */
*(.multiboot_header)
}
.text : ALIGN (4K)
{
*(.text)
}
}
Output of nm kernel-nasm.bin kernel-gas.bin:
kernel-nasm.bin:
e4524ffb a CHECKSUM
00000003 a FLAGS
1badb002 a MAGIC
00000001 a MBALIGN
00000002 a MEMINFO
0010000c r header_end
00100000 r header_start
00101000 T start
kernel-gas.bin:
e4524ffb a CHECKSUM
00000003 a FLAGS
1badb002 a MAGIC
00000001 a MBALIGN
00000002 a MEMINFO
0000000c n header_end
00000000 n header_start
00100000 T start
Here's the commands I'm using to assemble the code. I'm using Homebrew's LLVM 14.0.6 on macOS:
# For kernel-nasm.bin
nasm -felf32 kernel-nasm.asm -o kernel-nasm.o
ld.lld -n -o kernel-nasm.bin -T linker.ld kernel-nasm.o
# For kernel-gas.bin
as --target=i386-pc-none-elf kernel-gas.S -o kernel-gas.o
ld.lld -n -o kernel-gas.bin -T linker.ld kernel-gas.o
As you can see from the --target= option, as on this machine is clang, not from GNU Binutils. Same for the ld.lld linker being LLVM, not Binutils.
The output of objdump -x kernel-nasm.bin is:
kernel-nasm.bin: file format elf32-i386
kernel-nasm.bin
architecture: i386, flags 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
start address 0x00101000
Program Header:
LOAD off 0x00001000 vaddr 0x00100000 paddr 0x00100000 align 2**12
filesz 0x0000000c memsz 0x0000000c flags r--
LOAD off 0x00002000 vaddr 0x00101000 paddr 0x00101000 align 2**12
filesz 0x0000000b memsz 0x0000000b flags r-x
STACK off 0x00000000 vaddr 0x00000000 paddr 0x00000000 align 2**0
filesz 0x00000000 memsz 0x00000000 flags rw-
Sections:
Idx Name Size VMA LMA File off Algn
0 .boot 0000000c 00100000 00100000 00001000 2**12
CONTENTS, ALLOC, LOAD, READONLY, DATA
1 .text 0000000b 00101000 00101000 00002000 2**12
CONTENTS, ALLOC, LOAD, READONLY, CODE
2 .comment 0000001c 00000000 00000000 0000200b 2**0
CONTENTS, READONLY
SYMBOL TABLE:
00000000 l df *ABS* 00000000 hdr.asm
00000001 l *ABS* 00000000 MBALIGN
00000002 l *ABS* 00000000 MEMINFO
00000003 l *ABS* 00000000 FLAGS
1badb002 l *ABS* 00000000 MAGIC
e4524ffb l *ABS* 00000000 CHECKSUM
00100000 l .boot 00000000 header_start
0010000c l .boot 00000000 header_end
00101000 g .text 00000000 start
The output of objdump -x kernel-gas.bin is:
kernel-gas.bin: file format elf32-i386
kernel-gas.bin
architecture: i386, flags 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
start address 0x00100000
Program Header:
LOAD off 0x00001000 vaddr 0x00100000 paddr 0x00100000 align 2**12
filesz 0x0000000b memsz 0x0000000b flags r-x
STACK off 0x00000000 vaddr 0x00000000 paddr 0x00000000 align 2**0
filesz 0x00000000 memsz 0x00000000 flags rw-
Sections:
Idx Name Size VMA LMA File off Algn
0 .boot 0000000c 00000000 00000000 00002000 2**12
CONTENTS, READONLY
1 .comment 0000001c 00000000 00000000 0000200c 2**0
CONTENTS, READONLY
2 .text 0000000b 00100000 00100000 00001000 2**12
CONTENTS, ALLOC, LOAD, READONLY, CODE
SYMBOL TABLE:
e4524ffb l *ABS* 00000000 CHECKSUM
00000003 l *ABS* 00000000 FLAGS
1badb002 l *ABS* 00000000 MAGIC
00000001 l *ABS* 00000000 MBALIGN
00000002 l *ABS* 00000000 MEMINFO
0000000c l .boot 00000000 header_end
00000000 l .boot 00000000 header_start
00100000 g .text 00000000 start
According to the GNU AS documentation, "If the section name is not recognized, the default will be for the section to have none of the above flags: it will not be allocated in memory, nor writable, nor executable. The section will contain data."
To make sure the .boot section is loaded into memory and can be read by the bootloader, the section must have the "a" flag added to it (more info in the documentation above). Like this:
// ... code ...
.section .multiboot_header, "a"
header_start:
.align 4
.long MAGIC
.long FLAGS
.long CHECKSUM
header_end:
// ... code ...

Is there a gfortran equivalent to gcc's __attribute__((section("name")))?

I am using the nestedvm package, which includes a patched Gnu gcc compiler. For this package, callable user methods/functions have to annotated with __attribute__((section(".text"))), as shown in the C example below.
void echo(const char *string, int count) __attribute__((section(".text")));
void echo(const char *string, int count) {
int i;
for(i=0;i<count;i++)
printf("%d: %s\n",i,string);
}
I don't know about the inner workings of the patched compiler, but without this annotation, the user function is not visible to outside callers.
If using gfortran, how can I accomplish this annotation for Fortran subroutines and functions? Could this be done with a linker script file? I could write a C wrapper to the Fortran functions, but would like to avoid this if possible.
** UPDATE 1 **
Using nm to investigate the .o file sheds some light on the issue...a C method without the attribute looks like the suckram function (which is not callable in nestedvm), while the echo function has the attribute and is callable in nestedvm:
Name Value Class Type Size Line Section
suckram |00000000| T | FUNC|00000078| |.text.suckram
echo |00000200| T | FUNC|00000074| |.text
The test1 subroutine in my Fortran object looks like the suckram method without the attribute:
test1_ |00000000| T | FUNC|00000080| |.text.test1_
According to some nestedvm documentation I found, in order for a user function to be callable in nestedvm, it has to end up in the .text section.
** UPDATE 2 **
A link command line is below. It is too long to put in a comment. I removed some of the many .o files (…)
mips-unknown-elf-gfortran -O3 -mmemcpy -ffunction-sections -fdata-sections -falign-functions=512 -fno-rename-registers -fno-schedule-insns -fno-delayed-branch -march=mips1 -specs=/home/jhuber/Documents/source/nestedvm/upstream/install/mips-unknown-elf/lib/crt0-override.spec -I. -Wall -Wno-unused -o build/refprop/Refprop.mips build/refprop/NVM.o (...) build/refprop/TRNS_VIS.o build/refprop/MAIN.o -march=mips1 -specs=/home/jhuber/Documents/source/nestedvm/upstream/install/mips-unknown-elf/lib/crt0-override.spec --static -Wl,--gc-sections -Wl,-Map=output1.map -Wl,--cref -lc -Wl,-Map=output.map -Wl,--cref
Also, even though I am calling the code as a library, nestedvm requires the library to have a MAIN routine for initialization. If I make some dummy calls to the library functions in the MAIN routine, those functions that are called in MAIN are moved the .text section, and become callable.
** UPDATE 3 **
Verbose output from make. I removed some of the many .o files (…)
mips-unknown-elf-gfortran -O3 -mmemcpy -ffunction-sections -fdata-sections -falign-functions=512 -fno-rename-registers -fno-schedule-insns -fno-delayed-branch -march=mips1 -specs=/home/jhuber/Documents/source/nestedvm/upstream/install/mips-unknown-elf/lib/crt0-override.spec -I. -Wall -Wno-unused -o build/refprop/Refprop.mips build/refprop/NVM.o (…) build/refprop/TRNS_VIS.o build/refprop/MAIN.o -march=mips1 -specs=/home/jhuber/Documents/source/nestedvm/upstream/install/mips-unknown-elf/lib/crt0-override.spec --static -Wl,--gc-sections -Wl,-Map=output1.map -Wl,--cref -lc -Wl,-Map=output.map -Wl,--cref -v
Driving: mips-unknown-elf-gfortran -O3 -mmemcpy -ffunction-sections -fdata-sections -falign-functions=512 -fno-rename-registers -fno-schedule-insns -fno-delayed-branch -march=mips1 -specs=/home/jhuber/Documents/source/nestedvm/upstream/install/mips-unknown-elf/lib/crt0-override.spec -I. -Wall -Wno-unused -o build/refprop/Refprop.mips build/refprop/NVM.o (…) build/refprop/TRNS_VIS.o build/refprop/MAIN.o -march=mips1 -specs=/home/jhuber/Documents/source/nestedvm/upstream/install/mips-unknown-elf/lib/crt0-override.spec --static -Wl,--gc-sections -Wl,-Map=output1.map -Wl,--cref -lc -Wl,-Map=output.map -Wl,--cref -v -l gfortran -l m
Using built-in specs.
Reading specs from /home/jhuber/Documents/source/nestedvm/upstream/install/mips-unknown-elf/lib/crt0-override.spec
Reading specs from /home/jhuber/Documents/source/nestedvm/upstream/install/mips-unknown-elf/lib/crt0-override.spec
COLLECT_GCC=mips-unknown-elf-gfortran
COLLECT_LTO_WRAPPER=/home/jhuber/Documents/source/nestedvm/upstream/install/libexec/gcc/mips-unknown-elf/4.8.5/lto-wrapper
Target: mips-unknown-elf
Configured with: ../gcc-4.8.5/configure --prefix=/home/jhuber/Documents/source/nestedvm/upstream/install --target=mips-unknown-elf --disable-threads --disable-libssp --with-gnu-ld --with-gnu-as --with-newlib=yes --enable-sjlj-exceptions --enable-languages=c : (reconfigured) ../gcc-4.8.5/configure --prefix=/home/jhuber/Documents/source/nestedvm/upstream/install --target=mips-unknown-elf --disable-threads --disable-libssp --with-gnu-ld --with-gnu-as --with-newlib=yes --enable-sjlj-exceptions --enable-languages=c --enable-languages=c,c++,fortran
Thread model: single
gcc version 4.8.5 (GCC)
Reading specs from /home/jhuber/Documents/source/nestedvm/upstream/install/lib/gcc/mips-unknown-elf/4.8.5/../../../../mips-unknown-elf/lib/libgfortran.spec
rename spec lib to liborig
COLLECT_GCC_OPTIONS='-O3' '-mmemcpy' '-ffunction-sections' '-fdata-sections' '-falign-functions=512' '-fno-rename-registers' '-fno-schedule-insns' '-fno-delayed-branch' '-march=mips1' '-specs=/home/jhuber/Documents/source/nestedvm/upstream/install/mips-unknown-elf/lib/crt0-override.spec' '-I' '.' '-Wall' '-Wno-unused' '-o' 'build/refprop/Refprop.mips' '-march=mips1' '-specs=/home/jhuber/Documents/source/nestedvm/upstream/install/mips-unknown-elf/lib/crt0-override.spec' '-static' '-v'
COMPILER_PATH=/home/jhuber/Documents/source/nestedvm/upstream/install/libexec/gcc/mips-unknown-elf/4.8.5/:/home/jhuber/Documents/source/nestedvm/upstream/install/libexec/gcc/mips-unknown-elf/4.8.5/:/home/jhuber/Documents/source/nestedvm/upstream/install/libexec/gcc/mips-unknown-elf/:/home/jhuber/Documents/source/nestedvm/upstream/install/lib/gcc/mips-unknown-elf/4.8.5/:/home/jhuber/Documents/source/nestedvm/upstream/install/lib/gcc/mips-unknown-elf/:/home/jhuber/Documents/source/nestedvm/upstream/install/lib/gcc/mips-unknown-elf/4.8.5/../../../../mips-unknown-elf/bin/
LIBRARY_PATH=/home/jhuber/Documents/source/nestedvm/upstream/install/lib/gcc/mips-unknown-elf/4.8.5/:/home/jhuber/Documents/source/nestedvm/upstream/install/lib/gcc/mips-unknown-elf/4.8.5/../../../../mips-unknown-elf/lib/
COLLECT_GCC_OPTIONS='-O3' '-mmemcpy' '-ffunction-sections' '-fdata-sections' '-falign-functions=512' '-fno-rename-registers' '-fno-schedule-insns' '-fno-delayed-branch' '-march=mips1' '-specs=/home/jhuber/Documents/source/nestedvm/upstream/install/mips-unknown-elf/lib/crt0-override.spec' '-I' '.' '-Wall' '-Wno-unused' '-o' 'build/refprop/Refprop.mips' '-march=mips1' '-specs=/home/jhuber/Documents/source/nestedvm/upstream/install/mips-unknown-elf/lib/crt0-override.spec' '-static' '-v'
/home/jhuber/Documents/source/nestedvm/upstream/install/libexec/gcc/mips-unknown-elf/4.8.5/collect2 -EB -o build/refprop/Refprop.mips /home/jhuber/Documents/source/nestedvm/upstream/install/lib/gcc/mips-unknown-elf/4.8.5/crti.o /home/jhuber/Documents/source/nestedvm/upstream/install/lib/gcc/mips-unknown-elf/4.8.5/crtbegin.o /home/jhuber/Documents/source/nestedvm/upstream/install/lib/gcc/mips-unknown-elf/4.8.5/../../../../mips-unknown-elf/lib/crt0.o -L/home/jhuber/Documents/source/nestedvm/upstream/install/lib/gcc/mips-unknown-elf/4.8.5 -L/home/jhuber/Documents/source/nestedvm/upstream/install/lib/gcc/mips-unknown-elf/4.8.5/../../../../mips-unknown-elf/lib build/refprop/NVM.o (…) build/refprop/TRNS_VIS.o build/refprop/MAIN.o --gc-sections -Map=output1.map --cref -lc -Map=output.map --cref -lgfortran -lm -lgcc -lm -lgcc -lgcc /home/jhuber/Documents/source/nestedvm/upstream/install/lib/gcc/mips-unknown-elf/4.8.5/crtend.o /home/jhuber/Documents/source/nestedvm/upstream/install/lib/gcc/mips-unknown-elf/4.8.5/crtn.o
I did some local tests, and -ffunction-sections puts each fortran function its own section, as expected. Compare:
$ gfortran -c -O3 -o hello.o hello.f90
$ objdump -h hello.o
hello.o: file format elf64-x86-64
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 000000aa 0000000000000000 0000000000000000 00000040 2**4
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
1 .data 00000000 0000000000000000 0000000000000000 000000ea 2**0
CONTENTS, ALLOC, LOAD, DATA
2 .bss 00000000 0000000000000000 0000000000000000 000000ea 2**0
ALLOC
3 .rodata.str1.1 0000000a 0000000000000000 0000000000000000 000000ea 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
4 .text.startup 00000026 0000000000000000 0000000000000000 00000100 2**4
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
5 .rodata 0000001c 0000000000000000 0000000000000000 00000130 2**4
CONTENTS, ALLOC, LOAD, READONLY, DATA
6 .comment 00000026 0000000000000000 0000000000000000 0000014c 2**0
CONTENTS, READONLY
7 .note.GNU-stack 00000000 0000000000000000 0000000000000000 00000172 2**0
CONTENTS, READONLY
8 .eh_frame 00000068 0000000000000000 0000000000000000 00000178 2**3
CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA
to:
$ gfortran -ffunction-sections -c -O3 -o hello.o hello.f90
$ objdump -h hello.o
hello.o: file format elf64-x86-64
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 00000000 0000000000000000 0000000000000000 00000040 2**0
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .data 00000000 0000000000000000 0000000000000000 00000040 2**0
CONTENTS, ALLOC, LOAD, DATA
2 .bss 00000000 0000000000000000 0000000000000000 00000040 2**0
ALLOC
3 .rodata.str1.1 0000000a 0000000000000000 0000000000000000 00000040 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
4 .text.MAIN__ 00000097 0000000000000000 0000000000000000 00000050 2**4
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
5 .text.foo_ 0000000a 0000000000000000 0000000000000000 000000f0 2**4
CONTENTS, ALLOC, LOAD, READONLY, CODE
6 .text.startup.main 00000026 0000000000000000 0000000000000000 00000100 2**4
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
7 .rodata 0000001c 0000000000000000 0000000000000000 00000130 2**4
CONTENTS, ALLOC, LOAD, READONLY, DATA
8 .comment 00000026 0000000000000000 0000000000000000 0000014c 2**0
CONTENTS, READONLY
9 .note.GNU-stack 00000000 0000000000000000 0000000000000000 00000172 2**0
CONTENTS, READONLY
10 .eh_frame 00000068 0000000000000000 0000000000000000 00000178 2**3
CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA
The builtin linker script on my local machine rolls all of these into .text by default. It appears whatever you're linking with doesn't. You should be able to modify that script to do what you're trying. It's a bit more difficult than the attribute extensions, since you'll have to maintain the list in a separate file, but you should be able to locate things however you like. I can work up an example here if you give some more context about that in your question.

.dbug_loc is missing from binary

I was inspecting ELF binary for the code mentioned below.
I compiled it on gcc 7.4.0 on Ubuntu x86_64 system in Virtual Box as :
gcc -g scratch1.c -o scratch1.out
#include <stdio.h>
void do_stuff(int my_arg){
int my_local = my_arg + 2;
int i;
for (i = 0; i < my_local; ++i) printf("i = %d\n", i);
}
int main(){
do_stuff(2);
return 0;
}
However when I tried to refer to .debug_loc section, it was empty.
objdump --dwarf=loc scratch1.out
scratch1.out: file format elf64-x86-64
Although, I do see some other debug_ sections
[26] .debug_aranges PROGBITS 0000000000000000 0000103b
0000000000000030 0000000000000000 0 0 1
[27] .debug_info PROGBITS 0000000000000000 0000106b
000000000000035f 0000000000000000 0 0 1
[28] .debug_abbrev PROGBITS 0000000000000000 000013ca
0000000000000125 0000000000000000 0 0 1
[29] .debug_line PROGBITS 0000000000000000 000014ef
00000000000000e6 0000000000000000 0 0 1
[30] .debug_str PROGBITS 0000000000000000 000015d5
00000000000002b5 0000000000000001 MS 0 0 1
Need your help why this section is missing.
Need your help why this section is missing.
The .debug_loc section contains DW_AT_location lists, usually emitted only for optimized code.
Since you compiled without optimization, the compiler didn't emit this section. Try building with:
gcc -g -O3 scratch1.c -o scratch1.out
Here is what I see with gcc 8.3.0:
$ gcc -g scratch.c && readelf -WS a.out | grep debug_loc
# no output
$ gcc -g scratch.c -O3 && readelf -WS a.out | grep debug_loc
[32] .debug_loc PROGBITS 0000000000000000 0039db 000230 00 0 0 1

qemu: fatal: Trying to execute code outside RAM or ROM at 0xd08ec08e

I have a function written in C that reads a character from the keyboard, and returns the pressed character.
kmain.c
#include <stdint.h>
char getch()
{
uint16_t inchar;
__asm__ __volatile__ ("int $0x16\n\t"
: "=a"(inchar)
: "0"(0x0));
return ((char)inchar);
}
void println(char *str)
{
while (*str)
{
// AH=0x0e, AL=char to print, BH=page, BL=fg color
__asm__ __volatile__ ("int $0x10"
:
: "a" ((0x0e<<8) | *str++),
"b" (0x0000));
}
}
void kernelmain()
{
println("Println called from C code");
char c;
c = getch();
println(c);
}
boot.asm
extern println
extern kernelmain
global start
bits 16
section .text
start:
xor ax, ax
mov ds, ax
mov es, ax
mov ss, ax
mov esp, 0x7C00
jmp 0x0000:setcs
setcs:
cld
push dword msg1
call dword println
; If you use call instead of jmp, it gonna throw a nice error :)
jmp kernelmain
cli
hlt ; halt the processor
section .data
msg1 db 'Println called from NASM code', 0x0A, 0x0D, 0
But when I want to print that obtained key, it throw this useless error:
qemu: fatal: Trying to execute code outside RAM or ROM at 0xd08ec08e
EAX=00002d78 EBX=00000000 ECX=00000000 EDX=00000000
ESI=00000000 EDI=00000000 EBP=d88ec031 ESP=00007c08
EIP=d08ec08e EFL=00000206 [-----P-] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0000 00000000 0000ffff 00009300
CS =0000 00000000 0000ffff 00009b00
SS =0000 00000000 0000ffff 00009300
DS =0000 00000000 0000ffff 00009300
FS =0000 00000000 0000ffff 00009300
GS =0000 00000000 0000ffff 00009300
LDT=0000 00000000 0000ffff 00008200
TR =0000 00000000 0000ffff 00008b00
GDT= 000f6c00 00000037
IDT= 00000000 000003ff
CR0=00000010 CR2=00000000 CR3=00000000 CR4=00000000
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000
DR6=ffff0ff0 DR7=00000400
CCS=00000004 CCD=0000fe9c CCO=EFLAGS
EFER=0000000000000000
FCW=037f FSW=0000 [ST=0] FTW=00 MXCSR=00001f80
FPR0=0000000000000000 0000 FPR1=0000000000000000 0000
FPR2=0000000000000000 0000 FPR3=0000000000000000 0000
FPR4=0000000000000000 0000 FPR5=0000000000000000 0000
FPR6=0000000000000000 0000 FPR7=0000000000000000 0000
XMM00=00000000000000000000000000000000 XMM01=00000000000000000000000000000000
XMM02=00000000000000000000000000000000 XMM03=00000000000000000000000000000000
XMM04=00000000000000000000000000000000 XMM05=00000000000000000000000000000000
XMM06=00000000000000000000000000000000 XMM07=00000000000000000000000000000000
Aborted (core dumped)
to compile kernel.bin:
gcc -fno-PIC -ffreestanding -m16 -c kmain.c -o kmain.o
nasm -f elf32 boot.asm -o boot.o
ld -melf_i386 -T link.ld kmain.o boot.o -o kernel.elf
objcopy -O binary kernel.elf kernel.bin
qemu-system-i386 -fda kernel.bin
I found questions with this same error, but they didn't help me. Also, I know it would be better to compile this with OpenWatcom, but it's too complicated.

Zlibstat.lib link error, VS 2010, zlib 1.2.8

I am trying to use zlibstat.lib generated by building solution in
zlib-1.2.8\contrib\vstudio\vc10\zlibvc.sln
It generated a zlibstat.lib but when I link it with another project I get the following errors:
error LNK2001: unresolved external symbol _compress2
error LNK2001: unresolved external symbol _uncompress
error LNK2019: unresolved external symbol _compress2 referenced in function...
error LNK2019: unresolved external symbol _crc32 referenced in function ....
I used dumpbin to dump list of symbols from this zlibstat.lib
x86:
00B 00000000 SECT4 notype () External | _uncompress#16
029 000024F0 SECT5 notype () Static | _compress_block
00B 00000000 SECT4 notype () External | _compress2#20
00F 000000C0 SECT4 notype () External | _compress#16
010 000000E0 SECT4 notype () External | _compressBound#4
x64:
00A 00000000 SECT4 notype () External | uncompress
00D 00000000 SECT5 notype Static | $pdata$uncompress
010 00000000 SECT6 notype Static | $unwind$uncompress
050 00002E50 SECT5 notype () Static | compress_block
051 000000B4 SECT6 notype Static | $pdata$compress_block
052 00000078 SECT7 notype Static | $unwind$compress_block
00A 00000000 SECT4 notype () External | compress2
00D 00000000 SECT5 notype Static | $pdata$compress2
010 00000000 SECT6 notype Static | $unwind$compress2
015 00000150 SECT4 notype () External | compress
016 0000000C SECT5 notype Static | $pdata$compress
017 00000008 SECT6 notype Static | $unwind$compress
019 000001A0 SECT4 notype () External | compressBound
If add the code of zlib to my project it works fine..
What am I doing wrong when trying to link it with library?
I am using 64 bit machine and the configuration platform is win32.. I tried using x64 but didnt work..
For anyone coming across this question:
I have just solved this myself minutes ago and I personally think that this is a small error in the 1.2.8 sources. The 1.2.8 release contains a VS2010 project to build the zlibstat.lib and altough one would expect a static library file given the name, the macro ZLIB_WINAPI is defined which produces a dynamically linked lib file.
So without further ado: To compile zlibstat.lib in VS2010:
Simply go to the project's proprerties, go to C/C++->Preprocessor and remove the ZLIB_WINAPI macro from the Preprocessor Definitions

Resources