rust-lang / rfcs

RFCs for changes to Rust
https://rust-lang.github.io/rfcs/
Apache License 2.0
5.98k stars 1.57k forks source link

Propose add function level inline assembly for rust. #1793

Open lygstate opened 8 years ago

lygstate commented 8 years ago

For example:

extern "C" { pub fn get_registers() inline_assembly = 'ByteArray Literal for the Object file to be linked directly'; }

and the ByteArray Literal could be generated a procedure macro.

extern "C" { pub fn get_registers() inline_assembly = get_registers_macro_assembly!(); }

lygstate commented 8 years ago

By this, we can implement section and other platform specific things directly without burden the rustc For example, the following is a MSVC construct for section implement.

void some_fucntion_implement_init_by_rust(void);
#pragma section(".CRT$XCU",read)
void (*some_fucntion_implement_init)(void) = some_fucntion_implement_init_by_rust;
#pragma comment(linker,"/include:some_fucntion_implement_init")

And the following is the HEX string generated by MSVC compiler: 64 86 03 20 19 05 2a 58 5b 01 20 20 0a 20 20 20 20 20 20 20 2e 64 72 65 63 74 76 65 20 20 20 20 20 20 20 20 55 20 20 20 8c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 0a 10 20 2e 64 65 62 75 67 24 53 20 20 20 20 20 20 20 20 68 20 20 20 e1 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 40 20 10 42 2e 64 61 74 61 20 20 20 20 20 20 20 20 20 20 20 08 20 20 20 49 01 20 20 51 01 20 20 20 20 20 20 01 20 20 20 40 20 40 c0 20 20 20 2f 69 6e 63 6c 75 64 65 3a 73 6f 6d 65 5f 66 75 63 6e 74 69 6f 6e 5f 69 6d 70 6c 65 6d 65 6e 74 5f 69 6e 69 74 20 2f 44 45 46 41 55 4c 54 4c 49 42 3a 22 4c 49 42 43 4d 54 22 20 2f 44 45 46 41 55 4c 54 4c 49 42 3a 22 4f 4c 44 4e 41 4d 45 53 22 20 04 20 20 20 f1 20 20 20 5a 20 20 20 1c 20 01 11 20 20 20 20 45 3a 5c 6a 73 2d 65 67 6e 69 6e 65 5c 74 65 73 74 2e 6f 62 6a 20 3a 20 3c 11 20 62 20 20 d0 20 13 20 20 20 95 5e 01 20 13 20 20 20 95 5e 01 20 4d 69 63 72 6f 73 6f 66 74 20 28 52 29 20 4f 70 74 69 6d 69 7a 69 6e 67 20 43 6f 6d 70 69 6c 65 72 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 06 20 20 20 01 20 40 63 6f 6d 70 2e 69 64 95 5e 04 01 ff ff 20 20 03 20 40 66 65 61 74 2e 30 30 90 01 20 80 ff ff 20 20 03 20 2e 64 72 65 63 74 76 65 20 20 20 20 01 20 20 20 03 01 55 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2e 64 65 62 75 67 24 53 20 20 20 20 02 20 20 20 03 01 68 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 04 20 20 20 20 20 20 20 20 20 20 20 02 20 2e 64 61 74 61 20 20 20 20 20 20 20 03 20 20 20 03 01 08 20 20 20 01 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 29 20 20 20 20 20 20 20 03 20 20 20 02 20 46 20 20 20 73 6f 6d 65 5f 66 75 63 6e 74 69 6f 6e 5f 69 6d 70 6c 65 6d 65 6e 74 5f 69 6e 69 74 5f 62 79 5f 72 75 73 74 20 73 6f 6d 65 5f 66 75 63 6e 74 69 6f 6e 5f 69 6d 70 6c 65 6d 65 6e 74 5f 69 6e 69 74 20


And following is the dump from dumpbin of MSVC

Dump of file test.obj

File Type: COFF OBJECT

FILE HEADER VALUES 8664 machine (x64) 3 number of sections 582A0519 time date stamp Tue Nov 15 02:40:25 2016 15B file pointer to symbol table A number of symbols 0 size of optional header 0 characteristics

