Relative expressions and ASSERT
H.J. Lu
hjl.tools@gmail.com
Fri Dec 17 04:17:00 GMT 2010
On Thu, Dec 16, 2010 at 4:01 PM, Alan Modra <amodra@gmail.com> wrote:
> On Thu, Dec 16, 2010 at 03:14:38PM -0800, H.J. Lu wrote:
>> Your patch doesn't work. I got
>>
>> ./ld: kernel image bigger than KERNEL_IMAGE_SIZE
>>
>> due to arch/x86/kernel/vmlinux.lds:
>>
>> ----
>> /*
>> * Build-time check on the image size:
>> */
>> . = ASSERT((_end - _text <= (512 * 1024 * 1024)),
>> "kernel image bigger than KERNEL_IMAGE_SIZE");
>
> Extracting the relevant parts from the kernel link script:
>
> SECTIONS
> {
> . = 0xc000;
> .text :
> {
> _text = .;
> *(.text)
> }
> _end = .;
> }
> ASSERT (_end - _text <= 0x100, "fail");
>
> You'd think that under the new rules, this ought to work. "_end" is
> an absolute address, so when evaluating "_end - _text", "_text" ought
> to be converted from relative to absolute, the subtraction resuling in
> an absolute address. Then 0x100 gets converted from a number to
> absolute address before being compared.
>
> The trouble is that "_end" is *not* treated as an absolute address but
> as a plain number. That makes ld convert "_end" to a .text relative
> address when evaluation "_end - _text", which doesn't cause a problem
> at that stage, but the result is a relative address. That means 0x100
> is converted to a .text relative address too, which gives the wrong
> result.
>
> The underlying problem is that we don't distinguish between plain
> numbers and absolute addresses once values are stored in symbols.
>
I am putting this into the Linux binutils.
--
H.J.
---
ld/
2010-12-16 H.J. Lu <hongjiu.lu@intel.com>
PR ld/12327
* ldexp.c (exp_fold_tree_1): Only make absolute symbol value
absolute.
ld/testsuite/
2010-12-16 H.J. Lu <hongjiu.lu@intel.com>
PR ld/12327
* ld-scripts/defined.exp: Run defined4.
* ld-scripts/defined4.d: New.
* ld-scripts/defined4.s: Likewise.
* ld-scripts/defined4.t: Likewise.
-------------- next part --------------
ld/
2010-12-16 H.J. Lu <hongjiu.lu@intel.com>
PR ld/12327
* ldexp.c (exp_fold_tree_1): Only make absolute symbol value
absolute.
ld/testsuite/
2010-12-16 H.J. Lu <hongjiu.lu@intel.com>
PR ld/12327
* ld-scripts/defined.exp: Run defined4.
* ld-scripts/defined4.d: New.
* ld-scripts/defined4.s: Likewise.
* ld-scripts/defined4.t: Likewise.
diff --git a/ld/ldexp.c b/ld/ldexp.c
index de7f9f2..c8fa331 100644
--- a/ld/ldexp.c
+++ b/ld/ldexp.c
@@ -691,12 +691,15 @@ fold_name (etree_type *tree)
static void
exp_fold_tree_1 (etree_type *tree)
{
+ bfd_boolean absolute;
+
if (tree == NULL)
{
memset (&expld.result, 0, sizeof (expld.result));
return;
}
+ absolute = TRUE;
switch (tree->type.node_class)
{
case etree_value:
@@ -851,6 +854,21 @@ exp_fold_tree_1 (etree_type *tree)
case etree_name:
fold_name (tree);
+ if (tree->name.name
+ && tree->name.name[0] != '.'
+ && tree->name.name[1] != '\0'
+ && link_info.hash)
+ {
+ struct bfd_link_hash_entry *h;
+
+ /* Only make absolute symbol value absolute. */
+ h = bfd_link_hash_lookup (link_info.hash, tree->name.name,
+ FALSE, FALSE, TRUE);
+ if (h
+ && (h->type == bfd_link_hash_defined
+ || h->type == bfd_link_hash_defweak))
+ absolute = (h->u.def.section == bfd_abs_section_ptr);
+ }
break;
default:
@@ -861,7 +879,8 @@ exp_fold_tree_1 (etree_type *tree)
/* Any value not inside an output section statement is an
absolute value. */
- if (expld.result.valid_p
+ if (absolute
+ && expld.result.valid_p
&& expld.section == bfd_abs_section_ptr)
make_abs ();
}
diff --git a/ld/testsuite/ld-scripts/defined.exp b/ld/testsuite/ld-scripts/defined.exp
index 15cc079..5742ae9 100644
--- a/ld/testsuite/ld-scripts/defined.exp
+++ b/ld/testsuite/ld-scripts/defined.exp
@@ -66,4 +66,5 @@ if ![ld_simple_link $ld tmpdir/def "$LDFLAGS -T $srcdir/$subdir/defined.t tmpdir
set prms_id 0
run_dump_test "defined2"
run_dump_test "defined3"
+run_dump_test "defined4"
set LDFLAGS "$saved_LDFLAGS"
--- /dev/null 2010-12-14 15:22:59.420000000 -0800
+++ binutils/ld/testsuite/ld-scripts/defined4.d 2010-12-16 14:00:46.264217155 -0800
@@ -0,0 +1,10 @@
+#ld: -Tdefined4.t
+#nm: -B
+#source: defined4.s
+
+# Check that arithmetic on DEFINED works.
+#...
+0+0 D defined
+#...
+0+0 D defined1
+#pass
--- /dev/null 2010-12-14 15:22:59.420000000 -0800
+++ binutils/ld/testsuite/ld-scripts/defined4.s 2010-12-16 12:46:23.558273203 -0800
@@ -0,0 +1,4 @@
+ .globl defined
+ .data
+defined:
+ .word 0
--- /dev/null 2010-12-14 15:22:59.420000000 -0800
+++ binutils/ld/testsuite/ld-scripts/defined4.t 2010-12-16 12:46:45.236797081 -0800
@@ -0,0 +1,6 @@
+SECTIONS {
+ .text : { *(.text) }
+ .data : { *(.data) }
+ .bss : { *(.bss) *(COMMON) }
+}
+defined1 = defined;
More information about the Binutils
mailing list