This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: weak alias in gas on arm-elf
Hi Daniel,
I have just tested a few things and realised why I was getting so
confused to begin with.
The original code doesn't branch, because these are entries in a vector
table - so the PC was loaded with the address of the handler instead of
having a branch instruction to the handler.
This leads to:
b _start /* MODE: Supervisor */
ldr pc, srUndef /* MODE: Undefined */
ldr pc, srSWI /* MODE: Supervisor */
ldr pc, srPAbort /* MODE: Abort */
ldr pc, srDAbort /* MODE: Abort */
nop /* reserved (Checksum) */
ldr pc, [pc,#-0x120] /* MODE: IRQ */
ldr pc, srFIQ /* MODE: FIQ */
.weak srUndef
srUndef:
b .
.weak srSWI
srSWI:
b .
...
Emitting the following output:
00000000 <startup>:
0: ea000039 b ec <start>
4: e59ff014 ldr pc, [pc, #20] ; 20 <srUndef>
8: e59ff014 ldr pc, [pc, #20] ; 24 <srUndef+0x4>
c: e59ff014 ldr pc, [pc, #20] ; 28 <srPAbort>
10: e59ff014 ldr pc, [pc, #20] ; 2c <srDAbort>
14: e1a00000 nop (mov r0,r0)
18: e51ff120 ldr pc, [pc, #-288] ; ffffff00 <__ethram_beg__+0x801fff00>
1c: e59ff00c ldr pc, [pc, #12] ; 30 <srFIQ>
20: eafffffe b 20 <srUndef>
24: eafffffe b 24 <srUndef+0x4>
28: eafffffe b 28 <srPAbort>
2c: eafffffe b 2c <srDAbort>
30: eafffffe b 30 <srFIQ>
Disassembly of section prog:
00000034 <srSWI>:
/*
==========================================================================
*/
int __attribute__((interrupt("SWI"))) srSWI(int reason, void* args)
{
34: e52dc004 str ip, [sp, #-4]!
...
As can be seen at address 24: the label srSWI which was given the weak
attribute in the assembler file has gone because there is an srSWI in
the main C code which takes precedence. That makes sense, except that
the weak label code is still present, AND the instruction at address 8
is still loading the PC with the weak symbol address.
This is what originally threw me. I presume this output is intended in
this situation?
If I change the assembler file to branches:
b _start /* MODE: Supervisor */
bl srUndef /* MODE: Undefined */
bl srSWI /* MODE: Supervisor */
bl srPAbort /* MODE: Abort */
bl srDAbort /* MODE: Abort */
nop /* reserved (Checksum) */
ldr pc, [pc,#-0x120] /* MODE: IRQ */
bl srFIQ /* MODE: FIQ */
.weak srUndef
srUndef:
b .
.weak srSWI
srSWI:
b .
...
the weak attribute acts exactly as needed. The following is emitted:
00000000 <startup>:
0: ea000039 b ec <start>
4: eb000005 bl 20 <srUndef>
8: eb000009 bl 34 <srSWI>
c: eb000005 bl 28 <srPAbort>
10: eb000005 bl 2c <srDAbort>
14: e1a00000 nop (mov r0,r0)
18: e51ff120 ldr pc, [pc, #-288] ; ffffff00 <__ethram_beg__+0x801fff00>
1c: eb000003 bl 30 <srFIQ>
20: eafffffe b 20 <srUndef>
24: eafffffe b 24 <srUndef+0x4>
28: eafffffe b 28 <srPAbort>
2c: eafffffe b 2c <srDAbort>
30: eafffffe b 30 <srFIQ>
Disassembly of section prog:
00000034 <srSWI>:
/*
==========================================================================
*/
int __attribute__((interrupt("SWI"))) srSWI(int reason, void* args)
{
...
The reason the ldr is used is because it can address 4Gb memory space,
whereas a branch instruction can only address 32Mb memory space. In my
case this is more than enough and I'm okay to use the branch instructions.
Sorry for the long email!
Best Regards,
Brian Sidebotham.
Daniel Jacobowitz wrote:
On Mon, Jul 02, 2007 at 01:36:34PM +0100, Brian Sidebotham wrote:
.weak works as I expect, and the symbols it creates are branches to the reset
vector (pc=0).
That's your mistake. .weak does not create symbols; like .globl, it
changes the visibility of a label.
__handler1:
bl handler1
.weak handler1
handler1:
bl startup