mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-05-31 17:52:27 +00:00
Remove .internal from more header filenames
This commit is contained in:
parent
c265c17d54
commit
31194165d2
734 changed files with 779 additions and 778 deletions
509
libc/macros.h
Normal file
509
libc/macros.h
Normal file
|
@ -0,0 +1,509 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_MACROS_H_
|
||||
#define COSMOPOLITAN_LIBC_MACROS_H_
|
||||
#if 0
|
||||
/*───────────────────────────────────────────────────────────────────────────│─╗
|
||||
│ cosmopolitan § macros ─╬─│┼
|
||||
╚────────────────────────────────────────────────────────────────────────────│*/
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @fileoverview Common C preprocessor, assembler, and linker macros.
|
||||
*/
|
||||
|
||||
#ifdef MAX
|
||||
#undef MAX
|
||||
#endif
|
||||
|
||||
#ifdef MIN
|
||||
#undef MIN
|
||||
#endif
|
||||
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
||||
#define IS2POW(X) (!((X) & ((X) - 1)))
|
||||
#define ROUNDUP(X, K) (((X) + (K) - 1) & -(K))
|
||||
#define ROUNDDOWN(X, K) ((X) & -(K))
|
||||
#ifndef __ASSEMBLER__
|
||||
#define ABS(X) ((X) >= 0 ? (X) : -(X))
|
||||
#define MIN(X, Y) ((Y) > (X) ? (X) : (Y))
|
||||
#define MAX(X, Y) ((Y) < (X) ? (X) : (Y))
|
||||
#else
|
||||
// The GNU assembler does not grok the ?: ternary operator; furthermore,
|
||||
// boolean expressions yield -1 and 0 for "true" and "false", not 1 and 0.
|
||||
#define __MAPBOOL(P) (!!(P) / (!!(P) + !(P)))
|
||||
#define __IFELSE(P, X, Y) (__MAPBOOL(P) * (X) + __MAPBOOL(!(P)) * (Y))
|
||||
#define MIN(X, Y) (__IFELSE((Y) > (X), (X), (Y)))
|
||||
#define MAX(X, Y) (__IFELSE((Y) < (X), (X), (Y)))
|
||||
#endif
|
||||
#define PASTE(A, B) __PASTE(A, B)
|
||||
#define STRINGIFY(A) __STRINGIFY(A)
|
||||
#define EQUIVALENT(X, Y) (__builtin_constant_p((X) == (Y)) && ((X) == (Y)))
|
||||
#define TYPE_BIT(type) (sizeof(type) * CHAR_BIT)
|
||||
#define TYPE_SIGNED(type) (((type) - 1) < 0)
|
||||
#define TYPE_INTEGRAL(type) (((type)0.5) != 0.5)
|
||||
|
||||
#define ARRAYLEN(A) \
|
||||
((sizeof(A) / sizeof(*(A))) / ((unsigned)!(sizeof(A) % sizeof(*(A)))))
|
||||
|
||||
#define __STRINGIFY(A) #A
|
||||
#define __PASTE(A, B) A##B
|
||||
#ifdef __ASSEMBLER__
|
||||
// clang-format off
|
||||
|
||||
// Ends function definition.
|
||||
// @cost saves 1-3 lines of code
|
||||
.macro .endfn name:req bnd vis
|
||||
.size "\name",.-"\name"
|
||||
.type "\name",@function
|
||||
.ifnb \bnd
|
||||
.\bnd "\name"
|
||||
.endif
|
||||
.ifnb \vis
|
||||
.\vis "\name"
|
||||
.endif
|
||||
.endm
|
||||
|
||||
// Ends variable definition.
|
||||
// @cost saves 1-3 lines of code
|
||||
.macro .endobj name:req bnd vis
|
||||
.size "\name",.-"\name"
|
||||
.type "\name",@object
|
||||
.ifnb \bnd
|
||||
.\bnd "\name"
|
||||
.endif
|
||||
.ifnb \vis
|
||||
.\vis "\name"
|
||||
.endif
|
||||
.endm
|
||||
|
||||
// Shorthand notation for widely-acknowledged sections.
|
||||
.macro .rodata
|
||||
.section .rodata,"a",@progbits
|
||||
.endm
|
||||
.macro .init
|
||||
.section .init,"ax",@progbits
|
||||
.endm
|
||||
.macro .real
|
||||
.section .text.real,"ax",@progbits
|
||||
.endm
|
||||
.macro .head
|
||||
.section .text.head,"ax",@progbits
|
||||
.endm
|
||||
.macro .text.startup
|
||||
.section .text.startup,"ax",@progbits
|
||||
.endm
|
||||
.macro .text.exit
|
||||
.section .text.exit,"ax",@progbits
|
||||
.endm
|
||||
.macro .firstclass
|
||||
.section .text.hot,"ax",@progbits
|
||||
.endm
|
||||
.macro .text.unlikely
|
||||
.section .text.unlikely,"ax",@progbits
|
||||
.endm
|
||||
.macro .text.likely
|
||||
.section .text.hot,"ax",@progbits
|
||||
.endm
|
||||
.macro .text.modernity
|
||||
.section .text.modernity,"ax",@progbits
|
||||
.balign 16
|
||||
.endm
|
||||
.macro .text.antiquity
|
||||
.section .text.antiquity,"ax",@progbits
|
||||
.endm
|
||||
.macro .text.hot
|
||||
.section .text.hot,"ax",@progbits
|
||||
.endm
|
||||
.macro .preinit_array
|
||||
.section .preinit_array,"a",@init_array
|
||||
.endm
|
||||
.macro .init_array
|
||||
.section .init_array,"a",@init_array
|
||||
.endm
|
||||
.macro .text.windows
|
||||
.section .text.windows,"ax",@progbits
|
||||
.endm
|
||||
|
||||
// Mergeable NUL-terminated UTF-8 string constant section.
|
||||
//
|
||||
// @note linker de-dupes C strings here across whole compile
|
||||
// @note therefore item/values are reordered w.r.t. link order
|
||||
// @note therefore no section relative addressing
|
||||
.macro .rodata.str1.1
|
||||
.section .rodata.str1.1,"aMS",@progbits,1
|
||||
.balign 1
|
||||
.endm
|
||||
|
||||
// Locates unreferenced code invulnerable to --gc-sections.
|
||||
.macro .keep.text
|
||||
.section .keep.text,"ax",@progbits
|
||||
.endm
|
||||
|
||||
// Flags code as only allowed for testing purposes.
|
||||
.macro .testonly
|
||||
.section .test,"ax",@progbits
|
||||
.endm
|
||||
|
||||
// Makes code runnable while code morphing.
|
||||
.macro .privileged
|
||||
.section .privileged,"ax",@progbits
|
||||
.endm
|
||||
|
||||
// Declares alternative implementation of function.
|
||||
// @param implement e.g. tinymath_pow
|
||||
// @param canonical e.g. pow
|
||||
.macro .alias implement:req canonical:req
|
||||
.equ \canonical,\implement
|
||||
.weak \canonical
|
||||
.endm
|
||||
|
||||
#ifdef __aarch64__
|
||||
.macro jmp dest:req
|
||||
b \dest
|
||||
.endm
|
||||
#endif
|
||||
|
||||
// Pulls unrelated module into linkage.
|
||||
//
|
||||
// In order for this technique to work with --gc-sections, another
|
||||
// module somewhere might want to weakly reference whats yoinked.
|
||||
.macro .yoink symbol:req
|
||||
.section .yoink
|
||||
#ifdef __x86_64__
|
||||
nopl "\symbol"(%rip)
|
||||
#elif defined(__aarch64__)
|
||||
b "\symbol"
|
||||
#endif
|
||||
.previous
|
||||
.endm
|
||||
|
||||
// Begins definition of frameless function that calls no functions.
|
||||
.macro .leafprologue
|
||||
#if !(defined(TINY) && !defined(__PG__))
|
||||
#ifdef __x86_64__
|
||||
push %rbp
|
||||
mov %rsp,%rbp
|
||||
#elif defined(__aarch64__)
|
||||
stp x29,x30,[sp,#-16]!
|
||||
mov x29,sp
|
||||
#endif
|
||||
#endif
|
||||
.endm
|
||||
|
||||
// Ends definition of frameless function that calls no functions.
|
||||
.macro .leafepilogue
|
||||
#if !(defined(TINY) && !defined(__PG__))
|
||||
#ifdef __x86_64__
|
||||
pop %rbp
|
||||
#elif defined(__aarch64__)
|
||||
ldp x29,x30,[sp],#16
|
||||
#endif
|
||||
#endif
|
||||
ret
|
||||
.endm
|
||||
|
||||
// Documents unreachable assembly code.
|
||||
.macro .unreachable
|
||||
#if !defined(NDEBUG) && defined(__x86_64__)
|
||||
ud2 // crash if contract is broken
|
||||
#elif !defined(NDEBUG) && defined(__aarch64__)
|
||||
brk #1000
|
||||
#elif defined(__FNO_OMIT_FRAME_POINTER__) && defined(__x86_64__)
|
||||
nop // avoid noreturn tail call backtrace ambiguity
|
||||
#endif
|
||||
.endm
|
||||
|
||||
// Embeds Fixed-Width Zero-Padded String.
|
||||
// @note .fxstr is better
|
||||
.macro .ascin str:req fieldsize:req
|
||||
1347: .ascii "\str"
|
||||
.org 1347b+\fieldsize,0x00
|
||||
.endm
|
||||
|
||||
// Inserts --ftrace pre-prologue.
|
||||
// This goes immediately before the function symbol.
|
||||
// @see .ftrace2
|
||||
.macro .ftrace1
|
||||
#ifdef FTRACE
|
||||
#ifdef __x86_64__
|
||||
.rept 9
|
||||
nop
|
||||
.endr
|
||||
#elif defined(__aarch64__)
|
||||
.rept 6
|
||||
nop
|
||||
.endr
|
||||
#endif /* __x86_64__ */
|
||||
#endif /* FTRACE */
|
||||
.endm
|
||||
|
||||
// Inserts --ftrace prologue.
|
||||
// This goes immediately after the function symbol.
|
||||
// @see .ftrace1
|
||||
.macro .ftrace2
|
||||
#ifdef FTRACE
|
||||
#ifdef __x86_64__
|
||||
xchg %ax,%ax
|
||||
#elif defined(__aarch64__)
|
||||
nop
|
||||
#endif /* __x86_64__ */
|
||||
#endif /* FTRACE */
|
||||
.endm
|
||||
|
||||
#ifdef __x86_64__
|
||||
|
||||
#if __MNO_VZEROUPPER__ + 0
|
||||
#define vzeroupper
|
||||
#endif
|
||||
|
||||
// Mergeable numeric constant sections.
|
||||
//
|
||||
// @note linker de-dupes item/values across whole compile
|
||||
// @note therefore item/values are reordered w.r.t. link order
|
||||
// @note therefore no section relative addressing
|
||||
.macro .rodata.cst4
|
||||
.section .rodata.cst4,"aM",@progbits,4
|
||||
.balign 4
|
||||
.endm
|
||||
.macro .rodata.cst8
|
||||
.section .rodata.cst8,"aM",@progbits,8
|
||||
.balign 8
|
||||
.endm
|
||||
.macro .rodata.cst16
|
||||
.section .rodata.cst16,"aM",@progbits,16
|
||||
.balign 16
|
||||
.endm
|
||||
.macro .rodata.cst32
|
||||
.section .rodata.cst32,"aM",@progbits,32
|
||||
.balign 32
|
||||
.endm
|
||||
.macro .rodata.cst64
|
||||
.section .rodata.cst64,"aM",@progbits,64
|
||||
.balign 64
|
||||
.endm
|
||||
.macro .tdata
|
||||
.section .tdata,"awT",@progbits
|
||||
.balign 4
|
||||
.endm
|
||||
.macro .tbss
|
||||
.section .tdata,"awT",@nobits
|
||||
.balign 4
|
||||
.endm
|
||||
|
||||
// Loads address of errno into %rcx
|
||||
.macro .errno
|
||||
call __errno_location
|
||||
.endm
|
||||
|
||||
// Post-Initialization Read-Only (PIRO) BSS section.
|
||||
// @param ss is an optional string, for control image locality
|
||||
.macro .piro ss
|
||||
.ifnb \ss
|
||||
.section .piro.sort.bss.\ss,"aw",@nobits
|
||||
.else
|
||||
.section .piro.bss,"aw",@nobits
|
||||
.endif
|
||||
.endm
|
||||
|
||||
// Helpers for Cosmopolitan _init() amalgamation magic.
|
||||
// @param name should be consistent across macros for a module
|
||||
// @see libc/runtime/_init.S
|
||||
.macro .initro number:req name:req
|
||||
.section ".initro.\number\().\name","a",@progbits
|
||||
.balign 8
|
||||
.endm
|
||||
.macro .initbss number:req name:req
|
||||
.section ".piro.bss.init.2.\number\().\name","aw",@nobits
|
||||
.balign 8
|
||||
.endm
|
||||
.macro .init.start number:req name:req
|
||||
.section ".init.\number\().\name","ax",@progbits
|
||||
"\name":
|
||||
.endm
|
||||
.macro .init.end number:req name:req bnd=globl vis
|
||||
.endfn "\name",\bnd,\vis
|
||||
.previous
|
||||
.endm
|
||||
|
||||
// LOOP Instruction Replacement.
|
||||
.macro .loop label:req
|
||||
.byte 0x83
|
||||
.byte 0xe9
|
||||
.byte 0x01
|
||||
jnz \label
|
||||
.endm
|
||||
|
||||
// Pushes CONSTEXPR ∈ [-128,127].
|
||||
// @note assembler is wrong for non-literal constexprs
|
||||
.macro pushb x:req
|
||||
.byte 0x6a
|
||||
.byte \x
|
||||
.endm
|
||||
|
||||
// Sign-extends CONSTEXPR ∈ [-128,127] to REGISTER.
|
||||
// @cost ≥1 cycles, -2 bytes
|
||||
.macro pushpop constexpr:req register:req
|
||||
pushb \constexpr
|
||||
pop \register
|
||||
.endm
|
||||
|
||||
// Moves REGISTER to REGISTER.
|
||||
// @cost ≥1 cycles, -1 REX byte
|
||||
.macro movpp src:req dest:req
|
||||
push \src
|
||||
pop \dest
|
||||
.endm
|
||||
|
||||
// Embeds fixed-width zero-filled string table.
|
||||
// @note zero-padded ≠ nul-terminated
|
||||
.macro .fxstr width head rest:vararg
|
||||
.ifnb \head
|
||||
0: .ascii "\head"
|
||||
.org 0b+\width
|
||||
.fxstr \width,\rest
|
||||
.endif
|
||||
.endm
|
||||
|
||||
// Marks symbols as object en-masse.
|
||||
// @note zero-padded ≠ nul-terminated
|
||||
.macro .object symbol rest:vararg
|
||||
.ifnb \symbol
|
||||
.type \symbol,@object
|
||||
.object \rest
|
||||
.endif
|
||||
.endm
|
||||
|
||||
// Pads function prologue unconditionally for runtime hooking.
|
||||
// @cost ≥0.3 cycles, 5 bytes
|
||||
// @see .ftrace1
|
||||
.macro .hookable
|
||||
.byte 0x0f
|
||||
.byte 0x1f
|
||||
.byte 0x44
|
||||
.byte 0x00
|
||||
.byte 0x00
|
||||
.endm
|
||||
|
||||
// Puts initialized data in uninitialized data section.
|
||||
.macro .bsdata name:req expr:req bnd vis
|
||||
.section ".initbss.300._init_\name","aw",@nobits
|
||||
"\name":
|
||||
.quad 0
|
||||
.endobj "\name",\bnd,\vis
|
||||
.previous
|
||||
.section ".initro.300._init_\name","a",@progbits
|
||||
.quad \expr
|
||||
.previous
|
||||
.section ".init.300._init_\name","ax",@progbits
|
||||
"_init_\name":
|
||||
movsq
|
||||
.endfn "_init_\name"
|
||||
.previous
|
||||
.endm
|
||||
|
||||
// ICE Breakpoint.
|
||||
// Modern gas forgot this but objdump knows
|
||||
// @mode long,legacy,real
|
||||
.macro icebp
|
||||
.byte 0xF1
|
||||
.endm
|
||||
.macro int1
|
||||
icebp
|
||||
.endm
|
||||
|
||||
// Sets breakpoint for software debugger.
|
||||
// @mode long,legacy,real
|
||||
.macro .softicebp
|
||||
.byte 0x53 # push bx
|
||||
.byte 0x87 # xchg bx,bx (bochs breakpoint)
|
||||
.byte 0xdb
|
||||
.byte 0x5b # pop bx
|
||||
.byte 0x66 # xchg ax,ax (microsoft breakpoint)
|
||||
.byte 0x90
|
||||
int3 # gdb breakpoint
|
||||
.endm
|
||||
|
||||
// Assembles Intel Official 4-Byte NOP.
|
||||
.macro fatnop4
|
||||
.byte 0x0f,0x1f,0x40,0x00
|
||||
.endm
|
||||
|
||||
// Calls Windows function.
|
||||
//
|
||||
// @param cx,dx,r8,r9,stack
|
||||
// @return ax
|
||||
// @clob ax,cx,dx,r8-r11
|
||||
.macro ntcall symbol:req
|
||||
sub $32,%rsp
|
||||
call *\symbol(%rip)
|
||||
add $32,%rsp
|
||||
.endm
|
||||
|
||||
// Custom emulator instruction for bottom stack frame.
|
||||
.macro bofram endfunc:req
|
||||
.byte 0x0f,0x1f,0105,\endfunc-. # nopl disp8(%rbp)
|
||||
.endm
|
||||
|
||||
// Good alignment for functions where alignment actually helps.
|
||||
// @note 16-byte
|
||||
.macro .alignfunc
|
||||
#ifndef __OPTIMIZE_SIZE__
|
||||
.p2align 4
|
||||
#endif
|
||||
.endm
|
||||
|
||||
// TODO(jart): delete
|
||||
// Loads Effective Address
|
||||
// Supporting security blankets
|
||||
.macro ezlea symbol:req reg:req
|
||||
#if __pic__ + __pie__ + __code_model_medium__ + __code_model_large__ + 0 > 1
|
||||
// lea \symbol(%rip),%r\reg
|
||||
mov $\symbol,%e\reg
|
||||
#else
|
||||
mov $\symbol,%e\reg
|
||||
#endif
|
||||
.endm
|
||||
|
||||
// Loads address of linktime mergeable string literal into register.
|
||||
.macro loadstr text:req reg:req regsz bias=0
|
||||
.section .rodata.str1.1,"aSM",@progbits,1
|
||||
.type .Lstr\@,@object
|
||||
.Lstr\@: .asciz "\text"
|
||||
.Lstr\@.size = .-.Lstr\@ - 1
|
||||
.size .Lstr\@,.-.Lstr\@
|
||||
.previous
|
||||
ezlea .Lstr\@,\reg
|
||||
.ifnb \regsz
|
||||
#ifdef __OPTIMIZE_SIZE__
|
||||
.if .Lstr\@.size + \bias < 128
|
||||
pushpop .Lstr\@.size,%r\regsz
|
||||
.else
|
||||
mov $.Lstr\@.size,%e\regsz
|
||||
.endif
|
||||
#else
|
||||
mov $.Lstr\@.size,%e\regsz
|
||||
#endif
|
||||
.endif
|
||||
.endm
|
||||
|
||||
.macro .poison name:req kind:req
|
||||
.endm
|
||||
|
||||
.macro .underrun
|
||||
.endm
|
||||
|
||||
.macro .overrun
|
||||
.endm
|
||||
|
||||
#else
|
||||
|
||||
.macro .underrun
|
||||
.endm
|
||||
.macro .overrun
|
||||
.endm
|
||||
|
||||
// clang-format on
|
||||
#endif /* __x86_64__ */
|
||||
#endif /* __ASSEMBLER__ */
|
||||
#endif /* COSMOPOLITAN_LIBC_MACROS_H_ */
|
Loading…
Add table
Add a link
Reference in a new issue