2019-08-19 13:08:17

by Christophe Leroy

[permalink] [raw]
Subject: [PATCH 3/3] powerpc: use __builtin_trap() in BUG/WARN macros.

The below exemples of use of WARN_ON() show that the result
is sub-optimal in regard of the capabilities of powerpc.

void test_warn1(unsigned long long a)
{
WARN_ON(a);
}

void test_warn2(unsigned long a)
{
WARN_ON(a);
}

void test_warn3(unsigned long a, unsigned long b)
{
WARN_ON(a < b);
}

void test_warn4(unsigned long a, unsigned long b)
{
WARN_ON(!a);
}

void test_warn5(unsigned long a, unsigned long b)
{
WARN_ON(!a && b);
}

00000000 <test_warn1>:
0: 7c 64 23 78 or r4,r3,r4
4: 31 24 ff ff addic r9,r4,-1
8: 7c 89 21 10 subfe r4,r9,r4
c: 0f 04 00 00 twnei r4,0
10: 4e 80 00 20 blr

00000014 <test_warn2>:
14: 31 23 ff ff addic r9,r3,-1
18: 7c 69 19 10 subfe r3,r9,r3
1c: 0f 03 00 00 twnei r3,0
20: 4e 80 00 20 blr

00000024 <test_warn3>:
24: 7c 84 18 10 subfc r4,r4,r3
28: 7d 29 49 10 subfe r9,r9,r9
2c: 7d 29 00 d0 neg r9,r9
30: 0f 09 00 00 twnei r9,0
34: 4e 80 00 20 blr

00000038 <test_warn4>:
38: 7c 63 00 34 cntlzw r3,r3
3c: 54 63 d9 7e rlwinm r3,r3,27,5,31
40: 0f 03 00 00 twnei r3,0
44: 4e 80 00 20 blr

00000048 <test_warn5>:
48: 2f 83 00 00 cmpwi cr7,r3,0
4c: 39 20 00 00 li r9,0
50: 41 9e 00 0c beq cr7,5c <test_warn5+0x14>
54: 7c 84 00 34 cntlzw r4,r4
58: 54 89 d9 7e rlwinm r9,r4,27,5,31
5c: 0f 09 00 00 twnei r9,0
60: 4e 80 00 20 blr

RELOCATION RECORDS FOR [__bug_table]:
OFFSET TYPE VALUE
00000000 R_PPC_ADDR32 .text+0x0000000c
0000000c R_PPC_ADDR32 .text+0x0000001c
00000018 R_PPC_ADDR32 .text+0x00000030
00000018 R_PPC_ADDR32 .text+0x00000030
00000024 R_PPC_ADDR32 .text+0x00000040
00000030 R_PPC_ADDR32 .text+0x0000005c

Using __builtin_trap() instead of inline assembly of twnei/tdnei
provides a far better result:

00000000 <test_warn1>:
0: 7c 64 23 78 or r4,r3,r4
4: 0f 04 00 00 twnei r4,0
8: 4e 80 00 20 blr

0000000c <test_warn2>:
c: 0f 03 00 00 twnei r3,0
10: 4e 80 00 20 blr

00000014 <test_warn3>:
14: 7c 43 20 08 twllt r3,r4
18: 4e 80 00 20 blr

0000001c <test_warn4>:
1c: 0c 83 00 00 tweqi r3,0
20: 4e 80 00 20 blr

00000024 <test_warn5>:
24: 2f 83 00 00 cmpwi cr7,r3,0
28: 41 9e 00 08 beq cr7,30 <test_warn5+0xc>
2c: 0c 84 00 00 tweqi r4,0
30: 4e 80 00 20 blr

RELOCATION RECORDS FOR [__bug_table]:
OFFSET TYPE VALUE
00000000 R_PPC_ADDR32 .text+0x00000004
0000000c R_PPC_ADDR32 .text+0x0000000c
00000018 R_PPC_ADDR32 .text+0x00000014
00000024 R_PPC_ADDR32 .text+0x0000001c
00000030 R_PPC_ADDR32 .text+0x0000002c

