2016年1月28日 星期四

linker script symbol type R_386_16, R_386_32

the 1st edition: 20120316
the 2nd edition: 20160128

之前寫在 linker script 裡的變數

__bss_start__ =.;
.bss :
{
*(.bss)
}
__bss_end__ = .;

有 type 的區別。

當我使用 32 bit 暫存器時

# init bss
init_bss_asm:
movl $__bss_end__, %edi    /* Destination */
movl $__bss_start__, %esi   /* Source */
jmp 2f
1:
movl %esi, %eax
movb $0x0, (%eax)
addl $1, %esi

2:
cmpl %edi, %esi
jne 1b
ret

objdump -x p_kernel.o

000000a4 R_386_32          __bss_end__
000000a9 R_386_32          __bss_start__



而使用 16 bit 暫存器時

init_bss_asm:
movw $__bss_end__, %di    /* Destination */
movw $__bss_start__, %si   /* Source */
#  movw $0x0, %ax
#  movw %ax, %gs
jmp 2f
1:
movw %si, %ax
movb $0x0, (%eax)
#  movb $0x1, (%eax)
#  movb $0x1, %ds:(%eax)
add $1, %si

2:
cmpw %di, %si
jne 1b
ret

objdump -x p_kernel.o

000000a4 R_386_16          __bss_end__
000000a9 R_386_16          __bss_start__

遇到一個這樣的問題:
當我在 C 語言用了
u8 task_stack[0x9000];
這麼大的變數 (存放在 .bss section)

然後照樣 make 我的 kernel, 結果竟然跳出來令我傻眼的錯誤訊息:

descent@ubuntu:simple_os$ make p_kernel.elf 
as -o p_kernel.o p_kernel.s
gcc -std=c99 -fno-stack-protector -ffreestanding -fno-builtin -g -c process.c
ld -nostdlib -M -g -o p_kernel.elf -Tk.ld p_kernel.o start.o process.o > p_kernel.elf.map
p_kernel.o: In function `init_bss_asm':
(.text+0xa5): relocation truncated to fit: R_386_16 against symbol `__bss_end__' defined in *ABS* section in p_kernel.elf

媽呀!這是什麼意思阿!
亂想的過程不重要, 反正最後就是 type 不對, bss 無法超過某個值, google 很久, code 亂改了很久, 終於被我猜到是這個問題。

修改成用 32 bit register, 這兩個變數 __bss_end__, __bss_start__ 的 type 就變成 R_386_32, 我也可以加大我的 .bss section。

真的把我嚇壞了。



20160127 補充:

在 porting simple_stdcpplib 到 x86 16 bit 環境時, 我又遇到這問題了:

x86.ld
 1 ENTRY(begin)
 2 
 3 SECTIONS
 4 {
 5   . = 0x100;
 6 
 7   .text :
 8   {
 9     KEEP(*(booting))
10     KEEP(*(.isr_vector))
11     *(.text)
12     *(.text.*)
13     _etext = .;
14     _sidata = .;
15   } 
16 
17 
18   .= ALIGN(32);
19   .rodata :
20   {
21     *(.rodata)
22     *(.rodata.*)
23   }
24 
25   init_array : 
26   {
27     __start_global_ctor__ = .;
28     *(.init_array)
29     __end_global_ctor__ = .;
30     _sidata = .;
31   }
32 
33 
34 
35   /* Initialized data will initially be loaded in FLASH at the end of the .text section. */
36   /* .data : AT(0x5000) */
37   .data : 
38   {
39     _data = .;
40 
41     _sdata = .;
42     *(.ccm)
43 
44     *(.data)  /* Initialized data */
45     _edata = .;
46   } 
47 
48   .myheap (NOLOAD):
49   {
50     . = ALIGN(8);
51     *(.myheap)
52     . = ALIGN(8);
53   }
54 
55 /*
56   .sig : AT(0x7DFE)
57   {
58       SHORT(0xaa55);
59   }
60 */
61   .bss : 
62   {
63     _bss = .;
64     _sbss = .;
65     *(.bss)         /* Zero-filled run time allocate data memory */
66     _ebss = .;
67   } 
68   _estack = 0xa0000; /* 640k */
69 }  


l
 1 #arm-none-eabi-g++ -m32 -fno-common -g -DX86 -DX86_16 -I. -Ix86 -fno-exceptions -fno-rtti -ffreestanding -nostdlib -nodefaultlibs -std=c++11 -g -Wl,--build-id=none -Wl,-T./x86.ld -nostartfiles -o mymain.elf  mymain.o -L. -lmystdcpp -lgcc
 2 g++ -m32 -fno-common -g -DX86 -DX86_16 -I. -Ix86 -fno-exceptions -fno-rtti -ffreestanding -nostdlib -nodefaultlibs -std=c++11 -g -Wl,--build-id=none -Wl,-T./x86.ld -nostartfiles -o mymain.elf mymain.o -L. -lmystdcpp -lgcc
 3 ./libmystdcpp.a(mem.o): In function `print_memarea()':
 4 /media/work/git/jserv-course/simple_stdcpplib/mem.cpp:52:(.text+0x33): relocation truncated to fit: R_386_16 against symbol `free_index' defined in .bss section in ./libmystdcpp.a(mem.o)
 5 ./libmystdcpp.a(mem.o): In function `(anonymous namespace)::search_free_area(unsigned char)':
 6 /media/work/git/jserv-course/simple_stdcpplib/mem.cpp:124:(.text+0x27a): relocation truncated to fit: R_386_16 against symbol `free_index' defined in .bss section in ./libmystdcpp.a(mem.o)
 7 ./libmystdcpp.a(mem.o): In function `(anonymous namespace)::mymalloc_internal(unsigned char)':
 8 /media/work/git/jserv-course/simple_stdcpplib/mem.cpp:141:(.text+0x31d): relocation truncated to fit: R_386_16 against symbol `free_index' defined in .bss section in ./libmystdcpp.a(mem.o)
 9 /media/work/git/jserv-course/simple_stdcpplib/mem.cpp:147:(.text+0x35f): relocation truncated to fit: R_386_16 against symbol `free_index' defined in .bss section in ./libmystdcpp.a(mem.o)
10 /media/work/git/jserv-course/simple_stdcpplib/mem.cpp:151:(.text+0x372): relocation truncated to fit: R_386_16 against symbol `free_index' defined in .bss section in ./libmystdcpp.a(mem.o)
11 /media/work/git/jserv-course/simple_stdcpplib/mem.cpp:154:(.text+0x3a1): relocation truncated to fit: R_386_16 against symbol `free_index' defined in .bss section in ./libmystdcpp.a(mem.o)
12 /media/work/git/jserv-course/simple_stdcpplib/mem.cpp:156:(.text+0x3c9): relocation truncated to fit: R_386_16 against symbol `free_index' defined in .bss section in ./libmystdcpp.a(mem.o)
13 /media/work/git/jserv-course/simple_stdcpplib/mem.cpp:156:(.text+0x3d0): relocation truncated to fit: R_386_16 against symbol `free_index' defined in .bss section in ./libmystdcpp.a(mem.o)
14 ./libmystdcpp.a(mem.o): In function `myfree(void*)':
15 /media/work/git/jserv-course/simple_stdcpplib/mem.cpp:191:(.text+0x4c6): relocation truncated to fit: R_386_16 against symbol `free_index' defined in .bss section in ./libmystdcpp.a(mem.o)
16 /media/work/git/jserv-course/simple_stdcpplib/mem.cpp:194:(.text+0x4d0): relocation truncated to fit: R_386_16 against symbol `free_index' defined in .bss section in ./libmystdcpp.a(mem.o)
17 /media/work/git/jserv-course/simple_stdcpplib/mem.cpp:194:(.text+0x4e0): additional relocation overflows omitted from the output
18 collect2: error: ld returned 1 exit status
19 makefile:85: recipe for target 'mymain.elf' failed
20 make: *** [mymain.elf] Error 1

看起來是在 access .bss section 的時候, .bss type 是 r_386_16, 但是我不知道怎麼改動其 type 為 r_386_32, 最後修改 x86.ld, 讓 .bss 放在 .text 後面, 很不優雅的解決這問題。

modify x86.ld
 1 ENTRY(begin)
 2 
 3 SECTIONS
 4 {
 5   . = 0x100;
 6 
 7   .text :
 8   {
 9     KEEP(*(booting))
10     KEEP(*(.isr_vector))
11     *(.text)
12     *(.text.*)
13     _etext = .;
14     _sidata = .;
15   } 
16   .bss : 
17   {
18     _bss = .;
19     _sbss = .;
20     *(.bss)         /* Zero-filled run time allocate data memory */
21     _ebss = .;
22   } 
23 
24 
25   .= ALIGN(32);
26   .rodata :
27   {
28     *(.rodata)
29     *(.rodata.*)
30   }
31 
32   init_array : 
33   {
34     __start_global_ctor__ = .;
35     *(.init_array)
36     __end_global_ctor__ = .;
37     _sidata = .;
38   }
39 
40 
41 
42   /* Initialized data will initially be loaded in FLASH at the end of the .text section. */
43   /* .data : AT(0x5000) */
44   .data : 
45   {
46     _data = .;
47 
48     _sdata = .;
49     *(.ccm)
50 
51     *(.data)  /* Initialized data */
52     _edata = .;
53   } 
54 
55   .myheap (NOLOAD):
56   {
57     . = ALIGN(8);
58     *(.myheap)
59     . = ALIGN(8);
60   }
61 
62 /*
63   .sig : AT(0x7DFE)
64   {
65       SHORT(0xaa55);
66   }
67 */
68   _estack = 0xa0000; /* 640k */
69 }  

沒有留言:

張貼留言

使用 google 的 reCAPTCHA 驗證碼, 總算可以輕鬆留言了。

我實在受不了 spam 了, 又不想讓大家的眼睛花掉, 只好放棄匿名留言。這是沒辦法中的辦法了。留言的朋友需要有 google 帳號。