#Ultra

1 messages · Page 2 of 1

prime wraith
#

can i do it first try or not

onyx turret
#

i wanna see the gdt init fail

#

do it

prime wraith
#

well its doing something

ornate torrent
#

bro

#

f'... {addr :x} ...'

prime wraith
#

im just doing print(symbol)

#

thats default python formatting

ornate torrent
#

oh lol

dusky kraken
#

are you using dataclass?

prime wraith
#

yep

dusky kraken
#

ah

ornate torrent
#

I didn't look that close - only saw the base-10 pointer integer value

#

dataclasses probably have something to format it in base-16

prime wraith
#

dataclass is insanely OP

#

probably, I just printed it to make sure im parsing shit correctly

ornate torrent
#

me when twohundred dataframes with different column sets because different data sources provide differently structured data

prime wraith
#

lol

#

lol i found a bug in linux kallsyms

#

should i fix it or not i wonder

#

ah wait nvm im just rarted

prime wraith
#

alright im done with reading in the symbols, filtering them, sorting and discarding stuff outside of text including linux compat

#

tomorrow i have to start actual token interning tables

#
def is_linker(self) -> bool:
    if LINUX_COMPAT:
        if len(self.name) < 8:
            return False
        
        if not self.name.startswith("__"):
            return False
        
        return any(self.name.startswith(x) for x in [
            "__start_",
            "__stop_",
            "__end_",
        ]) or any(self.name.endswith(x) for x in [
            "_start",
            "_end",
        ])
    
    return self.name.startswith("linker_symbol")
#

least insane python code

uneven abyss
#

we have nm at home

prime wraith
#

this is parsing nm output

#

Looks like my build of linux has 125855 text symbols

#

at least those that pass the filter

dusky kraken
prime wraith
#

Ye

latent geode
#

I wonder how well kallsyms compression would work with mangled symbols

#

a lot of substrings are often repeated

uneven abyss
#

will ultra have the IO_ULTRing

#

far superior to io_uring

prime wraith
#

it wont have anything superior because its aiming for linux abi compatibility with userspace

#

that means all syscalls are 1:1

prime wraith
uneven abyss
#

omg

#

we're saved

prime wraith
#

yes

#

given i implement all syscalls

#

or well the nvk driver would have to be ported like leo did for managarm

uneven abyss
#

infy flavored linux best os

prime wraith
#

but all other drivers im gonna do myself

#

if u read the title post for this thread

#

it outlines my goals basically

uneven abyss
#

let's gooooo cuda drivers

prime wraith
#

if i work on it at this pace that will only take 5 years

#

anyway back to kallsyms

prime wraith
#

hmm fuck

#

the compound token table is somehow sublty different for my script and linux

#

idk why

#

have to debug this

#

hmm the symbol list is exactly the same and sorted identically so this is optimistic at least

#

and my script decompresses the symbol names correctly also, so compression logic is correct yet somehow produces different shit???

#

so now its just a matter of serializing this into an assembly file

#

it was a very subtle thing where tokens with identical scores would choose the last

#

linux picks the first tho

dusky kraken
#

generate an object file directly trl

#

it's not that hard trl

prime wraith
#
class TokenTable:
    class TokenizedSymbol:
        def __init__(self, symbol: Symbol):
            self.tokens: List[int] = [ord(c) for c in symbol.canonical_name()]

    def __init__(self, symbols: List[Symbol]) -> None:
        self.symbols = [TokenTable.TokenizedSymbol(s) for s in symbols]

        # This stores two-byte sequences and we want to have O(1) lookups
        self.multibyte_tokens: List[int] = [0] * 0x10000 # (UINT16_MAX + 1)

        # Top 256 tokens that will end up in kallsyms
        #
        # These are recursive:
        # If the token at index only has 1 entry this is the token
        # Otherwise it's a compound token consisting of two sub-tokens
        self.best_tokens: List[List[int]] = [[]] * 0x100 # (UINT8_MAX + 1)

        for symbol in self.symbols:
            self.__add_symbol(symbol, record_for_best=True)

        self.__optimize()

    def __for_each_token(self, symbol: TokenizedSymbol, addend: int,
                         record_for_best: bool = False) -> None:
        for i in range(0, len(symbol.tokens) - 1):
            self.multibyte_tokens[
                (symbol.tokens[i + 1] << 8) + symbol.tokens[i]
            ] += addend

        if record_for_best:
            for token in symbol.tokens:
                self.best_tokens[token] = [token]

    def __add_symbol(
        self, symbol: TokenizedSymbol, record_for_best: bool = False
    ) -> None:
        self.__for_each_token(symbol, +1, record_for_best)

    def __remove_symbol(self, symbol: TokenizedSymbol) -> None:
        self.__for_each_token(symbol, -1)

    def __most_used_multibyte_token(self) -> Tuple[int, int]:
        best_score = -1
        best_index = 0

        for i, score in enumerate(self.multibyte_tokens):
            if score <= best_score:
                continue

            best_score = score
            best_index = i

        return (best_index, best_score)

    def replace_all_matching_compound(
            src: List[int], target: Tuple[int, int], replacement: int
    ) -> List[int]:
        dst: List[int] = src.copy()
        i: int = 0

        while i < (len(dst) - 1):
            if dst[i] != target[0] or dst[i + 1] != target[1]:
                i += 1
                continue

            dst[i:i + 2] = [replacement]

        return dst

    def __compress_with_compound_token(self, idx: int) -> None:
        token = self.best_tokens[idx]

        for symbol in self.symbols:
            compressed_tokens = TokenTable.replace_all_matching_sequences(
                symbol.tokens, (token[0], token[1]), idx
            )

            if compressed_tokens == symbol.tokens:
                continue

            self.__remove_symbol(symbol)
            symbol.tokens = compressed_tokens
            self.__add_symbol(symbol)


    def __optimize(self) -> None:
        for i, this_token in reversed(list(enumerate(self.best_tokens))):
            if this_token:
                continue

            most_used = self.__most_used_multibyte_token()
            if most_used[1] == 0:
                # Nothing to optimize, no tokens are used
                break

            self.best_tokens[i] = [
                (most_used[0] >> 0) & 0xFF,
                (most_used[0] >> 8) & 0xFF
            ]

            self.__compress_with_compound_token(i)

    def unwind_compound(self, tokens: List[int]) -> str:
        out_str = ""

        for token in tokens:
            if len(self.best_tokens[token]) == 1:
                out_str += chr(token)
            else: # compound token
                out_str += self.unwind_compound(self.best_tokens[token])

        return out_str

The entire compression algo

dusky kraken
prime wraith
#

what are you producing it for exactly?

dusky kraken
#

my assembler

#

also written in scheme

prime wraith
#

ah

#

fuck, the table produced is different for vmlinux

#

thats probably because i filter or not filter something i should

#

also it takes like half a minute for linux lmao

