Bug 24289 - MEMORY regions can no longer use LENGTH and ORIGIN (2.32 regression).
Summary: MEMORY regions can no longer use LENGTH and ORIGIN (2.32 regression).
Status: RESOLVED FIXED
Alias: None
Product: binutils
Classification: Unclassified
Component: ld (show other bugs)
Version: 2.32
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2019-03-01 22:13 UTC by Nick Bowler
Modified: 2019-03-06 15:26 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments
Possible fix (664 bytes, patch)
2019-03-01 22:13 UTC, Nick Bowler
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Nick Bowler 2019-03-01 22:13:11 UTC
Created attachment 11659 [details]
Possible fix

Consider the following linker script:

  % cat >test.ld <<'EOF'
  MEMORY {
     a : ORIGIN = 0,                     LENGTH = 16M
     b : ORIGIN = ORIGIN(a) + LENGTH(a), LENGTH = 16M
  }
  
  SECTIONS {
     ENTRY(entry)
     .text 1M : { *(.text*) } >a
  }
  
  a_start = ORIGIN(a);
  a_end   = ORIGIN(a) + LENGTH(a);
  b_start = ORIGIN(b);
  b_end   = ORIGIN(b) + LENGTH(b);
EOF

This works as exepcted with ld-2.31: the codestart symbol gets the value 0 and
the datastart symbol gets the value 16777216.  However, 2.32 appears to reject
the LENGTH(code) use in the MEMORY block:

  % ld --version
  GNU ld (GNU Binutils) 2.32.0.20190301
  [...]

  % ld -Ttest.ld test.o
  ld: invalid origin for memory region b

This appears to be caused by the fix for PR23648 (which I reported...),
but for some reason I didn't notice this particular problem until now :(

Anyway the issue seems to be that when evaluating the expressions, ORIGIN and
LENGTH explicitly don't get processed when the phase is lang_first_phase_enum,
and that patch which moved lang_do_memory_regions moved the evaluation of
memory regions into this phase.

Simply removing the phase check for ORIGIN and LENGTH evaluation seems to
fix this problem with no test regressions.
Comment 1 Nick Bowler 2019-03-01 22:17:36 UTC
(In reply to Nick Bowler from comment #0)
> This works as exepcted with ld-2.31: the codestart symbol gets the value 0
> and the datastart symbol gets the value 16777216.  However, 2.32 appears to
> reject the LENGTH(code) use in the MEMORY block:

Proofread fail... I revised the test.ld script but not this paragraph.
"codestart" should be "a_start", "datastart" should be "b_start", and
"LENGTH(code)" should be "ORIGIN(a) + LENGTH(a)"
Comment 2 Sourceware Commits 2019-03-06 15:21:42 UTC
The master branch has been updated by Nick Clifton <nickc@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=912ebfa0d748b4a762dbc4311364c38692c7f626

commit 912ebfa0d748b4a762dbc4311364c38692c7f626
Author: Nick Bowler <nbowler@draconx.ca>
Date:   Wed Mar 6 15:20:29 2019 +0000

    Allow the use of the ORIGIN and LENGTH attributes in expressions inside MEMORY regions.
    
    	PR 24289
    	* ldexp.c (fold_name): Allow lookups of the LENGTH and ORIGIN
    	attributes during the first phase.
Comment 3 Nick Clifton 2019-03-06 15:26:43 UTC
Hi Nick,

  Thanks for the bug report and patch.  I have checked the patch in, so I
  hope that this resolves the problem.

Cheers
  Nick