Why MergeObjectFromObjects1 rule is needed?

I replaced runtime_loader and libroot.so (clang version of libroot.so currently cause problem with infinite output similar to runtime_loader) from GCC build and now it is working!
Haiku%20(clang)

3 Likes

libroot.so issue is reproduceable on regular Haiku build by putting it it lib folder:

	thread 50177: w>StyledEdit: Open 
		state: Exception (Segment violation)

		Frame		IP			Function Name
		-----------------------------------------------
		0x7ff500d1f000	0x375bea4b94	/boot/home/Desktop/New folder/lib/libroot.so + 0xf6b94 
			Unable to retrieve disassembly for IP 0x375bea4b94: address does not point to a function.
		0x7ff500d1f020	0x375bea4c67	/boot/home/Desktop/New folder/lib/libroot.so + 0xf6c67 
		0x7ff500d1f040	0x375bea4c67	/boot/home/Desktop/New folder/lib/libroot.so + 0xf6c67 
		0x7ff500d1f060	0x375bea4c67	/boot/home/Desktop/New folder/lib/libroot.so + 0xf6c67 
		0x7ff500d1f080	0x375bea4c67	/boot/home/Desktop/New folder/lib/libroot.so + 0xf6c67 
		0x7ff500d1f0a0	0x375bea4c67	/boot/home/Desktop/New folder/lib/libroot.so + 0xf6c67 
		0x7ff500d1f0c0	0x375bea4c67	/boot/home/Desktop/New folder/lib/libroot.so + 0xf6c67 

