Intel® C++ Compiler
Community support and assistance for creating C++ code that runs on platforms based on Intel® processors.
7956 Discussions

OS X 32bit + inline assembler = broken shared library

Kuzmin__Igor
Beginner
314 Views

I've found a bug in OS X version of Intel C++ compiler when compiling shared 32bit library with inline msasm code in it. The problem is that compiler fails to produce either PIC code or text relocation for inline assembler referencing global or static variables which results in wrong memory address being referenced. Here's minimal test case (also attached for your convenience):

header.h:

void f(void);

main.c:

#include "header.h"
int main() {
	f();
	return 0;
}

lib.c:

#include <stdio.h>
#include "header.h"
void f(void) {
	static int i;
	void* p;
	_asm{
#ifdef __i386
		lea ecx, 
		mov 

, ecx #else lea rcx, mov

, rcx #endif } printf("asm %p C %p\n", p, &i); }

test.sh (clang is included for comparison, || && logic is needed for compatibility with 2013 SP1 version):

#!/bin/bash
icc -g -fno-pic -use-msasm -shared -o libtest.dylib lib.c || \
icc -g -fno-pic -use-msasm -c -o lib.o lib.c && \
clang -g -fno-pic -shared -o libtest.dylib lib.o
icc -g main.c -L. -ltest -o test
echo intel 64
DYLD_LIBRARY_PATH=. ./test 

icc -g -fPIC -use-msasm -shared -o libtest.dylib lib.c || \
icc -g -fPIC -use-msasm -c -o lib.o lib.c && \
clang -g -fPIC -shared -o libtest.dylib lib.o
icc -g main.c -L. -ltest -o test
echo PIC intel 64
DYLD_LIBRARY_PATH=. ./test 

icc -g -fno-pic -m32 -use-msasm -read_only_relocs warning -shared -o libtest.dylib lib.c || \
icc -g -fno-pic -m32 -use-msasm -c -o lib.o lib.c && \
clang -g -fno-pic -m32 -read_only_relocs warning -shared -o libtest.dylib lib.o
icc -g -m32 main.c -L. -ltest -o test
echo intel 32
DYLD_LIBRARY_PATH=. ./test 

icc -g -fPIC -m32 -use-msasm -read_only_relocs warning -shared -o libtest.dylib lib.c || \
icc -g -fPIC -m32 -use-msasm -c -o lib.o lib.c && \
clang -g -fPIC -m32 -read_only_relocs warning -shared -o libtest.dylib lib.o
icc -g -m32 main.c -L. -ltest -o test
echo PIC intel 32
DYLD_LIBRARY_PATH=. ./test 

clang -g -fno-pic -fms-extensions --shared -o libtest.dylib lib.c
clang -g main.c -L. -ltest -o test
echo clang 64
DYLD_LIBRARY_PATH=. ./test 

clang -g -fPIC -fms-extensions --shared -o libtest.dylib lib.c
clang -g main.c -L. -ltest -o test
echo PIC clang 64
DYLD_LIBRARY_PATH=. ./test 

clang -g -fno-pic -m32 -fms-extensions -read_only_relocs warning --shared -o libtest.dylib lib.c
clang -g -m32 main.c -L. -ltest -o test
echo clang 32
DYLD_LIBRARY_PATH=. ./test 

clang -g -fPIC -m32 -fms-extensions -read_only_relocs warning --shared -o libtest.dylib lib.c
clang -g -m32 main.c -L. -ltest -o test
echo PIC clang 32
DYLD_LIBRARY_PATH=. ./test 

And output of test.sh run:

intel 64
asm 0x107544018 C 0x107544018
PIC intel 64
asm 0x102f67018 C 0x102f67018
intel 32
asm 0xc1 C 0xb400c
PIC intel 32
asm 0xc1 C 0x5500c
clang 64
asm 0x108615018 C 0x108615018
PIC clang 64
asm 0x10a35e018 C 0x10a35e018
ld: warning: text reloc in _f to _f.i
ld: warning: text reloc in _f to cstring
ld: warning: text reloc in _f to _f.i
clang 32
asm 0xa400c C 0xa400c
ld: warning: text reloc in _f to _f
PIC clang 32
asm 0xf9eb6 C 0x7d00c

From this (and looking at disassembly of produced code) I conclude the following:

  • 64 bit doesn't have this issue (BTW on Linux 32/64 bits this test case works correctly too);
  • Intel compiler produces PIC code for C part in both -fPIC and -fno-pic modes;
  • Intel compiler produces non-PIC code for inline asm part in both modes, but doesn't create text relocations, which results in broken library;
  • Apple's clang correctly creates text relocations (and non-PIC code) for -fno-pic mode;
  • Apple's clang fails in -fPIC mode by creating PIC code and text relocation, so effectively double-correcting the library load offset.

So in fairness Intel compiler isn't the only one mishandling the situation, but at least I can use non-PIC mode (which is the one I want so it happens) with Apple's clang.

I'm using latest versions of OS X (10.10.4) and Xcode (6.4). I've tested 2015 and 2013 SP1 versions of Intel Parallel Studio XE Composer Edition for C++ OS X (earlier ones don't install on my system).

0 Kudos
2 Replies
KitturGanesh
Employee
314 Views

Thanks for the detailed info on the issue which I'll try to reproduce and file with the developers and update you accordingly, appreciate much.

_Kittur 

0 Kudos
KitturGanesh
Employee
314 Views

@parafin - realized I didn't update you that I've already filed the issue with the developers and will  keep you updated accordingly. Appreciate your patience till then.

_Kittur

0 Kudos
Reply