linux: Consolidate brk implementation

It removes all the arch-specific assembly implementation.  The
outliers are alpha, where its kernel ABI explict return -ENOMEM
in case of failure; and i686, where it can't use
"call *%gs:SYSINFO_OFFSET" during statup in static PIE.

Also some ABIs exports an additional ___brk_addr symbol and to
handle it an internal HAVE_INTERNAL_BRK_ADDR_SYMBOL is added.

Checked on x86_64-linux-gnu, i686-linux-gnu, adn with builsd for
the affected ABIs.

Reviewed-by: Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com>
This commit is contained in:
Adhemerval Zanella 2020-06-26 16:06:49 -03:00
parent 880433de13
commit 720480934a
36 changed files with 60 additions and 745 deletions

View File

@ -234,6 +234,9 @@
# define INTERNAL_SYSCALL_NCS(number, nr, args...) \ # define INTERNAL_SYSCALL_NCS(number, nr, args...) \
INTERNAL_SYSCALL_RAW (number, nr, args) INTERNAL_SYSCALL_RAW (number, nr, args)
#undef HAVE_INTERNAL_BRK_ADDR_SYMBOL
#define HAVE_INTERNAL_BRK_ADDR_SYMBOL 1
#endif /* __ASSEMBLER__ */ #endif /* __ASSEMBLER__ */
/* Pointer mangling is supported for AArch64. */ /* Pointer mangling is supported for AArch64. */

View File

@ -1,83 +0,0 @@
/* Copyright (C) 1993-2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Brendan Kehoe <brendan@zen.org>, 1993.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library. If not, see
<https://www.gnu.org/licenses/>. */
/* __brk is a special syscall under Linux since it never returns an
error. Instead, the error condition is indicated by returning the old
break value (instead of the new, requested one). */
#include <sysdep.h>
#include <errno.h>
#ifdef PIC
.section .bss
.align 3
.globl __curbrk
__curbrk: .skip 8
.type __curbrk,@object
.size __curbrk,8
#else
.comm __curbrk, 8
#endif
.text
.align 4
.globl __brk
.ent __brk
.usepv __brk, std
cfi_startproc
__brk:
ldgp gp, 0(t12)
subq sp, 16, sp
cfi_adjust_cfa_offset (16)
#ifdef PROF
.set noat
lda AT, _mcount
jsr AT, (AT), _mcount
.set at
#endif
/* Save the requested brk across the system call. */
stq a0, 0(sp)
ldiq v0, __NR_brk
call_pal PAL_callsys
ldq a0, 0(sp)
addq sp, 16, sp
cfi_adjust_cfa_offset (-16)
/* Be prepared for an OSF-style brk. */
bne a3, SYSCALL_ERROR_LABEL
beq v0, $ok
/* Correctly handle the brk(0) query case. */
cmoveq a0, v0, a0
xor a0, v0, t0
lda v0, ENOMEM
bne t0, SYSCALL_ERROR_LABEL
/* Update __curbrk and return cleanly. */
lda v0, 0
$ok: stq a0, __curbrk
ret
PSEUDO_END(__brk)
cfi_endproc
weak_alias (__brk, brk)

View File

