Fix for kernel DRM build
PATCH 1/1 Fix for kernel DRM build
When building the latest 2.4.0-010109 kernel with DRI support enabled, I got the following link-time error:
ld: drivers/char/drm/drm.o: linking 64-bit files with 32-bit files
ld: drivers/char/drm/drm.o: linking constant-gp files with non-constant-gp files
It turns out that drm.o was built as follows:
rm -f drmlib.a
ar rcs drmlib.a init.o memory.o proc.o auth.o context.o drawable.o bufs.o lists.o lock.o ioctl.o fops.o vm.o dma.o ctxbitmap.o
rm -f drm.o
ld -r -o drm.o drmlib.a
Looks like the ar output confuses the linker. I don't even know if this is supposed to work with the current toolchain. In any case, if you remove the ar step and use ld -r directly the problem disappears. The enclosed patch fixes the DRI Makefile to remove the ar step.
Uros.
--
Uros Prestor
[email protected]
drivers/char/drm/Makefile +6 -8
@@ -63,9 +63,9 @@ lib-objs-mod := $(patsubst %.o,%-mod.o,$(lib-objs)) ifdef MAKING_MODULES - lib = drmlib-mod.a + lib = drmlib-mod.o else - obj-y += drmlib.a + obj-y += drmlib.o endif include $(TOPDIR)/Rules.make
@@ -73,13 +73,11 @@ $(patsubst %.o,%.c,$(lib-objs-mod)): @ln -sf $(subst -mod,,$@) $@ -drmlib-mod.a: $(lib-objs-mod) - rm -f $@ - $(AR) $(EXTRA_ARFLAGS) rcs $@ $(lib-objs-mod) +drmlib-mod.o: $(lib-objs-mod) + $(LD) -r -o $@ $(lib-objs-mod) -drmlib.a: $(lib-objs) - rm -f $@ - $(AR) $(EXTRA_ARFLAGS) rcs $@ $(lib-objs) +drmlib.o: $(lib-objs) + $(LD) -r -o $@ $(lib-objs) gamma.o: $(gamma-objs) $(lib) $(LD) -r -o $@ $(gamma-objs) $(lib)
This should be labeled a toolchain issue. The problem occurs whenever someone is building and linking against an "empty" archive. The same problem occurred in the "media/" subdirectory but I did a quick hack to work around the problem.
--david
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line · Uros Prestor
Uros> When building the latest 2.4.0-010109 kernel with DRI support Uros> enabled, I got the following link-time error:
Uros> ld: drivers/char/drm/drm.o: linking 64-bit files with
Uros> 32-bit files ld: drivers/char/drm/drm.o: linking constant-gp Uros> files with non-constant-gp files
Uros> It turns out that drm.o was built as follows:
Uros> rm -f drmlib.a ar rcs drmlib.a init.o memory.o proc.o
Uros> auth.o context.o drawable.o bufs.o lists.o lock.o ioctl.o Uros> fops.o vm.o dma.o ctxbitmap.o rm -f drm.o ld -r -o drm.o Uros> drmlib.a
Uros> Looks like the ar output confuses the linker. I don't even Uros> know if this is supposed to work with the current toolchain. Uros> In any case, if you remove the ar step and use ld -r directly Uros> the problem disappears. The enclosed patch fixes the DRI Uros> Makefile to remove the ar step.
Uros> Uros.
Uros> -- Uros Prestor [email protected]
Uros> diff -ruN linux-2.4.0-010109/drivers/char/drm/Makefile Uros> linux-2.4.0-010109.drm/drivers/char/drm/Makefile --- Uros> linux-2.4.0-010109/drivers/char/drm/Makefile Thu Jan 4 Uros> 13:07:01 2001 +++ Uros> linux-2.4.0-010109.drm/drivers/char/drm/Makefile Tue Jan 9 Uros> 13:43:21 2001 @@ -63,9 +63,9 @@ lib-objs-mod := $(patsubst Uros> %.o,%-mod.o,$(lib-objs))
Uros> ifdef MAKING_MODULES - lib = drmlib-mod.a + lib Uros> drmlib-mod.o else - obj-y += drmlib.a + obj-y += drmlib.o
Uros> endif
Uros> include $(TOPDIR)/Rules.make @@ -73,13 +73,11 @@ $(patsubst Uros> %.o,%.c,$(lib-objs-mod)): @ln -sf $(subst -mod,,$@) $@ Uros> -drmlib-mod.a: $(lib-objs-mod) - rm -f $@ - $(AR) Uros> $(EXTRA_ARFLAGS) rcs $@ $(lib-objs-mod) +drmlib-mod.o: Uros> $(lib-objs-mod) + $(LD) -r -o $@ $(lib-objs-mod) Uros> -drmlib.a: $(lib-objs) - rm -f $@ - $(AR) $(EXTRA_ARFLAGS) rcs Uros> $@ $(lib-objs) +drmlib.o: $(lib-objs) + $(LD) -r -o $@ Uros> $(lib-objs) Uros> gamma.o: $(gamma-objs) $(lib) $(LD) -r -o $@ $(gamma-objs) Uros> $(lib)
Quoted 5 lines · David Mosberger
This should be labeled a toolchain issue. The problem occurs whenever someone is building and linking against an "empty" archive. The same problem occurred in the "media/" subdirectory but I did a quick hack to work around the problem.
This patch seems to work for me.
H.J.
---
2001-01-09 H.J. Lu <[email protected]>
* elf64-ia64.c (elf64_ia64_merge_private_bfd_data): Don't merge with the empty input file.
elf64-ia64.c renamed from elf64-ia64.c.empty +4 -0
@@ -3973,6 +3973,10 @@ elf64_ia64_merge_private_bfd_data (ibfd, || bfd_get_flavour (obfd) != bfd_target_elf_flavour)return false; +/* If the input file has no data, we have nothing to merge. */ +if (ibfd->sections =NULL ) +return true; + in_flags =elf_elfheader (ibfd)->e_flags; out_flags =elf_elfheader (obfd)->e_flags;
Quoted 4 lines
ld:
drivers/char/drm/drm.o: linking 64-bit files with 32-bit files
ld:drivers/char/drm/drm.o: linking constant-gp files with non-constant-gp files
I've sent a proposed patch to [email protected] for comment.
I don't like HJ's proposed solution, which is to ignore the ELF header flags if an object file is empty. That can mask real errors, as this ar/ld -r trick is not the only way to create empty object files.
My proposed patch fixes the linker to notice when the output file is empty, and then we set the ELF header flags from the first member of the first archive even though we aren't linking it in. This fixes the kernel build failure. Alternatively, it might be better to check the ELF header flags of every member of every archive to avoid ambiguity, but that seemed like unnecessary extra work so I won't do that unless the binutils maintainers request it.
Here is my proposed patch.
2001-01-15 Jim Wilson <[email protected]>
* ldlang.c (lang_check): If file_chain.head is NULL, then find first member of first archive, and call bfd_merge_private_bfd_data on it.
Index: ldlang.c
=================================RCS file: /cvs/cvsfiles/devo/ld/ldlang.c,v retrieving revision 1.289
diff -p -r1.289 ldlang.c
*** ldlang.c 2000/07/10 11:46:54 1.289
--- ldlang.c 2001/01/16 00:03:58
*************** lang_check ()
*** 3477,3482 ****
--- 3477,3507 ----
bfd_set_error_handler (pfn);
}
} + + /* There can be no used input files if the only inputs are archives. + In that case, arbitrarily pick the first element of the first archive + and use that one to initialize private bfd data. This construct occurs + in the linux kernel, and if we don't have the bfd_merge_private_bfd_data + call, we can get errors in the final link. */
+ if (file_chain.head = NULL)
+ {
+ lang_input_statement_type *f;
+
+ for (f = (lang_input_statement_type *) input_file_chain.head;
+ f != NULL;
+ f = (lang_input_statement_type *) f->next_real_file)
+ {
+ if (f->the_bfd
+ && bfd_check_format (f->the_bfd, bfd_archive))
+ {
+ bfd *member;
+
+ member = bfd_openr_next_archived_file (f->the_bfd, (bfd *) NULL); + bfd_merge_private_bfd_data (member, output_bfd); + break;
+ }
+ }
+ }
}
/* Look through all the global common symbols and attach them to the
Quoted 7 lines · Jim Wilson
Quoted 4 lines
ld:
drivers/char/drm/drm.o: linking 64-bit files with 32-bit files
ld:drivers/char/drm/drm.o: linking constant-gp files with non-constant-gp filesI've sent a proposed patch to [email protected] for comment.
Quoted 7 lines
I don't like HJ's proposed solution, which is to ignore the ELF header flags if an object file is empty. That can mask real errors, as this ar/ld -r trick is not the only way to create empty object files.
My proposed patch fixes the linker to notice when the output file is empty, and then we set the ELF header flags from the first member of the first archive even though we aren't linking it in. This fixes the kernel build
Does that work with an empty archive or an archive with files of mixed types? I thought about your approach. But I decided against it since it didn't work with the cases above.
H.J.
Quoted 3 lines
Does that work with an empty archive or an archive with files of mixed types? I thought about your approach. But I decided against it since it didn't work with the cases above.
No, but I don't see how we can make those cases work in a reasonable fashion, except to give an error, and hence the user should not expect them to work. If there are linux kernel Makefiles that do this, then I would consider them broken.
If you want to argue for your solution, then you should make this argument on the [email protected] list, as that is where the issue will be decided.
Jim