Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

gcc: limiting the instructions allowed for inline assembly language

2 views
Skip to first unread message

Mark Hobley

unread,
Jan 20, 2009, 10:08:09 PM1/20/09
to
Is there a way that I can cause the gcc compiler to error, if any processor
supplementary instructions are included via inline assembly language?

Specifically, I want an error to occur if any code is encountered that
includes any of the following instructions at compile time:

cmov,cpuid,fcmov,fcomi,nopl,rdpmc,rdtsc

I am hoping there is some sort of command line switch that I can apply
using a wrapper script around the compiler, or a configuration file that
I can edit to remove support for these.

Mark.

--
Mark Hobley
Linux User: #370818 http://markhobley.yi.org/

Sam

unread,
Jan 20, 2009, 11:07:31 PM1/20/09
to
Mark Hobley writes:

> Is there a way that I can cause the gcc compiler to error, if any processor
> supplementary instructions are included via inline assembly language?
>
> Specifically, I want an error to occur if any code is encountered that
> includes any of the following instructions at compile time:
>
> cmov,cpuid,fcmov,fcomi,nopl,rdpmc,rdtsc
>
> I am hoping there is some sort of command line switch that I can apply
> using a wrapper script around the compiler, or a configuration file that
> I can edit to remove support for these.

Without knowing the specific x86 family these instructions belong to, sounds
to me like you want to output assembly for some <i686 CPU class.

gcc takes an -march parameter that specifies the output CPU type. gcc's info
pages give the possible values in section "3.17.14 Intel 386 and AMD x86-64
Options".

Mark Hobley

unread,
Jan 21, 2009, 12:08:08 AM1/21/09
to
Sam <s...@email-scan.com> wrote:
> Without knowing the specific x86 family these instructions belong to, sounds
> to me like you want to output assembly for some <i686 CPU class.

Yeah. That's right. I want to build for an early 80486 (with floating
point unit, but without cpuid.)



> gcc takes an -march parameter that specifies the output CPU type.

Yeah. I have that set, but unfortunately I sometimes compile third party
code with inline assembly language containing the instructions, and these are
not filtered out by the -march parameter and end up in the resultant binary.

I really want a compilation error if such instructions are encountered
in the code.

Maxwell Lol

unread,
Jan 21, 2009, 6:16:44 AM1/21/09
to
markh...@hotpop.donottypethisbit.com (Mark Hobley) writes:

>
> I really want a compilation error if such instructions are encountered
> in the code.

perhaps the comp.lang.c and gnu.gcc newsgroup could help?

Sam

unread,
Jan 21, 2009, 7:05:27 AM1/21/09
to
Mark Hobley writes:

gcc does not examine inline assembly. It's passed on to the linker.

The only thing you could do, perhaps, is to run objdump on the resulting
binary and grep for the offending instructions yourself.


Jean-David Beyer

unread,
Jan 21, 2009, 7:17:10 AM1/21/09
to
If gcc works the same way the Bell Labs SVID compiler used to work, then gcc
is a "small" program that invokes the preprocessor, the compiler, the
assembler, and the linker. In that case, you could take the source to gcc
and have it insert a tester before the assembler and run sed or something on
it to catch the offending assembler instructions before letting the
assembler run. If the offending instructions appear, give an error return to
the gcc program.

--
.~. Jean-David Beyer Registered Linux User 85642.
/V\ PGP-Key: 9A2FC99A Registered Machine 241939.
/( )\ Shrewsbury, New Jersey http://counter.li.org
^^-^^ 07:10:01 up 35 days, 18:55, 3 users, load average: 4.79, 4.39, 4.14

Black Hat

unread,
Jan 21, 2009, 1:05:17 PM1/21/09
to
On 21 Jan 2009 at 3:08, Mark Hobley wrote:
> Is there a way that I can cause the gcc compiler to error, if any
> processor supplementary instructions are included via inline assembly
> language?
>
> Specifically, I want an error to occur if any code is encountered that
> includes any of the following instructions at compile time:
>
> cmov,cpuid,fcmov,fcomi,nopl,rdpmc,rdtsc
>
> I am hoping there is some sort of command line switch that I can apply
> using a wrapper script around the compiler, or a configuration file
> that I can edit to remove support for these.

