Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using syscalls and ld script #44

Open
cbytensky opened this issue Sep 3, 2022 · 5 comments
Open

Using syscalls and ld script #44

cbytensky opened this issue Sep 3, 2022 · 5 comments
Labels
help wanted Extra attention is needed

Comments

@cbytensky
Copy link

cbytensky commented Sep 3, 2022

I made a projet that produces 159-bytes ELF64 AMD64 binary:
https://github.com/cbytensky/hello_syscall

@johnthagen
Copy link
Owner

@cbytensky Looks nice! If you could add some more information to the README about the limitations (OS/portability, etc) and some details about why this reduces binary size (no std or libc bindings etc) I'll add your repo as a reference.

@cbytensky
Copy link
Author

cbytensky commented Sep 15, 2022

1. Use _start instead of main and get rid of startup code.

_start is the symbol that ld is lookig for as entry point.

1.1. In main.rs instead of fn main() write:

pub extern fn _start() {

1.2. In .cargo/config file in project dir:

[build]
rustflags = ["-C", "link-arg=-nostartfiles"]

1.3. (Optional) Add target

If there are custom build script in your project or in any crates that your project uses, you shoud also add this line to [build] section:

target = "x86_64-unknown-linux-gnu"

So .cargo/config will be:

[build]
target = "x86_64-unknown-linux-gnu"
rustflags = ["-C", "link-arg=-nostartfiles"]

Some examples you could see in https://github.com/cbytensky/helloworld_libc

@cbytensky
Copy link
Author

cbytensky commented Sep 16, 2022

2. Use custom build script.

2.1. Add rustflags to use custom build script

To use build script located in file elf64-static.ld add to .cargo/config:

[build]
rustflags = [ "-C", "link-arg=-Wl,-T,elf64-static.ld" ]

I made my build script elf64-static.ld mostly by removing parts of default build script and checking that program builds successfully.

2.2. Get default build script:

ld --verbose

2.3. Add to the build script program headers segments specifications:

PHDRS {
	text PT_LOAD FILEHDR PHDRS;
	interp PT_INTERP;
	dynamic PT_DYNAMIC;
}

2.4. Assign all sections to specific program header segments. For example assign t section to text segment:

	t : {
		⟨...⟩
	} :text

@cbytensky
Copy link
Author

cbytensky commented Sep 16, 2022

3. Using syscalls instead of libc

When using syscalls there is no need for dynamic linking that significally reduces file size.

Example here: https://github.com/cbytensky/hello_syscall

@johnthagen
Copy link
Owner

@cbytensky This is great. Could you add a central README that summarizes this (or a gist) that I could link too that discusses all of your techniques and perhaps has other links to your various subprojects.

Ideally, I'd like to see a small discussion about the tradeoffs/limitations of these methods as well.

When that's done, I'd be happy to add a link to this in the references section of this repo.

@johnthagen johnthagen added the help wanted Extra attention is needed label Feb 21, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

2 participants