Note that we keep using an assembly text using "twi 31, 0, 0" for
inconditional traps because GCC drops all code after
__builtin_trap() when the condition is always true at build time.

In addition, this patch also fixes bugs in the BUG_ON(x) macro
which unlike WARN_ON(x) uses (x) directly as the condition by
forcing it to long instead of using !!(x). This leads to
upper part of an unsigned long long being ignored on PPC32 and
may produce bugs on PPC64 if (x) is a smaller type like an int.

Signed-off-by: Christophe Leroy <[email protected]>
---
arch/powerpc/include/asm/bug.h | 17 ++++++++++-------
1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/arch/powerpc/include/asm/bug.h b/arch/powerpc/include/asm/bug.h
index dbf7da90f507..a229130ffcf9 100644
--- a/arch/powerpc/include/asm/bug.h
+++ b/arch/powerpc/include/asm/bug.h
@@ -44,14 +44,14 @@
#ifdef CONFIG_DEBUG_BUGVERBOSE
#define _EMIT_BUG_ENTRY \
".section __bug_table,\"aw\"\n" \
- "2:\t" PPC_LONG "1b, %0\n" \
+ "2:\t" PPC_LONG "1b - 4, %0\n" \
"\t.short %1, %2\n" \
".org 2b+%3\n" \
".previous\n"
#else
#define _EMIT_BUG_ENTRY \
".section __bug_table,\"aw\"\n" \
- "2:\t" PPC_LONG "1b\n" \
+ "2:\t" PPC_LONG "1b - 4\n" \
"\t.short %2\n" \
".org 2b+%3\n" \
".previous\n"
@@ -59,7 +59,8 @@

#define BUG_ENTRY(insn, flags, ...) \
__asm__ __volatile__( \
- "1: " insn "\n" \
+ insn "\n" \
+ "1:\n" \
_EMIT_BUG_ENTRY \
: : "i" (__FILE__), "i" (__LINE__), \
"i" (flags), \
@@ -82,7 +83,9 @@
if (x) \
BUG(); \
} else { \
- BUG_ENTRY(PPC_TLNEI " %4, 0", 0, "r" ((__force long)(x))); \
+ if (x) \
+ __builtin_trap(); \
+ BUG_ENTRY("", 0); \
} \
} while (0)

@@ -94,9 +97,9 @@
if (__ret_warn_on) \
__WARN_TAINT(TAINT_WARN); \
} else { \
- BUG_ENTRY(PPC_TLNEI " %4, 0", \
- BUGFLAG_WARNING | BUGFLAG_TAINT(TAINT_WARN), \
- "r" (__ret_warn_on)); \
+ if (__ret_warn_on) \
+ __builtin_trap(); \
+ BUG_ENTRY("", BUGFLAG_WARNING | BUGFLAG_TAINT(TAINT_WARN)); \
} \
unlikely(__ret_warn_on); \
})
--
2.13.3


2019-08-19 13:26:38

by Segher Boessenkool

[permalink] [raw]
Subject: Re: [PATCH 3/3] powerpc: use __builtin_trap() in BUG/WARN macros.

On Mon, Aug 19, 2019 at 01:06:31PM +0000, Christophe Leroy wrote:
> Note that we keep using an assembly text using "twi 31, 0, 0" for
> inconditional traps because GCC drops all code after
> __builtin_trap() when the condition is always true at build time.

As I said, it can also do this for conditional traps, if it can prove
the condition is always true.

Can you put the bug table asm *before* the __builtin_trap maybe? That
should make it all work fine... If you somehow can tell what machine
instruction is that trap, anyway.


Segher

2019-08-19 14:11:39

by Christophe Leroy

