[Solved] Rust string comparision fail

Programming, for all ages and all languages.
Post Reply
User avatar
pvc
Member
Member
Posts: 201
Joined: Mon Jan 15, 2018 2:27 pm

[Solved] Rust string comparision fail

Post by pvc »

I can't help but wonder why this

Code: Select all

println!("{:?}", "abc" == "abc");

prints

Code: Select all

false


I tried to use BTreeMap<&str, ...>, but it completely failed to match anything. I even tried the example from https://doc.rust-lang.org/std/collections/struct.BTreeMap.html. But it failed to display the review of 'Office Space'. When I try to compare strings this way in normal program, everything works as supposed. But in #![no_std] environment, it just fails horribly.
Last edited by pvc on Fri Mar 12, 2021 3:39 am, edited 1 time in total.
Ethin
Member
Member
Posts: 624
Joined: Sun Jun 23, 2019 5:36 pm
Location: North Dakota, United States

Re: Rust string comparision fail

Post by Ethin »

Could you put your actual code here? Instead of a single line? I can get string comparisons to work fine in my OS.
User avatar
iansjack
Member
Member
Posts: 4604
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: Rust string comparision fail

Post by iansjack »

[quote="pvc"]I can't help but wonder why this

Code: Select all

println!("{:?}", "abc" == "abc");
prints

Code: Select all

false

It prints

Code: Select all

true
for me.

More to the point - why would you ever want to do a comparison of two constants like this?
User avatar
pvc
Member
Member
Posts: 201
Joined: Mon Jan 15, 2018 2:27 pm

Re: Rust string comparision fail

Post by pvc »

Found it. It turns out that my memcmp implementation had a bug. I absolutely forgot that there are some small bits of assembly code I had to provide at the very beginnning. I've managed to somehow copy the wrong body for my memcmp subroutine from my earlier project.

@iansjack To show that something that should definitely work, doesn't.
Ethin
Member
Member
Posts: 624
Joined: Sun Jun 23, 2019 5:36 pm
Location: North Dakota, United States

Re: [Solved] Rust string comparision fail

Post by Ethin »

I'm not sure how your doing things, but you should not need to write implementations of memcmp, memmove or anything else like that. The Rust core library already defines these and the compiler should be automatically generating calls to them. Do your best not to reimplement the wheel; you will find that the majority of low-level functions (memcmp, memmove and such) are things you just don't need to do in Rust, which is pretty nice. You need to do things like asm functions and such (hlt, outb, etc.), but you don't need to do things like population count or memory comparison or movement functions. (Generally, any functions that you'd need to define in libgcc can be safely omitted because they're most likely already defined in libcore, or a variant of them is. Use libcore as much as possible. (Yes, its possible to omit libcore, but I have no idea why you'd ever want to.))
User avatar
pvc
Member
Member
Posts: 201
Joined: Mon Jan 15, 2018 2:27 pm

Re: [Solved] Rust string comparision fail

Post by pvc »

Ethin wrote:I'm not sure how your doing things, but you should not need to write implementations of memcmp, memmove or anything else like that. The Rust core library already defines these and the compiler should be automatically generating calls to them.


It wouldn't link without 'memcpy', 'memcmp' or 'memset'. These have to be provided. Even 'core' crate documentation mentions it. It may be that if I used 'cargo' to somehow build my kernel, these could be provided by LLVM but I am doing this with Makefiles. First, I compile my kernel as static (.a) library and then link it with my multiboot startup code and few extra object files.
Ethin
Member
Member
Posts: 624
Joined: Sun Jun 23, 2019 5:36 pm
Location: North Dakota, United States

Re: [Solved] Rust string comparision fail

Post by Ethin »

Yeah, your not doing things properly. Cargo should be the sole tool you use to generate binaries; you shouldn't need makefiles (that's what Cargo is for). Its very possible to write a 32-bit kernel that uses multiboot without makefiles. To do so, you need a target definition file; this looks something like:

Code: Select all

{
"llvm-target": "x86_64-kernel-none",
"data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128",
"arch": "x86_64",
"target-endian": "little",
"target-pointer-width": "64",
"target-c-int-width": "32",
"os": "none",
"executables": true,
"linker-flavor": "ld.lld",
"linker": "rust-lld",
"panic-strategy": "abort",
"disable-redzone": true,
"features": "-mmx,-sse,+soft-float"
}

Another target definition for a custom pure rust bootloader looks like this:

Code: Select all

{
    "llvm-target": "x86_64-unknown-none-gnu",
    "data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128",
    "linker-flavor": "ld.lld",
    "linker": "rust-lld",
    "pre-link-args": {
        "ld.lld": [
       "--script=linker.ld"
   ]
    },
    "target-endian": "little",
    "target-pointer-width": "64",
    "target-c-int-width": "32",
    "arch": "x86_64",
    "os": "none",
    "features": "-mmx,-sse,+soft-float",
    "disable-redzone": true,
    "panic-strategy": "abort",
    "executables": true,
   "relocation_model": "static"
}

Information on custom target definitions can be found over here and some extra info is over here.
Then, you need to create a .cargo directory with a config.toml file inside that looks something like:

Code: Select all

[unstable]
build-std = ["core", "compiler_builtins", "alloc"]

[build]
# Replace this target string with your custom JSON file
target = "x86_64-kernel-none.json"

Then you can include custom asm to prepare your kernel for protected mode and all that jaz. You include that in your main.rs file with the global_asm! macro. The setup might seem a bit convoluted but once you get it working you (typically) never have to touch it again.
Edit: also, you *need* to do this on nightly. Beta or stable channels won't let you do this stuff.
User avatar
pvc
Member
Member
Posts: 201
Joined: Mon Jan 15, 2018 2:27 pm

Re: [Solved] Rust string comparision fail

Post by pvc »

@Ethin
I was able to cobble up something that uses cargo only. Now I struggle with multiple targets, which in my case are arch×mach permutations. I am able to build for multiple targets, but there are still 2 places I need to change to do so. I need to automate my build.rs (it's responsible for compiling .s files) a little bit better. Otherwise, it works.

EDIT: Multiple targets work now.
Ethin
Member
Member
Posts: 624
Joined: Sun Jun 23, 2019 5:36 pm
Location: North Dakota, United States

Re: [Solved] Rust string comparision fail

Post by Ethin »

Congratulations. Enjoy OS Dev on Rust! :-)
Post Reply