473,386 Members | 1,883 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

Undefined reference to memcpy in standalone program

Hi,

I've just upgraded my gcc and I'm currently trying to compile some code for
my own operating system kernel, but I am getting an error of "Undefined
reference to `memcpy`" when I try to link it using the GNU linker. I do not
reference the symbol memcpy explicitly anywhere in the offending function.
I have narrowed the offending code down to the initialisation of an array
of pointers to char (i.e. an array of strings), which is given below. It
seems that for some reason gcc is inserting calls to the standard library
in some attempt to optimise my code. How do I stop it from doing this? I'm
running version 3.3.1 and am compiling with the --freestanding flag, which
I thought should be enough to prevent this kind of behaviour (it certainly
was on previous versions; either that or gcc did not try and perform this
action then).

char* CPUstrings[] = {
"UNKNOWN Processor",
"Generic 386",
"NexGen 586",
"Cyrix M1 or IBM Bluelightning",
"Generic 486",
"Intel 386",
"Intel 486DX",
"Intel 486SX",
"Intel 486DX2",
"Intel 486SL",
"Intel 486SX2",
"Intel 486DX2 WB",
"Intel 486DX4",
"Intel 486DX4 WB",
"Intel 486",
"Intel Pentium Early P5",
"Intel Pentium 80501",
"Intel Pentium P54C 80502",
"Intel Pentium P24T (overdrive for 486 socket)",
"Intel Pentium MMX P55C",
"Intel Pentium P54C",
"Intel Pentium MMX P55",
"Intel Pentium P5",
"Intel Pentium Pro (Sample)",
"Intel Pentium Pro",
"Intel Pentium II (Klamath)",
"Intel Pentium II (Deschutes)/Xeon/Celeron",
"Intel Celeron A/Pentium II",
"Intel Pentium III (Katmai)",
"Intel Pentium III (Coppermine)",
"Intel Pentium III Xeon (Cascades)",
"Intel Pentium P6",
"Intel Pentium IV",
"UMC 486DX",
"UMC 486SX"
"UMC 486",
"AMD 486DX2, or DX4 in 2x WT mode",
"AMD 486DX2, or DX4 in 2x WB mode",
"AMD 486DX4, or 5x86 in 3x WT mode",
"AMD 486DX4 SV8B, 3x WB mode",
"AMD 5x86, 4x WT mode",
"AMD 5x86, 4x WB mode",
"AMD 486",
"AMD K5 Model 0",
"AMD K5 Model 1",
"AMD K5 Model 2",
"AMD K5 Model 3",
"AMD K6 Model 6",
"AMD K6 Model 7",
"AMD K6-II Model 8",
"AMD K6-III Model 9 (Sharptooth)",
"AMD K6-II+/K6-III+",
"AMD K5/K6",
"AMD Athlon 0.25u (external L2 cache)",
"AMD Athlon 0.18u (external L2 cache)",
"AMD Duron",
"AMD Athlon 0.18u (integrated L2 cache)",
"AMD K7 Athlon/Duron",
"Rise mP6 iDragon .25u",
"Rise mP6 iDragon .18u",
"Rise mP6 iDragon II .25u",
"Rise mP6 iDragon II .18u",
"Rise mP6",
"TransMeta Crusoe"
};

Thanks!