[permalink] [raw]
Subject: Re: [PATCH 3/3] powerpc: use __builtin_trap() in BUG/WARN macros.



Le 19/08/2019 à 15:23, Segher Boessenkool a écrit :
> On Mon, Aug 19, 2019 at 01:06:31PM +0000, Christophe Leroy wrote:
>> Note that we keep using an assembly text using "twi 31, 0, 0" for
>> inconditional traps because GCC drops all code after
>> __builtin_trap() when the condition is always true at build time.
>
> As I said, it can also do this for conditional traps, if it can prove
> the condition is always true.

But we have another branch for 'always true' and 'always false' using
__builtin_constant_p(), which don't use __builtin_trap(). Is there
anything wrong with that ?:

#define BUG_ON(x) do { \
if (__builtin_constant_p(x)) { \
if (x) \
BUG(); \
} else { \
if (x) \
__builtin_trap(); \
BUG_ENTRY("", 0); \
} \
} while (0)

#define WARN_ON(x) ({ \
int __ret_warn_on = !!(x); \
if (__builtin_constant_p(__ret_warn_on)) { \
if (__ret_warn_on) \
__WARN_TAINT(TAINT_WARN); \
} else { \
if (__ret_warn_on) \
__builtin_trap(); \
BUG_ENTRY("", BUGFLAG_WARNING | BUGFLAG_TAINT(TAINT_WARN)); \
} \
unlikely(__ret_warn_on); \
})


>
> Can you put the bug table asm *before* the __builtin_trap maybe? That
> should make it all work fine... If you somehow can tell what machine
> instruction is that trap, anyway.

And how can I tell that ?

When I put it *after*, it always points to the trap instruction. When I
put it *before* it usually points on the first instruction used to
prepare the registers for the trap condition.

Christophe

2019-08-19 14:38:31

by Segher Boessenkool

[permalink] [raw]
Subject: Re: [PATCH 3/3] powerpc: use __builtin_trap() in BUG/WARN macros.

On Mon, Aug 19, 2019 at 04:08:43PM +0200, Christophe Leroy wrote:
> Le 19/08/2019 ? 15:23, Segher Boessenkool a ?crit?:
> >On Mon, Aug 19, 2019 at 01:06:31PM +0000, Christophe Leroy wrote:
> >>Note that we keep using an assembly text using "twi 31, 0, 0" for
> >>inconditional traps because GCC drops all code after
> >>__builtin_trap() when the condition is always true at build time.
> >
> >As I said, it can also do this for conditional traps, if it can prove
> >the condition is always true.
>
> But we have another branch for 'always true' and 'always false' using
> __builtin_constant_p(), which don't use __builtin_trap(). Is there
> anything wrong with that ?:

The compiler might not realise it is constant when it evaluates the
__builtin_constant_p, but only realises it later. As the documentation
for the builtin says:
A return of 0 does not indicate that the
value is _not_ a constant, but merely that GCC cannot prove it is a
constant with the specified value of the '-O' option.

(and there should be many more and more serious warnings here).

> #define BUG_ON(x) do { \
> if (__builtin_constant_p(x)) { \
> if (x) \
> BUG(); \
> } else { \
> if (x) \
> __builtin_trap(); \
> BUG_ENTRY("", 0); \
> } \
> } while (0)

I think it may work if you do

#define BUG_ON(x) do { \
if (__builtin_constant_p(x)) { \
if (x) \
BUG(); \
} else { \
BUG_ENTRY("", 0); \
if (x) \
__builtin_trap(); \
} \
} while (0)

or even just

#define BUG_ON(x) do { \
BUG_ENTRY("", 0); \
if (x) \
__builtin_trap(); \
} \
} while (0)

if BUG_ENTRY can work for the trap insn *after* it.

> >Can you put the bug table asm *before* the __builtin_trap maybe? That
> >should make it all work fine... If you somehow can tell what machine
> >instruction is that trap, anyway.
>
> And how can I tell that ?

