Linker generating misaligned addresses?
Posted: Sun Jul 31, 2011 4:17 pm
Hey guys,
I've been spending the better part of an afternoon wrestling with my hobby kernel, and I've somehow created a bug that I can't really get my head around. I'm hoping someone on here might be able to lend a missing piece of insight.
Basically, out of nowhere, it seems my compiler or linker is giving out addresses for my string constants that are 3 bytes too high. I'm using gcc and ld, and it looks like they take all of your string constants and put them in a pool in memory and then assign the pointers in your code addresses for the various strings' locations in the pool. This all makes sense to me, but for some reason, the addresses appear to be off, because every string I point out is missing its first 3 characters.
For example, this is an objdump of my function console_init( ):
char* test_string = "ABCDEFGHIJKLMNOP";
void console_init() {
c01094e1: 55 push %ebp
c01094e2: 89 e5 mov %esp,%ebp
c01094e4: 83 ec 04 sub $0x4,%esp
blank_screen();
c01094e7: e8 84 fd ff ff call c0109270 <blank_screen>
update_cursor();
c01094ec: e8 18 fe ff ff call c0109309 <update_cursor>
print_line(test_string);
c01094f1: a1 08 10 11 c0 mov 0xc0111008,%eax
c01094f6: 89 04 24 mov %eax,(%esp)
c01094f9: e8 c4 ff ff ff call c01094c2 <print_line>
}
c01094fe: c9 leave
c01094ff: c3 ret
Now, over in GDB, I look up 0xc0111008 and it's holding what should be the address to the string "ABCDEFGHIJKLMNOP" but instead it's got the address to "DEF..." See my gdb session here:
[bochs]:
0xc0111008 <bogus+ 0>: 3
<bochs:10> x /1xw 0xc0111008
[bochs]:
0xc0111008 <bogus+ 0>: 0xc010a633
<bochs:11> x /20cb 0xc010a633
[bochs]:
0xc010a633 <bogus+ 0>: D E F G H I J K
0xc010a63b <bogus+ 8>: L M N O P \0 f r
0xc010a643 <bogus+ 16>: a m e
But the value at 0xc0111008 should not be 0xc010a633 but instead 0c010a630, as that's where the string really starts
<bochs:12> x /20cb 0xc010a630
[bochs]:
0xc010a630 <bogus+ 0>: A B C D E F G H
0xc010a638 <bogus+ 8>: I J K L M N O P
0xc010a640 <bogus+ 16>: \0 f r a
I honestly don't know how I've done this to myself. Has anyone run into this before? Ideas to try?
I've been spending the better part of an afternoon wrestling with my hobby kernel, and I've somehow created a bug that I can't really get my head around. I'm hoping someone on here might be able to lend a missing piece of insight.
Basically, out of nowhere, it seems my compiler or linker is giving out addresses for my string constants that are 3 bytes too high. I'm using gcc and ld, and it looks like they take all of your string constants and put them in a pool in memory and then assign the pointers in your code addresses for the various strings' locations in the pool. This all makes sense to me, but for some reason, the addresses appear to be off, because every string I point out is missing its first 3 characters.
For example, this is an objdump of my function console_init( ):
char* test_string = "ABCDEFGHIJKLMNOP";
void console_init() {
c01094e1: 55 push %ebp
c01094e2: 89 e5 mov %esp,%ebp
c01094e4: 83 ec 04 sub $0x4,%esp
blank_screen();
c01094e7: e8 84 fd ff ff call c0109270 <blank_screen>
update_cursor();
c01094ec: e8 18 fe ff ff call c0109309 <update_cursor>
print_line(test_string);
c01094f1: a1 08 10 11 c0 mov 0xc0111008,%eax
c01094f6: 89 04 24 mov %eax,(%esp)
c01094f9: e8 c4 ff ff ff call c01094c2 <print_line>
}
c01094fe: c9 leave
c01094ff: c3 ret
Now, over in GDB, I look up 0xc0111008 and it's holding what should be the address to the string "ABCDEFGHIJKLMNOP" but instead it's got the address to "DEF..." See my gdb session here:
[bochs]:
0xc0111008 <bogus+ 0>: 3
<bochs:10> x /1xw 0xc0111008
[bochs]:
0xc0111008 <bogus+ 0>: 0xc010a633
<bochs:11> x /20cb 0xc010a633
[bochs]:
0xc010a633 <bogus+ 0>: D E F G H I J K
0xc010a63b <bogus+ 8>: L M N O P \0 f r
0xc010a643 <bogus+ 16>: a m e
But the value at 0xc0111008 should not be 0xc010a633 but instead 0c010a630, as that's where the string really starts
<bochs:12> x /20cb 0xc010a630
[bochs]:
0xc010a630 <bogus+ 0>: A B C D E F G H
0xc010a638 <bogus+ 8>: I J K L M N O P
0xc010a640 <bogus+ 16>: \0 f r a
I honestly don't know how I've done this to myself. Has anyone run into this before? Ideas to try?