SECTION HEADER #1 .drectve name 0 physical address 0 virtual address 55 size of raw data 8C file pointer to raw data (0000008C to 000000E0) 0 file pointer to relocation table 0 file pointer to line numbers 0 number of relocations 0 number of line numbers 100A00 flags Info Remove 1 byte align

RAW DATA #1 00000000: 20 20 20 2F 69 6E 63 6C 75 64 65 3A 73 6F 6D 65 /include:some 00000010: 5F 66 75 63 6E 74 69 6F 6E 5F 69 6D 70 6C 65 6D _fucntion_implem 00000020: 65 6E 74 5F 69 6E 69 74 20 2F 44 45 46 41 55 4C ent_init /DEFAUL 00000030: 54 4C 49 42 3A 22 4C 49 42 43 4D 54 22 20 2F 44 TLIB:"LIBCMT" /D 00000040: 45 46 41 55 4C 54 4C 49 42 3A 22 4F 4C 44 4E 41 EFAULTLIB:"OLDNA 00000050: 4D 45 53 22 20 MES"

Linker Directives


/include:some_fucntion_implement_init /DEFAULTLIB:LIBCMT /DEFAULTLIB:OLDNAMES

SECTION HEADER #2 .debug$S name 0 physical address 0 virtual address 68 size of raw data E1 file pointer to raw data (000000E1 to 00000148) 0 file pointer to relocation table 0 file pointer to line numbers 0 number of relocations 0 number of line numbers 42100040 flags Initialized Data Discardable 1 byte align Read Only

RAW DATA #2 00000000: 04 00 00 00 F1 00 00 00 5A 00 00 00 1C 00 01 11 ....ñ...Z....... 00000010: 00 00 00 00 45 3A 5C 6A 73 2D 65 67 6E 69 6E 65 ....E:\js-egnine 00000020: 5C 74 65 73 74 2E 6F 62 6A 00 3A 00 3C 11 00 62 \test.obj.:.<..b 00000030: 00 00 D0 00 13 00 00 00 95 5E 01 00 13 00 00 00 ..Ð......^...... 00000040: 95 5E 01 00 4D 69 63 72 6F 73 6F 66 74 20 28 52 .^..Microsoft (R 00000050: 29 20 4F 70 74 69 6D 69 7A 69 6E 67 20 43 6F 6D ) Optimizing Com 00000060: 70 69 6C 65 72 00 00 00 piler...

SECTION HEADER #3 .data name 0 physical address 0 virtual address 8 size of raw data 149 file pointer to raw data (00000149 to 00000150) 151 file pointer to relocation table 0 file pointer to line numbers 1 number of relocations 0 number of line numbers C0400040 flags Initialized Data 8 byte align Read Write

RAW DATA #3 00000000: 00 00 00 00 00 00 00 00 ........

RELOCATIONS #3 Symbol Symbol Offset Type Applied To Index Name


00000000 ADDR64 00000000 00000000 6 some_fucntion_implement_init_by_rust

COFF SYMBOL TABLE 000 01045E95 ABS notype Static | @comp.id 001 80000190 ABS notype Static | @feat.00 002 00000000 SECT1 notype Static | .drectve Section length 55, #relocs 0, #linenums 0, checksum 0 004 00000000 SECT2 notype Static | .debug$S Section length 68, #relocs 0, #linenums 0, checksum 0 006 00000000 UNDEF notype () External | some_fucntion_implement_init_by_rust 007 00000000 SECT3 notype Static | .data Section length 8, #relocs 1, #linenums 0, checksum 0 009 00000000 SECT3 notype External | some_fucntion_implement_init

String Table Size = 0x46 bytes

Summary

       8 .data
      68 .debug$S
      55 .drectve
So we just need a macro to construct such a object file directly.
The compiler doesn't care about how the Macro Procedure generate the file, it's just output the
object file of this function, and link it latter.
The only things we need to care is `some_fucntion_implement_init` & `some_fucntion_implement_init_by_rust`
and some offsets. and some literal about the MSVC compiler.
durka commented 8 years ago

I think we have this already (at least in Accepted RFC Rust, not sure about Implemented RFC Rust). See #1548 and #1201.

Amanieu commented 8 years ago

Isn't this the same thing as just linking an external .o file using build.rs?

lygstate commented 8 years ago

@Amanieu it's different, cause we can creating the .o at the compile time without modifing the build.rs and natrually platoform indepent.