I don't know how BUG_ENTRY works exactly.


Segher

2019-08-19 15:07:31

by Christophe Leroy

[permalink] [raw]
Subject: Re: [PATCH 3/3] powerpc: use __builtin_trap() in BUG/WARN macros.



Le 19/08/2019 à 16:37, Segher Boessenkool a écrit :
> On Mon, Aug 19, 2019 at 04:08:43PM +0200, Christophe Leroy wrote:
>> Le 19/08/2019 à 15:23, Segher Boessenkool a écrit :
>>> On Mon, Aug 19, 2019 at 01:06:31PM +0000, Christophe Leroy wrote:
>>>> Note that we keep using an assembly text using "twi 31, 0, 0" for
>>>> inconditional traps because GCC drops all code after
>>>> __builtin_trap() when the condition is always true at build time.
>>>
>>> As I said, it can also do this for conditional traps, if it can prove
>>> the condition is always true.
>>
>> But we have another branch for 'always true' and 'always false' using
>> __builtin_constant_p(), which don't use __builtin_trap(). Is there
>> anything wrong with that ?:
>
> The compiler might not realise it is constant when it evaluates the
> __builtin_constant_p, but only realises it later. As the documentation
> for the builtin says:
> A return of 0 does not indicate that the
> value is _not_ a constant, but merely that GCC cannot prove it is a
> constant with the specified value of the '-O' option.

So you mean GCC would not be able to prove that
__builtin_constant_p(cond) is always true but it would be able to prove
that if (cond) is always true ?

And isn't there a away to tell GCC that '__builtin_trap()' is
recoverable in our case ?

>
> (and there should be many more and more serious warnings here).
>
>> #define BUG_ON(x) do { \
>> if (__builtin_constant_p(x)) { \
>> if (x) \
>> BUG(); \
>> } else { \
>> if (x) \
>> __builtin_trap(); \
>> BUG_ENTRY("", 0); \
>> } \
>> } while (0)
>
> I think it may work if you do
>
> #define BUG_ON(x) do { \
> if (__builtin_constant_p(x)) { \
> if (x) \
> BUG(); \
> } else { \
> BUG_ENTRY("", 0); \
> if (x) \
> __builtin_trap(); \
> } \
> } while (0)

It doesn't work:

void test_bug1(unsigned long long a)
{
BUG_ON(a);
}

00000090 <test_bug1>:
90: 7c 63 23 78 or r3,r3,r4
94: 0f 03 00 00 twnei r3,0
98: 4e 80 00 20 blr

RELOCATION RECORDS FOR [__bug_table]:
OFFSET TYPE VALUE
00000084 R_PPC_ADDR32 .text+0x00000090

As you see, the relocation in __bug_table points to the 'or' and not to
the 'twnei'.

>
> or even just
>
> #define BUG_ON(x) do { \
> BUG_ENTRY("", 0); \
> if (x) \
> __builtin_trap(); \
> } \
> } while (0)
>
> if BUG_ENTRY can work for the trap insn *after* it.
>
>>> Can you put the bug table asm *before* the __builtin_trap maybe? That
>>> should make it all work fine... If you somehow can tell what machine
>>> instruction is that trap, anyway.
>>
>> And how can I tell that ?
>
> I don't know how BUG_ENTRY works exactly.

It's basic, maybe too basic: it adds an inline asm with a label, and
adds a .long in the __bug_table section with the address of that label.

When putting it after the __builtin_trap(), I changed it to using the
address before the one of the label which is always the twxx instruction
as far as I can see.

