Bug 17601 - __start function can not reach __libc_start_main in different region
Summary: __start function can not reach __libc_start_main in different region
Status: CLOSED FIXED
Alias: None
Product: glibc
Classification: Unclassified
Component: libc (show other bugs)
Version: unspecified
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-11-14 16:22 UTC by Petar Jovanovic
Modified: 2015-04-29 22:28 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:
fweimer: security-


Attachments
patch for start.S (436 bytes, patch)
2014-11-14 16:59 UTC, Petar Jovanovic
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Petar Jovanovic 2014-11-14 16:22:05 UTC
Reproduction steps:

Try to compile the following example for mips32:

int main() {
  asm(".fill 100000000, 4, 0x00000000\n");
  return 0;
}

Current behaviour:

Compiling it will trigger the following error:

../sysdeps/mips/start.S:109:(.text+0x44): relocation truncated to fit: R_MIPS_26 against `__libc_start_main@@GLIBC_2.0'
collect2: error: ld returned 1 exit status

Expected behaviour:

The program is linked without problems and can be executed.

Additional info:

This is a small and trivial example, but the real world application - and that is Chromium browser_tests will fail to link due to the very same issue.
As reported by ld, the root cause is in the function __start which tends to use:

jal     __libc_start_main

even though __libc_start_main may not be in the same 256MB-aligned region.
This function ends up as part of the initial runtime code in crt1.o.
Comment 1 Petar Jovanovic 2014-11-14 16:59:36 UTC
Created attachment 7936 [details]
patch for start.S

Potential fix for start.S is attached.

This would likely need to be followed with similar change in gcc/config/mips/mips.h
for CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC) macro

i.e. replace use of 
jal " USER_LABEL_PREFIX #FUNC "\n\

with
la $25, " USER_LABEL_PREFIX #FUNC "\n\
jalr $25\n\
Comment 2 jsm-csl@polyomino.org.uk 2014-11-14 17:51:56 UTC
Please submit the patch to libc-alpha once you've tested the affected 
cases (including MIPS16, since you're changing that code).
Comment 3 Sourceware Commits 2014-12-02 23:05:37 UTC
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU C Library master sources".

The branch, master has been updated
       via  bbe4c142b024d639418069b480b0f3d05b489803 (commit)
      from  909e16d96064708b43170eeb01135315f540e6ff (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=bbe4c142b024d639418069b480b0f3d05b489803

commit bbe4c142b024d639418069b480b0f3d05b489803
Author: Petar Jovanovic <petar.jovanovic@rt-rk.com>
Date:   Tue Dec 2 23:04:43 2014 +0000

    mips: Do not use jal to reach __libc_start_main
    
    Since __libc_start_main may not be in the same 256MB-aligned region as
    the function __start, replace use of jal instruction with la/jalr.
    
    This fixes linker issue reported in:
    https://sourceware.org/bugzilla/show_bug.cgi?id=17601
    
    	[BZ #17601]
    	* sysdeps/mips/start.S (__start): Use indirect jump to call
    	__libc_start_main.

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog            |    6 ++++++
 NEWS                 |    2 +-
 sysdeps/mips/start.S |    8 ++++++--
 3 files changed, 13 insertions(+), 3 deletions(-)
Comment 4 Joseph Myers 2014-12-02 23:12:08 UTC
Fix applied for 2.21.
Comment 5 Petar Jovanovic 2014-12-03 22:41:51 UTC
[Just a comment that may be obvious to someone familiar with the issue
but not to someone who comes across this page for the first time.]

The glibc part of the issue has been fixed, but we still need to
upstream a similar change to GCC (see comment #1 in this issue) before
the whole problem is resolved.
Comment 6 Petar Jovanovic 2015-04-29 22:26:46 UTC
Just for a reference, GCC part of the fix is now committed in r222589 [1].

The issue can be closed now.

[1] https://gcc.gnu.org/viewcvs/gcc?view=revision&revision=222589
Comment 7 Petar Jovanovic 2015-04-29 22:28:08 UTC
Fixes for glibc and GCC have been committed.