You'd really be much better off asking this in comp.lang.c.

Mark Hobley

unread,
Jan 21, 2009, 1:08:09 PM1/21/09
to
Sam <s...@email-scan.com> wrote:
> gcc does not examine inline assembly. It's passed on to the linker.

Do you mean the assembler?

I need to trap the tool that translates the assembly language mnemonic
into the machine code binary instruction.

> The only thing you could do, perhaps, is to run objdump on the resulting
> binary and grep for the offending instructions yourself.

Yeah, I could do that. Its a bit of a crap way of doing this. Especially
with a compiled vmlinuz image. I have tried a few times to produce a
decent instruction listing for these, and it has not been successful.

Microsoft's tools were much better in this area. With Microsoft MASM,
Microsoft Quickbasic, or Microsoft C, it was possible to get the program
listing with the assembly language instructions interdispersed straight
from the compiler, just by providing a switch to the make command line.

There was none of this hassle of trying to edit makefiles, getting the object
dumper to work, or decompilation of compiled binaries to try and examine
the compiled code.

Mark Hobley

unread,
Jan 21, 2009, 1:08:09 PM1/21/09
to
Jean-David Beyer <jeand...@verizon.net> wrote:

> If gcc works the same way the Bell Labs SVID compiler used to work, then gcc
> is a "small" program that invokes the preprocessor, the compiler, the
> assembler, and the linker. In that case, you could take the source to gcc
> and have it insert a tester before the assembler and run sed or something on
> it to catch the offending assembler instructions before letting the
> assembler run. If the offending instructions appear, give an error return to
> the gcc program.

Yeah, that would be good. I don't think it is constructed in this manner
though. I think it compiles files ready for linking without going through the
assembler, certainly the compiler packages do not seem dependent on
the assembler. I am sure that I had a machine with the compiler, but no
assembler before, and the compiler worked file. However, I will do some tests
to check.

It is really strange that the inline assembler mnemonics have to be translated
externally.

I never did like this non-ANSI way of inlining code. and AT&T syntax is
just nasty. I prefer to keep C code in one file, and assembly language
instructions in another, and use separate tools to compile, but
use the linker to connect them together to build the executable.

Jean-David Beyer

unread,
Jan 21, 2009, 1:48:17 PM1/21/09
to
Mark Hobley wrote:
> Jean-David Beyer <jeand...@verizon.net> wrote:
>
>> If gcc works the same way the Bell Labs SVID compiler used to work,
>> then gcc is a "small" program that invokes the preprocessor, the
>> compiler, the assembler, and the linker. In that case, you could take
>> the source to gcc and have it insert a tester before the assembler and
>> run sed or something on it to catch the offending assembler
>> instructions before letting the assembler run. If the offending
>> instructions appear, give an error return to the gcc program.
>
> Yeah, that would be good. I don't think it is constructed in this manner
> though. I think it compiles files ready for linking without going
> through the assembler, certainly the compiler packages do not seem
> dependent on the assembler. I am sure that I had a machine with the
> compiler, but no assembler before, and the compiler worked file. However,
> I will do some tests to check.

I do not know what gcc does. Compiling straight to code has been the
practice for 10 or 20 years now, but you never know.


>
> It is really strange that the inline assembler mnemonics have to be
> translated externally.
>
> I never did like this non-ANSI way of inlining code. and AT&T syntax is
> just nasty. I prefer to keep C code in one file, and assembly language
> instructions in another, and use separate tools to compile, but use the
> linker to connect them together to build the executable.
>

That is much better when you can do it. The reason for in-line code is for
the case where the call and return overhead is large compared with the cost
of the function itself. Then there really no alternatives to assembly-level
code. OTOH, situations that require assembly-level code are almost
nonexistent. Read Jon Bently's book for examples on how to optimize programs.