#define BUG_ENTRY(insn, flags, ...) \
__asm__ __volatile__( \
"1: " insn "\n" \
".section __bug_table,\"aw\"\n" \
"2:\t" PPC_LONG "1b, %0\n" \
"\t.short %1, %2\n" \
".org 2b+%3\n" \
".previous\n" \
: : "i" (__FILE__), "i" (__LINE__), \
"i" (flags), \
"i" (sizeof(struct bug_entry)), \
##__VA_ARGS__)

Christophe

2019-08-19 15:48:43

by Segher Boessenkool

[permalink] [raw]
Subject: Re: [PATCH 3/3] powerpc: use __builtin_trap() in BUG/WARN macros.

On Mon, Aug 19, 2019 at 05:05:46PM +0200, Christophe Leroy wrote:
> Le 19/08/2019 ? 16:37, Segher Boessenkool a ?crit?:
> >On Mon, Aug 19, 2019 at 04:08:43PM +0200, Christophe Leroy wrote:
> >>Le 19/08/2019 ? 15:23, Segher Boessenkool a ?crit?:
> >>>On Mon, Aug 19, 2019 at 01:06:31PM +0000, Christophe Leroy wrote:
> >>>>Note that we keep using an assembly text using "twi 31, 0, 0" for
> >>>>inconditional traps because GCC drops all code after
> >>>>__builtin_trap() when the condition is always true at build time.
> >>>
> >>>As I said, it can also do this for conditional traps, if it can prove
> >>>the condition is always true.
> >>
> >>But we have another branch for 'always true' and 'always false' using
> >>__builtin_constant_p(), which don't use __builtin_trap(). Is there
> >>anything wrong with that ?:
> >
> >The compiler might not realise it is constant when it evaluates the
> >__builtin_constant_p, but only realises it later. As the documentation
> >for the builtin says:
> > A return of 0 does not indicate that the
> > value is _not_ a constant, but merely that GCC cannot prove it is a
> > constant with the specified value of the '-O' option.
>
> So you mean GCC would not be able to prove that
> __builtin_constant_p(cond) is always true but it would be able to prove
> that if (cond) is always true ?

Not sure what you mean, sorry.

> And isn't there a away to tell GCC that '__builtin_trap()' is
> recoverable in our case ?

No, GCC knows that a trap will never fall through.

> >I think it may work if you do
> >
> >#define BUG_ON(x) do { \
> > if (__builtin_constant_p(x)) { \
> > if (x) \
> > BUG(); \
> > } else { \
> > BUG_ENTRY("", 0); \
> > if (x) \
> > __builtin_trap(); \
> > } \
> >} while (0)
>
> It doesn't work:

You need to make a BUG_ENTRY so that it refers to the *following* trap
instruction, if you go this way.

> >I don't know how BUG_ENTRY works exactly.
>
> It's basic, maybe too basic: it adds an inline asm with a label, and
> adds a .long in the __bug_table section with the address of that label.
>
> When putting it after the __builtin_trap(), I changed it to using the
> address before the one of the label which is always the twxx instruction
> as far as I can see.
>
> #define BUG_ENTRY(insn, flags, ...) \
> __asm__ __volatile__( \
> "1: " insn "\n" \
> ".section __bug_table,\"aw\"\n" \
> "2:\t" PPC_LONG "1b, %0\n" \
> "\t.short %1, %2\n" \
> ".org 2b+%3\n" \
> ".previous\n" \
> : : "i" (__FILE__), "i" (__LINE__), \
> "i" (flags), \
> "i" (sizeof(struct bug_entry)), \
> ##__VA_ARGS__)

#define MY_BUG_ENTRY(lab, flags) \
__asm__ __volatile__( \
".section __bug_table,\"aw\"\n" \
"2:\t" PPC_LONG "%4, %0\n" \
"\t.short %1, %2\n" \
".org 2b+%3\n" \
".previous\n" \
: : "i" (__FILE__), "i" (__LINE__), \
"i" (flags), \
"i" (sizeof(struct bug_entry)), \
"i" (lab))

called as

#define BUG_ON(x) do { \
MY_BUG_ENTRY(&&lab, 0); \
lab: if (x) \
__builtin_trap(); \
} while (0)