#

python is slow as shit

#

vaguely similar

#

ill have to diff the symbols im processing vs their script

prime wraith
#

holy shit

#

turns out it was correct all along, i was just comparing against stage 1 link

#

so now my script generates identical token table to linux kallsyms

dusky kraken
#

nice

prime wraith
#

file gen time

#

im thinking for my kernel ill just use a .C file, im not sure why you'd do assembly

#

but ill have GAS for linux compat

#

or maybe ill do NASM

#
$ time python3 generate_symbol_tables.py symbols.asm --binary ~/linux/vmlinux --linux-mode

real    0m18.582s
user    0m16.691s
sys     0m0.213s
#

kinda sad

latent geode
prime wraith
#
/mnt/d/ultra/scripts$ time ~/linux/scripts/kallsyms ~/linux/System.map > linux.syms

real    0m1.331s
user    0m0.358s
sys     0m0.068s
#

SKULL python is very fast

latent geode
#

oof

prime wraith
#

i now need to add serialization to file and im done with it

#
$ time python3 generate_symbol_tables.py symbols.asm --binary ../build-clang-x86_64/kernel-x86_64 --linux-mode

real    0m0.478s
user    0m0.243s
sys     0m0.055s
#

well at least for my kernel its fast

latent geode
#

lol

prime wraith
#

ah i just realized u must use assembly, because you do multiple link stages and at first stage the symbol table is empty but symbols must still be there

#

in C u cant really make an empty array

#

or u could do a dummy symbol i guess but optimizations and shit

wide ether
prime wraith
#

static unsigned long symbols[0]; doesnt really work right

wide ether
#

static unsigned long empty_array[] = {};?

#

if that's what you mean

prime wraith
#

idk, if that works yeah

#

if that symbol actually can be linked against

wide ether
#

you can make it extern

#

sorry i wasn't really reading back that much, what is the problem exactly

prime wraith
#

nvm its not really a problem

#

im too lazy to explain it

wide ether
#

lmfao

prime wraith
#

this shit is a lot more annoying to make in an abstract manner than i had thought

#

but at least i can 100% prove that my thing is correct this way by diffing against linux

prime wraith
#

holy shit its coming together

#

Tioread16_at literally 2 bytes to encode the entire name

prime wraith
#

very close to being done

prime wraith
#

Kernel symbol table

versed obsidian
#

nice

#

have fun

prime wraith
#

Lol yes

#

I have the fastest symbol table but no gdt

thorny kelp
#

lol

onyx turret
#

ur os already more advanced with symbol lookup then most

prime wraith
#

Its not even integrated into the os yet and the script is not completely finished lol

onyx turret
#

yea still lmao

#

also prepare your eyes to get cursed

#

anyways

#

why are u so interested in very fast symbol lookup exactly

prime wraith
#

What am I looking at

onyx turret
#

failed install of a kde vista theme, with some config i stole

prime wraith
#

Ah

prime wraith
onyx turret
#

makes sense

#

what are your plans on the VMM design, as well as what are you gonna use for the PMM (buddy?)

#

is ultra gonna be monolithic or

prime wraith
#

Pmm is gonna be buddy yeah

onyx turret
#

makes sense

prime wraith
#

Its a mini Linux project

#

So yeah ofc

onyx turret
#

right

prime wraith
#

I wanna study every subsystem in depth then implement a simplified version of it for my kernel basically

onyx turret
#

fair fair

#

have fun implementing evdev

#

or DRM or any complicated linux interface

#

honestly ultra will probs be in userspace before nyaux ever runs xorg lol

#

to be fair

#

your really good at programming your code is fucking crazy smart

prime wraith
#

Yeah ill have to do evdev and all netlink stuff

onyx turret
#

yea fun

prime wraith
#

I'm not getting to userspace any time soon

onyx turret
#

fucking insane how good it is

prime wraith
#

Lol how

onyx turret
#

i cannot explain it into words

#

it just is

#

onyx turret
prime wraith
#

Well thanks idk

onyx turret
prime wraith
#

Which is gonna take tons of time

onyx turret
#

that is fair

#

u can get to userspace easily

onyx turret
#

as long as u got a PMM, VMM, VFS, some backing FS, scheduler

prime wraith
#

If I wanna do anything meaningful with the userspace I need at least an entire vfs and tmpfs

#

Which is gonna take 99999 years

onyx turret
#

yea tmpfs and a vfs is easy

#

that wont take 99999 years lol

prime wraith
#

Dunno

onyx turret
#

unless u want things like a dentry cache or a page cache itll take u at most 2 days for the VFS itself

#

tmpfs is lit 15 minutes

#

its just files in ram

prime wraith
#

It will probably take me at least a week to study how Linux does vfs and dentry

#

And page cache

onyx turret
#

that is fair, i think linux does it in a way quite complicated

prime wraith
#

I'm trying to make it at least somewhat production quality

#

But we'll see not sure

#

Thats kinda far away rn

#

I need a buddy and heap first

onyx turret
#

makes sense

#

slab is easy enough same with buddy

#

goodluck!

prime wraith
#

I'm not that great

onyx turret
prime wraith
#

We'll see when I get there lol

onyx turret
#

okay lol

latent geode
prime wraith
#

I appreciate your belief in my non retarness

prime wraith
#
infy@DESKTOP-IGT40G0:/mnt/d/ultra/scripts$ ~/linux/scripts/kallsyms ~/linux/System.map > linuxsymbols.S
infy@DESKTOP-IGT40G0:/mnt/d/ultra/scripts$ python3 generate_symbol_tables.py mysymbols.S --binary ~/linux/vmlinux --linux-mode --gnu-as
infy@DESKTOP-IGT40G0:/mnt/d/ultra/scripts$ diff linuxsymbols.S mysymbols.S
infy@DESKTOP-IGT40G0:/mnt/d/ultra/scripts$ echo "$?"
0
#

holy fuck

#

i cant believe it works

dusky kraken
#

nice

prime wraith
#

400k lines of GAS

#

(for the linux kernel kallsyms)

#

it was annoying as fuck for the final touchups

#

because the original script uses alternate form for some fucking reason

#

in some formatting

#

and doesnt in other

#

and also mixes tabs and spaces

#

so rn the serializer is hacked with some linux awareness, ill have to get rid of that somehow

#

other than that the serialization stuff is pretty clean imo

#

should be easy to implement C/NASM "backends"

#

if i get rid of GAS-specific hacks for linux compat

#

or hide them away

#

the linuxes script is 750 lines and mines only 650

#

(mine is two orders of magnitude slower trl )

#

or well, one order of magnitude actually

prime wraith
#

okay so

#

script cleanup time

#

GAS backend will be linux-compat exclusive

#

for my kernel ill have C mode probably

#
infy@DESKTOP-IGT40G0:~$ cat test.c
#include <stdio.h>

int array[] = {
};

