Skip to content

Commit

Permalink
Meson/Linux: parse the malloc.cpp source instead of malloc.cpp.o
Browse files Browse the repository at this point in the history
I want to avoid having to build the .o file before extracting malloc.o
from libc.a. To parse the source file, we need a clear marker, which I
also used to avoid having to have duplicate declarations.

Because of Meson is incapable of using backslashes in custom_target()
commands (see [1]), I had to write a shell script to execute sed, so I
decided to move the ar x command there too.

[1] mesonbuild/meson#1564

Signed-off-by: Thiago Macieira <[email protected]>
  • Loading branch information
thiagomacieira committed Jun 29, 2023
1 parent 3796a6f commit 9b955fb
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 24 deletions.
46 changes: 46 additions & 0 deletions framework/sysdeps/linux/extract-malloc.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#!/bin/bash -e
# Copyright 2023 Intel Corporation.
# SPDX-License-Identifier: Apache-2.0
#
while [[ "$1" = *=* ]]; do
# Evaluate variable assignments, like AR= and OBJCOPY=
eval "$1"
shift
done
if [[ "$1" = "--" ]]; then
shift
fi

if [[ $# -lt 3 ]]; then
cat <<EOF
Extracts malloc.o from static libc and localizes symbols defined in malloc.cpp.
Syntax:
$0 [variable-assignments] /path/to/libc.a /path/to/malloc.cpp /path/to/output/malloc.o
Variable assignments can be:
AR=/path/to/ar
EOF
exit 0
fi

# Positional arguments
libc_a=$1
malloc_cpp=$2
output=$3
output_dirname=${output%/*}
output_basename=${output##*/}

# Define $AR and $OBJCOPY if they aren't defined.
: ${AR:=ar}
: ${OBJCOPY:=objcopy}

# Generate the -L arguments based on DECLARE_OVERRIDE inside malloc.cpp
objcopy_args=(`sed -En "/^DECLARE_OVERRIDE\((\w+)\).*/s//-L\1/p" "$malloc_cpp"`)

# Extract malloc.o from libc.a
"$AR" x --output "$output_dirname" "$libc_a" malloc.o

# Rename if necessary
[[ "$output_basename" = malloc.o ]] || mv -- "$output_dirname/malloc.o" "$output"

# Transform it
"$OBJCOPY" "${objcopy_args[@]}" "$output"
21 changes: 13 additions & 8 deletions framework/sysdeps/linux/malloc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,19 @@
# endif

extern "C" {
extern void *__libc_memalign(size_t alignment, size_t size);
extern int __libc_posix_memalign (void **memptr, size_t alignment, size_t size);
extern void *__libc_memalign (size_t alignment, size_t bytes);
extern void *__libc_valloc (size_t bytes);
extern void *__libc_pvalloc (size_t bytes);
extern void *__libc_calloc (size_t n, size_t elem_size);
extern void *__libc_malloc(size_t size);
extern void *__libc_realloc (void *oldmem, size_t bytes);
#define DECLARE_OVERRIDE(FUNC) extern decltype(FUNC) __libc_ ## FUNC

// The following lines are parsed by the buildsystem, so be careful when
// modifying them. See extract-malloc.sh.
DECLARE_OVERRIDE(calloc);
DECLARE_OVERRIDE(malloc);
DECLARE_OVERRIDE(memalign);
DECLARE_OVERRIDE(posix_memalign);
DECLARE_OVERRIDE(pvalloc);
DECLARE_OVERRIDE(realloc);
DECLARE_OVERRIDE(valloc);

#undef DECLARE_OVERRIDE
}

static void *bzero_block(void *ptr, size_t len)
Expand Down
27 changes: 11 additions & 16 deletions framework/sysdeps/linux/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -42,35 +42,30 @@ _sysdeps_a = static_library(

if get_option('cpp_link_args').contains('-static')
ar = find_program('ar')
nm = find_program('nm')
objcopy = find_program('objcopy')

# Need to extract malloc.o from libc.a and transform it
# Step 1: extract it:
# Step 1: find libc.a by asking the compiler
libc_a = run_command(cc.cmd_array(), '-print-file-name=libc.a',
check: true
)

orig_glibc_malloc_o = custom_target(
'extract-malloc.o',
output: 'malloc.o',
input: libc_a.stdout().strip(),
command: [
ar, 'x', '--output', '@OUTDIR@', '@INPUT@', '@OUTPUT@',
]
)
# Step 2: transform it by localizing (-L) all the symbols from our malloc.cpp
# Step 2: run our extractor script
glibc_malloc_o = custom_target(
'glibc_malloc.o',
input: [
_sysdeps_a.extract_objects('malloc.cpp'),
orig_glibc_malloc_o,
libc_a.stdout().strip(),
files('malloc.cpp'),
],
output: 'glibc_malloc.o',
command: [
shell, '-c', objcopy.full_path() + ' `' +
nm.full_path() + ' --defined $0 | sed -En "/^.* T /s//-L /p"` $1 $2',
'@INPUT@', '@OUTPUT@',
shell,
files('extract-malloc.sh'),
'AR=' + ar.full_path(),
'OBJCOPY=' + objcopy.full_path(),
'--',
'@INPUT@',
'@OUTPUT@',
]
)
# Step 3: add this file to the sysdeps library
Expand Down

0 comments on commit 9b955fb

Please sign in to comment.