@ -1,5 +1,5 @@
/* brk system call for Linux/ARM. /* Change data segment size. Linux/Alpha.
Copyright (C) 1995-2020 Free Software Foundation, Inc. Copyright (C) 2020 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -20,17 +20,14 @@
#include <unistd.h> #include <unistd.h>
#include <sysdep.h> #include <sysdep.h>
/* This must be initialized data because commons can't have aliases. */
void *__curbrk = 0; void *__curbrk = 0;
int int
__brk (void *addr) __brk (void *addr)
{ {
void *newbrk; /* Alpha brk returns -ENOMEM in case of failure. */
__curbrk = (void *) INTERNAL_SYSCALL_CALL (brk, addr);
__curbrk = newbrk = (void *) INLINE_SYSCALL (brk, 1, addr); if ((unsigned long) __curbrk == -ENOMEM)
if (newbrk < addr)
{ {
__set_errno (ENOMEM); __set_errno (ENOMEM);
return -1; return -1;

View File

@ -1 +0,0 @@
#include <brk.S>

View File

@ -221,6 +221,9 @@ hidden_proto (__syscall_error)
# define PTR_MANGLE(var) (void) (var) # define PTR_MANGLE(var) (void) (var)
# define PTR_DEMANGLE(var) (void) (var) # define PTR_DEMANGLE(var) (void) (var)
# undef HAVE_INTERNAL_BRK_ADDR_SYMBOL
# define HAVE_INTERNAL_BRK_ADDR_SYMBOL 1
#endif /* !__ASSEMBLER__ */ #endif /* !__ASSEMBLER__ */
#endif /* linux/arc/sysdep.h */ #endif /* linux/arc/sysdep.h */

View File

@ -1,6 +1,6 @@
/* Copyright (C) 2011-2020 Free Software Foundation, Inc. /* Change data segment. Linux generic version.
Copyright (C) 2020 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
@ -23,10 +23,12 @@
/* This must be initialized data because commons can't have aliases. */ /* This must be initialized data because commons can't have aliases. */
void *__curbrk = 0; void *__curbrk = 0;
#if HAVE_INTERNAL_BRK_ADDR_SYMBOL
/* Old braindamage in GCC's crtstuff.c requires this symbol in an attempt /* Old braindamage in GCC's crtstuff.c requires this symbol in an attempt
to work around different old braindamage in the old Linux ELF dynamic to work around different old braindamage in the old Linux ELF dynamic
linker. */ linker. */
weak_alias (__curbrk, ___brk_addr) weak_alias (__curbrk, ___brk_addr)
#endif
int int
__brk (void *addr) __brk (void *addr)

View File

@ -461,6 +461,9 @@ __local_syscall_error: \
# define INTERNAL_SYSCALL_NCS(number, nr, args...) \ # define INTERNAL_SYSCALL_NCS(number, nr, args...) \
INTERNAL_SYSCALL_RAW##nr (number, args) INTERNAL_SYSCALL_RAW##nr (number, args)
#undef HAVE_INTERNAL_BRK_ADDR_SYMBOL
#define HAVE_INTERNAL_BRK_ADDR_SYMBOL 1
#endif /* __ASSEMBLER__ */ #endif /* __ASSEMBLER__ */
/* Pointer mangling support. */ /* Pointer mangling support. */

View File

@ -1,5 +0,0 @@
/* We can use the normal code but we also know the __curbrk is not exported
from ld.so. */
extern void *__curbrk attribute_hidden;
#include <brk.c>

View File

@ -1,41 +0,0 @@
/* brk system call for Linux/HPPA.
Copyright (C) 1995-2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library. If not, see
<https://www.gnu.org/licenses/>. */
#include <errno.h>
#include <unistd.h>
#include <sysdep.h>
/* This must be initialized data because commons can't have aliases. */
void *__curbrk = 0;
int
__brk (void *addr)
{
void *newbrk;
__curbrk = newbrk = (void *) INLINE_SYSCALL (brk, 1, addr);
if (newbrk < addr)
{
__set_errno (ENOMEM);
return -1;
}
return 0;
}
weak_alias (__brk, brk)

View File

@ -21,25 +21,4 @@
# define I386_USE_SYSENTER 0 # define I386_USE_SYSENTER 0
#endif #endif
#include <errno.h> #include <sysdeps/unix/sysv/linux/brk.c>
#include <unistd.h>
#include <sysdep.h>
/* This must be initialized data because commons can't have aliases. */
void *__curbrk = 0;
/* Old braindamage in GCC's crtstuff.c requires this symbol in an attempt
to work around different old braindamage in the old Linux ELF dynamic
linker. */
weak_alias (__curbrk, ___brk_addr)
int
__brk (void *addr)
{
void *newbrk = (void *) INTERNAL_SYSCALL_CALL (brk, addr);
__curbrk = newbrk;
if (newbrk < addr)
return INLINE_SYSCALL_ERROR_RETURN_VALUE (ENOMEM);
return 0;
}
weak_alias (__brk, brk)

View File

@ -291,6 +291,9 @@ struct libc_do_syscall_args
# define HAVE_TIME_VSYSCALL "__vdso_time" # define HAVE_TIME_VSYSCALL "__vdso_time"
# define HAVE_CLOCK_GETRES_VSYSCALL "__vdso_clock_getres" # define HAVE_CLOCK_GETRES_VSYSCALL "__vdso_clock_getres"
# undef HAVE_INTERNAL_BRK_ADDR_SYMBOL
# define HAVE_INTERNAL_BRK_ADDR_SYMBOL 1
/* Define a macro which expands inline into the wrapper code for a system /* Define a macro which expands inline into the wrapper code for a system
call. This use is for internal calls that do not need to handle errors call. This use is for internal calls that do not need to handle errors
normally. It will never touch errno. This returns just what the kernel normally. It will never touch errno. This returns just what the kernel

View File

@ -1,50 +0,0 @@
/* brk system call for Linux/ia64
Copyright (C) 1999-2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Stéphane Eranian <eranian@hpl.hp.com> and
Jes Sorensen, <Jes.Sorensen@cern.ch>, April 1999.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
#include <sysdep.h>
#include <asm/errno.h>
.global __curbrk
.type __curbrk,@object
.size __curbrk,8
.data
.align 8
__curbrk:
data8 0
weak_alias (__curbrk, ___brk_addr)
LEAF(__brk)
.regstk 1, 0, 0, 0
DO_CALL(__NR_brk)
cmp.ltu p6, p0 = ret0, in0
addl r9 = @ltoff(__curbrk), gp
;;
ld8 r9 = [r9]
(p6) mov ret0 = ENOMEM
(p6) br.cond.spnt.few __syscall_error
;;
st8 [r9] = ret0
mov ret0 = 0
ret
END(__brk)
weak_alias (__brk, brk)

View File

@ -1 +0,0 @@
#include <brk.S>

View File

@ -172,6 +172,9 @@
#else /* not __ASSEMBLER__ */ #else /* not __ASSEMBLER__ */
#undef HAVE_INTERNAL_BRK_ADDR_SYMBOL
#define HAVE_INTERNAL_BRK_ADDR_SYMBOL 1
#define BREAK_INSN_1(num) "break " #num ";;\n\t" #define BREAK_INSN_1(num) "break " #num ";;\n\t"
#define BREAK_INSN(num) BREAK_INSN_1(num) #define BREAK_INSN(num) BREAK_INSN_1(num)

View File

@ -1,46 +0,0 @@
/* brk system call for Linux/m68k.
Copyright (C) 1996-2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library. If not, see
<https://www.gnu.org/licenses/>. */
#include <errno.h>
#include <unistd.h>
#include <sysdep.h>
void *__curbrk = 0;
/* Old braindamage in GCC's crtstuff.c requires this symbol in an attempt
to work around different old braindamage in the old Linux/x86 ELF
dynamic linker. Sigh. */
weak_alias (__curbrk, ___brk_addr)
int
__brk (void *addr)
{
void *newbrk;
newbrk = (void *) INTERNAL_SYSCALL_CALL (brk, addr);
__curbrk = newbrk;
if (newbrk < addr)
{
__set_errno (ENOMEM);
return -1;
}
return 0;
}
weak_alias (__brk, brk)

View File

@ -292,6 +292,9 @@ SYSCALL_ERROR_LABEL: \
LOAD_REGS_5 LOAD_REGS_5
#define ASM_ARGS_6 ASM_ARGS_5, "a" (_a0) #define ASM_ARGS_6 ASM_ARGS_5, "a" (_a0)
#undef HAVE_INTERNAL_BRK_ADDR_SYMBOL
#define HAVE_INTERNAL_BRK_ADDR_SYMBOL 1
#endif /* not __ASSEMBLER__ */ #endif /* not __ASSEMBLER__ */
/* Pointer mangling is not yet supported for M68K. */ /* Pointer mangling is not yet supported for M68K. */

View File

@ -1,42 +0,0 @@
/* Copyright (C) 2011-2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library. If not, see
<https://www.gnu.org/licenses/>. */
#include <errno.h>
#include <unistd.h>
#include <sysdep.h>
/* This must be initialized data because commons can't have aliases. */
void *__curbrk = 0;
/* Old braindamage in GCC's crtstuff.c requires this symbol in an attempt
to work around different old braindamage in the old Linux ELF dynamic
linker. */
weak_alias (__curbrk, ___brk_addr)
int
__brk (void *addr)
{
__curbrk = (void *) INTERNAL_SYSCALL_CALL (brk, addr);
if (__curbrk < addr)
{
__set_errno (ENOMEM);
return -1;
}
return 0;
}
weak_alias (__brk, brk)

View File

@ -310,6 +310,9 @@ SYSCALL_ERROR_LABEL_DCL: \
# define SINGLE_THREAD_BY_GLOBAL 1 # define SINGLE_THREAD_BY_GLOBAL 1
#undef HAVE_INTERNAL_BRK_ADDR_SYMBOL
#define HAVE_INTERNAL_BRK_ADDR_SYMBOL 1
#endif /* not __ASSEMBLER__ */ #endif /* not __ASSEMBLER__ */
#endif /* _LINUX_MICROBLAZE_SYSDEP_H */ #endif /* _LINUX_MICROBLAZE_SYSDEP_H */

View File

@ -1,46 +0,0 @@
/* brk system call for Linux/MIPS.
Copyright (C) 2000-2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library. If not, see
<https://www.gnu.org/licenses/>. */
#include <errno.h>
#include <unistd.h>
#include <sysdep.h>
void *__curbrk = 0;
/* Old braindamage in GCC's crtstuff.c requires this symbol in an attempt
to work around different old braindamage in the old Linux/x86 ELF
dynamic linker. Sigh. */
weak_alias (__curbrk, ___brk_addr)
int
__brk (void *addr)
{
void *newbrk;
newbrk = (void *) INTERNAL_SYSCALL_CALL (brk, addr);
__curbrk = newbrk;
if (newbrk < addr)
{
__set_errno (ENOMEM);
return -1;
}
return 0;
}
weak_alias (__brk, brk)

View File

@ -43,6 +43,9 @@
#else /* ! __ASSEMBLER__ */ #else /* ! __ASSEMBLER__ */
#undef HAVE_INTERNAL_BRK_ADDR_SYMBOL
#define HAVE_INTERNAL_BRK_ADDR_SYMBOL 1
/* Note that the original Linux syscall restart convention required the /* Note that the original Linux syscall restart convention required the
instruction immediately preceding SYSCALL to initialize $v0 with the instruction immediately preceding SYSCALL to initialize $v0 with the
syscall number. Then if a restart triggered, $v0 would have been syscall number. Then if a restart triggered, $v0 would have been

View File

@ -41,6 +41,9 @@
#else /* ! __ASSEMBLER__ */ #else /* ! __ASSEMBLER__ */
#undef HAVE_INTERNAL_BRK_ADDR_SYMBOL
#define HAVE_INTERNAL_BRK_ADDR_SYMBOL 1
#if _MIPS_SIM == _ABIN32 #if _MIPS_SIM == _ABIN32
/* Convert X to a long long, without losing any bits if it is one /* Convert X to a long long, without losing any bits if it is one
already or warning if it is a 32-bit pointer. */ already or warning if it is a 32-bit pointer. */

View File

@ -219,6 +219,9 @@
#define __SYSCALL_CLOBBERS "memory" #define __SYSCALL_CLOBBERS "memory"
#undef HAVE_INTERNAL_BRK_ADDR_SYMBOL
#define HAVE_INTERNAL_BRK_ADDR_SYMBOL 1
#endif /* __ASSEMBLER__ */ #endif /* __ASSEMBLER__ */
/* Pointer mangling support. */ /* Pointer mangling support. */

View File

@ -1 +0,0 @@
#include <brk.S>

View File

@ -1,52 +0,0 @@
/* brk system call for Linux/ppc.
Copyright (C) 1995-2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
#include <sysdep.h>
#define _ERRNO_H 1
#include <bits/errno.h>
.comm __curbrk,4,4
.section ".text"
ENTRY (__brk)
mflr r0
stwu r1,-16(r1)
cfi_adjust_cfa_offset (16)
stw r3,8(r1)
stw r0,20(r1)
cfi_offset (lr, 4)
DO_CALL(SYS_ify(brk))
lwz r6,8(r1)
#ifdef PIC
SETUP_GOT_ACCESS(r5,got_label)
addis r5,r5,__curbrk-got_label@ha
stw r3,__curbrk-got_label@l(r5)
#else
lis r4,__curbrk@ha
stw r3,__curbrk@l(r4)
#endif
lwz r0,20(r1)
cmplw r6,r3
addi r1,r1,16
mtlr r0
li r3,0
blelr+
li r3,ENOMEM
b __syscall_error@local
END (__brk)
weak_alias (__brk, brk)

View File

@ -1,43 +0,0 @@
/* brk system call for Linux. PowerPC64 version.
Copyright (C) 1995-2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
#include <sysdep.h>
#define _ERRNO_H 1
#include <bits/errno.h>
.comm __curbrk,8,8
.section ".toc","aw"
.LC__curbrk:
.tc __curbrk[TC],__curbrk
.section ".text"
ENTRY (__brk)
CALL_MCOUNT 1
std r3,-8(r1)
DO_CALL(SYS_ify(brk))
ld r6,-8(r1)
ld r5,.LC__curbrk@toc(r2)
std r3,0(r5)
cmpld r6,r3
li r3,0
blelr+
li r3,ENOMEM
TAIL_CALL_SYSCALL_ERROR
END (__brk)
weak_alias (__brk, brk)

View File

@ -155,6 +155,9 @@
RV64). */ RV64). */
# define HAVE_GETCPU_VSYSCALL "__vdso_getcpu" # define HAVE_GETCPU_VSYSCALL "__vdso_getcpu"
# undef HAVE_INTERNAL_BRK_ADDR_SYMBOL
# define HAVE_INTERNAL_BRK_ADDR_SYMBOL 1
# define INTERNAL_SYSCALL(name, nr, args...) \ # define INTERNAL_SYSCALL(name, nr, args...) \
internal_syscall##nr (SYS_ify (name), args) internal_syscall##nr (SYS_ify (name), args)

View File

@ -1,55 +0,0 @@
/*
Copyright (C) 2000-2020 Free Software Foundation, Inc.
Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
#include <errno.h>
#include <unistd.h>
#include <sysdep.h>
void *__curbrk = 0;
/* Old braindamage in GCC's crtstuff.c requires this symbol in an attempt
to work around different old braindamage in the old Linux/x86 ELF
dynamic linker. Sigh. */
weak_alias (__curbrk, ___brk_addr)
int
__brk (void *addr)
{
void *newbrk;
{
register void *__addr __asm__("2") = addr;
__asm__ ("svc %b1\n\t" /* call sys_brk */
: "=d" (__addr)
: "I" (SYS_ify(brk)), "r" (__addr)
: "cc", "memory" );
newbrk = __addr;
}
__curbrk = newbrk;
if (newbrk < addr)
{
__set_errno (ENOMEM);
return -1;
}
return 0;
}
weak_alias (__brk, brk)

View File

@ -175,6 +175,11 @@
#define ret_ERRVAL \ #define ret_ERRVAL \
br 14 br 14
#else
# undef HAVE_INTERNAL_BRK_ADDR_SYMBOL
# define HAVE_INTERNAL_BRK_ADDR_SYMBOL 1
#endif /* __ASSEMBLER__ */ #endif /* __ASSEMBLER__ */
/* Pointer mangling support. */ /* Pointer mangling support. */

View File

@ -173,6 +173,11 @@
#define ret_ERRVAL \ #define ret_ERRVAL \
br 14 br 14
#else
# undef HAVE_INTERNAL_BRK_ADDR_SYMBOL
# define HAVE_INTERNAL_BRK_ADDR_SYMBOL 1
#endif /* __ASSEMBLER__ */ #endif /* __ASSEMBLER__ */
/* Pointer mangling support. */ /* Pointer mangling support. */

View File

@ -1,47 +0,0 @@
/* brk system call for Linux/SH.
Copyright (C) 1999-2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
#include <errno.h>
#include <unistd.h>
#include <sysdep.h>
/* This must be initialized data because commons can't have aliases. */
void *__curbrk = 0;
int
__brk (void *addr)
{
void *newbrk;
register long r3 asm ("%r3") = SYS_ify (brk);
register long r4 asm ("%r4") = (long)addr;
asm volatile ("trapa #0x11\n\t" SYSCALL_INST_PAD
: "=z"(newbrk)
: "r" (r3), "r" (r4));
__curbrk = newbrk;
if (newbrk < addr)
{
__set_errno (ENOMEM);
return -1;
}
return 0;
}
weak_alias (__brk, brk)

View File

@ -1,54 +0,0 @@
/* brk system call for Linux/SPARC.
Copyright (C) 1995-2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Miguel de Icaza (miguel@nuclecu.unam.mx)
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
#include <errno.h>
#include <unistd.h>
#include <sysdep.h>
/* This must be initialized data because commons can't have aliases. */
void *__curbrk = 0;
/* Old braindamage in GCC's crtstuff.c requires this symbol in an attempt
to work around different old braindamage in the old Linux ELF dynamic
linker. */
weak_alias (__curbrk, ___brk_addr)
int
__brk (void *addr)
{
void *newbrk;
{
register void *o0 __asm__("%o0") = addr;
register int g1 __asm__("%g1") = __NR_brk;
__asm ("t 0x10" : "=r"(o0) : "r"(g1), "0"(o0) : "cc");
newbrk = o0;
}
__curbrk = newbrk;
if (newbrk < addr)
{
__set_errno (ENOMEM);
return -1;
}
return 0;
}
weak_alias (__brk, brk)

View File

@ -121,6 +121,9 @@ ENTRY(name); \
"f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", \ "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", \
"cc", "memory" "cc", "memory"
#undef HAVE_INTERNAL_BRK_ADDR_SYMBOL
#define HAVE_INTERNAL_BRK_ADDR_SYMBOL 1
#endif /* __ASSEMBLER__ */ #endif /* __ASSEMBLER__ */
/* Pointer mangling support. */ /* Pointer mangling support. */

View File

@ -1,104 +0,0 @@
/* Copyright (C) 1997-2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Richard Henderson <richard@gnu.ai.mit.edu>, 1997.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
/* __brk is a special syscall under Linux since it never returns an
error. Instead, the error condition is indicated by returning the old
break value (instead of the new, requested one). */
#include <sysdep.h>
#include <errno.h>
#ifdef PIC
.section .bss
.align 8
.globl __curbrk
__curbrk: .skip 8
.type __curbrk,@object
.size __curbrk,8
#else
.common __curbrk, 8, 8
#endif
.text
ENTRY (__brk)
save %sp, -192, %sp
cfi_def_cfa_register(%fp)
cfi_window_save
cfi_register(%o7, %i7)
#ifdef PIC
SETUP_PIC_REG(l7)
#endif
LOADSYSCALL(brk)
mov %i0, %o0
ta 0x6d
/* All the ways we can fail... */
bcs,pn %xcc, .Lerr1
nop
brz,pt %i0, .Lok
subcc %i0, %o0, %g0
bne,pn %xcc, .Lerr0
nop
/* Update __curbrk and return cleanly. */
.Lok:
#ifndef PIC
sethi %hi(__curbrk), %g1
or %g1, %lo(__curbrk), %g1
#else
sethi %gdop_hix22(__curbrk), %g1
xor %g1, %gdop_lox10(__curbrk), %g1
ldx [%l7 + %g1], %g1, %gdop(__curbrk)
#endif
stx %o0, [%g1]
mov %g0, %i0
/* Don't use "ret" cause the preprocessor will eat it. */
jmpl %i7+8, %g0
restore
/* What a horrible way to die. */
.Lerr0: set ENOMEM, %o0
.Lerr1:
#ifndef _LIBC_REENTRANT
#ifndef PIC
sethi %hi(errno), %g1
or %g1, %lo(errno), %g1
#else
sethi %gdop_hix22(errno), %g1
xor %g1, %gdop_lox10(errno), %g1
ldx [%l7 + %g1], %g1, %gdop(errno)
#endif
st %o0, [%g1]
#else
#if IS_IN (libc)
call HIDDEN_JUMPTARGET(__errno_location)
#else
call __errno_location
#endif
mov %o0,%l1
st %l1, [%o0]
#endif
sub %g0, 1, %i0
jmpl %i7+8, %g0
restore
END (__brk)
weak_alias (__brk, brk)

View File

@ -1 +0,0 @@
#include <brk.S>

View File

@ -99,4 +99,8 @@
it missing due the usage of a old generic version without it). */ it missing due the usage of a old generic version without it). */
#define HAVE_INTERNAL_SEND_SYMBOL 1 #define HAVE_INTERNAL_SEND_SYMBOL 1
/* Export the ___brk_addr symbol on brk.c implementation (some ABIs export
it due and old crtstuff.c code). */
#define HAVE_INTERNAL_BRK_ADDR_SYMBOL 0
#endif /* _SYSDEP_LINUX_H */ #endif /* _SYSDEP_LINUX_H */

View File

@ -1,41 +0,0 @@
/* brk system call for Linux/x86_64.
Copyright (C) 1995-2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
#include <errno.h>
#include <unistd.h>
#include <sysdep.h>
/* This must be initialized data because commons can't have aliases. */
void *__curbrk = 0;
int
__brk (void *addr)
{
void *newbrk;
__curbrk = newbrk = (void *) INLINE_SYSCALL (brk, 1, addr);
if (newbrk < addr)
{
__set_errno (ENOMEM);
return -1;
}
return 0;
}
weak_alias (__brk, brk)