int main() { printf("%p\n", array); }
infy@DESKTOP-IGT40G0:~$ gcc test.c -Wall -Wextra
infy@DESKTOP-IGT40G0:~$ ./a.out
0x614c4ba30014
#

yeah okay apparently this is allowed

#

then i dont see why it wouldnt work

onyx turret
prime wraith
#

im also curious whether u can emit constants like x = text_begin - offset

#
infy@DESKTOP-IGT40G0:~$ cat test.c
#include <stdio.h>
#include <stdint.h>

uint8_t data;
uint8_t *offset = &data + 123;

int main() { printf("%p\n", offset); }
infy@DESKTOP-IGT40G0:~$ gcc test.c -Wall -Wextra
infy@DESKTOP-IGT40G0:~$ ./a.out
0x63e754636094
#

okay lol yeah

#

then i dont see any blockers to a C backend

prime wraith
#

probably one because it needs to have a unique address

#

0 actually lmao

#

never seen sizeof return 0

latent geode
prime wraith
latent geode
#

makes sense

prime wraith
#

because an empty array right next to it is 4 bytes away

sterile kayak
prime wraith
#

yeah

#

its strange that sizeof returns 0 tho

#

because empty structs dont return 0

#

or well i guess its because of C sizeof rules for arrays

vestal zealot
#

Yooo I found the ultra thread lets go

haughty notch
#

I dodn't know about this thread nooo

#

Too little shilling from infy

errant temple
#

Enticing ngl

wide ether
#

get it

proper tulip
#

yeah only if the keyboard layout wasnt gay

errant temple
#

Nah 1650 or T400 first

errant temple
proper tulip
#

thats fair, i wanted a laptop tho :(

#

so i need to keep looking

errant temple
#

Also will this get lil and/or nvo support trl

wet quail
#

not function pointer, function

prime wraith
#

Progress update:

#

i've been touching grass a bit but im still finishing the kallsyms script

#

i wanna get rid of linux-specific hacks and put them away

#

so i have a clean backend for my kernel

#

and so that someone else can easily add their backend if they want to use the script for their kernel

#

basically just trying to separate stuff out into classes

#

and use enums instead of backend-specific strings

red parcel
#

wait, why not just use an elf for the symbols instead of a dedicated format?

#

given the only job of kallsyms is debug anyways

#

in freebsd /dev/ksyms is literally an elf file with a symbol table and string table

prime wraith
red parcel
#

ksymtab can be generated using a section attribute

prime wraith
#

yeah thats what my backend will be doing

red parcel
#

I think the only reason it is not is because they have support for using relative stuff

prime wraith
red parcel
#

as in, having the symbol data be two int32 which are relative to the location

#

kallsyms and ksymtab are two completely different things

prime wraith
#

idk what ksymtab is

red parcel
#

its what used for module linking (aka EXPORT_SYMBOL)

prime wraith
#

ah yeah, that one i dont care about

#

kallsyms is whats used for linking modules and backtraces

#

its just a set of 8 tables for fast symbol lookup and address -> symbol conversion

#

and its compressed as well

red parcel
#

wdym linking modules? you mean builtin ones? if so they are just ar files that are linked iirc

prime wraith
#

no, i mean dynamic modules

#

they depend on symbols that are core kernel

red parcel
#

dynamic modules don't use kallsyms

#

like kernel modules

#

they use the ksymtab

#

but like, why overcomplicate and not just use the symbols that come as part of being an elf file

prime wraith
#

#1385970208631427173 message

prime wraith
#

so either u clean it up at runtime or pay the price of linear scan every time

red parcel
#

I clean it up once at boot and then do a binary search

prime wraith
#

yeah so u pay a runtime cost plus u probably dont do symbol interning right

#

which kallsyms does

red parcel
#

yeah because who cares

prime wraith
#

idk why not

#

like u pay nothing at runtime and it takes very little space

red parcel
#

linux does it because they have like 250k symbols inside the kernel easily

#

and the interning doesn't save that much

#

or well, it does when you have 100s of thousands of symbols

#

tbf I hate it just because one of the most annoying parts of the linux build that everytime I get to it I dread it because it takes a few more seconds

#

and it means that for debugging you need vmlinux-to-elf

prime wraith
#

yeah their make is kinda annoying

#

even if u changed literally nothing it still takes 10 seconds to do nothing

red parcel
#

and somehow its still one of the best buildsystems for C

prime wraith
#

idc about that so i can just reuse my kallsyms

#

oh and also they use kallsyms everywhere for bpf and other types of tracing

red parcel
#

well, kallsyms can be quite slow for string -> address

prime wraith
#

how so

#

its pretty fast

red parcel
#

because you need to decompress the strings for the lookup

#

unless they changed all it works

prime wraith
#

decompression is just

for i in range(symbol_name):
    name += names[name_offsets[i]]
#

and its like 5-10 chars on average

#

and the names are sorted ofc

red parcel
#

yeah but you need linear search for finding the symbol name

#

you sure? I think kallsyms is sorted by address

#

not name

prime wraith
#

u dont, they're sorted by both address and lexicographically

#

like i said its 8 separate tables

#

1 table sorts by offsets from base (aka address), the other sorts by name

red parcel
#

well, I know that I had to add sleeps for a kernel module that used kallsyms_lookup_name to resolve symbols because otherwise it would freeze the kernel enough for the sound driver to crash

prime wraith
#

and u have other aux tables to help convert from name index to address index

prime wraith
red parcel
#

is it kallsyms_seqs_of_names?

ornate torrent
prime wraith
#

that thing converts an index of a name to its address

red parcel
#

it seems to only be 6.2+

prime wraith
#

oh yeah so I guess its a 6.2 addition

prime wraith
#

was typing something else first

red parcel
#

ok yeah I didn't know about that one lol

prime wraith
#

i guess it was slow af before

red parcel
#

when I last looked at it was v4.something

prime wraith
#

now u basically binary search for your name

#

when u find it, u grab its index

#

then convert it to the index of the address

red parcel
#

yeah that is fine then

prime wraith
#

and grab the address

red parcel
#

ksymtab is basically just sorted by name

#

the only other feature it has is namespace

prime wraith
#

i mean yeah makes sense

#

u dont need reverse lookups there i guess

red parcel
#

and the fact you can do GPL symbols :^)

prime wraith
#

what kind of namespace

red parcel
#

a string

prime wraith
#

like u can put global symbols behind a namespace?

red parcel
#

yeah

#

idr exactly how it works

prime wraith
#

how does it work in C?

#

lol

red parcel
#

seems like you need to use MODULE_IMPORT_NS for explicit stuff

#

and of course there is something to do it automatically

prime wraith
#

interesting

red parcel
#

and you can set a default namespace for your module

prime wraith
#

i guess if u have 99999 modules all with their own global symbols u must have some sort of ksymtab

#

