Discussion:
x64 address indexed by 32-bit address
(too old to reply)
Paul Edwards
2024-01-19 13:42:14 UTC
Permalink
Hi.

I am using a slightly modified GCC 3.2.3
to generate x64 code, and using PDPCLIB
and running under Linux x64.

I don't trust either (my) PDPCLIB or my
modified GCC 3.2.3

Assuming PDPCLIB is behaving correctly,
it is showing that the stack is above
4 GiB. It seems to be a 48-bit address.

The executable appears to be loaded in
low memory - way below 2 GiB.

***@kerravon-pc:~/scratch/eee/pdos/pdpclib$ ./pdptest ab def
welcome to pdptest
main function is at 00401334
allocating 10 bytes
m1 is 004087A8
allocating 20 bytes
m2 is 00408828
stack is around 7FFC36A1053C
printing arguments
argc = 3
arg 0 is <./pdptest>
arg 1 is <ab>
arg 2 is <def>
***@kerravon-pc:~/scratch/eee/pdos/pdpclib$


Now I have this code:

printf("argv[0] is %p %s\n", argv[0], argv[0]);
printf("len is %d\n", (int)strlen(argv[0]));
p = argv[0] + strlen (argv[0]);
printf("p is %p\n", p);
printf("p as string is %s\n", p);
printf("p current is %x\n", p[0]);
printf("as negative is %x\n", p[-1]);


which is generating (for that last line):

LM1873:
movl $4294967295, %eax
addq -64(%rbp), %rax
movsbl (%rax),%esi
movl $LC445, %edi
movb $0, %al
call _printf

That first instruction - the movl - has
negative 1 as an unsigned value. I tried
manually changing the generated assembler
to $-1 but the result appears to be the
same (I may have stuffed up the test).

And it crashes:

***@kerravon-pc:~/scratch/eee/gcc/gcc$ ./gcc-new.exe
argv[0] is 7FFC8DC50294 ./gcc-new.exe
len is 13
p is 7FFC8DC502A1
p as string is
p current is 0
Segmentation fault (core dumped)
***@kerravon-pc:~/scratch/eee/gcc/gcc$


I suspect what is happening is that it is
adding the entire value of eax as an unsigned
32-bit value to the 64-bit address and so the
address is being offset by nearly 4 GiB
instead of being offset by 1 byte.

GCC 3.2.3 was used to build systems I believe,
so it "must" work in some circumstances.

Any idea how this was meant to work?

Thanks. Paul.
Paul Edwards
2024-02-13 06:17:18 UTC
Permalink
Post by Paul Edwards
movl $4294967295, %eax
addq -64(%rbp), %rax
movsbl (%rax),%esi
movl $LC445, %edi
movb $0, %al
call _printf
This has now been resolved. I wasn't building my
modified gcc 3.2.3 properly, so it thought that
size_t was 32 bits instead of 64 and was making
it unsigned.

Now I am getting working code:

D:\devel\gcc\gcc>type foo.s
.file "foo.c"
.text
.p2align 2,,3
.globl foo
foo:
.LFB1:
movsbl -1(%rcx),%eax
ret
.LFE1:

D:\devel\gcc\gcc>


(rcx is because one of my modifications is to use
Win64 function call convention)

BFN. Paul.

Loading...