--
.~. Jean-David Beyer Registered Linux User 85642.
/V\ PGP-Key: 9A2FC99A Registered Machine 241939.
/( )\ Shrewsbury, New Jersey http://counter.li.org

^^-^^ 13:45:01 up 5:36, 3 users, load average: 4.27, 4.60, 4.35

Huibert Bol

unread,
Jan 21, 2009, 2:46:24 PM1/21/09
to
Mark Hobley wrote:

> Is there a way that I can cause the gcc compiler to error, if any processor
> supplementary instructions are included via inline assembly language?
>
> Specifically, I want an error to occur if any code is encountered that
> includes any of the following instructions at compile time:
>
> cmov,cpuid,fcmov,fcomi,nopl,rdpmc,rdtsc
>
> I am hoping there is some sort of command line switch that I can apply
> using a wrapper script around the compiler, or a configuration file that
> I can edit to remove support for these.

Using "-Wa,-march=i386" will make the assembler complain about any
instruction that was not present in the original i386 instruction set.

See

$ info '(as)i386-Options'

for the complete list of valid arguments to -march.

--
Huibert
"The Commercial Channel! All commercials all the time.
An eternity of useless products to rot your skeevy little mind, forever!"
-- Mike the TV (Reboot)

Mark Hobley

unread,
Jan 25, 2009, 8:08:10 AM1/25/09
to
Huibert Bol <huibe...@quicknet.nl> wrote:

> Using "-Wa,-march=i386" will make the assembler complain about any
> instruction that was not present in the original i386 instruction set.

This does not appear to be working:

cat /etc/testasm.c
int main(void)
{
asm("cpuid"); /* Invalid on the i386 */
}

gcc -march=i386 -Wa,-march=i386 testasm.c

Neither the compiler, nor the assembler complain about this, but the
instruction is not valid on the specified architecture.

Huibert Bol

unread,
Jan 25, 2009, 8:28:21 AM1/25/09
to
Mark Hobley wrote:

> Huibert Bol <huibe...@quicknet.nl> wrote:
>
>> Using "-Wa,-march=i386" will make the assembler complain about any
>> instruction that was not present in the original i386 instruction set.
>
> This does not appear to be working:
>
> cat /etc/testasm.c
> int main(void)
> {
> asm("cpuid"); /* Invalid on the i386 */
> }
>
> gcc -march=i386 -Wa,-march=i386 testasm.c

Works for me, perhaps your assembler is a bit behind.

$ gcc -m32 -Wa,-march=i386 testasm.c
ttt.c: Assembler messages:
ttt.c:3: Error: `cpuid' is not supported on `i386'

$ as -v
GNU assembler version 2.19 (x86_64-suse-linux) using BFD version (GNU Binutils; openSUSE 11.1) 2.19

Mark Hobley

unread,
Jan 25, 2009, 10:08:09 AM1/25/09
to
In comp.os.linux.misc Huibert Bol <huibe...@quicknet.nl> wrote:
> Works for me, perhaps your assembler is a bit behind.
> GNU assembler version 2.19 (x86_64-suse-linux) using BFD version (GNU Binutils; openSUSE 11.1) 2.19

Oh right. Mine was version 2.18 (Debian Lenny). I'll try building a new
one from the latest source tarball and retry.

Cheers,

Mark Hobley

unread,
Mar 6, 2009, 12:08:01 AM3/6/09
to
Huibert Bol <huibert....@quicknet.nl> wrote:

> Using "-Wa,-march=i386" will make the assembler complain about any
> instruction that was not present in the original i386 instruction set.

This does not appear to be working:

cat /etc/testasm.c
int main(void)
{
asm("cpuid"); /* Invalid on the i386 */
}

gcc -march=i386 -Wa,-march=i386 testasm.c

Neither the compiler, nor the assembler complain about this, but the

instruction is not valid on the specified architecture.

Huibert Bol <huibert....@quicknet.nl> wrote:

> Works for me, perhaps your assembler is a bit behind.
> GNU assembler version 2.19 (x86_64-suse-linux) using BFD version (GNU
Binutils; openSUSE 11.1) 2.19