otherwise u will have collisions

#

for modules that have multiple C files that need to call into each other

red parcel
#

yeah

prime wraith
#

why the hell do they have a lexer in genksyms

#

does it actually scan for EXPORT_SYMBOL

#

in every c file

red parcel
#

damn, apparently linux has symbols in the kallsyms for function padding as well

#

prefixed by __pfx_

prime wraith
#

wdym?

red parcel
#

the alignment nops the compiler provides for functions get their own symbol

prime wraith
#

lol

#

well the ksyms is not super smart, it just includes everything that lies inside the text section

#

i know because my shit is not super smart and the thing it produces is identical

red parcel
#
functions will have PADDING_BYTES of NOP in front of them. Unwinders
and other things that symbolize code locations will typically
attribute these bytes to the preceding function.

Given that these bytes nominally belong to the following symbol this
mis-attribution is confusing.
prime wraith
red parcel
#

it seems to actually be objtool feature

prime wraith
#

but its unlikely that a function faults at nop lol

#

why is this so complex lol

#

i guess this is the thing that produces ksymtab

red parcel
prime wraith
#

why does it need to fucking parse C lol

red parcel
#

I mean, there is no way it parses the entire included source tree when generating kallsyms

prime wraith
#

this is ksymtab

red parcel
#

ohhhh

#

yeah then this is even more confusing

prime wraith
#

what the hell is going on

red parcel
#

ooo I remember something

#

ksymtab has a crc32 table as well

#

of the actual code of the function

#

I think the idea of it is to check its the same function you linked against or something?

#

I don't remember exactly

prime wraith
#

but like

#

for that u can just open the elf and find the symbol

#

offset

red parcel
#

yeah I have no idea what it is doing there

prime wraith
#

or is this doing a crc32 of the source code lol

#

im confused af lmao

red parcel
#

I forgot linux added the cleanups macros lol

prime wraith
#

is this in the actual kernel?

red parcel
#

yeah

prime wraith
#

damn

prime wraith
#

what exactly does scoped_guard(rcu) do?

uneven abyss
prime wraith
#

Documentation/kbuild/gendwarfksyms.rst

#

this cannot be real

red parcel
#

bruh why is it from the source code

prime wraith
#

so it lexes it to find the body of the thing i guess?

#

crazy stuff

red parcel
prime wraith
#

ah

#

makes sense

red parcel
prime wraith
#

cool

#
However, this is incompatible with languages such
as Rust, where the source code has insufficient information about
the resulting ABI. With CONFIG_GENDWARFKSYMS (and CONFIG_DEBUG_INFO)
selected, **gendwarfksyms** is used instead to calculate symbol versions
from the DWARF debugging information, which contains the necessary
details about the final module ABI.
#

apparently theres also a dwarf version

red parcel
#

jesus

#

such overcomplication for nothing lol

prime wraith
#

i wonder what would be the simplest way to do module versioning

#

or maybe u just dont do it

red parcel
#

at work we have a module system where we also export and do it manually

#

so we do something like EXPORT(symbol_name, numeric_version)

#

and it just does a bit of name aliasing

prime wraith
#

ah yeah fair

#

just append a version if doing a breaking change yeah

red parcel
#

so whoever imports essentially does symbol_name_v1 and so on

prime wraith
#

its manual but u can also skip a version bump if its a bug fix and not a behavior change for example right

red parcel
#

which is also explicit

#

yeah

#

you only increment if you broke abi or behaviour

prime wraith
#

for core functions thats probably not that often

prime wraith
red parcel
#

its for embedded stuff that don't run linux :^)

prime wraith
#

u have ur own kernel? thats cool

red parcel
#

its built on top of existing rtoses but yeah

prime wraith
#

i will probably just do numeric_version as well when I get around to that

red parcel
#

tbh

#

you could just have the module include the kernel version in the header or something

#

and verify it at load time

prime wraith
#

fair lol

red parcel
#

kernels really don't need backwards/forward module compat

prime wraith
#

im wondering why they didnt just do that

red parcel
#

unless you have OEM drivers ig

prime wraith
#

because they have out of tree modules i guess?

red parcel
#

yeah

prime wraith
#

but those are built against headers that come from a specific version anyway

red parcel
#

yeah, its weird

#

like linux doesn't have stable kernel abi anyways

prime wraith
#

yeah im not sure what problem is being solved here

#

maybe we're forgetting some use case or edge case lol

red parcel
#

we have wrote kernel modules that work between linux majors, but only because they don't use the structs whenever possible lol

prime wraith
#

lol yeah

red parcel
#

and for them I wouldn't want symbol versioning anyways since the idea is to be generic

prime wraith
#

modules that support a lot of kernel versions tend to have tons of ifdefs

red parcel
#

especially one that is generated from the freaking source code

prime wraith
#

yeah

#

the nt module style is pretty interesting in that regard

#

that u just use explicitly filled calback tables

#

or ioctls or wahtever they call them

red parcel
#

I sure do like it when a subsystem has a function that is a dispatcher for other functions

prime wraith
#

yeah lol

#

like storport with 10 billion option switch table

red parcel
#

yeah that one

#

I was trying to find it lol

prime wraith
#

lmao

red parcel
#

either way at least it works :^)

#

meanwhile you have freebsd

#

which has kernel abi

prime wraith
#

yeah, no C parsing required

red parcel
#

with userspace

prime wraith
#

to find out if it works

red parcel
prime wraith
#

is this like ntdll

red parcel
#

yeah

prime wraith
#

ah

#

do u know how they do modules?

red parcel
#

but a bit weirder since it also accesses some kernel structs directly

prime wraith
#

very interesting

red parcel
#

the kernel has symbols that contain offsets in structs

#

so process enumeration is looking at the kernel structures directly that the offsets are exported in the symbol list

#

iirc

prime wraith
#

lol

#

thats one way to do it i guess

red parcel
#

tbh I have no idea how their kernel modules work

#

I don't think I saw their source code having EXPORT like macro

prime wraith
#

@willow fern sorry to ping, do u happen to know how freebsd dynamic modules work? how do they do versioning/export?

#

linux literally parses .c files for that

red parcel
#

I think it just uses elfs (?)

prime wraith
#

id hope so lol

red parcel
#

ok yeah they use elf

#

bruh they have support for ifuncs in the kernel

prime wraith
#

lol

prime wraith
red parcel
#

nope not seeing anything for that

prime wraith
red parcel
#

:^)

prime wraith
#

even freebsd developers use it

#

they dir structure is so weird i cant even find C code lmfao

red parcel
#

lmao

#

yeah its weird

prime wraith
#

like they have sys/modules

#

but there is no code inside there

#

just makefiles

#

wtf?

red parcel
#

the elf code is under sys/kern/link_elf_obj.c

willow fern
red parcel
#

oh yeah

#

you can man kernel functions

#

its fun

prime wraith
#