not sure how reliable that works -- *if* it works, I just typed that in
without testing or anything -- but hopefully you get the idea.


Segher

2019-08-23 23:31:32

by Christophe Leroy

[permalink] [raw]
Subject: Re: [PATCH 3/3] powerpc: use __builtin_trap() in BUG/WARN macros.



On 08/19/2019 03:45 PM, Segher Boessenkool wrote:
> On Mon, Aug 19, 2019 at 05:05:46PM +0200, Christophe Leroy wrote:
>> Le 19/08/2019 à 16:37, Segher Boessenkool a écrit :
>>> On Mon, Aug 19, 2019 at 04:08:43PM +0200, Christophe Leroy wrote:
>>>> Le 19/08/2019 à 15:23, Segher Boessenkool a écrit :
>>>>> On Mon, Aug 19, 2019 at 01:06:31PM +0000, Christophe Leroy wrote:
>>>>>> Note that we keep using an assembly text using "twi 31, 0, 0" for
>>>>>> inconditional traps because GCC drops all code after
>>>>>> __builtin_trap() when the condition is always true at build time.
>>>>>
>>>>> As I said, it can also do this for conditional traps, if it can prove
>>>>> the condition is always true.
>>>>
>>>> But we have another branch for 'always true' and 'always false' using
>>>> __builtin_constant_p(), which don't use __builtin_trap(). Is there
>>>> anything wrong with that ?:
>>>
>>> The compiler might not realise it is constant when it evaluates the
>>> __builtin_constant_p, but only realises it later. As the documentation
>>> for the builtin says:
>>> A return of 0 does not indicate that the
>>> value is _not_ a constant, but merely that GCC cannot prove it is a
>>> constant with the specified value of the '-O' option.
>>
>> So you mean GCC would not be able to prove that
>> __builtin_constant_p(cond) is always true but it would be able to prove
>> that if (cond) is always true ?
>
> Not sure what you mean, sorry.
>
>> And isn't there a away to tell GCC that '__builtin_trap()' is
>> recoverable in our case ?
>
> No, GCC knows that a trap will never fall through.
>
>>> I think it may work if you do
>>>
>>> #define BUG_ON(x) do { \
>>> if (__builtin_constant_p(x)) { \
>>> if (x) \
>>> BUG(); \
>>> } else { \
>>> BUG_ENTRY("", 0); \
>>> if (x) \
>>> __builtin_trap(); \
>>> } \
>>> } while (0)
>>
>> It doesn't work:
>
> You need to make a BUG_ENTRY so that it refers to the *following* trap
> instruction, if you go this way.
>
>>> I don't know how BUG_ENTRY works exactly.
>>
>> It's basic, maybe too basic: it adds an inline asm with a label, and
>> adds a .long in the __bug_table section with the address of that label.
>>
>> When putting it after the __builtin_trap(), I changed it to using the
>> address before the one of the label which is always the twxx instruction
>> as far as I can see.
>>
>> #define BUG_ENTRY(insn, flags, ...) \
>> __asm__ __volatile__( \
>> "1: " insn "\n" \
>> ".section __bug_table,\"aw\"\n" \
>> "2:\t" PPC_LONG "1b, %0\n" \
>> "\t.short %1, %2\n" \
>> ".org 2b+%3\n" \
>> ".previous\n" \
>> : : "i" (__FILE__), "i" (__LINE__), \
>> "i" (flags), \
>> "i" (sizeof(struct bug_entry)), \
>> ##__VA_ARGS__)
>
> #define MY_BUG_ENTRY(lab, flags) \
> __asm__ __volatile__( \
> ".section __bug_table,\"aw\"\n" \
> "2:\t" PPC_LONG "%4, %0\n" \
> "\t.short %1, %2\n" \
> ".org 2b+%3\n" \
> ".previous\n" \
> : : "i" (__FILE__), "i" (__LINE__), \
> "i" (flags), \
> "i" (sizeof(struct bug_entry)), \
> "i" (lab))
>
> called as
>
> #define BUG_ON(x) do { \
> MY_BUG_ENTRY(&&lab, 0); \
> lab: if (x) \
> __builtin_trap(); \
> } while (0)
>
> not sure how reliable that works -- *if* it works, I just typed that in
> without testing or anything -- but hopefully you get the idea.
>