> $ gcc -m32 -Wa,-march=i386 testasm.c


> ttt.c: Assembler messages:
> ttt.c:3: Error: `cpuid' is not supported on `i386'
> $ as -v

> GNU assembler version 2.19 (x86_64-suse-linux) using BFD version (GNU
> Binutils; openSUSE 11.1) 2.19

Oh right. Mine was version 2.18 (Debian Lenny). I'll try building a new
one from the latest source tarball and retry.

Hmmm, I have just rebuild a new version of the assembler, and I still
cannot get the assembler to complain about the invalid instruction:

cat /etc/testasm.c
int main(void)
{
asm("cpuid"); /* Invalid on the i386 */
}

gcc -march=i386 -Wa,-march=i386 testasm.c

I still get no errors here.

as -v
GNU assembler version 2.19.1 (i386-pc-linux) using BFD version (GNU
Binutils) 2.19.1

Does anyone know why the Suse 64 bit version can trap the build error,
but the IA32 version build using the www.gnu.org distribution supplied tarball
does not trap this?

Darren Salt

unread,
Mar 6, 2009, 7:33:20 AM3/6/09
to
I demand that Mark Hobley may or may not have written...

> Huibert Bol <huibert....@quicknet.nl> wrote:
[snip]


>> $ as -v
>> GNU assembler version 2.19 (x86_64-suse-linux) using BFD version (GNU
>> Binutils; openSUSE 11.1) 2.19

> Oh right. Mine was version 2.18 (Debian Lenny). I'll try building a new one
> from the latest source tarball and retry.

Or you could install binutils from testing.

> Hmmm, I have just rebuild a new version of the assembler, and I still
> cannot get the assembler to complain about the invalid instruction:

> cat /etc/testasm.c
> int main(void)
> {
> asm("cpuid"); /* Invalid on the i386 */
> }

> gcc -march=i386 -Wa,-march=i386 testasm.c

> I still get no errors here.

[snip]


> Does anyone know why the Suse 64 bit version can trap the build error, but
> the IA32 version build using the www.gnu.org distribution supplied tarball
> does not trap this?

I see the same error here (running on amd64, so I have to add -m32).

I'd drop -Wa,-march=i386 and use signal(SIGILL, ...), setjmp and longjmp to
catch failure at runtime.

--
| Darren Salt | linux or ds at | nr. Ashington, | Toon
| RISC OS, Linux | youmustbejoking,demon,co,uk | Northumberland | Army
| + Output less CO2 => avoid massive flooding. TIME IS RUNNING OUT *FAST*.

Never use a long word when a diminutive one will do.

Mark Hobley

unread,
Mar 6, 2009, 8:08:01 PM3/6/09
to
Darren Salt <ne...@youmustbejoking.demon.cu.invalid> wrote:
> I'd drop -Wa,-march=i386 and use signal(SIGILL, ...), setjmp and longjmp to
> catch failure at runtime.

Some of faulty code is in the kernel, and a runtime error can result in
a frozen machine. I really do want to trap the error at compile time, so
that I can make appropriate fixes.

I haven't got a 64 bit machine to cause a compilation error. I need
compilation errors to occur on a 32 bit machine.

Mark Hobley

unread,
Mar 7, 2009, 4:08:02 AM3/7/09
to
Mark Hobley <markh...@hotpop.donottypethisbit.com> wrote:

> int main(void)
> {
> asm("cpuid"); /* Invalid on the i386 */
> }
>
> gcc -march=i386 -Wa,-march=i386 testasm.c
>
> Neither the compiler, nor the assembler complain about this, but the
> instruction is not valid on the specified architecture.

I edited the source code to this package as follows:

./opcodes/i386-dis.c

Remove the line:

{ "cpuid", { XX } },

./opcodes/i386-tbl.h

Remove the line:

{ "cpuid", 0, 0xfa2, None, 2,
{ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1,
1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0 } } } },

./opcodes/i386-opc.tbl:

Remove the line:

