[PATCH 03/14] ARM: v6k: remove CPU_32v6K dependencies in asm/spinlock.h

Dave P. Martin dave.martin at linaro.org
Thu Jan 27 06:44:31 EST 2011


On Wed, Jan 26, 2011 at 04:06:40PM -0500, Nicolas Pitre wrote:
> On Wed, 26 Jan 2011, Dave Martin wrote:
> 
> > On Wed, Jan 26, 2011 at 3:52 PM, Russell King - ARM Linux
> > <linux at arm.linux.org.uk> wrote:
> > > So I don't think weak symbols work like we want them to.
> > >
> > 
> > That was the conclusion I came to also ... the linker seems to resolve
> > references in each object before discarding sections, so the weak
> > reference has already become concrete and section discard breaks it.
> 
> Well, I must add to the chorus.
> 
> And it seems to be impossible to obtain the name of the currently active 
> section from gas either, which would have made the conditional omission 
> of the fixup possible, or similar.
> 
> Bummer.
> 
> 
> Nicolas

I've achieved this sort of thing in the past by wrapping the assmbler.
It's not pretty though, and it's unlikely anyone would be interested
in merging such a thing...

The example below is really a hack and won't work well in the the
presence of macros or conditional assembler.  However, since gcc output
contains none of either except in inline asm, you can get away with
a surprising amount.

If it needed to be robust this could mostly be implemented in 
assembler macros, but the need to hook things like .section, combined
with gas's refusal to redefine existing directives, means that you
would have a run a script over the input first, to translate .section
and friends into something you can hook.

And implementing anything non-trivial with assembler macros, while
almost always possible (unlike crippled cpp) gets very painful and
confusing...

Cheers
---Dave

$ chmod +x gasfilter filt-as
$ PATH=$PWD:$PATH
$ arm-linux-gnueabi-gcc -wrapper $PWD/filt-as -c tst.s
$ arm-linux-gnueabi-objdump -dsh tst.o

tst.o:     file format elf32-littlearm

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         00000004  00000000  00000000  00000034  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .data         00000000  00000000  00000000  00000038  2**0
                  CONTENTS, ALLOC, LOAD, DATA
  2 .bss          00000000  00000000  00000000  00000038  2**0
                  ALLOC
  3 .text.fixup   00000004  00000000  00000000  00000038  2**0
                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
  4 .text.init    00000008  00000000  00000000  0000003c  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  5 .text.init.fixup 00000004  00000000  00000000  00000044  2**0
                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
  6 .ARM.attributes 00000021  00000000  00000000  00000048  2**0
                  CONTENTS, READONLY
Contents of section .text:
 0000 00f020e3                             .. .            
Contents of section .text.fixup:
 0000 00000000                             ....            
Contents of section .text.init:
 0000 00f020e3 00f020e3                    .. ... .        
Contents of section .text.init.fixup:
 0000 04000000                             ....            
Contents of section .ARM.attributes:
 0000 41200000 00616561 62690001 16000000  A ...aeabi......
 0010 05372d41 00060a07 41080109 020a042c  .7-A....A......,
 0020 01                                   .               

Disassembly of section .text:

00000000 <main>:
   0:	e320f000 	nop	{0}

Disassembly of section .text.fixup:

00000000 <.text.fixup>:
   0:	00000000 	.word	0x00000000

Disassembly of section .text.init:

00000000 <init>:
   0:	e320f000 	nop	{0}

00000004 <__fixup_3>:
   4:	e320f000 	nop	{0}

Disassembly of section .text.init.fixup:

00000000 <.text.init.fixup>:
   0:	00000004 	.word	0x00000004

diff -Nur filt-as filt-as
--- filt-as	1970-01-01 01:00:00.000000000 +0100
+++ filt-as	2011-01-27 11:30:11.858552002 +0000
@@ -0,0 +1,30 @@
+#!/bin/sh
+
+case "$1" in
+	as|*/as|*-as) ;;
+	*) exec "$@"
+esac
+
+real_as=$1
+shift
+
+out=a.out
+in=-
+
+while [ $# != 0 ]; do
+	case "$1" in
+		-o)
+			out=$2
+			shift
+			;;
+		*.s)
+			in=$1
+			;;
+		*)
+			args=$args\ $1
+	esac
+	shift
+done
+
+gasfilter <"$in" \
+| "$real_as" $args -o "$out"
diff -Nur gasfilter gasfilter
--- gasfilter	1970-01-01 01:00:00.000000000 +0100
+++ gasfilter	2011-01-27 11:10:01.478552002 +0000
@@ -0,0 +1,68 @@
+#!/usr/bin/perl
+
+use strict;
+
+my $xpushsection_defined;
+
+my @section_stack = ( undef );
+
+sub setsection ($$) {
+	my ($name, $line) = @_;
+
+	print ".purgem __xpushsection\n" if $xpushsection_defined;
+
+	print
+".macro __xpushsection name:req, flags
+	.pushsection \"$name.\\name\", \"\\flags\"
+.endm
+";
+
+	$section_stack[$#section_stack] = $name;
+
+	$xpushsection_defined = 1;
+
+	print $line
+}
+
+sub popsection ($)
+{
+	pop @section_stack;
+	setsection $section_stack[$#section_stack], $_[0];
+}
+
+sub pushsection ($$)
+{
+	my ($name, $line) = @_;
+
+	push @section_stack, $name;
+	setsection $name, $line;
+}
+
+sub xpushsection ($$) {
+	my ($name, $rest) = @_;
+
+	print "__xpushsection \"$name\"$rest\n"
+}
+
+sub process_line {
+	$_ = $_[0] if defined $_[0];
+
+	if (/^\s*(\.(text|data|bss))(\s|$)/) {
+		setsection $1, $_
+	} elsif (/^\s*\.section\s+([\$._0-9A-Za-z]+).*/) {
+		setsection $1, $_
+	} elsif (/^\s*\.pushsection\s+([\$._0-9A-Za-z]+).*/) {
+		pushsection $1, $_
+	} elsif (/^\s*\.popsection(\s|$)/) {
+		popsection $_
+	} elsif (/^\s*\.xpushsection\s+([\$._0-9A-Za-z]+)(.*)/) {
+		xpushsection $1, $2
+	} elsif (/^\s*\.xpopsection(\s|$)/) {
+		print ".popsection\n"
+	} else {
+		print
+	}
+}	
+
+process_line ".text\n";
+process_line while <>;
diff -Nur tst.s tst.s
--- tst.s	1970-01-01 01:00:00.000000000 +0100
+++ tst.s	2011-01-27 11:07:39.338552001 +0000
@@ -0,0 +1,23 @@
+.macro fixup
+	_fixup \@
+.endm
+
+.macro _fixup num
+__fixup_\num :
+	.xpushsection fixup, "a"
+	.long __fixup_\num
+	.xpopsection
+.endm
+
+.globl main
+main:
+	fixup
+	nop
+
+.section .text.init, "ax"
+.globl init
+init:	nop
+
+	fixup
+	nop
+



More information about the linux-arm-kernel mailing list