...

		0x7ff500d5dc20	0x375bea4c67	/boot/home/Desktop/New folder/lib/libroot.so + 0xf6c67 
		0x7ff500d5dc40	0x375bea4c67	/boot/home/Desktop/New folder/lib/libroot.so + 0xf6c67 
		0x7ff500d5dc60	0x375bea4c67	/boot/home/Desktop/New folder/lib/libroot.so + 0xf6c67 
		0x7ff500d5dce0	0x20f8463de0a	agg::rasterizer_compound_aa<agg::rasterizer_sl_clip<agg::ras_conv_dbl> >::sweep_styles() + 0x18a 
		0x7ff500d5ddd0	0x20f8463e964	void agg::render_scanlines_compound<agg::rasterizer_compound_aa<agg::rasterizer_sl_clip<agg::ras_conv_dbl> >, agg::scanline_u8, agg::scanline_bin, agg::renderer_base<agg::pixfmt_alpha_blend_rgba<agg::blender_rgba_pre<agg::rgba8, agg::order_bgra>, agg::row_ptr_cache<unsigned char>, unsigned int> >, agg::span_allocator<agg::rgba8>, BPrivate::Icon::IconRenderer::StyleHandler>(agg::rasterizer_compound_aa<agg::rasterizer_sl_clip<agg::ras_conv_dbl> >&, agg::scanline_u8&, agg::scanline_bin&, agg::renderer_base<ag 
		0x7ff500d5ddf0	0x20f8463b3b3	BPrivate::Icon::IconRenderer::_CommitRenderPass(BPrivate::Icon::IconRenderer::StyleHandler&, bool) + 0x33 
		0x7ff500d5def0	0x20f8463bbed	BPrivate::Icon::IconRenderer::_Render(BRect const&) + 0x78d 
		0x7ff500d5df20	0x20f8463c0a4	BPrivate::Icon::IconRenderer::Render() + 0x24 
		0x7ff500d5e280	0x20f8462fc60	BIconUtils::GetVectorIcon(unsigned char const*, unsigned long, BBitmap*) + 0x1c0 
		0x7ff500d5e2d0	0x20f84630006	BIconUtils::GetVectorIcon(BNode*, char const*, BBitmap*) + 0xf6 
		0x7ff500d5e3a0	0x20f846301c0	BIconUtils::GetIcon(BNode*, char const*, char const*, char const*, icon_size, BBitmap*) + 0x180 
		0x7ff500d5e460	0x20f8462cb3b	BPrivate::Storage::Mime::DatabaseLocation::GetIconForType(char const*, char const*, BBitmap&, icon_size) + 0x16b 
		0x7ff500d5e540	0xd8f3f37fbc	BPrivate::IconMenuItem::IconMenuItem(BMenu*, BMessage*, char const*, icon_size) + 0xbc 
		0x7ff500d5e7a0	0xd8f3f01753	BPrivate::BContainerWindow::AddMimeMenu(BMimeType const&, bool, BMenu*, int) + 0x3e3 
		0x7ff500d5e8e0	0xd8f3f01a2a	BPrivate::BContainerWindow::AddMimeTypesToMenu(BMenu*) + 0x1aa 
		0x7ff500d5e920	0xd8f3f533a6	BPrivate::BPoseView::AddPosesCompleted() + 0x36 
		0x7ff500d5e940	0xd8f3f1dd8c	BPrivate::BFilePanelPoseView::AddPosesCompleted() + 0xc 
		0x7ff500d5ea50	0xd8f3f65676	BPrivate::BPoseView::MessageReceived(BMessage*) + 0x9e6 
		0x7ff500d5ec80	0x20f845c260e	BWindow::DispatchMessage(BMessage*, BHandler*) + 0xb3e 
		0x7ff500d5eca0	0xd8f3f1c3ad	BPrivate::TFilePanel::DispatchMessage(BMessage*, BHandler*) + 0xd 
		0x7ff500d5ed30	0x20f845bdc5b	BWindow::task_looper() + 0x1bb 
		0x7ff500d5ed50	0x20f84503f2b	BLooper::_task0_(void*) + 0x1b 
		0x7ff500d5ed80	0x375be24f99	__wcstof_internal + 0x1f09 
		00000000	0x7fcc4b325260	commpage_thread_exit + 0 

		Registers:
			  rip:	0x000000375bea4b94
			  rsp:	0x00007ff500d1f000
			  rbp:	0x00007ff500d1f000
			  rax:	0x0000001e3113c240
			  rbx:	0x0000001e3113c240
			  rcx:	0x0000000000000004
			  rdx:	0x0000000000000001
			  rsi:	0x0000000000000000
			  rdi:	0x0000001e3113c240
			   r8:	0x0000000000000000
			   r9:	0x0000000000000006
			  r10:	0x00007ff500d5da10
			  r11:	0x0000001e31153c18
			  r12:	0x0000000000000001
			  r13:	0x8000000100000000
			  r14:	0x0000000000000004
			  r15:	0x00007ff500d5e0b0
			   cs:	0x002b
			   ds:	0x0000
			   es:	0x0000
			   fs:	0x0000
			   gs:	0x0000
			   ss:	0x0023
			  st0:	nan
			  st1:	nan
			  st2:	0
			  st3:	0
			  st4:	0
			  st5:	0
			  st6:	0
			  st7:	nan
			  mm0:	{0, 0, 0, 0}
			  mm1:	{0x100, 0, 0, 0}
			  mm2:	{0, 0, 0, 0}
			  mm3:	{0, 0, 0, 0}
			  mm4:	{0, 0, 0, 0}
			  mm5:	{0, 0, 0, 0}
			  mm6:	{0, 0, 0, 0}
			  mm7:	{0xf83a, 0xffff, 0, 0}
			 xmm0:	{0, 0, 0, 0, 0, 0, 0, 0}
			 xmm1:	{0, 0x6000, 0xdf5f, 0x401e, 0, 0, 0, 0}
			 xmm2:	{0, 0, 0, 0, 0, 0, 0, 0}
			 xmm3:	{0, 0, 0, 0, 0, 0, 0, 0}
			 xmm4:	{0, 0, 0, 0x3fe0, 0, 0, 0, 0}
			 xmm5:	{0, 0x6000, 0xe15f, 0x409e, 0, 0, 0, 0}
			 xmm6:	{0x6, 0, 0x2, 0, 0x12, 0, 0xa600, 0xffff}
			 xmm7:	{0x1, 0, 0x7, 0, 0x67, 0, 0x2d10, 0}
			 xmm8:	{0, 0, 0, 0, 0, 0, 0, 0}
			 xmm9:	{0, 0xc000, 0xbebe, 0x4022, 0, 0, 0, 0}
			xmm10:	{0, 0, 0, 0, 0, 0, 0, 0}
			xmm11:	{0, 0xc000, 0xbebe, 0x4022, 0, 0, 0, 0}
			xmm12:	{0, 0, 0, 0x403a, 0, 0, 0, 0}
			xmm13:	{0, 0, 0, 0x403a, 0, 0, 0, 0}
			xmm14:	{0, 0, 0xf0f1, 0x4004, 0, 0, 0, 0}
			xmm15:	{0, 0x6000, 0xdf5f, 0x403e, 0, 0, 0, 0}

libroot.so + 0xf6c67 is inside memset function and is return address after _memset external funstion. Seems that _memset is dynamically linked with something wrong and call itself.

Problem in runtime_loader is the same. </boot/system/runtime_loader@0x000000bc843cf000> <unknown> + 0x1d787 is also return address of _memset. Problem is likely that clang produce memset call inside memset implementation causing stack overflow.

I commented some code in memset implementation to avoid infinite recursion and now pure clang/lld Haiku build is working fine:

extern "C" void*
memset(void* ptr, int chr, size_t length)
{
	auto value = static_cast<unsigned char>(chr);
	auto destination = static_cast<uint8_t*>(ptr);
/*
	if (length < 32) {
		memset_small(destination, value, length);
		return ptr;
	}
	if (length < 2048) {
		memset_sse(destination, value, length);
		return ptr;
	}
*/
	memset_repstos(destination, value, length);
	return ptr;
}

Trac ticket: #15827.

2 Likes

Remaining problems with Haiku clang build:

  1. Linking of boot_loader_bios_ia32 fails because __divdi3, __moddi3, __udivdi3, __umoddi3 symbols are not found.
  2. Cleanup of Jam files is required:
    2.1 Clang need --no-rosegment -znorelro flags for kernel, kernel add-ons and runtime_loader.
    2.2 clang headers should be used insted of GCC.
    2.3 Some clang-specific warnings need to be silenced.
    2.4 Many old clang-specific handling should be removed because it is obsolete.
  3. Hybrid 32 bit builds need to be checked.
  4. Invalid MBR is generated and some tools fails to compile because MBR size is wrong.
  5. atexit is used in kernel and kernel add-ons instead of __cxa_atexit. Probably some Haiku target settings in clang are wrong.
2 Likes

You need a 32-bit libgcc, which comes with the x86_64 cross compiler but of course is not available when GCC is not used. Iā€™ve hacked one into my Jamfiles before and made this work.

Is there a good reason we should not just fix the kernel here?

Such asā€¦? Iā€™ve already moved most Clang-specific stuff that was not needed.

./configure already does this?

Yes. This used to work, LLVM changed something around version 7 or so and now it doesnā€™t, and I never looked into it.

No, this flags are not needed if #15819 and #15820 will be fixed. lld use different segment layout for better security.

I didnā€™t checked exactly yet, I currently build Haiku with clang without clang handling and with some patches. Clang handling donā€™t work for me.

1 Like

Following build method is working fine:

clang -c -m32 mbr.S
llvm-objcopy -O binary mbr.o mbr.bin

Also work with gcc and objcopy.

Returning to start post question, lld PE/COFF linker seems donā€™t support -r option. I tried to build PE module for haiku_loader.efi with clang/lld and MergeObjectFromObjects1 rule fails. Note that when linking PE executable, object files need to be in COFF format, ELF is not supported.