[U-Boot-Users] Non-static global variables cause relocation to fail

I tried to find documentation on this, but couldn't.
I've discovered, on PowerPC 85xx systems at least, that the mere presence of a non-static global variable, even if it isn't used by any code, will cause relocation to fail. Exactly how it fails, I can't say, but U-Boot does hang.
If I make the global variable static, the problem goes away. Note that I have no code that actually references the variable. It just sits there, occupying space.
Fortunately, the data structure doesn't need to be non-static. I just forgot to put 'static' in its definition. Of course, it would have been nice to know this up front.
Can someone explain why this is the case? Do I need to do anything special in my code to access global variables, static or not static?

In message 485AA905.9030907@freescale.com you wrote:
I tried to find documentation on this, but couldn't.
I've discovered, on PowerPC 85xx systems at least, that the mere presence of a non-static global variable, even if it isn't used by any code, will cause relocation to fail. Exactly how it fails, I can't say, but U-Boot does hang.
If I make the global variable static, the problem goes away. Note that I have no code that actually references the variable. It just sits there, occupying space.
Fortunately, the data structure doesn't need to be non-static. I just forgot to put 'static' in its definition. Of course, it would have been nice to know this up front.
Can someone explain why this is the case? Do I need to do anything special in my code to access global variables, static or not static?
You don't seriously expect any real help given such a vague description? It would be somewhat helpful if you said exactly which changes cause the code to work or fail...
Best regards,
Wolfgang Denk