ah

prime wraith
willow fern
#

but tldr is any non-static function is exported, and there are depend directives so you can specify version requirements

willow fern
#

the actual code is in e.g. sys/dev/somedriver/somedriver.c and the counterpart in sys/modules is just the case for building it as a module (rather than a static part of the kernel)

prime wraith
#

so if i have module a with do_bar in bar.c used by foo.c, and module b with do_bar they will collide?

#

even if module a doesnt consider it an exported api

willow fern
prime wraith
#

i meant more like if module c is loaded that wants do_bar

#

if u load just those 2 they wont collide because the symbols wont have UNDEF or whatever

prime wraith
willow fern
#

it looks as though it won't look except at what you MODULE_DEPEND() on

prime wraith
#

ohhhhh

#

so they basically use namespaces

#

like linux recently introduced

#

ok that makes sense

#
DRIVER_MODULE(bytgpio, acpi, bytgpio_driver, 0, 0);
MODULE_DEPEND(bytgpio, acpi, 1, 1, 1);
MODULE_DEPEND(bytgpio, gpiobus, 1, 1, 1);
ACPI_PNP_INFO(bytgpio_gpio_ids);
#

thats cool

#

i cant find what DRIVER_MODULE does tho

#

it seems to mention acpi twice

#

also whats interesting is version numbers are hardcoded

wide ether
#

are you going to do kconfig?

errant temple
#

nvidia-open

prime wraith
prime wraith
wide ether
errant temple
#

nvo is independent of kernel space considerations, mostly meme

wide ether
#

^

prime wraith
#

thats cool

errant temple
#

just sysdeps + bindings

wide ether
#

i'm going to adopt lil, that's for sure trl

#

you will catch me dead before i reinvent gpu drivers

errant temple
#

I might just start memeing with sandy + ivy bridge this week if time allows so that I have something to merge in mammogram

prime wraith
#

Letsgo

#

I might add it as an optional module why not

#

If it can be exported via DRM

#

Maybe also to check vs my code

#

But I wanted to make an igpu driver if u look at my thread title post

#

modesetting is less of a priority tho

#

Mostly interested in Accel

wide ether
#

funnily enough for me it's the opposite

#

i'd like a working modeset, especially multi monitor

errant temple
#

yeah same

prime wraith
#

u can have your bootloader set both to native res

#

after that u never really need to touch it

wide ether
#

you can not

prime wraith
#

why not?

wide ether
#

most GOP drivers don't modeset any secondary screens

#

so you only get one fb

#

this might be different on laptops, but on every pc i've ever touched you only ever get an fb on the first monitor

prime wraith
#

i see

#

my test devices are single screen latops

#

so i dont care that much

wide ether
#

fair enough

#

but if i'm touching gpus it will be 100% via lil

prime wraith
#

sadge

prime wraith
#
>>> "%#x" % 0
'0x0'
#

mfw python doesnt respect alternate form

#

like cmon

#

all u had to do was strip the 0x

uneven abyss
#

what is this 😭

#

kinda cursed

prime wraith
#

# enables alternate form in printf formatting

#

python seems to support it, but incorrectly

#

for hex numbers it prefixes 0x unless the number is 0

#

but python adds 0x always

#

alright my serializer is now completely abstracted away from the backend

#

idk why im wasting time doing all that stuff

#

but wahtever

#

and still matches linux kallsyms (for the vmlinux binary) completely so thats great

prime wraith
onyx turret
vestal zealot
#

Infy out here making the ultimate testing framework

ornate jasper
#

lol

prime wraith
#

funny thing is this is not even a framework

#

u have to use it manually lmfao

ornate jasper
#

reminds me i should work on a test runner for my project sometime

vestal zealot
#

What does it even do, anyway?

prime wraith
#

one sec ill post it

prime wraith
#

symbol table for the kernel

#

the C backend took like 20 minutes to add which is cool

vestal zealot
prime wraith
#

ah yeah true

#

i should probably add const to all of those

vestal zealot
#

So this is for in-kernel backtracing?

prime wraith
#

backtracing and symbol lookup for dynamic modules

vestal zealot
#

I see

ornate jasper
#

nice

prime wraith
#

its overengineered to have log N for address -> symbol and symbol -> address

#
  • string interning
vestal zealot
#

Are symbols big enough that you'd need this compression?

#

For unmangled symbols I can hardly imagine.

prime wraith
#

its not even for that

#

if u have a lot of symbols using the same prefix for example the prefix gets interned into one byte for all of those symbols

#

and it automatically interns most frequeuntly occuring tokens

vestal zealot
#

Why not just sort them and binary search? Sounds a lot easier to do.

prime wraith
#

for example when i add uacpi, all uacpi_ prefixes will turn into 1 byte

prime wraith
#

its just that the names are compressed as well

ornate jasper
#

idk whether to feel inadequate that i just parse the elf symbol table now lmao

vestal zealot
#

For my kernel's module loading I was just gonna make it a dynamic ELF file and call it a day meme

prime wraith
#

which may be less adequate

ornate jasper
prime wraith
ornate jasper
#

whatever works lol

prime wraith
#

next step is CFI stack unwinding so i can use these

#

ill use .eh_frame

#

already have it set as LOAD

ornate jasper
#

if you get eh frame working youll be ahead of me there, theres some more zig std innards i need to splice into to get it working for me (thread context stuff, zig std assumes that if it doesnt have ucontext or the windows capturecontext api then it cant use eh frame stuff)

#

so good luck there

prime wraith
#

ah that sucks

#

but tbh the guess algorithm works really well

#
while stack < stack_end:
   if addr_in_kernel_text(*stack): print(" > %s", symbol_from_addr(*stack))
   stack += 8
ornate jasper
#

assuming stack is the actual trace not the raw machine stack yeah

prime wraith
#

no, like raw machine stack

#

most likely the only place you will have ktext addresses is stuff pushed by call

ornate jasper
#

you can still get a backtrace without eh frame without guessing like that, using rbp

prime wraith
#

that requires no-omit-frame-pointer

ornate jasper
#

assuming your calling convention is sane and uses that

prime wraith
#

which is like 10-15% perf loss

#

from what ive seen

ornate jasper
#

imo its worth it to have the backtraces but ig that depends on whats worth to you

prime wraith
#

if u dont have CFI yeah

prime wraith
#

i wonder how the f to interpret this

prime wraith
#

damn actually this profiler is pretty good

#

i was able to shave off about 5 seconds

#

(when generating symbols for vmlinux)

#

whatever i guess, only takes 0.4 seconds for my kernel, which is good enough for me

#

no low hanging fruit left

#

caching symbol lengths would probably shave off a few more, but idc

proper tulip
#

i'll take a look at the script when you are done with it

#

i like optimizing python code :^)

prime wraith
#

it's 850 loc 💀

#

but ill appreciate it

proper tulip
#

