linux-mips
[Top] [All Lists]

MIPS gas problem

To: binutils@sourceware.cygnus.com, linux@cthulhu.engr.sgi.com, debian-mips@lists.debian.org
Subject: MIPS gas problem
From: Hiroyuki Machida <machida@sm.sony.co.jp>
Date: Thu, 20 Apr 2000 11:13:20 +0900
Sender: owner-linuxmips@oss.sgi.com
Hi

I found the problem  "__attribute__ ((aligned(xx))" doesn't work
properly on MIPS/Linux. Please try to execute the attached test. 
I think this problem can be reproduced on any ELF/MIPS box except
EMBEDED system which has OS name "elf". 

I tracked down and finaly found gas/config/t-mips.c:s_change_sec(sec) 
sets  always ".rodata" section-alignment to 2**4. This should be set 
to the maximum rodata object's alignment value.

% cc -c  rotest.c -o rotest.o
% objdump -h rotest.o

rotest.o:     file format elf32-littlemips

Sections:
Idx Name          Size      VMA               LMA               File off  Algn
  0 .text         00000330  0000000000000000  0000000000000000  00000040  2**4
                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
  1 .data         00000010  0000000000000000  0000000000000000  00000370  2**4
                  CONTENTS, ALLOC, LOAD, DATA
  2 .bss          00000000  0000000000000000  0000000000000000  00000380  2**4
                  ALLOC
  3 .reginfo      00000018  0000000000000000  0000000000000000  00000380  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA,LINK_ONCE_SAME_SIZE
  4 .mdebug       000002f8  0000000000000000  0000000000000000  00000398  2**2
                  CONTENTS, READONLY, DEBUGGING
  5 .rodata       00002060  0000000000000000  0000000000000000  00000690  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, DATA


The sample fix for binutils 2.9.1 is following. (This can be
apply to current CVS version, I suppose.)

Does anyone know the reason why gas/config/t-mips.c set to "rodata'
section alignment to 2**4 and ignore the maximum rodata object
alignment.? We have to know why this restriction is made, anyway.

---
Hiroyuki Machida
Creative Station                SCE Inc./Sony Corp.

Index: tc-mips.c
===================================================================
RCS file: /usr/cvsroot/caesar/src/compiler/binutils/gas/config/tc-mips.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -U10 -p -r1.4 -r1.5
--- tc-mips.c   1999/07/07 01:03:55     1.4
+++ tc-mips.c   2000/04/12 06:50:19     1.5
@@ -9727,21 +9727,28 @@ s_change_sec (sec)
                            (subsegT) get_absolute_expression ());
          if (OUTPUT_FLAVOR == bfd_target_elf_flavour)
            {
              bfd_set_section_flags (stdoutput, seg,
                                     (SEC_ALLOC
                                      | SEC_LOAD
                                      | SEC_READONLY
                                      | SEC_RELOC
                                      | SEC_DATA));
              if (strcmp (TARGET_OS, "elf") != 0)
-               bfd_set_section_alignment (stdoutput, seg, 4);
+               {
+                 static char first = 1;
+                 if (first)
+                   {
+                     bfd_set_section_alignment (stdoutput, seg, 4);
+                     first=0;
+                   }
+               }
            }
          demand_empty_rest_of_line ();
        }
       else
        {
          as_bad ("No read only data section in this object file format");
          demand_empty_rest_of_line ();
          return;
        }
       break;
@@ -9749,21 +9756,28 @@ s_change_sec (sec)
     case 's':
       if (USE_GLOBAL_POINTER_OPT)
        {
          seg = subseg_new (".sdata", (subsegT) get_absolute_expression ());
          if (OUTPUT_FLAVOR == bfd_target_elf_flavour)
            {
              bfd_set_section_flags (stdoutput, seg,
                                     SEC_ALLOC | SEC_LOAD | SEC_RELOC
                                     | SEC_DATA);
              if (strcmp (TARGET_OS, "elf") != 0)
-               bfd_set_section_alignment (stdoutput, seg, 4);
+               {
+                 static char first = 1;
+                 if (first)
+                   {
+                     bfd_set_section_alignment (stdoutput, seg, 4);
+                     first=0;
+                   }
+               }
            }
          demand_empty_rest_of_line ();
          break;
        }
       else
        {
          as_bad ("Global pointers not supported; recompile -G 0");
          demand_empty_rest_of_line ();
          return;
        }

--- end of patch




/*
 * rotest.c - rodata alignment test.
 */

#define AL1 1024
#define AL2 4096
const char globalc='a';
const int global1 __attribute__ ((aligned(AL1))) =0 ;
const int global2 __attribute__ ((aligned(AL2))) =1;

const int local1 __attribute__ ((aligned(AL1))) =0 ;
const int local2 __attribute__ ((aligned(AL2))) =1;

int total_ng=0;

void check(char *addr, unsigned long al)
{
        unsigned long mask = (al -1);
        if ((unsigned long) addr & mask){
                total_ng ++;
                printf("err:%x expected:%x\n", addr, 
                                (unsigned long) addr & ~mask);
        }
}


int
main(void)
{
        printf("* readonly local/gloabl\n");
        printf("chcking align:%x\n",AL1);
        check((char *)&local1,AL1); check((char *)&global1,AL1);
        printf("%x:%x\n", &local1,&global1);
        printf("chcking align:%x\n",4096);
        check((char *)&global1,AL2); check((char *)&global2,AL2);
        printf("%x:%x\n", &global1,&global2);

        printf("\n");
        if (total_ng) {
                printf("NG:%d\n",total_ng);
        } else {
                printf("OK\n");
        }
        printf("\n");
        return total_ng;
}


--- end of test


<Prev in Thread] Current Thread [Next in Thread>