mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-06-28 15:28:30 +00:00
Initial import
This commit is contained in:
commit
c91b3c5006
14915 changed files with 590219 additions and 0 deletions
8
libc/mem/alloca.h
Normal file
8
libc/mem/alloca.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_MEM_ALLOCA_H_
|
||||
#define COSMOPOLITAN_LIBC_MEM_ALLOCA_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
|
||||
#define alloca(size) __builtin_alloca(size)
|
||||
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_MEM_ALLOCA_H_ */
|
38
libc/mem/asprintf.c
Normal file
38
libc/mem/asprintf.c
Normal file
|
@ -0,0 +1,38 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/mem/mem.h"
|
||||
|
||||
/**
|
||||
* Formats string, allocating needed memory.
|
||||
*
|
||||
* @param *strp is output-only and must be free'd, even on error; this
|
||||
* behavior was adopted to help put your needs first in terms of
|
||||
* portability, since that's guaranteed to work with all libraries
|
||||
* @return bytes written (excluding NUL) or -1 w/ errno
|
||||
* @see xasprintf() for a better API
|
||||
*/
|
||||
int(asprintf)(char **strp, const char *fmt, ...) {
|
||||
int res;
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
res = (vasprintf)(strp, fmt, va);
|
||||
va_end(va);
|
||||
return res;
|
||||
}
|
34
libc/mem/calloc-hook.S
Normal file
34
libc/mem/calloc-hook.S
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.h"
|
||||
.yoink __FILE__
|
||||
|
||||
.initbss 800,_init_calloc
|
||||
hook$calloc:
|
||||
.quad 0
|
||||
.endobj hook$calloc,globl,hidden
|
||||
.previous
|
||||
|
||||
.init.start 800,_init_calloc
|
||||
.hidden dlcalloc
|
||||
ezlea dlcalloc,ax
|
||||
stosq
|
||||
yoink free
|
||||
.init.end 800,_init_calloc
|
32
libc/mem/calloc.S
Normal file
32
libc/mem/calloc.S
Normal file
|
@ -0,0 +1,32 @@
|
|||
/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.h"
|
||||
#include "libc/notice.inc"
|
||||
.yoink __FILE__
|
||||
|
||||
/ Allocates n * itemsize bytes, initialized to zero.
|
||||
/
|
||||
/ @param rdi is number of items (n)
|
||||
/ @param rsi is size of each item (itemsize)
|
||||
/ @return rax is memory address, or NULL w/ errno
|
||||
/ @note overreliance on memalign is a sure way to fragment space
|
||||
/ @see dlcalloc()
|
||||
calloc: jmp *hook$calloc(%rip)
|
||||
.endfn calloc,globl
|
59
libc/mem/free-cxx.S
Normal file
59
libc/mem/free-cxx.S
Normal file
|
@ -0,0 +1,59 @@
|
|||
/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.h"
|
||||
.yoink __FILE__
|
||||
|
||||
/ Frees memory the C++ way.
|
||||
/
|
||||
/ @param %rdi is pointer, or NULL for no-op
|
||||
/ @param %rsi is ignored
|
||||
/ @param %rdx is ignored
|
||||
_ZdlPvSt11align_val_tRKSt9nothrow_t:
|
||||
nop
|
||||
_ZdaPvSt11align_val_tRKSt9nothrow_t:
|
||||
nop
|
||||
_ZdlPvRKSt9nothrow_t:
|
||||
nop
|
||||
_ZdaPvRKSt9nothrow_t:
|
||||
nop
|
||||
_ZdlPvmSt11align_val_t:
|
||||
nop
|
||||
_ZdaPvmSt11align_val_t:
|
||||
nop
|
||||
_ZdlPvSt11align_val_t:
|
||||
nop
|
||||
_ZdaPvSt11align_val_t:
|
||||
nop
|
||||
_ZdaPvm:nop
|
||||
_ZdlPvm:nop
|
||||
_ZdaPv: nop
|
||||
_ZdlPv: jmp *hook$free(%rip)
|
||||
.endfn _ZdlPv,globl,weak
|
||||
.endfn _ZdaPv,globl,weak
|
||||
.endfn _ZdaPvm,globl,weak
|
||||
.endfn _ZdlPvm,globl,weak
|
||||
.endfn _ZdaPvRKSt9nothrow_t,globl,weak
|
||||
.endfn _ZdlPvRKSt9nothrow_t,globl,weak
|
||||
.endfn _ZdaPvSt11align_val_t,globl,weak
|
||||
.endfn _ZdlPvSt11align_val_t,globl,weak
|
||||
.endfn _ZdaPvmSt11align_val_t,globl,weak
|
||||
.endfn _ZdlPvmSt11align_val_t,globl,weak
|
||||
.endfn _ZdlPvSt11align_val_tRKSt9nothrow_t,globl,weak
|
||||
.endfn _ZdaPvSt11align_val_tRKSt9nothrow_t,globl,weak
|
35
libc/mem/free-hook.S
Normal file
35
libc/mem/free-hook.S
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.h"
|
||||
.yoink __FILE__
|
||||
|
||||
.initbss 800,_init_free
|
||||
hook$free:
|
||||
.quad 0
|
||||
.endobj hook$free,globl,hidden
|
||||
.previous
|
||||
|
||||
.init.start 800,_init_free
|
||||
ezlea dlfree,ax
|
||||
stosq
|
||||
yoink realloc
|
||||
.init.end 800,_init_free
|
||||
|
||||
.hidden dlfree
|
34
libc/mem/free.S
Normal file
34
libc/mem/free.S
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.h"
|
||||
.yoink __FILE__
|
||||
|
||||
/ Free memory returned by malloc() & co.
|
||||
/
|
||||
/ Releases the chunk of memory pointed to by p, that had been
|
||||
/ previously allocated using malloc or a related routine such as
|
||||
/ realloc. It has no effect if p is null. If p was not malloced or
|
||||
/ already freed, free(p) will by default cuase the current program to
|
||||
/ abort.
|
||||
/
|
||||
/ @param rdi is allocation address, which may be NULL
|
||||
/ @see dlfree()
|
||||
free: jmp *hook$free(%rip)
|
||||
.endfn free,globl
|
10
libc/mem/internal.h
Normal file
10
libc/mem/internal.h
Normal file
|
@ -0,0 +1,10 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_MEM_INTERNAL_H_
|
||||
#define COSMOPOLITAN_LIBC_MEM_INTERNAL_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
int PutEnvImpl(char *string, bool overwrite) hidden;
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_MEM_INTERNAL_H_ */
|
40
libc/mem/malloc-cxx.S
Normal file
40
libc/mem/malloc-cxx.S
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.h"
|
||||
.yoink __FILE__
|
||||
|
||||
/ Allocates memory the C++ way.
|
||||
/
|
||||
/ @param %rdi is bytes to allocate
|
||||
/ @param %rsi is ignored
|
||||
/ @return new memory or NULL on OOM
|
||||
_ZnamRKSt9nothrow_t:
|
||||
nop
|
||||
_ZnwmRKSt9nothrow_t:
|
||||
nop
|
||||
_Znam: nop
|
||||
_Znwm: test %rdi,%rdi
|
||||
jne 1f
|
||||
mov $1,%edi
|
||||
1: jmp *hook$malloc(%rip)
|
||||
.endfn _Znwm,globl,weak
|
||||
.endfn _Znam,globl,weak
|
||||
.endfn _ZnwmRKSt9nothrow_t,globl,weak
|
||||
.endfn _ZnamRKSt9nothrow_t,globl,weak
|
35
libc/mem/malloc-hook.S
Normal file
35
libc/mem/malloc-hook.S
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.h"
|
||||
.yoink __FILE__
|
||||
|
||||
.initbss 800,_init_malloc
|
||||
hook$malloc:
|
||||
.quad 0
|
||||
.endobj hook$malloc,globl,hidden
|
||||
.previous
|
||||
|
||||
.init.start 800,_init_malloc
|
||||
ezlea dlmalloc,ax
|
||||
stosq
|
||||
yoink free
|
||||
.init.end 800,_init_malloc
|
||||
|
||||
.hidden dlmalloc
|
42
libc/mem/malloc.S
Normal file
42
libc/mem/malloc.S
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.h"
|
||||
.yoink __FILE__
|
||||
|
||||
/ Allocates uninitialized memory.
|
||||
/
|
||||
/ Returns a pointer to a newly allocated chunk of at least n bytes, or
|
||||
/ null if no space is available, in which case errno is set to ENOMEM
|
||||
/ on ANSI C systems.
|
||||
/
|
||||
/ If n is zero, malloc returns a minimum-sized chunk. (The minimum size
|
||||
/ is 32 bytes on 64bit systems.) Note that size_t is an unsigned type,
|
||||
/ so calls with arguments that would be negative if signed are
|
||||
/ interpreted as requests for huge amounts of space, which will often
|
||||
/ fail. The maximum supported value of n differs across systems, but is
|
||||
/ in all cases less than the maximum representable value of a size_t.
|
||||
/
|
||||
/ @param rdi is number of bytes needed
|
||||
/ @return new memory, or NULL w/ errno
|
||||
/ @note malloc(0) → malloc(32)
|
||||
/ @see dlmalloc()
|
||||
malloc: jmp *hook$malloc(%rip)
|
||||
.endfn malloc,globl
|
||||
|
53
libc/mem/malloc_usable_size.S
Normal file
53
libc/mem/malloc_usable_size.S
Normal file
|
@ -0,0 +1,53 @@
|
|||
/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.h"
|
||||
#include "libc/notice.inc"
|
||||
.yoink __FILE__
|
||||
|
||||
/ Returns the number of bytes you can actually use in
|
||||
/ an allocated chunk, which may be more than you requested
|
||||
/ (although often not) due to alignment and minimum size
|
||||
/ constraints.
|
||||
/
|
||||
/ You can use this many bytes without worrying about overwriting
|
||||
/ other allocated objects. This is not a particularly great
|
||||
/ programming practice. malloc_usable_size can be more useful in
|
||||
/ debugging and assertions, for example:
|
||||
/
|
||||
/ p = malloc(n)
|
||||
/ assert(malloc_usable_size(p) >= 256)
|
||||
/
|
||||
/ @param rdi is address of allocation
|
||||
/ @return rax is total number of bytes
|
||||
/ @see dlmalloc_usable_size()
|
||||
malloc_usable_size:
|
||||
jmp *hook$malloc_usable_size(%rip)
|
||||
.endfn malloc_usable_size,globl
|
||||
|
||||
.initbss 800,_init_malloc_usable_size
|
||||
hook$malloc_usable_size:
|
||||
.quad 0
|
||||
.endobj hook$malloc_usable_size,globl,hidden
|
||||
.previous
|
||||
|
||||
.init.start 800,_init_malloc_usable_size
|
||||
ezlea dlmalloc_usable_size,ax
|
||||
stosq
|
||||
.init.end 800,_init_malloc_usable_size
|
77
libc/mem/mem.h
Normal file
77
libc/mem/mem.h
Normal file
|
@ -0,0 +1,77 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_MEM_MEM_H_
|
||||
#define COSMOPOLITAN_LIBC_MEM_MEM_H_
|
||||
#include "libc/fmt/pflink.h"
|
||||
|
||||
#define M_TRIM_THRESHOLD (-1)
|
||||
#define M_GRANULARITY (-2)
|
||||
#define M_MMAP_THRESHOLD (-3)
|
||||
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
/*───────────────────────────────────────────────────────────────────────────│─╗
|
||||
│ cosmopolitan § dynamic memory ─╬─│┼
|
||||
╚────────────────────────────────────────────────────────────────────────────│*/
|
||||
|
||||
void free(void *) libcesque;
|
||||
void *malloc(size_t) attributeallocsize((1)) mallocesque;
|
||||
void *calloc(size_t, size_t) attributeallocsize((1, 2)) mallocesque;
|
||||
void *memalign(size_t, size_t) attributeallocalign((1))
|
||||
attributeallocsize((2)) mallocesque;
|
||||
void *realloc(void *, size_t) reallocesque;
|
||||
void *realloc_in_place(void *, size_t);
|
||||
bool grow(void *, size_t *, size_t, size_t) paramsnonnull((1, 2)) libcesque;
|
||||
void *reallocarray(void *, size_t, size_t) nodiscard;
|
||||
void *valloc(size_t) attributeallocsize((1)) vallocesque;
|
||||
void *pvalloc(size_t) attributeallocsize((1)) mallocesque;
|
||||
char *strdup(const char *) paramsnonnull() mallocesque;
|
||||
char *strndup(const char *, size_t) paramsnonnull()
|
||||
attributeallocsize((2)) mallocesque;
|
||||
int posix_memalign(void **, size_t, size_t); /* wut */
|
||||
|
||||
int malloc_trim(size_t);
|
||||
size_t bulk_free(void **, size_t);
|
||||
size_t malloc_usable_size(const void *);
|
||||
void **independent_calloc(size_t, size_t, void **);
|
||||
void **independent_comalloc(size_t, size_t *, void **);
|
||||
|
||||
int asprintf(char **, const char *, ...) printfesque(2)
|
||||
paramsnonnull((1, 2)) libcesque;
|
||||
int vasprintf(char **, const char *, va_list) paramsnonnull() libcesque;
|
||||
|
||||
wchar_t *wcsdup(const wchar_t *) strlenesque nodiscard;
|
||||
|
||||
struct mallinfo {
|
||||
size_t arena; /* non-mmapped space allocated from system */
|
||||
size_t ordblks; /* number of free chunks */
|
||||
size_t smblks; /* always 0 */
|
||||
size_t hblks; /* always 0 */
|
||||
size_t hblkhd; /* space in mmapped regions */
|
||||
size_t usmblks; /* maximum total allocated space */
|
||||
size_t fsmblks; /* always 0 */
|
||||
size_t uordblks; /* total allocated space */
|
||||
size_t fordblks; /* total free space */
|
||||
size_t keepcost; /* releasable (via malloc_trim) space */
|
||||
};
|
||||
struct mallinfo mallinfo(void);
|
||||
|
||||
void malloc_stats(void);
|
||||
bool32 mallopt(int, int);
|
||||
size_t malloc_footprint(void);
|
||||
size_t malloc_max_footprint(void);
|
||||
size_t malloc_footprint_limit(void);
|
||||
size_t malloc_set_footprint_limit(size_t);
|
||||
void malloc_inspect_all(void (*handler)(void *, void *, size_t, void *),
|
||||
void *);
|
||||
|
||||
/*───────────────────────────────────────────────────────────────────────────│─╗
|
||||
│ cosmopolitan § dynamic memory » optimizations ─╬─│┼
|
||||
╚────────────────────────────────────────────────────────────────────────────│*/
|
||||
|
||||
#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
|
||||
#define asprintf(SP, FMT, ...) (asprintf)(SP, PFLINK(FMT), ##__VA_ARGS__)
|
||||
#define vasprintf(SP, FMT, VA) (vasprintf)(SP, PFLINK(FMT), VA)
|
||||
#endif
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_MEM_MEM_H_ */
|
59
libc/mem/mem.mk
Normal file
59
libc/mem/mem.mk
Normal file
|
@ -0,0 +1,59 @@
|
|||
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
||||
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
|
||||
|
||||
PKGS += LIBC_MEM
|
||||
|
||||
LIBC_MEM_ARTIFACTS += LIBC_MEM_A
|
||||
LIBC_MEM = $(LIBC_MEM_A_DEPS) $(LIBC_MEM_A)
|
||||
LIBC_MEM_A = o/$(MODE)/libc/mem/mem.a
|
||||
LIBC_MEM_A_FILES := $(wildcard libc/mem/*)
|
||||
LIBC_MEM_A_HDRS = $(filter %.h,$(LIBC_MEM_A_FILES))
|
||||
LIBC_MEM_A_SRCS_S = $(filter %.S,$(LIBC_MEM_A_FILES))
|
||||
LIBC_MEM_A_SRCS_C = $(filter %.c,$(LIBC_MEM_A_FILES))
|
||||
|
||||
LIBC_MEM_A_SRCS = \
|
||||
$(LIBC_MEM_A_SRCS_S) \
|
||||
$(LIBC_MEM_A_SRCS_C)
|
||||
|
||||
LIBC_MEM_A_OBJS = \
|
||||
$(LIBC_MEM_A_SRCS:%=o/$(MODE)/%.zip.o) \
|
||||
$(LIBC_MEM_A_SRCS_S:%.S=o/$(MODE)/%.o) \
|
||||
$(LIBC_MEM_A_SRCS_C:%.c=o/$(MODE)/%.o)
|
||||
|
||||
LIBC_MEM_A_CHECKS = \
|
||||
$(LIBC_MEM_A).pkg \
|
||||
$(LIBC_MEM_A_HDRS:%=o/$(MODE)/%.ok)
|
||||
|
||||
LIBC_MEM_A_DIRECTDEPS = \
|
||||
LIBC_STR \
|
||||
LIBC_FMT \
|
||||
LIBC_RAND \
|
||||
LIBC_STUBS \
|
||||
LIBC_CALLS \
|
||||
LIBC_RUNTIME \
|
||||
LIBC_NEXGEN32E \
|
||||
LIBC_SYSV \
|
||||
THIRD_PARTY_DLMALLOC
|
||||
|
||||
LIBC_MEM_A_DEPS := \
|
||||
$(call uniq,$(foreach x,$(LIBC_MEM_A_DIRECTDEPS),$($(x))))
|
||||
|
||||
$(LIBC_MEM_A): libc/mem/ \
|
||||
$(LIBC_MEM_A).pkg \
|
||||
$(LIBC_MEM_A_OBJS)
|
||||
|
||||
$(LIBC_MEM_A).pkg: \
|
||||
$(LIBC_MEM_A_OBJS) \
|
||||
$(foreach x,$(LIBC_MEM_A_DIRECTDEPS),$($(x)_A).pkg)
|
||||
|
||||
LIBC_MEM_LIBS = $(foreach x,$(LIBC_MEM_ARTIFACTS),$($(x)))
|
||||
LIBC_MEM_SRCS = $(foreach x,$(LIBC_MEM_ARTIFACTS),$($(x)_SRCS))
|
||||
LIBC_MEM_HDRS = $(foreach x,$(LIBC_MEM_ARTIFACTS),$($(x)_HDRS))
|
||||
LIBC_MEM_BINS = $(foreach x,$(LIBC_MEM_ARTIFACTS),$($(x)_BINS))
|
||||
LIBC_MEM_CHECKS = $(foreach x,$(LIBC_MEM_ARTIFACTS),$($(x)_CHECKS))
|
||||
LIBC_MEM_OBJS = $(foreach x,$(LIBC_MEM_ARTIFACTS),$($(x)_OBJS))
|
||||
LIBC_MEM_TESTS = $(foreach x,$(LIBC_MEM_ARTIFACTS),$($(x)_TESTS))
|
||||
$(LIBC_MEM_OBJS): $(BUILD_FILES) libc/mem/mem.mk
|
||||
|
||||
.PHONY: o/$(MODE)/libc/mem
|
||||
o/$(MODE)/libc/mem: $(LIBC_MEM_CHECKS)
|
47
libc/mem/memalign-cxx.S
Normal file
47
libc/mem/memalign-cxx.S
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.h"
|
||||
.yoink __FILE__
|
||||
|
||||
/ Allocates aligned memory the C++ way.
|
||||
/
|
||||
/ @param %rdi is bytes to allocate
|
||||
/ @param %rsi is byte alignment
|
||||
/ @param %rdx is ignored
|
||||
/ @return new memory or NULL on OOM
|
||||
_ZnamSt11align_val_tRKSt9nothrow_t:
|
||||
nop
|
||||
_ZnwmSt11align_val_tRKSt9nothrow_t:
|
||||
nop
|
||||
_ZnwmSt11align_val_t:
|
||||
nop
|
||||
_ZnamSt11align_val_t:
|
||||
test %rdi,%rdi
|
||||
jnz 1f
|
||||
mov $1,%eax
|
||||
1: mov $__BIGGEST_ALIGNMENT__,%eax
|
||||
cmp %rax,%rsi
|
||||
cmovb %rax,%rsi
|
||||
xchg %rdi,%rsi
|
||||
jmp *hook$memalign(%rip)
|
||||
.endfn _ZnwmSt11align_val_t,globl,weak
|
||||
.endfn _ZnamSt11align_val_t,globl,weak
|
||||
.endfn _ZnamSt11align_val_tRKSt9nothrow_t,globl,weak
|
||||
.endfn _ZnwmSt11align_val_tRKSt9nothrow_t,globl,weak
|
35
libc/mem/memalign-hook.S
Normal file
35
libc/mem/memalign-hook.S
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.h"
|
||||
.yoink __FILE__
|
||||
|
||||
.initbss 800,_init_memalign
|
||||
hook$memalign:
|
||||
.quad 0
|
||||
.endobj hook$memalign,globl,hidden
|
||||
.previous
|
||||
|
||||
.init.start 800,_init_memalign
|
||||
ezlea dlmemalign,ax
|
||||
stosq
|
||||
yoink free
|
||||
.init.end 800,_init_memalign
|
||||
|
||||
.hidden dlmemalign
|
40
libc/mem/memalign.S
Normal file
40
libc/mem/memalign.S
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.h"
|
||||
#include "libc/notice.inc"
|
||||
.yoink __FILE__
|
||||
|
||||
/ Allocates aligned memory.
|
||||
/
|
||||
/ Returns a pointer to a newly allocated chunk of n bytes, aligned in
|
||||
/ accord with the alignment argument. The alignment argument should be
|
||||
/ a power of two. If the argument is not a power of two, the nearest
|
||||
/ greater power is used. 8-byte alignment is guaranteed by normal
|
||||
/ malloc calls, so don't bother calling memalign with an argument of 8
|
||||
/ or less.
|
||||
/
|
||||
/ @param rdi is alignment in bytes
|
||||
/ @param rsi (newsize) is number of bytes needed
|
||||
/ @return rax is memory address, or NULL w/ errno
|
||||
/ @note overreliance on memalign is a sure way to fragment space
|
||||
/ @see dlmemalign()
|
||||
memalign:
|
||||
jmp *hook$memalign(%rip)
|
||||
.endfn memalign,globl
|
51
libc/mem/posix_memalign.S
Normal file
51
libc/mem/posix_memalign.S
Normal file
|
@ -0,0 +1,51 @@
|
|||
/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.h"
|
||||
.yoink __FILE__
|
||||
|
||||
/ Allocates aligned memory the POSIX way.
|
||||
/
|
||||
/ Allocates a chunk of n bytes, aligned in accord with the alignment
|
||||
/ argument. Differs from memalign only in that it (1) assigns the
|
||||
/ allocated memory to *pp rather than returning it, (2) fails and
|
||||
/ returns EINVAL if the alignment is not a power of two (3) fails and
|
||||
/ returns ENOMEM if memory cannot be allocated.
|
||||
/
|
||||
/ @param rdi is void **pp
|
||||
/ @param rsi is size_t align
|
||||
/ @param rdx is size_t size
|
||||
/ @return eax
|
||||
posix_memalign:
|
||||
jmp *hook$posix_memalign(%rip)
|
||||
.endfn posix_memalign,globl
|
||||
|
||||
.initbss 800,_init_posix_memalign
|
||||
hook$posix_memalign:
|
||||
.quad 0
|
||||
.endobj hook$posix_memalign,globl,hidden
|
||||
.previous
|
||||
|
||||
.init.start 800,_init_posix_memalign
|
||||
.hidden dlposix_memalign
|
||||
ezlea dlposix_memalign,ax
|
||||
stosq
|
||||
.init.end 800,_init_posix_memalign
|
||||
|
||||
yoink free
|
76
libc/mem/putenv.c
Normal file
76
libc/mem/putenv.c
Normal file
|
@ -0,0 +1,76 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/alg/alg.h"
|
||||
#include "libc/mem/internal.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
static size_t g_environcap;
|
||||
|
||||
int PutEnvImpl(char *string, bool overwrite) {
|
||||
if (!environ) {
|
||||
g_environcap = 0;
|
||||
if ((environ = calloc(8, sizeof(char *)))) {
|
||||
g_environcap = 8;
|
||||
}
|
||||
}
|
||||
char *equalp = strchr(string, '=');
|
||||
if (!equalp) return einval();
|
||||
unsigned namelen = equalp + 1 - string;
|
||||
unsigned i;
|
||||
for (i = 0; environ[i]; ++i) {
|
||||
if (strncmp(environ[i], string, namelen) == 0) {
|
||||
if (!overwrite) {
|
||||
free_s(&string);
|
||||
return 0;
|
||||
}
|
||||
goto replace;
|
||||
}
|
||||
}
|
||||
if (i + 1 >= g_environcap) {
|
||||
if (!g_environcap) g_environcap = i + 1;
|
||||
if (!grow(&environ, &g_environcap, sizeof(char *), 0)) {
|
||||
free_s(&string);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
environ[i + 1] = NULL;
|
||||
replace:
|
||||
free_s(&environ[i]);
|
||||
environ[i] = string;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Emplaces environment key=value.
|
||||
* @see setenv(), getenv()
|
||||
*/
|
||||
int putenv(char *string) { return PutEnvImpl(string, true); }
|
||||
|
||||
textexit static void putenv_fini(void) {
|
||||
for (char **envp = environ; *envp; ++envp) free_s(envp);
|
||||
free_s(&environ);
|
||||
}
|
||||
|
||||
textstartup static void putenv_init(void) { atexit(putenv_fini); }
|
||||
|
||||
const void *const putenv_ctor[] initarray = {putenv_init};
|
45
libc/mem/pvalloc.S
Normal file
45
libc/mem/pvalloc.S
Normal file
|
@ -0,0 +1,45 @@
|
|||
/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.h"
|
||||
#include "libc/notice.inc"
|
||||
.yoink __FILE__
|
||||
|
||||
/ Equivalent to valloc(minimum-page-that-holds(n)), that is,
|
||||
/ round up n to nearest PAGESIZE.
|
||||
/
|
||||
/ @param rdi is number of bytes needed
|
||||
/ @return rax is memory address, or NULL w/ errno
|
||||
/ @see dlpvalloc()
|
||||
pvalloc:jmp *hook$pvalloc(%rip)
|
||||
.endfn pvalloc,globl
|
||||
|
||||
.initbss 800,_init_pvalloc
|
||||
hook$pvalloc:
|
||||
.quad 0
|
||||
.endobj hook$pvalloc,globl,hidden
|
||||
.previous
|
||||
|
||||
.init.start 800,_init_pvalloc
|
||||
.hidden dlpvalloc
|
||||
ezlea dlpvalloc,ax
|
||||
stosq
|
||||
.init.end 800,_init_pvalloc
|
||||
|
||||
yoink free
|
34
libc/mem/realloc-hook.S
Normal file
34
libc/mem/realloc-hook.S
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.h"
|
||||
.yoink __FILE__
|
||||
|
||||
.initbss 800,_init_realloc
|
||||
hook$realloc:
|
||||
.quad 0
|
||||
.endobj hook$realloc,globl,hidden
|
||||
.previous
|
||||
|
||||
.init.start 800,_init_realloc
|
||||
.hidden dlrealloc
|
||||
ezlea dlrealloc,ax
|
||||
stosq
|
||||
yoink free
|
||||
.init.end 800,_init_realloc
|
59
libc/mem/realloc.S
Normal file
59
libc/mem/realloc.S
Normal file
|
@ -0,0 +1,59 @@
|
|||
/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.h"
|
||||
#include "libc/notice.inc"
|
||||
.yoink __FILE__
|
||||
|
||||
/ Allocates / resizes / frees memory, e.g.
|
||||
/
|
||||
/ Returns a pointer to a chunk of size n that contains the same data as
|
||||
/ does chunk p up to the minimum of (n, p's size) bytes, or null if no
|
||||
/ space is available.
|
||||
/
|
||||
/ If p is NULL, realloc is equivalent to malloc.
|
||||
/ If p is not NULL and n is 0, realloc is equivalent to free.
|
||||
/
|
||||
/ The returned pointer may or may not be the same as p. The algorithm
|
||||
/ prefers extending p in most cases when possible, otherwise it employs
|
||||
/ the equivalent of a malloc-copy-free sequence.
|
||||
/
|
||||
/ Please note that p is NOT free()'d should realloc() fail, thus:
|
||||
/
|
||||
/ if ((p2 = realloc(p, n2))) {
|
||||
/ p = p2;
|
||||
/ ...
|
||||
/ } else {
|
||||
/ ...
|
||||
/ }
|
||||
/
|
||||
/ if n is for fewer bytes than already held by p, the newly unused
|
||||
/ space is lopped off and freed if possible.
|
||||
/
|
||||
/ The old unix realloc convention of allowing the last-free'd chunk to
|
||||
/ be used as an argument to realloc is not supported.
|
||||
/
|
||||
/ @param rdi (p) is address of current allocation or NULL
|
||||
/ @param rsi (n) is number of bytes needed
|
||||
/ @return rax is result, or NULL w/ errno w/o free(p)
|
||||
/ @note realloc(p=0, n=0) → malloc(32)
|
||||
/ @note realloc(p≠0, n=0) → free(p)
|
||||
/ @see dlrealloc()
|
||||
realloc:jmp *hook$realloc(%rip)
|
||||
.endfn realloc,globl
|
53
libc/mem/realloc_in_place.S
Normal file
53
libc/mem/realloc_in_place.S
Normal file
|
@ -0,0 +1,53 @@
|
|||
/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.h"
|
||||
#include "libc/notice.inc"
|
||||
.yoink __FILE__
|
||||
|
||||
/ Resizes the space allocated for p to size n, only if this can be
|
||||
/ done without moving p (i.e., only if there is adjacent space
|
||||
/ available if n is greater than p's current allocated size, or n is
|
||||
/ less than or equal to p's size). This may be used instead of plain
|
||||
/ realloc if an alternative allocation strategy is needed upon failure
|
||||
/ to expand space, for example, reallocation of a buffer that must be
|
||||
/ memory-aligned or cleared. You can use realloc_in_place to trigger
|
||||
/ these alternatives only when needed.
|
||||
/
|
||||
/ @param rdi (p) is address of current allocation
|
||||
/ @param rsi (newsize) is number of bytes needed
|
||||
/ @return rax is result, or NULL w/ errno
|
||||
/ @see dlrealloc_in_place()
|
||||
realloc_in_place:
|
||||
jmp *hook$realloc_in_place(%rip)
|
||||
.endfn realloc_in_place,globl
|
||||
|
||||
.initbss 800,_init_realloc_in_place
|
||||
hook$realloc_in_place:
|
||||
.quad 0
|
||||
.endobj hook$realloc_in_place,globl,hidden
|
||||
.previous
|
||||
|
||||
.init.start 800,_init_realloc_in_place
|
||||
.hidden dlrealloc_in_place
|
||||
ezlea dlrealloc_in_place,ax
|
||||
stosq
|
||||
.init.end 800,_init_realloc_in_place
|
||||
|
||||
yoink free
|
35
libc/mem/reallocarray.c
Normal file
35
libc/mem/reallocarray.c
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/conv/conv.h"
|
||||
#include "libc/conv/sizemultiply.h"
|
||||
#include "libc/mem/mem.h"
|
||||
|
||||
/**
|
||||
* Manages array memory, the BSD way.
|
||||
*
|
||||
* @param ptr may be NULL for malloc() behavior
|
||||
* @param nmemb may be 0 for free() behavior; shrinking is promised too
|
||||
* @return new address or NULL w/ errno and ptr is NOT free()'d
|
||||
*/
|
||||
void *reallocarray(void *ptr, size_t nmemb, size_t itemsize) {
|
||||
size_t newsize;
|
||||
sizemultiply(&newsize, nmemb, itemsize); /* punts error */
|
||||
return realloc(ptr, newsize);
|
||||
}
|
37
libc/mem/setenv.c
Normal file
37
libc/mem/setenv.c
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/mem/internal.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
/**
|
||||
* Copies variable to environment.
|
||||
*
|
||||
* @return 0 on success, or -1 w/ errno
|
||||
* @see putenv(), getenv()
|
||||
*/
|
||||
int setenv(const char *name, const char *value, int overwrite) {
|
||||
size_t namelen = strlen(name);
|
||||
size_t valuelen = strlen(value);
|
||||
char *s = malloc(namelen + valuelen + 2);
|
||||
memcpy(mempcpy(mempcpy(s, name, namelen), "=", 1), value, valuelen + 1);
|
||||
return PutEnvImpl(s, overwrite);
|
||||
}
|
34
libc/mem/strdup.c
Normal file
34
libc/mem/strdup.c
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=8 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
/**
|
||||
* Allocates new copy of string.
|
||||
*
|
||||
* @param s is a NUL-terminated byte string
|
||||
* @return new string or NULL w/ errno
|
||||
* @error ENOMEM
|
||||
*/
|
||||
char *strdup(const char *s) {
|
||||
size_t len = strlen(s);
|
||||
char *s2 = malloc(len + 1);
|
||||
return s2 ? memcpy(s2, s, len + 1) : NULL;
|
||||
}
|
40
libc/mem/strndup.c
Normal file
40
libc/mem/strndup.c
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=8 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
/**
|
||||
* Allocates new copy of string, with byte limit.
|
||||
*
|
||||
* @param s is a NUL-terminated byte string
|
||||
* @param n if less than strlen(s) will truncate the string
|
||||
* @return new string or NULL w/ errno
|
||||
* @error ENOMEM
|
||||
*/
|
||||
char *strndup(const char *s, size_t n) {
|
||||
char *s2;
|
||||
size_t len = strnlen(s, n);
|
||||
if ((s2 = malloc(len + 1))) {
|
||||
memcpy(s2, s, len);
|
||||
s2[len] = '\0';
|
||||
return s2;
|
||||
}
|
||||
return s2;
|
||||
}
|
29
libc/mem/unhexstr.c
Normal file
29
libc/mem/unhexstr.c
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/fmt/bing.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
nodiscard void *unhexstr(const char *hexdigs) {
|
||||
assert(strlen(hexdigs) % 2 == 0);
|
||||
return unhexbuf(memalign(__BIGGEST_ALIGNMENT__, strlen(hexdigs) / 2),
|
||||
strlen(hexdigs), hexdigs);
|
||||
}
|
44
libc/mem/valloc.S
Normal file
44
libc/mem/valloc.S
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*-*- mode:asm; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.h"
|
||||
#include "libc/notice.inc"
|
||||
.yoink __FILE__
|
||||
|
||||
/ Equivalent to memalign(PAGESIZE, n).
|
||||
/
|
||||
/ @param rdi is number of bytes needed
|
||||
/ @return rax is memory address, or NULL w/ errno
|
||||
/ @see dlvalloc()
|
||||
valloc: jmp *hook$valloc(%rip)
|
||||
.endfn valloc,globl
|
||||
|
||||
.initbss 800,_init_valloc
|
||||
hook$valloc:
|
||||
.quad 0
|
||||
.endobj hook$valloc,globl,hidden
|
||||
.previous
|
||||
|
||||
.init.start 800,_init_valloc
|
||||
.hidden dlvalloc
|
||||
ezlea dlvalloc,ax
|
||||
stosq
|
||||
.init.end 800,_init_valloc
|
||||
|
||||
yoink free
|
57
libc/mem/vasprintf.c
Normal file
57
libc/mem/vasprintf.c
Normal file
|
@ -0,0 +1,57 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/fmt/fmt.h"
|
||||
#include "libc/mem/mem.h"
|
||||
|
||||
/**
|
||||
* Formats string w/ dynamic memory allocation.
|
||||
*
|
||||
* @param *strp is output-only and must be free'd, even on error; since
|
||||
* that's the behavior that'll make your code most portable
|
||||
* @return complete bytes written (excluding NUL) or -1 w/ errno
|
||||
* @see xasprintf() for a better API
|
||||
*/
|
||||
int(vasprintf)(char **strp, const char *fmt, va_list va) {
|
||||
/**
|
||||
* This implementation guarantees the smallest possible allocation,
|
||||
* using an optimistic approach w/o changing asymptotic complexity.
|
||||
*/
|
||||
size_t size = 32;
|
||||
if ((*strp = malloc(size))) {
|
||||
va_list va2;
|
||||
va_copy(va2, va);
|
||||
int wrote = (vsnprintf)(*strp, size, fmt, va);
|
||||
if (wrote == -1) return -1;
|
||||
if (wrote <= size - 1) {
|
||||
return wrote;
|
||||
} else {
|
||||
size = wrote + 1;
|
||||
char *buf2 = realloc(*strp, size);
|
||||
if (buf2) {
|
||||
*strp = buf2;
|
||||
wrote = (vsnprintf)(*strp, size, fmt, va2);
|
||||
assert(wrote == size - 1);
|
||||
return wrote;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
27
libc/mem/wcsdup.c
Normal file
27
libc/mem/wcsdup.c
Normal file
|
@ -0,0 +1,27 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
wchar_t *wcsdup(const wchar_t *s) {
|
||||
size_t len = wcslen(s);
|
||||
char *s2 = malloc(len * sizeof(wchar_t) + 1);
|
||||
return s2 ? memcpy(s2, s, len * sizeof(wchar_t) + 1) : NULL;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue