I'm trying to write a bootloader in c and I noticed that string literals only worked if I passed them as a char *.
If it Could help:
when I converted both versions to assembly I found one difference that was only in the working version which is
mov DWORD PTR -8[ebp], eax
push DWORD PTR -8[ebp]
just before calling puts
Here's my code :
asm("jmp main");
void putc(char c) {
asm volatile("mov %%al, %0" :: "a"(c));
asm volatile("mov %ah, 0x0e");
asm volatile("int 0x10");
}
void puts(const char *s) {
while(*s) putc(*s++);
}
void newl() {
char s[] = { 0x0D, 0x0A, 0 };
puts(s);
}
void clear() {
asm volatile("mov ah, 0");
asm volatile("mov al, 0x3");
asm volatile("int 0x10");
}
void __attribute__((optimize("-O0"))) main() {
clear();
char * a = "Hello World";
puts(a); // WORKS
puts("Hello World"); // DOESN'T WORK (DOES NOT WRITE ANYTHING)
newl();
}
LD.LD :
ENTRY(main)
SECTIONS
{
. = 0x7C00;
.text : AT(0x7C00)
{
*(.text);
}
.sig : AT(0x7C00 + 510)
{
SHORT(0xaa55);
}
/DISCARD/ : {
*(.comment)
*(.eh_frame)
}
}
How I compiled:
gcc -m16 -c -ffreestanding -fno-pie -fno-exceptions -masm=intel -s -Os -static -Wall -ffunction-sections -fdata-sections main.cpp -o main.o
ld -m elf_i386 -o main.elf -T ld.ld main.o
objcopy -O binary main.elf main.bin
and I ran it with : qemu-system-x86_64 -fda main.bin
with char * a = "Hello World"; puts(a); :
objdump -h:
Idx Name Size VMA LMA File off Algn
0 .text 00000003 00000000 00000000 00000034 2**0
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
1 .data 00000000 00000000 00000000 00000037 2**0
CONTENTS, ALLOC, LOAD, DATA
2 .bss 00000000 00000000 00000000 00000037 2**0
ALLOC
3 .rodata 0000000c 00000000 00000000 00000037 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
4 .text.main 00000051 00000000 00000000 00000043 2**0
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
5 .text.putc 00000014 00000000 00000000 00000094 2**0
CONTENTS, ALLOC, LOAD, READONLY, CODE
6 .text.puts 0000002f 00000000 00000000 000000a8 2**0
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
7 .text.newl 00000029 00000000 00000000 000000d7 2**0
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
8 .text.clear 00000008 00000000 00000000 00000100 2**0
CONTENTS, ALLOC, LOAD, READONLY, CODE
9 .comment 0000001f 00000000 00000000 00000108 2**0
CONTENTS, READONLY
10 .note.GNU-stack 00000000 00000000 00000000 00000127 2**0
CONTENTS, READONLY
11 .eh_frame 000000b8 00000000 00000000 00000128 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA
with puts("Hello World");:
objdump -h:
Idx Name Size VMA LMA File off Algn
0 .text 00000003 00000000 00000000 00000034 2**0
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
1 .data 00000000 00000000 00000000 00000037 2**0
CONTENTS, ALLOC, LOAD, DATA
2 .bss 00000000 00000000 00000000 00000037 2**0
ALLOC
3 .rodata 0000000c 00000000 00000000 00000037 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
4 .text.main 00000047 00000000 00000000 00000043 2**0
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
5 .text.putc 00000014 00000000 00000000 0000008a 2**0
CONTENTS, ALLOC, LOAD, READONLY, CODE
6 .text.puts 0000002f 00000000 00000000 0000009e 2**0
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
7 .text.newl 00000029 00000000 00000000 000000cd 2**0
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
8 .text.clear 00000008 00000000 00000000 000000f6 2**0
CONTENTS, ALLOC, LOAD, READONLY, CODE
9 .comment 0000001f 00000000 00000000 000000fe 2**0
CONTENTS, READONLY
10 .note.GNU-stack 00000000 00000000 00000000 0000011d 2**0
CONTENTS, READONLY
11 .eh_frame 000000b8 00000000 00000000 00000120 2**2
CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA
Related
I am using the openwifi project and I am trying to extract data out of the FPGA (Zedboard) to the ZYNQ. Therefore, I added a AXI DMA in scatter gather mode to my block diagram with the following configuration:
The addresses are:
As far as I know, everything should be correctly configured and connected in Vivado. Because of the additional AXI DMA, I had to add it to the linux device tree:
dma#80420000 {
#dma-cells = <0x01>;
clock-names = "s_axi_lite_aclk\0m_axi_sg_aclk\0m_axi_mm2s_aclk\0m_axi_s2mm_aclk";
clocks = <0x02 0x11 0x02 0x11 0x02 0x11 0x02 0x11>;
compatible = "xlnx,axi-dma-1.00.a";
interrupt-names = "mm2s_introut\0s2mm_introut";
interrupt-parent = <0x01>;
interrupts = <0x00 0x27 0x04 0x00 0x28 0x04>;
reg = <0x80420000 0x10000>;
xlnx,addrwidth = <0x20>;
xlnx,include-sg ;
xlnx,sg-length-width = <0x0e>;
phandle = <0x0c>;
dma-channel#80420000 {
compatible = "xlnx,axi-dma-mm2s-channel";
dma-channels = <0x1>;
interrupts = <0x00 0x44 0x04>;
xlnx,datawidth = <0x40>;
xlnx,device-id = <0x2>;
};
dma-channel#80420030 {
compatible = "xlnx,axi-dma-s2mm-channel";
dma-channels = <0x1>;
interrupts = <0x00 0x45 0x04>;
xlnx,datawidth = <0x40>;
xlnx,device-id = <0x2>;
};
};
2 AXI DMAs were already configured by openwifi (dma#80410000 & dma#80400000). The complete modified device-tree can be found here. The original tree by openwifi is here (Due to the length I can't post it on SO).
My problem is that when I am trying to load the xilinx_dma driver into linux, I get the following error:
Unhandled fault: imprecise external abort (0x406) at 0xb6f38000
pgd = df614000
[b6f38000] *pgd=1627f831, *pte=1ece359f, *ppte=1ece3e7e
Internal error: : 406 [#1] PREEMPT SMP ARM
Modules linked in: xilinx_dma(+) ad9361_drv mac80211 cfg80211 ipv6
CPU: 0 PID: 2093 Comm: insmod Not tainted 4.14.0-gb6e379910a11-dirty #2
Hardware name: Xilinx Zynq Platform
task: df7ff280 task.stack: d622c000
PC is at xilinx_dma_chan_reset+0x58/0x27c [xilinx_dma]
LR is at xilinx_dma_chan_reset+0x44/0x27c [xilinx_dma]
pc : [<bf17d600>] lr : [<bf17d5ec>] psr: 60060013
sp : d622dce0 ip : 00000000 fp : 00000001
r10: dfbb5094 r9 : 00000000 r8 : 00000000
r7 : 00000000 r6 : 00000000 r5 : 00000000 r4 : df493410
r3 : dec0de1c r2 : 00000000 r1 : dfb89374 r0 : 00000058
Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment none
Control: 18c5387d Table: 1f61404a DAC: 00000051
Process insmod (pid: 2093, stack limit = 0xd622c210)
Stack: (0xd622dce0 to 0xd622e000)
dce0: df493410 d6023010 00000000 00000000 00000000 00000000 dfbb5094 bf17dff4
dd00: bf180dc0 df493410 bf180ca0 bf180cb4 014080c0 d6023018 d6023020 dfbb4d78
dd20: df572610 00000000 bf180c70 bf180c80 df576a50 cf73edc0 00000020 0000000e
dd40: 00000001 00000040 00000001 df572610 ffffffed bf182014 fffffdfb 00000000
dd60: 00000000 00000007 00000028 c03b2a20 df572610 c0c79fa8 c0c79fac bf182014
dd80: 00000000 c03b1240 df572610 bf182014 df572644 00000000 cf73d924 00000001
dda0: 00000000 c03b1394 00000000 bf182014 c03b12f0 c03af7a0 df491f58 df570ab4
ddc0: bf182014 d6ae7000 c0c1f458 c03b07a0 bf1810f8 00000000 bf185000 bf182014
dde0: 00000000 bf185000 d4b80600 c03b1c3c ffffe000 00000000 bf185000 c0101a20
de00: 00000000 00000000 c0c54234 c0c54220 c0994394 00000000 014000c0 e30a4000
de20: dfda5600 c0c54380 00000000 0000f730 c0c54380 c01af084 00000001 a0030013
de40: d4b80600 e3057000 bf1820c0 00000001 cf73d900 d4b80600 cf73d924 c018895c
de60: bf1820c0 cf73d924 00000001 d622df50 00000001 cf73d900 bf1820c0 c01875f0
de80: bf1820cc 00007fff bf1820c0 c0184b7c bf182108 00000000 bf1821c0 c0805304
dea0: bf1821f0 c0a0d880 bf18227c bf1821d4 c0998804 00000000 bf181104 bf000001
dec0: 0004bad4 00000000 d622df48 bf180024 00000001 00000000 00000000 00000000
dee0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
df00: 00000000 00000000 7fffffff 00000000 00000003 0046e398 0000017b c0107b24
df20: d622c000 00000000 00000000 c0188008 7fffffff 00000000 00000003 00000000
df40: 00000000 e3057000 0004bad4 00000000 e305c1b7 e3057000 0004bad4 e30a223c
df60: e30a2020 e308d180 00008000 00008310 00000000 00000000 00000000 00002bb0
df80: 00000034 00000035 00000020 0000001b 00000018 00000000 be8646c4 be864844
dfa0: 45194a00 c0107960 be8646c4 be864844 00000003 0046e398 00000000 00000000
dfc0: be8646c4 be864844 45194a00 0000017b 0047adc8 00000000 0046ab60 00000000
dfe0: be864670 be864660 00465177 b6f312b2 80030030 00000003 00000000 00000000
[<bf17d600>] (xilinx_dma_chan_reset [xilinx_dma]) from [<bf17dff4>] (xilinx_dma_probe+0x424/0xb04 [xilinx_dma])
[<bf17dff4>] (xilinx_dma_probe [xilinx_dma]) from [<c03b2a20>] (platform_drv_probe+0x50/0xac)
[<c03b2a20>] (platform_drv_probe) from [<c03b1240>] (driver_probe_device+0x238/0x2e8)
[<c03b1240>] (driver_probe_device) from [<c03b1394>] (__driver_attach+0xa4/0xa8)
[<c03b1394>] (__driver_attach) from [<c03af7a0>] (bus_for_each_dev+0x4c/0x9c)
[<c03af7a0>] (bus_for_each_dev) from [<c03b07a0>] (bus_add_driver+0x188/0x20c)
[<c03b07a0>] (bus_add_driver) from [<c03b1c3c>] (driver_register+0x78/0xf4)
[<c03b1c3c>] (driver_register) from [<c0101a20>] (do_one_initcall+0x44/0x168)
[<c0101a20>] (do_one_initcall) from [<c018895c>] (do_init_module+0x60/0x1f0)
[<c018895c>] (do_init_module) from [<c01875f0>] (load_module+0x1b8c/0x23a0)
[<c01875f0>] (load_module) from [<c0188008>] (SyS_finit_module+0x9c/0xb4)
[<c0188008>] (SyS_finit_module) from [<c0107960>] (ret_fast_syscall+0x0/0x48)
Code: e5933000 e0833005 e5933000 f57ff04f (e5943000)
---[ end trace e3cdb0330d71dd39 ]---
I identified that the error occurs in this function inside xilinx_dma.c:
/* IO accessors */
static inline u32 dma_read(struct xilinx_dma_chan *chan, u32 reg)
{
return ioread32(chan->xdev->regs + reg); // Here
}
So the ioread32 doesn't work. My question is: Why is this and what can I do about it?
If I remove the new AXI DMA from the device tree or change its compatible property to something random it works fine. So I suppose something has to be wrongly configured in the AXI DMA I added.
I have tried a simple linker script in MinGW using the following commands
gcc -Wall -c boot.c
ld boot.o -o boot.exe -T linker.ld
boot.c contains
int my_main(void){
return 0x1000;
}
linker.ld contains
ENTRY(my_main)
SECTIONS
{
.text : { *(.text) }
.data : { *(.data) }
.bss : { *(.bss) }
}
the linker output is warning warning: cannot find entry symbol my_main; defaulting to 00000000
and the virtual addresses of the sections are weird values:
C:\src>objdump -h boot.exe
boot.exe: file format pei-i386
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 0000000c 00000000 00000000 00000200 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .rdata 00000024 00001000 00001000 00000400 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
2 .eh_fram 00000038 00002000 00002000 00000600 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
and when i try to execute it, windows says "This app can't run in your PC"
I'm using the below code for reading bits/bytes in a structure.
Each line is printed in two different methods when DEBUG is 1, else it uses only one method.
Code:
#include <stdio.h>
#define DEBUG 0
typedef struct n{
int a;
int b;
int (*add)(struct n*, int,int);
int (*sub)(struct n*, int,int);
} num;
int add (num *st, int a, int b){}
int sub(num *st, int a, int b){}
int main(){
num* var = calloc(1,sizeof(num));
var->add = add;
var->sub = sub;
var->a = 13;
var->b = 53;
long int *byte = (long int*)var;
int i;
int j;
for(i=0;i<6;i++){
# if DEBUG == 1
for(j=0;j<64;j++){
printf("%d",( *(byte+i) & (1UL<<(63-j)) )?1:0 );
putchar( ((j+1)%8 == 0)?' ':'\0' );
}
putchar('\n');
# endif
printf("0x%06x %06x\n",(*(byte+i) >> 32), *(byte+i));
}
printf("\n0x%x\n",var->add);
printf("0x%x\n",var->sub);
}
Output 1: (DEBUG==1)
00000000 00000000 00000000 00110101 00000000 00000000 00000000 00001101
0x000035 00000d
00000000 00000000 00000000 00000000 00000000 01000000 00000111 01110000
0x000000 400770
00000000 00000000 00000000 00000000 00000000 01000000 00000111 01100000
0x000000 400760
00000000 00000000 00000000 00000000 00000000 00000010 00001111 11100001
0x000000 020fe1
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
0x000000 000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
0x000000 000000
0x400770
0x400760
Output 2: (DEBUG==0)
0x000000 000000
0x000000 000000
0x000000 000000
0x000000 020fe1
0x000000 000000
0x000000 000000
0x400640
0x400630
As you can see, everything except one line is blank in Output 2.
I'm just curious to know why this is happening.
Also enlighten me, if there's a better way to print bits/bytes.
Nb: I'm using an online compiler(onlinegdb.com) for testing
What you are printing here is address of functions.
printf("\n0x%x\n",var->add);
printf("0x%x\n",var->sub);
When you enable DEBUG.
# if DEBUG == 1
for(j=0;j<64;j++){
printf("%d",( *(byte+i) & (1UL<<(63-j)) )?1:0 );
putchar( ((j+1)%8 == 0)?' ':'\0' );
}
putchar('\n');
# endif
You are adding above code to your code segment.
Hence addresses of function(add and sub) inside code segment may change.
Note:: You are not following strict aliasing rule here.
long int *byte = (long int*)var;
This appears to be an issue with the compiler you are using, I don't see any specific reason why your code would return 0's. When your code is compiled with GCC and run the results are as follows:
Debug = 1
00000000 00000000 00000000 00001101 00000000 00000000 00000000 00001101
0x00000d 00000d
00000000 00000000 00000000 00110101 00000000 00000000 00000000 00110101
0x000035 000035
00000000 01000000 00010101 01100000 00000000 01000000 00010101 01100000
0x401560 401560
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
0x000000 000000
00000000 01000000 00010101 01110010 00000000 01000000 00010101 01110010
0x401572 401572
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
0x000000 000000
0x401560
0x401572
And Debug = 0:
0x00000d 00000d
0x000035 000035
0x401560 401560
0x000000 000000
0x401572 401572
0x000000 000000
0x401560
0x401572
I'd recommend getting GCC on your machine and compiling your code with -Wall. There are a handful of things in this code that make it hard to understand and could make for unpredictable behavior that -Wall will warn you about.
Among other things I am trying to understand the difference between OUTPUT_ARCH(arm) and OUTPUT_ARCH(armv4).
Assume we have next files (I have used linker script example from here as a basis):
main.c:
int main(void)
{
test_1();
test_2();
return 0;
}
main.lds:
OUTPUT_ARCH(arm)
SECTIONS
{
. = 0x10000;
.text : { *(.text) }
. = 0x8000000;
.data : { *(.data) }
.bss : { *(.bss) }
}
test_1.c:
void test_1(void)
{
return;
}
test_2.c:
void test_2(void)
{
return;
}
If we compile it and dump its content we have next:
c:\SysGCC\arm-elf\bin>arm-elf-gcc.exe test_1.c -c
c:\SysGCC\arm-elf\bin>arm-elf-gcc.exe test_2.c -c
c:\SysGCC\arm-elf\bin>arm-elf-objdump.exe -x test_1.o
test_1.o: file format elf32-littlearm
test_1.o
architecture: arm, flags 0x00000010:
HAS_SYMS
start address 0x00000000
private flags = 200: [APCS-32] [FPA float format] [software FP]
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 00000014 00000000 00000000 00000034 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .data 00000000 00000000 00000000 00000048 2**0
CONTENTS, ALLOC, LOAD, DATA
2 .bss 00000000 00000000 00000000 00000048 2**0
ALLOC
3 .comment 00000012 00000000 00000000 00000048 2**0
CONTENTS, READONLY
4 .ARM.attributes 00000010 00000000 00000000 0000005a 2**0
CONTENTS, READONLY
SYMBOL TABLE:
00000000 l df *ABS* 00000000 test_1.c
00000000 l d .text 00000000 .text
00000000 l d .data 00000000 .data
00000000 l d .bss 00000000 .bss
00000000 l d .comment 00000000 .comment
00000000 l d .ARM.attributes 00000000 .ARM.attributes
00000000 g F .text 00000014 test_1
c:\SysGCC\arm-elf\bin>arm-elf-gcc.exe -static -nostartfiles -T main.lds -o main.elf test_1.o test_2.o
c:\SysGCC\arm-elf\bin>arm-elf-objdump.exe -x main.elf
main.elf: file format elf32-littlearm
main.elf
architecture: arm, flags 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
start address 0x00010000
Program Header:
LOAD off 0x00008000 vaddr 0x00010000 paddr 0x00010000 align 2**15
filesz 0x00000028 memsz 0x00000028 flags r-x
private flags = 200: [APCS-32] [FPA float format] [software FP]
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 00000028 00010000 00010000 00008000 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .comment 00000011 00000000 00000000 00008028 2**0
CONTENTS, READONLY
2 .ARM.attributes 00000010 00000000 00000000 00008039 2**0
CONTENTS, READONLY
SYMBOL TABLE:
00010000 l d .text 00000000 .text
00000000 l d .comment 00000000 .comment
00000000 l d .ARM.attributes 00000000 .ARM.attributes
00000000 l df *ABS* 00000000 test_1.c
00000000 l df *ABS* 00000000 test_2.c
00010014 g F .text 00000014 test_2
00010000 g F .text 00000014 test_1
But if I change OUTPUT_ARCH(arm) to OUTPUT_ARCH(armv4), I get an error from linker:
c:\SysGCC\arm-elf\bin>arm-elf-gcc.exe -static -nostartfiles -T main.lds -o main.elf test_1.o test_2.o
c:/sysgcc/arm-elf/bin/../lib/gcc/arm-elf/4.6.3/../../../../arm-elf/bin/ld.exe: error: test_1.o uses software FP, whereas main.elf uses hardware FP
c:/sysgcc/arm-elf/bin/../lib/gcc/arm-elf/4.6.3/../../../../arm-elf/bin/ld.exe: failed to merge target specific data of file test_1.o
c:/sysgcc/arm-elf/bin/../lib/gcc/arm-elf/4.6.3/../../../../arm-elf/bin/ld.exe: error: test_2.o uses software FP, whereas main.elf uses hardware FP
c:/sysgcc/arm-elf/bin/../lib/gcc/arm-elf/4.6.3/../../../../arm-elf/bin/ld.exe: failed to merge target specific data of file test_2.o
collect2: ld returned 1 exit status
It can be fixed by specifying -mfloat-abi=hard option. In this case there is a difference in private flags comparing with previous output:
c:\SysGCC\arm-elf\bin>arm-elf-gcc.exe -mfloat-abi=hard test_1.c -c
c:\SysGCC\arm-elf\bin>arm-elf-gcc.exe -mfloat-abi=hard test_2.c -c
c:\SysGCC\arm-elf\bin>arm-elf-objdump.exe -x test_1.o
test_1.o: file format elf32-littlearm
test_1.o
architecture: arm, flags 0x00000010:
HAS_SYMS
start address 0x00000000
private flags = 0: [APCS-32] [FPA float format]
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 00000014 00000000 00000000 00000034 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .data 00000000 00000000 00000000 00000048 2**0
CONTENTS, ALLOC, LOAD, DATA
2 .bss 00000000 00000000 00000000 00000048 2**0
ALLOC
3 .comment 00000012 00000000 00000000 00000048 2**0
CONTENTS, READONLY
4 .ARM.attributes 00000010 00000000 00000000 0000005a 2**0
CONTENTS, READONLY
SYMBOL TABLE:
00000000 l df *ABS* 00000000 test_1.c
00000000 l d .text 00000000 .text
00000000 l d .data 00000000 .data
00000000 l d .bss 00000000 .bss
00000000 l d .comment 00000000 .comment
00000000 l d .ARM.attributes 00000000 .ARM.attributes
00000000 g F .text 00000014 test_1
c:\SysGCC\arm-elf\bin>arm-elf-gcc.exe -static -nostartfiles -T main.lds -o main.elf test_1.o test_2.o
c:\SysGCC\arm-elf\bin>arm-elf-objdump.exe -x main.elf
main.elf: file format elf32-littlearm
main.elf
architecture: arm, flags 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
start address 0x00010000
Program Header:
LOAD off 0x00008000 vaddr 0x00010000 paddr 0x00010000 align 2**15
filesz 0x00000028 memsz 0x00000028 flags r-x
private flags = 0: [APCS-32] [FPA float format]
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 00000028 00010000 00010000 00008000 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .comment 00000011 00000000 00000000 00008028 2**0
CONTENTS, READONLY
2 .ARM.attributes 00000010 00000000 00000000 00008039 2**0
CONTENTS, READONLY
SYMBOL TABLE:
00010000 l d .text 00000000 .text
00000000 l d .comment 00000000 .comment
00000000 l d .ARM.attributes 00000000 .ARM.attributes
00000000 l df *ABS* 00000000 test_1.c
00000000 l df *ABS* 00000000 test_2.c
00010014 g F .text 00000014 test_2
00010000 g F .text 00000014 test_1
Does it mean that OUTPUT_ARCH(armv4) causes linker to generate output solely for hard float?
In general, what is the difference between OUTPUT_ARCH(arm) and OUTPUT_ARCH(armv4)?
According to ld manual OUTPUT_ARCH() specifies a particular output machine architecture.
The argument is one of the names used by the BFD library.
But I have found no clear information about BFD library except general information.
I use arm-elf toolchain from here (Binutils 2.22, GCC 4.6.3, Newlib 1.2.0, GDB 7.4).
Thank you in advance for help.
UPDATE 1:
This update is a reply for the comment below.
Compiler -v output from old toolchain we use now:
Using built-in specs.
Target: arm-elf
Configured with: ../gcc-4.4.1/configure --target=arm-elf --host=i686-pc-mingw32 --with-cpu=xscale --without-stabs -nfp --prefix=/c/cross-gcc/4.4.1 --disable-nls --disable-shared --disable-__cxa_atexit
--enable-threads --with-gnu-gcc --with-gnu-ld --with-gnu-as --with-dwarf2 --enable-languages=c,c++ --enable-interwork --disable-multilib --with-gmp=/c/cross-gcc/4.4.1 --with-mpfr=/c/cross-gcc/4.4.1 -
-with-newlib --with-headers=../../newlib-1.17.0/newlib-1.17.0/newlib/libc/include --disable-libssp --disable-libstdcxx-pch --disable-libmudflap --disable-libgomp -v
Thread model: single
gcc version 4.4.1 (GCC)
Compiler -v output from newer toolchain I used in the examples (SysGCC arm-elf):
Using built-in specs.
COLLECT_GCC=arm-elf-gcc.exe
COLLECT_LTO_WRAPPER=c:/sysgcc/arm-elf/bin/../libexec/gcc/arm-elf/4.6.3/lto-wrapper.exe
Target: arm-elf
Configured with: ../gcc-4.6.3/configure --target arm-elf --enable-win32-registry=SysGCC-arm-elf-4.6.3 --prefix /c/gnu/auto/bu-2.22+gcc-4.6.3+gmp-4.2.4+mpfr-2.4.1+mpc-0.8+newlib-1.20.0-arm-elf/ --enabl
e-languages=c,c++ --disable-nls --with-newlib --with-headers=../newlib-1.20.0/newlib/libc/include --enable-interwork --enable-multilib --with-float=soft
Thread model: single
gcc version 4.6.3 (GCC)
There is no difference between linker output for OUTPUT_ARCH(arm) and OUTPUT_ARCH(armv4) for old compiler. I think I should have checked it before.
Seems that it is an answer to this question.
My goal is to use the combination -mfpu=vfpv3 -mfloat-abi=hard, but according to Debian documentation and GCC 4.4.7 manual this combination is not supported by GCC 4.4.
In fact if I try to compile with -mfpu=vfpv3 -mfloat-abi=hard by old compiler, it returns error:
sorry, unimplemented: -mfloat-abi=hard and VFP
Still and all it is possible to use -mfpu=vfpv3 -mfloat-abi=softfp with old compiler, but according to this comparison it gives big overhead for small routines.
What does this mean in below file? 2**2 and 2**0
$ objdump -h main.o
main.o: file format elf32-i386
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 0000000b 00000000 00000000 00000034 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .data 00000000 00000000 00000000 00000040 2**2
CONTENTS, ALLOC, LOAD, DATA
2 .bss 00000000 00000000 00000000 00000040 2**2
ALLOC
3 .note.GNU-stack 00000000 00000000 00000000 00000040 2**0
CONTENTS, READONLY, CODE
I would assume that 2**2 means 22, or 4 byte alignment, while 2**0 means no (one byte) alignment.
This value comes from the sh_addralign field of the ELF section header. The ELF specification states (emphasis mine):
sh_addralign Some sections have address alignment constraints. For example, if a section holds a
doubleword, the system must ensure doubleword alignment for the entire section.
That is, the value of sh_addr must be congruent to 0, modulo the value of
sh_addralign. Currently, only 0 and positive integral powers of two are allowed.
Values 0 and 1 mean the section has no alignment constraints.
As Ray Toal mentioned, since the alignment must be a power of two, it only makes sense that objdump would express this value as a power of two with the 2**x notation.
Note that in some languages, like Python and FORTRAN, ** is a power or exponentiation operator.
Looking at objdump.c, we see:
static void
dump_section_header (bfd *abfd, asection *section,
void *ignored ATTRIBUTE_UNUSED)
{
// ...
printf (" %08lx 2**%u", (unsigned long) section->filepos,
bfd_get_section_alignment (abfd, section));
And in objdump.h:
#define bfd_get_section_alignment(bfd, ptr) ((ptr)->alignment_power + 0)
where the alignment_power member of bfd is:
/* The alignment requirement of the section, as an exponent of 2 -
e.g., 3 aligns to 2^3 (or 8). */
unsigned int alignment_power;