From: SourceForge.net <no...@so...> - 2007-11-21 10:32:35
|
Bugs item #1057171, was opened at 2004-10-30 06:27 Message generated for change (Comment added) made by patryks You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=100599&aid=1057171&group_id=599 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: linker Group: None Status: Open Resolution: None Priority: 5 Private: No Submitted By: Akiya ISHIDA (akiya-i) Assigned to: Nobody/Anonymous (nobody) Summary: Linker problem on multiple defined global variable Initial Comment: Attached source files, aa.c and bb.c, are intended to share global variables. I should put 'extern' keyword on ether one of the two, but I forgot. When I link two object modules into one executable, z80- linker doesn't say any error and assign different address to each of those global variables. If I put 'extern' on ether one, it's OK. ============ aa.c Page 1 char a,b; char c=10; void aa() { a = b + c; } void main() { void bb(); bb(); } ============ bb.c Page 1 char a,b,c; void bb() { c = a+ b; } ============ compile.sh Page 1 sdcc -mz80 -c aa.c sdcc -mz80 -c bb.c sdcc -mz80 -o xx aa.o bb.o ============ disassenble Page 1 aa: 0x020a 21 02 80 LD HL,#0x8002 <-- linker assiend different address from bb.o 0x020d d5 PUSH DE 0x020e fd 21 00 80 LD IY,#0x8000 <-- 0x0212 fd e5 PUSH IY 0x0214 d1 POP DE 0x0215 fd 21 01 80 LD IY,#0x8001 <-- 0x0219 fd 7e 00 LD A,(IY+#0) 0x021c 86 ADD A,(HL) 0x021d 12 LD (DE),A 0x021e d1 POP DE 0x021f c9 RET main: 0x0220 cd 24 02 CALL #0x0224 0x0223 c9 RET bb: 0x0224 21 04 80 LD HL,#0x8004 <-- 0x0227 d5 PUSH DE 0x0228 fd 21 05 80 LD IY,#0x8005 <-- 0x022c fd e5 PUSH IY 0x022e d1 POP DE 0x022f fd 21 03 80 LD IY,#0x8003 <-- 0x0233 fd 7e 00 LD A,(IY+#0) 0x0236 86 ADD A,(HL) 0x0237 12 LD (DE),A 0x0238 d1 POP DE 0x0239 c9 RET SDCC : mcs51/gbz80/z80/avr/ds390/pic16/pic14/ TININative/xa51/ds400/hc08 2.4.4 #849 (Sep 25 2004) (UNIX) ---------------------------------------------------------------------- Comment By: Patryk (patryks) Date: 2007-11-21 11:31 Message: Logged In: YES user_id=1788180 Originator: NO Maarten, "Your construction with uC.h and uC.c will no longer work if all sfr's are to become static automatically." I know, and I vote against it. My solution is more natural in C: global objects defined once and declared where needed. Static SFRs in every file: "private" in every module, but sharing space just as globals - it means mess in compiler/linker, asking for more troubles in the future. Is there any difference at all between __data __at (0x80) unsigned char P0; __bit __at (0x80) RI; and __sfr __at 0x80 P0; __sbit __at 0x98 RI; beside possibility of multi-definition of __sfr/__sbit in project? Of course there are between __sfr16/32 and unsigned int/long. The only disadvantage I see in my solution is the need to compile/link additional C module. If one rename C8051F347.h to C8051F347orig.h and uC.h/uC.c to C8051F347.h/C8051F347.c, then there are no other changes needed in other sources of the project. Compilers for other platforms tend to define registers with bit-fields (Frescale CodeWarrior for HC08, Texas Instruments TMS320, Atmel AVR32). CodeWarrior instantiates registers with additional C module (like in my solution), this way (also MCS51 "sfr" way) code is easier to debug - registers are valid symbols. Other solutions either drop instantiation to the user (TMS320) or use macros that cast address (literal) to pointer and dereference it (AVR32). "Function overriding is exactly as I would like it to be. I have no intention of changing that." I.e. no warning? Maybe warning that is off by default? "If the linker finds several definitions with the same name in the libraries it generates a warning I think, but I'm not sure." sdcc-doc-20070630-4871.zip, asmlnk.doc, page 2-3, 2.3 LIBRARY PATH(S) AND FILE(S) "Each library file contains a list (one file per line) of modules included in this particular library. Each existing object module is scanned for a match to the undefined symbol. The first module containing the symbol is then linked with the previous modules to resolve the symbol de- finition. The library object modules are rescanned until no more symbols can be resolved." Linker seems to be satisfied with first symbol found :-( Regards, Patryk ---------------------------------------------------------------------- Comment By: Maarten Brock (maartenbrock) Date: 2007-11-20 20:09 Message: Logged In: YES user_id=888171 Originator: NO Patryk, Your construction with uC.h and uC.c will no longer work if all sfr's are to become static automatically. Function overriding is exactly as I would like it to be. I have no intention of changing that. If the linker finds several definitions with the same name in the libraries it generates a warning I think, but I'm not sure. Maarten ---------------------------------------------------------------------- Comment By: Patryk (patryks) Date: 2007-11-20 09:58 Message: Logged In: YES user_id=1788180 Originator: NO Previous post was main and I was logged in! ---------------------------------------------------------------------- Comment By: Nobody/Anonymous (nobody) Date: 2007-11-20 09:12 Message: Logged In: NO "In order to fix this I would like to remove the address check and never accept multiple definitions." Yes, this is how it should be: no chance to mess something by accidentally choosing same names for different functions/variables. BTW: library functions/variables (putchar(), strcpy(), atoi(), errno etc.) may be override by simply defining function with same name. One can really mess with unhappily choosen name. Shouldn't be there some warning? Also: is it assured somehow, that all symbols defined in library/libraries got unique name? I mean assured by librarian (linker?), not by developer(s). ---------------------------------------------------------------------- Comment By: Patryk (patryks) Date: 2007-11-20 09:08 Message: Logged In: YES user_id=1788180 Originator: NO "In order to fix this I would like to remove the address check and never accept multiple definitions." Yes, this is how it should be: no chance to mess something by accidentally choosing same names for different functions/variables. BTW: library functions/variables (putchar(), strcpy(), atoi(), errno etc.) may be override by simply defining function with same name. One can really mess with unhappily choosen name. Shouldn't be there some warning? Also: is it assured somehow, that all symbols defined in library/libraries got unique name? I mean assured by librarian (linker?), not by developer(s). ---------------------------------------------------------------------- Comment By: Patryk (patryks) Date: 2007-11-20 08:41 Message: Logged In: YES user_id=1788180 Originator: NO I didn't like SFRs to be defined (i.e. instantiated) in (almost) every source file. Beside 'extern' things requiring some non-standard linker behaviour for SFRs, they made asm/lst files less readable: many pages at begin (in every file) wasted for common definitions. Instead I have wrapped header for given uC in "uC.h" containing declarations, and defined (instantiated) them in accompanying source "uC.c": uC.h //============================================================================ #ifndef UC_H #define UC_H #ifndef UC_C #define __sfr extern __sfr #define __sfr16 extern __sfr16 #define __sfr32 extern __sfr32 #define __sbit extern __sbit #endif #include "C8051F347.h" #ifndef UC_C #undef __sfr #undef __sfr16 #undef __sfr32 #undef __sbit #endif #endif // UC_H //============================================================================ uC.c //============================================================================ #define UC_C #include "uC.h" #undef UC_C //============================================================================ ---------------------------------------------------------------------- Comment By: Maarten Brock (maartenbrock) Date: 2007-11-19 16:34 Message: Logged In: YES user_id=888171 Originator: NO It appears to be a matter of chance. If you happen to define the variables in the same order, they get the same relative address. And when they have the same address the linker accepts the multiple definitions. I think this was done to accept sfr definitions. In order to fix this I would like to remove the address check and never accept multiple definitions. This requires sfr/sbit to become static automatically (does not apply to pic/pic16). Any comments / objections are welcome. Otherwise I will commit this later this week. ---------------------------------------------------------------------- Comment By: Maarten Brock (maartenbrock) Date: 2007-11-15 21:24 Message: Logged In: YES user_id=888171 Originator: NO I just looked at this and it is not restricted to the z80 linker. The mcs51 has the same problem. When a variable is defined more than once but in different modules it is treated as if the definitions were static. ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=100599&aid=1057171&group_id=599 |