but if you say there's no low hanging fruits there probably isn't

prime wraith
#

if you manage to optimzie it

prime wraith
# proper tulip but if you say there's no low hanging fruits there probably isn't

not sure

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
     19/1    0.000    0.000   18.810   18.810 {built-in method builtins.exec}
        1    0.033    0.033   18.810   18.810 generate_symbol_tables.py:1(<module>)
        1    0.381    0.381   18.758   18.758 generate_symbol_tables.py:758(main)
        1    0.024    0.024   14.451   14.451 generate_symbol_tables.py:319(__init__)
        1    0.001    0.001   13.818   13.818 generate_symbol_tables.py:403(__optimize)
      192    8.867    0.046   13.620    0.071 generate_symbol_tables.py:377(__compress_with_compound_token)
  3151379    3.810    0.000    3.915    0.000 generate_symbol_tables.py:337(__for_each_token)
  1638618    0.172    0.000    2.189    0.000 generate_symbol_tables.py:348(__add_symbol)
  1512761    0.164    0.000    2.062    0.000 generate_symbol_tables.py:353(__remove_symbol)
   378575    0.590    0.000    2.032    0.000 generate_symbol_tables.py:722(emit)
        1    0.000    0.000    1.203    1.203 generate_symbol_tables.py:307(make_context)
        1    0.005    0.005    1.203    1.203 generate_symbol_tables.py:247(__init__)
        1    0.142    0.142    1.199    1.199 generate_symbol_tables.py:176(__init__)