Wolfgang Denk wrote:
You don't seriously expect any real help given such a vague description? It would be somewhat helpful if you said exactly which changes cause the code to work or fail...
I did say that. Simply making the global variable not static caused it to fail.
Works:
static struct __attribute__ ((__packed__)) eeprom {
Doesn't work:
struct __attribute__ ((__packed__)) eeprom {
Everything else is the same.

In message 485AC5C5.5080709@freescale.com you wrote:
I did say that. Simply making the global variable not static caused it to fail.
Ummm... I guess there must be more than one variable in U-Boot, as there are several source files and several board configurations.
Also, there are several tool chains being used.
You provide NONE of that *essential* information.
Works:
static struct __attribute__ ((__packed__)) eeprom {
Doesn't work:
struct __attribute__ ((__packed__)) eeprom {
Everything else is the same.
What is "same"? Which source file is this? Which line? Which board? Which compiler from which distro? Which binutils?
Best regards,
Wolfgang Denk

Wolfgang Denk wrote:
In message 485AC5C5.5080709@freescale.com you wrote:
I did say that. Simply making the global variable not static caused it to fail.
Ummm... I guess there must be more than one variable in U-Boot, as there are several source files and several board configurations.
Sorry, I was under the assumption that the problem is not unique to the actual variable in question. That is, making any global variable non-static risks having relocation fail.
I was looking for a more general explanation to the problem. I was hoping that someone who understood the relocation code well could explain to me, in theoretical terms, how this could happen.
What is "same"? Which source file is this? Which line? Which board? Which compiler from which distro? Which binutils?
This is a new file that I haven't posted yet. It is a replacement for board/freescale/common/sys_eeprom.c. It's currently undergoing internal review. That's why I asked for a general explanation.
Compiler: powerpc-linux-gnu-gcc (GCC) 4.2.1 Binutils: GNU ld (GNU Binutils) 2.18.50.20070820

In message 485ACBD4.8030608@freescale.com you wrote:
Sorry, I was under the assumption that the problem is not unique to the actual variable in question. That is, making any global variable non-static risks having relocation fail.
Hm...as you will notice, there are many global vaiables being used without problems, so I don't easily buy such a very general statement.
I was looking for a more general explanation to the problem. I was hoping that
How about analyzing your specific problem instead of assuming that it is a general problem?
Did you, for example, try changing another static variable in another source file for another, known to be working board, and observe the same problem?
Or why exactly do you assume it is a general problem?
This is a new file that I haven't posted yet. It is a replacement for
Ah. So there is a chance that it's just bugs in your new code?
That's why I asked for a general explanation.
Sounds unreasonable to me.
Compiler: powerpc-linux-gnu-gcc (GCC) 4.2.1 Binutils: GNU ld (GNU Binutils) 2.18.50.20070820
Hm... did you try another, maybe less recent, toolchain, with the same results?
Best regards,
Wolfgang Denk

Timur Tabi wrote:
Wolfgang Denk wrote:
You don't seriously expect any real help given such a vague description? It would be somewhat helpful if you said exactly which changes cause the code to work or fail...
I did say that. Simply making the global variable not static caused it to fail.
Works:
static struct __attribute__ ((__packed__)) eeprom {
Doesn't work:
struct __attribute__ ((__packed__)) eeprom {
Everything else is the same.
Hi Timur,
That isn't a variable, that is the first line of a struct declaration. You cut some pretty important information: what the struct is, the actual variable in question, and whether it is initialized.
I'm guessing from the name "eeprom" that you have a non-zero initializer on it??? Does it make a difference if it is uninitialized, initialized to {0}, or initialized to non-zero values?
Does it make a difference if it is packed or not (my guess: much less likely than initialization to cause works/broken).
Best regards, gvb

Jerry Van Baren wrote:
That isn't a variable, that is the first line of a struct declaration.
I didn't include this part (although since the code compiles, it should be obvious that it exists):
} e;
So I'm defining a global variable called 'e'. Perhaps the short name is part of the problem.
You cut some pretty important information: what the struct is, the actual variable in question, and whether it is initialized.
As Wolfgang pointed out, my assumption that this is a generic problem is flawed, and it's most likely a problem with my specific implementation.
I'm guessing from the name "eeprom" that you have a non-zero initializer on it???
No, no initializer.
Does it make a difference if it is uninitialized, initialized to {0}, or initialized to non-zero values?
I don't know, I haven't considered it.
I did notice this code in fsl_i2c.c:
#ifdef CFG_SPD_BUS_NUM static unsigned int i2c_bus_num __attribute__ ((section ("data"))) = CFG_SPD_BUS_NUM; #else static unsigned int i2c_bus_num __attribute__ ((section ("data"))) = 0; #endif
I wrote this code, but I don't remember why I added the "__attribute__ ((section ("data")))". I guess I should have commented it, but I wonder if it applies to my current problem.
Does it make a difference if it is packed or not (my guess: much less likely than initialization to cause works/broken).
It needs to be packed, otherwise the code won't work. Sadly, someone defined a 4-byte integer at address 0x72 in the EEPROM.
When I post the full patch, I'll revisit this problem. Sorry for all the noise.

In message 485BC2E5.8040101@freescale.com you wrote:
I did notice this code in fsl_i2c.c:
#ifdef CFG_SPD_BUS_NUM static unsigned int i2c_bus_num __attribute__ ((section ("data"))) = CFG_SPD_BUS_NUM; #else static unsigned int i2c_bus_num __attribute__ ((section ("data"))) = 0; #endif
I wrote this code, but I don't remember why I added the "__attribute__ ((section ("data")))". I guess I should have commented it, but I wonder if it applies to my current problem.
Most probably you reference these variables before the bss has been set up and initialized, i. e. before relocation to RAM, and you wanted to make sure that they are really initialized with zero.
Best regards,
Wolfgang Denk

Timur Tabi wrote:
Jerry Van Baren wrote:
[snip]
I'm guessing from the name "eeprom" that you have a non-zero initializer on it???
No, no initializer.
Does it make a difference if it is uninitialized, initialized to {0}, or initialized to non-zero values?
I don't know, I haven't considered it.
I did notice this code in fsl_i2c.c:
#ifdef CFG_SPD_BUS_NUM static unsigned int i2c_bus_num __attribute__ ((section ("data"))) = CFG_SPD_BUS_NUM; #else static unsigned int i2c_bus_num __attribute__ ((section ("data"))) = 0; #endif
I wrote this code, but I don't remember why I added the "__attribute__ ((section ("data")))". I guess I should have commented it, but I wonder if it applies to my current problem.
It doesn't apply in the original complaint and may be flat out wrong, but I recall having a problem forcing a zero initializer into the data section. Gcc insisted on putting it in bss and, after playing language lawyer with the gcc manual/descriptions/etc, I concluded it was expected behavior of gcc.
[snip]
When I post the full patch, I'll revisit this problem. Sorry for all the noise.
Interesting quirk. We may give you a hard time, but that just betrays our curiosity. ;-)
Best regards, gvb
participants (3)
-
Jerry Van Baren
-
Timur Tabi
-
Wolfgang Denk