mirror of
https://github.com/netwide-assembler/nasm.git
synced 2025-07-24 10:25:42 -04:00
malloc: simplify nasm_malloc code, add nasm_strcatn()
Simplify the nasm_malloc() code by moving the pointer check into a common subroutine. We can now issue a filename error even for failures like malloc(). Add support for the gcc sentinel attribute (verify that a list ends with NULL). Add a handful of safe_alloc attributes. Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
This commit is contained in:
parent
1ce81e10ef
commit
740ec3572b
7
aclocal.m4
vendored
7
aclocal.m4
vendored
@ -106,10 +106,11 @@ AC_DEFUN(PA_FUNC_ATTRIBUTE,
|
|||||||
AC_INCLUDES_DEFAULT
|
AC_INCLUDES_DEFAULT
|
||||||
extern ifelse([$3],[],[void *],[$3]) __attribute__(($1$2))
|
extern ifelse([$3],[],[void *],[$3]) __attribute__(($1$2))
|
||||||
bar(ifelse([$4],[],[int],[$4]));
|
bar(ifelse([$4],[],[int],[$4]));
|
||||||
void *foo(void);
|
ifelse([$3],[],[void *],[$3]) foo(void);
|
||||||
void *foo(void)
|
ifelse([$3],[],[void *],[$3]) foo(void)
|
||||||
{
|
{
|
||||||
return bar(ifelse([$5],[],[1],[$5]));
|
ifelse([$3],[void],[],[return])
|
||||||
|
bar(ifelse([$5],[],[1],[$5]));
|
||||||
}
|
}
|
||||||
])],
|
])],
|
||||||
[AC_MSG_RESULT([yes])
|
[AC_MSG_RESULT([yes])
|
||||||
|
@ -220,6 +220,7 @@ PA_FUNC_ATTRIBUTE(noreturn)
|
|||||||
PA_FUNC_ATTRIBUTE(returns_nonnull)
|
PA_FUNC_ATTRIBUTE(returns_nonnull)
|
||||||
PA_FUNC_ATTRIBUTE(malloc)
|
PA_FUNC_ATTRIBUTE(malloc)
|
||||||
PA_FUNC_ATTRIBUTE(alloc_size, (1))
|
PA_FUNC_ATTRIBUTE(alloc_size, (1))
|
||||||
|
PA_FUNC_ATTRIBUTE(sentinel,,, [const char *, ...], ["a","b",NULL])
|
||||||
PA_FUNC_ATTRIBUTE(format, [(printf,1,2)], int, [const char *, ...], ["%d",1])
|
PA_FUNC_ATTRIBUTE(format, [(printf,1,2)], int, [const char *, ...], ["%d",1])
|
||||||
PA_FUNC_ATTRIBUTE(const)
|
PA_FUNC_ATTRIBUTE(const)
|
||||||
PA_FUNC_ATTRIBUTE(pure)
|
PA_FUNC_ATTRIBUTE(pure)
|
||||||
|
@ -264,7 +264,7 @@ size_t strnlen(const char *s, size_t maxlen);
|
|||||||
#ifdef HAVE_FUNC_ATTRIBUTE_MALLOC
|
#ifdef HAVE_FUNC_ATTRIBUTE_MALLOC
|
||||||
# define safe_alloc never_null __attribute__((malloc))
|
# define safe_alloc never_null __attribute__((malloc))
|
||||||
#else
|
#else
|
||||||
# define safe_alloc
|
# define safe_alloc never_null
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_FUNC_ATTRIBUTE_ALLOC_SIZE
|
#ifdef HAVE_FUNC_ATTRIBUTE_ALLOC_SIZE
|
||||||
@ -277,6 +277,12 @@ size_t strnlen(const char *s, size_t maxlen);
|
|||||||
# define safe_realloc(s) never_null
|
# define safe_realloc(s) never_null
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_FUNC_ATTRIBUTE_SENTINEL
|
||||||
|
# define end_with_null __attribute__((sentinel))
|
||||||
|
#else
|
||||||
|
# define end_with_null
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* How to tell the compiler that a function doesn't return
|
* How to tell the compiler that a function doesn't return
|
||||||
*/
|
*/
|
||||||
|
@ -79,6 +79,8 @@ void * safe_realloc(2) nasm_realloc(void *, size_t);
|
|||||||
void nasm_free(void *);
|
void nasm_free(void *);
|
||||||
char * safe_alloc nasm_strdup(const char *);
|
char * safe_alloc nasm_strdup(const char *);
|
||||||
char * safe_alloc nasm_strndup(const char *, size_t);
|
char * safe_alloc nasm_strndup(const char *, size_t);
|
||||||
|
char * safe_alloc nasm_strcat(const char *one, const char *two);
|
||||||
|
char * safe_alloc end_with_null nasm_strcatn(const char *one, ...);
|
||||||
|
|
||||||
/* Assert the argument is a pointer without evaluating it */
|
/* Assert the argument is a pointer without evaluating it */
|
||||||
#define nasm_assert_pointer(p) ((void)sizeof(*(p)))
|
#define nasm_assert_pointer(p) ((void)sizeof(*(p)))
|
||||||
@ -282,8 +284,6 @@ void src_set(int32_t line, const char *filename);
|
|||||||
*/
|
*/
|
||||||
int32_t src_get(int32_t *xline, const char **xname);
|
int32_t src_get(int32_t *xline, const char **xname);
|
||||||
|
|
||||||
char *nasm_strcat(const char *one, const char *two);
|
|
||||||
|
|
||||||
char *nasm_skip_spaces(const char *p);
|
char *nasm_skip_spaces(const char *p);
|
||||||
char *nasm_skip_word(const char *p);
|
char *nasm_skip_word(const char *p);
|
||||||
char *nasm_zap_spaces_fwd(char *p);
|
char *nasm_zap_spaces_fwd(char *p);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* ----------------------------------------------------------------------- *
|
/* ----------------------------------------------------------------------- *
|
||||||
*
|
*
|
||||||
* Copyright 1996-2016 The NASM Authors - All Rights Reserved
|
* Copyright 1996-2018 The NASM Authors - All Rights Reserved
|
||||||
* See the file AUTHORS included with the NASM distribution for
|
* See the file AUTHORS included with the NASM distribution for
|
||||||
* the specific copyright holders.
|
* the specific copyright holders.
|
||||||
*
|
*
|
||||||
@ -14,7 +14,7 @@
|
|||||||
* copyright notice, this list of conditions and the following
|
* copyright notice, this list of conditions and the following
|
||||||
* disclaimer in the documentation and/or other materials provided
|
* disclaimer in the documentation and/or other materials provided
|
||||||
* with the distribution.
|
* with the distribution.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
@ -42,33 +42,36 @@
|
|||||||
#include "nasmlib.h"
|
#include "nasmlib.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
|
|
||||||
|
static no_return nasm_alloc_failed(void)
|
||||||
|
{
|
||||||
|
nasm_fatal(0, "out of memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void *validate_ptr(void *p)
|
||||||
|
{
|
||||||
|
if (unlikely(!p))
|
||||||
|
nasm_alloc_failed();
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
void *nasm_malloc(size_t size)
|
void *nasm_malloc(size_t size)
|
||||||
{
|
{
|
||||||
void *p = malloc(size);
|
return validate_ptr(malloc(size));
|
||||||
if (!p)
|
|
||||||
nasm_fatal(ERR_NOFILE, "out of memory");
|
|
||||||
return p;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void *nasm_calloc(size_t size, size_t nelem)
|
void *nasm_calloc(size_t size, size_t nelem)
|
||||||
{
|
{
|
||||||
void *p = calloc(size, nelem);
|
return validate_ptr(calloc(size, nelem));
|
||||||
if (!p)
|
|
||||||
nasm_fatal(ERR_NOFILE, "out of memory");
|
|
||||||
return p;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void *nasm_zalloc(size_t size)
|
void *nasm_zalloc(size_t size)
|
||||||
{
|
{
|
||||||
return nasm_calloc(size, 1);
|
return validate_ptr(calloc(1, size));
|
||||||
}
|
}
|
||||||
|
|
||||||
void *nasm_realloc(void *q, size_t size)
|
void *nasm_realloc(void *q, size_t size)
|
||||||
{
|
{
|
||||||
void *p = q ? realloc(q, size) : malloc(size);
|
return validate_ptr(q ? realloc(q, size) : malloc(size));
|
||||||
if (!p)
|
|
||||||
nasm_fatal(ERR_NOFILE, "out of memory");
|
|
||||||
return p;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void nasm_free(void *q)
|
void nasm_free(void *q)
|
||||||
@ -106,3 +109,55 @@ char *nasm_strcat(const char *one, const char *two)
|
|||||||
memcpy(rslt + l1, two, l2+1);
|
memcpy(rslt + l1, two, l2+1);
|
||||||
return rslt;
|
return rslt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *nasm_strcatn(const char *str1, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
char *rslt; /* Output buffer */
|
||||||
|
size_t s; /* Total buffer size */
|
||||||
|
size_t n; /* Number of arguments */
|
||||||
|
size_t *ltbl; /* Table of lengths */
|
||||||
|
size_t l, *lp; /* Length for current argument */
|
||||||
|
const char *p; /* Currently examined argument */
|
||||||
|
char *q; /* Output pointer */
|
||||||
|
|
||||||
|
n = 0; /* No strings encountered yet */
|
||||||
|
p = str1;
|
||||||
|
va_start(ap, str1);
|
||||||
|
while (p) {
|
||||||
|
n++;
|
||||||
|
p = va_arg(ap, const char *);
|
||||||
|
}
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
ltbl = nasm_malloc(n * sizeof(size_t));
|
||||||
|
|
||||||
|
s = 1; /* Space for final NULL */
|
||||||
|
p = str1;
|
||||||
|
lp = ltbl;
|
||||||
|
va_start(ap, str1);
|
||||||
|
while (p) {
|
||||||
|
*lp++ = l = strlen(p);
|
||||||
|
s += l;
|
||||||
|
p = va_arg(ap, const char *);
|
||||||
|
}
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
q = rslt = nasm_malloc(s);
|
||||||
|
|
||||||
|
p = str1;
|
||||||
|
lp = ltbl;
|
||||||
|
va_start(ap, str1);
|
||||||
|
while (p) {
|
||||||
|
l = *lp++;
|
||||||
|
memcpy(q, p, l);
|
||||||
|
q += l;
|
||||||
|
p = va_arg(ap, const char *);
|
||||||
|
}
|
||||||
|
va_end(ap);
|
||||||
|
*q = '\0';
|
||||||
|
|
||||||
|
nasm_free(ltbl);
|
||||||
|
|
||||||
|
return rslt;
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user