I've not been able to make it work. GCC puts the label (.L2 and .L6)
outside of the function, so the instruction preceding the label is blr,
not the trap.

#define _EMIT_BUG_ENTRY \
".section __bug_table,\"aw\"\n" \
"2:\t" PPC_LONG "%4, %0\n" \
"\t.short %1, %2\n" \
".org 2b+%3\n" \
".previous\n"

#define BUG_ENTRY(flags, label) \
__asm__ __volatile__( \
_EMIT_BUG_ENTRY \
: : "i" (__FILE__), "i" (__LINE__), \
"i" (flags), \
"i" (sizeof(struct bug_entry)), \
"i" (label - 4))

#define __recoverable_trap() asm volatile ("twi 31, 0, 0;");

#define __WARN_FLAGS(flags) do { \
__label__ label; \
BUG_ENTRY(BUGFLAG_WARNING | (flags), &&label); \
__recoverable_trap(); \
label: ; \
} while (0)

#define WARN_ON(x) ({ \
int __ret_warn_on = !!(x); \
if (__builtin_constant_p(__ret_warn_on)) { \
if (__ret_warn_on) \
__WARN_TAINT(TAINT_WARN); \
} else { \
__label__ label; \
BUG_ENTRY(BUGFLAG_WARNING | BUGFLAG_TAINT(TAINT_WARN), &&label); \
if (__ret_warn_on) \
__builtin_trap(); \
label: ; \
} \
unlikely(__ret_warn_on); \
})

void test_warn1(unsigned long long a)
{
WARN_ON(a);
}

void test_warn2(unsigned long a)
{
WARN_ON(a);
}

00000000 <test_warn1>:
0: 7c 63 23 78 or r3,r3,r4
4: 0f 03 00 00 twnei r3,0
8: 4e 80 00 20 blr

0000000c <test_warn2>:
c: 0f 03 00 00 twnei r3,0
10: 4e 80 00 20 blr

RELOCATION RECORDS FOR [__bug_table]:
OFFSET TYPE VALUE
00000000 R_PPC_ADDR32 .text+0x00000008
00000004 R_PPC_ADDR32 .rodata.str1.4
0000000c R_PPC_ADDR32 .text+0x00000010
00000010 R_PPC_ADDR32 .rodata.str1.4


.file "test.c"
.section ".text"
.Ltext0:
.align 2
.globl test_warn1
.type test_warn1, @function
test_warn1:
.LFB598:
.file 1 "arch/powerpc/mm/test.c"
.loc 1 34 0
.LBB2:
.LBB3:
.loc 1 35 0
#APP
# 35 "arch/powerpc/mm/test.c" 1
.section __bug_table,"aw"
2: .long .L2-4, .LC0
.short 35, 2305
.org 2b+12
.previous

# 0 "" 2
#NO_APP
or 3,3,4
twnei 3,0
blr
.L3:
.L2:
.LBE3:
.LBE2:
.LFE598:
.size test_warn1, .-test_warn1
.align 2
.globl test_warn2
.type test_warn2, @function
test_warn2:
.LFB599:
.loc 1 39 0
.LBB4:
.LBB5:
.loc 1 40 0
#APP
# 40 "arch/powerpc/mm/test.c" 1
.section __bug_table,"aw"
2: .long .L6-4, .LC0
.short 40, 2305
.org 2b+12
.previous

# 0 "" 2
#NO_APP
twnei 3,0
blr
.L7:
.L6:
.LBE5:
.LBE4:
.LFE599:

Any idea ?

Christophe