// 586 and late 486 extensions.
cpuid, 0, 0xfa2, None, 2, Cpu486, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { 0 }

I now rebuild the binutils package and copy the revised assembler over
the top of the original. I still get no complaint from the
compiler about this invalid instruction.

gcc -march=i386 -Wa,-march=i386 testasm.c

No error occurs here, even though the embedded instruction is invalid.

Does anyone know how to fix this?

Mark Hobley

unread,
Mar 7, 2009, 8:08:03 AM3/7/09
to
Mark Hobley <markh...@hotpop.donottypethisbit.com> wrote:
> gcc -march=i386 -Wa,-march=i386 testasm.c
>
> No error occurs here, even though the embedded instruction is invalid.
>
> Does anyone know how to fix this?

Here is some information from a system trace of the above command:

16185 execve("/usr/bin/gcc", ["gcc", "-march=i386", "-Wa,-march=i386",
"testasm.c"], [/* 21 vars */]) = 0

<snip>

16185 uname({sys="Linux", node="localhost", ...}) = 0

-- This is probably not return the correct results. but I cannot fix
this, because the toolchain is broken.

<snip>

16186 access("/usr/lib/gcc/i486-t2-linux-gnu/4.2.2/", X_OK) = 0
16186 access("/usr/lib/gcc/i486-t2-linux-gnu/4.2.2/", X_OK) = 0
16186 access("testasm.c", F_OK) = 0
16186 access("/usr/lib/gcc/i486-t2-linux-gnu/4.2.2/specs", R_OK) = -1
ENOENT (No such file or directory)
16186 access("/usr/lib/gcc/i486-t2-linux-gnu/4.2.2/specs", R_OK) = -1
ENOENT (No such file or directory)
16186 access("/usr/lib/gcc/i486-t2-linux-gnu/4.2.2/../../../../i486-t2-linux-gnu
/lib/i486-t2-linux-gnu/4.2.2/specs", R_OK) = -1 ENOENT (No such file or
directory)
16186 access("/usr/lib/gcc/i486-t2-linux-gnu/4.2.2/../../../../i486-t2-linux-gnu
/lib/specs", R_OK) = -1 ENOENT (No such file or directory)
16186 access("/usr/lib/gcc/i486-t2-linux-gnu/specs", R_OK) = -1 ENOENT
(No such file or directory)
16186 access("/usr/lib/gcc/i486-t2-linux-gnu/4.2.2/", X_OK) = 0

What the hell is all that lot? The architecture is wrong. I want i386.

<snip>

16187 execve("/usr/libexec/gcc/i486-t2-linux-gnu/4.2.2/cc1",
["/usr/libexec/gcc/i486-t2-linux-g"..., "-quiet"..., "testasm.c"..., "-quiet"...,
"-dumpbase"..., "testasm.c"..., "-march=i386"..., "-march=i386"..., "-auxbase"...,
"testasm"..., "-o"..., "/tmp/ccomoxOO.s"...], [/* 23 vars */]) = 0

Hmmm, I don't know what that means? It looks like gcc is passing running
another compiler called cc1.

16187 access("/usr/lib/gcc/i486-t2-linux-gnu/4.2.2/", X_OK) = 0
16187 stat64("/usr/local/include", {st_mode=S_IFDIR|0755, st_size=4096,
...}) = 0
16187 stat64("/usr/lib/gcc/i486-t2-linux-gnu/4.2.2/include",
{st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
16187 stat64("/usr/lib/gcc/i486-t2-linux-gnu/4.2.2/../../../../i486-t2-linux-gnu
/include", 0xbffedf60) = -1 ENOENT (No such file or directory)

16187 stat64("testasm.c.gch", 0xbffedf40) = -1 ENOENT (No such file or
directory)
16187 open("testasm.c", O_RDONLY|O_NOCTTY) = 3

Right .. we are probably attempting to compile from here ...

16186 stat64("/usr/libexec/gcc/i486-t2-linux-gnu/4.2.2/as", 0xbfd1ec30)
= -1 ENOENT (No such file or directory)
16186 stat64("/usr/libexec/gcc/i486-t2-linux-gnu/4.2.2/as", 0xbfd1ec30)
= -1 ENOENT (No such file or directory)
16186 stat64("/usr/libexec/gcc/i486-t2-linux-gnu/as", 0xbfd1ec30) = -1
ENOENT (No such file or directory)
16186 stat64("/usr/lib/gcc/i486-t2-linux-gnu/4.2.2/as", 0xbfd1ec30) = -1
ENOENT (No such file or directory)
16186 stat64("/usr/lib/gcc/i486-t2-linux-gnu/as", 0xbfd1ec30) = -1
ENOENT (No such file or directory)
16186 stat64("/usr/libexec/gcc/i486-t2-linux-gnu/4.2.2/as", 0xbfd1ec30)
= -1 ENOENT (No such file or directory)
16186 stat64("/usr/libexec/gcc/i486-t2-linux-gnu/as", 0xbfd1ec30) = -1
ENOENT (No such file or directory)
16186 stat64("/usr/lib/gcc/i486-t2-linux-gnu/4.2.2/as", 0xbfd1ec30) = -1
ENOENT (No such file or directory)
16186 stat64("/usr/lib/gcc/i486-t2-linux-gnu/as", 0xbfd1ec30) = -1
ENOENT (No such file or directory)
16186 stat64("/usr/lib/gcc/i486-t2-linux-gnu/4.2.2/../../../../i486-t2-linux-gnu
/bin/i486-t2-linux-gnu/4.2.2/as", 0xbfd1ec30) = -1 ENOENT (No such file
or directory)
16186 stat64("/usr/lib/gcc/i486-t2-linux-gnu/4.2.2/../../../../i486-t2-linux-gnu
/bin/as", {st_mode=S_IFREG|0755, st_size=232980, ...}) = 0
16186 access("/usr/lib/gcc/i486-t2-linux-gnu/4.2.2/../../../../i486-t2-linux-gnu
/bin/as", X_OK) = 0
16186 vfork() = 16188
16186 waitpid(16188, <unfinished ...>
16188 execve("/usr/lib/gcc/i486-t2-linux-gnu/4.2.2/../../../../i486-t2-linux-gnu
/bin/as", ["/usr/lib/gcc/i486-t2-linux-gnu/4"..., "-Qy"..., "-march=i386"..., "-march=i386"..., "-o"..., "/tmp/ccCaOapG.o"..., "/tmp/ccomoxOO.s"...],
[/* 23 vars */]) = 0

Look at those paths!!! Is the new assembler running or not?

<snip>

16188 open("/usr/lib/libopcodes-2.17.50.0.15.20070418.so", O_RDONLY) = 3
16188 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\260\232\0\0004\0\
0\0"..., 512) = 512

Is the opcode library the one that was build from the new binutils?
I'll have a look at the file date to see if I can tell. I wonder if
there is some way of obtaining a version number ...

Mark Hobley

unread,
Mar 7, 2009, 3:08:06 PM3/7/09
to
Mark Hobley <markh...@hotpop.donottypethisbit.com> wrote:

> 16188 open("/usr/lib/libopcodes-2.17.50.0.15.20070418.so", O_RDONLY) = 3
> 16188 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\260\232\0\0004\0\
> 0\0"..., 512) = 512
>
> Is the opcode library the one that was build from the new binutils?
> I'll have a look at the file date to see if I can tell. I wonder if
> there is some way of obtaining a version number ...

I have now copied /usr/local/lib/libopcodes.a and /usr/local/lib/libopcodes.la
to the /usr/lib directory.

I do not have a /usr/local/lib/libopcodes-2.17.50.0.15.20070418.so file
or a /usr/local/lib/libopcodes.so symlink, so I have not yet replaced
these files.

Is there a way that I can force binutils to install in /usr/bin and
/usr/lib, rather than /usr/local/bin and /usr/local/lib at configure time?

Mark Hobley

unread,
Mar 7, 2009, 3:08:06 PM3/7/09
to
Mark Hobley <markh...@hotpop.donottypethisbit.com> wrote:

> 16188 open("/usr/lib/libopcodes-2.17.50.0.15.20070418.so", O_RDONLY) = 3
> 16188 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\260\232\0\0004\0\
> 0\0"..., 512) = 512
>
> Is the opcode library the one that was build from the new binutils?
> I'll have a look at the file date to see if I can tell. I wonder if
> there is some way of obtaining a version number ...

ls -l libopcodes*
-rwxr-xr-x 1 root root 191912 2007-11-11 17:04 libopcodes-2.17.50.0.15.20070418.so
-rw-r--r-- 1 root root 208574 2007-11-11 17:04 libopcodes.a
-rwxr-xr-x 1 root root 806 2007-11-11 17:04 libopcodes.la
lrwxrwxrwx 1 root root 35 2009-01-28 02:24 libopcodes.so -> libopcodes-2.17.50.0.15.20070418.so

Ok. These dates do not look right to me. I will see if I can locate these
files from the new build.

Mark Hobley

unread,
Mar 7, 2009, 4:08:01 PM3/7/09
to
Mark Hobley <markh...@hotpop.donottypethisbit.com> wrote:
> Is there a way that I can force binutils to install in /usr/bin and
> /usr/lib, rather than /usr/local/bin and /usr/local/lib at configure time?

It appears that the configure script has a --prefix switch. I am
rebuilding the binutils suite again using:

./configure --build='i386-pc-linux' --prefix=/usr --disable-nls
make
make install

I will then retry to recompile testasm.c

Mark Hobley

unread,
Mar 7, 2009, 5:08:01 PM3/7/09
to
Mark Hobley <markh...@hotpop.donottypethisbit.com> wrote:
> ./configure --build='i386-pc-linux' --prefix=/usr --disable-nls
> I will then retry to recompile testasm.c

I rebuild the binutils suite, and the problem still occurs.

cat /etc/testasm.c


int main(void)
{
asm("cpuid"); /* Invalid on the i386 */
}

gcc -march=i386 -Wa,-march=i386 testasm.c

No error occurs, but the instruction is not valid.

I did a system trace again, following the rebuild, and there still
appears to be a reference to libopcodes-2.17.50.0.15.20070418.so as
follows:

18926 open("/usr/lib/libopcodes-2.17.50.0.15.20070418.so", O_RDONLY) = 3
18926 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\260\232\0\0004\0\


0\0"..., 512) = 512

I examined the build directory for binutils, and could not find any
replacement libopcodes.so file. I wonder if this is the cause of the
problem.

cd ~/binutils
find ./ -name "libopcode*"
./binutils-2.19.51.0.2/build/opcodes/.libs/libopcodes.a
./binutils-2.19.51.0.2/build/opcodes/.libs/libopcodes.lai
./binutils-2.19.51.0.2/build/opcodes/.libs/libopcodes.la
./binutils-2.19.51.0.2/build/opcodes/libopcodes.a
./binutils-2.19.51.0.2/build/opcodes/libopcodes.la

How do I rebuild the libopcodes.so file to match the new assembler?

Gang Greene

unread,
Mar 7, 2009, 5:39:51 PM3/7/09
to
Mark Hobley wrote:

I have been following this thread a little and decided to compile your test
pgm an give it a go

Here is my result:

$ gcc -march=i386 -Wa,-march=i386 testasm.c
testasm.c: Assembler messages:
testasm.c:3: Error: `cpuid' is not supported on `i386'

I am using:

$ gcc --version
gcc (GCC) 4.3.3
Copyright (C) 2008 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Arch linux with the gcc tool chain compiled with these flags:

CFLAGS="-march=native -mtune=generic -O2 -pipe -fomit-frame-pointer"
CXXFLAGS=${CFLAGS}

on an AMD K7 processor, -march=native tunes gcc for AMD

Maybe you some how broke your tool chain?

Mark Hobley

unread,
Mar 7, 2009, 11:08:01 PM3/7/09
to
Gang Greene <GangG...@bildanet.com> wrote:
> $ gcc -march=i386 -Wa,-march=i386 testasm.c
> testasm.c: Assembler messages:
> testasm.c:3: Error: `cpuid' is not supported on `i386'

I can't get that error. I suspect that the libopcodes.so file is to
blame.

I need to somehow recompile libopcodes.so

> $ gcc --version

gcc --version

gcc -v
Using built-in specs.
Target: i486-t2-linux-gnu
Configured with: ../configure --prefix=/usr --bindir=/usr/bin
--sbindir=/usr/sbin --libdir=/usr/lib --datadir=/usr/share
--includedir=/usr/include --infodir=/usr/info --mandir=/usr/man
--sysconfdir=/etc --localstatedir=/var --disable-debug --with-libpam
--with-pam --enable-libpam --enable-pam --build=i486-t2-linux-gnu
--host=i486-t2-linux-gnu --enable-__cxa_atexit --disable-checking
--disable-bootstrap --disable-libstdcxx-pch --disable-multilib
--with-gnu-as --with-gnu-ld --enable-threads=posix --enable-libgcj
--enable-languages=c,c++,objc,java --enable-shared
Thread model: posix
gcc version 4.2.2

This is a stage 0 buildstrap system. I will be building the latest
version of gcc with the new assembler, once it works.

> Maybe you some how broke your tool chain?

I haven't yet built the toolchain. That is what I am trying to do. This
is a stage 0 buildstrap. I am trying to build a toolchain that will be
used to compile the rest of the system.

I need to somehow force compilation of a new libopcodes.so from the
latest version of binutils. The libopcodes library from the distribution
build kit is faulty. (It was build for a higher platform than my target.)

I am at stage 0 (building the toolchain for the initial bootstap).

Mark Hobley

unread,
Mar 8, 2009, 3:08:02 AM3/8/09
to
Mark Hobley <markh...@hotpop.donottypethisbit.com> wrote:
> gcc -v
> Using built-in specs.
> Target: i486-t2-linux-gnu
> gcc version 4.2.2

I am going to abandon the T2 distribution build kit, and use a Linux From
Scratch livecd. This will give me gcc version 4.2.3.

However, it will not give me the version of binutils that I require, so
I will still need to rebuild the libopcodes.so file.

In the meantime, I will try to get LFS bootable from the hard drive, and
networking operational from LFS.

Gang Greene

unread,
Mar 8, 2009, 8:34:32 AM3/8/09
to
Mark Hobley wrote:

> Mark Hobley <markh...@hotpop.donottypethisbit.com> wrote:
>> gcc -v
>> Using built-in specs.
>> Target: i486-t2-linux-gnu
>> gcc version 4.2.2
>
> I am going to abandon the T2 distribution build kit, and use a Linux From
> Scratch livecd. This will give me gcc version 4.2.3.
>
> However, it will not give me the version of binutils that I require, so
> I will still need to rebuild the libopcodes.so file.
>
> In the meantime, I will try to get LFS bootable from the hard drive, and
> networking operational from LFS.
>
> Mark.
>

I have used LFS and find it very good

Best of Luck

Mark Hobley

unread,
Mar 8, 2009, 11:08:01 AM3/8/09
to
Gang Greene <GangG...@bildanet.com> wrote:
> I have used LFS and find it very good

The problem is that I am building for i386 compatible machines using a
machine with a later generation processor, and cpuid and some badly written
inline assembly language code in various places is spoiling the build. I really
need that libopcodes.so fix, so that I can trap any invalid instructions
at compile time, allowing me to fix the code, and recompile.

Mark Hobley

unread,
Mar 9, 2009, 2:08:04 PM3/9/09
to
Mark Hobley <markh...@hotpop.donottypethisbit.com> wrote:
> The problem is that I am building for i386 compatible machines using a
> machine with a later generation processor, and cpuid and some badly written
> inline assembly language code in various places is spoiling the build.

Have you seen this in the changelog?

Changes in 2.19:
* Support for SSE5 has been added to the i386 port.

What the hell is that? The i386 does not support SSE5.

0 new messages