The following code
const char c0[128] = "";
const char c1[128] = "";
const char c2[128] = "";
const char c3[128] = "";
const char __at(256) h[3] = {0x55, 0xa, 0x55};
Compiled e.g with
sdcc -mz80 test.c --code-loc 0x0000
Results in both h and c2 placed at 0x100.
But the manual (3.5.5) states:
If however you provide an initializer actual memory allocation will take place and overlaps will be detected by
the linker.
Philipp
I'm afraid the linker only does that for mcs51 and hc08 and not for z80 or stm8.
So, on one hand, we could fix this bug by fixing the manual.
On the other hand, I wonder if there is ever a reasong to have overlapping variables from C code. So would it make sense to have all linkers avoid overlaps, and even when the variable is not initialized?
Philip
This stems from the time when we had several linkers and this was only implemented in the two mentioned. During merging AFAIK conditions were added to cover the differences. This should be fixed in the linker (and maybe the backends), not in the manual.
Currently, sdld puts all absolute addressed symbols in one ABS segment, and the generated .rel does not hold enough information about their space (data / xdata / code).
Maybe a .abs can be genrated along with the .rel, which holds some extra information. For example,
__xdata char __at(6) a;
char __at(9) b;
results a .abs like
a xdata 6
b data 9
Then the sdld parses each .abs file and prints errors if any conflict overlap is detected.
AFAIK this is not true. The difference between data / xdata / code is properly recorded for mcs51 in the .rel files for both RELative and ABSolute segments. And instead of all absolutes in one ABS segment I believe every absolute gets it's own segment.
But I don't think the z80 assembler accepts the CODE/DATA/XDATA/etc indicators. Now I guess z80 only needs CODE and DATA.
Another solution might be creating seperated COABS XDABS DABS than only one ABS. But both solutions need modification on both sdcc and sdld. I will figure out which one is easier to implement.
Please investigate first how this works for mcs51.
I tried the following test.c,
with
sdcc test.c -mhc08 --code-loc 0x0000
sdcc test.c -mmcs51 --code-loc 0x0000
but got no error.
Last edit: Ben Shi 2015-12-21
This will not produce an error because only h[] has an absolute address. And c0 to c3 and the function code will be placed around it.
Should sdcc/sdld support,
Or
Current I can not get any error from sdcc/sdld in both above ways on all ports. But I would endorse the first one.
The following code gives this error: memory overlap near 0x80 for CABS2
I am afraid there might be several issues around __at, first
the variable c is placed in the xdata place, even in --model-small, unless __data is specified.
Last edit: Ben Shi 2015-12-21
Sorry, the above c is in data, but
qq is in xdata even in model-small.
The second issue,
sdcc gave errors like,
b.asm:59: Error: <o> .org in REL area or directive / mnemonic error
b.asm:59: Error: </o>
The third issue,
sdcc detected the confict for mcs51 and hc08, but not stm8 and z80.
Last edit: Ben Shi 2015-12-21
I agree that all linkers should detect and avoid overlaps.
I can think of only two situations where overlapping variables might be OK, neither of which apply in this case:
When I run low on memory, as I often do with the sorts of systems SDCC targets, it helps when the compiler overlaps "
const" "variables" that contain exactly the same data bytes. I am happy for the compiler to place 4 identical strings c0, c1, c2, c3 overlapping exactly the same region of ROM, with that region containing a (final) 0x00 byte, especially when I specify "--opt-code-size". But it would be wrong to overlap that 0x00 byte with any of the non-zero bytes of the h[] array.When the user uses "
__at()" twice to manually place 2 variables at the same or overlapping locations. This is highly unusual. The compiler should detect and at least warn about it.With some CPUs, it may appear that 2 things are at the same numeric location, but they don't really overlap because they are in physically different memory spaces (2 spaces with Harvard architecture, 3 or more spaces with some DSPs and the 8051). The compiler must track which thing is in which space and emit the correct address-space-specific instruction sequence.