27858052/27858032    0.886    0.000    0.886    0.000 {built-in method builtins.len
#

basically the core compression stuff is what takes the longest

#

--no-compress trl

uneven abyss
#

this is very ultra

#

is this python script open source

prime wraith
#

yeah once i finish it ofc

#

scripts/generate_symbol_tables.py in the ultra repo

prime wraith
#

very ultra

obtuse sparrow
prime wraith
#

mostly because i decided to support linux so i have two backends and everything is abstracted away into classes

obtuse sparrow
#

I've a lua script that does that in less than 200 loc

prime wraith
#

this is the script atm

obtuse sparrow
#

Mine just uses nm on a intermediary version of the kernel binary and then generates an .asm file. Then i just assemble that and link it to produce the final binary

prime wraith
#

yeah this is basically what this does

#

although it generates .c files

#

or GAS optionally

#

if u look closely it calls nm

#

the idea is u have multiple stages:

  1. link the kernel against a fake empty symbol table (that this script produces if u provide no binary)
  2. link the kernel against the new symbol table
  3. regenerate symbol table
  4. relink the kernel
  5. if something shifted, repeat
proper tulip
#

how do u do 5 lol

#

do you just generate the symbol table one more time?

prime wraith
#

regen symbol table, relink kernel

#

yeah

proper tulip
#

and compare it to the last?

#

ah

prime wraith
#

since it only includes .text stuff its unlikely to shift around

#

but even if it included every symbol, this would work anyway u just have to filter out the symbol table symbols

#

im scared of running mypy on this lmfao

#

inb4 999999999 warnings

#
infy@DESKTOP-IGT40G0:/mnt/d/ultra/scripts$ python -m mypy --disallow-incomplete-defs --no-implicit-optional ./generate_symbol_tables.py  | wc -l
61
infy@DESKTOP-IGT40G0:/mnt/d/ultra/scripts$ python -m flake8 --ignore=E743 ./generate_symbol_tables.py | wc -l
44
#

how am i this bad still

prime wraith
#
$ python -m mypy --disallow-incomplete-defs --no-implicit-optional ./generate_symbol_tables.py
Success: no issues found in 1 source file

yay

#

had to add a bunch of stupid assert isinstance for it to shut up about subclasses

prime wraith
#

alright, fixed every warning and also 0 global variable left LETSFUCKINGGOOOOOO

#

will be integrating into the kernel tomorrow and maybe start with CFI

#

takes only 0.27s for my kernel, so thats great

ornate jasper
#

nice

little aurora
#

ideally the symbol table goes into one of the data sections which is ideally after text (you control the linker script)

#

so nothing will shift

#

because you said it yourself, it's only text symbols

#

and text won't move

#

Limine does it like this and it works just fine

#

i've never seen its stack trace fail, ever

prime wraith
#

so the generated text changes

#

but yeah if u only include text the odds are small

#

also linux stores .rodata in .text so for them its very possible

#

but i dont ofc

little aurora
#

because you're just linking

#

and at compile time the compiler doesn't know

#

so the generated code that is linked will end up being the same

#

(this is all without considering LTO of course, but i assume you're just gonna be forcing LTO off for all this)

prime wraith
#

i dont see why LTO shouldnt be supported

little aurora
prime wraith
#

maybe with LTO there is a chance it changes

little aurora
prime wraith
#

why not?

little aurora
#

so all of this is pointless

#

LTO mangles everything

prime wraith
#

well it will have to produce something for eh_frame

#

some sort of a backtrace

little aurora
#

it has symbols, they are just not helpful symbols

#

if we're talking about plain elf symbols from text

prime wraith
#

yeah im curious how the backtraces would change with lto

little aurora
#

just try it

#

i would personally not bother supporting LTO + this symbol stuff

prime wraith
#

do u expect it to be like one huge function?

little aurora
#

it basically is

prime wraith
#

like its more work to not

little aurora
#

well, it's free now that you did the useless work needed to support it as above

little aurora
#

not in an objective sense

#

for example it wouldn't be free for Limine without changing the symbols producing code

#

and that is effort for nothing since, as above, LTO mangles everything

prime wraith
#

also like, how does runtime linking work for LTO if its all mangled? linux still supports runtime modules there

little aurora
#

external symbols aren't done away with

#

LTO isn't stupid

#

but anything that isn't to be exported externally gets mangled up

#

seriously, just try it

prime wraith
#

so only local symbols basically?

little aurora
#

local to the whole executable

#

not to the TU

prime wraith
#

last time i checked its either global or local

little aurora
#

that's ELF

prime wraith
#

how do u mark it as exported externally?

little aurora
#

for a normal ELF executable, basically, you don't

#

well, there is a way

#

you can link a non-LTO TU (that can be an asm file) in, and the asm file externs and uses all of the symbols you don't want the linker to disappear

prime wraith
#

i dont think linux does that and it still works somehow?

little aurora
#

what works?

prime wraith
#

module linking at runtime

little aurora
#

but that's because modules aren't "normal executables" as i said above

#

they are objects

prime wraith
#

but the kernel is

#

so according to u it would get mangled

#

and not have symbols

little aurora
#

and why do you think that is a problem?

prime wraith
#

because runtime modules want to link against kernel symbols

little aurora
#

i cannot speak for Linux or any of the black magic they do to get this working

#

because i simply do not know

prime wraith
#

yeah idk

#

but ill experiment

#

to see what it generates

little aurora
#

if i am wrong feel free to correct me and i will crucify myself for spreading misinfo :p

prime wraith
#

sure lol

prime wraith
vestal zealot
prime wraith
#

well for that you would have to enable per-function sections

#

which im not going to do ofc

#
config LD_DEAD_CODE_DATA_ELIMINATION
    bool "Dead code and data elimination (EXPERIMENTAL)"
    depends on HAVE_LD_DEAD_CODE_DATA_ELIMINATION
    depends on EXPERT
    depends on $(cc-option,-ffunction-sections -fdata-sections)
    depends on $(ld-option,--gc-sections)
    help
      Enable this if you want to do dead code and data elimination with
      the linker by compiling with -ffunction-sections -fdata-sections,
      and linking with --gc-sections.

      This can reduce on disk and in-memory size of the kernel
      code and static data, particularly for small configs and
      on small systems. This has the possibility of introducing
      silently broken kernel if the required annotations are not
      present. This option is not well tested yet, so use at your
      own risk.
#

lol

#

@little aurora I think i solved the mystery

prime wraith
#
#define __EXPORT_SYMBOL_REF(sym)            \
    .balign 8                ASM_NL    \
    .quad sym
little aurora
#

well yeah

#

that corroborates what i said basically

#

if i understand this right

prime wraith
#

it puts this asm into .export_symbol

#

so yeah ig

wide ether
#

man

#

i'm missing out on all this cool stuff with rust

little aurora
#

rewrite CSMWrap in rust

wide ether
#

💀

prime wraith
#

yeah it basically generates this at compile time

#

just a C file with exports

#

and this uses inline asm to reference the symbol

#

which probably prevents LTO from destroying it

little aurora
#

it does

#

because even when you do LTO, you can pass .o files that are not LTO files, which means that to some degree if a symbol has to be used by a non-LTO TU/object it can't just disappear

prime wraith
#

does global asm() statements u put produce a non LTO-ed .o?

little aurora
#

like for example, you can LTO programs using Nyu-EFI based on the template, and they will still work, despite all the shenenigans needed to make PEs out of ELFs

#

it still works because if the LD script needs a symbol or another TU that is not LTO needs a symbol, the symbol won't be disappeared

little aurora
#

maybe?

#

global asm() statements are super cringe anyways

#

if it's worth anything, my personally suggestion is to just force LTO off whenever you want to turn on this type of symbol tracking

#

that's the main reason why Limine forces LTO off, all the time

#

because i think the stacktrace being there is always worth it

#

over the minor speedup granted by LTO

prime wraith
#

yeah we'll see, for now i dont care about LTO at all, it's not even supported

red parcel
#

LTO is basically unity build at the IR level, so anything that a unity build would be able to do LTO can do (to some degree)

#

For hidden symbols it will obviously be more prone to inline since it knows it won't duplicate it

#

But it can still happily inline huge functions at times if the compiler thinks it should

ornate torrent
#

(assuming C and -fvisibility=hidden)

prime wraith
#

Man cmake is incredibly powerful:

$ python3 ../build.py
Not rerunning cmake since build directory already exists (--reconfigure)
[  2%] Built target kernel-link-script
[  5%] Built target e9-console-objects
[  7%] Generating kernel_symbols_stub.c
[ 10%] Building C object kernel/CMakeFiles/kernel-x86_64-nosymbols.dir/kernel_symbols_stub.c.o
[ 12%] Linking C executable ../kernel-x86_64-nosymbols
[ 52%] Built target kernel-x86_64-nosymbols
[ 55%] Generating kernel_symbols.c
[ 57%] Building C object kernel/CMakeFiles/kernel-x86_64.dir/kernel_symbols.c.o
[ 60%] Linking C executable ../kernel-x86_64
[100%] Built target kernel-x86_64
#

i basically cloned my kernel target into two separate targets using literally one macro

#
macro(ultra_kernel_targets_apply FN)
    foreach(TARGET IN LISTS ULTRA_KERNEL_TARGETS)
        cmake_language(CALL ${FN} ${TARGET} ${ARGN})
    endforeach()
endmacro()
#

and i literally call

ultra_sources(
    entry.c
    panic.c
    console.c
    log.c
    io.c
)

And it adds the sources to both targets while also making sure they only have to build once

#

then I make the final kernel binary depend on the symbol table and thats it

#

we have 135 symbols, base is at 0xFFFFFFFF80000000 and it seems to get linked in correctly

prime wraith
#

and the symbol table from the final kernel binary seems to match the one with the stub symbol table, so mint was right

#

nothing shifted so no two-step relink needed

sterile kayak
#

I'd add a verification step to ensure that the symtab is actually correct, but nice

prime wraith
#

yeah i think ill add a step to verify it

#
[ 97%] Generating kernel_symbols_final.c
[100%] Built target ensure-symbol-table-matches

Done

prime wraith
#

And it adds the sources to both targets while also making sure they only have to build once
That was wrong

#

So i had to actually change it so my kernel is first generated as a static library

#

and then linked with the symbol table + module objects into the final binary

#

as an added bonus that stripped some extra unused symbols which is cool

ornate torrent
prime wraith
#

hmm, i do and it seems to work still?

#

what sort of shenanigans?

ornate torrent
#

there is -fwhole-archive or something which I would recommend using unless you eventually want to run into trouble.

#

speaking from experience.

prime wraith
#

actually fuck that, I just did

- add_library(${ULTRA_KERNEL_OBJECTS} STATIC)
+ add_library(${ULTRA_KERNEL_OBJECTS} OBJECT)
#

now all my symbols are back

#

forgot cmake can just do plain objects as a target

ornate torrent
#

linking together many object files into a single object file also has some pitfalls, though it has been a while since I've messed with that kind of thing.

prime wraith
#

i also have an instance of that for my module generator lol

#

id appreciate it if u remember which lmfao

prime wraith
ornate torrent
#

good for you

#

because ld -r is tricky.

prime wraith
#

that said...

#
add_custom_command(
    OUTPUT
    ${MODULE_OUTPUT}
    DEPENDS
    ${MODULE_OBJECT_TARGET} ${MODULE_SOURCES}
    COMMAND
    ${CMAKE_LINKER}
    -r -T${ULTRA_MODULE_LD_SCRIPT}
    $<TARGET_OBJECTS:${MODULE_OBJECT_TARGET}> -o ${MODULE_OUTPUT}
    COMMAND_EXPAND_LISTS
)
#

i do have this

#

how do i make -r safe

ornate torrent
#

define 'safe'

#

if it works, it works.

prime wraith
#

aka

#

pitfall avoidance

#

is there some option i should use

ornate torrent
#

now iirc one of the pitfalls occured when I had multiple subdirectory (every subdirectory would get its own kernel_objs.o, and those would all be recursively merged into a single top-level kernel_objs.o).

prime wraith
#

oh ok, I shouldnt have any recursive objects i think

#

even a module with subdirectories will get concatenated into one thing

ornate torrent
#

so long as you don't have any global constructors or initcall-like things, you should avoid most pitfalls.

prime wraith
#

well i do have those lmfao

ornate torrent
#

in modules?

prime wraith
#

for runtime modules it just has an entrypoint symbol

#

a static one works as an initcall yes

ornate torrent
prime wraith
#

anway ur saying scary things

ornate torrent
#

or any ld -r for that matter

ornate torrent
prime wraith
#

wdym?

#

if it has multiple translation units it will need an -r

ornate torrent
#

not if a module is compiled as builtin, does it?

prime wraith
#

oh yeah

#

in that case i just ultra_link_libraries(${MODULE_OBJECT_TARGET})

prime wraith
#

to make it one object file

ornate torrent
#

do you then rename it to foo.ko?

prime wraith
#

ye set(MODULE_OUTPUT "${CMAKE_BINARY_DIR}/${MODULE_NAME}.ko")

wide ether
#

just use .so's galaxybrain

prime wraith
#

nah fuck sos lmao

wide ether
#

why

#

less relocation work

prime wraith
#

slow

ornate torrent
prime wraith
#

real

ornate torrent
wide ether
prime wraith
ornate torrent
#

runtime LTO

wide ether
#

DLTO

dusky kraken
#

libbinutils.a linked into ld.so

ornate torrent
#

alright have we written a JIT VM for GIMPLE yet?

dusky kraken
dusky kraken
ornate torrent
#

yeah but it's hardly a VM.

prime wraith
dusky kraken
#

eh but neither is llvm and it fills a similar niche (and gimple ~= llvm ir)

ornate torrent
#

something like Hotspot but it runs GIMPLE.

prime wraith
#

so its a tradeoff

ornate torrent
prime wraith
#

with GOT/PLT u can share .text pages among all processes

#

thats probably a big reason why they do it

dusky kraken
#

i mean also not needing to relink the world to fix a libc bug

#

etc

ornate torrent
#

or you can do it the NT way and no DLL ASLR.

prime wraith
#

i mean, your executable depends on a specific libc version anyway right

dusky kraken
#

with glibc your executable depends on specific versioned symbols

#

so newer glibc keeps working

prime wraith
#

oh really

dusky kraken
#

yes you can attach versions to individual symbols

ornate torrent
#

glibc puts in a lot of effort into application forwards compatibility

prime wraith
#

thats cool

prime wraith
ornate torrent
#

'don't break userspace' but applied to userspace.

dusky kraken
#

and the static linker picks the latest one if unspecified, and the dynamic linker then picks the right symbol from the dso when linking

prime wraith
#

rseq 😿

ornate torrent
prime wraith
#

how does plt help with this exactly

#

u could just relocate in ld.so

#

like every reference to it

dusky kraken
#

the plt is there to avoid having to write the address in multiple places

prime wraith
#

yeah

prime wraith
dusky kraken
#

if you statically link libc, and then a bug is found and fixed in libc, you need to relink every program to apply the libc bugfix

#

(same applies to all libraries)

prime wraith
#

oh u mean that

#

I was talking more about using got/plt vs plain object linking at runtime lol

#

is it possible to generate an so that doesnt use that even

dusky kraken
#

i mean yeah i get that, i was bringing that up as another benefit for dsos for user space

prime wraith
#

yeah fair

dusky kraken
#

the only relocs it'd have would be R_RELATIVE

prime wraith
#

do references to the got/plt need to be relocated?

ember reef
dusky kraken
#

got entries get R_JUMP_SLOT and R_GLOB_DAT relocs (on x86_64)

#

depending on whether they're functions or pointers to data

prime wraith
#

i mean references to the got from .text

dusky kraken
#

no i mean the got array entries themselves

ornate torrent
prime wraith
#

yeah but do references have relocations as well?

dusky kraken
#

no accessing the got is done via pc-rel addressing

prime wraith
#

or how does it get away with a hardcoded offset

dusky kraken
#

the index into the got is known at static link time

prime wraith
#

ohh

ember reef
#

but on 64 bit theres tons of pcrel

#

so its less of an issue

#

(pcrel was added to the amd64 architecture specifically to provide microsoft a workaround to this PE issue. no im not joking.)

prime wraith
#

based nt no plt/got

ornate torrent
#

but then again

#

that isn't .text.

ember reef
#

yes

#

yeah thats far less common

prime wraith
#

COW'ed .rodata sad

ornate torrent
prime wraith
#

i mean yeah, ideally u dont cow it

#

lol

ember reef
#

yeah they dont need to set it read-only until after loading and linking is done

#

so its fine

#

to cow rodata during loading

dusky kraken
#

(or if using -fno-plt foo@plt is inlined into every foo call site)

ember reef
#

so it makes sense it works different

prime wraith
dusky kraken
#

yeah but you cant trash rax

#

it's a part of the calling conv

prime wraith
#

yeah whatever reg

ember reef
prime wraith
#

wait is jmp to an absolute address a thing?

#

didnt know that

prime wraith
ember reef
#

yeah, i alleviated it a bit with code (which by anecdotal data is vastly more common than data) by having the linker generate a jump to the final destination at the end of the text section and rerouting all the jumps to there, so that only that one jump needs to be relocated

#

which is sort of like a poor man's PLT

prime wraith
#

why poor lol

#

its literally plt

ember reef
#

is it

#

guess i independently invented plt

prime wraith
#

i mean yeah, there really isnt more to it

#

its just an array of addreses i think?

sterile kayak
#

the array of addresses is the got

ember reef
sterile kayak
#

plt is linker-generated thunk code that jumps to rtld (if unresolved) or the actual symbol (if resolved)

prime wraith
sterile kayak
#

yea

ember reef
#

i always felt lazy binding was of dubious value

prime wraith
#

i mean depends ig

ember reef
#

it came from some SunOS paper where even their own benchmarks on a 80s chip werent thaaat improved

sterile kayak
#

if you compile with -fno-plt you'd get something like call whatever@GOTPCREL(%rip)

prime wraith
#

so it reuses got to call into stuff?

ember reef
#

riscv's only improvement on the older riscs btw

#

auipc good

#

yaoi pc

prime wraith
#

riscv didnt learn from 32-bit pae that its terrible to have different format for different pt levels

ember reef
#

even with pae you can still do a recursive page table

prime wraith
#

its only the top-most level that changes anyway

ember reef
#

you just put the two page directories into consecutive entries in one of the page directories

prime wraith
#

and u would realistically populate it at cr3 load time

#

because it doesnt get invalidated by invlpg

#

its only 4 pointers afterall

ember reef
#

also they added cmpxchg8b to 32 bit chips specifically for updating PTEs atomically on PAE pretty sure

prime wraith
#

lol yeah probably