Richard Hayden.
Nov 14 '05 #1
7 12028
begin followup to Richard Hayden:
char* CPUstrings[] = {


Try again with

const char* const CPUstrings[] = {

--
Für Google, Tux und GPL!
Nov 14 '05 #2
Alexander Bartolich wrote:
begin followup to Richard Hayden:
char* CPUstrings[] = {


Try again with

const char* const CPUstrings[] = {


No change in output I'm afraid...

Thanks,

Richard Hayden.
Nov 14 '05 #3
begin followup to Richard Hayden:
No change in output I'm afraid...


Then the problem is something else.

$ const char* const CPUstrings[] = {
"UNKNOWN Processor",
"Generic 386"
};

void _start()
{
asm(
"mov $4,%eax\n"
"mov $1,%ebx\n"
"mov (CPUstrings),%ecx\n"
"mov $17,%edx\n"
"int $0x80\n"

"mov $1,%eax\n"
"mov $27,%ebx\n"
"int $0x80\n"
);
}

$ gcc -c -ffreestanding -Wall stand.c && ld stand.o -o stand
$ ./stand ; /bin/echo -e "\n$?"
UNKNOWN Processor
27

$ objdump -M intel -d stand

stand: file format elf32-i386

Disassembly of section .text:

08048074 <_start>:
8048074: 55 push ebp
8048075: 89 e5 mov ebp,esp
8048077: b8 04 00 00 00 mov eax,0x4
804807c: bb 01 00 00 00 mov ebx,0x1
8048081: 8b 0d 9c 80 04 08 mov ecx,ds:0x804809c
8048087: ba 11 00 00 00 mov edx,0x11
804808c: cd 80 int 0x80
804808e: b8 01 00 00 00 mov eax,0x1
8048093: bb 1b 00 00 00 mov ebx,0x1b
8048098: cd 80 int 0x80
804809a: 5d pop ebp
804809b: c3 ret

Obviously this thread has left the topic of comp.lang.c far behind...
Perhaps comp.lang.asm.x86, gnu.gcc or linux.dev.gcc is better suited.

--
Für Google, Tux und GPL!
Nov 14 '05 #4
In article <news:bs**********@titan.btinternet.com>
Richard Hayden <ra********@yahoo.co.uk> writes:
... I am getting an error of "Undefined reference to `memcpy`" [even though he never calls memcpy() himself].
I have narrowed the offending code down to the initialisation of an array
of pointers to char (i.e. an array of strings), which is given below.
This is probably not it.

More likely you have some function like:

void fn(void) {
char buf[] = "some initialization";
...
}

and gcc is doing the initialization via memcpy(); or you have a
struct-to-struct assignment that the compiler implements via a
call to memcpy() (although under various optimizations gcc will
subsequently inline this on x86 CPUs).
It seems that for some reason gcc is inserting calls to the
standard library in some attempt to optimise my code. How do
I stop it from doing this? I'm running version 3.3.1 and am
compiling with the --freestanding flag ...


("-ffreestanding", I presume.)

Unfortunately, hosted compilers are allowed to "know" all about
the entire C standard library and make arbitrary changes to your
source, and freestanding compilers are sufficiently difficult to
talk about to be mostly off-topic in comp.lang.c (freestanding
systems may not even have a main() function, as no doubt you already
know, having no doubt had to write your own startup code -- you can
then pick your own name for the entry point for your program).

GCC in particular may still use memcpy(), memset(), and a whole
host of generic 64-bit function calls (__muldi2, __divdi2, etc.),
even under -ffreestanding, depending on the machine in question
and sometimes on optimization levels. It may also need machine-
specific functions for other "ordinary" operations, such as
integer multiply and divide (.mul, .urem, etc., on pre-V8 sparc).

With GCC in particular, once you know which .o file(s) refer to
the unwanted function, you can compile to assembly code and read
this to pin down precisely where and why it wants some particular
function. It usually only takes a little "thinking like a
compiler-writer", at that point, to come up with ways to change
the generated code. (Or of course -- as in this case -- you can
simply write a little standalone memcpy()...)
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Nov 14 '05 #5

"Richard Hayden" <ra********@yahoo.co.uk> wrote in message
news:bs**********@titan.btinternet.com...
Hi,

I've just upgraded my gcc and I'm currently trying to compile some code for my own operating system kernel, but I am getting an error of "Undefined
reference to `memcpy`" when I try to link it using the GNU linker. I do not reference the symbol memcpy explicitly anywhere in the offending function.
I have narrowed the offending code down to the initialisation of an array
of pointers to char (i.e. an array of strings), which is given below. It
seems that for some reason gcc is inserting calls to the standard library
in some attempt to optimise my code. How do I stop it from doing this? I'm
running version 3.3.1 and am compiling with the --freestanding flag, which
I thought should be enough to prevent this kind of behaviour (it certainly
was on previous versions; either that or gcc did not try and perform this
action then).

char* CPUstrings[] = {
"UNKNOWN Processor",
"Generic 386",
"NexGen 586",
"Cyrix M1 or IBM Bluelightning",
"Generic 486",
"Intel 386",
"Intel 486DX",
"Intel 486SX",
"Intel 486DX2",
"Intel 486SL",
"Intel 486SX2",
"Intel 486DX2 WB",
"Intel 486DX4",
"Intel 486DX4 WB",
"Intel 486",
"Intel Pentium Early P5",
"Intel Pentium 80501",
"Intel Pentium P54C 80502",
"Intel Pentium P24T (overdrive for 486 socket)",
"Intel Pentium MMX P55C",
"Intel Pentium P54C",
"Intel Pentium MMX P55",
"Intel Pentium P5",
"Intel Pentium Pro (Sample)",
"Intel Pentium Pro",
"Intel Pentium II (Klamath)",
"Intel Pentium II (Deschutes)/Xeon/Celeron",
"Intel Celeron A/Pentium II",
"Intel Pentium III (Katmai)",
"Intel Pentium III (Coppermine)",
"Intel Pentium III Xeon (Cascades)",
"Intel Pentium P6",
"Intel Pentium IV",
"UMC 486DX",
"UMC 486SX"
"UMC 486",
"AMD 486DX2, or DX4 in 2x WT mode",
"AMD 486DX2, or DX4 in 2x WB mode",
"AMD 486DX4, or 5x86 in 3x WT mode",
"AMD 486DX4 SV8B, 3x WB mode",
"AMD 5x86, 4x WT mode",
"AMD 5x86, 4x WB mode",
"AMD 486",
"AMD K5 Model 0",
"AMD K5 Model 1",
"AMD K5 Model 2",
"AMD K5 Model 3",
"AMD K6 Model 6",
"AMD K6 Model 7",
"AMD K6-II Model 8",
"AMD K6-III Model 9 (Sharptooth)",
"AMD K6-II+/K6-III+",
"AMD K5/K6",
"AMD Athlon 0.25u (external L2 cache)",
"AMD Athlon 0.18u (external L2 cache)",
"AMD Duron",
"AMD Athlon 0.18u (integrated L2 cache)",
"AMD K7 Athlon/Duron",
"Rise mP6 iDragon .25u",
"Rise mP6 iDragon .18u",
"Rise mP6 iDragon II .25u",
"Rise mP6 iDragon II .18u",
"Rise mP6",
"TransMeta Crusoe"
};


You have specified that the strings and the pointer table to them have to be
initialised read/write data. Make the pointer table and target data
constants using the 'const' keyword twice to avoid the initialisation (const
char * const CPUstrings[] ...). This has the side effect that you have to
use the table and strings in such context that const data is allowed there.

HTH

Tauno Voipio
tauno voipio @ iki fi

Nov 14 '05 #6
On Wed, 24 Dec 2003 23:29:54 +0000 (UTC), Richard Hayden
<ra********@yahoo.co.uk> wrote:
Hi,

I've just upgraded my gcc and I'm currently trying to compile some code for
my own operating system kernel, but I am getting an error of "Undefined
reference to `memcpy`" when I try to link it using the GNU linker. I do not
reference the symbol memcpy explicitly anywhere in the offending function.
I have narrowed the offending code down to the initialisation of an array
of pointers to char (i.e. an array of strings), which is given below. <snip>
char* CPUstrings[] = { <snipped>


In addition to the other answers, especially (as usual) Chris Torek,
is there a reason you actually need it initialized at runtime and
can't just make it static? Doesn't your OS/boot support init data? Do
you want to make changes one time through the function and have them
gone (restored) the next time through (doesn't seem likely to me)?

- David.Thompson1 at worldnet.att.net
Nov 14 '05 #7
Eric Sosman wrote:
Hi,

I've just upgraded my gcc and I'm currently trying to compile some code for
my own operating system kernel, but I am getting an error of "Undefined
reference to `memcpy`" when I try to link it using the GNU linker. I do not
reference the symbol memcpy explicitly anywhere in the offending function.
I have narrowed the offending code down to the initialisation of an array
of pointers to char (i.e. an array of strings), which is given below. It
seems that for some reason gcc is inserting calls to the standard library
in some attempt to optimise my code. How do I stop it from doing this? I'm
running version 3.3.1 and am compiling with the --freestanding flag, which
I thought should be enough to prevent this kind of behaviour (it certainly
was on previous versions; either that or gcc did not try and perform this
action then).

char* CPUstrings[] = {
"UNKNOWN Processor",
"Generic 386",
"NexGen 586",
"Cyrix M1 or IBM Bluelightning",
"Generic 486",
"Intel 386",
"Intel 486DX",
"Intel 486SX",
"Intel 486DX2",
"Intel 486SL",
"Intel 486SX2",
"Intel 486DX2 WB",
"Intel 486DX4",
"Intel 486DX4 WB",
"Intel 486",
"Intel Pentium Early P5",
"Intel Pentium 80501",
"Intel Pentium P54C 80502",
"Intel Pentium P24T (overdrive for 486 socket)",
"Intel Pentium MMX P55C",
"Intel Pentium P54C",
"Intel Pentium MMX P55",
"Intel Pentium P5",
"Intel Pentium Pro (Sample)",
"Intel Pentium Pro",
"Intel Pentium II (Klamath)",
"Intel Pentium II (Deschutes)/Xeon/Celeron",
"Intel Celeron A/Pentium II",
"Intel Pentium III (Katmai)",
"Intel Pentium III (Coppermine)",
"Intel Pentium III Xeon (Cascades)",
"Intel Pentium P6",
"Intel Pentium IV",
"UMC 486DX",
"UMC 486SX"
"UMC 486",
"AMD 486DX2, or DX4 in 2x WT mode",
"AMD 486DX2, or DX4 in 2x WB mode",
"AMD 486DX4, or 5x86 in 3x WT mode",
"AMD 486DX4 SV8B, 3x WB mode",
"AMD 5x86, 4x WT mode",
"AMD 5x86, 4x WB mode",
"AMD 486",
"AMD K5 Model 0",
"AMD K5 Model 1",
"AMD K5 Model 2",
"AMD K5 Model 3",
"AMD K6 Model 6",
"AMD K6 Model 7",
"AMD K6-II Model 8",
"AMD K6-III Model 9 (Sharptooth)",
"AMD K6-II+/K6-III+",
"AMD K5/K6",
"AMD Athlon 0.25u (external L2 cache)",
"AMD Athlon 0.18u (external L2 cache)",
"AMD Duron",
"AMD Athlon 0.18u (integrated L2 cache)",
"AMD K7 Athlon/Duron",
"Rise mP6 iDragon .25u",
"Rise mP6 iDragon .18u",
"Rise mP6 iDragon II .25u",
"Rise mP6 iDragon II .18u",
"Rise mP6",
"TransMeta Crusoe"
};

Thanks!

Richard Hayden.


A while ago I read that memcpy was the one function reference
gcc-compiled code cannot do without.

Why not implement it yourself, or link it in from some gcc-provided
library for your target platform? You don't buy any unnecessary code
when doing this.

greetings,
Thomas

Nov 14 '05 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: RU | last post by:
Hi, I am working on a porting project to port C/C++ application from unixware C++, AT&T Standard components to g++ with STL on Linux. This application has been working properly on...
2
by: ferdous | last post by:
Hi Greetings to all I am new to ProC. I am compiling a very simple program written in ProC. I can compile the program using proc filename.pc and it generates the corresponding c code :) , but...
3
by: blueblueblue2005 | last post by:
Hi, I am learning C++ using the examples from Deitel How to Program in C++. I download the example code. now I am working on the operator overloading. I am working under Ubuntu Linux 5.04. I...
2
by: D. Stimits | last post by:
In PostgreSQL 7.2 (Redhat 7.3 version, so it is patched), I'm trying to create a Version-1 C server extension. The Version-0 format works, the Version-1 version fails with: undefined reference to...
4
by: Albert Oppenheimer | last post by:
I have a small program, test.c. It runs OK. This is on Linux (kernel 2.6.8.1, GCC 3.4.1). I decided to convert it to C++ before expanding it to a larger program. I changed the filename to...
5
by: druberego | last post by:
I read google and tried to find the solution myself. YES I do know that you can get undefined references if you: a) forget to implement the code for a prototype/header file item, or b) you forget...
3
by: s.z.s | last post by:
Hi! I hope the solution to that is not too stupid... I've got three files: <snip test_main.cc> #include"test.hh" int main(void) { A<inta1; a1.saywhat();
1
by: taiyang902 | last post by:
i program under linux ,and using kdevelop c/c++. the code follow, #ifdef HAVE_CONFIG_H #include <config.h> #endif #include <iostream> #include <cstdlib> using namespace std;
1
by: ajaycse | last post by:
I am facing the problem of calling cfitsio library from C program in linux. when i am giving compiling my C program using options "gcc -o CreateLevel1DataFitsFile CreateLevel1DataFitsFile.c -lm...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.